{ "info": { "author": "nvms", "author_email": "jon@pye.rs", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: MIT License", "Natural Language :: English", "Programming Language :: Python", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7" ], "description": "# Booker\nTested on Python 2.7, 3.5, 3.6 and 3.7.\n\nCron-esque, in-script task scheduler with an incredibly easy to use\nEnglish syntax. Booker can make calls (tasks) with specific intervals,\nstart times and end times.\n\n```python\nbooker.do(mycallable, 'every 7 days at 12:00 until 01-30-2020')\n```\n\n## Table of contents\n\n* [Basic usage](#basic-usage)\n* [Using the function decorator](#using-the-function-decorator)\n * [Tasks that do not repeat](#tasks-that-do-not-repeat)\n * [Starting immediately](#starting-immediately)\n * [Starting at a specific time](#starting-at-a-specific-time)\n * [Starting in 5 minutes](#starting-in-5-minutes)\n * [Combining at and in](#combining-at-and-in)\n * [Tasks that repeat with the every keyword](#tasks-that-repeat-with-the-every-keyword)\n * [Starting now](#starting-now)\n * [Starting at a specific time](#starting-at-a-specific-time-1)\n * [Starting in a while](#starting-in-a-while)\n * [Combining every with at and in.](#combining-every-with-at-and-in)\n * [Running until a specific date and time](#running-until-a-specific-date-and-time)\n* [Using the do() method](#using-the-do-method)\n* [Task labels](#task-labels)\n * [Assigning labels with the decorator](#assigning-labels-with-the-decorator)\n * [Assigning labels using do()](#assigning-labels-using-do)\n* [Cancelling tasks](#cancelling-tasks)\n * [All](#all)\n * [By label](#by-label)\n* [Why?](#why)\n* [Q&A](#qa)\n\n\n## Tests\n\nPlease inspect and run tests.py yourself. All tests are passing. You\nwill need the (awesome) [freezegun](https://github.com/spulec/freezegun) library\nto run the tests.\n\n## Why?\nThere are other job scheduling libraries out there that work well,\nsuch as [schedule](https://github.com/dbader/schedule) or the \nmore feature-packed [APScheduler](https://github.com/agronholm/apscheduler).\nHowever, as far as I know, there are none that employ the English language\nas the syntax for constructing schedules. Maybe there's a good reason\nfor that. \u00af\\\\\\_(\u30c4)_/\u00af\n\n__Again, why!__\n1. It's cool.\n2. Forgetting how to use it is nearly impossible.\n3. More reasons.\n\n## Basic usage\n```bash\n$ pip install booker\n```\nThe keywords `every`, `in`, `at` and `until` are explained below. They\nwork how you might expect them to work.\n```python\nimport booker\nimport time\n\ndef myfunc():\n print('Task has been run')\n\n# Runs daily at noon until a long, long time from now.\nbooker.do(myfunc, 'every 1 day at 12:00 until 01-30-2030 12:00')\n\n# Runs at 2PM. If the current time is past 2PM, it will run tomorrow at 2PM.\nbooker.do(myfunc, 'at 14:00')\n\n# Runs every 15 minutes, starting an hour from now, indefinitely.\nbooker.do(myfunc, 'every 15 minutes in 1 hour')\n\ntry:\n while True:\n time.sleep(1)\n except KeyboardInterrupt:\n sys.exit(0)\n```\n## Using the function decorator\n### Tasks that do not repeat\n#### Starting immediately\nThis is identical to just calling the method yourself.\n```python\n@booker.task()\ndef myfunc():\n print('Hello')\n```\n#### Starting `at` a specific time\nUse the `at` keyword for this. This keyword expects time to be in 24 hour format (HH:MM). Seconds are not given.\n```python\n@booker.task('at 14:00')\ndef myfunc():\n print('It is 2PM.')\n```\n#### Starting `in` 5 minutes\nUse the `in` keyword for this. The task below runs 3 days and 5 minutes from now.\n```python\n@booker.task('in 3 days 5 minutes')\ndef myfunc():\n print('Hello')\n```\n#### Combining `at` and `in`\nYou can combine `at` and `in` to define a task that, `at` a specific time,\nwill do something `in` a certain amount of time. It does not matter what\norder you put these phrases in.\n```python\n@booker.task('in 30 minutes at 12:00')\ndef myfunc():\n print('It is 12:30')\n```\n### Tasks that repeat with the `every` keyword\nWhen you use the `every` keyword, booker looks for additional keywords,\nprefixed by a number. Those keywords are `day[s]`, `hour[s]` or `hr[s]`,\n`minute[s]`, and `second[s]` and they should be following a number, e.g.:\n\n`7 days, 1 hour, 30 minutes, 1 second`\n\nThe commas in the syntax above aren't necessary, but you can throw them\nin there. They have no effect.\n#### Starting now\nLike the commas above, the `and` below is not required, but you can add\nit for readability. Booker will ignore what it does not understand.\n```python\n@booker.task('every 3 days and 12 hours')\n@booker.task('every 15 minutes 15 seconds')\n```\n#### Starting `at` a specific time\nYou can combine `every` with `at`.\n```python\n@booker.task('every 12 hours at 12:00')\n@booker.task('at 16:30, do this every 30 minutes')\n```\n#### Starting `in` a while\nUsing `every` with `in`, you can define a task that runs\n__in__ in a certain amount of time after the first epoch.\n```python\n@booker.task('every 1 day in 3 hours')\n@booker.task('in 30 minutes, do this every 5 seconds')\n```\n#### Combining `every` with `at` and `in`.\nCombining all of the above, the task below runs daily at 12:30. It does not\nmatter what order you put these phrases in.\n```python\n@booker.task('in 30 minutes at 12:00 every 1 day')\n```\n#### Running `until` a specific date and time\nUsing the `until` keyword, you can tell booker when to end\na task.\n\nYou need to provide the month, day, year, hour, and minute that\nyou want the task to end in `MM-DD-YYYY HH:MM` format.\n\nThe task below would run at noon, every week, until 6PM on January 2nd\nof the year 2020. Unless you had a power outage before then, or something.\n```python\n@booker.task('every 7 days at 12:00 until 01-02-2020 18:00')\n```\n## Using the `do()` method\nYou can use the `booker.do()` method to register a task with booker just as you\nwould do with the function decorator.\n```python\ndef myfunc(): ...\n\nbooker.do(myfunc, 'every 1 day starting at 12:00')\n```\nIf you build an `booker.Schedule` using `booker.get_schedule()`, you can pass\nthat Schedule object to `booker.do()`. The example below is indentical to the\nexample above.\n```python\ndef myfunc(): ...\n\nschedule = booker.get_schedule('every 1 day starting at 12:00')\nbooker.do(myfunc, schedule)\n```\n## Task labels\nYou can assign labels to tasks. Giving a task a label means that you can\ncancel it at any time.\n### Assigning labels with the decorator\n```python\n@booker.task('every 5 seconds', 'my-label')\ndef myfunc(): ...\n```\n### Assigning labels using `do()`\n```python\ndef myfunc(): ...\n\nbooker.do(myfunc, 'every 5 seconds', 'my-label')\n```\n## Cancelling tasks\n### By label\n```python\nbooker.cancel('my-label') # cancel all tasks with the label 'my-label'\n```\n### All\n```python\nbooker.cancel_all()\n```\n## Q&A\n### __Q__: What exactly is a task?\n__A__: A `threading.Timer` object.\n\n
\n\n### __Q__: Will booker block my main thread?\n__A__: No. Booker doesn't have its own thread, or control loop,\nor anything like that. It just spawns `threading.Timer` objects\nfor you when you create a task. It's up to you to keep your program\nalive throughout the duration of task execution (unless you set\n`booker.daemonize` to `False`). Usually you would do this with a\ntypical `while True: time.sleep(1)` loop.\n\nThe example below would quit immediately\nand the task that was defined would never run because, by default,\nbooker daemonizes all of its tasks. You can disable this by setting\n`booker.daemonize` to `False`.\n```python\n# This example quits immediately\nimport booker\n\ndef myfunc():\n ...\n\nbooker.do(myfunc, 'in 10 seconds')\n```\nThis example, on the other hand, would block your main thread\nand prevent the program from exiting until the task has finished.\n```python\n# This example quits after 10 seconds has passed\nimport booker\n\nbooker.daemonize = False\n\ndef myfunc():\n ...\n\nbooker.do(myfunc, 'in 10 seconds')\n```\n\n
\n\n### __Q__: It is 6PM. What happens with this task?\n```python\nbooker.do(myfunc, 'at 12:00')\n```\n__A__: It will run, once, tomorrow at noon.\n\n
\n\n### __Q__: I have a string: `2 hours, 59 minutes, 40 seconds`, and I want to run a task 5 minutes after that. How?\n\n__A__: Use `booker.get_schedule` to get an `booker.Schedule` and add 300 seconds to its `tts` (time-to-start) property.\n```python\nschedule = booker.get_schedule('in 2 hours, 59 minutes, 40 seconds')\nschedule.tts = schedule.tts + 300\n\nbooker.do(myfunc, schedule)\n```\n\n
\n\n### __Q__: How do I pass arguments to a task?\n\n__A__: Use a lambda.\n```python\ndef myfunc(myarg):\n print('Hello, {}'.format(myarg))\n\nbooker.do(lambda: myfunc('world!'), 'in 5 seconds')\n```\n\n
\n\n### __Q__: Can I view the status of a task?\n\n__A__: From `example.py`:\n```python\nfor task in booker.tasks():\n print(task)\n```\n__output:__\n```bash\nRepeatingTask: [__main__.pong] [interval: 1s] [tts: 2s] [running in: 0.00s] [until: indefinitely] [label: my-pong-task]\nSingleTask: [__main__.print_task_status] [tts: 3s] [finished 0.00s ago]\nSingleTask: [__main__.] [tts: 12s] [running in: 9.00s]\nSingleTask: [__main__.] [tts: 19s] [running in: 16.00s]\nSingleTask: [booker.cancel_all] [tts: 20s] [running in: 17.00s]\nRepeatingTask: [__main__.print_time] [interval: 1s] [tts: 0s] [running in: 0.00s] [until: indefinitely]\nRepeatingTask: [__main__.never_run] [interval: 1s] [tts: 5s] [until: 3s has passed]\nSingleTask: [__main__.] [tts: 7s] [running in: 4.00s]\nRepeatingTask: [__main__.ping] [interval: 1s] [tts: 0s] [running in: 0.00s] [until: indefinitely] [label: my-ping-task]\nSingleTask: [__main__.in_five_seconds] [tts: 5s] [running in: 2.00s]\nSingleTask: [__main__.in_ten_seconds] [tts: 10s] [running in: 7.00s]\n```\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/nvms/booker", "keywords": "schedule,scheduling,scheduler,cron,jobcron job,task,cron task,task scheduler,task scheduling", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "booker", "package_url": "https://pypi.org/project/booker/", "platform": "", "project_url": "https://pypi.org/project/booker/", "project_urls": { "Homepage": "https://github.com/nvms/booker" }, "release_url": "https://pypi.org/project/booker/1.0.1/", "requires_dist": null, "requires_python": "", "summary": "Python task scheduling with a simple, English syntax.", "version": "1.0.1" }, "last_serial": 4661797, "releases": { "1.0.0": [ { "comment_text": "", "digests": { "md5": "11e2f3756eb94797a66ab7d6f6983cb8", "sha256": "7a40d73c8049ed55244449cce02f9bd3909a4830d310f04f8fb94268e3b57c54" }, "downloads": -1, "filename": "booker-1.0.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "11e2f3756eb94797a66ab7d6f6983cb8", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 7309, "upload_time": "2019-01-04T21:03:31", "url": "https://files.pythonhosted.org/packages/0b/41/dd79f6c0583c6a4de1123ae8e5396ab912f9b5ea59fff433074b8271f16f/booker-1.0.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "5703fc520c0b4eed44d7e6a37ce37c0e", "sha256": "7e9d7430a43d99b9fadde812de4f197b7dfb1e467ea3414a9a7ba1699b167356" }, "downloads": -1, "filename": "booker-1.0.0-py3-none-any.whl", "has_sig": false, "md5_digest": "5703fc520c0b4eed44d7e6a37ce37c0e", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 7305, "upload_time": "2019-01-04T21:03:33", "url": "https://files.pythonhosted.org/packages/51/02/d85b50e9786346646fa2b711809b0bcaef00c648d86f9497fb87d98a8d9f/booker-1.0.0-py3-none-any.whl" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "e91aef94d856910ea28e1e86cb505dd9", "sha256": "c3be147a18b9129a4ce975728ca16b85c6edb85ec7cc590408e068f96094e4bb" }, "downloads": -1, "filename": "booker-1.0.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "e91aef94d856910ea28e1e86cb505dd9", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 10650, "upload_time": "2019-01-04T21:16:02", "url": "https://files.pythonhosted.org/packages/7c/42/72e79c22c42c8f3203eddaeec566a470ac794d6969f7e0b59aac22fa7917/booker-1.0.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "aa8225daa0388264f704baa11041bafe", "sha256": "b6bac891f46757c98a77fe1f4fa4552cccfb88e9ed418d14b8b52bebbd5a998b" }, "downloads": -1, "filename": "booker-1.0.1.tar.gz", "has_sig": false, "md5_digest": "aa8225daa0388264f704baa11041bafe", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13512, "upload_time": "2019-01-04T21:16:04", "url": "https://files.pythonhosted.org/packages/ab/9c/f5907065a0f6438aabfa125f2f6f5aac1af7c493643788791e63d950e9ec/booker-1.0.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "e91aef94d856910ea28e1e86cb505dd9", "sha256": "c3be147a18b9129a4ce975728ca16b85c6edb85ec7cc590408e068f96094e4bb" }, "downloads": -1, "filename": "booker-1.0.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "e91aef94d856910ea28e1e86cb505dd9", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 10650, "upload_time": "2019-01-04T21:16:02", "url": "https://files.pythonhosted.org/packages/7c/42/72e79c22c42c8f3203eddaeec566a470ac794d6969f7e0b59aac22fa7917/booker-1.0.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "aa8225daa0388264f704baa11041bafe", "sha256": "b6bac891f46757c98a77fe1f4fa4552cccfb88e9ed418d14b8b52bebbd5a998b" }, "downloads": -1, "filename": "booker-1.0.1.tar.gz", "has_sig": false, "md5_digest": "aa8225daa0388264f704baa11041bafe", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13512, "upload_time": "2019-01-04T21:16:04", "url": "https://files.pythonhosted.org/packages/ab/9c/f5907065a0f6438aabfa125f2f6f5aac1af7c493643788791e63d950e9ec/booker-1.0.1.tar.gz" } ] }