Repository navigation
Getting Started
This page installs API Dock, creates a config folder, adds one remote API and one database backed by a local Parquet file, and starts the server. The CLI reference is at the end.
API Dock needs Python 3.11 or later.
pip install api-dock # core package
pip install 'api-dock[postgres]' # also installs the PostgreSQL driver and poolWith conda or pixi (conda-forge):
conda install -c conda-forge api_dock
pixi add api_dockYou only need the postgres extra if your configs define PostgreSQL connections. See PostgreSQL.
Run api-dock init in the directory you will start the server from:
api-dock initIt creates api_dock_config/ and copies in the bundled example files:
api_dock_config/
├── config.yaml # the main config
├── databases/
│ ├── config.yaml # optional shared database config (all commented out)
│ └── example_db.yaml # an example database
└── remotes/
├── config.yaml # optional shared remote config (all commented out)
└── example_remote.yaml # an example remote API
The example files point at placeholder addresses (https://api.example.com, s3://your-bucket/...) and contain commented-out examples of most features. Replace or delete them before you use the server.
init stops with an error if api_dock_config/ already has .yaml files at its top level. --force runs it anyway and replaces existing files with the example's (since api_dock 0.10.0; before, it only added missing files). Every example file is copied, keeping its folders.
A remote is an HTTP API that API Dock forwards requests to. Replace api_dock_config/remotes/example_remote.yaml with a file for httpbin.org:
# api_dock_config/remotes/httpbin.yaml
name: httpbin
description: HTTP request and response service
url: https://httpbin.orgRequests to /httpbin/<path> are now forwarded to https://httpbin.org/<path>. The URL prefix comes from the file's name (the file name is used if name is missing). Allow-lists, restrictions and route remapping are covered in Routing and Restrictions.
A database is a set of tables plus routes that map URLs to SQL. Create a small Parquet file (DuckDB is installed with API Dock):
mkdir -p data
python -c "import duckdb; duckdb.sql(\"COPY (SELECT * FROM (VALUES (1, 'Oakland', 'US'), (2, 'Lyon', 'FR')) t(id, name, country)) TO 'data/places.parquet' (FORMAT parquet)\")"Then describe it:
# api_dock_config/databases/places.yaml
description: Example places table
tables:
places: data/places.parquet
routes:
- route: places
sql: SELECT [[places]].* FROM [[places]]
query_params:
- country:
sql: "[[places]].country = {{country}}"
- route: places/{{id}}
sql: SELECT [[places]].* FROM [[places]] WHERE [[places]].id = {{id}}-
tablesmaps a name to a file path or URI. Relative paths such asdata/places.parquetare read by DuckDB relative to the directory you start the server from. -
[[places]]refers to that table. AfterFROMit becomes'data/places.parquet' AS places; elsewhere it becomesplaces. -
{{id}}is a path variable and{{country}}a query parameter. Both reach DuckDB as bound parameters.
The URL prefix of a database is its entry in the main config's databases: list (which is also the file name). See SQL Database Support and Query Parameters for everything a database config can hold.
List the remote and the database in api_dock_config/config.yaml:
# api_dock_config/config.yaml
name: my-api
description: My first API Dock
authors:
- Your Name
remotes:
- httpbin # remotes/httpbin.yaml
databases:
- places # databases/places.yaml
settings:
add_trailing_slash: falseadd_trailing_slash defaults to true, which turns /httpbin/get into a request for https://httpbin.org/get/, and httpbin answers that with 404. Many APIs expect the slash, some (like httpbin) don't. See Configuration for every setting.
api-dock startAPI Dock checks every database config at startup and refuses to start if one is invalid, naming the database, version and route. By default it binds 0.0.0.0:8000; if the port is taken it tries the next four ports and prints the one it used.
curl http://localhost:8000/
# {"name":"my-api","description":"My first API Dock","authors":["Your Name"],"endpoints":["/"],"remotes":["httpbin","places"]}
curl http://localhost:8000/places/
# {"routes": ["places", "places/{{id}}"]}
curl http://localhost:8000/places/places
# [{"id": 1, "name": "Oakland", "country": "US"}, {"id": 2, "name": "Lyon", "country": "FR"}]
curl "http://localhost:8000/places/places?country=FR"
# [{"id": 2, "name": "Lyon", "country": "FR"}]
curl http://localhost:8000/places/places/1
# [{"id": 1, "name": "Oakland", "country": "US"}]
curl http://localhost:8000/httpbin/get
# httpbin's own JSON response-
/returns the metadata from the main config. Databases are listed underremotestoo. -
/<database>/lists the database's routes. For a versioned database it lists the versions instead (see Versioning). - An unknown route returns 404 with a JSON body, e.g.
{"error": "Route 'nope' not found in database 'places'"}.
| Command | What it does |
|---|---|
api-dock |
Lists the configs in api_dock_config/ and the bundled examples, plus the commands |
api-dock init [--force/-f] |
Creates api_dock_config/ and copies the example files; --force replaces existing ones |
api-dock start [CONFIG_NAME] |
Starts the server with api_dock_config/<CONFIG_NAME>.yaml (default config) |
api-dock describe [CONFIG_NAME] |
Prints the config's name, description, authors, remotes, databases (tables and route SQL) and endpoints |
api-dock generate-key |
Writes a new local encryption key file with permissions 600 |
api-dock encrypt PLAINTEXT |
Encrypts a value for use in a config file |
api-dock decrypt CIPHERTEXT |
Decrypts a value (for testing) |
api-dock lookups [CONFIG_NAME] |
Runs the config's lookups and prints their rows; with --url shows or --refreshes them on a running server |
start options:
| Option | Default | Meaning |
|---|---|---|
--host |
0.0.0.0 |
Address to bind |
--port |
8000 |
Port to bind; if it's in use, the next four ports are tried |
--backbone, -b
|
fastapi |
fastapi or flask. Flask buffers responses and refuses configs with PostgreSQL connections |
--log-level |
info |
critical, error, warning, info, debug or trace. With Flask, debug turns on Flask's debug mode |
CONFIG_NAME may include or omit .yaml. If api_dock_config/<CONFIG_NAME>.yaml doesn't exist, start and describe fall back to the bundled example config of that name. See Configuration.
describe builds the API the way start does (running lookups and the startup checks, so a bad config is reported), then prints every remote/version with its URL and every database/version with its schema, its own tables and each route's SQL with [[...]] references expanded (? marks a bound request value; query-param filters aren't shown). Before api_dock 0.10.0 it printed SQL as written and failed on versioned databases.
generate-key options: --output/-o (default .api_dock_key) and --force/-f to overwrite an existing key file.
encrypt and decrypt options:
| Option | Default | Meaning |
|---|---|---|
--method, -m
|
local_key |
local_key, env_key or aws_kms
|
--key-file |
.api_dock_key |
Key file for local_key
|
--key-env |
API_DOCK_ENCRYPTION_KEY |
Environment variable holding the key for env_key
|
--key-id |
none | KMS key ID, required for aws_kms
|
--region |
us-east-1 |
AWS region for aws_kms
|
How encrypted values are used is covered in Authentication and Cookies.
- Concepts: how remotes, databases, tables, schemas and versions fit together.
- Configuration: the main config and all settings.
- Routing and Restrictions: control which remote routes are reachable.
- SQL Database Support and Query Parameters: richer database routes.
- Versioning: serve several versions of a remote or database.
- Python API and Deployment: embed API Dock or run it in production.
Getting started
Remote APIs
Databases
- SQL Database Support
- Query Parameters
- Conditional SQL
- Shared Database Config
- Cross-Schema Queries
- PostgreSQL
- Lookups
Serving
Developing