**GenesisCoreLibs Looper Documentation**
==========================
**Overview**
------------
GCL Looper is a Python library designed to create daemon-like services that can run indefinitely, performing tasks at regular intervals or on demand.
**Usage Examples**
-----------------
### Basic Service
- Iterate infinitely
- There should be at least 5 seconds between start of previous and next iteration (`iter_min_period`)
- pause for 1 second between iterations (`iter_pause`)
```python
from gcl_looper.services import basic
class MyService(basic.BasicService):
def __init__(self, iter_min_period=5, iter_pause=1):
super(MyService, self).__init__(iter_min_period, iter_pause)
def _iteration(self):
print("Iteration", self._iteration_number)
service = MyService()
service.start()
```
### Finite Service without any pauses in-between
```python
from gcl_looper.services import basic
class MyFiniteService(basic.BasicService):
def __init__(self, iter_min_period=0, iter_pause=0):
super(MyFiniteService, self).__init__(iter_min_period, iter_pause)
self.countdown = 3
def _iteration(self):
if self.countdown > 1:
self.countdown -= 1
else:
self.stop()
service = MyFiniteService()
service.start()
```
### API service with database (restalchemy)
```python
from gcl_looper.services import bjoern_service
from gcl_looper.services import hub
from oslo_config import cfg
from restalchemy.storage.sql import engines
from restalchemy.common import config_opts as db_config_opts
from MY_PACKAGE.user_api import app
api_cli_opts = [
cfg.StrOpt(
"bind-host", default="127.0.0.1", help="The host IP to bind to"
),
cfg.IntOpt("bind-port", default=8080, help="The port to bind to"),
cfg.IntOpt(
"workers", default=1, help="How many http servers should be started"
),
]
DOMAIN = "user_api"
CONF = cfg.CONF
CONF.register_cli_opts(api_cli_opts, DOMAIN)
db_config_opts.register_posgresql_db_opts(conf=CONF)
def main():
serv_hub = hub.ProcessHubService()
for _ in range(CONF[DOMAIN].workers):
service = bjoern_service.BjoernService(
wsgi_app=app.build_wsgi_application(),
host=CONF[DOMAIN].bind_host,
port=CONF[DOMAIN].bind_port,
bjoern_kwargs=dict(reuse_port=True),
)
service.add_setup(
lambda: engines.engine_factory.configure_postgresql_factory(
conf=CONF
)
)
serv_hub.add_service(service)
serv_hub.start()
if __name__ == "__main__":
main()
```
**Public interface:**
-----------------------------
* **`start()`**: Starts the service.
* **`stop()`**: Stop the service.
* **`_loop_iteration()`**: Performs one iteration of the service loop.
**Implement these methods to get usable service:**
---------------------------
* **`_iteration()`**: This method must be implemented by subclasses to perform the actual work at each iteration.
Raw data
{
"_id": null,
"home_page": "https://github.com/infraguys/gcl_looper",
"name": "gcl-looper",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": null,
"author": "Genesis Corporation",
"author_email": "mail@gmelikov.ru",
"download_url": "https://files.pythonhosted.org/packages/e4/e4/6a6d3c41df8fb8475bc4282326d5fb185bc06a087ddb12cfbf3a370f7cb2/gcl_looper-1.0.1.tar.gz",
"platform": null,
"description": "**GenesisCoreLibs Looper Documentation**\n==========================\n\n**Overview**\n------------\n\nGCL Looper is a Python library designed to create daemon-like services that can run indefinitely, performing tasks at regular intervals or on demand.\n\n**Usage Examples**\n-----------------\n\n### Basic Service\n\n- Iterate infinitely\n- There should be at least 5 seconds between start of previous and next iteration (`iter_min_period`)\n- pause for 1 second between iterations (`iter_pause`)\n\n```python\nfrom gcl_looper.services import basic\n\nclass MyService(basic.BasicService):\n def __init__(self, iter_min_period=5, iter_pause=1):\n super(MyService, self).__init__(iter_min_period, iter_pause)\n\n def _iteration(self):\n print(\"Iteration\", self._iteration_number)\n\nservice = MyService()\nservice.start()\n```\n\n### Finite Service without any pauses in-between\n\n```python\nfrom gcl_looper.services import basic\n\nclass MyFiniteService(basic.BasicService):\n def __init__(self, iter_min_period=0, iter_pause=0):\n super(MyFiniteService, self).__init__(iter_min_period, iter_pause)\n self.countdown = 3\n\n def _iteration(self):\n if self.countdown > 1:\n self.countdown -= 1\n else:\n self.stop()\n\nservice = MyFiniteService()\nservice.start()\n```\n\n### API service with database (restalchemy)\n\n```python\nfrom gcl_looper.services import bjoern_service\nfrom gcl_looper.services import hub\nfrom oslo_config import cfg\nfrom restalchemy.storage.sql import engines\nfrom restalchemy.common import config_opts as db_config_opts\n\nfrom MY_PACKAGE.user_api import app\n\napi_cli_opts = [\n cfg.StrOpt(\n \"bind-host\", default=\"127.0.0.1\", help=\"The host IP to bind to\"\n ),\n cfg.IntOpt(\"bind-port\", default=8080, help=\"The port to bind to\"),\n cfg.IntOpt(\n \"workers\", default=1, help=\"How many http servers should be started\"\n ),\n]\n\nDOMAIN = \"user_api\"\n\nCONF = cfg.CONF\nCONF.register_cli_opts(api_cli_opts, DOMAIN)\ndb_config_opts.register_posgresql_db_opts(conf=CONF)\n\n\ndef main():\n\n serv_hub = hub.ProcessHubService()\n\n for _ in range(CONF[DOMAIN].workers):\n service = bjoern_service.BjoernService(\n wsgi_app=app.build_wsgi_application(),\n host=CONF[DOMAIN].bind_host,\n port=CONF[DOMAIN].bind_port,\n bjoern_kwargs=dict(reuse_port=True),\n )\n\n service.add_setup(\n lambda: engines.engine_factory.configure_postgresql_factory(\n conf=CONF\n )\n )\n\n serv_hub.add_service(service)\n\n serv_hub.start()\n\n\nif __name__ == \"__main__\":\n main()\n\n```\n\n**Public interface:**\n-----------------------------\n* **`start()`**: Starts the service.\n* **`stop()`**: Stop the service.\n* **`_loop_iteration()`**: Performs one iteration of the service loop.\n\n**Implement these methods to get usable service:**\n---------------------------\n\n* **`_iteration()`**: This method must be implemented by subclasses to perform the actual work at each iteration.\n\n",
"bugtrack_url": null,
"license": null,
"summary": "Looper is a daemonizer library, it can help you with lifecycle of your daemon.",
"version": "1.0.1",
"project_urls": {
"Homepage": "https://github.com/infraguys/gcl_looper"
},
"split_keywords": [],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "aa792512a6af57d7d15053ecb3c84782d7b5c65cd98cd31ffbc7030f235e0f5f",
"md5": "6372152be3376c8735dd80b75954ff0e",
"sha256": "2d2f710994f507108e6c03546d34a417b9656a73d8e348bb64a330bf86792398"
},
"downloads": -1,
"filename": "gcl_looper-1.0.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "6372152be3376c8735dd80b75954ff0e",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 18362,
"upload_time": "2025-08-05T08:42:01",
"upload_time_iso_8601": "2025-08-05T08:42:01.374883Z",
"url": "https://files.pythonhosted.org/packages/aa/79/2512a6af57d7d15053ecb3c84782d7b5c65cd98cd31ffbc7030f235e0f5f/gcl_looper-1.0.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "e4e46a6d3c41df8fb8475bc4282326d5fb185bc06a087ddb12cfbf3a370f7cb2",
"md5": "f65a1ae794f334a7316443d1277e6e6d",
"sha256": "84dc3feb910bf57185c4ab1e9687e7fc625dbf7db01f8db52a4d0b4e12b90477"
},
"downloads": -1,
"filename": "gcl_looper-1.0.1.tar.gz",
"has_sig": false,
"md5_digest": "f65a1ae794f334a7316443d1277e6e6d",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 14759,
"upload_time": "2025-08-05T08:42:02",
"upload_time_iso_8601": "2025-08-05T08:42:02.407221Z",
"url": "https://files.pythonhosted.org/packages/e4/e4/6a6d3c41df8fb8475bc4282326d5fb185bc06a087ddb12cfbf3a370f7cb2/gcl_looper-1.0.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-05 08:42:02",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "infraguys",
"github_project": "gcl_looper",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "pbr",
"specs": [
[
"<",
"5.8.1"
],
[
">=",
"1.10.0"
]
]
},
{
"name": "setuptools",
"specs": [
[
">=",
"75.3.0"
],
[
"<",
"76.0.0"
]
]
}
],
"tox": true,
"lcname": "gcl-looper"
}