Application infrastructure¶
Note
This topic describes application infrastructure of Micro.Web
Application¶
The main atom of the framework is the application, or Micro. Application does not introduce global singleton, as Flask does, but can be bound to Resource. Instead of it, application presents an interface to a dictionary, which shares the items between all instances of Micro. See an example:
from micro.core import Micro spam = 'eggs', 'sausage' app1 = Micro() app2 = Micro() app1['bacon'] = spam assert app2['bacon'] is spam
Routing¶
The framework routing is built on the analogy with famous flask and klein microframeworks from Python2 world. The main atom of routing is Micro.route() decorator. Micro uses aiohttp`s routing behind the scenes, so the syntax for routing expressions is the same as in aiohttp routing
Resource¶
Resource in terms of Micro is just a regular Python object, which has Micro instance as static property. This provides the possibility of routing into resource`s methods. See an example:
from micro.core import Micro class Resource: attr = 'spam' app = Micro() @app.route('/') def handle_request(self, request): return self.attr resource = Resource() if __name__ == '__main__': resource.app.run()
It will produce an output of ‘spam’ for requests on ‘/’.
Mounting resources¶
The resources can be mounted into each other under particular prefixes with use of Micro.mount() function. You can pass the prefix and resource instance to Micro.mount(), and all the URLs that defined in the scope of that resource will be served with a given prefix. See an example:
from micro.core import Micro class Leaf: app = Micro() @app.route('/') def leaf(self): return "leaf" leaf_resource = Leaf() class Branch: app = Micro() app.mount('leaf', leaf_resource) @app.route('/') def branch(self): return "branch" branch_resource = Branch() class Root: app = Micro() app.mount("/branch", branch_resource) @app.route('/') def root(self): return "root" root_resource = Root() if __name__ == '__main__': root_resource.app.run()
Returning values from request handler functions¶
Micro.Web use next rules for dealing with the returnables of your request handler functions:
- If the request handler function return string
it will be written to the client as-is and the HTTP response will have ‘text/plain’ content-type.
- If the request handler function return dictionary or list
it will be attempted to serialize into JSON, if successful, the resulting JSON string will be sent to the client, and the HTTP response will have ‘application/json’ content-type.
- If the request handler function return aiohttp.web_reqrep.StreamResponse inheritor,
it will be sent to the client as-is the same way as aiohttp does.
- If the request handler function return arbitrary Python object with to_output() method,
the return value of this method will be processed again for output, with this rules applying for that value.
- If the request handler function return a micro.web.response.ResponseFuture,
the framework will just wait until the underlying response completes.
See Response module reference for details.
Outgoing headers manipulation¶
Handling errors¶
Users can set custom error handlers for different subclasses of aiohttp’s web exceptions with Micro.set_error_handler()
Gunicorn integration¶
Micro integrates with Gunicorn the same way as aiohttp.web.Application does. Self-describing example:
from micro.web import Micro
app = Micro()
@app.route('/')
def index(request):
return web.Response(text="Welcome home!")
Save this code into file named test.py, and then start gunicorn:
gunicorn test:app -k aiohttp.worker.GunicornWebWorker -b localhost:8080
[2015-05-06 18:24:54 +0300] [13202] [INFO] Starting gunicorn 19.3.0
[2015-05-06 18:24:54 +0300] [13202] [INFO] Listening at: http://127.0.0.1:8080 (13202)
[2015-05-06 18:24:54 +0300] [13202] [INFO] Using worker: aiohttp.worker.GunicornWebWorker
[2015-05-06 18:24:54 +0300] [13206] [INFO] Booting worker with pid: 13206
Testing¶
Support for aiohttp middlewares¶
Micro supports the aiohttp middlewares (wrappers in terminology of Micro) by providing convenience attribute Micro.wrappers which is shared across all instances of Micro. You can append your legacy aiohttp middleware factories to this list, and they will be called on every request handling call. Note that, in oppose to vanilla aiohttp, the routing will not be initialized before the call of middleware handler. The original coder of Micro discourages use of aiohttp style middlewares in favor of Middlewares, which are way more consistent, testable and in this way reliable than original aiohttp`s.