Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

rowstile for Python

pip install --pre rowstile (--pre while only an alpha is published) installs the rowstile command (rowstile init, dev, migrate, review; also python -m rowstile) and the SDK for Python apps. Extras bring the integrations' dependencies: rowstile[fastapi], [sqlalchemy], [psycopg], [asyncpg]. Python 3.11 or newer.

The SDK for Python apps on a rowstile policy: every transaction signs in as whoever the request or the job acts for, refused writes become a 403 with the database's reason, rows the user can't see a 404, and the app refuses to start on a connection that skips row-level security. It holds no rowstile logic: it calls the authz.* functions the policy made, and translates their answers.

from fastapi import FastAPI
from sqlalchemy.ext.asyncio import create_async_engine
from rowstile.fastapi import Rowstile

engine = create_async_engine("postgresql+asyncpg://app@db/app")
app = FastAPI()
Rowstile(app, engine, user=current_user)     # current_user(request): its user's id, or None; before adding routes
module what
rowstile acting_as(who), @job(who), Principal, Refused, NotFound, refusal(exc), error_code(exc) (rowstile's code for any database error: AZ709), act_as_sql()
rowstile.fastapi Rowstile(app, engine, user=...): the request's principal, 403/404 problem bodies, the start-up check
rowstile.sqlalchemy install(engine) (sync or async; SQLModel too), ids(type, perm) for where, perms_of() for a list's buttons, can(), expect() for Core updates and deletes, why_stale() for the ORM's StaleDataError
rowstile.psycopg transaction(conn, who), atransaction(aconn, who), expect(), aexpect()
rowstile.asyncpg transaction(conn, who), expect()
rowstile.alembic include_name, include_object: autogenerate leaves rowstile's objects alone
rowstile.testing pytest fixtures: as_user, assert_refused, assert_not_found (awaited, with an async function), authz_owner_url, authz_app_url

Who a transaction acts for: 42 or "42" (a user), ("service", 3) (another principal type of the policy), or None (nobody: only what anyone may see; None given to a call is nobody too, whoever the code around it acts for). A plain id is always a user's, whatever it holds: "service:3" is the user with that id, so an id from outside (a username, an identity provider's subject) can't name a service. Principal.parse("service:3") reads back what str() wrote, for text your own code wrote. Every transaction signs in, even when nobody is signed in, and nothing uses a session-level SET, so pools and poolers in transaction mode are safe; behind one that keeps no prepared statements, turn the driver's off (Behind a pooler).

With FastAPI: user(request) runs in a middleware that Rowstile(...) adds, so give it the session or the token to read from the request itself. What a middleware of yours puts on request.state is there only if that middleware was added after Rowstile(...) (Starlette runs the one added last first); added before, it hasn't run yet. user may raise an HTTPException. The start-up check runs whether or not the app has a lifespan. WebSockets are not signed in: use rowstile.acting_as() in the endpoint. An engine in AUTOCOMMIT can't be signed in (the sign-in lasts a transaction): its queries fail with NotSignedIn.

Policy changes ship as migrations for your tool (rowstile migrate, with tool = "alembic" in rowstile.toml). The types and permissions of your policy are generated names (rowstile client py), so a misspelled permission doesn't type-check.

integrations/fastapi/ is the conformance suite: a small FastAPI app on SQLAlchemy (async, asyncpg) and Alembic, and the checks every supported stack passes (integrations/fastapi/test.sh).

Metadata

Release files for rowstile 0.1.0a2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rowstile 0.1.0a2
File Size Uploaded
rowstile-0.1.0a2.tar.gz 300.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for rowstile 0.1.0a2
File Interpreter ABI Platform
rowstile-0.1.0a2-py3-none-any.whl Python 3 none any Details

Total release size: 627.9 kB

Release files / rowstile-0.1.0a2.tar.gz

Download URL rowstile-0.1.0a2.tar.gz
Size 300.3 kB
Tags Source
SHA-256 checksum
How to use checksums
5e0d9cbaa42a51ba079e174961ea921b23894df3ed016ff268cbbb5da91af3b5
BLAKE2b-256 checksum
How to use checksums
8c0f1b6b0f136b9c5ea48d42b5ba91f4af34661f6e5880f0b37814ab64856c03
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

Release files / rowstile-0.1.0a2-py3-none-any.whl

Download URL rowstile-0.1.0a2-py3-none-any.whl
Size 327.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5604db7ef7b73fea49f5964ef0a0f955a42d0430a216e5a22fb81abc6b0b6843
BLAKE2b-256 checksum
How to use checksums
8173ee72938622b656d19970f4e0a8b5f3f29b7c3fedb9c9b210c6162dda3cf9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page