Giter VIP home page Giter VIP logo

aiohttp-cors's People

Contributors

alefteris avatar asvetlov avatar dependabot-preview[bot] avatar dependabot[bot] avatar diogommartins avatar dreamsorcerer avatar edwardbetts avatar jettify avatar lemming avatar mgorny avatar pedrokiefer avatar pyup-bot avatar rutsky avatar sloria avatar vovanbo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aiohttp-cors's Issues

method '*' treated differently from others

I'm trying to use aiohttp-cors with aiohttp-graphl, which registers a route with the '*' method. I get

ValueError: <PlainResource 'graphql' /graphql> already has a '*' handler for all methods

Here is a small reproducer showing that '*' is different:

import asyncio
import aiohttp
import aiohttp_cors
from aiohttp.web_runner import GracefulExit


async def handler(request):
    return aiohttp.web.Response(text="Hello!")

app = aiohttp.web.Application()

cors = aiohttp_cors.setup(app)

routes = [{
    'method': 'GET',
    'path': '/test',
    'handler': handler,
    'name': 'test-good'
    }, {
    'method': '*',  # ValueError: <PlainResource 'another-route'  /another-route> already has a '*' handler for all methods                                           
    'path': '/another-route',
    'handler': handler,
    'name': 'another-route'
    }, ]

for route in routes:
    print('creating a route for method', route['method'])
    cors.add(
        app.router.add_route(
            method=route['method'],
            path=route['path'],
            handler=route['handler'],
            name=route['name']
        )
    )

web.run_app(app, host='localhost', port=8081)

which prints

creating a route for method GET
creating a route for method *
Traceback (most recent call last):
...
ValueError: <PlainResource 'another-route'  /another-route> already has a '*' handler for all methods

Reading the aiohttp-cors code I can see that _is_web_view() is False and then causes this confusing message? But only for method '*' and not GET.

I hacked the aiohttp-cors code to create separate routes for all the methods other than OPTIONS, and my program now runs successfully. But obviously that's not a fix.

TypeError: Use async with instead - error while using aiohttp 3.3.2

While using asyncio and aiohttp, I am getting this error on environment: Python 3, mac

Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 26 2018, 23:26:24) 
[Clang 6.0 (clang-600.0.57)] on darwin
Traceback (most recent call last):
  File "/Applications/PyCharm.app/Contents/helpers/pydev/pydev_run_in_console.py", line 52, in run_file
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "/Applications/PyCharm.app/Contents/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "/Users/divyanshushekhar/ScrapeFOLDER/Scraping/scrape-parallel.py", line 173, in <module>
    with aiohttp.ClientSession(loop=loop) as session:
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/aiohttp/client.py", line 806, in __enter__
    raise TypeError("Use async with instead")
TypeError: Use async with instead
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x111337b38>

Searching google gives the result https://stackoverflow.com/questions/46066629/proxy-broker-error-use-async-with-instead which says to install aiohttp version 2.0.0 which I did but got another issue #183

Use semantic versioning

I want to use semantic versioning for versioning aiohttp_cors.

E.g. release not yet stable version as 0.1.0, 0.2.0, ..., and subsequent stable versions as 1.0.0, 2.0.0, ..., according to semantic versioning rules.

Any objections?

/cc @asvetlov

GPG signatures for source validation

As we all know, today more than ever before, it is crucial to be able to trust our computing environments. One of the main difficulties that package maintainers of GNU/Linux distributions face, is the difficulty to verify the authenticity and the integrity of the source code. With GPG signatures it is possible for packagers to verify source code releases quickly and easily.

In order to securely package your software I am kindly requesting GPG signatures for the source tarballs. If you are not yet familiar with secure source code signing I recommend using GPGit which automates the process of secure source code signing and also has a quick start guide on GPG for learning how to use it manually.

Thanks in advance.

TypeError: issubclass() arg 1 must be a class when initialize my app with new relic

I am using aiohttp and initializing new relic in my __main__ file this way:

import newrelic.agent

if config.NEW_RELIC_SETTED:
    newrelic.agent.initialize()

# some initializations ...
web.run_app(app)

Api is the class that I am using aiohttp and initializing my session, web.Application, cors setup and so on

However, when I run my application the following error ocours:

Traceback (most recent call last):
  File "/home/gabrielly.silva/sieve/api_portal/app/__main__.py", line 12, in <module>
    Api().start()
  File "/home/gabrielly.silva/sieve/api_portal/app/api.py", line 41, in __init__
    self.register_routes()
  File "/home/gabrielly.silva/sieve/api_portal/app/api.py", line 90, in register_routes
    self.cors.add(route)
  File "/home/gabrielly.silva/sieve/api_portal/.venv/lib/python3.7/site-packages/aiohttp_cors/cors_config.py", line 263, in add
    return self._cors_impl.add(routing_entity, config)
  File "/home/gabrielly.silva/sieve/api_portal/.venv/lib/python3.7/site-packages/aiohttp_cors/cors_config.py", line 135, in add
    routing_entity, self._preflight_handler)
  File "/home/gabrielly.silva/sieve/api_portal/.venv/lib/python3.7/site-packages/aiohttp_cors/urldispatcher_router_adapter.py", line 195, in add_preflight_handler
    self.add_preflight_handler(route.resource, handler)
  File "/home/gabrielly.silva/sieve/api_portal/.venv/lib/python3.7/site-packages/aiohttp_cors/urldispatcher_router_adapter.py", line 165, in add_preflight_handler
    if _is_web_view(route_obj):
  File "/home/gabrielly.silva/sieve/api_portal/.venv/lib/python3.7/site-packages/aiohttp_cors/urldispatcher_router_adapter.py", line 95, in _is_web_view
    if isinstance(handler, type) and issubclass(handler, web.View):
  File "/usr/lib/python3.7/abc.py", line 143, in __subclasscheck__
    return _abc_subclasscheck(cls, subclass)
TypeError: issubclass() arg 1 must be a class

In the point that the function __is_web_view_ compares if handler is a subclasse of web.View, the handler is wrapped by new relic

$ type(handler)
<class 'newrelic.common.object_wrapper.FunctionWrapper'>

Is there a way that I can work around and solve this?

Thanks

Wildcard ports for localhost

I'm wondering if there is a way for me to use a regex to allow any localhost ports to be allowed?

Something like:

"http://localhost:[0-9]*": aiohttp_cors.ResourceOptions(
    expose_headers="*",
    allow_headers="*",
)

Routing hierarchy confusion with CORs

We just encountered a strange CORS bug that that we found a solution to. Our solution is this git commit:

diff --git a/prism_orchestrator_server/router.py b/prism_orchestrator_server/router.py
index 58dfd83..34262f7 100644
--- a/prism_orchestrator_server/router.py
+++ b/prism_orchestrator_server/router.py
@@ -106,6 +106,15 @@ def register_routes(container):
     visual_classes = router.add_resource("/visual-classes/")
     visual_classes.add_route("GET", resources["visual_classes"].index)
 
+    visual_class_merge = router.add_resource("/visual-classes/merge")
+    visual_class_merge.add_route("PUT", resources["visual_classes"].merge)
+
+    visual_class_move = router.add_resource("/visual-classes/move")
+    visual_class_move.add_route("PUT", resources["visual_classes"].move)
+
+    visual_class_extract = router.add_resource("/visual-classes/extract")
+    visual_class_extract.add_route("PUT", resources["visual_classes"].extract)
+
     visual_class = router.add_resource("/visual-classes/{visual_class_id}")
     visual_class.add_route("GET", resources["visual_classes"].get)
 
@@ -119,15 +128,6 @@ def register_routes(container):
     )
     visual_class_history.add_route("GET", resources["visual_classes"].get_history)
 
-    visual_class_merge = router.add_resource("/visual-classes/merge")
-    visual_class_merge.add_route("PUT", resources["visual_classes"].merge)
-
-    visual_class_move = router.add_resource("/visual-classes/move")
-    visual_class_move.add_route("PUT", resources["visual_classes"].move)
-
-    visual_class_extract = router.add_resource("/visual-classes/extract")
-    visual_class_extract.add_route("PUT", resources["visual_classes"].extract)
-
     router.add_route("GET", "/instances", redirect_perm("/instances/"))
     router.add_route("POST", "/instances", redirect_perm("/instances/"))
     instances = router.add_resource("/instances/")

Basically the problem was that /visual-classes/merge, /visual-classes/move and /visual-classes/extract routes were defined after /visual-classes/{visual_class_id}, and while aiohttp was able to handle this routing order with no problems, it appears that aiohttp-cors cannot.

That is aiohttp-cors fixes the GET for /visual-classes/{visual_class_id} and later when I try to enable CORS for /visual-classes/merge for PUT, it doesn't work, because it thinks that GET cors options have already been set for /visual-classes/{visual_class_id}.

After some debugging. The only solution was to move the more specific routes on top of the generic route. And then CORS worked beautifully.

I think this is a bug in aiohttp-cors, and it's particularly nasty because it's very silent, and when you think aiohttp routing works fine, but cors doesn't, it can be difficult to realize this.

can not use when aiohttp version > v1.0.5

[E 2016-11-18_11:45:00 server:208]
Traceback (most recent call last):
File "/Users/yihong/virtualenvs/py35/lib/python3.5/site-packages/aiohttp/server.py", line 265, in start
yield from self.handle_request(message, payload)
File "/Users/yihong/virtualenvs/py35/lib/python3.5/site-packages/aiohttp/web.py", line 96, in handle_request
resp = yield from handler(request)
File "/Users/yihong/virtualenvs/py35/lib/python3.5/site-packages/aiohttp_cors/cors_config.py", line 253, in _preflight_handler
request, origin, request_method)
File "/Users/yihong/virtualenvs/py35/lib/python3.5/site-packages/aiohttp_cors/urldispatcher_router_adapter.py", line 400, in get_preflight_request_config
requested_method, path)
TypeError: resolve() takes 2 positional arguments but 3 were given

can somebody update it?

Only 1 is allowed

Hello,
I am trying to work on a project, and I am facing an issue.
The problem is that when I am requesting a resource from the server, google chrome is saying that the "Access-Control-Allow-Origin' header contains multiple values"
This is my code

@asyncio.coroutine
def handler(request):
    return web.Response(
        text="Hello!",
        headers={
            "X-Custom-Server-Header": "Custom data",
        })


app = web.Application()

cors = aiohttp_cors.setup(app)

resource = cors.add(app.router.add_resource("/"))

route = cors.add(
    resource.add_route("POST", handler), {
        "*": aiohttp_cors.ResourceOptions(allow_methods="*",
                                          allow_headers=("X-Requested-With", "Content-Type", "AUTHORIZATION"),
                                          expose_headers="*",
                                          allow_credentials=False
                                          )
    })
if __name__ == '__main__':
    web.run_app(app, port=os.getenv("PORT"), host='0.0.0.0')

i am serving aiohttp over nginx

Consider making methods coroutine

Currently all public API can be expressed in the following example:

class RouterAdapter(AbstractRouterAdapter):
    def route_methods(self, route):
        """Returns list of HTTP methods that route handles"""

    def add_options_method_handler(self, route, handler):
        """Add OPTIONS method request handler that will be issued at the same
        paths as provided `route`.

        :return: Newly added route.
        """

router_adapter = RouterAdapter()
cors = aiohttp_cors.setup(app, router_adapter=router_adapter, ...)
cors.add(route, ...)

Is any of these methods may be required to be coroutines?

E.g. is it reasonable to assume that router.add_route() will never be coroutine for custom routers?

ValueError: Duplicate 'handler', already handled by <DynamicRoute 'handler' [GET] /v1/handler/ -> <function handler at 0x103c85378>

I get a ValueError when passing a name to router.add_route

        cors.add(
            app.router.add_route(method, full_url, handler, name=name),
            {
                '*': aiohttp_cors.ResourceOptions(
                    allow_credentials=True, expose_headers='*', allow_headers='*'
                )
            }

        )

Traceback:

    app = create_app(TestConfig)
api/app.py:27: in create_app
    routes.setup(app)
api/routes.py:26: in setup
    allow_credentials=True, expose_headers='*', allow_headers='*'
../../../miniconda/envs/rero/lib/python3.5/site-packages/aiohttp_cors/__init__.py:193: in add
    route, self._preflight_handler)
../../../miniconda/envs/rero/lib/python3.5/site-packages/aiohttp_cors/urldispatcher_router_adapter.py:45: in add_options_method_handler
    self._router.register_route(new_route)
../../../miniconda/envs/rero/lib/python3.5/site-packages/aiohttp/web_urldispatcher.py:459: in register_route
    .format(name, self._routes[name]))
E   ValueError: Duplicate 'should_i_release', already handled by <DynamicRoute 'should_i_release' [GET] /v1/should_i_release/{username}/{repo}/ -> <function should_i_release at 0x103c85378>

Removing name=name from the call to app.router.add_route removes the error.

Problems with aiohttp 3.0.1

This code works fine with aiohttp 2.3.10:

def setup_routes(app):
    app.router.add_routes(routes)
    setup_swagger(app,
                  api_base_url='/',
                  swagger_url='/api/doc',
                  description='API testing interface',
                  title='API',
                  api_version='2.0.0')

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

    for route in list(app.router.routes()):
        if not isinstance(route.resource, StaticResource):  # <<< WORKAROUND
            cors.add(route)

curl -H "Origin: http://example.com" -H "Access-Control-Request-Method: POST" -H "Access-Control-Request-Headers: X-Requested-With" -X OPTIONS --verbose localhost:8080/api/users

*   Trying ::1...
* TCP_NODELAY set
* connect to ::1 port 8080 failed: Connection refused
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> OPTIONS /api/users HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.58.0
> Accept: */*
> Origin: http://example.com
> Access-Control-Request-Method: POST
> Access-Control-Request-Headers: X-Requested-With
> 
< HTTP/1.1 200 OK
< Access-Control-Allow-Origin: http://example.com
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Methods: POST
< Access-Control-Allow-Headers: X-REQUESTED-WITH
< Content-Length: 0
< Content-Type: application/octet-stream
< Date: Wed, 14 Feb 2018 23:19:55 GMT
< Server: Python/3.6 aiohttp/2.3.10
<

But following (fixed OPTIONS error, adding routes differently) code fails for aiohttp 3.0.1:

    # This code fails with:
    # RuntimeError: Added route will never be executed, method OPTIONS is already registered
    # for route in list(app.router.routes()):
    #     if not isinstance(route.resource, StaticResource):  # <<< WORKAROUND
    #         cors.add(route)

    for resource in app.router.resources():
        cors.add(resource)

Same cURL request results in:

*   Trying ::1...
* TCP_NODELAY set
* connect to ::1 port 8080 failed: Connection refused
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> OPTIONS /api/users HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.58.0
> Accept: */*
> Origin: http://example.com
> Access-Control-Request-Method: POST
> Access-Control-Request-Headers: X-Requested-With
> 
< HTTP/1.1 403 Forbidden
< Content-Type: text/plain; charset=utf-8
< Content-Length: 99
< Date: Wed, 14 Feb 2018 23:21:01 GMT
< Server: Python/3.6 aiohttp/3.0.1
< 
* Connection #0 to host localhost left intact
CORS preflight request failed: request method 'POST' is not allowed for 'http://example.com' origin

Rename `aiohttp_cors` package to `aiohttp-cors`

See #43 for reasoning.

@asvetlov thanks for making the change c34202e.

In order to complete renameing we need to:

  • rename package in sources (c34202e)
  • rename GitHub repository
  • test that this change will not break anything (if it will, it's OK, but we need to explicitly state that)
  • add notice to change log
  • rename package on PyPI (how?)
  • publish renamed package (last time I released aiohttp-cors I worked on publishing to PyPI from Travis: it should be enough to push master branch with tag in order to force uploading on PyPI)

@asvetlov which parts you want to complete by yourself right now and which part can you want to delegate to me (during this week)?

CORS on static files

One of our applications requires CORS headers for static files. I'm currently using the default setup to add all of our APIs as being CORS enabled. The static route is added as add_static.

Am I missing something?

aiohttp cors breaks with new aiohttp 3.0 release

aiohttp cors setup breaks with

 File "/home/idwaker/Code/webapp/app/api/common/utils/loaders.py", line 43, in init_cors
    cors = aiohttp_cors.setup(app, defaults=CORS_DEFAULTS)
  File "/home/idwaker/.local/share/virtualenvs/webapp-69lhAx_Z/lib/python3.6/site-packages/aiohttp_cors/__init__.py", line 65, in setup
    cors = CorsConfig(app, defaults=defaults)
  File "/home/idwaker/.local/share/virtualenvs/webapp-69lhAx_Z/lib/python3.6/site-packages/aiohttp_cors/cors_config.py", line 247, in __init__
    self._resources_router_adapter)
  File "/home/idwaker/.local/share/virtualenvs/webapp-69lhAx_Z/lib/python3.6/site-packages/aiohttp_cors/cors_config.py", line 117, in __init__
    self._app.on_response_prepare.append(self._on_response_prepare)
  File "aiohttp/_frozenlist.pyx", line 97, in aiohttp._frozenlist.FrozenList.append
  File "aiohttp/_frozenlist.pyx", line 19, in aiohttp._frozenlist.FrozenList._check_frozen
RuntimeError: Cannot modify frozen list.

on latest 3.0 release of aiohttp

my init_cors is something like this

async def init_cors(app: web.Application):
    logger = get_logger(app['name'])
    cors = aiohttp_cors.setup(app, defaults=CORS_DEFAULTS)

    # add resources to cors
    for resource in list(app.router.resources()):
        if isinstance(resource, web.Resource):
            cors.add(resource)
    logger.info("Initialized CORS for {}".format(app['name']))

and i am loading init_cors on app.on_startup

The issue seems to occur when i defer cors setup to on_startup signal like

app.on_startup.append(init_cors)

But it works normally if i put the cors init code on app setup like

 # register routes here
    register_routes(app)

    cors = aiohttp_cors.setup(app, defaults=CORS_DEFAULTS)

    # add resources to cors
    for resource in list(app.router.resources()):
        if isinstance(resource, web.Resource):
            cors.add(resource)

Yum broken when RPM from this requirement with underscores.

Please never use underscores in python-packages names.

PEP-008 conatins

Python packages should also have short, all-lowercase names, although the use of underscores is discouraged.

We have a really problem. When our build system convert all dependencies to RPM (using FPM) yum is broken. We are can't use this package in our projects.

What is the best way to grant CORS for all subdomains dynamically?

I need to provide CORS permissions for many subdomains (i do not know all), that are located on known list of domains. E.g. *.example.com, *.corp-example.com, etc.

To allow CORS for any origin, i can do the following:

import aiohttp_cors
from aiohttp.web_app import Application

app = Application()
aiohttp_cors.setup(app, defaults={
    "*": aiohttp_cors.ResourceOptions(
        allow_credentials=True,
        expose_headers="*",
        allow_headers="*",
    )
})

for handler in handlers:
    # Register handler
    route = app.router.add_route('*', handler.URL_PATH, handler)
    
    # Handler should be handled with CORS
    app['aiohttp_cors'].add(route)

It works, but is not secure. What is simplest way to check if client origin meets some requirements (e.g. that origin matches ^[a-z0-9_-]+.example.com$) and if does not - to deny request?

I supposed that it is possible to extend some basic method to add such checks, or to provide lambda to aiohttp_cors.setup defaults, that would accept origin as input parameter and return appropriate config.

Class based views are not supported

When using web.View as the handler if the route being added for '*' then cors doesn't work because the server seems not to be able to find the OPTIONS. Not sure why that is, I didn't take the time to investigate but my guess is that the * end up taking priority and the routing goes to the * handler instead of the CORS handler.

0.7.0 + master: pytest is failing

I'm trying to package your module as an rpm package. So I'm using the typical build, install and test cycle used on building packages from non-root account.

  • "setup.py build"
  • "setup.py install --root </install/prefix>"
  • "pytest with PYTHONPATH pointing to sitearch and sitelib inside </install/prefix>

May I ask for help because few units are failing:

+ PYTHONPATH=/home/tkloczko/rpmbuild/BUILDROOT/python-aiohttp-cors-0.7.0-15.fc35.x86_64/usr/lib64/python3.8/site-packages:/home/tkloczko/rpmbuild/BUILDROOT/python-aiohttp-cors-0.7.0-15.fc35.x86_64/usr/lib/python3.8/site-packages
+ /usr/bin/pytest -ra --import-mode=importlib
=========================================================================== test session starts ============================================================================
platform linux -- Python 3.8.12, pytest-6.2.5, py-1.10.0, pluggy-0.13.1
benchmark: 3.4.1 (defaults: timer=time.perf_counter disable_gc=False min_rounds=5 min_time=0.000005 max_time=1.0 calibration_precision=10 warmup=False warmup_iterations=100000)
Using --randomly-seed=1568170391
rootdir: /home/tkloczko/rpmbuild/BUILD/aiohttp-cors-0.7.0, configfile: pytest.ini
plugins: forked-1.3.0, shutil-1.7.0, virtualenv-1.7.0, expect-1.1.0, flake8-1.0.7, timeout-1.4.2, betamax-0.8.1, freezegun-0.4.2, aspectlib-1.5.2, toolbox-0.5, rerunfailures-9.1.1, requests-mock-1.9.3, cov-2.12.1, flaky-3.7.0, benchmark-3.4.1, xdist-2.3.0, pylama-7.7.1, datadir-1.3.1, regressions-2.2.0, cases-3.6.3, xprocess-0.18.1, black-0.3.12, anyio-3.3.0, asyncio-0.15.1, subtests-0.5.0, isort-2.0.0, hypothesis-6.14.6, mock-3.6.1, profiling-1.7.0, randomly-3.8.0, Faker-8.12.1, nose2pytest-1.0.8, pyfakefs-4.5.1, tornado-0.8.1, twisted-1.13.3, aiohttp-0.3.0
collected 85 items / 2 errors / 83 selected

================================================================================== ERRORS ==================================================================================
_________________________________________________________ ERROR collecting tests/integration/test_real_browser.py __________________________________________________________
tests/integration/test_real_browser.py:30: in <module>
    from selenium import webdriver
/usr/lib/python3.8/site-packages/selenium/webdriver/__init__.py:18: in <module>
    from .firefox.webdriver import WebDriver as Firefox  # noqa
/usr/lib/python3.8/site-packages/selenium/webdriver/firefox/webdriver.py:28: in <module>
    from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver
/usr/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py:26: in <module>
    from .webelement import WebElement
/usr/lib/python3.8/site-packages/selenium/webdriver/remote/webelement.py:43: in <module>
    getAttribute_js = pkgutil.get_data(_pkg, 'getAttribute.js').decode('utf8')
/usr/lib64/python3.8/pkgutil.py:638: in get_data
    return loader.get_data(resource_name)
<frozen importlib._bootstrap_external>:1032: in get_data
    ???
E   FileNotFoundError: [Errno 2] No such file or directory: '/usr/lib/python3.8/site-packages/selenium/webdriver/remote/getAttribute.js'
_____________________________________________________________ ERROR collecting tests/unit/test_cors_config.py ______________________________________________________________
tests/unit/test_cors_config.py:30: in <module>
    class _View(web.View, CorsViewMixin):
tests/unit/test_cors_config.py:33: in _View
    def get(self):
/usr/lib64/python3.8/asyncio/coroutines.py:111: in coroutine
    warnings.warn('"@coroutine" decorator is deprecated since Python 3.8, use "async def" instead',
E   DeprecationWarning: "@coroutine" decorator is deprecated since Python 3.8, use "async def" instead
========================================================================= short test summary info ==========================================================================
ERROR tests/integration/test_real_browser.py - FileNotFoundError: [Errno 2] No such file or directory: '/usr/lib/python3.8/site-packages/selenium/webdriver/remote/getAtt...
ERROR tests/unit/test_cors_config.py - DeprecationWarning: "@coroutine" decorator is deprecated since Python 3.8, use "async def" instead
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 2 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
============================================================================ 2 errors in 0.64s =============================================================================
pytest-xprocess reminder::Be sure to terminate the started process by running 'pytest --xkill' if you have not explicitly done so in your fixture with 'xprocess.getinfo(<process_name>).terminate()'.

cant import aiohttp_cors

Hi,
i installed aiohttp_cors, but i cant import it. when i open the python interactive shell with python3 it works, but when i open it with pyrthon3.7 it does not. in my project i use python3.7, is there any way to make it work?

No CORS header on 404 responses ?

I've registered my routes that way:

    cors = aiohttp_cors.setup(app, defaults={
        "*": aiohttp_cors.ResourceOptions(
            allow_credentials=True,
            expose_headers="*",
            allow_headers="*",
            allow_methods="*"
        )
    })
    for route in app.router.routes():
        cors.add(route)

However, the JS fetch API raises a CORS exception if I access a unkown URL.

const resp = await fetch('https://myapi.example.com/unknown/url') // raises a TypeError exception

// This code is never reached, but it would if resp had the CORS headers
resp.status === 404
resp.ok === false

What would be the recommended way to add CORS headers to aiohttp built-in 404 response ?

Authentication middleware prevent CORS to be send correctly

I have an authentication middleware. In the middleware if the request method is OPTIONS I am returning the handler intact with the aim that aiohttp-cors handle the preflight request and return the correct response headers. However, the response headers are not being sent correctly by the signals.

It is quite possible that I am doing something wrong in my middleware, and the OPTIONS call need to be handled differently. This is my middleware:

@middleware
async def auth_middleware(request, handler):
    if isinstance(request.match_info.route, SystemRoute):  # eg. 404
        return await handler(request)

    if request.method == hdrs.METH_OPTIONS:
        return await handler(request)

    try:
        request['claims'] = await authenticate(request)
    except ValueError as e:
        raise HTTPUnauthorized(PayloadErrors(e.args[0]))

    return await handler(request)

I am creating the app as following:

def create_app():
    app = Application(middlewares=middlewares)
    setup_cors(app)
    return app

And this is how I am setting up cors:

def setup_cors(app: Application):
    resources = [
        'http://localhost:8100',
        'http://www.example.com',
    ]

    cors = aiohttp_cors.setup(app, defaults={
        resource: aiohttp_cors.ResourceOptions(
            allow_credentials=True,
            expose_headers='*',
            allow_methods='*',
            allow_headers='*',
        ) for resource in resources
    })

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

However, whenever I make a call I get the following error:

Unhandled exception
Traceback (most recent call last):
  File "/python3.7/site-packages/aiohttp/web_protocol.py", line 398, in start
    await resp.prepare(request)
  File "/python3.7/site-packages/aiohttp/web_response.py", line 299, in prepare
    await request._prepare_hook(self)
  File "/python3.7/site-packages/aiohttp/web_request.py", line 686, in _prepare_hook
    await app.on_response_prepare.send(self, response)
  File "/python3.7/site-packages/aiohttp/signals.py", line 35, in send
    await receiver(*args, **kwargs)
  File "/python3.7/site-packages/aiohttp_cors/cors_config.py", line 171, in _on_response_prepare
    assert hdrs.ACCESS_CONTROL_ALLOW_ORIGIN not in response.headers
AssertionError
Unhandled exception
Traceback (most recent call last):
  File "/python3.7/site-packages/aiohttp/web_protocol.py", line 398, in start
    await resp.prepare(request)
  File "/python3.7/site-packages/aiohttp/web_response.py", line 299, in prepare
    await request._prepare_hook(self)
  File "/python3.7/site-packages/aiohttp/web_request.py", line 686, in _prepare_hook
    await app.on_response_prepare.send(self, response)
  File "/python3.7/site-packages/aiohttp/signals.py", line 35, in send
    await receiver(*args, **kwargs)
  File "/python3.7/site-packages/aiohttp_cors/cors_config.py", line 171, in _on_response_prepare
    assert hdrs.ACCESS_CONTROL_ALLOW_ORIGIN not in response.headers
AssertionError

router_adapter.py

I believe it worth to be renamed into abc.py -- nice to have all ABC in the same place, router_adapter.py is not good name for all possible abcs.

RouterAdapter should be renamed into AbstractRouterAdapter or something like this.

We can do renaming without making a harm: the library is very young and most likely users don't use RouterAdapter and router_adapter.py explicitly.

Let's make renaming right now, later it will be more painful.

aiohttp 2.0+ support?

Just wanted to know if there is a particular issue why it was restricted to aiohttp <2.0. Was it simply not passing the unittests or someone just needs to thoroughly check unittests and compatibility?

DeprecationWarnings with Python 3.8: "@coroutine" decorator

=============================== warnings summary ===============================
tests/unit/test_cors_config.py:33
  .../tests/unit/test_cors_config.py:33: DeprecationWarning: "@coroutine" decorator is deprecated since Python 3.8, use "async def" instead
    def get(self):

tests/integration/test_main.py::test_dummy_setup[pyloop]
  /usr/lib64/python3.8/site-packages/aiohttp/web_server.py:53: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
    await asyncio.gather(*coros, loop=self._loop)

-- Docs: https://docs.pytest.org/en/latest/warnings.html
==================== 93 passed, 2 warnings in 2.61 seconds =====================

With current default tests config:

============================= test session starts ==============================
platform linux -- Python 3.8.0, pytest-5.2.2, py-1.8.0, pluggy-0.13.0
cachedir: .tox/py38/.pytest_cache
rootdir: /...aiohttp-cors, inifile: pytest.ini
plugins: cov-2.8.1, pylint-0.14.1, aiohttp-0.3.0
collected 91 items / 1 errors / 90 selected

==================================== ERRORS ====================================
_______________ ERROR collecting tests/unit/test_cors_config.py ________________
tests/unit/test_cors_config.py:30: in <module>
    class _View(web.View, CorsViewMixin):
tests/unit/test_cors_config.py:33: in _View
    def get(self):
/usr/lib64/python3.8/asyncio/coroutines.py:111: in coroutine
    warnings.warn('"@coroutine" decorator is deprecated since Python 3.8, use "async def" instead',
E   DeprecationWarning: "@coroutine" decorator is deprecated since Python 3.8, use "async def" instead
!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!
=============================== 1 error in 0.27s ===============================

Python 3.8 test_static_resource failure: TypeError: issubclass() arg 1 must be a class

Hello. I wish to run tests on Python 3.8, but I needed to fight some problems. This is how I was able to run them on current master:

diff --git a/pytest.ini b/pytest.ini
deleted file mode 100644
index e62899b..0000000
--- a/pytest.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[pytest]
-filterwarnings=
-    error
diff --git a/tox.ini b/tox.ini
index 9668d37..bb10832 100644
--- a/tox.ini
+++ b/tox.ini
@@ -5,6 +5,7 @@ envlist = py34, py35, check
 commands = {envpython} setup.py test
 deps =
     pytest
+    pytest-aiohttp
 
 [testenv:check]
 deps =
$ tox -e py38

And this is the error I get:

============================= test session starts ==============================
platform linux -- Python 3.8.0, pytest-5.2.2, py-1.8.0, pluggy-0.13.0
cachedir: .tox/py38/.pytest_cache
rootdir: /home/churchyard/Dokumenty/aiohttp-cors, inifile: tox.ini, testpaths: aiohttp_cors, tests
plugins: cov-2.8.1, pylint-0.14.1, aiohttp-0.3.0
collected 99 items

tests/doc/test_basic_usage.py ..                                         [  2%]
tests/integration/test_main.py ......................................... [ 43%]
.............................                                            [ 72%]
tests/integration/test_real_browser.py ssssss                            [ 78%]
tests/unit/test___about__.py .                                           [ 79%]
tests/unit/test_cors_config.py ....F...                                  [ 87%]
tests/unit/test_mixin.py .....                                           [ 92%]
tests/unit/test_preflight_handler.py .                                   [ 93%]
tests/unit/test_resource_options.py ...                                  [ 96%]
tests/unit/test_urldispatcher_router_adapter.py ...                      [100%]

=================================== FAILURES ===================================
_____________________________ test_static_resource _____________________________

app = <Application 0x7f735d3d6100>
cors = <aiohttp_cors.cors_config.CorsConfig object at 0x7f735d35c400>

    def test_static_resource(app, cors):
        """Test adding static resource."""
        assert len(app.router.keys()) == 0
        app.router.add_static(
            "/file", "/", name="dynamic_named_route")
        assert len(app.router.keys()) == 1
        for resource in list(app.router.resources()):
>           if issubclass(resource, web.StaticResource):

tests/unit/test_cors_config.py:106: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

cls = <class 'aiohttp.web_urldispatcher.StaticResource'>
subclass = <StaticResource 'dynamic_named_route' /file -> PosixPath('/')>

    def __subclasscheck__(cls, subclass):
        """Override for issubclass(subclass, cls)."""
>       return _abc_subclasscheck(cls, subclass)
E       TypeError: issubclass() arg 1 must be a class

.tox/py38/lib64/python3.8/abc.py:102: TypeError
=============================== warnings summary ===============================
tests/unit/test_cors_config.py:33
  /home/churchyard/Dokumenty/aiohttp-cors/tests/unit/test_cors_config.py:33: DeprecationWarning: "@coroutine" decorator is deprecated since Python 3.8, use "async def" instead
    def get(self):

tests/integration/test_main.py::test_dummy_setup[pyloop]
  /home/churchyard/Dokumenty/aiohttp-cors/.tox/py38/lib/python3.8/site-packages/aiohttp/web_server.py:53: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
    await asyncio.gather(*coros, loop=self._loop)

-- Docs: https://docs.pytest.org/en/latest/warnings.html
============= 1 failed, 92 passed, 6 skipped, 2 warnings in 5.91s ==============

allow_headers argument probably not working

i have tried to use allow_headers argument. And it seem that it doesn't work.

'*': aiohttp_cors.ResourceOptions(
        expose_headers="*",
        allow_headers=("X-Requested-With", "Content-Type"),
    )

my options request is:

http OPTIONS http://localhost:9001/api/v1/hello_world Origin:'http://localhost:9001' Access-Control-Request-Method:GET X-Requested-With12:httpie

and response is:

HTTP/1.1 200 OK
Access-Control-Allow-Methods: GET
Access-Control-Allow-Origin: http://localhost:9001
Content-Length: 0
Content-Type: application/octet-stream
Date: Wed, 25 Oct 2017 10:39:40 GMT
Server: Python/3.6 aiohttp/2.2.3

I believe that response should be 403 with  not allowed header.
Am i right?

OOP view

Can I create views in OOP style? How in tornado or in Django CBV.

Cors and IOS Safari

Hello!
Cors wont working on Apple devices - cors is not working. It works only if i manually disable CORS Tracking Protection in device settings.
What's wrong with apple?

Use of type annotations

@asvetlov:

Say, I doubt using types in annotations make sense.
They are neither checked in runtime as I see nor pep 484 compatible.

@asvetlov, can you explain why they are not PEP 484 compatible?

E.g. this looks like a proper type annotation:

from aiohttp import web
...
class CorsConfig:
...
def setup(app: web.Application, *, defaults: dict=None) -> CorsConfig:

There should be collections.abc.Mapping instead of dict but other parts looks correct to me.

Type annotations yet not used at runtime, but can be used right now for documentation purposes and as hints for IDEs like PyCharm (PyCharm right now has limited support of them).

Is it possible to return `Access-Control-Allow-Origin: *` in response to preflight request instead of existing `Origin` header?

I'm developing figma plugin and figma uploads plugins html from local filesystem, in this case, all requests will have 'Origin: null' header and thus Access-Control-Allow-Origin will have null, which, in turn, leads to CORS error in browser. I've checked preflight_handler.py source and did not found any way to change usage of existing Origin header value to externally defined one(*). Am I missing something?

403 Error when aiohttp resources are not fully merged

Aiohttp merges resources, when they are added in the correct order:
screenshot from 2019-02-22 15-40-04

When using aiohttp-cors, resources have to be fully merged, or you end up having 2 resources for the same path, one for the GET method one for the POST, but the latter will not be considered when aiohttp-cors answers the OPTIONS request. It seems that aiohttp-cors supports only a single resource per path.

It would be nice if a hint about this could be added to the docs, if the support of multiple resources for the same path is too complex.

Requirements:

aiohttp==3.0.6
aiohttp_cors==0.7.0

Replicate:

def handler():
    pass

app.router.add_route('POST', '/a', handler)
app.router.add_route('GET', '/b', handler)
app.router.add_route('PUT', '/a', handler)

# Configure default CORS settings.
cors = aiohttp_cors.setup(app, defaults={
    "*": aiohttp_cors.ResourceOptions(
    allow_credentials=True,
    expose_headers="*",
    allow_headers="*")
})

# Configure CORS on all routes.
for route in list(app.router.routes()):
    cors.add(route)

SyntaxError: aiohttp import does not work

While trying to use asyncio and aiohttp , I am getting this error.
Environment: Python 3, Mac

Traceback (most recent call last):
  File "/Applications/PyCharm.app/Contents/helpers/pydev/pydev_run_in_console.py", line 52, in run_file
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "/Applications/PyCharm.app/Contents/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "/Users/divyanshushekhar/ScrapeAMAZON/Scraping/scrape-consistency.py", line 10, in <module>
    import aiohttp
  File "/Applications/PyCharm.app/Contents/helpers/pydev/_pydev_bundle/pydev_import_hook.py", line 19, in do_import
    module = self._system_import(name, *args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/aiohttp/__init__.py", line 6, in <module>
    from .client import *  # noqa
  File "/Applications/PyCharm.app/Contents/helpers/pydev/_pydev_bundle/pydev_import_hook.py", line 19, in do_import
    module = self._system_import(name, *args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/aiohttp/client.py", line 15, in <module>
    from . import connector as connector_mod
  File "/Applications/PyCharm.app/Contents/helpers/pydev/_pydev_bundle/pydev_import_hook.py", line 19, in do_import
    module = self._system_import(name, *args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/aiohttp/connector.py", line 11, in <module>
    from . import hdrs, helpers
  File "/Applications/PyCharm.app/Contents/helpers/pydev/_pydev_bundle/pydev_import_hook.py", line 19, in do_import
    module = self._system_import(name, *args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/aiohttp/helpers.py", line 29
    ensure_future = asyncio.async
                                ^
SyntaxError: invalid syntax

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.