Getting started¶
Install gazebo and stand up a minimal OGC-style API.
Install¶
pip install gazebo # core: pydantic only
pip install 'gazebo[fastapi]' # + the GazeboApp / FastAPI glue
Requires Python 3.12+.
Your first app¶
The app below is complete and runnable. It shows the three ideas you'll use in
every gazebo service: an endpoint on a GazeboRouter returning a
LinkedCollection of deferred links; one app-scoped dependency injected by type;
and a create_app() factory so tests can pass overrides. (A real service would
also inject a database and a request-derived user — see
Gazebo Gardens.)
from dataclasses import dataclass
from gazebo.collection import LinkedCollection
from gazebo.ext.fastapi import GazeboApp, GazeboRouter, Overrides, Providers
from gazebo.link import Link
@dataclass
class Settings:
greeting: str = 'hello'
@classmethod
def __provide__(cls) -> Settings:
return cls()
class Things(LinkedCollection[dict], items_alias='things'):
pass
router = GazeboRouter()
@router.get('/things', response_model=Things)
async def list_things(settings: Settings, limit: int = 10) -> Things:
items = [{'id': i, 'greeting': settings.greeting} for i in range(limit)]
return Things(items=items, links=[Link.self_link(), Link.root_link()])
def create_app(overrides: Overrides | None = None) -> GazeboApp:
providers = Providers().app(Settings)
app = GazeboApp(providers, overrides=overrides)
app.include_router(router)
@app.get('/', name='landing')
async def landing() -> dict:
return {'service': 'things'}
return app
app = create_app()
What just happened¶
Four gazebo features are already at work:
- Links resolved at serialize time.
Link.self_link()/root_link()are built with no request in hand; the glue fills in real URLs when the response serializes — see Links. - A collection envelope.
ThingsaddsnumberReturnedand a configurable items alias for free — see Collections. - By-type injection.
settingsis resolved from the registry by its type, noDepends— see Dependency injection. - Proxy-correct URLs. Put this behind a load balancer and the links follow
X-Forwarded-*— see Proxy & context.
Testing it¶
Tests drive the app through TestClient and substitute config with
Overrides passed into create_app — by
parameter, never by mutating a global, so tests stay isolated:
from fastapi.testclient import TestClient
def test_things() -> None:
overrides = Overrides().set(Settings, Settings(greeting='hi'))
with TestClient(create_app(overrides)) as client:
body = client.get('/things?limit=2').json()
assert body['numberReturned'] == 2
assert body['things'][0]['greeting'] == 'hi'
Next¶
- The core — links, collections, problems, landing pages.
- Dependency injection — providers, scopes, lifecycle.
- FastAPI integration — the app, routers, proxy, health.