Source code for aiida_restapi.main

"""Declaration of FastAPI application."""

import os
from json import JSONDecodeError

import pydantic as pdt
from aiida.common import exceptions as aiida_exceptions
from aiida.engine.daemon.client import DaemonException
from fastapi import APIRouter, FastAPI
from fastapi import exceptions as fastapi_exceptions
from fastapi.responses import RedirectResponse

from aiida_restapi.common import exceptions as restapi_exceptions
from aiida_restapi.config import API_CONFIG
from aiida_restapi.graphql import main
from aiida_restapi.jsonapi.utils import jsonapi_error
from aiida_restapi.routers import auth, computers, daemon, groups, nodes, querybuilder, server, submit, tests, users


[docs] def create_app() -> FastAPI: """Create the FastAPI application and include the routers. :return: The FastAPI application. :rtype: FastAPI """ read_only = os.getenv('AIIDA_RESTAPI_READ_ONLY') == '1' app = FastAPI() api_router = APIRouter(prefix=API_CONFIG['PREFIX']) api_router.add_route( '/', lambda _: RedirectResponse(url=api_router.url_path_for('endpoints')), ) for module in (auth, server, users, computers, groups, nodes, querybuilder, submit, daemon, tests): if read_router := getattr(module, 'read_router', None): api_router.include_router(read_router) if not read_only and (write_router := getattr(module, 'write_router', None)): api_router.include_router(write_router) api_router.add_route( f'{API_CONFIG["PREFIX"]}/graphql', main.app, methods=['POST'], ) app.include_router(api_router) app.exception_handlers |= { error_class: lambda req, exc, sc=status_code: jsonapi_error(req, exc, sc) for error_class, status_code in { JSONDecodeError: 400, aiida_exceptions.StoringNotAllowed: 403, aiida_exceptions.NotExistent: 404, FileNotFoundError: 404, aiida_exceptions.MultipleObjectsError: 409, aiida_exceptions.ValidationError: 422, pdt.ValidationError: 422, fastapi_exceptions.ValidationException: 422, aiida_exceptions.InvalidOperation: 422, aiida_exceptions.EntryPointError: 422, aiida_exceptions.MissingEntryPointError: 422, aiida_exceptions.DbContentError: 422, aiida_exceptions.InputValidationError: 422, aiida_exceptions.ContentNotExistent: 422, restapi_exceptions.SchemaNotSupported: 422, aiida_exceptions.UnsupportedSchemaError: 422, restapi_exceptions.QueryBuilderException: 422, aiida_exceptions.LicensingException: 451, restapi_exceptions.JsonApiException: 500, DaemonException: 500, Exception: 500, }.items() } app.exception_handlers[fastapi_exceptions.RequestValidationError] = nodes.unsupported_model_error_handler return app