Loading src/federation_manager/api/internal/identity.py 0 → 100644 +39 −0 Changes for src/federation_manager/api/internal/identity.py: 39 added lines, 0 removed lines. Original line number Diff line number Diff line from typing import Annotated from fastapi import APIRouter, Depends from pydantic import BaseModel from federation_manager.application.federation import LocalOperator from federation_manager.dependencies import get_local_operator router = APIRouter(prefix="/internal/identity", tags=["internal-identity"]) class MobileNetworkCodes(BaseModel): mcc: str mncs: list[str] class Identity(BaseModel): """What this OP sends every partner in CreateFederation; read from config, never stored.""" federation_id: str country_code: str mobile_network_codes: MobileNetworkCodes platform_caps: list[str] partner_status_link: str instance_status_link: str | None avail_zone_notif_link: str | None @router.get("") async def get_identity(local: Annotated[LocalOperator, Depends(get_local_operator)]) -> Identity: return Identity( federation_id=local.federation_id, country_code=local.country_code, mobile_network_codes=MobileNetworkCodes(mcc=local.mcc, mncs=list(local.mncs)), platform_caps=list(local.platform_caps), partner_status_link=local.partner_status_link, instance_status_link=local.instance_status_link, avail_zone_notif_link=local.avail_zone_notif_link, ) src/federation_manager/main.py +2 −0 Changes for src/federation_manager/main.py: 2 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ from federation_manager.api.ewbi.v1.onboarding import router as ewbi_onboarding_ from federation_manager.api.ewbi.v1.service import router as ewbi_service_router from federation_manager.api.ewbi.v1.zones import router as ewbi_zones_router from federation_manager.api.internal.federation import router as internal_federation_router from federation_manager.api.internal.identity import router as internal_identity_router from federation_manager.api.internal.partner_federations import ( router as internal_partner_federations_router, ) Loading Loading @@ -206,6 +207,7 @@ def create_app(lifespan: Lifespan[FastAPI] | None = None) -> FastAPI: app.include_router(ewbi_zones_router) app.include_router(ewbi_onboarding_router) app.include_router(internal_federation_router) app.include_router(internal_identity_router) app.include_router(internal_partner_federations_router) app.include_router(internal_partners_router) app.include_router(internal_zones_router) Loading tests/test_internal_identity.py 0 → 100644 +55 −0 Changes for tests/test_internal_identity.py: 55 added lines, 0 removed lines. Original line number Diff line number Diff line from collections.abc import AsyncIterator from contextlib import asynccontextmanager from fastapi import FastAPI from fastapi.testclient import TestClient from federation_manager.application.federation import LocalOperator from federation_manager.dependencies import get_local_operator from federation_manager.main import create_app IDENTITY = "/internal/identity" @asynccontextmanager async def _no_infra(app: FastAPI) -> AsyncIterator[None]: yield def _client(local: LocalOperator) -> TestClient: app = create_app(lifespan=_no_infra) app.dependency_overrides[get_local_operator] = lambda: local return TestClient(app) def test_returns_local_operator_identity_from_config() -> None: local = LocalOperator( federation_id="oop-i2cat", country_code="ES", mcc="214", mncs=("07", "01"), partner_status_link="https://fm.example/operatorplatform/federation/v1/callbacks/partner-status", instance_status_link="https://fm.example/operatorplatform/federation/v1/callbacks/instance-status", ) response = _client(local).get(IDENTITY) assert response.status_code == 200 assert response.json() == { "federation_id": "oop-i2cat", "country_code": "ES", "mobile_network_codes": {"mcc": "214", "mncs": ["07", "01"]}, "platform_caps": ["serviceAPIs"], "partner_status_link": local.partner_status_link, "instance_status_link": local.instance_status_link, "avail_zone_notif_link": None, } def test_default_config_identity_is_served() -> None: app = create_app(lifespan=_no_infra) body = TestClient(app).get(IDENTITY).json() assert body["federation_id"] == "oop-local" assert body["partner_status_link"].startswith("http") Loading
src/federation_manager/api/internal/identity.py 0 → 100644 +39 −0 Changes for src/federation_manager/api/internal/identity.py: 39 added lines, 0 removed lines. Original line number Diff line number Diff line from typing import Annotated from fastapi import APIRouter, Depends from pydantic import BaseModel from federation_manager.application.federation import LocalOperator from federation_manager.dependencies import get_local_operator router = APIRouter(prefix="/internal/identity", tags=["internal-identity"]) class MobileNetworkCodes(BaseModel): mcc: str mncs: list[str] class Identity(BaseModel): """What this OP sends every partner in CreateFederation; read from config, never stored.""" federation_id: str country_code: str mobile_network_codes: MobileNetworkCodes platform_caps: list[str] partner_status_link: str instance_status_link: str | None avail_zone_notif_link: str | None @router.get("") async def get_identity(local: Annotated[LocalOperator, Depends(get_local_operator)]) -> Identity: return Identity( federation_id=local.federation_id, country_code=local.country_code, mobile_network_codes=MobileNetworkCodes(mcc=local.mcc, mncs=list(local.mncs)), platform_caps=list(local.platform_caps), partner_status_link=local.partner_status_link, instance_status_link=local.instance_status_link, avail_zone_notif_link=local.avail_zone_notif_link, )
src/federation_manager/main.py +2 −0 Changes for src/federation_manager/main.py: 2 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ from federation_manager.api.ewbi.v1.onboarding import router as ewbi_onboarding_ from federation_manager.api.ewbi.v1.service import router as ewbi_service_router from federation_manager.api.ewbi.v1.zones import router as ewbi_zones_router from federation_manager.api.internal.federation import router as internal_federation_router from federation_manager.api.internal.identity import router as internal_identity_router from federation_manager.api.internal.partner_federations import ( router as internal_partner_federations_router, ) Loading Loading @@ -206,6 +207,7 @@ def create_app(lifespan: Lifespan[FastAPI] | None = None) -> FastAPI: app.include_router(ewbi_zones_router) app.include_router(ewbi_onboarding_router) app.include_router(internal_federation_router) app.include_router(internal_identity_router) app.include_router(internal_partner_federations_router) app.include_router(internal_partners_router) app.include_router(internal_zones_router) Loading
tests/test_internal_identity.py 0 → 100644 +55 −0 Changes for tests/test_internal_identity.py: 55 added lines, 0 removed lines. Original line number Diff line number Diff line from collections.abc import AsyncIterator from contextlib import asynccontextmanager from fastapi import FastAPI from fastapi.testclient import TestClient from federation_manager.application.federation import LocalOperator from federation_manager.dependencies import get_local_operator from federation_manager.main import create_app IDENTITY = "/internal/identity" @asynccontextmanager async def _no_infra(app: FastAPI) -> AsyncIterator[None]: yield def _client(local: LocalOperator) -> TestClient: app = create_app(lifespan=_no_infra) app.dependency_overrides[get_local_operator] = lambda: local return TestClient(app) def test_returns_local_operator_identity_from_config() -> None: local = LocalOperator( federation_id="oop-i2cat", country_code="ES", mcc="214", mncs=("07", "01"), partner_status_link="https://fm.example/operatorplatform/federation/v1/callbacks/partner-status", instance_status_link="https://fm.example/operatorplatform/federation/v1/callbacks/instance-status", ) response = _client(local).get(IDENTITY) assert response.status_code == 200 assert response.json() == { "federation_id": "oop-i2cat", "country_code": "ES", "mobile_network_codes": {"mcc": "214", "mncs": ["07", "01"]}, "platform_caps": ["serviceAPIs"], "partner_status_link": local.partner_status_link, "instance_status_link": local.instance_status_link, "avail_zone_notif_link": None, } def test_default_config_identity_is_served() -> None: app = create_app(lifespan=_no_infra) body = TestClient(app).get(IDENTITY).json() assert body["federation_id"] == "oop-local" assert body["partner_status_link"].startswith("http")