Git Product home page Git Product logo

webhooks's Introduction

webhooks

_Note: This project is in the process of being reactivated and modernized. It's not ready to work anywhere._

https://badge.fury.io/py/webhooks.png Build Status Wheel Status

Python + Webhooks Made Easy

WARNING This project is in a beta state. It's still undergoing some changes and documentation is in-progress.

Python Versions

Currently works in:

  • Python 2.7
  • Python 3.3

Existing Features

  • Easy to integrate into any package or project
  • Comes with several built-in senders for synchronous webhooks.
  • Comes with a RedisQ-powered asynchronous webhook.
  • Extendable functionality through the use of custom senders and hash functions.

Planned Features

  • Comes with many built-in senders for synchronous and asynchronous webhooks.
  • Special functions for combining multiple sends of identical payloads going to one target into one.
  • Follows http://resthooks.org patterns
  • Great documentation
  • Compatibility with PyPy

Usage

Follow these easy steps:

  1. Import the webhook decorator.
  2. Define a function that returns a JSON-serializable dictionary or iterable.
  3. Add the webhook decorator and pass in a sender_callable.
  4. Define timeout, any custom headers such as authentication, signing_secret, and encoding (application/json|application/x-www-form-urlencoded)
  5. Call the function!

Synchronous example (async examples to come soon):

>>> from webhooks import webhook
>>> from webhooks.senders import targeted

>>> @webhook(sender_callable=targeted.sender)
>>> def basic(wife, husband, url, encoding, timeout, custom_headers, signing_secret):
>>>     return {"husband": husband, "wife": wife}

>>> r = basic("Audrey Roy Greenfeld", "Daniel Roy Greenfeld", url="http://httpbin.org/post", encoding="application/json", \
>>>     timeout=10, custom_headers = {"Basic" : "dXNlcjpzdXBlcnNlY3JldA=="}, signing_secret="secret1")
>>> import pprint
>>> pprint.pprint(r)
{'attempt': 1,
 'error': None,
 'hash': '9d930cc754004d5790869fdfb6064f62',
 'husband': 'Daniel Roy Greenfeld',
 'post_attributes': {'headers': {'Basic': 'dXNlcjpzdXBlcnNlY3JldA==',
                                 'x-hub-signature': 'sha256=e67a669f944fe752f9d9da15c5bcb4d332fceb4940ab512090e124c52c44cfa5'},
                     'json': '{"hash": "9d930cc754004d5790869fdfb6064f62", "husband": "Daniel Roy Greenfeld", "wife": "Audrey Roy Greenfeld"}',
                     'timeout': 10},
 'response': '{\n  "args": {}, \n  "data": "\\"{\\\\\\"hash\\\\\\": \\\\\\"9d930cc754004d5790869fdfb6064f62\\\\\\", \\\\\\"husband\\\\\\": \\\\\\"Daniel Roy Greenfeld\\\\\\", \\\\\\"wife\\\\\\": \\\\\\"Audrey Roy Greenfeld\\\\\\"}\\"", \n  "files": {}, \n  "form": {}, \n  "headers": {\n    "Accept": "*/*", \n    "Accept-Encoding": "gzip, deflate", \n    "Basic": "dXNlcjpzdXBlcnNlY3JldA==", \n    "Connection": "close", \n    "Content-Length": "125", \n    "Content-Type": "application/json", \n    "Host": "httpbin.org", \n    "User-Agent": "python-requests/2.18.4", \n    "X-Hub-Signature": "sha256=e67a669f944fe752f9d9da15c5bcb4d332fceb4940ab512090e124c52c44cfa5"\n  }, \n  "json": "{\\"hash\\": \\"9d930cc754004d5790869fdfb6064f62\\", \\"husband\\": \\"Daniel Roy Greenfeld\\", \\"wife\\": \\"Audrey Roy Greenfeld\\"}", \n  "origin": "38.104.237.126", \n  "url": "http://httpbin.org/post"\n}\n',
 'status_code': 200,
 'success': True,
 'wife': 'Audrey Roy Greenfeld'}

Projects Powered by Webhooks

webhooks's People

Contributors

pydanny avatar audreyfeldroy avatar noahhai avatar movermeyer avatar

Stargazers

 avatar  avatar Stéphane "Twidi" Angel avatar Camilla Napoles avatar Arun Krishnamurthy avatar Hillarydalie avatar Josef Rousek avatar Mangabo  Kolawole avatar  avatar Josh Thomas avatar Agustín Cangiani avatar Clasque Moseti avatar BorysiukVolodymyr avatar James Ethridge avatar Dante Mendoza avatar Phawit Pornwattanakul avatar  avatar Sam Teahan avatar Walison Filipe avatar  avatar  avatar Dhiraj avatar Mathieu Boudreau, PhD avatar Anthony McClosky avatar  avatar Ziv Litmanowicz avatar Aluma Gelbard avatar  avatar Kirill K avatar Todd Hill avatar ScalaWilliam avatar methimpact avatar Sean Summers avatar  avatar Kristian Rother avatar Andrew Hart avatar  avatar Stephen DiCato avatar WizardOfOzzie avatar Jürgen Hermann avatar Mitchell Stanton-Cook avatar Jose Padilla avatar Eduard Carreras avatar Steven Loria avatar Michael Warkentin avatar Ross Crawford-d'Heureuse avatar Jonathan Barratt avatar Miguel Eduardo Gil Biraud avatar Tomas Thor Jonsson avatar Huy Nguyen Quang avatar monk-blade avatar Mark Steve Samson avatar Daniel Groves avatar tzangms avatar  avatar Jeff Triplett avatar Paul Hallett avatar Mauricio Antunes avatar Aykut Özat avatar  avatar

Watchers

 avatar Eduard Carreras avatar Ziv Litmanowicz avatar  avatar

webhooks's Issues

Consider adding support for message authentication

Support could be added either directly or by ensuring it's easy for a third party package to extend webhooks with this functionality.

Some uses of webhooks may allow for multiple senders with different permissions or handle sensitive data that needs to be verified to be both accurate and authenticated.

One solution to this problem is HMAC which uses a shared secret key and is already implemented in the Python Standard Library:
https://docs.python.org/3.4/library/hmac.html

As a point of comparison, you can see how the financial service Dwolla uses HMAC for their webhooks:
https://developers.dwolla.com/dev/pages/webhooks

Author Django ORM sender, models, admin, and some basic views

All Django specific code should go in webhooks/django. Need to:

  1. Create webhooks with URLs, event names, and creator in the admin
  2. Track the result of pushing webhooks
  3. Set/track how many times things are attempted.
  4. Potentially provide hooks for async behavior

webhooks for async job

Hi,
I just found a small issue when I tried to use async_redis.sender function

senderobj = Senderable(
    wrapped, dkwargs, hash_value, ATTEMPTS, *args, **kwargs
)

# connection = value_in("url", dkwargs, kwargs)  # url params should be set to senderobj.url
senderobj.url = value_in("url", dkwargs, kwargs)
connection = value_in("connection", dkwargs, kwargs)

@job('default', connection=connection)
def worker(senderobj):

    return senderobj.send()

return worker(senderobj)

I think the above code might be an issue to use async sender. If I'm wrong, please correct me. Thanks.

Do not override logging settings

Hi pydanny :). This line in base.py overrides the configured logging settings. Could you remove this line, as logging should be setup elsewhere in the consumer web application? Thanks!

Create class-based version of webhook decorator

Rather than use decorators on functions, allow users to implement via classes.

Sample API that I'm not happy with so I'm still thinking about it

class Basic(BaseWebhook):

    def send(wife: Object, husband: Object):
        return {"husband": husband, "wife": wife}

    def recorder(self):
        # Call out to persistence

basic = Basic(url, encoding, timeout, custom_headers, signing_secret)
basic.send(husband, wife)

Create new abstract base class for Sender class

Objectives:

  • type hints for clarity and reduction of docs
  • Base class shouldn't be the stock implementation
  • Should be obvious in design so others can easily create senders in order to solve their needs

Determine new decorator API

Objectives for new design

The current design is ungainly in places, let's improve on it!

Old API

Problems:

  1. Long argument names
  2. url, encoding, timeout, custom_headers, and signing secret added to request/response by the decorator. What's a better way to do it?
>>> @webhook(sender_callable=targeted.sender, hash_function=uuid.uuid4)
>>> def basic(wife, husband, url, encoding, timeout, custom_headers, signing_secret):
>>>     return {"husband": husband, "wife": wife}

New API

Objectives:

  1. Shorten argument names for ease of use
  2. Add a recorder decorator argument so implementors can save results to logs, db, or whatever they way
  3. TODO Try to find a better way to add url, encoding, timeout, custom_headers, and signing_secret to requests
>>> import uuid
>>> from webhook import webhook
>>> from mystff import sender_func, save_to_db
>>>
>>> @webhook(sender=sender_func, hasher=uuid.uuid4, recorder=save_to_db)
>>> async def basic(wife, husband, url, encoding, timeout, custom_headers, signing_secret):
>>>     # I'm not happy with how arguments are managed right now, still thinking about it
>>>     return {"husband": husband, "wife": wife}
>>> await basic(...args here)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.