{"id":13689302,"url":"https://github.com/realpython/codetiming","last_synced_at":"2025-05-16T14:04:48.731Z","repository":{"id":51449593,"uuid":"199325522","full_name":"realpython/codetiming","owner":"realpython","description":"A flexible, customizable timer for your Python code","archived":false,"fork":false,"pushed_at":"2022-11-08T17:54:06.000Z","size":73,"stargazers_count":290,"open_issues_count":6,"forks_count":40,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-05-13T15:08:57.724Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://pypi.org/project/codetiming/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/realpython.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-07-28T18:54:10.000Z","updated_at":"2025-04-07T18:46:03.000Z","dependencies_parsed_at":"2022-08-21T23:00:45.975Z","dependency_job_id":null,"html_url":"https://github.com/realpython/codetiming","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/realpython%2Fcodetiming","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/realpython%2Fcodetiming/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/realpython%2Fcodetiming/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/realpython%2Fcodetiming/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/realpython","download_url":"https://codeload.github.com/realpython/codetiming/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254544146,"owners_count":22088807,"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":[],"created_at":"2024-08-02T15:01:41.978Z","updated_at":"2025-05-16T14:04:48.712Z","avatar_url":"https://github.com/realpython.png","language":"Python","readme":"[![Python Timer Functions: Three Ways to Monitor Your Code](https://files.realpython.com/media/Three-Ways-to-Time-Your-Code_Watermarked.8d561fcc7a35.jpg)](https://realpython.com/python-timer)\n\n# `codetiming` - A flexible, customizable timer for your Python code\n\n[![Latest version](https://img.shields.io/pypi/v/codetiming)](https://pypi.org/project/codetiming/)\n[![Python versions](https://img.shields.io/pypi/pyversions/codetiming)](https://pypi.org/project/codetiming/)\n[![Downloads](https://img.shields.io/pypi/dd/codetiming)](https://pypi.org/project/codetiming/)\n[![Tests](https://img.shields.io/github/workflow/status/realpython/codetiming/unit_tests?label=tests)](https://github.com/realpython/codetiming/actions)\n[![Checked with mypy](http://www.mypy-lang.org/static/mypy_badge.svg)](http://mypy-lang.org/)\n[![Interrogate DocStrings](https://raw.githubusercontent.com/realpython/codetiming/main/interrogate_badge.svg)](https://interrogate.readthedocs.io/)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n[![MIT license](https://img.shields.io/pypi/l/codetiming)](https://mit-license.org/)\n\nInstall `codetiming` from PyPI:\n\n```\n$ python -m pip install codetiming\n```\n\nThe source code is [available on GitHub](https://github.com/realpython/codetiming).\n\nFor a complete tutorial on `codetiming`, see [Python Timer Functions: Three Ways to Monitor Your Code](https://realpython.com/python-timer) on [Real Python](https://realpython.com/).\n\n## Basic Usage\n\nYou can use `codetiming.Timer` in several different ways:\n\n1. As a **class**:\n\n    ```python\n    t = Timer(name=\"class\")\n    t.start()\n    # Do something\n    t.stop()\n    ```\n\n2. As a **context manager**:\n\n    ```python\n    with Timer(name=\"context manager\"):\n        # Do something\n    ```\n\n3. As a **decorator**:\n\n    ```python\n    @Timer(name=\"decorator\")\n    def stuff():\n        # Do something\n    ```\n\n\n## Arguments\n\n`Timer` accepts the following arguments when it's created. All arguments are optional:\n\n- **`name`:** An optional name for your timer\n- **`text`:** The text that's shown when your timer ends. It should contain a `{}` placeholder that will be filled by the elapsed time in seconds (default: `\"Elapsed time: {:.4f} seconds\"`)\n- **`initial_text`:** Show text when your timer starts. You may provide the string to be logged or `True` to show the default text `\"Timer {name} started\"` (default: `False`)\n- **`logger`:** A function/callable that takes a string argument and will report the elapsed time when the logger is stopped (default: `print()`)\n\nYou can turn off explicit reporting of the elapsed time by setting `logger=None`.\n\nIn the template text, you can also use explicit attributes to refer to the `name` of the timer or log the elapsed time in `milliseconds`, `seconds` (the default), or `minutes`. For example:\n\n```python\nt1 = Timer(name=\"NamedTimer\", text=\"{name}: {minutes:.1f} minutes\")\nt2 = Timer(text=\"Elapsed time: {milliseconds:.0f} ms\")\n```\n\nNote that the strings used by `text` are **not** f-strings. Instead, they are used as templates that will be populated using `.format()` behind the scenes. If you want to combine the `text` template with an f-string, you need to use double braces for the template values:\n\n```python\nt = Timer(text=f\"{__file__}: {{:.4f}}\")\n```\n\n`text` is also allowed to be a callable like a function or a class. If `text` is a callable, it is expected to require one argument: the number of seconds elapsed. It should return a text string that will be logged using logger:\n\n```python\nt = Timer(text=lambda secs: f\"{secs / 86400:.0f} days\")\n```\n\nThis allows you to use third-party libraries like [`humanfriendly`](https://pypi.org/project/humanfriendly/) to do the text formatting:\n\n```python\nfrom humanfriendly import format_timespan\n\nt1 = Timer(text=format_timespan)\nt2 = Timer(text=lambda secs: f\"Elapsed time: {format_timespan(secs)}\")\n```\n\nYou may include a text that should be logged when the timer starts by setting `initial_text`:\n\n```python\nt = Timer(initial_text=\"And so it begins ...\")\n```\n\nYou can also set `initial_text=True` to use a default initial text.\n\n\n## Capturing the Elapsed Time\n\nWhen using `Timer` as a class, you can capture the elapsed time when calling `.stop()`:\n\n```python\nelapsed_time = t.stop()\n```\n\nYou can also find the last measured elapsed time in the `.last` attribute. The following code will have the same effect as the previous example:\n\n```python\nt.stop()\nelapsed_time = t.last\n```\n\n\n## Named Timers\n\nNamed timers are made available in the class dictionary `Timer.timers`. The elapsed time will accumulate if the same name or same timer is used several times. Consider the following example:\n\n```pycon\n\u003e\u003e\u003e import logging\n\u003e\u003e\u003e from codetiming import Timer\n\n\u003e\u003e\u003e t = Timer(\"example\", text=\"Time spent: {:.2f}\", logger=logging.warning)\n\n\u003e\u003e\u003e t.start()\n\u003e\u003e\u003e t.stop()\nWARNING:root:Time spent: 3.58\n3.5836678670002584\n\n\u003e\u003e\u003e with t:\n...     _ = list(range(100_000_000))\n... \nWARNING:root:Time spent: 1.73\n\n\u003e\u003e\u003e Timer.timers\n{'example': 5.312697440000193}\n```\n\nThe example shows how you can redirect the timer output to the logging module. Note that the elapsed time spent in the two different uses of `t` has been accumulated in `Timer.timers`.\n\nYou can also get simple statistics about your named timers. Continuing from the example above:\n\n```pycon\n\u003e\u003e\u003e Timer.timers.max(\"example\")\n3.5836678670002584\n\n\u003e\u003e\u003e Timer.timers.mean(\"example\")\n2.6563487200000964\n\n\u003e\u003e\u003e Timer.timers.stdev(\"example\")\n1.311427314335879\n```\n\n`timers` support `.count()`, `.total()`, `.min()`, `.max()`, `.mean()`, `.median()`, and `.stdev()`.\n\n\n## Acknowledgments\n\n`codetiming` is based on a similar module initially developed for the [Midgard Geodesy library](https://kartverket.github.io/midgard/) at the [Norwegian Mapping Authority](https://www.kartverket.no/en/).","funding_links":[],"categories":["Python"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frealpython%2Fcodetiming","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frealpython%2Fcodetiming","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frealpython%2Fcodetiming/lists"}