Project time management, billing, and invoice generation.
PyTM is installed with uv, a fast, single-binary Python package manager. It takes care of getting a suitable Python version for you too, so there's nothing else to install first.
Install uv (skip this if you already have it):
curl -LsSf https://astral.sh/uv/install.sh | sh
Windows, and other install options, are covered in the uv installation docs.
Install PyTM as a standalone command-line tool:
uv tool install python-pytm
This puts a
pytmcommand on yourPATH, isolated in its own environment, without touching any other Python project on your machine.Prefer not to install anything permanently? Try it in one shot instead:
uvx python-pytm --help
Check the version by typing the following in your terminal.:
pytm --version
To see the available commands type:
pytm --help
- Start a new project with a default name:
pytm project start - Start a new project with the given name or, start an existing project:
pytm project start PROJECT_NAME - Rename a project:
pytm project rename OLD_PROJECT_NAME NEW_NAME - Remove a project:
pytm project remove PROJECT_NAME - Check the status of a project:
pytm project status PROJECT_NAME - Check the list of tasks and duration of a project:
pytm project summary PROJECT_NAME - Finish active project:
pytm project finish - Pause active project:
pytm project pause - Abort active project:
pytm project abort
- Start a new task with a default name in the current active project:
pytm task start - Start a new task with the given name or existing task in the current active project:
pytm task start TASK_NAME - Rename a task of the active project:
pytm task rename OLD_TASK_NAME NEW_NAME - Remove a task:
pytm task remove TASK_NAME - current task's status:
pytm task status - Finish active task:
pytm task finish - Pause active task:
pytm task pause - Abort active task:
pytm task abort - Atomically pause the active task and start/resume another:
pytm task switch TASK_NAME - Correct a task's recorded duration by hand:
pytm task edit TASK_NAME --duration HOURS
- Time logged today, across all projects:
pytm today - Time logged this week, across all projects:
pytm week - The week's start day (default Saturday) is configurable:
pytm config user --week-start monday
Automatically start/switch tasks based on the directory you cd into and the git branch you're on — opt-in, per directory, no auto-detection.
Link a directory (and its subdirectories) to a project:
cd ~/code/my-client-project pytm hook link my-client-project
Enable the hook in your shell rc file (
~/.bashrcor~/.zshrc):eval "$(pytm hook init bash)" # or: pytm hook init zsh
From then on, cd-ing into a linked directory (or any of its subdirectories) starts/resumes its project, and switching git branch there switches to a task named after the branch. Directories that were never linked are left untouched — nothing is inferred automatically.
Manage links:
pytm hook list,pytm hook unlinkSee what a directory would resolve to without applying it:
pytm hook resolve
Configure project, user and invoice info:
pytm config project PROJECT_NAME pytm config user pytm config invoice
Generate Invoice:
pytm invoice auto PROJECT_NAME pytm invoice manual
Check version:
pytm --version pytm -v
Check summary of all the projects:
pytm summary
For a list of all the available commands try:
pytm --help
This is for working on PyTM itself, not for just using it — if you only want
the pytm command, see Installing PyTM above instead.
Clone this repository and
cdinto it:git clone https://github.com/wasi0013/PyTM.git cd PyTM
Create a virtual environment (uv downloads a matching Python for you if needed) and install dependencies into it:
uv venv uv pip install -r requirements.txt
Run the tests:
uv run pytest
uv runfinds the.venvcreated above automatically, so there's no need to manually activate it first.
- Author - Wasi - (wasi0013).
- License - see the LICENSE file.
- Contributing - see CONTRIBUTING.rst for detail. You can also help by creating issues.
- Version - see the tags on this repository.
- Acknowledgments - bootstrapped using this cookiecutter package.
- Built With ❤️ using Python.




