pylemetry 1.2.0__tar.gz → 1.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pylemetry-1.2.2/.github/actions/bump-version/action.yaml +32 -0
- {pylemetry-1.2.0 → pylemetry-1.2.2}/.github/actions/configure-uv/action.yaml +2 -1
- {pylemetry-1.2.0 → pylemetry-1.2.2}/.github/workflows/ci.yaml +4 -8
- pylemetry-1.2.2/.github/workflows/release.yaml +104 -0
- {pylemetry-1.2.0 → pylemetry-1.2.2}/PKG-INFO +8 -13
- {pylemetry-1.2.0 → pylemetry-1.2.2}/README.md +6 -11
- {pylemetry-1.2.0 → pylemetry-1.2.2}/pyproject.toml +2 -2
- {pylemetry-1.2.0 → pylemetry-1.2.2}/src/pylemetry/decorators/__init__.py +0 -1
- {pylemetry-1.2.0 → pylemetry-1.2.2}/src/pylemetry/decorators/count.py +4 -6
- {pylemetry-1.2.0 → pylemetry-1.2.2}/src/pylemetry/decorators/time.py +5 -7
- {pylemetry-1.2.0 → pylemetry-1.2.2}/src/pylemetry/meters/counter.py +1 -3
- {pylemetry-1.2.0 → pylemetry-1.2.2}/src/pylemetry/meters/gauge.py +1 -3
- {pylemetry-1.2.0 → pylemetry-1.2.2}/src/pylemetry/meters/meter.py +2 -5
- {pylemetry-1.2.0 → pylemetry-1.2.2}/src/pylemetry/meters/timer.py +3 -5
- {pylemetry-1.2.0 → pylemetry-1.2.2}/src/pylemetry/registry.py +5 -8
- {pylemetry-1.2.0 → pylemetry-1.2.2}/src/pylemetry/reporting/__init__.py +2 -3
- {pylemetry-1.2.0 → pylemetry-1.2.2}/src/pylemetry/reporting/logging.py +3 -3
- {pylemetry-1.2.0 → pylemetry-1.2.2}/src/pylemetry/reporting/reporter.py +6 -7
- {pylemetry-1.2.0 → pylemetry-1.2.2}/src/pylemetry/utils/__init__.py +0 -1
- {pylemetry-1.2.0 → pylemetry-1.2.2}/test/test_pylemetry/decorators/test_count.py +1 -3
- {pylemetry-1.2.0 → pylemetry-1.2.2}/test/test_pylemetry/decorators/test_time.py +2 -4
- {pylemetry-1.2.0 → pylemetry-1.2.2}/test/test_pylemetry/meters/test_timer.py +2 -1
- {pylemetry-1.2.0 → pylemetry-1.2.2}/test/test_pylemetry/reporting/test_logging.py +1 -1
- {pylemetry-1.2.0 → pylemetry-1.2.2}/test/test_pylemetry/reporting/test_reporter.py +1 -1
- {pylemetry-1.2.0 → pylemetry-1.2.2}/test/test_pylemetry/test_registry.py +1 -1
- {pylemetry-1.2.0 → pylemetry-1.2.2}/uv.lock +2 -2
- pylemetry-1.2.0/.github/workflows/release.yaml +0 -89
- {pylemetry-1.2.0 → pylemetry-1.2.2}/.gitignore +0 -0
- {pylemetry-1.2.0 → pylemetry-1.2.2}/LICENSE +0 -0
- {pylemetry-1.2.0 → pylemetry-1.2.2}/src/__init__.py +0 -0
- {pylemetry-1.2.0 → pylemetry-1.2.2}/src/pylemetry/__init__.py +0 -0
- {pylemetry-1.2.0 → pylemetry-1.2.2}/src/pylemetry/meters/__init__.py +0 -0
- {pylemetry-1.2.0 → pylemetry-1.2.2}/src/pylemetry/py.typed +0 -0
- {pylemetry-1.2.0 → pylemetry-1.2.2}/src/pylemetry/reporting/reporting_type.py +0 -0
- {pylemetry-1.2.0 → pylemetry-1.2.2}/src/pylemetry/utils/timer_units.py +0 -0
- {pylemetry-1.2.0 → pylemetry-1.2.2}/test/conftest.py +0 -0
- {pylemetry-1.2.0 → pylemetry-1.2.2}/test/test_pylemetry/meters/test_counter.py +0 -0
- {pylemetry-1.2.0 → pylemetry-1.2.2}/test/test_pylemetry/meters/test_gauge.py +0 -0
- {pylemetry-1.2.0 → pylemetry-1.2.2}/test/test_pylemetry/utils/test_timer_units.py +0 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
name: Bump version
|
|
2
|
+
description: Bump the project version and create a pull request
|
|
3
|
+
|
|
4
|
+
inputs:
|
|
5
|
+
github-token:
|
|
6
|
+
description: GitHub token
|
|
7
|
+
required: true
|
|
8
|
+
|
|
9
|
+
runs:
|
|
10
|
+
using: composite
|
|
11
|
+
steps:
|
|
12
|
+
- name: Bump Version
|
|
13
|
+
run: uv version --bump patch --bump alpha
|
|
14
|
+
shell: bash
|
|
15
|
+
|
|
16
|
+
- name: Get New Version Branch Name
|
|
17
|
+
id: bump_version
|
|
18
|
+
run: echo "branch_name=feature/bump_version_$(uv version --short)" >> $GITHUB_OUTPUT
|
|
19
|
+
shell: bash
|
|
20
|
+
|
|
21
|
+
- name: Commit Version Bump
|
|
22
|
+
uses: EndBug/add-and-commit@v11.1.1
|
|
23
|
+
with:
|
|
24
|
+
message: "Bump project version following release"
|
|
25
|
+
default_author: github_actions
|
|
26
|
+
new_branch: ${{ steps.bump_version.outputs.branch_name }}
|
|
27
|
+
|
|
28
|
+
- name: Raise Pull Request
|
|
29
|
+
run: gh pr create -B main -H ${{ steps.bump_version.outputs.branch_name }} --title "Update version to v$(uv version --short)" --body 'Created by GitHub Actions in the Release pipeline'
|
|
30
|
+
shell: bash
|
|
31
|
+
env:
|
|
32
|
+
GITHUB_TOKEN: ${{ inputs.github-token }}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
name: Configure uv
|
|
2
|
+
description: Configure uv for running within pipelines
|
|
2
3
|
runs:
|
|
3
4
|
using: composite
|
|
4
5
|
steps:
|
|
5
6
|
- name: Install uv
|
|
6
|
-
uses: astral-sh/setup-uv@
|
|
7
|
+
uses: astral-sh/setup-uv@v10.2.0
|
|
7
8
|
|
|
8
9
|
- name: Install dependencies
|
|
9
10
|
run: uv sync --locked --dev
|
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
name: Test, Build, and Publish
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
|
-
push:
|
|
5
|
-
branches:
|
|
6
|
-
- develop
|
|
7
4
|
pull_request:
|
|
8
5
|
branches:
|
|
9
6
|
- main
|
|
10
|
-
- develop
|
|
11
7
|
|
|
12
8
|
jobs:
|
|
13
9
|
lint:
|
|
@@ -15,11 +11,11 @@ jobs:
|
|
|
15
11
|
runs-on: ubuntu-latest
|
|
16
12
|
|
|
17
13
|
steps:
|
|
18
|
-
- uses: actions/checkout@
|
|
14
|
+
- uses: actions/checkout@v7.0.1
|
|
19
15
|
|
|
20
16
|
- uses: ./.github/actions/configure-uv
|
|
21
17
|
|
|
22
|
-
- uses: astral-sh/ruff-action@
|
|
18
|
+
- uses: astral-sh/ruff-action@v4.1.0
|
|
23
19
|
|
|
24
20
|
- name: Type Checks
|
|
25
21
|
run: uv run mypy .
|
|
@@ -29,7 +25,7 @@ jobs:
|
|
|
29
25
|
runs-on: ubuntu-latest
|
|
30
26
|
|
|
31
27
|
steps:
|
|
32
|
-
- uses: actions/checkout@
|
|
28
|
+
- uses: actions/checkout@v7.0.1
|
|
33
29
|
|
|
34
30
|
- uses: ./.github/actions/configure-uv
|
|
35
31
|
|
|
@@ -43,7 +39,7 @@ jobs:
|
|
|
43
39
|
needs: [lint, test]
|
|
44
40
|
|
|
45
41
|
steps:
|
|
46
|
-
- uses: actions/checkout@
|
|
42
|
+
- uses: actions/checkout@v7.0.1
|
|
47
43
|
|
|
48
44
|
- uses: ./.github/actions/configure-uv
|
|
49
45
|
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
inputs:
|
|
6
|
+
dry-run:
|
|
7
|
+
description: Run as a dry-run
|
|
8
|
+
type: boolean
|
|
9
|
+
bump-to-stable:
|
|
10
|
+
description: Bump the version to the next stable version
|
|
11
|
+
type: boolean
|
|
12
|
+
default: true
|
|
13
|
+
override-version:
|
|
14
|
+
description: Override the current version and set as the release version
|
|
15
|
+
type: string
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
lint:
|
|
19
|
+
name: Lint & Types
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v7.0.1
|
|
24
|
+
|
|
25
|
+
- uses: ./.github/actions/configure-uv
|
|
26
|
+
|
|
27
|
+
- uses: astral-sh/ruff-action@v4.1.0
|
|
28
|
+
|
|
29
|
+
- name: Type Checks
|
|
30
|
+
run: uv run mypy .
|
|
31
|
+
|
|
32
|
+
test:
|
|
33
|
+
name: Unit Tests
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v7.0.1
|
|
38
|
+
|
|
39
|
+
- uses: ./.github/actions/configure-uv
|
|
40
|
+
|
|
41
|
+
- name: Run tests with Tox
|
|
42
|
+
run: tox
|
|
43
|
+
|
|
44
|
+
publish:
|
|
45
|
+
name: Build & Publish
|
|
46
|
+
runs-on: ubuntu-latest
|
|
47
|
+
environment: release
|
|
48
|
+
needs: [lint, test]
|
|
49
|
+
permissions:
|
|
50
|
+
contents: write
|
|
51
|
+
pull-requests: write
|
|
52
|
+
|
|
53
|
+
steps:
|
|
54
|
+
- uses: actions/checkout@v7.0.1
|
|
55
|
+
with:
|
|
56
|
+
ssh-key: ${{ secrets.DEPLOY_KEY }}
|
|
57
|
+
|
|
58
|
+
- uses: ./.github/actions/configure-uv
|
|
59
|
+
|
|
60
|
+
- name: Set release version
|
|
61
|
+
if: ${{ inputs.bump-to-stable || inputs.override-version != '' }}
|
|
62
|
+
run: |
|
|
63
|
+
if [[ $OVERRIDE_VERSION != '' ]]; then
|
|
64
|
+
uv version $OVERRIDE_VERSION;
|
|
65
|
+
elif $BUMP_TO_STABLE; then
|
|
66
|
+
uv version --bump stable
|
|
67
|
+
fi;
|
|
68
|
+
env:
|
|
69
|
+
BUMP_TO_STABLE: ${{ inputs.bump-to-stable }}
|
|
70
|
+
OVERRIDE_VERSION: ${{ inputs.override-version }}
|
|
71
|
+
|
|
72
|
+
- name: Get version from uv
|
|
73
|
+
id: version
|
|
74
|
+
run: echo "version=$(uv version --short)" >> $GITHUB_OUTPUT
|
|
75
|
+
|
|
76
|
+
- name: Build
|
|
77
|
+
run: uv build
|
|
78
|
+
|
|
79
|
+
- name: Publish to PyPI
|
|
80
|
+
env:
|
|
81
|
+
PYPI_TOKEN: ${{ secrets.pypi_token }}
|
|
82
|
+
DRY_RUN: ${{ inputs.dry-run }}
|
|
83
|
+
run: |
|
|
84
|
+
if $DRY_RUN; then
|
|
85
|
+
uv publish --index pypi --dry-run --token $PYPI_TOKEN
|
|
86
|
+
else
|
|
87
|
+
uv publish --index pypi --token $PYPI_TOKEN
|
|
88
|
+
fi;
|
|
89
|
+
|
|
90
|
+
- name: GitHub Release
|
|
91
|
+
if: ${{ !inputs.dry-run }}
|
|
92
|
+
uses: ncipollo/release-action@v1
|
|
93
|
+
env:
|
|
94
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
95
|
+
with:
|
|
96
|
+
tag: ${{ steps.version.outputs.version }}
|
|
97
|
+
name: ${{ steps.version.outputs.version }}
|
|
98
|
+
artifacts: "dist/pylemetry-*.tar.gz,dist/pylemetry-*.whl"
|
|
99
|
+
|
|
100
|
+
- name: Bump Version
|
|
101
|
+
if: ${{ !inputs.dry-run }}
|
|
102
|
+
uses: ./.github/actions/bump-version
|
|
103
|
+
with:
|
|
104
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: pylemetry
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.2
|
|
4
4
|
Summary: A Python metrics library
|
|
5
5
|
Project-URL: Homepage, https://pypi.org/project/pylemetry/
|
|
6
6
|
Project-URL: Repository, https://github.com/amurphy4/pylemetry
|
|
@@ -60,13 +60,11 @@ from pylemetry.decorators import count
|
|
|
60
60
|
|
|
61
61
|
|
|
62
62
|
@count()
|
|
63
|
-
def some_method() -> None:
|
|
64
|
-
...
|
|
63
|
+
def some_method() -> None: ...
|
|
65
64
|
|
|
66
65
|
|
|
67
66
|
@count("named_counter")
|
|
68
|
-
def another_method() -> None:
|
|
69
|
-
...
|
|
67
|
+
def another_method() -> None: ...
|
|
70
68
|
|
|
71
69
|
|
|
72
70
|
def main() -> None:
|
|
@@ -145,20 +143,18 @@ from pylemetry.decorators import time
|
|
|
145
143
|
|
|
146
144
|
|
|
147
145
|
@time()
|
|
148
|
-
def some_method() -> None:
|
|
149
|
-
...
|
|
146
|
+
def some_method() -> None: ...
|
|
150
147
|
|
|
151
148
|
|
|
152
149
|
@time("named_timer")
|
|
153
|
-
def another_method() -> None:
|
|
154
|
-
...
|
|
150
|
+
def another_method() -> None: ...
|
|
155
151
|
|
|
156
152
|
|
|
157
153
|
def main() -> None:
|
|
158
154
|
for _ in range(100):
|
|
159
155
|
some_method()
|
|
160
156
|
another_method()
|
|
161
|
-
|
|
157
|
+
|
|
162
158
|
timer = registry.get_timer("some_method")
|
|
163
159
|
timer.get_count() # 100
|
|
164
160
|
timer.get_value() # Sum total execution time of the some_method function
|
|
@@ -209,8 +205,7 @@ from pylemetry.decorators import time
|
|
|
209
205
|
|
|
210
206
|
|
|
211
207
|
@time("example_timer", tags={"tag_1": "args[0]", "tag_2": "kwargs[param_2]", "tag_3": "some value"})
|
|
212
|
-
def some_method(param_1: int, param_2: int) -> None:
|
|
213
|
-
...
|
|
208
|
+
def some_method(param_1: int, param_2: int) -> None: ...
|
|
214
209
|
|
|
215
210
|
|
|
216
211
|
def main() -> None:
|
|
@@ -37,13 +37,11 @@ from pylemetry.decorators import count
|
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
@count()
|
|
40
|
-
def some_method() -> None:
|
|
41
|
-
...
|
|
40
|
+
def some_method() -> None: ...
|
|
42
41
|
|
|
43
42
|
|
|
44
43
|
@count("named_counter")
|
|
45
|
-
def another_method() -> None:
|
|
46
|
-
...
|
|
44
|
+
def another_method() -> None: ...
|
|
47
45
|
|
|
48
46
|
|
|
49
47
|
def main() -> None:
|
|
@@ -122,20 +120,18 @@ from pylemetry.decorators import time
|
|
|
122
120
|
|
|
123
121
|
|
|
124
122
|
@time()
|
|
125
|
-
def some_method() -> None:
|
|
126
|
-
...
|
|
123
|
+
def some_method() -> None: ...
|
|
127
124
|
|
|
128
125
|
|
|
129
126
|
@time("named_timer")
|
|
130
|
-
def another_method() -> None:
|
|
131
|
-
...
|
|
127
|
+
def another_method() -> None: ...
|
|
132
128
|
|
|
133
129
|
|
|
134
130
|
def main() -> None:
|
|
135
131
|
for _ in range(100):
|
|
136
132
|
some_method()
|
|
137
133
|
another_method()
|
|
138
|
-
|
|
134
|
+
|
|
139
135
|
timer = registry.get_timer("some_method")
|
|
140
136
|
timer.get_count() # 100
|
|
141
137
|
timer.get_value() # Sum total execution time of the some_method function
|
|
@@ -186,8 +182,7 @@ from pylemetry.decorators import time
|
|
|
186
182
|
|
|
187
183
|
|
|
188
184
|
@time("example_timer", tags={"tag_1": "args[0]", "tag_2": "kwargs[param_2]", "tag_3": "some value"})
|
|
189
|
-
def some_method(param_1: int, param_2: int) -> None:
|
|
190
|
-
...
|
|
185
|
+
def some_method(param_1: int, param_2: int) -> None: ...
|
|
191
186
|
|
|
192
187
|
|
|
193
188
|
def main() -> None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "pylemetry"
|
|
3
|
-
version = "1.2.
|
|
3
|
+
version = "1.2.2"
|
|
4
4
|
description = "A Python metrics library"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.10"
|
|
@@ -60,7 +60,7 @@ explicit_package_bases = true
|
|
|
60
60
|
line-length = 120
|
|
61
61
|
|
|
62
62
|
[tool.ruff.lint]
|
|
63
|
-
select = ["E", "F", "
|
|
63
|
+
select = ["ARG", "B", "E", "F", "I", "N", "RUF", "TID", "UP", "W"]
|
|
64
64
|
|
|
65
65
|
[tool.pytest.ini_options]
|
|
66
66
|
addopts = "--cov=pylemetry --cov-report=html"
|
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
import re
|
|
2
|
-
|
|
3
|
-
from typing import Callable, Optional, ParamSpec, TypeVar, Union
|
|
4
|
-
|
|
2
|
+
from collections.abc import Callable
|
|
5
3
|
from functools import wraps
|
|
4
|
+
from typing import ParamSpec, TypeVar
|
|
6
5
|
|
|
7
6
|
from pylemetry import registry
|
|
8
7
|
from pylemetry.meters import Counter
|
|
9
8
|
|
|
10
|
-
|
|
11
9
|
P = ParamSpec("P")
|
|
12
10
|
R = TypeVar("R", covariant=True)
|
|
13
11
|
|
|
14
12
|
|
|
15
13
|
def count(
|
|
16
|
-
name:
|
|
14
|
+
name: str | None = None, tags: dict[str, str | int | float] | None = None
|
|
17
15
|
) -> Callable[[Callable[P, R]], Callable[P, R]]:
|
|
18
16
|
"""
|
|
19
17
|
Decorator to count the number of invocations of a given callable. Creates a Counter meter in the Registry
|
|
@@ -29,7 +27,7 @@ def count(
|
|
|
29
27
|
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
|
|
30
28
|
counter_name = f.__qualname__ if name is None else name
|
|
31
29
|
|
|
32
|
-
_tags: dict[str,
|
|
30
|
+
_tags: dict[str, str | int | float] = {}
|
|
33
31
|
|
|
34
32
|
if tags:
|
|
35
33
|
for key, value in tags.items():
|
|
@@ -1,22 +1,20 @@
|
|
|
1
1
|
import re
|
|
2
|
-
|
|
3
|
-
from typing import Callable, Optional, ParamSpec, TypeVar, Union
|
|
4
|
-
|
|
2
|
+
from collections.abc import Callable
|
|
5
3
|
from functools import wraps
|
|
4
|
+
from typing import ParamSpec, TypeVar
|
|
6
5
|
|
|
7
6
|
from pylemetry import registry
|
|
8
7
|
from pylemetry.meters import Timer
|
|
9
8
|
from pylemetry.utils import TimerUnits
|
|
10
9
|
|
|
11
|
-
|
|
12
10
|
P = ParamSpec("P")
|
|
13
11
|
R = TypeVar("R", covariant=True)
|
|
14
12
|
|
|
15
13
|
|
|
16
14
|
def time(
|
|
17
|
-
name:
|
|
15
|
+
name: str | None = None,
|
|
18
16
|
unit: TimerUnits = TimerUnits.NANOSECONDS,
|
|
19
|
-
tags:
|
|
17
|
+
tags: dict[str, str | int | float] | None = None,
|
|
20
18
|
) -> Callable[[Callable[P, R]], Callable[P, R]]:
|
|
21
19
|
"""
|
|
22
20
|
Decorator to time the invocations of a given callable. Creates a Timer meter in the Registry with either the
|
|
@@ -33,7 +31,7 @@ def time(
|
|
|
33
31
|
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
|
|
34
32
|
time_name = f.__qualname__ if name is None else name
|
|
35
33
|
|
|
36
|
-
_tags: dict[str,
|
|
34
|
+
_tags: dict[str, str | int | float] = {}
|
|
37
35
|
|
|
38
36
|
if tags:
|
|
39
37
|
for key, value in tags.items():
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
from typing import Union, Optional
|
|
2
|
-
|
|
3
1
|
from pylemetry.meters.meter import Meter, MeterType
|
|
4
2
|
|
|
5
3
|
|
|
6
4
|
class Counter(Meter):
|
|
7
|
-
def __init__(self, name: str, tags:
|
|
5
|
+
def __init__(self, name: str, tags: dict[str, str | int | float] | None = None) -> None:
|
|
8
6
|
super().__init__(MeterType.COUNTER, name, tags)
|
|
9
7
|
|
|
10
8
|
def add(self, value: int = 1) -> None:
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
from typing import Union, Optional
|
|
2
|
-
|
|
3
1
|
from pylemetry.meters.meter import Meter, MeterType
|
|
4
2
|
|
|
5
3
|
|
|
6
4
|
class Gauge(Meter):
|
|
7
|
-
def __init__(self, name: str, tags:
|
|
5
|
+
def __init__(self, name: str, tags: dict[str, str | int | float] | None = None) -> None:
|
|
8
6
|
super().__init__(MeterType.GAUGE, name, tags)
|
|
9
7
|
|
|
10
8
|
def set_value(self, value: float):
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from enum import Enum
|
|
2
2
|
from threading import Lock
|
|
3
|
-
from typing import Union, Optional
|
|
4
3
|
|
|
5
4
|
|
|
6
5
|
class MeterType(Enum):
|
|
@@ -10,9 +9,7 @@ class MeterType(Enum):
|
|
|
10
9
|
|
|
11
10
|
|
|
12
11
|
class Meter:
|
|
13
|
-
def __init__(
|
|
14
|
-
self, meter_type: MeterType, name: str, tags: Optional[dict[str, Union[str, int, float]]] = None
|
|
15
|
-
) -> None:
|
|
12
|
+
def __init__(self, meter_type: MeterType, name: str, tags: dict[str, str | int | float] | None = None) -> None:
|
|
16
13
|
self.lock = Lock()
|
|
17
14
|
self.value = 0.0
|
|
18
15
|
self.last_interval_value = 0.0
|
|
@@ -46,5 +43,5 @@ class Meter:
|
|
|
46
43
|
with self.lock:
|
|
47
44
|
self.last_interval_value = self.value
|
|
48
45
|
|
|
49
|
-
def get_tags(self) -> dict[str,
|
|
46
|
+
def get_tags(self) -> dict[str, str | int | float]:
|
|
50
47
|
return self.__tags
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
from typing import Generator, Union, Optional
|
|
2
|
-
|
|
3
1
|
import time
|
|
4
|
-
|
|
2
|
+
from collections.abc import Generator
|
|
5
3
|
from contextlib import contextmanager
|
|
6
4
|
|
|
7
5
|
from pylemetry.meters.meter import Meter, MeterType
|
|
@@ -13,7 +11,7 @@ class Timer(Meter):
|
|
|
13
11
|
self,
|
|
14
12
|
name: str,
|
|
15
13
|
unit: TimerUnits = TimerUnits.NANOSECONDS,
|
|
16
|
-
tags:
|
|
14
|
+
tags: dict[str, str | int | float] | None = None,
|
|
17
15
|
) -> None:
|
|
18
16
|
super().__init__(MeterType.TIMER, name, tags)
|
|
19
17
|
|
|
@@ -32,7 +30,7 @@ class Timer(Meter):
|
|
|
32
30
|
self.ticks.append(tick)
|
|
33
31
|
|
|
34
32
|
@contextmanager
|
|
35
|
-
def time(self) -> Generator[None
|
|
33
|
+
def time(self) -> Generator[None]:
|
|
36
34
|
"""
|
|
37
35
|
Context manager to time in seconds a code block and add the result to the internal ticks list
|
|
38
36
|
"""
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from collections.abc import Mapping
|
|
2
|
-
from typing import Optional, Union
|
|
3
2
|
|
|
4
|
-
from pylemetry.meters import Counter, Gauge,
|
|
3
|
+
from pylemetry.meters import Counter, Gauge, Meter, MeterType, Timer
|
|
5
4
|
|
|
6
5
|
METERS: dict[MeterType, dict[str, Meter]] = {
|
|
7
6
|
MeterType.COUNTER: {},
|
|
@@ -40,9 +39,7 @@ def add_meter(meter: Meter) -> None:
|
|
|
40
39
|
METERS[meter.meter_type][combined_name] = meter
|
|
41
40
|
|
|
42
41
|
|
|
43
|
-
def get_meter(
|
|
44
|
-
name, meter_type: MeterType, tags: Optional[Mapping[str, Union[str, int, float]]] = None
|
|
45
|
-
) -> Optional[Meter]:
|
|
42
|
+
def get_meter(name, meter_type: MeterType, tags: Mapping[str, str | int | float] | None = None) -> Meter | None:
|
|
46
43
|
"""
|
|
47
44
|
Get a meter from the global registry by its name
|
|
48
45
|
|
|
@@ -86,7 +83,7 @@ def add_counter(counter: Counter) -> None:
|
|
|
86
83
|
add_meter(counter)
|
|
87
84
|
|
|
88
85
|
|
|
89
|
-
def get_counter(name: str, tags:
|
|
86
|
+
def get_counter(name: str, tags: Mapping[str, str | int | float] | None = None) -> Counter | None:
|
|
90
87
|
"""
|
|
91
88
|
Get a counter from the global registry by its name
|
|
92
89
|
|
|
@@ -120,7 +117,7 @@ def add_gauge(gauge: Gauge) -> None:
|
|
|
120
117
|
add_meter(gauge)
|
|
121
118
|
|
|
122
119
|
|
|
123
|
-
def get_gauge(name: str, tags:
|
|
120
|
+
def get_gauge(name: str, tags: Mapping[str, str | int | float] | None = None) -> Gauge | None:
|
|
124
121
|
"""
|
|
125
122
|
Get a gauge from the global registry by its name
|
|
126
123
|
|
|
@@ -154,7 +151,7 @@ def add_timer(timer: Timer) -> None:
|
|
|
154
151
|
add_meter(timer)
|
|
155
152
|
|
|
156
153
|
|
|
157
|
-
def get_timer(name: str, tags:
|
|
154
|
+
def get_timer(name: str, tags: Mapping[str, str | int | float] | None = None) -> Timer | None:
|
|
158
155
|
"""
|
|
159
156
|
Get a timer from the global registry by its name
|
|
160
157
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from .logging import LoggingReporter
|
|
2
|
-
from .reporting_type import ReportingType
|
|
3
2
|
from .reporter import Reporter
|
|
3
|
+
from .reporting_type import ReportingType
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
__all__ = ["LoggingReporter", "ReportingType", "Reporter"]
|
|
5
|
+
__all__ = ["LoggingReporter", "Reporter", "ReportingType"]
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import
|
|
2
|
+
from typing import ParamSpec, Protocol, TypeVar
|
|
3
3
|
|
|
4
4
|
from pylemetry import registry
|
|
5
5
|
from pylemetry.meters import MeterType
|
|
@@ -30,7 +30,7 @@ class LoggingReporter(Reporter):
|
|
|
30
30
|
level: int,
|
|
31
31
|
_type: ReportingType,
|
|
32
32
|
clear_registry_on_exit: bool = False,
|
|
33
|
-
universal_tags:
|
|
33
|
+
universal_tags: dict[str, str | int | float] | None = None,
|
|
34
34
|
) -> None:
|
|
35
35
|
super().__init__(interval, clear_registry_on_exit, universal_tags)
|
|
36
36
|
|
|
@@ -44,7 +44,7 @@ class LoggingReporter(Reporter):
|
|
|
44
44
|
MeterType.TIMER: "{name} [{type}] -- {value}",
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
def configure_message_format(self, message_format: str, meter_type:
|
|
47
|
+
def configure_message_format(self, message_format: str, meter_type: MeterType | None = None):
|
|
48
48
|
if not meter_type:
|
|
49
49
|
for _type in list(MeterType):
|
|
50
50
|
self.message_formats[_type] = message_format
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
from typing_extensions import Self
|
|
1
|
+
import threading
|
|
3
2
|
from types import TracebackType
|
|
4
3
|
|
|
5
|
-
import
|
|
4
|
+
from typing_extensions import Self
|
|
6
5
|
|
|
7
6
|
from pylemetry import registry
|
|
8
|
-
from pylemetry.meters import Counter, Gauge,
|
|
7
|
+
from pylemetry.meters import Counter, Gauge, Meter, Timer
|
|
9
8
|
|
|
10
9
|
|
|
11
10
|
class Reporter:
|
|
@@ -13,10 +12,10 @@ class Reporter:
|
|
|
13
12
|
self,
|
|
14
13
|
interval: float,
|
|
15
14
|
clear_registry_on_exit: bool = False,
|
|
16
|
-
universal_tags:
|
|
15
|
+
universal_tags: dict[str, str | int | float] | None = None,
|
|
17
16
|
) -> None:
|
|
18
17
|
self.interval = interval
|
|
19
|
-
self.__timer_thread:
|
|
18
|
+
self.__timer_thread: threading.Timer | None = None
|
|
20
19
|
self.running = False
|
|
21
20
|
self.clear_registry_on_exit = clear_registry_on_exit
|
|
22
21
|
|
|
@@ -31,7 +30,7 @@ class Reporter:
|
|
|
31
30
|
return self
|
|
32
31
|
|
|
33
32
|
def __exit__(
|
|
34
|
-
self, exc_type:
|
|
33
|
+
self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None
|
|
35
34
|
):
|
|
36
35
|
self.stop()
|
|
37
36
|
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from typing import Union
|
|
2
|
-
|
|
3
1
|
import pytest
|
|
4
2
|
|
|
5
3
|
from pylemetry import registry
|
|
@@ -123,7 +121,7 @@ def test_count_decorator_updates_existing_counter_with_tags(call_count: int) ->
|
|
|
123
121
|
def mock(value: str, value_2: int) -> None:
|
|
124
122
|
print(f"Mocked with '{value}' and '{value_2}'")
|
|
125
123
|
|
|
126
|
-
tags: dict[str,
|
|
124
|
+
tags: dict[str, str | int] = {"tag_1": "Hello World!", "tag_2": 2, "tag_3": "another_value"}
|
|
127
125
|
|
|
128
126
|
assert registry.get_counter(counter_name, tags=tags) is None
|
|
129
127
|
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
from typing import Union
|
|
2
|
-
|
|
3
1
|
import pytest
|
|
4
2
|
|
|
5
3
|
from pylemetry import registry
|
|
6
4
|
from pylemetry.decorators import time
|
|
7
|
-
from pylemetry.meters import
|
|
5
|
+
from pylemetry.meters import MeterType, Timer
|
|
8
6
|
from pylemetry.utils import TimerUnits
|
|
9
7
|
|
|
10
8
|
|
|
@@ -131,7 +129,7 @@ def test_time_decorator_updates_existing_timer_with_tags(call_count: int) -> Non
|
|
|
131
129
|
def mock(value: str, value_2: int) -> None:
|
|
132
130
|
print(f"Mocked with '{value}' and '{value_2}'")
|
|
133
131
|
|
|
134
|
-
tags: dict[str,
|
|
132
|
+
tags: dict[str, str | int] = {"tag_1": "Hello World!", "tag_2": 2, "tag_3": "another_value"}
|
|
135
133
|
|
|
136
134
|
assert registry.get_timer(timer_name, tags=tags) is None
|
|
137
135
|
|
|
@@ -7,7 +7,7 @@ from logot.loguru import LoguruCapturer
|
|
|
7
7
|
from loguru import logger as loguru_logger
|
|
8
8
|
|
|
9
9
|
from pylemetry import registry
|
|
10
|
-
from pylemetry.meters import Counter, Gauge,
|
|
10
|
+
from pylemetry.meters import Counter, Gauge, MeterType, Timer
|
|
11
11
|
from pylemetry.reporting import LoggingReporter, ReportingType
|
|
12
12
|
|
|
13
13
|
|
|
@@ -5,7 +5,7 @@ import pytest
|
|
|
5
5
|
|
|
6
6
|
from pylemetry import registry
|
|
7
7
|
from pylemetry.meters import Counter, Gauge, Timer
|
|
8
|
-
from pylemetry.reporting import
|
|
8
|
+
from pylemetry.reporting import LoggingReporter, Reporter, ReportingType
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
def test_reporter_base_class_cant_flush() -> None:
|
|
@@ -106,7 +106,7 @@ name = "exceptiongroup"
|
|
|
106
106
|
version = "1.3.0"
|
|
107
107
|
source = { registry = "https://pypi.org/simple" }
|
|
108
108
|
dependencies = [
|
|
109
|
-
{ name = "typing-extensions"
|
|
109
|
+
{ name = "typing-extensions" },
|
|
110
110
|
]
|
|
111
111
|
sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" }
|
|
112
112
|
wheels = [
|
|
@@ -257,7 +257,7 @@ wheels = [
|
|
|
257
257
|
|
|
258
258
|
[[package]]
|
|
259
259
|
name = "pylemetry"
|
|
260
|
-
version = "1.2.
|
|
260
|
+
version = "1.2.2"
|
|
261
261
|
source = { editable = "." }
|
|
262
262
|
dependencies = [
|
|
263
263
|
{ name = "typing-extensions" },
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
name: Release
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches:
|
|
6
|
-
- main
|
|
7
|
-
|
|
8
|
-
jobs:
|
|
9
|
-
lint:
|
|
10
|
-
name: Lint & Types
|
|
11
|
-
runs-on: ubuntu-latest
|
|
12
|
-
|
|
13
|
-
steps:
|
|
14
|
-
- uses: actions/checkout@v5
|
|
15
|
-
|
|
16
|
-
- uses: ./.github/actions/configure-uv
|
|
17
|
-
|
|
18
|
-
- uses: astral-sh/ruff-action@v3
|
|
19
|
-
|
|
20
|
-
- name: Type Checks
|
|
21
|
-
run: uv run mypy .
|
|
22
|
-
|
|
23
|
-
test:
|
|
24
|
-
name: Unit Tests
|
|
25
|
-
runs-on: ubuntu-latest
|
|
26
|
-
|
|
27
|
-
steps:
|
|
28
|
-
- uses: actions/checkout@v5
|
|
29
|
-
|
|
30
|
-
- uses: ./.github/actions/configure-uv
|
|
31
|
-
|
|
32
|
-
- name: Run tests with Tox
|
|
33
|
-
run: tox
|
|
34
|
-
|
|
35
|
-
publish:
|
|
36
|
-
name: Build & Publish
|
|
37
|
-
runs-on: ubuntu-latest
|
|
38
|
-
environment: release
|
|
39
|
-
needs: [lint, test]
|
|
40
|
-
permissions:
|
|
41
|
-
contents: write
|
|
42
|
-
pull-requests: write
|
|
43
|
-
|
|
44
|
-
steps:
|
|
45
|
-
- uses: actions/checkout@v5
|
|
46
|
-
with:
|
|
47
|
-
ssh-key: ${{ secrets.DEPLOY_KEY }}
|
|
48
|
-
|
|
49
|
-
- uses: ./.github/actions/configure-uv
|
|
50
|
-
|
|
51
|
-
- name: Get version from uv
|
|
52
|
-
id: version
|
|
53
|
-
run: echo "version=$(uv version --short)" >> $GITHUB_OUTPUT
|
|
54
|
-
|
|
55
|
-
- name: Build
|
|
56
|
-
run: uv build
|
|
57
|
-
|
|
58
|
-
- name: Publish to PyPI
|
|
59
|
-
env:
|
|
60
|
-
PYPI_TOKEN: ${{ secrets.pypi_token }}
|
|
61
|
-
run: uv publish --index pypi --token $PYPI_TOKEN
|
|
62
|
-
|
|
63
|
-
- name: GitHub Release
|
|
64
|
-
uses: ncipollo/release-action@v1
|
|
65
|
-
env:
|
|
66
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
67
|
-
with:
|
|
68
|
-
tag: ${{ steps.version.outputs.version }}
|
|
69
|
-
name: ${{ steps.version.outputs.version }}
|
|
70
|
-
artifacts: "dist/pylemetry-*.tar.gz,dist/pylemetry-*.whl"
|
|
71
|
-
|
|
72
|
-
- name: Bump Version
|
|
73
|
-
run: uv version --bump patch --bump alpha
|
|
74
|
-
|
|
75
|
-
- name: Get New Version Branch Name
|
|
76
|
-
id: bump_version
|
|
77
|
-
run: echo "branch_name=feature/bump_version_$(uv version --short)" >> $GITHUB_OUTPUT
|
|
78
|
-
|
|
79
|
-
- name: Commit Version Bump
|
|
80
|
-
uses: EndBug/add-and-commit@v9
|
|
81
|
-
with:
|
|
82
|
-
message: "Bump project version following release"
|
|
83
|
-
default_author: github_actions
|
|
84
|
-
new_branch: ${{ steps.bump_version.outputs.branch_name }}
|
|
85
|
-
|
|
86
|
-
- name: Raise Pull Request
|
|
87
|
-
run: gh pr create -B develop -H ${{ steps.bump_version.outputs.branch_name }} --title "Update version to v$(uv version --short)" --body 'Created by GitHub Actions in the Release pipeline'
|
|
88
|
-
env:
|
|
89
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|