Created
May 20, 2021 05:55
-
-
Save Tythos/79d5b439ff710e8dbe315eab0a96754e to your computer and use it in GitHub Desktop.
WsgiApp.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""This is a convenient wrapping/mapping pattern for Flask-based WSGI | |
applications. Specifically, a WSGI app may require state (for database | |
connections, for example) that is poorly-managed by function-based WSGI | |
routes. Instead, this pattern lets a specific class instance define it's | |
server state, with methods being defined and decorated for the usual Flask | |
route syntax. The URL map is then dynamically constructed from the pattern | |
property that the decorator attaches to route methods, with support for | |
optional route arguments (like method=[]) as well. | |
""" | |
import flask | |
def route(pattern, **options): | |
"""This decorator can be used in place of the normal @APP.route pattern to | |
flag specific methods with specific URL routes. | |
""" | |
def wrapper(method): | |
method.pattern = pattern | |
method.options = options | |
return method | |
return wrapper | |
class WsgiApp(flask.Flask): | |
"""WSGI application object, derived from flask.Flask class. | |
""" | |
def __init__(self, *args, **kwargs): | |
"""Forwards to most standard constructor behavior, but also invokes the | |
dynamic routing assignment logic in *addMethodRoutes()*. | |
""" | |
super().__init__(__name__, *args, **kwargs) | |
self.addMethodRoutes() | |
def addMethodRoutes(self): | |
"""Looks up unique methods with the "pattern" attribute, which is then | |
used to add a URL rule for those methods. | |
""" | |
for name in dir(self): | |
if hasattr(self, name): | |
attr = getattr(self, name) | |
if hasattr(attr, "pattern"): | |
pattern = getattr(attr, "pattern") | |
options = getattr(attr, "options") | |
self.add_url_rule(pattern, name, attr, **options) | |
@route("/", methods=["GET"]) | |
def index(self): | |
"""This is an example of how the standard Flask routing logic can be | |
adapted to a class method using the decorator. In this case, @route | |
actually points to the locally-defined decorator, which is then | |
mapped dynamically upon instantiation. We also demonstrate how | |
URL-specific options can be propagated to the URL map. | |
""" | |
return b"OK", 200, {"Content-Type": "text/plain"} | |
def main(): | |
"""By default, starts a demo instance of the WsgiApp. Since this is | |
derived from flask.Flask, it can be transparently served by any WSGI | |
server, as well. | |
""" | |
WsgiApp().run() | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment