Name | brewblox-service JSON |
Version |
3.3.2
JSON |
| download |
home_page | |
Summary | Scaffolding for Brewblox backend services |
upload_time | 2023-09-13 08:55:33 |
maintainer | |
docs_url | None |
author | BrewPi |
requires_python | >=3.9,<4 |
license | GPL-3.0 |
keywords |
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# Scaffolding for Brewblox service applications
In order to reduce code duplication between services, generic functionality is implemented here.
For an example on how to implement your own service based on `brewblox-service`, see <https://github.com/brewblox/brewblox-boilerplate>.
## [brewblox_service](./brewblox_service/__init__.py)
Small generic tools are defined here.
`brewblox_logger` can be used for creating module-specific loggers. It is not required, but will play a bit nicer with default formatting of the log.
Example:
```python
from brewblox_service import brewblox_logger
LOGGER = brewblox_logger(__name__)
LOGGER.info('hello')
```
## [service.py](./brewblox_service/service.py)
Parses commandline arguments, creates an `aiohttp` application object, and runs it.
The shortest implementation is:
```python
parser = service.create_parser('my_service')
config = service.create_config(parser)
app = service.create_app(config)
service.run_app(app)
```
This will get you a working web application, but it will not have any endpoints.
Applications can configure their own features, and add new commandline arguments.
Example:
```python
class ExtendedConfig(models.BaseServiceConfig):
my_arg: str
# Separately creating the parser allows adding arguments to the default set
parser = service.create_parser('my_service')
parser.add_argument('--my-arg')
# Get a config object from the extended args
config = service.create_config(parser, model=ExtendedConfig)
# Now create the app
app = service.create_app(config)
async def setup():
# Add features for this service
# You can call async functions here
device.setup(app)
api.setup(app)
# Run the app. It will await the setup() coroutine
service.run_app(app, setup())
```
## [features.py](./brewblox_service/features.py)
Many service features are application-scoped. Their lifecycle should span multiple requests, either because they are not request-driven, or because they manage asynchronous I/O operations (such as listening to AMQP messages).
The `ServiceFeature` class offers an abstract base class for this behavior. Implementing classes should define `startup(app)` and `shutdown(app)` functions, and those will be automatically called when the application starts up and shuts down.
Both `startup()` and `shutdown()` are called in an async context, making them the async counterparts of `__init__()` and `__del__()` functions.
Features must be constructed after the app is created, but before it starts running. (`service.create_app()` and `service.run_app(app)`).
It is recommended but not required to add features in an async setup function.
The `add()` and `get()` functions make it easy to centrally declare a feature, and then use it in any function that has a reference to the aiohttp app.
## [repeater.py](./brewblox_service/repeater.py)
A very common use case for features is to have the equivalent of a `while True` loop.
The `RepeaterFeature` class handles the boilerplate involved in setting this up in an async context.
## [mqtt.py](./brewblox_service/mqtt.py)
Basic MQTT messaging: publish and listen to events.
To publish data, all you need is the `publish(topic, message)` function.
To listen to incoming messages, you can combine `subscribe(topic)` with one or more calls to `listen(topic, callback)`.
The subscribe/listen functions allow for + and # wildcards to be used.
For a detailed explanation of how to use MQTT topics, see <http://www.steves-internet-guide.com/understanding-mqtt-topics/>.
For the Brewblox spec on how and where to publish data, see <https://brewblox.com/dev/reference/events.html>.
Includes top-level convenience functions for `publish(topic, message)`, `listen(topic, callback)` and `subscribe(topic)`.
Raw data
{
"_id": null,
"home_page": "",
"name": "brewblox-service",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.9,<4",
"maintainer_email": "",
"keywords": "",
"author": "BrewPi",
"author_email": "development@brewpi.com",
"download_url": "https://files.pythonhosted.org/packages/fc/b3/a2855a743646eb5704801d6005aade03f97b18f7ead631a79da2df6bb639/brewblox_service-3.3.2.tar.gz",
"platform": null,
"description": "# Scaffolding for Brewblox service applications\n\nIn order to reduce code duplication between services, generic functionality is implemented here.\n\nFor an example on how to implement your own service based on `brewblox-service`, see <https://github.com/brewblox/brewblox-boilerplate>.\n\n## [brewblox_service](./brewblox_service/__init__.py)\n\nSmall generic tools are defined here.\n\n`brewblox_logger` can be used for creating module-specific loggers. It is not required, but will play a bit nicer with default formatting of the log.\n\nExample:\n\n```python\nfrom brewblox_service import brewblox_logger\n\nLOGGER = brewblox_logger(__name__)\nLOGGER.info('hello')\n```\n\n## [service.py](./brewblox_service/service.py)\n\nParses commandline arguments, creates an `aiohttp` application object, and runs it.\n\nThe shortest implementation is:\n\n```python\nparser = service.create_parser('my_service')\nconfig = service.create_config(parser)\napp = service.create_app(config)\nservice.run_app(app)\n```\n\nThis will get you a working web application, but it will not have any endpoints.\n\nApplications can configure their own features, and add new commandline arguments.\n\nExample:\n\n```python\nclass ExtendedConfig(models.BaseServiceConfig):\n my_arg: str\n\n# Separately creating the parser allows adding arguments to the default set\nparser = service.create_parser('my_service')\nparser.add_argument('--my-arg')\n\n# Get a config object from the extended args\nconfig = service.create_config(parser, model=ExtendedConfig)\n\n# Now create the app\napp = service.create_app(config)\n\nasync def setup():\n # Add features for this service\n # You can call async functions here\n device.setup(app)\n api.setup(app)\n\n# Run the app. It will await the setup() coroutine\nservice.run_app(app, setup())\n```\n\n## [features.py](./brewblox_service/features.py)\n\nMany service features are application-scoped. Their lifecycle should span multiple requests, either because they are not request-driven, or because they manage asynchronous I/O operations (such as listening to AMQP messages).\n\nThe `ServiceFeature` class offers an abstract base class for this behavior. Implementing classes should define `startup(app)` and `shutdown(app)` functions, and those will be automatically called when the application starts up and shuts down.\n\nBoth `startup()` and `shutdown()` are called in an async context, making them the async counterparts of `__init__()` and `__del__()` functions.\n\nFeatures must be constructed after the app is created, but before it starts running. (`service.create_app()` and `service.run_app(app)`).\nIt is recommended but not required to add features in an async setup function.\n\nThe `add()` and `get()` functions make it easy to centrally declare a feature, and then use it in any function that has a reference to the aiohttp app.\n\n## [repeater.py](./brewblox_service/repeater.py)\n\nA very common use case for features is to have the equivalent of a `while True` loop.\nThe `RepeaterFeature` class handles the boilerplate involved in setting this up in an async context.\n\n## [mqtt.py](./brewblox_service/mqtt.py)\n\nBasic MQTT messaging: publish and listen to events.\nTo publish data, all you need is the `publish(topic, message)` function.\n\nTo listen to incoming messages, you can combine `subscribe(topic)` with one or more calls to `listen(topic, callback)`.\nThe subscribe/listen functions allow for + and # wildcards to be used.\n\nFor a detailed explanation of how to use MQTT topics, see <http://www.steves-internet-guide.com/understanding-mqtt-topics/>.\n\nFor the Brewblox spec on how and where to publish data, see <https://brewblox.com/dev/reference/events.html>.\n\nIncludes top-level convenience functions for `publish(topic, message)`, `listen(topic, callback)` and `subscribe(topic)`.\n\n",
"bugtrack_url": null,
"license": "GPL-3.0",
"summary": "Scaffolding for Brewblox backend services",
"version": "3.3.2",
"project_urls": null,
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "79e6af39a6dc5f0083c4a2a4f3f76fc03988960a09865eb9c513dc961881a909",
"md5": "80581c6a0c6a4277838737e131c7f15c",
"sha256": "2b0bb621956a61e7846fa30d8005df8428416a0e3fe1ae2729f081d36bf7d8e3"
},
"downloads": -1,
"filename": "brewblox_service-3.3.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "80581c6a0c6a4277838737e131c7f15c",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9,<4",
"size": 32134,
"upload_time": "2023-09-13T08:55:31",
"upload_time_iso_8601": "2023-09-13T08:55:31.955481Z",
"url": "https://files.pythonhosted.org/packages/79/e6/af39a6dc5f0083c4a2a4f3f76fc03988960a09865eb9c513dc961881a909/brewblox_service-3.3.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "fcb3a2855a743646eb5704801d6005aade03f97b18f7ead631a79da2df6bb639",
"md5": "49ca9f8b1d6d2260ee7f766b8de9a1d3",
"sha256": "0bf13ecf42729978cb9e4b2b3f5b4c5b2623bdc1aab16581fa6ca299ca6b4eac"
},
"downloads": -1,
"filename": "brewblox_service-3.3.2.tar.gz",
"has_sig": false,
"md5_digest": "49ca9f8b1d6d2260ee7f766b8de9a1d3",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9,<4",
"size": 28771,
"upload_time": "2023-09-13T08:55:33",
"upload_time_iso_8601": "2023-09-13T08:55:33.931728Z",
"url": "https://files.pythonhosted.org/packages/fc/b3/a2855a743646eb5704801d6005aade03f97b18f7ead631a79da2df6bb639/brewblox_service-3.3.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-09-13 08:55:33",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "brewblox-service"
}