The shared Python substrate for ForkTex services.
One install, no extras: import forktex resolves every module.
pip install forktex
This is not the 0.8.x
forktex, which was an agentic CLI — for that, pinforktex==0.8.1. Pre-1.0, minor versions may break; see CHANGELOG.md.
Modules
Primitives
| Module | What it is |
|---|---|
log |
Structured JSON logging (Loki-ready), trace_id contextvar, setup_logging |
error |
AppError hierarchy, AppErrorCode, ErrorEnvelope, to_envelope |
types |
Base Pydantic models, frozen value objects, camelCase wire shapes |
iso |
Canonical ISO-8601 date/time — every datetime it returns is UTC-aware |
Role facades — one per piece of infrastructure:
| Module | What it is |
|---|---|
database |
Async Postgres/SQLAlchemy: sessions, ORM bases, CRUD, advisory locks, migrations |
cache |
Async Redis: @cached, namespaced keys, invalidation |
storage |
S3/MinIO objects: presigned URLs, bucket lifecycle |
Bootstrap — process-level wiring:
| Module | What it is |
|---|---|
api |
FastAPI app factory: middleware stack, error envelope, health probes |
graph, queue, store, vault and vector are set aside in
backlog/facades/ until a consumer needs them.
Quick start
from contextlib import asynccontextmanager
from fastapi import Depends, FastAPI
from sqlalchemy.ext.asyncio import AsyncSession
from forktex.database import close_engine, init_engine, transaction
from forktex.log import setup_logging
setup_logging(service="my-api")
@asynccontextmanager
async def lifespan(app: FastAPI):
await init_engine(settings.db_url, pool_pre_ping=True, pool_recycle=1800)
yield
await close_engine()
app = FastAPI(lifespan=lifespan)
@app.get("/projects")
async def list_projects(session: AsyncSession = Depends(transaction.dependency)):
...
Transactions
The outermost caller owns the transaction: whoever opens it commits it once, and rolls it back on any exception.
@transaction
async def place_order(session: AsyncSession, *, reference: str) -> Order:
return await create(session, Order, reference=reference)
await place_order(reference="A-1") # opens a session, commits it
async with transaction() as session:
order = await place_order(session, reference="A-2") # joins this transaction
await add_line(session, order=order, sku="X") # the same one
raise PaymentFailed # both roll back
transaction() |
async with — the library commits |
@transaction |
the same unit of work as a decorator |
transaction.dependency |
the same unit of work as a generator, for Depends |
session() |
no boundary — you commit, or leaving the block raises |
savepoint(session) |
a part allowed to fail without the rest |
Inside the first two, commit(), rollback() and begin() raise TransactionBoundaryError.
To abort, raise. Full contract in docs/database.md.
init_engine / cache.init / storage.init configure one process-wide default; Database(url),
Cache(url) and StorageClient(config) build handles directly, so a process can hold several.
Documentation
One page per module under docs/: wiring, the public surface, the error contract,
the gotchas. docs/development.md is the contributor guide.
Development
make install # poetry install --with dev
make test # pytest with the coverage floor
make ci # format-check · lint · license-check · typecheck · audit · test · build · smoke
Integration tests use testcontainers, so Docker must be available.
License
Dual-licensed: AGPL-3.0-or-later, or a commercial license from FORKTEX S.R.L. (info@forktex.com). See LICENSE and NOTICE.
Metadata
Release files for forktex 0.15.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 |
|---|---|---|---|---|
| forktex-0.15.0.tar.gz | 38.8 kB | Without provenance | Details for forktex-0.15.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| forktex-0.15.0-py3-none-any.whl | Python 3 | none | any | Details for forktex-0.15.0-py3-none-any.whl |
Total release size: 108.7 kB
Release files / forktex-0.15.0.tar.gz
| Download URL | forktex-0.15.0.tar.gz |
|---|---|
| Size | 38.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a32b9e5f7eec47781d102d40349b035c905f770bdd6a5b1b10a44f53439ffe32
|
|
BLAKE2b-256 checksum How to use checksums |
3ff173a0ae67d12b8147ccc8699d7ae2971c0c4cfa606be887129df21bf49038
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.6
|
Release files / forktex-0.15.0-py3-none-any.whl
| Download URL | forktex-0.15.0-py3-none-any.whl |
|---|---|
| Size | 70.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b67ff5660de882f7c573fe88fd2d671f193fd4c2c90ce44272be9cde51eac4cc
|
|
BLAKE2b-256 checksum How to use checksums |
c6a222cb7f3057dc3ca30642e79564905743152d9db29eb7567b606634f9a7b2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.6
|
Security for forktex 0.15.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.