from aiohttp import web from aiohttp_apispec import docs, json_schema, querystring_schema from apollo_utils.service.clients.aiohttp.utils.response import dump_response_schema from apollo_utils.service.exceptions import BadRequest, NotFound from server.constants.core import BASE_API_PREFIX from server.db.models.core import Application from server.domains import applications as app_dom from server.schemas.applications import ApplicationResponse, Applications, ApplicationsBulk router = web.RouteTableDef() @router.get(BASE_API_PREFIX + "/service/applications/") @docs( tags=["service", "application"], summary="Get an application by slug.", ) @querystring_schema(Applications.Get.Request) @dump_response_schema(Applications.Get.Response, apply=True) async def get_application(request: web.Request) -> web.Response: params = request["querystring"] app = await Application.get(slug=params["slug"]) if not app: raise NotFound(f"An application with the slug {params['slug']} is not found.") return app @router.post(BASE_API_PREFIX + "/service/applications/") @docs( tags=["service", "application"], summary="Create an application.", ) @json_schema(Applications.Create.Request) @dump_response_schema(Applications.Create.Response, code=201, apply=True) async def create_application(request: web.Request) -> web.Response: params = request["json"] app = await Application.get(slug=params["slug"], _active_only=False) if app: if app.is_active: raise BadRequest(f"An application with the slug={params['slug']} already exists.") raise BadRequest( f"An application with the slug={params['slug']} does not exist, but the service still store " f"data related to it. So select another slug or contact the team if you want to " f"restore the old one." ) return await Application.create(params) @router.put(BASE_API_PREFIX + "/service/applications/") @docs( tags=["service", "application"], summary="Update an application.", ) @json_schema(Applications.Update.Request) @dump_response_schema(Applications.Update.Response, apply=True) async def update_application(request: web.Request) -> web.Response: params = request["json"] slug = params.pop("slug") app = await Application.get(slug=slug) if not app: raise BadRequest(f"An application with the slug {params['slug']} does not exists exists.") settings, types = params.get("settings") or app.settings, params.get("types") or app.types if not app_dom.is_valid(settings, types): raise BadRequest(f"Settings and types are not consistent: settings={settings}, types={types}") return await Application.update(params, slug=slug, return_source=Application) @router.delete(BASE_API_PREFIX + "/service/applications/") @docs( tags=["service", "application"], summary="Delete an application.", ) @querystring_schema(Applications.Delete.Request) async def delete_application(request: web.Request) -> web.Response: slug = request["querystring"]["slug"] result = await Application.delete(slug=slug) if not result: raise NotFound(f"Application with the slug={slug} does not exist.") return web.Response() # Test handler, will be removed in final version @router.post(BASE_API_PREFIX + "/service/applications/bulk/") @docs( tags=["service", "application"], ) @json_schema(ApplicationsBulk.Update.Request) @dump_response_schema(ApplicationResponse(many=True), code=201, apply=False) async def create_application_bulk(request: web.Request) -> web.Response: params = request["json"] # result = await Application.create_bulk(params["data"]) await Application.update_bulk(params["data"], bind_values=("name",), bind_filters=("slug",)) return web.Response() @router.get(BASE_API_PREFIX + "/service/applications/bulk/") @docs( tags=["service", "application"], summary="Get an application by slug.", ) @querystring_schema(ApplicationsBulk.Get.Request) @dump_response_schema(ApplicationResponse(many=True), apply=True) async def get_application_bulk(request: web.Request) -> web.Response: params = request["querystring"] apps, count = await Application.list( filters=[Application.slug.in_(params["slug"])], limit=params.get("limit"), offset=params.get("offset") ) return apps