pawabase
The Python client SDK for Pawabase: records, auth, storage, functions, flows, realtime, user administration
and environment management, for apps, scripts and servers. Blocking and asyncio clients with the same methods.
pip install pawabase # httpx only
pip install "pawabase[realtime]" # + websockets, for live channels
Writing functions that run on Pawabase, and the pawabase command, are a separate package: pawabase-functions.
from pawabase import Pawabase
pb = Pawabase("https://api.example.com", "pb_pk_…") # AsyncPawabase for asyncio: the same methods, awaited
A publishable key (pb_pk_…) is what an app holds: policies decide what it can do, and a signed-in user's token goes on top. A secret key
(pb_sk_…) belongs on servers only: it bypasses policies and unlocks pb.admin and pb.manage.
Records
posts = pb.from_("posts")
page = posts.eq("status", "live").gte("views", 10).order("-created_at").select("id", "title").expand("author").per_page(20).execute()
page.data, page.total, page.has_next
for post in posts.eq("status", "live").iterate(): # every row, page after page
...
posts.where(status="live", views={"gte": 10}).all() # a list
posts.eq("slug", "hello").single() # NotFoundError if none
posts.eq("status", "draft").count()
row = posts.create(title="Hello")
posts.get(row["id"], expand=["author"])
posts.update(row["id"], title="Hello, world") # PATCH
posts.delete(row["id"])
posts.create_many(rows) # failures are collected, not raised
Operators: eq neq gt gte lt lte like ilike in_ not_in is_ is_not. The server applies one filter per field; a second filter on a field raises QueryError
before anything is sent, instead of silently dropping one. eq(col, None) and eq(col, True) become is, because eq.false matches true rows on the server.
Accounts
pb.auth.sign_up(email="ada@example.com", password="…", name="Ada")
result = pb.auth.sign_in_with_password(email="ada@example.com", password="…")
if result.status == "mfa_required":
result = result.verify(input("Code: "))
pb.auth.get_user(); pb.auth.update_user(name="Ada L.")
pb.auth.sign_out() # scope="global" signs out everywhere
The session is kept in memory (pass session_store=FileSessionStore("~/.myapp/session.json") to stay signed in between runs), its token goes on every
request, and an expiring or rejected token is renewed with the refresh token. Also: magic links, social sign-in (oauth_url, exchange_code), email
verification, password reset, linked identities, pb.auth.mfa (authenticator app, emailed codes, recovery codes), pb.auth.sessions, pb.auth.devices,
pb.auth.api_keys (keys a user makes for themselves), and pb.auth.orgs (organizations, members, invitations, teams).
More ways in: guest sessions (sign_in_anonymously(), then upgrade_anonymous(email=…, password=…) keeps what the guest made), emailed codes
(send_email_code(email=…) then verify_email_code(email=…, code=…)), and passkeys (pb.auth.passkeys: register_options / register_verify and
authenticate_options / authenticate_verify carry the WebAuthn ceremony; the device does the signing). issue_token("billing") trades the session for
a short-lived token for another service, and jwks() returns the public keys a server checks such tokens with.
A web server acts as the visiting user without sharing a connection's credentials:
with pb.as_user(request_token) as user_client: # same connection pool, this user's token
user_client.from_("orders").execute()
Files
avatars = pb.storage.from_("avatars")
avatars.upload("ada.png", open("ada.png", "rb"), content_type="image/png")
data = avatars.download("ada.png")
avatars.list(prefix="2026/"); list(avatars.list_all())
avatars.public_url("ada.png") # public buckets: no key needed
avatars.transform_url("ada.png", width=200, height=200, fit="cover", format="webp")
avatars.create_signed_url("report.pdf", expires_in=600) # a temporary link anyone can read
avatars.create_signed_upload_url("in/x.png", max_bytes=1_000_000) # a browser uploads straight to storage
avatars.create_share_link("report.pdf", expires_in=3600) # for people with no account (secret key)
Functions, flows, routes
pb.functions.invoke("orders.create", sku="A1") # branch="my-feature" runs a branch's version
pb.flows.invoke("welcome", email="ada@example.com")
pb.routes.post("orders/42/pay", method="card")
Realtime
async with AsyncPawabase(url, key) as pb:
room = pb.realtime.channel("chat:lobby", presence={"name": "Ada"})
room.on("message", lambda m: print(m["payload"]))
await room.subscribe()
await room.send("message", {"text": "hello"})
async for change in pb.realtime.channel("resource:posts"): # live record changes, as you may read them
print(change["event"], change["payload"]["record"])
Publishing, presence and history also work over plain HTTP on the blocking client: pb.realtime.publish(...), .presence(channel), .history(channel).
Without a socket: pb.realtime.sse(["chat:lobby"]) listens over Server-Sent Events (a generator on the sync client, an async generator on the async one), and
pb.realtime.publish(...) sends. Channel rules and dashboards are managed with pb.manage.realtime_channels and pb.manage.dashboards.
Administering users and the environment (secret key)
admin = Pawabase(url, "pb_sk_…", environment="production")
admin.admin.users.create(email="ada@example.com", password="…", roles=["editor"])
admin.admin.users.update(user_id, disabled=True)
admin.admin.orgs.add_member("acme", email="ada@example.com", role="admin")
admin.manage.secrets.set("STRIPE_KEY", "sk_live_…")
admin.manage.firewall.ban("203.0.113.7", seconds=3600)
admin.manage.jobs.replay(job="send_mail", since_minutes=60, dry_run=True)
admin.manage.observability.logs(q="timeout", minutes=15)
admin.manage.backups.snapshot("before-launch")
admin.manage.environment("staging").flows.list() # the same API for another environment the key may manage
pb.admin administers the people who sign in to your application: users, roles, orgs, invitations, sessions, api_keys, devices, insight
(events, statistics, identity backup, hosted pages). pb.manage is the environment's management plane, in four families:
| Family | Services |
|---|---|
| Data | resources, schema, policies, schemas, transformers, routes, database, runtime |
| Automation | flows, schedules, subscriptions, events, webhooks, inbound_hooks, jobs, functions |
| Files and mail | buckets, cache, mail, mail_templates |
| Access | keys, secrets, domains, firewall |
| Observe | observability, alarms, status_page, health (service health, plan usage, audit) |
| Lifecycle | environments (previews, promote, blueprints), releases (branches, revisions, API versions), backups (backups, snapshots, restore) |
Definitions (flows, policies, webhooks…) share list, get_one, create, replace and remove, and take branch= to work on a feature branch.
Both are scoped to the client's environment; a key manages only its own.
Errors and retries
Every failure raises PawabaseError (.status_code, .code, .message, .details, .request_id) or a subclass: AuthenticationError (401), ForbiddenError
(403), QuotaExceededError (403, the plan's limit: details has limit, allowed, used), NotFoundError, ConflictError (409), ValidationError (400/422),
RateLimitedError, ServerError, NetworkError. Reads are retried on connection errors and 502/503/504; a 429 waits as the gateway asks.
BSD 3-Clause licensed.
Metadata
Release files for pawabase 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pawabase-0.3.0.tar.gz | 59.0 kB | Without provenance | Details for pawabase-0.3.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pawabase-0.3.0-py3-none-any.whl | Python 3 | none | any | Details for pawabase-0.3.0-py3-none-any.whl |
Total release size: 119.2 kB
Release files / pawabase-0.3.0.tar.gz
| Download URL | pawabase-0.3.0.tar.gz |
|---|---|
| Size | 59.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0529406cf68c8c8b3b4a0f22b473923d9d2df541fa668cd36b6a790b8c167aa3
|
|
BLAKE2b-256 checksum How to use checksums |
c131ed6f7bde0877988a351062e196dd4a8df228b87ab80dcb406e38a54562a1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.6 {"installer":{"name":"uv","version":"0.13.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / pawabase-0.3.0-py3-none-any.whl
| Download URL | pawabase-0.3.0-py3-none-any.whl |
|---|---|
| Size | 60.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
728d29116cdd3d6c4f70fb0c8eed6a8316c4ed57c9652a1446ffbba0dfa24b50
|
|
BLAKE2b-256 checksum How to use checksums |
a489a2462ed69bf228251324d549fd2eb12b8c35c63705aeebb1a46121250e84
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.6 {"installer":{"name":"uv","version":"0.13.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for pawabase 0.3.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.