Computational Stopwatch
Simple stopwatch to easily print the elapsed time of a set of operations. It's a minimalistic library, but it is very useful in many real cases.
Installation
pip install computational_stopwatch
or
conda install -c <your-anaconda-channel> computational_stopwatch
Usage
The easiest way to use this tool is in conjunction with the with python statement:
>> from computational_stopwatch import Stopwatch
>>
>> with Stopwatch():
>> time.sleep(3) # <- simulates a computation
Elapsed time 0:00:03.003106
Anything within the scope of the with statement will count against the elapsed time. An optional task name to be printed along the elapsed time (e.g. for better identification in a log) can be set in the constructor. This name will be prepended to the printed message. This is useful to track the elapsed time of several tasks ran in sequence.
>> with Stopwatch("My short task"):
>> time.sleep(3) # <- simulates a computation
My short task complete. Elapsed time 0:00:03.003106
Alternatively to the use with the with statment, the class can be directly instantiated and the print function explicitly called.
>> sw = Stopwatch()
>> time.sleep(3)
>> sw.print_elapsed_time()
Elapsed time 0:00:03.003280
or simply
>> sw = Stopwatch()
>> time.sleep(3)
>> print(sw)
0:00:03.003269
The start time can be reset with the reset_time function and the get_elapsed_time method returns the unformatted elapsed time, which is useful for numerical comparisons.
Different verbosity levels can be set in the constructor, with 2 as the default level, with 1 only the time is printed when the object is deleted, and with 0 nothing is printed. This is convenient to directly assess the elapsed time in seconds without any rogue prints on deletion:
>> sw = Stopwatch(verbosity=0)
>> time.sleep(3)
>> t = sw.get_elapsed_time()
>> print(t)
3.0032315254211426
By default, everything is printed on the standard output. Further or alternative streams can be set in the constructor. For instance, the folowing snipped:
>> log_file = open('/tmp/my_log_file.txt','w')
>> with Stopwatch("My logged task", streams=[sys.stdout, log_file]):
>> time.sleep(3) # <- simulates a computation
My logged task complete. Elapsed time 0:00:03.002731
prints the message both on the standard output as well as in the log file for future perusal.
Releasing
Releases are cut by pushing a git tag; nothing is published by hand.
The version lives in exactly one place, __version__ in
computational_stopwatch/stopwatch.py. Both setup.py and
conda-recipe/meta.yaml read it from there, so the PyPI and conda packages can
never disagree about what they ship.
Release steps
- Bump the version in
computational_stopwatch/stopwatch.py:__version__ = '1.0.6'
- Write the changelog entry in
HISTORY.md, with a heading that matches the new version exactly:## v1.0.6 - what changed
- Commit onto
main:git checkout main git add computational_stopwatch/stopwatch.py HISTORY.md git commit -m 'release v1.0.6'
- Tag and push. The tag must be
v+ the version from step 1:git tag -a v1.0.6 -m 'v1.0.6' git push origin main --follow-tags
- Watch the pipeline in GitLab → Build → Pipelines. On success the release
is live on both indexes:
pip install computational_stopwatch==1.0.6 conda install -c <your-anaconda-channel> computational_stopwatch=1.0.6
What the pipeline does
The v* tag triggers .gitlab-ci.yml, which runs three stages:
| Stage | Job | What it does |
|---|---|---|
verify |
verify tag |
Refuses the release unless the tag matches __version__, the tagged commit is an ancestor of main, and HISTORY.md has the matching section |
build |
build sdist and wheel |
python -m build plus twine check |
release |
publish to pypi |
Uploads dist/* to PyPI |
release |
publish to anaconda |
conda build conda-recipe and uploads the noarch package to anaconda.org |
If verify tag fails, nothing is uploaded anywhere — fix the mismatch, delete
the tag (git tag -d v1.0.6 && git push origin :refs/tags/v1.0.6), and tag again.
Required CI/CD variables
Set these in GitLab → Settings → CI/CD → Variables, all Masked and Protected. No secret belongs in the repository.
| Variable | Value |
|---|---|
PYPI_API_TOKEN |
PyPI API token, including the pypi- prefix |
ANACONDA_API_TOKEN |
anaconda.org token with allow write permission |
ANACONDA_USER |
anaconda.org user or organisation to upload into |
Because the variables are Protected, add v* under Settings → Repository →
Protected tags, otherwise the release jobs cannot see them.
Running the tests
The suite is developer-only and is not part of any published package.
pip install -e . pytest
pytest
It runs in the verify stage of the pipeline on every branch, merge request and
tag, and a tagged release will not publish unless it is green.
Building locally
python -m build # dist/*.whl, dist/*.tar.gz
conda build conda-recipe -c conda-forge # noarch conda package
Versions History
v1.0.8
- package version (pip and conda) is now derived directly from the git tag via
setuptools_scm, instead of a hardcoded__version__
v1.0.5
- minor fix
v1.0.4
- added
HISTORY.mdin the pip package for compatibility with the conda packaging
v1.0.3
- added
__str__function to easily include just the time stamp inside other strings
v1.0.2
- updated the README
- added multiple streams functionality
v1.0.1
- minor fixes
v1.0.0
- first reelease
Release files for computational-stopwatch 1.0.8
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| computational_stopwatch-1.0.8.tar.gz | 8.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| computational_stopwatch-1.0.8-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 14.9 kB
Release files / computational_stopwatch-1.0.8.tar.gz
| Download URL | computational_stopwatch-1.0.8.tar.gz |
|---|---|
| Size | 8.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7893622ddbf02b3ef7717b3383414b77403d67fb640e873ea8c7c193bd989e1b
|
|
BLAKE2b-256 checksum How to use checksums |
4833b3b40003c5aeb2fe479ca1f4032c2c44697010cfe5775f874043957fca02
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.16
|
Release files / computational_stopwatch-1.0.8-py3-none-any.whl
| Download URL | computational_stopwatch-1.0.8-py3-none-any.whl |
|---|---|
| Size | 6.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cc9b17f1f5e2e7b09543010eb5e1e3b83127f72abd560a49bd0fd0bbe4fd2bef
|
|
BLAKE2b-256 checksum How to use checksums |
c0f29874d19ba0648262d258fb74f2a1d43a91c502cfde94eb5076a6472882d2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.16
|