Skip to content

MSFLib

MSFLib (pronounced "musflib") is a set of Python packages for building FastAPI backends. A small core package, msflib, supplies the shared plumbing: settings, base models, a CRUD action layer, an event bus, scope and policy primitives, database setup and seeding. On top of it sit optional feature modules such as accounts, authentication, workspaces, payments and AI infrastructure.

You write a normal FastAPI application, the host app. You install the packages you need, define your own models and routes next to the ones the modules provide, and mount the module routers where you want them. MSFLib does not run your app and does not own your FastAPI() instance.

What a module is

A module is a separately installable msflib-* package. Each one is a slice of the shared msflib namespace (for example msflib.auth or msflib.workspaces) and typically provides some mix of:

  • Models: SQLModel tables and the Pydantic schemas that go with them.
  • Actions: service-layer classes, usually ModelAction subclasses, that hold the database logic.
  • Routers: factory functions that build a FastAPI APIRouter from the dependencies you hand them (session, identity, settings).
  • Dependencies: factories that return namespaces of FastAPI dependencies, such as "the current account".
  • Settings: a settings class with its own namespace, mixed into your app's settings class (or composed as a nested field; see the authentication guide for a current limitation).

Modules are written to be wired, not configured by import side effects. A module's router factory asks you for the session and identity dependencies it needs, so the same module works with whatever auth and database layout your app already has. Modules depend on msflib and, in some cases, on each other (see the table below).

Package map

All packages live in one repository, msflib/fastapi. "Depends on" lists the direct msflib-* dependencies declared in each package's pyproject.toml; every package also depends on msflib itself.

Package Import Purpose Depends on
msflib msflib Core: settings, base models, actions, event bus, scope and policy, DB setup, seeding, utilities none
msflib-auth msflib.auth Login, token issue and revocation, password reset, optional Google OAuth, identity dependency factories none
msflib-account msflib.account Accounts and profiles: registration, self-service and admin endpoints none
msflib-tenancy msflib.tenancy A minimal Tenant model and tenant resolution, the target for tenant_id foreign keys none
msflib-workspaces msflib.workspaces Workspace lifecycle, ownership and membership account, tenancy
msflib-notifications msflib.notifications Account inbox and admin broadcast over in-app, email and SMS channels account, tenancy
msflib-workspace-notifications msflib.workspace_notifications Workspace-level notifications, including Discord channels workspaces, notifications
msflib-workspace-config msflib.workspace_config Tenant, workspace and user scoped configuration values and categories tenancy
msflib-payments msflib.payments Payment initiation and verification over Stripe and Paystack, payment queue none
msflib-ai-core msflib.ai_core Provider-agnostic LLM, embedding and vector-store factories, prompts, ingestion pipeline tenancy
msflib-ai-api msflib.ai_api HTTP endpoints for scoped retrieval and grounded Q&A on top of ai-core account, ai-core, tenancy
msflib-drivelink msflib.drivelink A Drive-style virtual filesystem account
msflib-ingestion msflib.ingestion Shared ingestion job model and Celery-backed queue with an operator API tenancy
msflib-documents msflib.documents Document upload, extraction, chunking, embedding and indexing account, drivelink, ai-core, ingestion, tenancy
msflib-knowledge msflib.knowledge Scoped knowledge model projected to graph and vector stores, with semantic queries ai-core, documents, ingestion, tenancy
msflib-conversation msflib.conversation Channels, threads, messages, membership and reactions tenancy

The import column is a namespace package: msflib is declared with pkgutil.extend_path, so all of these packages install into the same msflib directory tree. Check what a package's __init__ exports before relying on from msflib.x import y; several modules export nothing at the top level and expect you to import from submodules.

Picking what to install

Start from what your app has to do, then add the packages that provide it. Installing a package pulls in the msflib-* packages it depends on.

If you need Install
CRUD endpoints over your own models, settings, events, seeding msflib only
User accounts and login msflib-account and msflib-auth
Per-tenant isolation keys on your tables msflib-tenancy
Teams or organisations that users join msflib-workspaces (brings account and tenancy)
Settings that differ by tenant, workspace or user msflib-workspace-config
In-app, email or SMS notifications msflib-notifications, plus msflib-workspace-notifications for workspace-level ones
Taking payments msflib-payments
LLM calls, embeddings, vector search msflib-ai-core, plus msflib-ai-api for ready-made endpoints
Chat threads and channels msflib-conversation
File storage with a folder tree msflib-drivelink
Document ingestion and retrieval msflib-documents and msflib-ingestion; add msflib-knowledge for the knowledge graph

Some packages have optional extras (for example msflib-ai-core[openai,pgvector] or msflib-notifications[email]); each module page lists them. The core has one, migrations, which adds Alembic.

Known issue (#279)

The sms, email and discord extras of the notification packages currently add nothing: their dependencies (twilio, emails, discord-py) are already hard requirements of the core, so you do not need them. For msflib-workspace-notifications, avoid the sms and all extras: they require twilio ^8.0.0 while the core requires ^9.4.6, so the resolver cannot satisfy both.

Installing

Packages are installed from the git repository, one subdirectory per package. With Poetry:

[tool.poetry.dependencies]
msflib = { git = "https://github.com/msflib/fastapi.git", subdirectory = "core", rev = "core-v0.2.1" }
msflib-account = { git = "https://github.com/msflib/fastapi.git", subdirectory = "modules/account", rev = "account-v0.2.2" }
msflib-auth = { git = "https://github.com/msflib/fastapi.git", subdirectory = "modules/auth", rev = "auth-v0.2.2" }

Pin a release tag in rev. Tags are named <package directory>-v<version>, for example core-v0.2.1, account-v0.2.2 or workspace_config-v0.2.1, and each package is versioned independently. The versions above were current when this page was written; list the latest with:

git ls-remote --tags https://github.com/msflib/fastapi.git 'core-v*'

Do not use rev = "dev" (or @dev with pip) in anything you deploy. dev is the moving development head: it can change or break between installs. The Quick Start walks through the same installation for the core package.

Note

MSFLib 0.2.0 and later require Pydantic v2. If your app is still on Pydantic v1, use the 0.1.x tags.

Where to go next

  • Quick Start: a four-page walk from an empty directory to a tested CRUD API on the core package.
  • Modules: one page per package.
  • Diving Deeper: mounting routes, overriding models, subclassing actions, authentication, long-running jobs.
  • Concepts: tiered configuration, policy, scopes, the event bus, dependency injection and seeding.
  • Contributing: working on MSFLib itself.