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/
└── 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 lets it continue, but it still only adds files that are missing; it never overwrites an existing file.
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/ with remotes/ and databases/ and copies the example files (never overwrites) |
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) |
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 limitations: it prints route SQL as written (it does not expand [[...]] references), reads database files from api_dock_config/databases/, and prints an error line for 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