Schedule automated builds and uploads of Python packages to PyPI
Project description
timed-pypi-uploader
A lightweight Python tool for scheduling automated builds and uploads of Python packages to PyPI at specified times or on recurring intervals.
Features
- One-time or recurring scheduling using cron expressions or specific dates/times
- Automatic build backend detection (Hatch, Poetry, setuptools, flit)
- Secure token storage via system keyring
- Dry-run mode for testing without actual uploads
- Git change detection to skip releases when no changes exist
- TestPyPI support for pre-production testing
Installation
pip install timed-pypi-uploader
Quick Start
1. Configure your PyPI token
# Store PyPI token securely
timed-pypi-uploader config --pypi-token pypi-XXXXXXXXXXXX
# Or for TestPyPI
timed-pypi-uploader config --test-pypi-token pypi-XXXXXXXXXXXX
2. Run an immediate release
# Build and upload to PyPI
timed-pypi-uploader run --project-dir .
# Dry run first
timed-pypi-uploader run --dry-run
# Upload to TestPyPI
timed-pypi-uploader run --test-pypi
3. Schedule a release
# One-time release at specific time
timed-pypi-uploader schedule --at "2026-02-01T09:00:00" --project-dir .
# Recurring release (daily at 3am)
timed-pypi-uploader schedule --cron "0 3 * * *"
# Only release if git changes exist
timed-pypi-uploader schedule --cron "0 3 * * *" --check-git-changes
Commands
| Command | Description |
|---|---|
config |
Configure tokens and settings |
schedule |
Schedule a future release |
run |
Run a release immediately |
build |
Build distributions only |
upload |
Upload existing distributions |
check |
Verify all dependencies are installed |
Configuration
Create a .timed-uploader.toml file in your project:
[general]
project_dir = "."
build_backend = "auto" # auto, hatch, poetry, build, flit
test_mode = false
clean_before_build = true
[schedule]
type = "cron" # or "one-time"
cron = "0 3 * * *" # Daily at 3am
# at = "2026-02-01T09:00:00" # For one-time
check_git_changes = true
[tokens]
# Tokens stored via keyring, not in this file
pypi_keyring_service = "timed-pypi-uploader-pypi"
Or initialize with:
timed-pypi-uploader config --init
Examples
Build only (no upload)
timed-pypi-uploader build --project-dir /path/to/project
Upload existing dist files
timed-pypi-uploader upload --project-dir /path/to/project
Schedule with verbose logging
timed-pypi-uploader schedule --at "2026-02-01T09:00:00" --verbose
Run in background
nohup timed-pypi-uploader schedule --cron "0 3 * * *" &
Security
- Tokens are never stored in plaintext files
- Uses system keyring (macOS Keychain, Windows Credential Manager, Linux Secret Service)
- Always test with
--dry-runand TestPyPI first
Dependencies
typer- CLI frameworkapscheduler- Job schedulingkeyring- Secure credential storagebuild- PEP 517 package buildingtwine- PyPI uploading
License
MIT
Support
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
timed_pypi_uploader-0.1.0.tar.gz
(23.0 kB
view details)
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file timed_pypi_uploader-0.1.0.tar.gz.
File metadata
- Download URL: timed_pypi_uploader-0.1.0.tar.gz
- Upload date:
- Size: 23.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0dbc05218dbc0773e8753213c7b9a294f15df3ad94c3a25c7a5ed50f36942317
|
|
| MD5 |
388d7ad11c5d18cb89e515042b29e2df
|
|
| BLAKE2b-256 |
e2564d6e86dc2d30dbf2f18040fe7b9031ac595769e6795f1291eea652472fa7
|
File details
Details for the file timed_pypi_uploader-0.1.0-py3-none-any.whl.
File metadata
- Download URL: timed_pypi_uploader-0.1.0-py3-none-any.whl
- Upload date:
- Size: 27.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cefe02d7216699c9abd4d5923676defb050d061a3935dabf73bb8d6ea15bfd21
|
|
| MD5 |
15dbd1b2a1bf732e243bfaab2e122461
|
|
| BLAKE2b-256 |
70f05c64f5cfd0b2b1ad5df0345fa58f8949a62c34baab393d7627bbbcea3a94
|