Architecture¶
Periplo runs as one process: a FastAPI application, built on
loom-kernel, that serves the HTTP API
under /api/v1 and, when PERIPLO_WEB_DIR is set, the built web console on every other
path. The console and the API share one origin, so there is no CORS to configure and no
proxy to run.
Components¶
Component |
Where |
Role |
|---|---|---|
Composition root |
|
The only place that knows the concrete implementations. It reads the settings, builds every component and wires the extension ports. |
Catalog |
|
Walks each source, builds the catalog of tables and publishes it. Reads schemas, statistics and history from the Delta logs. |
Queries |
|
Checks that a query only names catalog tables, runs it on a fresh DataFusion session and streams the result as Arrow. |
ETL |
|
The |
Identity and tenancy |
|
Answers who is calling and for which tenant, once per |
Access |
|
Authorizes each action and writes audit events. |
Web console |
|
Serves the built console, with long-lived caching for hashed assets. |
Life of a request¶
Identity and tenant. A middleware authenticates every
/api/*request with theAuthenticatorport, resolves its tenant with theTenantResolverport, and publishes both as the request context. A refusal ends the request with401or403before any route runs.Data plane. A catalog or query route resolves the data plane of the tenant: its catalog, snapshots, caches and query engine.
Authorization. The route asks
Accesswhether the action (read the catalog, run a query, view or operate an ETL) is allowed on its target. Denials of state-changing actions are audited.Work. The route does its work. A route that reads storage asks for the tenant’s storage credentials first, and reads only with them. Operating an ETL is audited before it happens (an action that cannot be audited does not happen) and again with its outcome.
In the open-source defaults every caller is anonymous and belongs to a single tenant,
served by a single data plane with the process’s own credentials, and the only rule is
PERIPLO_ETL_ALLOW_OPERATE. Extending Periplo explains how to
replace each of these pieces.
Catalog¶
At start-up the application begins the first discovery in the background and serves liveness at once; readiness waits for that discovery. Sources are walked one after the other, each from a pool of threads that only make listing calls (see Sources file). The result is published as a whole: a request always sees one complete catalog, never a half-built one. A source whose walk fails keeps the tables of its last successful one.
Metadata of a single table is read when it is asked for. Opened Delta snapshots are kept
in a bounded registry and revalidated after PERIPLO_METADATA_TTL_SECONDS; the derived
answers (schema, statistics, history) live in a byte-bounded cache. The table routes
answer conditional GET requests with ETag and 304 Not Modified.
Queries¶
A query goes through these steps:
It is parsed, and every table it names must be in the catalog; anything else is refused before a slot is taken.
It takes one of
PERIPLO_MAX_CONCURRENT_QUERIESslots, or is refused with429.It runs on a new DataFusion session that holds exactly the tables it names, each pinned to one Delta version, with DDL, DML and other statements disabled.
The result streams back as an Arrow IPC stream (
application/vnd.apache.arrow.stream), cut at the row and byte limits, with its id in theX-Query-Idheader. The id can be used to read the query’s state or cancel it.
Every query is audited with its normalized SQL, never with row data.
HTTP API¶
The API describes itself: the running application serves its OpenAPI document at
/openapi.json and interactive documentation at /docs.
Method and path |
Purpose |
|---|---|
|
The published catalog. |
|
Schema and version of one table. |
|
Statistics from the Delta log. |
|
Latest commits of the table. |
|
Each source with the report of its last discovery. |
|
Start a new discovery. |
|
Run a query; the body is |
|
State of a query; cancel it. |
|
Whether the ETL integration is configured and operating is allowed. |
|
Deployments, their runs, and the process-by-run grid. |
|
One run, its attempts and steps, and its logs. |
|
Operate an ETL, when allowed. |
|
Liveness; readiness ( |