Name | daemon-application JSON |
Version |
2.0.0
JSON |
| download |
home_page | |
Summary | A simple python package for creating daemon applications. |
upload_time | 2023-09-11 02:32:36 |
maintainer | Zhao ZhiPeng |
docs_url | None |
author | Zhao ZhiPeng |
requires_python | >=2.7, !=3.2.0 |
license | MIT |
keywords |
daemon-application
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# daemon-application
## Description
A simple python package for creating daemon applications.
*Notice:*
- *Runs the application in daemon mode on Linux only. On Windows, the application runs in foreground model.*
## Install
```
pip install daemon-application
```
## Usage
### Example for raw APIs
```
import time
import threading
import signal
from daemon_application import daemon_start
stopflag = False
def main():
def on_exit(*args, **kwargs):
with open("backgroud.log", "a", encoding="utf-8") as fobj:
print("process got exit signal...", file=fobj)
print(args, file=fobj)
print(kwargs, file=fobj)
global stopflag
stopflag = True
signal.signal(signal.SIGTERM, on_exit)
signal.signal(signal.SIGINT, on_exit)
while not stopflag:
time.sleep(1)
print(time.time())
if __name__ == "__main__":
print("start background application...")
daemon_start(main, "background.pid", True)
```
### Example for DaemonApplication
```
import time
from daemon_application import DaemonApplication
class HelloApplication(DaemonApplication):
def main(self):
while True:
print("hello")
time.sleep(1)
controller = HelloApplication().get_controller()
if __name__ == "__main__":
controller()
```
### Example for DaemonApplication adding new global options
```
import time
import click
from daemon_application import DaemonApplication
class HelloApplication(DaemonApplication):
def get_main_options(self):
options = [
click.option("-m", "--message", default="hello")
]
return options + super().get_main_options()
def main(self):
while True:
print(self.config["message"])
time.sleep(1)
controller = HelloApplication().get_controller()
if __name__ == "__main__":
controller()
```
*The output of the command help that added a new global option*
```
Usage: example.py [OPTIONS] COMMAND [ARGS]...
Options:
--pidfile TEXT pidfile file path.
--workspace TEXT Set running folder
--daemon / --no-daemon Run application in background or in foreground.
-c, --config TEXT Config file path. Application will search config
file if this option is missing. Use sub-command
show-config-fileapaths to get the searching tactics.
-m, --message TEXT
--help Show this message and exit.
Commands:
restart Restart Daemon application.
show-config-filepaths Print out the config searching paths.
start Start daemon application.
stop Stop daemon application.
```
### Example of graceful-stop-application using daemon-application and graceful-sigterm.
```python
import time
import signal
import logging
import sigterm # pip install graceful-sigterm
from daemon_application import DaemonApplication
_logger = logging.getLogger(__name__)
class HelloApplication(DaemonApplication):
def main(self):
# setup sigterm
sigterm.setup()
sigterm.setup(signal.SIGINT)
sigterm.register_worker(self._main)
sigterm.execute()
def _main(self):
# start application main
while not sigterm.is_stopped():
_logger.info("hello")
time.sleep(1)
_logger.info("gracefully stopped!")
controller = HelloApplication().get_controller()
if __name__ == "__main__":
controller()
```
Start the application, and kill by the pid. The application output looks like:
```log
test@test daemon-application % python t1.py --no-daemon start
Start application without config file.
2023-09-11 10:13:44,186 INFO 7634 8205548160base daemon_start 174 Start application in FRONT mode, pid=7634.
2023-09-11 10:13:44,187 INFO 7634 8205548160sigterm setup 88 signal setup: sig=15, handler=<function default_handler at 0x100beaa20>
2023-09-11 10:13:44,187 INFO 7634 8205548160sigterm setup 88 signal setup: sig=2, handler=<function default_handler at 0x100beaa20>
2023-09-11 10:13:44,187 INFO 7634 8205548160sigterm execute 94 start workers...
2023-09-11 10:13:44,187 INFO 7634 6180237312t1 _main 19 hello
2023-09-11 10:13:45,192 INFO 7634 6180237312t1 _main 19 hello
2023-09-11 10:13:46,197 INFO 7634 6180237312t1 _main 19 hello
2023-09-11 10:13:47,202 INFO 7634 6180237312t1 _main 19 hello
2023-09-11 10:13:48,208 INFO 7634 6180237312t1 _main 19 hello
2023-09-11 10:13:49,214 INFO 7634 6180237312t1 _main 19 hello
2023-09-11 10:13:50,219 INFO 7634 6180237312t1 _main 19 hello
2023-09-11 10:13:50,404 INFO 7634 8205548160sigterm default_handler 51 get TERM signal, prepare to stop server...
2023-09-11 10:13:51,224 INFO 7634 6180237312t1 _main 21 gracefully stopped!
2023-09-11 10:13:51,225 INFO 7634 8205548160sigterm execute 101 worker <Thread(Thread-1 (_main), stopped daemon 6180237312)> end.
2023-09-11 10:13:51,225 INFO 7634 8205548160sigterm execute 104 main thread end.
```
Look into the log, you will see `gracefully stopped!`. The kill command is not kill the main process, but set the is_stopped flag, and the application gracefully exit by it's logical controller.
## Configs
### Config items and default values
- pidfile: app.pid
- stop-timeout: 30
- stop-signal: SIGINT
- daemon: True
- workspace: ""
- loglevel: INFO
- logfile: app.log
- logfmt: default
### services fields
- class: class path string, e.g. zenutils.serviceutils.DebugService
- args: []
- kwargs: {}
## Note
Logging is ENABLED as `logutils.setup(**self.config)` by default.
## Test Passed With Pythons
- 2.7
- 3.3
- 3.4
- 3.5
- 3.6
- 3.7
- 3.8
- 3.9
- 3.10
- 3.11
## Release
### v2.0.0
- Remove rpc related parts. *Notice:* SimpleRpcApplication Based Application should change deps to `daemon-application~=1.0.5`.
### v1.0.5
- Change rpcutils, make it more easy to use.
### v0.5.10
- Use dictutils.deep_merge to update config.
### v0.5.9
- Unit test passed.
### v0.5.8
- Work with zenutils.socketserverutils.
### v0.5.7
- Improve the srpcd command.
### v0.5.6
- Add SimpleRpcServer class and srpcd command.
### v0.5.5
- Config in DaemonApplication is set to the dictutils.Object class for ease use while remaining compatible with all dict operations.
### v0.5.4
- Doc update.
### v0.5.3
- Add DaemonApplication.load_config, so that you can start DaemonApplication service directly by your code.
- Add stop_timeout for daemon_stop. If stop timeout, kill process tree by force.
### v0.5.2
- Add global options: loglevel, logfile, logfmt.
- Update default_config override mechanism.
### v0.4.4
- Fix the problem in sub-command stop.
### v0.4.3
- Deps on pyyaml.
### v0.4.2
- Remove a print() statement.
### v0.4.1
- Fix documents URLs.
### v0.4.0
- Remove fastutils deps.
- Add `--config` global command option for DaemonApplication.
- Provide a way to override the global options for subclass of DaemonApplication.
- The sub-command `restart` will do just `start` if the old application is not running or crashed.
- Use gitee.com source code hosting service.
### v0.3.3
- Fix show-config-filepaths.
### v0.3.2
- Add click deps in requirements.txt
### v0.3.1
- Add DaemonApplication.
### v0.3.0
- New wrapper.
### v0.2.1
- Old releases.
Raw data
{
"_id": null,
"home_page": "",
"name": "daemon-application",
"maintainer": "Zhao ZhiPeng",
"docs_url": null,
"requires_python": ">=2.7, !=3.2.0",
"maintainer_email": "zhaozhipeng@zencore.cn",
"keywords": "daemon-application",
"author": "Zhao ZhiPeng",
"author_email": "zhaozhipeng@zencore.cn",
"download_url": "https://files.pythonhosted.org/packages/18/e1/25d87de141dfc2a0b6f4f24307579bcb39ef93551b231f7f9172120bdb37/daemon-application-2.0.0.tar.gz",
"platform": null,
"description": "# daemon-application\n\n## Description\n\nA simple python package for creating daemon applications.\n\n*Notice:*\n\n- *Runs the application in daemon mode on Linux only. On Windows, the application runs in foreground model.*\n\n\n## Install\n\n```\npip install daemon-application\n```\n\n## Usage\n\n### Example for raw APIs\n\n```\nimport time\nimport threading\nimport signal\nfrom daemon_application import daemon_start\n\nstopflag = False\n\ndef main():\n def on_exit(*args, **kwargs):\n with open(\"backgroud.log\", \"a\", encoding=\"utf-8\") as fobj:\n print(\"process got exit signal...\", file=fobj)\n print(args, file=fobj)\n print(kwargs, file=fobj)\n global stopflag\n stopflag = True\n signal.signal(signal.SIGTERM, on_exit)\n signal.signal(signal.SIGINT, on_exit)\n while not stopflag:\n time.sleep(1)\n print(time.time())\n\nif __name__ == \"__main__\":\n print(\"start background application...\")\n daemon_start(main, \"background.pid\", True)\n```\n\n### Example for DaemonApplication\n\n```\nimport time\nfrom daemon_application import DaemonApplication\n\nclass HelloApplication(DaemonApplication):\n def main(self):\n while True:\n print(\"hello\")\n time.sleep(1)\n\ncontroller = HelloApplication().get_controller()\n\nif __name__ == \"__main__\":\n controller()\n\n```\n\n### Example for DaemonApplication adding new global options\n\n```\nimport time\nimport click\nfrom daemon_application import DaemonApplication\n\nclass HelloApplication(DaemonApplication):\n\n def get_main_options(self):\n options = [\n click.option(\"-m\", \"--message\", default=\"hello\")\n ]\n return options + super().get_main_options()\n\n def main(self):\n while True:\n print(self.config[\"message\"])\n time.sleep(1)\n\ncontroller = HelloApplication().get_controller()\n\nif __name__ == \"__main__\":\n controller()\n```\n\n*The output of the command help that added a new global option*\n\n```\nUsage: example.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n --pidfile TEXT pidfile file path.\n --workspace TEXT Set running folder\n --daemon / --no-daemon Run application in background or in foreground.\n -c, --config TEXT Config file path. Application will search config\n file if this option is missing. Use sub-command\n show-config-fileapaths to get the searching tactics.\n\n -m, --message TEXT\n --help Show this message and exit.\n\nCommands:\n restart Restart Daemon application.\n show-config-filepaths Print out the config searching paths.\n start Start daemon application.\n stop Stop daemon application.\n```\n\n### Example of graceful-stop-application using daemon-application and graceful-sigterm.\n\n```python\nimport time\nimport signal\nimport logging\nimport sigterm # pip install graceful-sigterm\nfrom daemon_application import DaemonApplication\n\n_logger = logging.getLogger(__name__)\n\n\nclass HelloApplication(DaemonApplication):\n def main(self):\n # setup sigterm\n sigterm.setup()\n sigterm.setup(signal.SIGINT)\n sigterm.register_worker(self._main)\n sigterm.execute()\n\n def _main(self):\n # start application main\n while not sigterm.is_stopped():\n _logger.info(\"hello\")\n time.sleep(1)\n _logger.info(\"gracefully stopped!\")\n\n\ncontroller = HelloApplication().get_controller()\n\nif __name__ == \"__main__\":\n controller()\n```\n\nStart the application, and kill by the pid. The application output looks like:\n\n```log\ntest@test daemon-application % python t1.py --no-daemon start\nStart application without config file.\n2023-09-11 10:13:44,186 INFO 7634 8205548160base daemon_start 174 Start application in FRONT mode, pid=7634.\n2023-09-11 10:13:44,187 INFO 7634 8205548160sigterm setup 88 signal setup: sig=15, handler=<function default_handler at 0x100beaa20>\n2023-09-11 10:13:44,187 INFO 7634 8205548160sigterm setup 88 signal setup: sig=2, handler=<function default_handler at 0x100beaa20>\n2023-09-11 10:13:44,187 INFO 7634 8205548160sigterm execute 94 start workers...\n2023-09-11 10:13:44,187 INFO 7634 6180237312t1 _main 19 hello\n2023-09-11 10:13:45,192 INFO 7634 6180237312t1 _main 19 hello\n2023-09-11 10:13:46,197 INFO 7634 6180237312t1 _main 19 hello\n2023-09-11 10:13:47,202 INFO 7634 6180237312t1 _main 19 hello\n2023-09-11 10:13:48,208 INFO 7634 6180237312t1 _main 19 hello\n2023-09-11 10:13:49,214 INFO 7634 6180237312t1 _main 19 hello\n2023-09-11 10:13:50,219 INFO 7634 6180237312t1 _main 19 hello\n2023-09-11 10:13:50,404 INFO 7634 8205548160sigterm default_handler 51 get TERM signal, prepare to stop server...\n2023-09-11 10:13:51,224 INFO 7634 6180237312t1 _main 21 gracefully stopped!\n2023-09-11 10:13:51,225 INFO 7634 8205548160sigterm execute 101 worker <Thread(Thread-1 (_main), stopped daemon 6180237312)> end.\n2023-09-11 10:13:51,225 INFO 7634 8205548160sigterm execute 104 main thread end.\n```\n\nLook into the log, you will see `gracefully stopped!`. The kill command is not kill the main process, but set the is_stopped flag, and the application gracefully exit by it's logical controller.\n\n## Configs\n\n### Config items and default values\n\n- pidfile: app.pid\n- stop-timeout: 30\n- stop-signal: SIGINT\n- daemon: True\n- workspace: \"\"\n- loglevel: INFO\n- logfile: app.log\n- logfmt: default\n\n### services fields\n\n- class: class path string, e.g. zenutils.serviceutils.DebugService\n- args: []\n- kwargs: {}\n\n## Note\n\nLogging is ENABLED as `logutils.setup(**self.config)` by default.\n\n## Test Passed With Pythons\n\n- 2.7\n- 3.3\n- 3.4\n- 3.5\n- 3.6\n- 3.7\n- 3.8\n- 3.9\n- 3.10\n- 3.11\n\n## Release\n\n### v2.0.0\n\n- Remove rpc related parts. *Notice:* SimpleRpcApplication Based Application should change deps to `daemon-application~=1.0.5`.\n\n### v1.0.5\n\n- Change rpcutils, make it more easy to use.\n\n### v0.5.10\n\n- Use dictutils.deep_merge to update config.\n\n### v0.5.9\n\n- Unit test passed.\n\n### v0.5.8\n\n- Work with zenutils.socketserverutils.\n\n### v0.5.7\n\n- Improve the srpcd command.\n\n### v0.5.6\n\n- Add SimpleRpcServer class and srpcd command.\n\n### v0.5.5\n\n- Config in DaemonApplication is set to the dictutils.Object class for ease use while remaining compatible with all dict operations.\n\n### v0.5.4\n\n- Doc update.\n\n### v0.5.3\n\n- Add DaemonApplication.load_config, so that you can start DaemonApplication service directly by your code.\n- Add stop_timeout for daemon_stop. If stop timeout, kill process tree by force.\n\n### v0.5.2\n\n- Add global options: loglevel, logfile, logfmt.\n- Update default_config override mechanism.\n\n### v0.4.4\n\n- Fix the problem in sub-command stop.\n\n### v0.4.3\n\n- Deps on pyyaml.\n\n### v0.4.2\n\n- Remove a print() statement.\n\n### v0.4.1\n\n- Fix documents URLs.\n\n### v0.4.0\n\n- Remove fastutils deps.\n- Add `--config` global command option for DaemonApplication.\n- Provide a way to override the global options for subclass of DaemonApplication.\n- The sub-command `restart` will do just `start` if the old application is not running or crashed.\n- Use gitee.com source code hosting service.\n\n### v0.3.3\n\n- Fix show-config-filepaths.\n\n### v0.3.2\n\n- Add click deps in requirements.txt\n\n### v0.3.1\n\n- Add DaemonApplication.\n\n### v0.3.0\n\n- New wrapper.\n\n### v0.2.1\n\n- Old releases.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A simple python package for creating daemon applications.",
"version": "2.0.0",
"project_urls": null,
"split_keywords": [
"daemon-application"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "d778b223b825f742a75b4897f86f085d96a4f5ccdb45bd75077505f922da9615",
"md5": "335cd26e7eb48fd7cec37839a4365cce",
"sha256": "aa5adf2d3ddc43dbfb31a9ebc03e69fb4e99fe894a69c9f1dbca0d4442e67ace"
},
"downloads": -1,
"filename": "daemon_application-2.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "335cd26e7eb48fd7cec37839a4365cce",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=2.7, !=3.2.0",
"size": 9496,
"upload_time": "2023-09-11T02:32:34",
"upload_time_iso_8601": "2023-09-11T02:32:34.332226Z",
"url": "https://files.pythonhosted.org/packages/d7/78/b223b825f742a75b4897f86f085d96a4f5ccdb45bd75077505f922da9615/daemon_application-2.0.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "18e125d87de141dfc2a0b6f4f24307579bcb39ef93551b231f7f9172120bdb37",
"md5": "50c7e444c034d534b3d59a329c72f503",
"sha256": "3da3f0e78c7e073aa60c341a542a68641093b78e340d7d2bdb1fa4f813c867af"
},
"downloads": -1,
"filename": "daemon-application-2.0.0.tar.gz",
"has_sig": false,
"md5_digest": "50c7e444c034d534b3d59a329c72f503",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=2.7, !=3.2.0",
"size": 11122,
"upload_time": "2023-09-11T02:32:36",
"upload_time_iso_8601": "2023-09-11T02:32:36.350539Z",
"url": "https://files.pythonhosted.org/packages/18/e1/25d87de141dfc2a0b6f4f24307579bcb39ef93551b231f7f9172120bdb37/daemon-application-2.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-09-11 02:32:36",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "daemon-application"
}