Maillol / aiohttp-pydantic

Aiohttp View that validates request body and query sting regarding the annotations declared in the View method
MIT License
63 stars 20 forks source link

Using aiohttp_pydantic with aiohttp_cors gives errors in initialization #60

Closed Nniol closed 1 month ago

Nniol commented 1 month ago

Hi,

I have a website, which runs fine with CORS.

So I added in pydantic models and then aiohttp_pydantic , however if I use add_get it works fine but the the oas swagger page fails. If I use add_view then the swagger page (oas) works but cors gives an error:

    app = web.Application()
    oas.setup(app)
    app.on_shutdown.append(on_shutdown)
    app.router.add_get("/", redirect_to_api_doc)
    app.router.add_view("/json/ep1", EP1View)
    app.router.add_view("/json/ep2", EP2View)
    app.router.add_post("/offer", offer)

    cors = setup(
        app,
        defaults={
            os.getenv("FRONTEND_HOST"): ResourceOptions(
                allow_credentials=True, expose_headers="*", allow_headers="*"
            )
        },
    )

    for route in list(app.router.routes()):
        cors.add(route)

    web.run_app(
        app, access_log=None, host=args.host, port=args.port, ssl_context=ssl_context
    )

Gives

File "C:\..........airotc\fm_aiortc\Lib\site-packages\aiohttp_cors\urldispatcher_router_adapter.py", line 170, in add_preflight_handler
    raise ValueError("{!r} already has a '*' handler "
ValueError: <PlainResource  /json/effectors> already has a '*' handler for all methods

Using _addget insead of _addview in the above code gets the website running and the endpoints work however on using oas endpoint i get:

  File "C:\......................airotc\fm_aiortc\Lib\site-packages\aiohttp_pydantic\oas\view.py", line 92, in _add_http_method_to_oas
    handler = getattr(view, http_method)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: type object 'EP1View' has no attribute 'head'

EP1View defined as

class EP1View(PydanticView):
    async def get(self) -> Union[r200[ThingList], r500[Error]]:
        """Gets all valid things from another thing
        Tags: EP1

        Returns:
            Union[r200[ThingList],r500[Error]]: Valid Target List of an Error
        """
        _, list_json= csv_to_json(__________,________)
        return web.Response(content_type="application/json", text=list_json.json())
Maillol commented 1 month ago

aiohttp_cors works with aiohttp.web.view but PydanticView is a aiohttp.abc.AbstractView.

from aiohttp import web

class EP1View(web.View, PydanticView, aiohttp_cors.CorsViewMixin):

    cors_config = {
        "*": aiohttp_cors.ResourceOptions(
            allow_credentials=True,
            allow_headers="*",
        )
    }

    async def get(self) -> Union[r200[ThingList], r500[Error]]:
        ...

cors = aiohttp_cors.setup(app, ...)
cors.add(app.router.add_route("*", "/json/ep1", EP1View))
Nniol commented 1 month ago

Looks good.

Thank you for your help