More readme

This commit is contained in:
s3lph 2019-11-30 03:24:29 +01:00
parent acb4dcad6e
commit 5c6065996e

128
README.md
View file

@ -3,8 +3,9 @@
[![pipeline status](https://gitlab.com/s3lph/spaceapi-server/badges/master/pipeline.svg)][master] [![pipeline status](https://gitlab.com/s3lph/spaceapi-server/badges/master/pipeline.svg)][master]
[![coverage report](https://gitlab.com/s3lph/spaceapi-server/badges/master/coverage.svg)][master] [![coverage report](https://gitlab.com/s3lph/spaceapi-server/badges/master/coverage.svg)][master]
A lightweight server for [SpaceAPI][spaceapi] endpoints. Includes support for pluggable templating, so dynamic content, A lightweight server for [SpaceAPI][spaceapi] endpoints. Includes
like sensor values, can be added. support for pluggable templating, so dynamic content, like sensor
values, can be added.
## Dependencies ## Dependencies
@ -16,13 +17,47 @@ like sensor values, can be added.
[MIT License][mit] [MIT License][mit]
## Introduction
This project is an attempt to implement a lightweight, yet versatile
SpaceAPI endpoint server. In its simplest configuration, it just
serves a plain, static, boring JSON document.
In order to provide dynamic content (e.g. whether your space is
currently open), you can replace parts of the JSON document (anything
except object keys) with [Jinja2 templates][jinja], from which you can
invoke custom plugins, which look up and return your dynamic content.
## Usage ## Usage
```bash ### 0. Download
python -m spaceapi_server config.json
```
## Configuration Head over to the [Releases][releases], download and install the
package that suits your needs. Alternatively, clone the repo and get
started.
The remainder of this document will assume that you installed the
server as an OS distribution package.
### 1. Overview
The configuration of this server consists of three parts:
- The **main configuration** file, usually located at
`/etc/spaceapi-server/config.json`. This file controls all the
internal settings of the server.
- The **response template** file, located at
`/etc/spaceapi-server/template.json`. This file defines the content
served by your sever.
- The **plugins** directory, located at
`/etc/spaceapi-server/plugins/`. Here you can put your plugins for
rendering dynamic content.
### 2. Configure the Server
Open the file `/etc/spaceapi-server/config.json`.
The following options are currently available:
```json ```json
{ {
@ -33,23 +68,36 @@ python -m spaceapi_server config.json
"plugins_dir": "plugins", # Path to the directory containing your plugins. "plugins_dir": "plugins", # Path to the directory containing your plugins.
"plugins": { "plugins": {
# Plugin-specific configuration should go in here, e.g. `.plugins.sqlite.database` # Plugin-specific configuration should go in here, separated by plugin
"my_plugin": {
"my_option": "Hello, World!",
"my_other_option: [ 42, 1337 ]
}
} }
} }
``` ```
## Serve a Static SpaceAPI Endpoint ### 3. Configure a Static SpaceAPI Endpoint
Have a look at [SpaceAPI: Getting Started][spaceapi-getting-started]. If you only want to serve static content, your Open the file `/etc/spaceapi-server/template.json`. By default it
`template.json` may consist of regular JSON data, which is served almost-as-is (once parsed and re-serialized). contains a minimal example response. If you only want to serve static
content, your `template.json` should simply contain the SpaceAPI JSON
response you want to serve.
## Add Dynamic Content The content is served "almost-as-is" (once parsed and re-serialized).
This example guides you through adding a dynamic `.state` property to your SpaceAPI endpoint. We'll use the following To learn about how a SpaceAPI response should look like, have a look
(rather simple, and probably not too useful) data source: Check a certain file, and mark the space as open depending on at [SpaceAPI: Getting Started][spaceapi-getting-started].
its existence.
1. Create a plugin to fetch the data. Let's name it `mybackend.py` and put in in our plugins directory: ### 4. Add Dynamic Content
This example guides you through adding a dynamic `state` property to
your SpaceAPI endpoint. We'll use the following (rather simple, and
probably not too useful) data source: Check a certain file, and mark
the space as open depending on its existence.
1. Create a plugin to fetch the data. Let's name it `filestate.py`
and put in in our plugins directory:
```python ```python
import os import os
@ -58,7 +106,7 @@ its existence.
@plugins.template_function @plugins.template_function
def space_state(): def space_state():
# Get the plugin config dict # Get the plugin config dict
conf = config.get_plugin_config('mybackend') conf = config.get_plugin_config(filestate')
# Get the filename # Get the filename
filename = conf.get('filename', '/var/space_state') filename = conf.get('filename', '/var/space_state')
try: try:
@ -76,9 +124,11 @@ its existence.
} }
``` ```
The `@template_function` decorator registers the function as a callable in Jinja's globals. There's also The `@template_function` decorator registers the function as a
`@template_filter`, which registers a Jinja2 filter, and `@template_test`, which registers a test. For more callable in Jinja's globals. There's also `@template_filter`,
information on the Jinja2 templating engine, see [Jinja2][jinja]. which registers a Jinja2 filter, and `@template_test`, which
registers a test. For more information on the Jinja2 templating
engine, see [Jinja2][jinja].
2. Call the template function in your template: 2. Call the template function in your template:
@ -90,9 +140,12 @@ its existence.
} }
``` ```
Although the value for the `state` key is a string containing the Jinja2 template, the return value of your template Although the value for the `state` key is a string containing the
function is a complex data type, which will be inserted into the result as such. Please be aware that only the Jinja2 template, the return value of your template function is a
first token of a templated string is used in the result. This limitation is caused by the way Jinja2 is (ab-) used. complex data type, which will be inserted into the result as such.
Please be aware that only the first token of a templated string is
used in the result. This limitation is caused by the way Jinja2
is (ab-) used.
3. Configure the server: 3. Configure the server:
@ -101,19 +154,42 @@ its existence.
"template": "template.json", "template": "template.json",
"plugins_dir": "plugins", "plugins_dir": "plugins",
"plugins": { "plugins": {
"mybackend": { "filestate": {
"filename", "/var/space_state" "filename": "/var/space_state"
} }
} }
# ... # ...
``` ```
4. Start the server and query it. ### 5. Start the Server
Start the server with e.g.:
```bash
systemctl start spaceapi-server.service
```
To reload the configuration, template and plugins, send a SIGHUP,
e.g. through `systemctl reload`.
If you need to run the server ad-hoc, you can start it with:
```bash
python3 -m spaceapi_server /path/to/config.json
```
### 6. Test the Server
```bash
curl http://localhost:8000/
```
You should be greeted with the SpaceAPI endpoint response.
[master]: https://gitlab.com/s3lph/spaceapi-server/commits/master [master]: https://gitlab.com/s3lph/spaceapi-server/commits/master
[releases]: https://gitlab.com/s3lph/spaceapi-server/-/releases
[spaceapi]: https://spaceapi.io/ [spaceapi]: https://spaceapi.io/
[pypi-bottle]: https://pypi.org/project/bottle/ [pypi-bottle]: https://pypi.org/project/bottle/
[pypi-jinja2]: https://pypi.org/project/Jinja2/ [pypi-jinja2]: https://pypi.org/project/Jinja2/
[mit]: https://gitlab.com/s3lph/spaceapi-server/blob/master/LICENSE [mit]: https://gitlab.com/s3lph/spaceapi-server/blob/master/LICENSE
[spaceapi-getting-started]: https://spaceapi.io/getting-started/ [spaceapi-getting-started]: https://spaceapi.io/getting-started/
[jinja]: https://jinja.palletsprojects.com/ [jinja]: https://jinja.palletsprojects.com/