Architecture
This document describes the current Adapt architecture.
High-Level Design
Adapt is a FastAPI application that:
- Loads configuration from
DOCROOT/.adapt/conf.json - Initializes SQLite-backed storage and cache
- Selects candidate plugins by extension and uses plugin detection to accept resources
- Generates API/UI/schema/media routes per discovered resource
- Enforces authentication and authorization through dependencies
Core Components
Application Layer
Key responsibilities in adapt/app.py:
- app creation and shared state initialization
- middleware registration
- auth/admin router mounting
- dynamic route generation
- health and landing/media-gallery routes
Discovery and Plugin Layer
Key modules:
adapt/discovery.pyadapt/plugins/*adapt/routes.py
Flow:
- Discovery scans docroot
- Extension determines plugin class via
plugin_registry - Plugin
detect()accepts or rejects the file - Plugin
load()returns one or more resource descriptors - Discovery assigns schema, UI, and options companion paths
- Plugin
apply_options()can modify each descriptor - Plugins can generate companion files under
.adapt/ - Route configs from plugin are mounted into the app
Data and Security Layer
Key modules:
adapt/storage.py(SQLModel tables + DB engine)adapt/auth/*(sessions, password, dependencies)adapt/security.py(CSRF + security headers)adapt/locks.py(lock manager)adapt/cache.py(SQLite-backed cache)
Implemented Middleware and Security Flow
Current middleware stack includes:
- Trusted host middleware
- security middleware (CSRF validation + security headers)
- auth middleware (session user hydration)
Request flow for unsafe methods with session authentication:
- CSRF token validated (
adapt_csrfcookie +X-CSRF-Token) - user resolved from session or API key
- endpoint dependency checks permission
- route handler executes
Route Generation Model
For each resource, plugins provide (prefix, router) pairs.
Routes are mounted with permission dependencies and namespace variants.
Each resource has an extensionless namespace and an extension-qualified
namespace. For example, data.csv uses both data and data.csv. An Excel
sheet adds its sub-namespace to both forms, such as data/Sheet1 and
data.xlsx/Sheet1.
Common prefixes:
apischemauimedia
Dataset plugins use ui_path for an HTML template. The media plugin writes
JSON metadata to ui_path and renders its HTML player from the built-in
template.
Data Model Summary
Primary tables include:
usersgroupspermissionusergroupgrouppermissiondbsessionapikeyauditloglock_records
All live in docroot-local SQLite (.adapt/adapt.db).
Caching Model
Current cache implementation is SQLite-backed (adapt/cache.py).
- cache table name:
cache - TTL-based entries
- resource-scoped invalidation
- used by plugins and admin cache endpoints
Caching is plugin-specific, not a response-wide FastAPI cache. CSV, Excel, and Parquet plugins cache parsed rows; dataset schemas are cached separately; HTML and Markdown plugins cache rendered/read content; and the media plugin caches extracted metadata. Generic file response bodies and streamed media bodies are not cached.
Locking Model
Locking uses DB records with per-resource uniqueness and expiration.
- one lock record can exist per resource
- lock acquisition retries with exponential backoff
- stale locks can be cleaned
- write operations use lock context manager
- writable built-in dataset plugins replace the target atomically where supported
Adapt returns 409 Conflict when lock acquisition exhausts all retries.
Locking and atomic replacement reduce risk. Races can still occur. A write can
still stop before completion.
Observability
- Python logging configured via
conf.jsonloggingsection - audit logs available via
/admin/audit-logs - successful REST and MCP dataset mutations create audit records
- health endpoint at
/health
Deployment Notes
Current implementation is optimized for single-instance docroot-local operation.
Multi-instance, shared DB/cache, and websocket-style real-time update architectures are future design topics, not current built-in behavior.
Manual navigation: Previous: Plugin Development | Index | Next: Troubleshooting