from importlib.metadata import version from fastapi import APIRouter import jsonschema from pydantic import BaseModel import requests router = APIRouter() class Site(BaseModel): latitude: float longitude: float name: str @classmethod def from_inprov_site(cls, site: dict) -> 'Site': return cls( latitude=site['latitude'], longitude=site['longitude'], name=site['name'] ) class SiteList(BaseModel): sites: list[Site] class Router(BaseModel): fqdn: str site: str @classmethod def from_inprov_router(cls, router: dict) -> 'Router': return cls( fqdn = router['fqdn'], site = router['site'] ) class RouterList(BaseModel): routers: list[Router] class Endpoint(BaseModel): hostname: str interface: str @classmethod def from_inprov_endpoint(cls, endpoint: dict) -> 'Endpoint': return cls( hostname = endpoint['hostname'], interface = endpoint['interface'], ) class Overlays(BaseModel): speed: int @classmethod def from_inprov_overlays(cls, overlays: dict) -> 'Overlays': return cls( speed = overlays['speed'], ) class Service(BaseModel): sid: str name: str type: str endpoints: list[Endpoint] overlays: Overlays @classmethod def from_inprov_service(cls, service: dict) -> 'Service': return cls( sid = service['sid'], name = service['name'], type = service['type'], endpoints = list(map(Endpoint.from_inprov_endpoint, service['endpoints'])), overlays = Overlays.from_inprov_overlays(service['overlays']), ) class ServiceList(BaseModel): services: list[Service] INPROV_SITE_LIST_SCHEMA = { '$schema': 'https://json-schema.org/draft/2020-12/schema', 'definitions': { 'site': { 'type': 'object', 'properties': { 'name': {'type': 'string'}, 'latitude': {'type': 'number'}, 'longitude': {'type': 'number'}, }, 'required': ['name', 'latitude', 'longitude'], 'additionalProperties': True, }, }, 'type': 'array', 'items': {'$ref': '#/definitions/site'} } INPROV_ROUTER_LIST_SCHEMA = { '$schema': 'https://json-schema.org/draft/2020-12/schema', 'definitions': { 'router': { 'type': 'object', 'properties': { 'fqdn': {'type': 'string'}, 'site': {'type': 'string'}, }, 'required': ['fqdn', 'site'], }, }, 'type': 'array', 'items': {'$ref': '#/definitions/router'} } INPROV_SERVICE_LIST_SCHEMA = { '$schema': 'https://json-schema.org/draft/2020-12/schema', 'definitions': { 'endpoint': { 'type': 'object', 'properties': { 'hostname': {'type': 'string'}, 'interface': {'type': 'string'}, }, }, 'service': { 'type': 'object', 'properties': { 'sid': {'type': 'string'}, 'name': {'type': 'string'}, 'type': {'type': 'string'}, 'endpoints': { 'type': 'array', 'items': {'$ref': '#/definitions/endpoint'}, 'minItems': 1, }, 'overlays': { 'type': 'object', 'properties': { 'speed': {'type': 'number'}, }, 'required': ['speed'], }, }, 'required': ['sid', 'name', 'type', 'endpoints', 'overlays'], }, }, 'type': 'array', 'items': {'$ref': '#/definitions/service'} } @router.get("/sites") def get_sites() -> SiteList: """ handler for /sites """ # TODO: catch/handle the usual exceptions rv = requests.get( 'https://test-inprov01.geant.org/map/sites', headers={'Accept': 'application/json'}) rv.raise_for_status() site_list_json = rv.json() jsonschema.validate(site_list_json, INPROV_SITE_LIST_SCHEMA) return SiteList(sites=map(Site.from_inprov_site, site_list_json)) @router.get("/routers") def get_routers() -> RouterList: """ handler for /sites """ # TODO: catch/handle the usual exceptions rv = requests.get( 'https://test-inprov01.geant.org/map/routers', headers={'Accept': 'application/json'}) rv.raise_for_status() router_list_json = rv.json() jsonschema.validate(router_list_json, INPROV_ROUTER_LIST_SCHEMA) return RouterList(routers=map(Router.from_inprov_router, router_list_json)) @router.get("/trunks") def get_trunks() -> ServiceList: """ handler for /trunks """ # TODO: catch/handle the usual exceptions rv = requests.get( 'https://test-inprov01.geant.org/map/services/IP TRUNK', headers={'Accept': 'application/json'}) rv.raise_for_status() service_list_json = rv.json() jsonschema.validate(service_list_json, INPROV_SERVICE_LIST_SCHEMA) return ServiceList(services=map(Service.from_inprov_service, service_list_json))