Skip to content

Libraries

Blupinta’s libraries call the public API for you: the sign-in at auth.blupinta.app, every operation with its types, a home followed as its versions are saved. They only talk to the API: a home’s checks are Blupinta’s, asked through POST /v1/homes/check. Their sources are public, at github.com/blupinta/blupinta, under the Apache 2.0 licence. The examples below are the ones the libraries’ own checks compile, so they work as written.

For the browser and Node: every operation called by its id (client.call('getHome', …)), with its parameters and answer typed; a refusal is a BlupintaError with the API’s code; watchHome shows the copy kept on the device, then each new version.

Terminal window
npm install @blupinta/sdk
quickstart.ts
// A dashboard's first lines with @blupinta/sdk: connect with a code typed on a phone, then show the home and follow
// each new version. Typechecked with the package, so it can't drift from it.
import { createClient } from '@blupinta/sdk'
import { startDeviceSignIn, tokenKeeper } from '@blupinta/sdk/auth'
import { memoryHomeStore, watchHome } from '@blupinta/sdk/watch'
const signIn = await startDeviceSignIn({ scope: 'openid offline_access projects:read' })
console.log(`Open ${signIn.verificationUri} and type ${signIn.userCode}`)
const tokens = await signIn.tokens()
const client = createClient({ token: tokenKeeper({ clientId: 'device', tokens }) })
const { rows } = await client.call('listProjects')
const project = rows[0]
if (!project) throw new Error('no project was chosen')
watchHome(client, project.id, {
store: memoryHomeStore(),
onHome: (saved) => console.log(`${saved.home.name}: version ${saved.number}`),
onError: (error) => console.error(error.code, error.problems),
})

useHome, useProject and useRevisions in a BlupintaProvider, and useSignIn for the browser’s sign-in with PKCE, finished by itself on your app’s return address (Registering it).

Quickstart.tsx
// A page with @blupinta/react: sign in with Blupinta, then show a home that updates as versions are saved.
// Typechecked with the package, so it can't drift from it.
import { useHome } from '@blupinta/react/hooks'
import { BlupintaProvider } from '@blupinta/react/provider'
import { useSignIn } from '@blupinta/react/sign-in'
import { createClient } from '@blupinta/sdk'
import { useMemo } from 'react'
export function App() {
const session = useSignIn({
clientId: 'app_…', // registered in Blupinta's settings, Developers
redirectUri: 'https://your.app/', // one of its return addresses: this page finishes the sign-in
scope: 'openid offline_access projects:read',
})
const client = useMemo(() => createClient({ token: session.token }), [session.token])
if (!session.tokens)
return (
<button type="button" onClick={session.signIn}>
Sign in with Blupinta
</button>
)
return (
<BlupintaProvider client={client}>
<Home projectId="…" />
</BlupintaProvider>
)
}
function Home({ projectId }: { projectId: string }) {
const { data, error, isLoading } = useHome(projectId)
if (isLoading) return <p>Loading…</p>
if (error) return <p>{error.code}</p>
return (
<h1>
{data?.home.name}, version {data?.number}
</h1>
)
}
Terminal window
npx @blupinta/cli login # a code typed in your browser; the tokens in your keychain
npx @blupinta/cli pull "My home" --dir home # home.json and its files
npx @blupinta/cli check home/home.json # Blupinta's checks on the file
npx @blupinta/cli push --dir home -m "Moved the sofa"
npx @blupinta/cli watch "My home" --exec "./redraw.sh"

Every command takes --json, for scripts and agents. A push made on an old version is refused, saying who saved after it.

An MCP server: an agent lists the projects, reads a home and its versions, checks a home and saves a new version. Sign in with npx @blupinta/cli login, then add it to the agent:

{ "mcpServers": { "blupinta": { "command": "npx", "args": ["-y", "@blupinta/mcp"] } } }

Every operation in blupinta.v1, called through Blupinta.call (or acall, with asyncio); the device flow, a home followed with watch_home, webhooks checked with is_signed_webhook.

Terminal window
pip install blupinta
quickstart.py
"""A script's first lines with blupinta: connect with a code typed on a phone, list the projects, read a home, then
follow each new version. Compiled by the package's tests, so it can't drift from it."""
from blupinta import Blupinta, TokenKeeper, start_device_sign_in, watch_home
from blupinta.v1.api.projects import get_home, list_projects
signing_in = start_device_sign_in("openid offline_access projects:read")
print(f"Open {signing_in.verification_uri} and type {signing_in.user_code}")
tokens = signing_in.tokens()
with Blupinta(TokenKeeper(tokens, client_id="device")) as blupinta:
project = blupinta.call(list_projects).rows[0]
saved = blupinta.call(get_home, project.id)
print(f"{saved.home['name']}: version {saved.number}")
for saved, _etag in watch_home(blupinta, project.id, etag=None):
print(f"new version {saved.number}: {saved.message}")