Resource dispatch; a method to resolve a request to an endopint using the WSGI HTTP_METHOD and attribute access.
© 2009-2019 Alice Bevan-McGregor and contributors.
Dispatch is the process of taking some starting point and a path, then resolving the object that path refers to. This process is common to almost every web application framework (transforming URLs into controllers), RPC system, and even filesystem shell. Other terms for this process include: “traversal”, “routing”, or “lookup”.
Resource dispatch utilizes the HTTP verb (provided as the HTTP_METHOD WSGI environment variable) to determine which method to call.
This package speaks a standardized dispatch protocol and is not entirely intended for direct use by most developers. The target audience is instead the authors of frameworks that may require such modular dispatch for use by their own users.
Installing web.dispatch.resource is easy, just execute the following in a terminal:
pip install web.dispatch.resource
Note: We strongly recommend always using a container, virtualization, or sandboxing environment of some kind when developing using Python; installing things system-wide is yucky (for a variety of reasons) nine times out of ten. We prefer light-weight virtualenv, others prefer solutions as robust as Vagrant.
If you add web.dispatch.resource to the install_requires argument of the call to setup() in your application’s setup.py file, this dispatcher will be automatically installed and made available when your own application or library is installed. We recommend using “less than” version numbers to ensure there are no unintentional side-effects when updating. Use web.dispatch.resource<2.1 to get all bugfixes for the current release, and web.dispatch.resource<3.0 to get bugfixes and feature updates while ensuring that large breaking changes are not installed.
Installing the current development version requires Git, a distributed source code management system. If you have Git you can run the following to download and link the development version into your Python runtime:
git clone https://github.com/marrow/web.dispatch.resource.git pip install -e web.dispatch.resource
You can then upgrade to the latest version at any time:
cd web.dispatch.resource git pull pip install -U -e .
If you would like to make changes and contribute them back to the project, fork the GitHub project, make your changes, and submit a pull request. This process is beyond the scope of this documentation; for more information see GitHub’s documentation.
This section is split to cover framework authors who will need to integrate the overall protocol into their systems, and the object interactions this form of dispatch provides for end users.
This form of dispatch relies on having an object whose attributes, named after HTTP verbs, are callable. Typically classes with methods are used for this purpose. A basic example, using the web.dispatch.resource:Resource helper class, would be:
class Potato(Resource): def get(self): return "This is a marvellous potato."
This represents a resource (thus the name) with two different endpoints based on the HTTP verb in the request. Fairly basic so far. To define a collection of resources, however, things get a little more complex:
class Field(Collection): __resource__ = Potato potatoes = 10 def get(self): return str(self.potatoes) + " potatoes in the field." def post(self): Field.potatoes += 1 return "There are now " + str(Field.potatoes) + " potatoes in the field." def delete(self): Field.potatoes = 0 return "You monster." def __getitem__(self, index): try: index = int(index) except ValueError: raise KeyError() if index <= 0 or index > self.potatoes: raise KeyError() return index
This defines a resource (since colections are also resources) with a few standard operations on it, plus this strange double underscore method. This is a standard Python feature that lets you define that instances of your class can be accessed using mapping subscripts, like a dictionary. This is how resource dispatch looks up individual items out of collections.
If a KeyError is raised in __getitem__, then that identifier is assumed to not exist.
The result of this lookup (using the next path element being dispatched against) is passed positionally to the constructor of the class pointed to by the __resource__ attribute of the Collection subclass, as is a reference to the collection that spawned it.
We can now update our initial example resource to behave as part of a collection:
class Potato(Resource): def get(self): return "One of " + str(self._collection.potatoes) + " beautiful potatoes." def delete(self): self._collection.potatoes -= 1 return "You monster."
The text result of a GET request to / will be 10 potatoes in the field. You can probably infer the remaining behaviour.
Custom verbs may be defined as additional methods. Any method whose name is not prefixed with an underscore is treated as an HTTP verb. Lastly, if there are remaining path elements, and the next matches an attribute whose value is a class, then that class will be instantiated and yielded as the next step of dispatch.
- Updated minimum Python version. Marrow Package now requires Python 3.6 or later.
- Removed Python 2 support and version specific code. The project has been updated to modern Python packaging standards, including modern namespace use. Modern namespaces are wholly incompatible with the previous namespacing mechanism; this project can not be simultaneously installed with any Marrow project that is Python 2 compatible.
- Extract of the resource dispatch mechanism from WebCore.
- Updated to utilize the standardized dispatch protocol.
- Process fully integrated in the WebCore web framework as the “RESTful dialect”.
web.dispatch.resource has been released under the MIT Open Source license.
The MIT License
Copyright © 2009-2019 Alice Bevan-McGregor and contributors.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
|Filename, size||File type||Python version||Upload date||Hashes|
|Filename, size web.dispatch.resource-3.0.0-py2.py3-none-any.whl (15.7 kB)||File type Wheel||Python version py2.py3||Upload date||Hashes View hashes|
|Filename, size web.dispatch.resource-3.0.0.tar.gz (16.6 kB)||File type Source||Python version None||Upload date||Hashes View hashes|
Hashes for web.dispatch.resource-3.0.0-py2.py3-none-any.whl
Hashes for web.dispatch.resource-3.0.0.tar.gz