Skip to main content

Provides a sub-microsecond-precise thread-safe timer and methods to work with date and time data.

Project description

ataraxis-time

A Python library that provides a sub-microsecond-precise thread-safe timer and methods to work with date and time data.

PyPI - Version PyPI - Python Version Ruff uv type-checked: mypy PyPI - License PyPI - Status PyPI - Wheel


Detailed Description

This library uses the 'chrono' C++ library to access the fastest available system clock and use it to provide interval timing and delay functionality via a Python binding API. While the performance of the timer heavily depends on the particular system configuration and utilization, most modern CPUs should be capable of sub-microsecond precision using this timer. Due to using a C-extension to provide interval and delay timing functionality, the library is thread- and process-safe and releases the GIL when using the appropriate delay command. Additionally, the library offers a set of standalone helper functions that can be used to manipulate date and time data.

The library can be used as a standalone module, but it is primarily designed to integrate with the broader 'Ataraxis' science-automation project, providing date- and time-related functionality to other project modules.


Features

  • Supports Windows, Linux, and OSx.
  • Sub-microsecond precision on modern CPUs (~ 3 GHz+) during delay and interval timing.
  • Releases GIL during (non-blocking) delay timing even when using microsecond and nanosecond precision.
  • Pure-python API.
  • Fast C++ core with direct extension API access via nanobind.
  • GPL 3 License.

Table of Contents


Dependencies

For users, all library dependencies are installed automatically for all supported installation methods (see Installation section). For developers, see the Developers section for information on installing additional development dependencies.


Installation

Source

Note. Building from source may require additional build-components to be available to compile the C++ portion of the library. It is highly advised to use the option to install from PIP or CONDA instead.

  1. Download this repository to your local machine using your preferred method, such as git-cloning. Optionally, use one of the stable releases that include precompiled binary wheels in addition to source code.
  2. cd to the root directory of the project using your CLI of choice.
  3. Run python -m pip install . to install the project. Alternatively, if using a distribution with precompiled binaries, use python -m pip install WHEEL_PATH, replacing 'WHEEL_PATH' with the path to the wheel file.
  4. Optionally, run the timer benchmark using benchmark_timer command from your CLI (no need to use 'python' directive). You can use benchmark_timer --help command to see the list of additional configuration parameters that can be used to customize the benchmark behavior.

PIP

Use the following command to install the library using PIP: pip install ataraxis-time

Conda / Mamba

Note. Due to conda-forge contributing process being more nuanced than pip uploads, conda versions may lag behind pip and source code distributions.

Use the following command to install the library using Conda or Mamba: conda install ataraxis-time


Usage

This is a minimal example of how to use the precision timer class from this library:

# First, import the timer class.
from ataraxis_time import PrecisionTimer
import time as tm

# Then, instantiate the timer class using the desired precision. Supported precisions are: 'ns' (nanoseconds),
# 'us' (microseconds), 'ms' (milliseconds), and 's' seconds.
timer = PrecisionTimer('us')

# Interval timing example
timer.reset()  # Resets (re-bases) the timer
tm.sleep(1)  # Simulates work (for 1 second)
print(f'Work time: {timer.elapsed} us')  # This returns the 'work' duration using the precision units of the timer.

print()  # Separates interval example from delay examples

# Delay example:
for i in range(10):
    print(f'us delay iteration: {i}')
    timer.delay_block(500)  # Delays for 500 microseconds, does not release the GIL

print()  # Separates the us loop from ms loop

timer.set_precision('ms')  # Switches timer precision to milliseconds
for i in range(10):
    print(f'ms delay iteration: {i}')
    timer.delay_noblock(500)  # Delays for 500 milliseconds, releases the GIL

This is a minimal example of how to use helper-functions from this library:

# Import the desired function(s) from the time_helpers sub-package.
from ataraxis_time.time_helpers import convert_time, get_timestamp

# Time converter example. The function can convert single inputs and lists / numpy arrays.
initial_time = 12
time_in_seconds = convert_time(time=initial_time, from_units='d', to_units='s')  # Returns 1036800.0

# Obtains the current date and time and uses it to generate a timestamp that can be used in file-names (for example).
dt = get_timestamp(time_separator='-')  # Returns 2024-06-18-00-06-25 (yyyy-mm-dd-hh-mm-ss)

API Documentation

See the API documentation for the detailed description of the methods and classes exposed by components of this library. The documentation also covers the C++ source code and any cli-interfaces (such as benchmark timer).


Developers

This section provides installation, dependency, and build-system instructions for the developers that want to modify the source code of this library. Additionally, it contains instructions for recreating the conda environments that were used during development from the included .yml files.

Installing the library

  1. Download this repository to your local machine using your preferred method, such as git-cloning.
  2. cd to the root directory of the project using your CLI of choice.
  3. Install development dependencies. You have multiple options of satisfying this requirement:
    1. Preferred Method: Use conda or pip to install tox or use an environment that has it installed and call tox -e import-env to automatically import the os-specific development environment included with the source code in your local conda distribution.
    2. Run python -m pip install .'[dev]' command to install development dependencies and the library. For some systems, you may need to use a slightly modified version of this command: python -m pip install .[dev].
    3. As long as you have an environment with tox installed and do not intend to run any code outside the predefined project automation pipelines, tox will automatically install all required dependencies for each task. Generally, this option is not recommended.

Note: When using tox automation, having a local version of the library may interfere with tox methods that attempt to build the library using an isolated environment. It is advised to remove the library from your test environment, or disconnect from the environment, prior to running any tox tasks. This problem is rarely observed with the latest version of the automation pipeline, but is worth mentioning.

Additional Dependencies

In addition to installing the required python packages, separately install the following dependencies:

  • Doxygen, if you want to generate C++ code documentation.
  • An appropriate build tool or Docker, if you intend to build binary wheels via cibuildwheel (See the link for information on which dependencies to install).
  • Python distributions, one for each version that you intend to support. Currently, this library supports 3.10, 3.11 and 3.12. The easiest way to get tox to work as intended is to have separate python distributions, but using pyenv is a good alternative too. This is needed for the 'test' task to work as intended

Development Automation

To help developers, this project comes with a set of fully configured 'tox'-based pipelines for verifying and building the project. Each of the tox commands builds the project in an isolated environment before carrying out its task. Some commands rely on the 'automation.py' module that provides the helper-scripts implemented in python. This module is stored in the source code root directory for each Sun Lab project.

  • tox -e stubs Builds the library and uses mypy-stubgen to generate the stubs for the library wheel and move them to the appropriate position in the '/src' directory. This enables mypy and other type-checkers to work with this library.
  • tox -e lint Checks and, where safe, fixes code formatting, style, and type-hinting.
  • tox -e {py310, py311, py312}-test Builds the library and executes the tests stored in the /tests directory using pytest-coverage module.
  • tox -e combine-test-reports Combines coverage reports from all test commands (for each python version) and compiles them into an interactive .html file stored inside '/reports' directory.
  • tox -e doxygen Uses externally installed Doxygen distribution to generate documentation from docstrings of the C++ source code files.
  • tox -e docs Uses Sphinx to generate API documentation from Python Google-style docstrings. If Doxygen-generated .xml files for the C++ extension are available, uses Breathe plugin to convert them to Sphinx-compatible format and add them to the final API .html file.
  • tox Sequentially carries out the commands above (in the same order). Use tox --parallel to parallelize command execution (may not work on all platforms).

The commands above are considered 'checkout' commands and generally required to pass before every code push. The commands below are not intended to be used as-frequently and, therefore, are not part of the 'generic' tox-flow.

  • tox -e build Builds the sdist and binary wheels for the library for all architectures supported by the host machine and saves them to the '/dist' directory.
  • tox -e upload Uploads the sdist and wheels to PIP using twine, if they have not yet been uploaded. Optionally use tox -e upload -- --replace-token true to replace the token stored in .pypirc file.
  • tox -e recipe Uses Grayskull to generate the conda-forge recipe from the latest available PIP-distribution. Assumes sdist is included with binary wheels when they are uploaded to PIP.
  • tox -e export-env Exports the os-specific local conda development environment as a .yml and spec.txt file to the '/envs' directory. This automatically uses the project-specific base-environment-name.
  • tox -e import-env Imports and os-specific conda development environment from the .yml file stored in the '/envs' directory.
  • tox -e rename-envs Replaces the base-name for all environment files inside the '/envs' directory. Remember to also change the base-name argument of the export-env command.

Environments

All environments used during development are exported as .yml files and as spec.txt files to the envs folder. The environment snapshots were taken on each of the three supported OS families: Windows 11, OSx 14.5 and Ubuntu Cinnamon 24.04 LTS.

To install the development environment for your OS:

  1. Download this repository to your local machine using your preferred method, such as git-cloning.
  2. cd into the envs folder.
  3. Use one of the installation methods below:
    1. Preferred Method: Install tox or use another environment with already installed tox and call tox -e import-env.
    2. Alternative Method: Run conda env create -f ENVNAME.yml or mamba env create -f ENVNAME.yml. Replace 'ENVNAME.yml' with the name of the environment you want to install (axt_dev_osx for OSx, axt_dev_win64 for Windows and axt_dev_lin64 for Linux).

Note: the OSx environment was built against M1 (Apple Silicon) platform and may not work on Intel-based Apple devices.


Authors


License

This project is licensed under the GPL3 License: see the LICENSE file for details.


Acknowledgments

  • All Sun Lab members for providing the inspiration and comments during the development of this library.
  • My NBB Cohort for answering 'random questions' pertaining to the desired library functionality.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ataraxis_time-1.0.3.tar.gz (86.3 kB view hashes)

Uploaded Source

Built Distributions

ataraxis_time-1.0.3-pp310-pypy310_pp73-win_amd64.whl (86.9 kB view hashes)

Uploaded PyPy Windows x86-64

ataraxis_time-1.0.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (105.1 kB view hashes)

Uploaded PyPy manylinux: glibc 2.17+ x86-64

ataraxis_time-1.0.3-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl (108.2 kB view hashes)

Uploaded PyPy manylinux: glibc 2.17+ i686

ataraxis_time-1.0.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (101.6 kB view hashes)

Uploaded PyPy manylinux: glibc 2.17+ ARM64

ataraxis_time-1.0.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl (79.0 kB view hashes)

Uploaded PyPy macOS 11.0+ ARM64

ataraxis_time-1.0.3-pp310-pypy310_pp73-macosx_10_15_x86_64.whl (80.2 kB view hashes)

Uploaded PyPy macOS 10.15+ x86-64

ataraxis_time-1.0.3-cp312-abi3-win_arm64.whl (81.2 kB view hashes)

Uploaded CPython 3.12+ Windows ARM64

ataraxis_time-1.0.3-cp312-abi3-win_amd64.whl (86.8 kB view hashes)

Uploaded CPython 3.12+ Windows x86-64

ataraxis_time-1.0.3-cp312-abi3-win32.whl (82.7 kB view hashes)

Uploaded CPython 3.12+ Windows x86

ataraxis_time-1.0.3-cp312-abi3-musllinux_1_2_x86_64.whl (539.4 kB view hashes)

Uploaded CPython 3.12+ musllinux: musl 1.2+ x86-64

ataraxis_time-1.0.3-cp312-abi3-musllinux_1_2_i686.whl (579.3 kB view hashes)

Uploaded CPython 3.12+ musllinux: musl 1.2+ i686

ataraxis_time-1.0.3-cp312-abi3-musllinux_1_2_aarch64.whl (519.6 kB view hashes)

Uploaded CPython 3.12+ musllinux: musl 1.2+ ARM64

ataraxis_time-1.0.3-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (105.3 kB view hashes)

Uploaded CPython 3.12+ manylinux: glibc 2.17+ x86-64

ataraxis_time-1.0.3-cp312-abi3-manylinux_2_17_i686.manylinux2014_i686.whl (108.2 kB view hashes)

Uploaded CPython 3.12+ manylinux: glibc 2.17+ i686

ataraxis_time-1.0.3-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (101.5 kB view hashes)

Uploaded CPython 3.12+ manylinux: glibc 2.17+ ARM64

ataraxis_time-1.0.3-cp312-abi3-macosx_11_0_arm64.whl (79.2 kB view hashes)

Uploaded CPython 3.12+ macOS 11.0+ ARM64

ataraxis_time-1.0.3-cp312-abi3-macosx_10_14_x86_64.whl (81.2 kB view hashes)

Uploaded CPython 3.12+ macOS 10.14+ x86-64

ataraxis_time-1.0.3-cp311-cp311-win_arm64.whl (82.7 kB view hashes)

Uploaded CPython 3.11 Windows ARM64

ataraxis_time-1.0.3-cp311-cp311-win_amd64.whl (88.8 kB view hashes)

Uploaded CPython 3.11 Windows x86-64

ataraxis_time-1.0.3-cp311-cp311-win32.whl (84.2 kB view hashes)

Uploaded CPython 3.11 Windows x86

ataraxis_time-1.0.3-cp311-cp311-musllinux_1_2_x86_64.whl (542.4 kB view hashes)

Uploaded CPython 3.11 musllinux: musl 1.2+ x86-64

ataraxis_time-1.0.3-cp311-cp311-musllinux_1_2_i686.whl (583.0 kB view hashes)

Uploaded CPython 3.11 musllinux: musl 1.2+ i686

ataraxis_time-1.0.3-cp311-cp311-musllinux_1_2_aarch64.whl (522.3 kB view hashes)

Uploaded CPython 3.11 musllinux: musl 1.2+ ARM64

ataraxis_time-1.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (108.2 kB view hashes)

Uploaded CPython 3.11 manylinux: glibc 2.17+ x86-64

ataraxis_time-1.0.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl (111.4 kB view hashes)

Uploaded CPython 3.11 manylinux: glibc 2.17+ i686

ataraxis_time-1.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (104.1 kB view hashes)

Uploaded CPython 3.11 manylinux: glibc 2.17+ ARM64

ataraxis_time-1.0.3-cp311-cp311-macosx_11_0_arm64.whl (81.5 kB view hashes)

Uploaded CPython 3.11 macOS 11.0+ ARM64

ataraxis_time-1.0.3-cp311-cp311-macosx_10_14_x86_64.whl (83.7 kB view hashes)

Uploaded CPython 3.11 macOS 10.14+ x86-64

ataraxis_time-1.0.3-cp310-cp310-win_arm64.whl (82.8 kB view hashes)

Uploaded CPython 3.10 Windows ARM64

ataraxis_time-1.0.3-cp310-cp310-win_amd64.whl (89.0 kB view hashes)

Uploaded CPython 3.10 Windows x86-64

ataraxis_time-1.0.3-cp310-cp310-win32.whl (84.3 kB view hashes)

Uploaded CPython 3.10 Windows x86

ataraxis_time-1.0.3-cp310-cp310-musllinux_1_2_x86_64.whl (542.6 kB view hashes)

Uploaded CPython 3.10 musllinux: musl 1.2+ x86-64

ataraxis_time-1.0.3-cp310-cp310-musllinux_1_2_i686.whl (583.4 kB view hashes)

Uploaded CPython 3.10 musllinux: musl 1.2+ i686

ataraxis_time-1.0.3-cp310-cp310-musllinux_1_2_aarch64.whl (522.2 kB view hashes)

Uploaded CPython 3.10 musllinux: musl 1.2+ ARM64

ataraxis_time-1.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (108.3 kB view hashes)

Uploaded CPython 3.10 manylinux: glibc 2.17+ x86-64

ataraxis_time-1.0.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl (111.6 kB view hashes)

Uploaded CPython 3.10 manylinux: glibc 2.17+ i686

ataraxis_time-1.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (104.2 kB view hashes)

Uploaded CPython 3.10 manylinux: glibc 2.17+ ARM64

ataraxis_time-1.0.3-cp310-cp310-macosx_11_0_arm64.whl (81.7 kB view hashes)

Uploaded CPython 3.10 macOS 11.0+ ARM64

ataraxis_time-1.0.3-cp310-cp310-macosx_10_14_x86_64.whl (83.8 kB view hashes)

Uploaded CPython 3.10 macOS 10.14+ x86-64

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page