Library for handling POST commands for Flask framework
Project description
Command Handler
Command Handler is a library for Flask framework which provides:
- API method for posting new commands,
- tools for easy command handlers management.
Installation
pip install command_handler
Usage
To use command_handler
import CommandHandler
object and call it with your flask
application passed.
from command_handler import CommandHandler
from flask import Flask
app = Flask(__name__)
ch = CommandHandler(app)
This will add a new endpoint to your API: /command
which is specified in Command input section.
Handlers can be added by addHandler
method of the returned object as described in Defining handlers section.
Configuration
The way CommandHandler
is designed allows to pass config parameters to the initializer.
Command input endpoint URL
It is possible to prefix default /command
route with any string accepted by Flask's routing
by defining rulePrefix
parameter.
Following code sets URL to /foo/bar/command
:
ch = CommandHandler(app, rulePrefix="/foo/bar")
It is also possible to change default /command
route suffix by defining ruleSuffix
.
Following code sets URL to /baz
:
ch = CommandHandler(app, ruleSuffix="baz")
Request validators
It is possible to define command request validators.
CommandHandler
by default sets command
and json
validators and it is not possible to remove them.
Validators can be defined by setting validators
parameter which accepts list of strings.
ch = CommandHandler(app, validators=["command", "json"])
List of possible validators can be found in Validators section
Custom validators
To register custom validator pass it to the command_handler.request.validator.ValidatorFactory.addAssert
method.
It has to accept one positional parameter which contains request passed to the view defined by CommandHandler
.
If request is invalid it is needed to raise command_handler.request.validator.exceptions.AssertionFailedException
.
First parameter of its constructor will be send to the response's body and second will be send as response code.
from command_handler.request.validator.ValidatorFactory
from command_handler.request.validator.exceptions import AssertionFailedException
def fooValidator(request):
raise AssertionFailedException("Something went wrong", 418)
ValidatorFactory.addAssert("foo", fooValidator)
Command input
By default route to the command input endpoint is /command
.
It can be configured as described in Configuration section.
Command input endpoint accepts only POST
requests
with the content matching following JSON schema:
{
"type": "object",
"properties": {
"command": {
"type": "string",
"description": "Name of the sent command",
"examples": [
"foo",
"foo.bar",
"foo.bar.baz"
]
},
"payload": {
"type": "object",
"description": "Payload of the sent command",
}
},
"required": [
"command",
"payload"
]
}
It is also required to send Content-Type
header which value matches ^application/.*json$
regular expression.
Additional validators can be defined as specified in Validators section.
Defining handlers
Command handlers can be defined by calling addHandler
method of CommandHandler
instance.
ch = CommandHandler(app)
ch.addHandler(lambda payload, command: None, "foo.*", {})
The following parameters are accepted by addHandler
method:
handler
Invokable object which is called when matching command has been posted.
handler
function has to accept two parameters:
- command's payload,
- command's name.
command
String which command's name is matched against.
Command matching is described in Command matching section.
schema
JSON schema object used to validate command's payload.
transformer = None
transformer
parameter can be used to transform command's payload before passing it to the handler.
It gets command's payload as only parameter and returns object passed to the handler as payload.
postProcessor = None
Invokable object which is called when handler processing is done.
It has to accept same parameters as handler.
If transformer
was passed to the addHandler
call it has additional named parameter origPayload
which contains original payload passed to the invoker.
If inner handler returns any value, it is passed as innerResult
named parameter.
Raising exceptions
There is no possibility of changing response of a command input endpoint except raising an exception.
When command_handler.request.exceptions.InvalidRequestException
is raised
command input endpoint returns response with HTTP code
specified during InvalidRequestEndpoint
creation (by default it is 400: Bad Request
)
and message which matches following JSON schema:
{
"type": "object",
"properties": {
"type": "string",
"description": "Message passed to the `InvalidRequestException` during creation",
"default": ""
},
"required": [
"error"
]
}
It is preferred to use 4xx
codes with InvalidRequestException
.
Following snippet will respond with 418: I'm a teapot
HTTP code and
{"error": "I'm a teapot handler"}
when foo.bar
command is sent:
def fooHandler(payload, command):
raise InvalidRequestException("I'm a teapot handler", code=418)
ch = CommandHandler(app)
ch.addHandler(fooHandler, "foo.bar", {})
When any other exception is raised command input endpoint
returns response with HTTP code 500: Internal server error
.
Command matching
Each command name sent to command input endpoint has to be a list of words delimited by dots.
Command name passed to addHandler
method must also be
in the same form. There are two special words for command name assigned to the handler:
*
can substitute exactly one word,#
can substitute zero or more words.
Command handler invoker will call handler which matches command name of handler
passed to addHandler
method. If there is no matching
handler command input endpoint will respond with 500: Internal server error
.
If there is more than one match the handler which was added first will be called. However handler's registry is not allowing to add handler which is assigned to the already covered name. It means that order of adding handler matters.
For example following snippet will work properly but adding those handlers in reverse order will cause in raising an exception.
ch.addHandler(lambda payload, command: None, "foo.bar", {})
ch.addHandler(lambda payload, command: None, "foo.#", {})
Validators
Command Handler contains following predefined request validators:
command
Validator which verifies if:
- request contains
payload
andcommand
fields, command
field value is a string,payload
field value is a dictionary,- value of
command
field is matchable to defined handlers, - value of
payload
field matches schema which had been assigned to the handler,
json
Validator which verifies if:
- request contains
Content-Type
header with value matching to^application/.*json$
regex, - request content is json-parseable.
privateIp
Validator which verifies if remote IP address of the request is private.
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
File details
Details for the file command_handler-1.2.1.tar.gz
.
File metadata
- Download URL: command_handler-1.2.1.tar.gz
- Upload date:
- Size: 16.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/40.8.0 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/3.6.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | bfdd77830b45e09546e6efb404d6a433d4dc7f462fd70fe957e90d8e2a857e3d |
|
MD5 | 20101f60290f85cf97d195264f6f1c6d |
|
BLAKE2b-256 | 7c786605e7ce9c4993ae88143bd638654a930250137e4a3c6ff7bb6ffac1fab9 |
File details
Details for the file command_handler-1.2.1-py3-none-any.whl
.
File metadata
- Download URL: command_handler-1.2.1-py3-none-any.whl
- Upload date:
- Size: 20.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/40.8.0 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/3.6.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | fa40126ee14bbd210e3fdc48f8bb37a81c06c62f28d71725a8ae5d996f8dcfec |
|
MD5 | 4c64c826572709eba467e56c82a37c3c |
|
BLAKE2b-256 | 1b075f6500045f9ce587a7aee39ed5fa496a0daafc7c4f6912cbcc1b28ddb160 |