Welcome to Grole’s documentation!¶
Install¶
Either download grole.py directly from github and place in your project folder, or pip3 install grole.
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.
Examples¶
from grole import Grole
app = Grole()
@app.route('/(.*)?')
def index(env, req):
name = req.match.group(1) or 'World'
return 'Hello, {}!'.format(name)
app.run()
Run this script and then point your browser at http://localhost:1234/.
Grole also has an inbuilt simple file server which will serve all the files in a directory. Just run grole.py or python -m grole. This supports the following command line arguments:
- –address - The address to listen on, empty string for any address
- –port - The port to listen on
- –directory - The directory to serve
- –noindex - Do not show file indexes
- –verbose - Use verbose logging (level=DEBUG)
- –quiet - Use quiet logging (level=ERROR)
Further examples can be found within the examples folder on github.
Grole API¶
Grole is a python (3.5+) nano web framework based on asyncio. It’s goals are to be simple, embedable (single file and standard library only) and easy to use.
-
class
grole.
Grole
(env={})[source]¶ Bases:
object
A Grole Webserver
-
__init__
(env={})[source]¶ Initialise a server
env is passed to request handlers to provide shared state. Note, env by default contains doc which is populated from registered route docstrings.
-
-
class
grole.
Request
[source]¶ Bases:
object
Represents a single HTTP request
The following members are populated with the request details:
- method: The request method
- location: The request location as it is sent
- path: The unescaped path part of the location
- query: The query string part of the location (if present)
- version: The request version, e.g. HTTP/1.1
- headers: Dictionary of headers from the request
- data: Raw data from the request body
- match: The re.MatchObject from the successful path matching
-
class
grole.
Response
(data=None, code=200, reason='OK', headers={}, version='HTTP/1.1')[source]¶ Bases:
object
Represents a single HTTP response
-
__init__
(data=None, code=200, reason='OK', headers={}, version='HTTP/1.1')[source]¶ Create a response
Parameters:
- data: Object to send e.g. ResponseBody / ResponseJSON.
- code: The response code, default 200
- reason: The response reason, default OK
- version: The response version, default HTTP/1.1
- headers: Dictionary of response headers, default is a Server header and those from the response body
Note, data is intelligently converted to an appropriate ResponseXYZ object depending on it’s type.
-
-
class
grole.
ResponseBody
(data=b'', content_type='text/plain')[source]¶ Bases:
object
Response body from a byte string
-
class
grole.
ResponseFile
(filename, content_type=None)[source]¶ Bases:
grole.ResponseBody
Respond with a file
Content type is guessed if not provided
-
class
grole.
ResponseJSON
(data='', content_type='application/json')[source]¶ Bases:
grole.ResponseString
Response body encoded in json
-
class
grole.
ResponseString
(data='', content_type='text/html')[source]¶ Bases:
grole.ResponseBody
Response body from a string
-
grole.
main
(args=['-T', '-b', 'readthedocssinglehtmllocalmedia', '-d', '_build/doctrees-readthedocssinglehtmllocalmedia', '-D', 'language=en', '.', '_build/localmedia'])[source]¶ Run Grole static file server
-
grole.
parse_args
(args=['-T', '-b', 'readthedocssinglehtmllocalmedia', '-d', '_build/doctrees-readthedocssinglehtmllocalmedia', '-D', 'language=en', '.', '_build/localmedia'])[source]¶ Parse command line arguments for Grole server running as static file server
Grole is a python (3.5+) nano web framework based on asyncio. It’s goals are to be simple, embedable (single file and standard library only) and easy to use. The authors intention is that it should support standing up quick and dirty web based APIs.
It’s loosely based on bottle and flask, but unlike them does not require a WSGI capable server to handle more than one request at once. Sanic is similar, but it does not meet the embedable use-case.
A grole is a multi-spouted drinking vessel (https://en.wikipedia.org/wiki/Grole), which harks to this modules bottle/flask routes but with the ability to serve multiple drinkers at once!