├── LICENSE ├── README.md ├── flask_webhook.py └── setup.py /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Bogdan-Alexandrescu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Flask-Webhook 2 | 3 | Yet another Redis extension for Flask. `Flask-Webhook` makes use of Flask Blueprints and allows easy creation of application webhooks. 4 | 5 | [![Latest Version](https://img.shields.io/pypi/v/Flask-Webhook.svg)] 6 | (https://pypi.python.org/pypi/Flask-Webhook/) 7 | [![Downloads](https://img.shields.io/pypi/dm/Flask-Webhook.svg)] 8 | (https://pypi.python.org/pypi/Flask-Webhook/) 9 | [![Download format](https://img.shields.io/pypi/format/Flask-Webhook.svg)] 10 | (https://pypi.python.org/pypi/Flask-Webhook/) 11 | [![License](https://img.shields.io/pypi/l/Flask-Webhook.svg)] 12 | (https://pypi.python.org/pypi/Flask-Webhook/) 13 | 14 | 15 | ## Supported Platforms 16 | 17 | * OSX and Linux. 18 | * Python 2.7 19 | * [Flask](http://flask.pocoo.org/) 0.10.1 20 | 21 | Probably works with other versions as well. 22 | 23 | ## Quickstart 24 | 25 | Install: 26 | ```bash 27 | pip install Flask-Webhook 28 | ``` 29 | 30 | Example: 31 | ```python 32 | from flask import Flask 33 | from flask.ext.webhook import WebHook 34 | 35 | app = Flask(__name__) 36 | 37 | #create webhook object (name and app are optional) 38 | #if app is not passed in in the constructor, my_webhook.init_app(app) is needed. 39 | my_webhook = WebHook(name='optional_webhook_name', url_prefix='/webhooks' app=app) 40 | my_webhook.add_route('/something', methods=['GET', 'POST']) 41 | 42 | #define a function handler to be called by the webhook 43 | def some_function(hookrequest): 44 | do something with the request object received by the webhook 45 | 46 | #attach your function handler to the webhook. 47 | #you can attach as many as you want and they all are going to be called 48 | # () should not be included 49 | my_webhook.handlers['some_name_for_your_handler'] = some_function 50 | ``` 51 | 52 | 53 | ## Factory Example 54 | 55 | ```python 56 | # extensions.py 57 | from flask.ext.webhook import WebHook 58 | 59 | my_webhook = WebHook(url_prefix='/webhooks') 60 | ``` 61 | 62 | ```python 63 | # application.py 64 | from flask import Flask 65 | from extensions import my_webhook 66 | 67 | def some_function(request): 68 | do something 69 | 70 | def some_other_function(request): 71 | do something else 72 | 73 | def create_app(): 74 | app = Flask(__name__) 75 | my_webhook.add_route('/something', methods=['GET', 'POST']) 76 | my_webhook.handlers['action1'] = some_function 77 | my_webhook.handlers['action2'] = some_other_function 78 | my_webhook.init_app(app) 79 | return app 80 | ``` 81 | 82 | ```python 83 | # manage.py 84 | from application import create_app 85 | 86 | app = create_app() 87 | app.run() 88 | ``` 89 | 90 | ## Changelog 91 | 92 | #### 0.1.0 93 | 94 | * Initial release. 95 | -------------------------------------------------------------------------------- /flask_webhook.py: -------------------------------------------------------------------------------- 1 | """Flask extension leveraging Blueprints for creating application webhooks. 2 | 3 | https://github.com/Bogdan-Alexandrescu/Flask-Webhook 4 | https://pypi.python.org/pypi/Flask-Webhook 5 | """ 6 | import sys 7 | 8 | from flask import Blueprint, jsonify, make_response, request 9 | 10 | 11 | __author__ = '@balex' 12 | __license__ = 'MIT' 13 | __version__ = '0.1.0' 14 | 15 | 16 | class FlaskWebhookHandleException(BaseException): pass 17 | 18 | 19 | class WebHook(object): 20 | """The JIRA hook blueprint and handler.""" 21 | 22 | def __init__(self, url_prefix, name=None, log=None, app=None): 23 | """Construct the JIRAHook Blueprint.""" 24 | self._app = app 25 | self._log = log 26 | self._name = name 27 | self._blueprint = Blueprint(self._name, __name__, url_prefix=url_prefix) 28 | self.handlers = dict() 29 | if app is not None: 30 | self.init_app(app) 31 | 32 | def add_route(self, route, methods): 33 | self._blueprint.add_url_rule(route, view_func=self._run_endpoint_handlers, methods=methods) 34 | if self._app: 35 | self.init_app(self._app) 36 | 37 | @property 38 | def hook(self): 39 | return self._blueprint 40 | 41 | def _run_endpoint_handlers(self): 42 | """Calls the event handlers handlers attached to the webhook object and returns a json response. 43 | 44 | """ 45 | for key, func in self.handlers.items(): 46 | try: 47 | func(request) 48 | except Exception: 49 | if self._log: 50 | self._log.error( "Caught exception while handling '%s': %s" % (key, sys.exc_info()) ) 51 | raise FlaskWebhookHandleException( "Caught exception while handling '%s': %s" % (key, sys.exc_info()) ) 52 | 53 | return_message = (dict(status='success', message="'%s' was triggered successfully" % self._name) 54 | if self._name else dict(status='success')) 55 | 56 | if self._log: 57 | self._log.info(return_message) 58 | return make_response(jsonify(return_message), 200) 59 | 60 | def init_app(self, app): 61 | """Method used to register the webhooks on the flask app object""" 62 | app.register_blueprint(self._blueprint) -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import ast 2 | from codecs import open # To use a consistent encoding 3 | import os 4 | import setuptools 5 | import setuptools.command.sdist 6 | import sys 7 | 8 | setuptools.command.sdist.READMES = tuple(list(setuptools.command.sdist.READMES) + ['README.md']) 9 | here = os.path.abspath(os.path.dirname(__file__)) 10 | 11 | 12 | # Get the long description and other data from the relevant files 13 | with open(os.path.join(here, 'README.md'), encoding='utf-8') as f: 14 | long_description = f.read() 15 | with open(os.path.join(here, 'flask_webhook.py'), encoding='utf-8') as f: 16 | lines = [l.strip() for l in f if l.startswith('__')] 17 | metadata = ast.literal_eval("{'" + ", '".join([l.replace(' = ', "': ") for l in lines]) + '}') 18 | __author__, __license__, __version__ = [metadata[k] for k in ('__author__', '__license__', '__version__')] 19 | if not all((__author__, __license__, __version__)): 20 | raise ValueError('Failed to obtain metadata from module.') 21 | 22 | 23 | # Setup definition. 24 | setuptools.setup( 25 | name='Flask-Webhook', 26 | version=__version__, 27 | 28 | description='Create Flask application webhooks with attached handlers', 29 | long_description=long_description, 30 | 31 | # The project's main homepage. 32 | url='https://github.com/Bogdan-Alexandrescu/Flask-Webhook', 33 | 34 | # Author details 35 | author=__author__, 36 | author_email='balex@ucdavis.edu', 37 | 38 | # Choose your license 39 | license=__license__, 40 | 41 | # See https://pypi.python.org/pypi?%3Aaction=list_classifiers 42 | classifiers=[ 43 | # How mature is this project? Common values are 44 | # 3 - Alpha 45 | # 4 - Beta 46 | # 5 - Production/Stable 47 | 'Development Status :: 3 - Alpha', 48 | 49 | # Indicate who your project is intended for 50 | 'Environment :: Web Environment', 51 | 'Framework :: Flask', 52 | 'Intended Audience :: Developers', 53 | 'Topic :: Software Development :: Build Tools', 54 | 55 | # Pick your license as you wish (should match "license" above) 56 | 'License :: OSI Approved :: MIT License', 57 | 58 | # Specify the Python versions you support here. In particular, ensure 59 | # that you indicate whether you support Python 2, Python 3 or both. 60 | 'Operating System :: POSIX', 61 | 'Programming Language :: Python :: 2.7', 62 | ], 63 | 64 | # What does your project relate to? 65 | keywords='flask blueprint webhook hook', 66 | 67 | platforms='any', 68 | 69 | py_modules=['flask_webhook'], 70 | zip_safe=False, 71 | 72 | # List run-time dependencies here. These will be installed by pip when your 73 | # project is installed. For an analysis of "install_requires" vs pip's 74 | # requirements files see: 75 | # https://packaging.python.org/en/latest/technical.html#install-requires-vs-requirements-files 76 | install_requires=['Flask'], 77 | 78 | ) --------------------------------------------------------------------------------