Provides utilities to implement a hookable interface
Reason this release was yanked:
extraneous file was added
Project description
PyTapable
A Library to Implement Hookable Interfaces
:corn: Table of Contents
:strawberry: About The Project
PyTapable provides a set of utility to help you implement hookable interfaces in your classes. This opens up the posibility for solving a number of usecases such as
- Providing plugable interfaces for your libraries and frameworks
- Code seperation by functional and service domains
:sun_with_face: Getting Started
This project can be used in python 2.7, 3.5 and greater
$ pip install pytapable
Example
Inline hooks
We first create our hook called my_hook
from pytapable import Hook
my_hook = Hook()
As a consumer, we can tap into this hook by passing a name for our tap and a callback function
def my_callback(context, greeting):
print(f"Hook says: {greeting}")
my_hook.tap('My Tap Name', my_callback)
Our callback is executed when the hook.call(...)
is executed. The callback receives whatever args were passed in the
hook.call
method in addition to a context dict
my_hook.call(greeting="Hi Callback")
Functional Hooks
Functional hooks are different from inline hooks in that the callback args are predefined.
from pytapable import CreateHook, HookableMixin, create_hook_name
class Car(HookableMixin):
HOOK_ON_MOVE = create_hook_name('on_move')
@CreateHook(name=HOOK_ON_MOVE)
def move(self, speed=10):
return f"Moving at {speed} Mph"
- Start adding the
HookableMixin
to the Car Class. This is necessary to install hooks on class methods. - Decorate the
Car.move
method using the@CreateHook
decorator. In the decorator, give it a name. As best practice we define the name as a Class Constant so consumers can easily refer to it. - The value of the hook can be anything. We use the
create_hook_name(str)
utility to generate a unique name. Generating a unique name is not required but becomes important when inheriting hooks from other Classes.
def callback(context, fn_args, fn_output):
kmph_speed = fn_args['speed'] * 1.61
print(f"The car is moving {kmph_speed} kmph")
c = Car()
c.hooks[Car.HOOK_ON_MOVE].tap('log_metric_speed', callback, before=False)
c.move(10)
- Here we tap into the
on_move
hook which fires our callback after thec.move
method has executed - The
c.move()
arguments are passed asfn_args
to the callback and return value, if any, is passed asfn_output
- The context holds a
is_before
andis_after
flag it signify if the callback was executed before or afterc.move()
:tropical_drink: Documentation
Full documentation is available here https://pytapable.readthedocs.io/en/latest
:satisfied: Contributing
Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are greatly appreciated.
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature
) - Commit your Changes (
git commit -m 'Add some AmazingFeature'
) - Push to the Branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
To tests on your changes locally, run:
$ pip install -r test_requirements.txt
$ tox .
This will run your changes on python-2 and python-3
Documentation for any new changes are a must. We use Sphinx and to build the documentation locally, run:
$ cd docs/
$ make html
# or on windows
$ make.bat html
:v: License
Distributed under the Apache License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for PyTapable-0.0.3-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5b98aaaface58982d4a4228de90a467ad6acac4501afc2d8cb7c8189d2304a82 |
|
MD5 | 2dd018a75562fd88c3951c05f45aefb5 |
|
BLAKE2b-256 | 578bcc904541567531ca39771419c2fd4ed81d90ca770af4f4ae1b7e8a5ca3f6 |