Changeset - 2eecd641dda8
[Not reviewed]
0 2 0
Joar Wandborg - 10 years ago 2013-12-20 13:51:32
joar@wandborg.se
Added CORS Flask endpoint decorator
2 files changed with 99 insertions and 6 deletions:
0 comments (0 inline, 0 general)
accounting/decorators.py
Show inline comments
...
 
@@ -6,3 +6,3 @@ from functools import wraps
 

	
 
from flask import jsonify
 
from flask import jsonify, request
 

	
...
 
@@ -24 +24,63 @@ def jsonify_exceptions(func):
 
    return wrapper
 

	
 

	
 
def cors(origin_callback=None):
 
    '''
 
    Flask endpoint decorator.
 

	
 
    Example:
 

	
 
    .. code-block:: python
 

	
 
        @app.route('/cors-endpoint', methods=['GET', 'OPTIONS'])
 
        @cors()
 
        def cors_endpoint():
 
            return jsonify(message='This is accessible via a cross-origin XHR')
 

	
 
        # Or if you want to control the domains this resource can be requested
 
        # from via CORS:
 
        domains = ['http://wandborg.se', 'http://sfconservancy.org']
 

	
 
        def restrict_domains(origin):
 
            return ' '.join(domains)
 

	
 
        @app.route('/restricted-cors-endpoint')
 
        @cors(restrict_domains)
 
        def restricted_cors_endpoint():
 
            return jsonify(
 
                message='This is accessible from %s' % ', '.join(domains))
 

	
 
    :param function origin_callback: A callback that takes one str() argument
 
        containing the ``Origin`` HTTP header from the :data:`request` object.
 
        This can be used to filter out which domains the resource can be
 
        requested via CORS from.
 
    '''
 
    if origin_callback is None:
 
        origin_callback = allow_all_origins
 

	
 
    def decorator(func):
 
        @wraps(func)
 
        def wrapper(*args, **kw):
 
            response = func(*args, **kw)
 
            cors_headers = {
 
                'Access-Control-Allow-Origin':
 
                    origin_callback(request.headers.get('Origin')) or '*',
 
                'Access-Control-Allow-Credentials': 'true',
 
                'Access-Control-Max-Age': 3600,
 
                'Access-Control-Allow-Methods': 'POST, GET, DELETE',
 
                'Access-Control-Allow-Headers':
 
                    'Accept, Content-Type, Connection, Cookie'
 
            }
 

	
 
            for key, val in cors_headers.items():
 
                response.headers[key] = val
 

	
 
            return response
 

	
 
        return wrapper
 

	
 
    return decorator
 

	
 

	
 
def allow_all_origins(origin):
 
    return origin
accounting/web.py
Show inline comments
...
 
@@ -12,3 +12,3 @@ import argparse
 

	
 
from flask import Flask, jsonify, request
 
from flask import Flask, jsonify, request, render_template
 
from flask.ext.script import Manager
...
 
@@ -16,2 +16,3 @@ from flask.ext.migrate import Migrate, MigrateCommand
 

	
 
from accounting.models import Transaction
 
from accounting.storage import Storage
...
 
@@ -21,3 +22,3 @@ from accounting.transport import AccountingEncoder, AccountingDecoder
 
from accounting.exceptions import AccountingException
 
from accounting.decorators import jsonify_exceptions
 
from accounting.decorators import jsonify_exceptions, cors
 

	
...
 
@@ -58,5 +59,26 @@ def index():
 

	
 
@app.route('/client')
 
def client():
 
    return render_template('client.html')
 

	
 

	
 
@app.route('/transaction', methods=['OPTIONS'])
 
@cors()
 
@jsonify_exceptions
 
def transaction_options():
 
    return jsonify(status='OPTIONS')
 

	
 

	
 
@app.route('/transaction/<string:transaction_id>', methods=['OPTIONS'])
 
@cors()
 
@jsonify_exceptions
 
def transaction_by_id_options(transaction_id=None):
 
    return jsonify(status='OPTIONS')
 

	
 

	
 
@app.route('/transaction', methods=['GET'])
 
def transaction_get():
 
@app.route('/transaction/<string:transaction_id>', methods=['GET'])
 
@cors()
 
@jsonify_exceptions
 
def transaction_get(transaction_id=None):
 
    '''
...
 
@@ -64,3 +86,6 @@ def transaction_get():
 
    '''
 
    return jsonify(transactions=storage.get_transactions())
 
    if transaction_id is None:
 
        return jsonify(transactions=storage.get_transactions())
 

	
 
    return jsonify(transaction=storage.get_transaction(transaction_id))
 

	
...
 
@@ -68,2 +93,3 @@ def transaction_get():
 
@app.route('/transaction/<string:transaction_id>', methods=['POST'])
 
@cors()
 
@jsonify_exceptions
...
 
@@ -87,2 +113,3 @@ def transaction_update(transaction_id=None):
 
@app.route('/transaction/<string:transaction_id>', methods=['DELETE'])
 
@cors()
 
@jsonify_exceptions
...
 
@@ -98,2 +125,3 @@ def transaction_delete(transaction_id=None):
 
@app.route('/transaction', methods=['POST'])
 
@cors()
 
@jsonify_exceptions
...
 
@@ -147,3 +175,6 @@ def transaction_post():
 
    '''
 
    transactions = request.json.get('transactions')
 
    if not isinstance(request.json, Transaction):
 
        transactions = request.json.get('transactions')
 
    else:
 
        transactions = [request.json]
 

	
0 comments (0 inline, 0 general)