""" The Moonstream HTTP API """ import logging import time from typing import Dict from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from . import actions, data from .middleware import BroodAuthMiddleware, MoonstreamHTTPException from .routes.address_info import router as addressinfo_router from .routes.dashboards import router as dashboards_router from .routes.queries import router as queries_router from .routes.streams import router as streams_router from .routes.subscriptions import router as subscriptions_router from .routes.txinfo import router as txinfo_router from .routes.users import router as users_router from .routes.whales import router as whales_router from .settings import DOCS_TARGET_PATH, ORIGINS from .version import MOONSTREAMAPI_VERSION logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) tags_metadata = [ {"name": "addressinfo", "description": "Blockchain addresses public information."}, { "name": "labels", "description": "Labels for transactions, addresses with additional information.", }, {"name": "dashboards", "description": "Operations with user dashboards."}, {"name": "queries", "description": "Operations with user queries."}, {"name": "streams", "description": "Operations with data streams and filters."}, {"name": "subscriptions", "description": "Operations with user subscriptions."}, {"name": "time", "description": "Server timestamp endpoints."}, {"name": "tokens", "description": "Operations with user tokens."}, {"name": "txinfo", "description": "Ethereum transactions info."}, {"name": "users", "description": "Operations with users."}, {"name": "whales", "description": "Whales summaries"}, ] app = FastAPI( title=f"Moonstream API", description="Moonstream API endpoints.", version=MOONSTREAMAPI_VERSION, openapi_tags=tags_metadata, openapi_url="/openapi.json", docs_url=None, redoc_url=f"/{DOCS_TARGET_PATH}", ) whitelist_paths: Dict[str, str] = {} whitelist_paths.update( { "/ping": "GET", "/version": "GET", "/now": "GET", "/docs": "GET", "/openapi.json": "GET", "/streams/info": "GET", "/subscriptions/types": "GET", "/users": "POST", "/users/token": "POST", "/users/password/reset_initiate": "POST", "/users/password/reset_complete": "POST", } ) app.add_middleware(BroodAuthMiddleware, whitelist=whitelist_paths) app.add_middleware( CORSMiddleware, allow_origins=ORIGINS, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) @app.get("/ping", response_model=data.PingResponse) async def ping_handler() -> data.PingResponse: """ Check server status. """ return data.PingResponse(status="ok") @app.get("/version", response_model=data.VersionResponse) async def version_handler() -> data.VersionResponse: """ Get server version. """ return data.VersionResponse(version=MOONSTREAMAPI_VERSION) @app.get("/now", tags=["time"]) async def now_handler() -> data.NowResponse: """ Get server current time. """ return data.NowResponse(epoch_time=time.time()) @app.get("/status", response_model=data.StatusResponse) async def status_handler() -> data.StatusResponse: """ Find latest crawlers records with creation timestamp: - ethereum_txpool - ethereum_trending """ try: crawl_types_timestamp = actions.check_api_status() except actions.StatusAPIException: raise MoonstreamHTTPException(status_code=500) except Exception as e: logger.error(f"Unhandled status exception, error: {e}") raise MoonstreamHTTPException(status_code=500) return data.StatusResponse( ethereum_txpool_timestamp=crawl_types_timestamp["ethereum_txpool"], ethereum_trending_timestamp=crawl_types_timestamp["ethereum_trending"], ) app.include_router(addressinfo_router) app.include_router(streams_router) app.include_router(subscriptions_router) app.include_router(txinfo_router) app.include_router(users_router) app.include_router(whales_router) app.include_router(dashboards_router) app.include_router(queries_router)