eminidatabase-sdk
pip install eminidatabase-sdk
Official Python SDK (eminidatabase_sdk.client.PlatformClient) and CLI (platform)
for the Cloud Database Platform. Every CLI command is a thin wrapper over the SDK,
and every SDK method is a thin wrapper over one API call — no client-side business
logic, no caching, no retries; that all lives in the platform itself (see the
backend's job/retry machinery). This is what proves the exit criterion of
../docs/architecture/09-plan-de-phases.md
(Phase 8): an external developer can create and manage a database entirely through
the CLI, without ever touching a dashboard (which doesn't exist yet — see the
backend-first sequencing rule in that same document).
TypeScript/Go SDKs are deliberately not in this package — see the Phase 8 note in the plan of phases for why they're deferred to Phase F (built once there's an actual frontend consuming and exercising them).
Setup
cd sdk
python -m venv .venv
./.venv/Scripts/activate # Windows; use `source .venv/bin/activate` on Unix
pip install -e .
pip install -r requirements.txt # adds pytest/ruff for development
The backend must be running (see ../backend/README.md) — this package is a client, it has no server of its own.
CLI usage
platform login --email dev@example.com --password ...
platform whoami
platform organizations create "ACME" acme
platform organizations list
platform projects create acme "Shop" shop
platform projects list acme
platform db create acme shop production --region eu-west-1 --wait
platform db list acme shop
platform db get acme shop production
platform db connect acme shop production
platform db sql acme shop production "SELECT 1"
platform db resize acme shop production --cpu 2 --ram 2048 --storage 20
platform db suspend acme shop production
platform db resume acme shop production
platform db delete acme shop production
platform db backup create acme shop production --wait
platform db backup list acme shop production
platform db restore acme shop production <backup-id> production-restored --wait
platform webhooks create acme https://example.com/hook database.created backup.completed
platform webhooks list acme
platform webhooks deliveries acme <webhook-id>
platform webhooks delete acme <webhook-id>
platform jobs get <job-id>
Organization/project/database arguments accept either a slug/name or a UUID —
_resolve_organization/_resolve_project/_resolve_database in cli.py do the
lookup, so a developer never has to handle a raw UUID by hand.
Credentials are stored locally in ~/.eminidatabase/credentials.json (override the
directory with EMINIDATABASE_CONFIG_DIR, override the API URL per-command with
--api-url or EMINIDATABASE_API_URL).
SDK usage
import asyncio
from eminidatabase_sdk import PlatformClient
async def main():
client = PlatformClient() # defaults to https://apidatabase.eminilabs.org/api/v1
await client.login("dev@example.com", "correct-horse-battery")
org = await client.create_organization("ACME", "acme")
project = await client.create_project(org["id"], "Shop", "shop")
result = await client.create_database(org["id"], project["id"], "production", "eu-west-1")
await client.wait_for_job(result["job_id"])
asyncio.run(main())
Webhooks
create_webhook returns the signing secret exactly once, like an API key —
list_webhooks never returns it again. Every delivery is a real signed HTTP POST
(same jobs/worker infrastructure as everything else in the backend, cf.
app/services/webhook_orchestrator.py):
X-Eminidatabase-Event: the event type (e.g.database.created)X-Eminidatabase-Signature:sha256=<hmac-sha256 of the exact request body, hex>
Verify it the same way the platform computes it:
import hashlib, hmac
expected = hmac.new(secret.encode(), body_bytes, hashlib.sha256).hexdigest()
assert hmac.compare_digest(expected, received_signature.removeprefix("sha256="))
Test
pytest
ruff check .
Tests run against the real backend FastAPI app in-process (httpx.ASGITransport,
see tests/conftest.py) — no live server needed, but every request goes through
real routing/validation/DB, the same pattern backend/tests/conftest.py itself
uses. db_session_factory is exposed as a fixture rather than imported as a bare
module (from tests.conftest import ...) deliberately: both sdk/tests/ and
backend/tests/ resolve as a package named tests once the backend is added to
sys.path, and a bare import silently picked up the wrong one, corrupting the
shared FastAPI dependency_overrides dict for the rest of the test session — see
the Phase 8 entry in
../docs/architecture/09-plan-de-phases.md
for the full story.
Layout
eminidatabase_sdk/
client.py PlatformClient — one method per API call
cli.py Typer app (`platform`), built entirely on top of PlatformClient
auth_store.py local credential persistence (~/.eminidatabase/credentials.json)
exceptions.py ApiError
tests/ pytest + httpx ASGI transport, one file for the SDK, one for the CLI
Release files for eminidatabase-sdk 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| eminidatabase_sdk-0.1.0.tar.gz | 15.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| eminidatabase_sdk-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 26.9 kB
Release files / eminidatabase_sdk-0.1.0.tar.gz
| Download URL | eminidatabase_sdk-0.1.0.tar.gz |
|---|---|
| Size | 15.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
be36d5949fc6a7def4a5c6762ac49aad969e2c94cdd843c7df5ebd9182c39629
|
|
BLAKE2b-256 checksum How to use checksums |
9146a97d0c1bf0b47761190e46bb88e1d2dab213616ad4b17b97dde84a892a74
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.7
|
Release files / eminidatabase_sdk-0.1.0-py3-none-any.whl
| Download URL | eminidatabase_sdk-0.1.0-py3-none-any.whl |
|---|---|
| Size | 11.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5ce0113680d1e797269c977ab1eaeeb8911960fd710093ee7146ad264159aa5d
|
|
BLAKE2b-256 checksum How to use checksums |
1c55ab7216b8044250681a42568c99920f8ccba30383a3b6a731f0e36b95b0b4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.7
|