Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 5 additions & 9 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,10 @@ that you want to expose:

.. code-block:: python

import asyncio
from aiohttp import web
import aiohttp_cors

@asyncio.coroutine
def handler(request):
async def handler(request):
return web.Response(
text="Hello!",
headers={
Expand Down Expand Up @@ -351,24 +349,22 @@ You can also use ``CorsViewMixin`` on ``web.View``:
class CorsView(web.View, CorsViewMixin):

cors_config = {
"*": ResourceOption(
"*": ResourceOptions(
allow_credentials=True,
allow_headers="X-Request-ID",
)
}

@asyncio.coroutine
def get(self):
async def get(self):
return web.Response(text="Done")

@custom_cors({
"*": ResourceOption(
"*": ResourceOptions(
allow_credentials=True,
allow_headers="*",
)
})
@asyncio.coroutine
def post(self):
async def post(self):
return web.Response(text="Done")

cors = aiohttp_cors.setup(app, defaults={
Expand Down
4 changes: 2 additions & 2 deletions aiohttp_cors/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"""CORS support for aiohttp."""

from collections.abc import Mapping
from typing import Any, Union
from typing import Any, Optional, Union

from aiohttp import web

Expand Down Expand Up @@ -56,7 +56,7 @@
def setup(
app: web.Application,
*,
defaults: Mapping[str, Union[ResourceOptions, Mapping[str, Any]]] = None
defaults: Optional[Mapping[str, Union[ResourceOptions, Mapping[str, Any]]]] = None
) -> CorsConfig:
"""Setup CORS processing for the application.

Expand Down
21 changes: 13 additions & 8 deletions aiohttp_cors/cors_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import collections
import warnings
from collections.abc import Mapping
from typing import Any, Union
from typing import Any, Optional, Union

from aiohttp import hdrs, web

Expand Down Expand Up @@ -45,8 +45,8 @@


def _parse_config_options(
config: Mapping[str, Union[ResourceOptions, Mapping[str, Any]]] = None,
):
config: Optional[Mapping[str, Union[ResourceOptions, Mapping[str, Any]]]] = None,
) -> Any:
"""Parse CORS configuration (default or per-route)

:param config:
Expand Down Expand Up @@ -113,7 +113,7 @@ def __init__(self, app: web.Application, router_adapter: AbstractRouterAdapter):
# headers on non-preflight requests.
self._app.on_response_prepare.append(self._on_response_prepare)

def add(self, routing_entity, config: _ConfigType = None):
def add(self, routing_entity: Any, config: Optional[_ConfigType] = None) -> Any:
"""Enable CORS for specific route or resource.

If route is passed CORS is enabled for route's resource.
Expand Down Expand Up @@ -216,9 +216,9 @@ def __init__(
self,
app: web.Application,
*,
defaults: _ConfigType = None,
router_adapter: AbstractRouterAdapter = None,
):
defaults: Optional[_ConfigType] = None,
router_adapter: Optional[AbstractRouterAdapter] = None,
) -> None:
"""Construct CORS configuration.

:param app:
Expand All @@ -245,7 +245,12 @@ def __init__(

self._cors_impl = _CorsConfigImpl(app, router_adapter)

def add(self, routing_entity, config: _ConfigType = None, webview: bool = False):
def add(
self,
routing_entity: Any,
config: Optional[_ConfigType] = None,
webview: bool = False,
) -> Any:
"""Enable CORS for specific route or resource.

If route is passed CORS is enabled for route's resource.
Expand Down
9 changes: 7 additions & 2 deletions aiohttp_cors/mixin.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import collections
from typing import Any, Callable, Mapping, TypeVar, Union

from .preflight_handler import _PreflightHandler
from .resource_options import ResourceOptions

_ConfigArg = Mapping[str, Union[ResourceOptions, Mapping[str, Any]]]
_F = TypeVar("_F", bound=Callable[..., Any])

def custom_cors(config):
def wrapper(function):

def custom_cors(config: _ConfigArg) -> Callable[[_F], _F]:
def wrapper(function: _F) -> _F:
name = f"{function.__name__}_cors_config"
setattr(function, name, config)
return function
Expand Down
32 changes: 18 additions & 14 deletions aiohttp_cors/resource_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@
import collections
import collections.abc
import numbers
from typing import Any, FrozenSet, Optional, Sequence, Union

__all__ = ("ResourceOptions",)


def _is_proper_sequence(seq):
def _is_proper_sequence(seq: Any) -> bool:
"""Returns is seq is sequence and not string."""
return isinstance(seq, collections.abc.Sequence) and not isinstance(seq, str)

Expand All @@ -45,12 +46,12 @@ class ResourceOptions(
def __init__(
self,
*,
allow_credentials=False,
expose_headers=(),
allow_headers=(),
max_age=None,
allow_methods=None
):
allow_credentials: bool = False,
expose_headers: Union[str, Sequence[str]] = (),
allow_headers: Union[str, Sequence[str]] = (),
max_age: Optional[int] = None,
allow_methods: Optional[Union[str, Sequence[str]]] = None
) -> None:
"""Construct resource CORS options.

Options will be normalized.
Expand Down Expand Up @@ -93,12 +94,12 @@ def __init__(
def __new__(
cls,
*,
allow_credentials=False,
expose_headers=(),
allow_headers=(),
max_age=None,
allow_methods=None
):
allow_credentials: bool = False,
expose_headers: Union[str, Sequence[str]] = (),
allow_headers: Union[str, Sequence[str]] = (),
max_age: Optional[int] = None,
allow_methods: Optional[Union[str, Sequence[str]]] = None
) -> "ResourceOptions":
"""Normalize source parameters and store them in namedtuple."""

if not isinstance(allow_credentials, bool):
Expand All @@ -109,6 +110,7 @@ def __new__(
_allow_credentials = allow_credentials

# `expose_headers` is either "*", or sequence of strings.
_expose_headers: Union[str, FrozenSet[str]]
if expose_headers == "*":
_expose_headers = expose_headers
elif not _is_proper_sequence(expose_headers):
Expand All @@ -128,6 +130,7 @@ def __new__(
_expose_headers = frozenset()

# `allow_headers` is either "*", or set of headers in upper case.
_allow_headers: Union[str, FrozenSet[str]]
if allow_headers == "*":
_allow_headers = allow_headers
elif not _is_proper_sequence(allow_headers):
Expand All @@ -149,6 +152,7 @@ def __new__(
)
_max_age = max_age

_allow_methods: Optional[Union[str, FrozenSet[str]]]
if allow_methods is None or allow_methods == "*":
_allow_methods = allow_methods
elif not _is_proper_sequence(allow_methods):
Expand All @@ -169,7 +173,7 @@ def __new__(
allow_methods=_allow_methods,
)

def is_method_allowed(self, method):
def is_method_allowed(self, method: str) -> bool:
if self.allow_methods is None:
return False

Expand Down