Skip to content

Commit

Permalink
Compatibility with Sanic v21.12, remove usage of Sanic-Plugin-Toolkit
Browse files Browse the repository at this point in the history
Simplified decorator code
Update examples
update readme
update changelog
bump copyright years
  • Loading branch information
ashleysommer committed Jan 4, 2022
1 parent 2d4f40b commit a8d4fb1
Show file tree
Hide file tree
Showing 28 changed files with 229 additions and 217 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
# Change Log
## 2.0.0
- Big changes for Sanic v21.12.0
- Remove the use of Sanic-Plugin-Toolkit.
- This plugin is simple enough that it doesn't need it
- Sanic-Plugin-Toolkit has issues with compatibility in Sanic v21.12.0+
- Add ability to use sanic-cors as a Sanic-Ext extension (experimental for now...)

## 1.0.1
- Fix exception handler compatibility with Sanic v21.9.0
- Bump min SPTK version requirement to v1.2.0
Expand Down
37 changes: 14 additions & 23 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ credential'ed requests, and please make sure you add some sort of
`CSRF <http://en.wikipedia.org/wiki/Cross-site_request_forgery>`__
protection before doing so!

**Sept Notice:**
Please upgrade to Sanic-CORS v1.0.1 if you need compatibility with Sanic v21.9+
**December 2021 Notice:**
If you need compatibility with Sanic v21.12+, upgrade to Sanic-CORS v2.0

**March Notice:**
Please upgrade to Sanic-CORS v1.0.0 if you need compatibility with Sanic v21.3+ (and don't forget to replace SPF with SPTK)
**Sept 2021 Notice:**
Please upgrade to Sanic-CORS v1.0.1 if you need compatibility with Sanic v21.9,<21.12

**Older Notice:**
Please upgrade to Sanic-CORS v1.0.0 if you need compatibility with Sanic v21.3+ (and don't forget to replace SPF with SPTK)
Please upgrade to Sanic-CORS v0.10.0 if you need compatibility with Sanic v19.12+. See `here <https://github.com/huge-success/sanic/issues/1749#issuecomment-571881532>`_ for more details.

Installation
Expand Down Expand Up @@ -92,22 +93,22 @@ with. Simply add ``@cross_origin(app)`` below a call to Sanic's
def hello_world(request):
return text("Hello, cross-origin-world!")
SPTK Usage
~~~~~~~~~~~~
Sanic-Ext Usage
~~~~~~~~~~~~~~~

Sanic-CORS uses Sanic-Plugin-Toolkit behind the scenes.
That means you can use the SPTK api to load the plugin for you if you are
orchestrating and application with multiple SPTK plugins.
Sanic-CORS can use Sanic-Ext to load the plugin for you.
( But you need to make sure to disable the built-in sanic-ext CORS support too)

.. code:: python
from sanic import Sanic
from sanic.response import text
from sanic_plugin_toolkit import SanicPluginRealm
from sanic_cors.extension import cors
from sanic_ext import Extend
from sanic_cors.extension import CORS
app = Sanic(__name__)
realm = SanicPluginRealm(app)
realm.register_plugin(cors, automatic_options=True)
CORS_OPTIONS = {"resources": r'/*', "origins": "*", "methods": ["GET", "POST", "HEAD", "OPTIONS"]}
# Disable sanic-ext built-in CORS, and add the Sanic-CORS plugin
Extend(app, extensions=[CORS], config={"CORS": False, "CORS_OPTIONS": CORS_OPTIONS})
@app.route("/", methods=['GET', 'OPTIONS'])
def hello_world(request):
Expand Down Expand Up @@ -172,16 +173,6 @@ Note: For the third example, you must use ``@route()``, rather than
work on that route, even though the decorator is handling the ``OPTIONS``
response.

Troubleshooting
---------------

If things aren't working as you expect, enable logging to help understand
what is going on under the hood, and why.

.. code:: python
logging.getLogger('sanic_cors').level = logging.DEBUG
Tests
-----

Expand Down
10 changes: 3 additions & 7 deletions examples/app_based_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
This is a tiny Sanic Application demonstrating Sanic-CORS, making it simple
to add cross origin support to your sanic app!
:copyright: (c) 2020 by Ashley Sommer (based on flask-cors by Cory Dolphin).
:copyright: (c) 2022 by Ashley Sommer (based on flask-cors by Cory Dolphin).
:license: MIT/X11, see LICENSE for more details.
"""
from sanic import Sanic
Expand All @@ -22,15 +22,11 @@


app = Sanic('SanicCorsAppBasedExample')
logging.basicConfig(level=logging.INFO)

# To enable logging for sanic-cors,
logging.getLogger('sanic_cors').level = logging.DEBUG

# One of the simplest configurations. Exposes all resources matching /api/* to
# CORS and allows the Content-Type header, which is necessary to POST JSON
# cross origin.
CORS(app, resources=r'/api/*')
CORS(app, resources=r'/api/*', origins="*", methods=["GET", "POST", "HEAD", "OPTIONS"])


@app.route("/")
Expand All @@ -51,7 +47,7 @@ def hello_world(request):
</html>
''')

@app.route("/api/v1/users/", methods=['GET', 'OPTIONS'])
@app.route("/api/v1/users/", methods=['GET'])
def list_users(request):
'''
Since the path matches the regular expression r'/api/*', this resource
Expand Down
2 changes: 1 addition & 1 deletion examples/blueprints_based_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
This is a tiny Sanic Application demonstrating Sanic-Cors, making it simple
to add cross origin support to your sanic app!
:copyright: (c) 2020 by Ashley Sommer (based on flask-cors by Cory Dolphin).
:copyright: (c) 2022 by Ashley Sommer (based on flask-cors by Cory Dolphin).
:license: MIT/X11, see LICENSE for more details.
"""
from sanic import Sanic, Blueprint
Expand Down
42 changes: 22 additions & 20 deletions examples/app_config_example.py → examples/sanic_ext_example.py
Original file line number Diff line number Diff line change
@@ -1,45 +1,47 @@
"""
Sanic-Cors example
===================
This is a tiny Sanic Application demonstrating Sanic-Cors, making it simple
This is a tiny Sanic Application demonstrating Sanic-CORS, making it simple
to add cross origin support to your sanic app!
:copyright: (c) 2020 by Ashley Sommer (based on flask-cors by Cory Dolphin).
:copyright: (c) 2022 by Ashley Sommer (based on flask-cors by Cory Dolphin).
:license: MIT/X11, see LICENSE for more details.
"""
from sanic import Sanic
from sanic.response import json, text
from sanic.response import json, html, text
from sanic.exceptions import ServerError
from sanic_plugin_toolkit import SanicPluginRealm
import logging
try:
from sanic_cors import CORS # The typical way to import sanic-cors
except ImportError:
# Path hack allows examples to be run without installation.
import os
parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
os.sys.path.insert(0, parentdir)
from sanic_cors import CORS

app = Sanic('SanicCorsAppBasedExample')
logging.basicConfig(level=logging.INFO)

# To enable logging for sanic-cors,
logging.getLogger('sanic_cors').level = logging.DEBUG

app.config['SPTK_LOAD_INI'] = True
app.config['SPTK_INI_FILE'] = 'sptk_cors.ini'
realm = SanicPluginRealm(app)

# We can get the assoc object from SPTK, it is now already registered
assoc = realm.get_plugin_assoc('CORS')
from sanic_ext import Extend

app = Sanic('SanicCorsAppBasedExample')
CORS_OPTIONS = {"resources": r'/api/*', "origins": "*", "methods": ["GET", "POST", "HEAD", "OPTIONS"]}
# Disable sanic-ext built-in CORS, and add the Sanic-CORS plugin
Extend(app, extensions=[CORS], config={"CORS": False, "CORS_OPTIONS": CORS_OPTIONS})

@app.route("/")
def hello_world(request):
'''
Since the path '/' does not match the regular expression r'/api/*',
this route does not have CORS headers set.
'''
return text('''
return html('''
<html>
<head></head>
<body>
<h1>Hello CORS!</h1>
<h3> End to end editable example with jquery! </h3>
<a class="jsbin-embed" href="http://jsbin.com/zazitas/embed?js,console">JS Bin on jsbin.com</a>
<script src="//static.jsbin.com/js/embed.min.js?3.35.12"></script>
</body>
</html>
''')

Expand Down Expand Up @@ -136,10 +138,10 @@ def get_exception(request):
raise Exception("example")

@app.exception(ServerError)
def server_error(req, e):
def server_error(request, e):
logging.exception('An error occurred during a request. %s', e)
return text("An internal error occured", status=500)


if __name__ == "__main__":
app.run(debug=True, auto_reload=False)
app.run(port=5000, debug=True, auto_reload=False)
2 changes: 0 additions & 2 deletions examples/sptk_cors.ini

This file was deleted.

4 changes: 1 addition & 3 deletions examples/view_based_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
This is a tiny Sanic Application demonstrating Sanic-Cors, making it simple
to add cross origin support to your sanic app!
:copyright: (c) 2020 by Ashley Sommer (based on flask-cors by Cory Dolphin).
:copyright: (c) 2022 by Ashley Sommer (based on flask-cors by Cory Dolphin).
:license: MIT/X11, see LICENSE for more details.
"""
from sanic import Sanic
Expand All @@ -23,8 +23,6 @@


app = Sanic('SanicCorsViewBasedExample')
logging.basicConfig(level=logging.INFO)


@app.route("/", methods=['GET', 'OPTIONS'])
@cross_origin(app, automatic_options=True)
Expand Down
2 changes: 1 addition & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
aiohttp>=2.3.0,<=3.2.1
sanic-testing>=0.3.0
sanic-testing>=0.8.2
nose
4 changes: 1 addition & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
sanic-plugin-toolkit>=1.2.0,<2
sanic>=21.3.1,<22,!=21.3.0,!=21.6.0,!=21.9.0

sanic>=21.9.3
2 changes: 1 addition & 1 deletion sanic_cors/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
Sanic-CORS is a simple extension to Sanic allowing you to support cross
origin resource sharing (CORS) using a simple decorator.
:copyright: (c) 2021 by Ashley Sommer (based on flask-cors by Cory Dolphin).
:copyright: (c) 2022 by Ashley Sommer (based on flask-cors by Cory Dolphin).
:license: MIT, see LICENSE for more details.
"""
from .decorator import cross_origin
Expand Down
2 changes: 1 addition & 1 deletion sanic_cors/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
~~~~
Core functionality shared between the extension and the decorator.
:copyright: (c) 2021 by Ashley Sommer (based on flask-cors by Cory Dolphin).
:copyright: (c) 2022 by Ashley Sommer (based on flask-cors by Cory Dolphin).
:license: MIT, see LICENSE for more details.
"""
import re
Expand Down
37 changes: 17 additions & 20 deletions sanic_cors/decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
Sanic route with. It accepts all parameters and options as
the CORS extension.
:copyright: (c) 2021 by Ashley Sommer (based on flask-cors by Cory Dolphin).
:copyright: (c) 2022 by Ashley Sommer (based on flask-cors by Cory Dolphin).
:license: MIT, see LICENSE for more details.
"""
from functools import wraps

from sanic_plugin_toolkit import SanicPluginRealm
from sanic.log import logger
from .core import *
from .extension import cors
from .extension import CORS


def cross_origin(app, *args, **kwargs):
Expand Down Expand Up @@ -101,20 +102,16 @@ def cross_origin(app, *args, **kwargs):
:type automatic_options: bool
"""
_options = kwargs
_real_decorator = cors.decorate(app, *args, run_middleware=False, with_context=False, **kwargs)

def wrapped_decorator(f):
realm = SanicPluginRealm(app) # get the singleton from the app
try:
plugin = realm.register_plugin(cors, skip_reg=True)
except ValueError as e:
# this is normal, if this plugin has been registered previously
assert e.args and len(e.args) > 1
plugin = e.args[1]
context = cors.get_context_from_realm(realm)
log = context.log
log(logging.DEBUG, "Enabled {:s} for cross_origin using options: {}".format(str(f), str(_options)))
return _real_decorator(f)

return wrapped_decorator
decorator_kwargs = kwargs
decorator_args = args
#_real_decorator = cors.decorate(app, *args, run_middleware=False, with_context=False, **kwargs)
cors = CORS(app, no_startup=True)
def wrapper(f):
@wraps(f)
async def inner(request, *args, **kwargs):
return await cors.route_wrapper(f, request, app, args, kwargs, *decorator_args, **decorator_kwargs)

logger.log(logging.DEBUG, "Enabled {:s} for cross_origin using options: {}".format(str(f), str(decorator_kwargs)))
return inner

return wrapper
Loading

0 comments on commit a8d4fb1

Please sign in to comment.