{"id":13591661,"url":"https://github.com/almarklein/timetagger","last_synced_at":"2026-02-02T14:16:15.464Z","repository":{"id":37477414,"uuid":"325533242","full_name":"almarklein/timetagger","owner":"almarklein","description":"Tag your time, get the insight","archived":false,"fork":false,"pushed_at":"2025-03-07T07:57:47.000Z","size":3841,"stargazers_count":1344,"open_issues_count":74,"forks_count":115,"subscribers_count":19,"default_branch":"main","last_synced_at":"2025-04-14T18:00:02.620Z","etag":null,"topics":["python","timetracker"],"latest_commit_sha":null,"homepage":"https://timetagger.app","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/almarklein.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"custom":["https://timetagger.app","https://almarklein.org/donate.html"]}},"created_at":"2020-12-30T11:29:32.000Z","updated_at":"2025-04-14T06:00:04.000Z","dependencies_parsed_at":"2023-10-16T11:50:52.666Z","dependency_job_id":"e8e55266-413b-44a5-8589-36d8624b0edf","html_url":"https://github.com/almarklein/timetagger","commit_stats":{"total_commits":402,"total_committers":17,"mean_commits":"23.647058823529413","dds":"0.057213930348258724","last_synced_commit":"bc577a3b117c5aafb71b0196b528730f513296b1"},"previous_names":[],"tags_count":61,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/almarklein%2Ftimetagger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/almarklein%2Ftimetagger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/almarklein%2Ftimetagger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/almarklein%2Ftimetagger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/almarklein","download_url":"https://codeload.github.com/almarklein/timetagger/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248933349,"owners_count":21185460,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["python","timetracker"],"created_at":"2024-08-01T16:01:00.331Z","updated_at":"2026-02-02T14:16:10.441Z","avatar_url":"https://github.com/almarklein.png","language":"Python","readme":"[![CI](https://github.com/almarklein/timetagger/workflows/CI/badge.svg)](https://github.com/almarklein/timetagger/actions)\n[![Documentation Status](https://readthedocs.org/projects/timetagger/badge/?version=latest)](https://timetagger.readthedocs.io/en/latest/?badge=latest)\n[![PyPI version](https://badge.fury.io/py/timetagger.svg)](https://badge.fury.io/py/timetagger)\n\n# TimeTagger\n\n*Tag your time, get the insight* - an open source time-tracker with an\ninteractive user experience and powerful reporting.\n\n* Website: https://timetagger.app\n* Demo: https://timetagger.app/demo\n* Docs: https://timetagger.readthedocs.io\n* CLI tool: https://github.com/almarklein/timetagger_cli\n* [TimeTagger_VSCodeExtension](https://github.com/Yamakaze-chan/TimeTagger_VSCodeExtension) (3d party)\n\n\n## Introduction\n\nTimeTagger is a web-based time-tracking solution that can run locally\nor on a server. It's aimed at individuals and freelancers, and has the\nfollowing features:\n\n* Intuitive UI based around an interactive timeline.\n* Lightweight feel by use of tags rather than projects.\n* Reporting in PDF and CSV.\n* Set daily/weekly/monthly targets.\n* Integrated Pomodoro method (experimental).\n* Responsive: works well on small and large screens.\n* Sync between devices.\n\n\n## Under the hood\n\nThe server runs on async Python using\n[uvicorn](https://github.com/encode/uvicorn) and\n[asgineer](https://github.com/almarklein/asgineer) - which is fun and bloody fast.\nIt uses SQLite via [itemdb](https://github.com/almarklein/itemdb) to\nstore the data, making it easy to deploy.\n\nThe client is a mix of HTML, CSS, Markdown, and ... Python!\n[PScript](https://github.com/flexxui/pscript) is used to compile the\nPython to JavaScript. This may be a bit idiosyncratic, but it's fun!\nMaybe I'll someday implement it in something that compiles down to Wasm :)\n\n\n## Install and run\n\nTimeTagger is implemented as a Python library that requires Python 3.6 or higher. The dependencies are listed in `requirements.txt` - these are installed automatically when you install TimeTagger with Pip.\n\n```\n# Install\npip install -U timetagger\n\n# Run\npython -m timetagger\n```\n\nIf the server runs on your local machine, you can use single-user mode out-of-the-box.\n\n\n## Self-hosting your time tracker\n\nDocker images are provided via the [Github container registry](https://github.com/almarklein/timetagger/pkgs/container/timetagger),\nso you can use e.g. Docker-compose to easily host your own server.\n\nThere are two variants, one that runs the server as root inside the container and a nonroot variant\nthat runs as user 1000:\n- [docker-compose.yml](https://github.com/almarklein/timetagger/blob/main/deploy/docker-compose.yml)\n- [docker-compose.nonroot.yml](https://github.com/almarklein/timetagger/blob/main/deploy/docker-compose.nonroot.yml)\n\nSee [this article](https://timetagger.app/articles/selfhost2/) for more information about self hosting.\n\n### Authentication using credentials\n\nIf you want multiple users, or if the server is not on localhost, you\nmay want to provide the server with user credentials using an\nenvironment variable or a command line arg (see the\n[docs on config](https://timetagger.readthedocs.io/en/latest/libapi/)).\n\n```\n# Using command-line args\npython -m timetagger --credentials=test:$2a$08$0CD1NFiIbancwWsu3se1v.RNR/b7YeZd71yg3cZ/3whGlyU6Iny5i\n\n# Using environment variables\nexport TIMETAGGER_CREDENTIALS='test:$2a$08$0CD1NFiIbancwWsu3se1v.RNR/b7YeZd71yg3cZ/3whGlyU6Iny5i'\npython -m timetagger\n```\n\nThe credentials take the form \"\u003cusername\u003e:\u003chash\u003e\", where the hash is a\n(salted) BCrypt hash of the password. You can generate credentials using\ne.g. https://timetagger.app/cred.\n\n\n### Authentication using a reverse proxy\n\nIf you have a reverse proxy which already authenticates users (e.g. [Authelia](https://www.authelia.com)) and provides the username through a HTTP header, you can tell TimeTagger to use this information. To configure it there are three environment variables and command line arguments (see the\n[docs on config](https://timetagger.readthedocs.io/en/latest/libapi/)).\n\n```\n# Using command-line args\npython -m timetagger --proxy_auth_enabled=True --proxy_auth_trusted=127.0.0.1 --proxy_auth_header=X-Remote-User\n\n# Using environment variables\nexport TIMETAGGER_PROXY_AUTH_ENABLED=True TIMETAGGER_PROXY_AUTH_TRUSTED=127.0.0.1 TIMETAGGER_PROXY_AUTH_HEADER=X-Remote-User\npython -m timetagger\n```\n\n\n## Show your support\n\nIf you're self-hosting TimeTagger and want to support the project, you can:\n\n* Write something about TimeTagger in a blog post or social media (and link to `https://timetagger.app`). This helps search engines find it better.\n* Contribute improvements via Github.\n* For financial support you can take a subscription or donate (see the donation links on the side).\n\n\n## Using the hosted version\n\nYou can also make use of https://timetagger.app so you don't have to worry about\nmaintaining a server, backups, and all that. An account is just €3 per month.\nWith that you'd also sponsor this project and open source in general.\n\n\n## Copyright and license\n\nAs usual, copyright applies to whomever made a particular contribution in this repository,\nwhich can be inspected via e.g. git blame. The owner of the copyright (i.e. the author)\nis free to use their code in any way.\n\nThis code is also subject to the GPL-3.0 License, to protect it from being used\ncommercially by other parties.\n\nContributors must agree to the\n[Contributor License Agreement](https://github.com/almarklein/timetagger/blob/main/CLA.md)\nto grant me (Almar) the right to use their contributions at e.g. the TimeTagger.app service.\nBy making a contribution to this project, you agree to this CLA.\n\n\n## Developers\n\nClone the repo and install in development mode:\n\n```sh\ngit clone https://github.com/almarklein/timetagger.git\ncd timetagger\npip install -e .\n```\n\nInstall additional developer dependencies:\n\n```\npip install invoke black flake8 pytest pytest-cov requests\n```\n\nThen these commands can be used during development:\n\n* `invoke -l` to see available invoke tasks\n* `invoke clean` to remove temporary files\n* `invoke format` to autoformat the code (using black)\n* `invoke lint` to detect linting errors (using flake8)\n* `invoke tests` to run tests (using pytest)\n","funding_links":["https://timetagger.app","https://almarklein.org/donate.html"],"categories":["python","Cross-Platform Time Tracking"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falmarklein%2Ftimetagger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falmarklein%2Ftimetagger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falmarklein%2Ftimetagger/lists"}