ASGI middleware for applying CORS headers to an ASGI application.
pip install asgi-cors
Some background on CORS
fetch() calls that can retrieve data from the application.
See MDN's CORS article for more background.
The easiest way to allow scripts running on other domains to access data from an application is to add the following HTTP header:
This will allow scripts running on ANY domain to make
fetch() calls against the application. For public data this is often fine, but there are situations where this may not be what you want to do: one example might be code that runs behind a VPN and needs to allow specific, trusted hosts to load data without opening itself up to every site on the internet.
For these cases, the server needs to inspect the Origin header from the client and return that Origin in the above header. For example, an incoming request from
http://localhost:8000 might be judged as trusted - in which case the application server needs to reply like so:
Note that the
Access-Control-Allow-Origin header can only return a single value. This means that if you want to allow requests from multiple origins you need to dynamically whitelist those origins and return a different header value depending on the incoming request.
How to use this middleware
We will assume you have an existing ASGI app, in a variable called
First, import the
from asgi_cors import asgi_cors
To enable CORS headers for everywhere (by adding the
Access-Control-Allow-Origin: * header to every request), do this:
app = asgi_cors(app, allow_all=True)
If you wish to only allow it from a specific host, use the following:
app = asgi_cors(app, hosts=[ "https://www.example.com" ])
fetch("https://your-api.com/").then(r => r.json()).then(d => console.log(d))
You can include multiple hosts in the list.
Finally, if you want to open your application up to requests from a wildcard-defined selection of hosts, use the following:
app = asgi_cors(app, host_wildcards=[ "http://localhost:800*", "http://*.example.com" ])
If you need to do something more complicated that cannot be expressed using the
host_wildcards= parameters, you can use
callback= to specify a custom function. For example:
def validate_origin(origin): return origin.startswith("https://") app = asgi_cors(app, callback=validate_origin)
Your callback function will be passed the
Origin header that was passed in by the browser.
Using the middleware as a decorator
If you are defining your ASGI application directly as a function, you can use the
asgi_cors_decorator function decorator like so:
from asgi_cors import asgi_cors_decorator @asgi_cors_decorator(allow_all=True) async def my_asgi_app(scope, recieve, send): # Your app goes here