Skip to content

FastAPI API Reference

App Factory

yoro.fastapi.app.create_app(prefix='')

Create the Yoro FastAPI application.

Parameters:

Name Type Description Default
prefix str

Optional URL prefix for all routes (e.g. "/api/v1/yoro").

''
Source code in src/yoro/fastapi/app.py
def create_app(prefix: str = "") -> FastAPI:
    """Create the Yoro FastAPI application.

    Args:
        prefix: Optional URL prefix for all routes (e.g. ``"/api/v1/yoro"``).
    """
    app = FastAPI(
        title="Yoro API",
        description="Geographic addressing via Hilbert curves — GPS ↔ compact codes",
        version=__version__,
    )

    @app.get(f"{prefix}/encode", response_model=EncodeResponse)
    def encode_endpoint(
        lat: float = Query(..., description="Latitude (WGS 84)"),
        lon: float = Query(..., description="Longitude (WGS 84)"),
        domain: str = Query("CI", description="Domain ISO code"),
        precision: int = Query(12, ge=1, le=20, description="Hilbert order"),
    ) -> EncodeResponse:
        domain = domain_for_country(domain)
        try:
            code_str = encode(lat, lon, precision=precision, domain=domain)
        except ValueError as e:
            raise HTTPException(status_code=400, detail=str(e))

        decoded = decode(code_str)
        res = resolution(decoded["precision"], domain=domain)

        return EncodeResponse(
            code=code_str,
            lat=decoded["lat"],
            lon=decoded["lon"],
            precision=decoded["precision"],
            resolution_m=round(res, 2),
            bounds=BoundsSchema(**decoded["bounds"]),
        )

    @app.get(f"{prefix}/decode", response_model=DecodeResponse)
    def decode_endpoint(
        code: str = Query(..., description="Yoro string (e.g. CI-4H7A3B)"),
    ) -> DecodeResponse:
        if "-" not in code:
            raise HTTPException(
                status_code=400,
                detail="code must contain a dash (e.g. 'CI-4H7A3B')",
            )

        try:
            decoded = decode(code)
        except ValueError as e:
            raise HTTPException(status_code=400, detail=str(e))

        res = resolution(decoded["precision"], domain=decoded["domain"])
        nbrs = neighbors(code)

        return DecodeResponse(
            code=code.upper(),
            lat=decoded["lat"],
            lon=decoded["lon"],
            precision=decoded["precision"],
            domain=decoded["domain"],
            resolution_m=round(res, 2),
            bounds=BoundsSchema(**decoded["bounds"]),
            neighbors=nbrs,
        )

    @app.get(f"{prefix}/precisions", response_model=PrecisionsResponse)
    def precisions_endpoint(
        domain: str = Query("CI", description="Domain ISO code"),
        max_code_length: int = Query(10, ge=1, le=15, description="Max code characters"),
    ) -> PrecisionsResponse:
        domain = domain_for_country(domain)
        try:
            levels = precision_levels(domain=domain, max_code_length=max_code_length)
        except ValueError as e:
            raise HTTPException(status_code=400, detail=str(e))
        return PrecisionsResponse(
            domain=domain,
            levels=[PrecisionLevelSchema(**lv) for lv in levels],
        )

    @app.get(f"{prefix}/domains", response_model=DomainsResponse)
    def domains_endpoint() -> DomainsResponse:
        result = {}
        for key, dom in DOMAINS.items():
            result[key] = DomainSchema(
                name=dom["name"],
                bounds=BoundsSchema(
                    lat_min=dom["lat_min"],
                    lat_max=dom["lat_max"],
                    lon_min=dom["lon_min"],
                    lon_max=dom["lon_max"],
                ),
            )
        return DomainsResponse(domains=result)

    @app.get(f"{prefix}/health")
    def health() -> dict:
        return {"status": "ok", "version": __version__}

    return app

Pydantic Schemas

yoro.fastapi.app.BoundsSchema

Bases: BaseModel

Source code in src/yoro/fastapi/app.py
class BoundsSchema(BaseModel):
    lat_min: float
    lat_max: float
    lon_min: float
    lon_max: float

yoro.fastapi.app.EncodeResponse

Bases: BaseModel

Source code in src/yoro/fastapi/app.py
class EncodeResponse(BaseModel):
    code: str
    lat: float
    lon: float
    precision: int
    resolution_m: float
    bounds: BoundsSchema

yoro.fastapi.app.DecodeResponse

Bases: BaseModel

Source code in src/yoro/fastapi/app.py
class DecodeResponse(BaseModel):
    code: str
    lat: float
    lon: float
    precision: int
    domain: str
    resolution_m: float
    bounds: BoundsSchema
    neighbors: list[str]

yoro.fastapi.app.PrecisionLevelSchema

Bases: BaseModel

Source code in src/yoro/fastapi/app.py
class PrecisionLevelSchema(BaseModel):
    precision: int
    code_length: int
    grid_size: int
    total_cells: int
    resolution_m: float

yoro.fastapi.app.PrecisionsResponse

Bases: BaseModel

Source code in src/yoro/fastapi/app.py
class PrecisionsResponse(BaseModel):
    domain: str
    levels: list[PrecisionLevelSchema]