Tutorial¶
Getting started¶
By default, grole will run a simple static file server in the current directory. To use this simply execute grole.py, or run python -m grole.
To serve your own functions, you first need a Grole
object. The constructor accepts a env variable which is passed to your handler functions such that you can share state between them. Logging is done by the python logging module, if you want logging then run logging.basicConfig(level=logging.INFO).
Once you have setup handler functions for your web API, you can then launch the server with Grole.run()
. This takes the host and port to serve on and does not return until interrupted.
Registering routes¶
Routes are registered to a Grole
object by decorating a function with the Grole.route()
decorator. The decorator function takes a regular expression as the path to match, an array of HTTP methods (GET, POST, etc), and whether you want this function in the API doc. Docstrings of functions in the API doc are available through env[‘doc’] within the handler function.
The order in which routes are registered is the order in which they will be tested when searching for a handler for a specific request.
Handling requests¶
Decorated functions registered to a Grole
object with Grole.route()
will be called if their associated regular expression matches that of a request (as well as the HTTP method).
A registered handler is given the following objects:
- env: The env dictionary that the
Grole
object was constructed with - req: A
Request
object containing the full details of the request. There.MatchObject
from the path match is also added in as req.match.
We now know enough to make a simple web API. An example of how to return the hex value when visiting /<inteter> is shown below:
from grole import Grole
app = Grole()
@app.route('/(\d+)')
def tohex(env, req):
return hex(int(req.match.group(1)))
app.run()
If you need to do something async within your handler, e.g. access a database using aioodbc then simply declare your handler as async and await as needed.
Responding¶
In-built python types returned by registered request handlers are automatically converted into 200 OK HTTP responses. The following mappings apply:
- bytes: Sent directly with content type text/plain
- string: Encoded as bytes and sent with content type text/html
- others: Encoded as json and sent with content type application/json
Finer grained control of the response data can be achieved using ResponseBody
or one of it’s children. These allow for overriding of the content type. The following are available:
ResponseBody
: bytes based responseResponseString
: string based responseResponseJSON
: json encoded responseResponseFile
: read a file to send as response
Control of the headers in the response can be achieved by returning a Response
object. This allows for sending responses other than 200 OK, for example.
Helpers¶
Various helper functions are provided to simplify common operations:
serve_static()
: Serve static files under a directory. Optionally provide simple directory indexes.serve_doc()
: Serve API documentation (docstrings) of registered request handlers using a simple plain text format.