sageapi/sageapi/router.py
Hermes Agent 5c65c78752 feat: sageapi initial scaffold
- 36 files: module structure following module-development-spec
- 7 table definitions: users_cache, pricing_cache, llmage_cache, uapi_cache, sync_state, customer_balance, accounting_records
- Auth: dapi_auth + uapi_sign
- Sync: base_sync + entity-specific sync modules (users/pricing/uapi/llmage)
- Cache: LRU cache manager with TTL
- API: balance, accounting, users, pricing, health handlers
- Config: YAML config loader with env overrides
- Utils: HTTP client, crypto helpers
2026-05-20 17:53:53 +08:00

119 lines
3.1 KiB
Python

"""SageAPI route registration.
Defines all RESTful API endpoints and maps them to handler functions.
Routes are registered during module initialization.
Endpoint pattern: /api/v1/<resource>/<action>
"""
from __future__ import annotations
from typing import Any, Callable
class Router:
"""Simple route registry for SageAPI endpoints."""
def __init__(self) -> None:
self._routes: list[dict[str, Any]] = []
def register(
self,
method: str,
path: str,
handler: Callable,
auth: str = 'dapi',
description: str = '',
) -> None:
"""Register an API route.
Args:
method: HTTP method (GET, POST, PUT, DELETE).
path: URL path pattern, e.g. '/api/v1/balance'.
handler: Callable that handles the request.
auth: Authentication method ('dapi', 'uapi', 'none').
description: Human-readable description of the endpoint.
"""
self._routes.append({
'method': method.upper(),
'path': path,
'handler': handler,
'auth': auth,
'description': description,
})
def get_routes(self) -> list[dict[str, Any]]:
"""Return all registered routes."""
return list(self._routes)
def match(self, method: str, path: str) -> dict[str, Any] | None:
"""Find a route matching the given method and path."""
method = method.upper()
for route in self._routes:
if route['method'] == method and route['path'] == path:
return route
return None
# Global router instance
router = Router()
def register_routes() -> None:
"""Register all SageAPI API routes.
Called during module initialization to populate the router
with all available endpoints.
"""
from .api.health import health_check
from .api.balance import get_customer_balance
from .api.accounting import create_accounting_record, query_accounting_records
from .api.users import query_users
from .api.pricing import query_pricing
# Health check (no auth required)
router.register(
'GET', '/api/v1/health',
handler=health_check,
auth='none',
description='Health check endpoint',
)
# Customer balance
router.register(
'GET', '/api/v1/balance',
handler=get_customer_balance,
auth='dapi',
description='Query customer balance',
)
# Accounting
router.register(
'POST', '/api/v1/accounting',
handler=create_accounting_record,
auth='dapi',
description='Create an accounting record',
)
router.register(
'GET', '/api/v1/accounting',
handler=query_accounting_records,
auth='dapi',
description='Query accounting records',
)
# Users
router.register(
'GET', '/api/v1/users',
handler=query_users,
auth='dapi',
description='Query user information',
)
# Pricing
router.register(
'GET', '/api/v1/pricing',
handler=query_pricing,
auth='dapi',
description='Query pricing information',
)