# Streamlit Job Scheduler
A simple and interactive Streamlit-based UI to configure and manage scheduled jobs — either **one-time** or **cron-based**.
## Features
- One-time scheduling (date + time + minute)
- Cron scheduling with flexible frequency (daily, weekly, monthly, etc.)
- Multi-hour and multi-day support in a single cron expression
- Human-readable cron descriptions
- Pytest unit tests
## Quick start
Install (editable during development) and run the Streamlit app:
```bash
pip install -e .
streamlit run -m streamlit_job_scheduler/ui.py
```
Or run directly (development):
```bash
python -m streamlit_job_scheduler/ui.py
```
### 🧩 Usage
```bash
pip install streamlit-job-scheduler
```
## Programmatic usage
Primary UI entry is [`streamlit_job_scheduler.ui.job_scheduler`](streamlit_job_scheduler/ui.py). Signature:
- job_scheduler(callback_func, config: SchedulerConfig = None) -> ScheduleInfo | None
- `callback_func`: optional callable that will be invoked with a [`streamlit_job_scheduler.models.ScheduleInfo`](streamlit_job_scheduler/models.py) when the user finalizes a schedule.
- `config`: optional [`streamlit_job_scheduler.models.SchedulerConfig`](streamlit_job_scheduler/models.py) to control initial UI state, title, pre-filled cron (parsed by [`streamlit_job_scheduler.scheduler.parse_cron_to_preconfig`](streamlit_job_scheduler/scheduler.py)), and display options.
Example (use inside a Streamlit session):
```py
from streamlit_job_scheduler.ui import job_scheduler
from streamlit_job_scheduler.models import SchedulerConfig
from streamlit_job_scheduler.enums import ScheduleType
config = SchedulerConfig(schedule_type=ScheduleType.CRONJOB, schedule="*/10 * * * *")
job = job_scheduler(None, config=config) # returns a ScheduleInfo when not using a callback
```
Returned object is a [`streamlit_job_scheduler.models.ScheduleInfo`](streamlit_job_scheduler/models.py) with `.schedule_type` and `.schedule` attributes.
## Cron helpers
- generate_cron_expr(frequency, ...) — build a cron expression for frequencies like "Every X minutes", "Hourly", "Daily", "Weekly", "Monthly", or "Custom". See implementation: [streamlit_job_scheduler/scheduler.py](streamlit_job_scheduler/scheduler.py) and symbol: [`streamlit_job_scheduler.scheduler.generate_cron_expr`](streamlit_job_scheduler/scheduler.py)
- describe_cron(expr) — turn a standard 5-field cron into a human-friendly description. See: [`streamlit_job_scheduler.scheduler.describe_cron`](streamlit_job_scheduler/scheduler.py)
- parse_cron_to_preconfig(cron_expr) — parse a cron expression into a dict suitable for pre-filling the UI. See: [`streamlit_job_scheduler.scheduler.parse_cron_to_preconfig`](streamlit_job_scheduler/scheduler.py)
Example:
```py
from streamlit_job_scheduler.scheduler import generate_cron_expr, describe_cron
expr = generate_cron_expr("Daily", hours=[9,17], minutes=[0,30])
print(expr) # -> "0,30 9,17 * * *"
print(describe_cron(expr)) # human readable description
```
## Tests
Pytest tests cover scheduler logic and a smoke UI test harness.
Run tests:
```bash
pytest -q
```
Tests to review:
- [streamlit_job_scheduler/tests/test_scheduler.py](streamlit_job_scheduler/tests/test_scheduler.py)
- [streamlit_job_scheduler/tests/test_ui.py](streamlit_job_scheduler/tests/test_ui.py)
## Development notes & gotchas
- The package requires Streamlit (see [setup.cfg](setup.cfg) and [pyproject.toml](pyproject.toml)).
- The UI function is designed to be run inside a Streamlit app — running it outside Streamlit will not render widgets.
- The UI function signature is `job_scheduler(callback_func, config=None)`. When using programmatically prefer passing the config as the second positional argument or as a keyword (`config=...`) so the function can detect the callback and config correctly. See implementation: [`streamlit_job_scheduler.ui.job_scheduler`](streamlit_job_scheduler/ui.py)
- Cron parsing expects standard 5-field cron expressions (minute hour day month weekday). See: [`streamlit_job_scheduler.scheduler.is_valid_cron`](streamlit_job_scheduler/scheduler.py)
## Contributing
- Modify code in `streamlit_job_scheduler/` and add tests in `streamlit_job_scheduler/tests/`.
- Run tests with `pytest`.
- Keep examples and README in sync with code in:
- [streamlit_job_scheduler/ui.py](streamlit_job_scheduler/ui.py)
- [streamlit_job_scheduler/scheduler.py](streamlit_job_scheduler/scheduler.py)
- [streamlit_job_scheduler/models.py](streamlit_job_scheduler/models.py)
- [streamlit_job_scheduler/enums.py](streamlit_job_scheduler/enums.py)
## License
MIT — see [LICENSE](LICENSE)
Raw data
{
"_id": null,
"home_page": null,
"name": "streamlit-job-scheduler",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "streamlit, scheduler, cron, ui",
"author": "Chandra D P",
"author_email": "Chandra D P <chandrasuvarna102@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/b0/46/a45fc26827c5563afd8c1fa85c7e33ea32f4f2e45f9f514a1bcf94e0a56d/streamlit_job_scheduler-0.0.1.tar.gz",
"platform": "any",
"description": "# Streamlit Job Scheduler\n\nA simple and interactive Streamlit-based UI to configure and manage scheduled jobs \u2014 either **one-time** or **cron-based**.\n\n## Features\n\n- One-time scheduling (date + time + minute)\n- Cron scheduling with flexible frequency (daily, weekly, monthly, etc.)\n- Multi-hour and multi-day support in a single cron expression\n- Human-readable cron descriptions\n- Pytest unit tests\n\n\n\n## Quick start\n\nInstall (editable during development) and run the Streamlit app:\n\n```bash\npip install -e .\nstreamlit run -m streamlit_job_scheduler/ui.py\n```\n\nOr run directly (development):\n\n```bash\npython -m streamlit_job_scheduler/ui.py\n```\n### \ud83e\udde9 Usage\n\n```bash\npip install streamlit-job-scheduler\n```\n## Programmatic usage\n\nPrimary UI entry is [`streamlit_job_scheduler.ui.job_scheduler`](streamlit_job_scheduler/ui.py). Signature:\n\n- job_scheduler(callback_func, config: SchedulerConfig = None) -> ScheduleInfo | None\n\n- `callback_func`: optional callable that will be invoked with a [`streamlit_job_scheduler.models.ScheduleInfo`](streamlit_job_scheduler/models.py) when the user finalizes a schedule.\n- `config`: optional [`streamlit_job_scheduler.models.SchedulerConfig`](streamlit_job_scheduler/models.py) to control initial UI state, title, pre-filled cron (parsed by [`streamlit_job_scheduler.scheduler.parse_cron_to_preconfig`](streamlit_job_scheduler/scheduler.py)), and display options.\n\nExample (use inside a Streamlit session):\n\n```py\nfrom streamlit_job_scheduler.ui import job_scheduler\nfrom streamlit_job_scheduler.models import SchedulerConfig\nfrom streamlit_job_scheduler.enums import ScheduleType\n\nconfig = SchedulerConfig(schedule_type=ScheduleType.CRONJOB, schedule=\"*/10 * * * *\")\njob = job_scheduler(None, config=config) # returns a ScheduleInfo when not using a callback\n```\n\nReturned object is a [`streamlit_job_scheduler.models.ScheduleInfo`](streamlit_job_scheduler/models.py) with `.schedule_type` and `.schedule` attributes.\n\n## Cron helpers\n\n- generate_cron_expr(frequency, ...) \u2014 build a cron expression for frequencies like \"Every X minutes\", \"Hourly\", \"Daily\", \"Weekly\", \"Monthly\", or \"Custom\". See implementation: [streamlit_job_scheduler/scheduler.py](streamlit_job_scheduler/scheduler.py) and symbol: [`streamlit_job_scheduler.scheduler.generate_cron_expr`](streamlit_job_scheduler/scheduler.py)\n\n- describe_cron(expr) \u2014 turn a standard 5-field cron into a human-friendly description. See: [`streamlit_job_scheduler.scheduler.describe_cron`](streamlit_job_scheduler/scheduler.py)\n\n- parse_cron_to_preconfig(cron_expr) \u2014 parse a cron expression into a dict suitable for pre-filling the UI. See: [`streamlit_job_scheduler.scheduler.parse_cron_to_preconfig`](streamlit_job_scheduler/scheduler.py)\n\nExample:\n\n```py\nfrom streamlit_job_scheduler.scheduler import generate_cron_expr, describe_cron\n\nexpr = generate_cron_expr(\"Daily\", hours=[9,17], minutes=[0,30])\nprint(expr) # -> \"0,30 9,17 * * *\"\nprint(describe_cron(expr)) # human readable description\n```\n\n## Tests\n\nPytest tests cover scheduler logic and a smoke UI test harness.\n\nRun tests:\n\n```bash\npytest -q\n```\n\nTests to review:\n- [streamlit_job_scheduler/tests/test_scheduler.py](streamlit_job_scheduler/tests/test_scheduler.py)\n- [streamlit_job_scheduler/tests/test_ui.py](streamlit_job_scheduler/tests/test_ui.py)\n\n## Development notes & gotchas\n\n- The package requires Streamlit (see [setup.cfg](setup.cfg) and [pyproject.toml](pyproject.toml)).\n- The UI function is designed to be run inside a Streamlit app \u2014 running it outside Streamlit will not render widgets.\n- The UI function signature is `job_scheduler(callback_func, config=None)`. When using programmatically prefer passing the config as the second positional argument or as a keyword (`config=...`) so the function can detect the callback and config correctly. See implementation: [`streamlit_job_scheduler.ui.job_scheduler`](streamlit_job_scheduler/ui.py)\n- Cron parsing expects standard 5-field cron expressions (minute hour day month weekday). See: [`streamlit_job_scheduler.scheduler.is_valid_cron`](streamlit_job_scheduler/scheduler.py)\n\n## Contributing\n\n- Modify code in `streamlit_job_scheduler/` and add tests in `streamlit_job_scheduler/tests/`.\n- Run tests with `pytest`.\n- Keep examples and README in sync with code in:\n - [streamlit_job_scheduler/ui.py](streamlit_job_scheduler/ui.py)\n - [streamlit_job_scheduler/scheduler.py](streamlit_job_scheduler/scheduler.py)\n - [streamlit_job_scheduler/models.py](streamlit_job_scheduler/models.py)\n - [streamlit_job_scheduler/enums.py](streamlit_job_scheduler/enums.py)\n\n## License\nMIT \u2014 see [LICENSE](LICENSE)\n",
"bugtrack_url": null,
"license": null,
"summary": "A Streamlit-based job scheduler with one-time and cron scheduling support",
"version": "0.0.1",
"project_urls": {
"Homepage": "https://github.com/CHANDRADP/streamlit-job-scheduler",
"Issues": "https://github.com/CHANDRADP/streamlit-job-scheduler/issues"
},
"split_keywords": [
"streamlit",
" scheduler",
" cron",
" ui"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "f247906f0b855eda66d096b4d25d7e28c0a7c73694520b9024bf8df5273292a7",
"md5": "4bc567e8938cd5de96b43eddfe2cafd7",
"sha256": "a0ddf7616faeb76be82932186daf5f485c61b6b34bd61e62041d27371c055d08"
},
"downloads": -1,
"filename": "streamlit_job_scheduler-0.0.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "4bc567e8938cd5de96b43eddfe2cafd7",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 11568,
"upload_time": "2025-11-08T14:09:05",
"upload_time_iso_8601": "2025-11-08T14:09:05.842295Z",
"url": "https://files.pythonhosted.org/packages/f2/47/906f0b855eda66d096b4d25d7e28c0a7c73694520b9024bf8df5273292a7/streamlit_job_scheduler-0.0.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "b046a45fc26827c5563afd8c1fa85c7e33ea32f4f2e45f9f514a1bcf94e0a56d",
"md5": "14b7770df562038c5ca38c85650f0138",
"sha256": "4a476a564c67f7059d78aee2b746c01f4a3d761f8a130cf4f89d384c7069dcb1"
},
"downloads": -1,
"filename": "streamlit_job_scheduler-0.0.1.tar.gz",
"has_sig": false,
"md5_digest": "14b7770df562038c5ca38c85650f0138",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 11000,
"upload_time": "2025-11-08T14:09:06",
"upload_time_iso_8601": "2025-11-08T14:09:06.985560Z",
"url": "https://files.pythonhosted.org/packages/b0/46/a45fc26827c5563afd8c1fa85c7e33ea32f4f2e45f9f514a1bcf94e0a56d/streamlit_job_scheduler-0.0.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-11-08 14:09:06",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "CHANDRADP",
"github_project": "streamlit-job-scheduler",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "streamlit-job-scheduler"
}