cmsdials 2.4.0__tar.gz → 3.0.0__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.
Files changed (94) hide show
  1. {cmsdials-2.4.0 → cmsdials-3.0.0}/.gitlab-ci.yml +1 -1
  2. cmsdials-3.0.0/PKG-INFO +159 -0
  3. cmsdials-3.0.0/README.md +136 -0
  4. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/_version.py +3 -3
  5. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/auth/client.py +8 -16
  6. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/ml_bad_lumisection/client.py +1 -2
  7. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/cmsdials.py +0 -2
  8. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/filters.py +0 -3
  9. cmsdials-3.0.0/cmsdials.egg-info/PKG-INFO +159 -0
  10. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials.egg-info/SOURCES.txt +0 -6
  11. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials.egg-info/scm_file_list.json +0 -6
  12. cmsdials-3.0.0/cmsdials.egg-info/scm_version.json +8 -0
  13. {cmsdials-2.4.0 → cmsdials-3.0.0}/tests/integration/env.py +10 -10
  14. {cmsdials-2.4.0 → cmsdials-3.0.0}/tests/integration/test_auth_client.py +3 -24
  15. {cmsdials-2.4.0 → cmsdials-3.0.0}/tests/integration/utils.py +5 -12
  16. {cmsdials-2.4.0 → cmsdials-3.0.0}/tests/unit/test_auth.py +11 -55
  17. cmsdials-2.4.0/PKG-INFO +0 -435
  18. cmsdials-2.4.0/README.md +0 -412
  19. cmsdials-2.4.0/cmsdials/auth/bearer.py +0 -62
  20. cmsdials-2.4.0/cmsdials/auth/secret_key.py +0 -68
  21. cmsdials-2.4.0/cmsdials/clients/oms_proxy/client.py +0 -68
  22. cmsdials-2.4.0/cmsdials/clients/oms_proxy/models.py +0 -14
  23. cmsdials-2.4.0/cmsdials.egg-info/PKG-INFO +0 -435
  24. cmsdials-2.4.0/cmsdials.egg-info/scm_version.json +0 -8
  25. cmsdials-2.4.0/tests/integration/test_oms_proxy_client.py +0 -60
  26. cmsdials-2.4.0/tests/unit/__init__.py +0 -0
  27. {cmsdials-2.4.0 → cmsdials-3.0.0}/.coveragerc +0 -0
  28. {cmsdials-2.4.0 → cmsdials-3.0.0}/.editorconfig +0 -0
  29. {cmsdials-2.4.0 → cmsdials-3.0.0}/.gitignore +0 -0
  30. {cmsdials-2.4.0 → cmsdials-3.0.0}/.mailmap +0 -0
  31. {cmsdials-2.4.0 → cmsdials-3.0.0}/.pre-commit-config.yaml +0 -0
  32. {cmsdials-2.4.0 → cmsdials-3.0.0}/.tool-versions +0 -0
  33. {cmsdials-2.4.0 → cmsdials-3.0.0}/LICENSE +0 -0
  34. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/__init__.py +0 -0
  35. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/auth/__init__.py +0 -0
  36. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/auth/_base.py +0 -0
  37. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/auth/client_credentials.py +0 -0
  38. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/auth/device.py +0 -0
  39. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/auth/exceptions.py +0 -0
  40. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/auth/models.py +0 -0
  41. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/__init__.py +0 -0
  42. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/dataset_index/__init__.py +0 -0
  43. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/dataset_index/client.py +0 -0
  44. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/dataset_index/models.py +0 -0
  45. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/file_index/__init__.py +0 -0
  46. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/file_index/client.py +0 -0
  47. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/file_index/models.py +0 -0
  48. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/h1d/__init__.py +0 -0
  49. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/h1d/client.py +0 -0
  50. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/h1d/models.py +0 -0
  51. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/h2d/__init__.py +0 -0
  52. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/h2d/client.py +0 -0
  53. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/h2d/models.py +0 -0
  54. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/lumisection/__init__.py +0 -0
  55. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/lumisection/client.py +0 -0
  56. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/lumisection/models.py +0 -0
  57. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/mes/__init__.py +0 -0
  58. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/mes/client.py +0 -0
  59. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/mes/models.py +0 -0
  60. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/ml_bad_lumisection/__init__.py +0 -0
  61. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/ml_bad_lumisection/models.py +0 -0
  62. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/ml_models_index/__init__.py +0 -0
  63. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/ml_models_index/client.py +0 -0
  64. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/ml_models_index/models.py +0 -0
  65. {cmsdials-2.4.0/cmsdials/clients/oms_proxy → cmsdials-3.0.0/cmsdials/clients/run}/__init__.py +0 -0
  66. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/run/client.py +0 -0
  67. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/run/models.py +0 -0
  68. {cmsdials-2.4.0/cmsdials/clients/run → cmsdials-3.0.0/cmsdials/clients/workspace}/__init__.py +0 -0
  69. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/clients/workspace/client.py +0 -0
  70. {cmsdials-2.4.0/cmsdials/clients/workspace → cmsdials-3.0.0/cmsdials/utils}/__init__.py +0 -0
  71. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/utils/_json.py +0 -0
  72. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/utils/api_client.py +0 -0
  73. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/utils/base_model.py +0 -0
  74. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials/utils/logger.py +0 -0
  75. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials.egg-info/dependency_links.txt +0 -0
  76. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials.egg-info/requires.txt +0 -0
  77. {cmsdials-2.4.0 → cmsdials-3.0.0}/cmsdials.egg-info/top_level.txt +0 -0
  78. {cmsdials-2.4.0 → cmsdials-3.0.0}/mypy.ini +0 -0
  79. {cmsdials-2.4.0 → cmsdials-3.0.0}/pyproject.toml +0 -0
  80. {cmsdials-2.4.0 → cmsdials-3.0.0}/pytest.ini +0 -0
  81. {cmsdials-2.4.0 → cmsdials-3.0.0}/ruff.toml +0 -0
  82. {cmsdials-2.4.0 → cmsdials-3.0.0}/setup.cfg +0 -0
  83. {cmsdials-2.4.0/cmsdials/utils → cmsdials-3.0.0/tests/integration}/__init__.py +0 -0
  84. {cmsdials-2.4.0 → cmsdials-3.0.0}/tests/integration/test_file_index_client.py +0 -0
  85. {cmsdials-2.4.0 → cmsdials-3.0.0}/tests/integration/test_h1d_client.py +0 -0
  86. {cmsdials-2.4.0 → cmsdials-3.0.0}/tests/integration/test_h2d_client.py +0 -0
  87. {cmsdials-2.4.0 → cmsdials-3.0.0}/tests/integration/test_lumisection_client.py +0 -0
  88. {cmsdials-2.4.0 → cmsdials-3.0.0}/tests/integration/test_mes_client.py +0 -0
  89. {cmsdials-2.4.0 → cmsdials-3.0.0}/tests/integration/test_resume.py +0 -0
  90. {cmsdials-2.4.0 → cmsdials-3.0.0}/tests/integration/test_run_client.py +0 -0
  91. {cmsdials-2.4.0/tests/integration → cmsdials-3.0.0/tests/unit}/__init__.py +0 -0
  92. {cmsdials-2.4.0 → cmsdials-3.0.0}/tests/unit/test_base_api_client.py +0 -0
  93. {cmsdials-2.4.0 → cmsdials-3.0.0}/tox.ini +0 -0
  94. {cmsdials-2.4.0 → cmsdials-3.0.0}/uv.lock +0 -0
@@ -82,7 +82,7 @@ test_matrix:
82
82
  path: coverage.xml
83
83
  variables:
84
84
  CLIENT_SECRET: "$CLIENT_SECRET"
85
- # Application owning CLIENT_SECRET, enables the api-access token tests
85
+ # Application owning CLIENT_SECRET, required by the integration tests
86
86
  CLIENT_ID: "cms-dials-dev-api-client-test"
87
87
  rules:
88
88
  - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
@@ -0,0 +1,159 @@
1
+ Metadata-Version: 2.4
2
+ Name: cmsdials
3
+ Version: 3.0.0
4
+ Summary: The Python api client interface to DIALS service
5
+ Author-email: Gabriel Moreira <gabriel.moreira@cern.ch>
6
+ Project-URL: Repository, https://gitlab.cern.ch/cms-dqmdc/libraries/dials-py
7
+ Classifier: Development Status :: 5 - Production/Stable
8
+ Classifier: Programming Language :: Python :: 3.9
9
+ Classifier: Programming Language :: Python :: 3.10
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Requires-Python: >=3.9
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Requires-Dist: requests<3.0.0,>=2.31.0
16
+ Requires-Dist: urllib3<2.0.0,>=1.26.16
17
+ Requires-Dist: pydantic<3.0.0,>=2.8.2
18
+ Provides-Extra: pandas
19
+ Requires-Dist: pandas>=1.5.3; extra == "pandas"
20
+ Provides-Extra: tqdm
21
+ Requires-Dist: tqdm>=4.66.1; extra == "tqdm"
22
+ Dynamic: license-file
23
+
24
+ ![Build Status](https://gitlab.cern.ch/cms-ppd/technical-support/libraries/dials-py/badges/develop/pipeline.svg)
25
+ ![Coverage](https://gitlab.cern.ch/cms-ppd/technical-support/libraries/dials-py/badges/develop/coverage.svg)
26
+ ![Latest Release](https://gitlab.cern.ch/cms-ppd/technical-support/libraries/dials-py/-/badges/release.svg)
27
+ [![PyPI version](https://badge.fury.io/py/cmsdials.png)](https://badge.fury.io/py/cmsdials)
28
+
29
+ # dials-py
30
+
31
+ The Python client of the [DIALS](https://cms-ppd.docs.cern.ch/ts/software/DIALS/index.html) API.
32
+
33
+ The full documentation, with every endpoint, filters, pandas and progress bar support, retrying and resuming long queries, ML certification JSONs and the development instance, is in the [dials-py user guide](https://cms-ppd.docs.cern.ch/ts/software/DIALS/user_guide/dials_py.html).
34
+
35
+ ## Installation
36
+
37
+ ```bash
38
+ pip install cmsdials
39
+ ```
40
+
41
+ The `pandas` and `tqdm` extras enable conversion to DataFrames and progress bars:
42
+
43
+ ```bash
44
+ pip install "cmsdials[pandas,tqdm]"
45
+ ```
46
+
47
+ ## Usage
48
+
49
+ Tokens are issued by CERN's Keycloak directly, dials-py never sends your password or a client secret to DIALS.
50
+
51
+ To log in as yourself, with the device flow (interactive, the credentials are cached in `.cache/` and renewed automatically):
52
+
53
+ ```python
54
+ from cmsdials.auth.device import Credentials
55
+
56
+ creds = Credentials.from_creds_file()
57
+ ```
58
+
59
+ To log in as an application, with its client id and secret (unattended scripts, the application must be granted [API access](https://cms-ppd.docs.cern.ch/ts/software/DIALS/user_guide/api_access.html)):
60
+
61
+ ```python
62
+ import os
63
+
64
+ from cmsdials.auth.client_credentials import Credentials
65
+
66
+ creds = Credentials(client_id="my-application", client_secret=os.environ["CLIENT_SECRET"])
67
+ ```
68
+
69
+ Then query DIALS, optionally in another workspace than the one picked from your e-groups:
70
+
71
+ ```python
72
+ from cmsdials import Dials
73
+ from cmsdials.filters import LumisectionHistogram1DFilters
74
+
75
+ dials = Dials(creds, workspace="tracker")
76
+
77
+ data = dials.h1d.list_all(
78
+ LumisectionHistogram1DFilters(me="PixelPhase1/Tracks/PXBarrel/charge_PXLayer_2"),
79
+ max_pages=5,
80
+ )
81
+ ```
82
+
83
+ ## Development
84
+
85
+ Install the dependencies and the package using `uv`:
86
+
87
+ ```shell
88
+ uv sync --all-groups --extra pandas --extra tqdm
89
+ uv run pre-commit install
90
+ uv pip install -e .
91
+ ```
92
+
93
+ ### Running tests
94
+
95
+ The repository has some tests written to make sure DIALS responses are compatible with pydantic metaclasses, you can use pytest to run all tests but you need to specify the client id and secret of an application to authenticate non-interactively against DIALS api:
96
+
97
+ ```bash
98
+ CLIENT_SECRET=... CLIENT_ID=... uv run pytest tests
99
+ ```
100
+
101
+ Any application granted API access in DIALS can be used: `CLIENT_ID` is its client id and `CLIENT_SECRET` its client secret, both obtained from the applications portal. Tests target the dev Keycloak applications by default, overwrite them with `AUTH_CLIENT_ID` and `AUTH_AUDIENCE`. The interactive authentication flow should be tested manually, an example for this can be found in [test_auth_client.py](/tests/integration/test_auth_client.py).
102
+
103
+ If testing against a local version of DIALS you need to specify the BASE_URL:
104
+
105
+ ```bash
106
+ CLIENT_SECRET=... CLIENT_ID=... BASE_URL=http://localhost:8000 uv run pytest tests
107
+ ```
108
+
109
+ #### Tox
110
+
111
+ Tox is pre-configured in `tox.ini`, so you can run the following to test against multiple python versions locally:
112
+
113
+ ```bash
114
+ CLIENT_SECRET=... CLIENT_ID=... uv run tox
115
+ ```
116
+
117
+ **[asdf](https://asdf-vm.com/) users**
118
+
119
+ tox requires multiple versions of Python to be installed. Using `asdf`, you have multiple versions installed, but they aren’t normally exposed to the current shell. You can use the following command to expose multiple versions of Python in the current directory:
120
+
121
+ ```bash
122
+ asdf set python 3.12.9 3.11.10 3.10.13 3.9.19
123
+ ```
124
+
125
+ This will use `3.12.9` by default (if you just run `python`), but it will also put `python3.11`, `python3.10` and `python3.9` symlinks in your path so you can run those too (which is exactly what tox is looking for).
126
+
127
+ ### Releasing the package on PyPI
128
+
129
+ The package is available in PyPI at [cmsdials](https://pypi.org/project/cmsdials/), under the [cmsdqm](https://pypi.org/org/cms-dqm/) organization. You'll need at leat Mantainer rights to be able to push new versions.
130
+
131
+ #### CI
132
+
133
+ Do not worry. The GitLab CI is configured to automatically publish the package on PyPI and the release notes in GitLab whever a tag is pushed to the repo.
134
+
135
+ > [!NOTE]
136
+ > For this to work the CI/CD variables named `UV_PUBLISH_TOKEN`, `GITLAB_TOKEN` should be registered in gitlab. The `UV_PUBLISH_TOKEN` is a api token access of CMSDQM organization and the `GITLAB_TOKEN` is a Project Access Token with api read/write rights, which is needed to read merge requests using the `glab-cli`.
137
+ > https://gitlab.cern.ch/cms-dqmdc/libraries/dials-py/-/settings/access_tokens
138
+
139
+ #### Manual
140
+
141
+ If you want to follow the manual approach, you need to first build and then publish.
142
+
143
+ ##### Build
144
+
145
+ You can use uv to build the package using:
146
+
147
+ ```bash
148
+ uv build
149
+ ```
150
+
151
+ The build system will automatically update the package version based on the git tag of the current commit.
152
+
153
+ ##### Publish
154
+
155
+ Provided you have already generate a PyPI api token in your account or in CMDQM org, you can publish using:
156
+
157
+ ```bash
158
+ UV_PUBLISH_TOKEN=... uv publish
159
+ ```
@@ -0,0 +1,136 @@
1
+ ![Build Status](https://gitlab.cern.ch/cms-ppd/technical-support/libraries/dials-py/badges/develop/pipeline.svg)
2
+ ![Coverage](https://gitlab.cern.ch/cms-ppd/technical-support/libraries/dials-py/badges/develop/coverage.svg)
3
+ ![Latest Release](https://gitlab.cern.ch/cms-ppd/technical-support/libraries/dials-py/-/badges/release.svg)
4
+ [![PyPI version](https://badge.fury.io/py/cmsdials.png)](https://badge.fury.io/py/cmsdials)
5
+
6
+ # dials-py
7
+
8
+ The Python client of the [DIALS](https://cms-ppd.docs.cern.ch/ts/software/DIALS/index.html) API.
9
+
10
+ The full documentation, with every endpoint, filters, pandas and progress bar support, retrying and resuming long queries, ML certification JSONs and the development instance, is in the [dials-py user guide](https://cms-ppd.docs.cern.ch/ts/software/DIALS/user_guide/dials_py.html).
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ pip install cmsdials
16
+ ```
17
+
18
+ The `pandas` and `tqdm` extras enable conversion to DataFrames and progress bars:
19
+
20
+ ```bash
21
+ pip install "cmsdials[pandas,tqdm]"
22
+ ```
23
+
24
+ ## Usage
25
+
26
+ Tokens are issued by CERN's Keycloak directly, dials-py never sends your password or a client secret to DIALS.
27
+
28
+ To log in as yourself, with the device flow (interactive, the credentials are cached in `.cache/` and renewed automatically):
29
+
30
+ ```python
31
+ from cmsdials.auth.device import Credentials
32
+
33
+ creds = Credentials.from_creds_file()
34
+ ```
35
+
36
+ To log in as an application, with its client id and secret (unattended scripts, the application must be granted [API access](https://cms-ppd.docs.cern.ch/ts/software/DIALS/user_guide/api_access.html)):
37
+
38
+ ```python
39
+ import os
40
+
41
+ from cmsdials.auth.client_credentials import Credentials
42
+
43
+ creds = Credentials(client_id="my-application", client_secret=os.environ["CLIENT_SECRET"])
44
+ ```
45
+
46
+ Then query DIALS, optionally in another workspace than the one picked from your e-groups:
47
+
48
+ ```python
49
+ from cmsdials import Dials
50
+ from cmsdials.filters import LumisectionHistogram1DFilters
51
+
52
+ dials = Dials(creds, workspace="tracker")
53
+
54
+ data = dials.h1d.list_all(
55
+ LumisectionHistogram1DFilters(me="PixelPhase1/Tracks/PXBarrel/charge_PXLayer_2"),
56
+ max_pages=5,
57
+ )
58
+ ```
59
+
60
+ ## Development
61
+
62
+ Install the dependencies and the package using `uv`:
63
+
64
+ ```shell
65
+ uv sync --all-groups --extra pandas --extra tqdm
66
+ uv run pre-commit install
67
+ uv pip install -e .
68
+ ```
69
+
70
+ ### Running tests
71
+
72
+ The repository has some tests written to make sure DIALS responses are compatible with pydantic metaclasses, you can use pytest to run all tests but you need to specify the client id and secret of an application to authenticate non-interactively against DIALS api:
73
+
74
+ ```bash
75
+ CLIENT_SECRET=... CLIENT_ID=... uv run pytest tests
76
+ ```
77
+
78
+ Any application granted API access in DIALS can be used: `CLIENT_ID` is its client id and `CLIENT_SECRET` its client secret, both obtained from the applications portal. Tests target the dev Keycloak applications by default, overwrite them with `AUTH_CLIENT_ID` and `AUTH_AUDIENCE`. The interactive authentication flow should be tested manually, an example for this can be found in [test_auth_client.py](/tests/integration/test_auth_client.py).
79
+
80
+ If testing against a local version of DIALS you need to specify the BASE_URL:
81
+
82
+ ```bash
83
+ CLIENT_SECRET=... CLIENT_ID=... BASE_URL=http://localhost:8000 uv run pytest tests
84
+ ```
85
+
86
+ #### Tox
87
+
88
+ Tox is pre-configured in `tox.ini`, so you can run the following to test against multiple python versions locally:
89
+
90
+ ```bash
91
+ CLIENT_SECRET=... CLIENT_ID=... uv run tox
92
+ ```
93
+
94
+ **[asdf](https://asdf-vm.com/) users**
95
+
96
+ tox requires multiple versions of Python to be installed. Using `asdf`, you have multiple versions installed, but they aren’t normally exposed to the current shell. You can use the following command to expose multiple versions of Python in the current directory:
97
+
98
+ ```bash
99
+ asdf set python 3.12.9 3.11.10 3.10.13 3.9.19
100
+ ```
101
+
102
+ This will use `3.12.9` by default (if you just run `python`), but it will also put `python3.11`, `python3.10` and `python3.9` symlinks in your path so you can run those too (which is exactly what tox is looking for).
103
+
104
+ ### Releasing the package on PyPI
105
+
106
+ The package is available in PyPI at [cmsdials](https://pypi.org/project/cmsdials/), under the [cmsdqm](https://pypi.org/org/cms-dqm/) organization. You'll need at leat Mantainer rights to be able to push new versions.
107
+
108
+ #### CI
109
+
110
+ Do not worry. The GitLab CI is configured to automatically publish the package on PyPI and the release notes in GitLab whever a tag is pushed to the repo.
111
+
112
+ > [!NOTE]
113
+ > For this to work the CI/CD variables named `UV_PUBLISH_TOKEN`, `GITLAB_TOKEN` should be registered in gitlab. The `UV_PUBLISH_TOKEN` is a api token access of CMSDQM organization and the `GITLAB_TOKEN` is a Project Access Token with api read/write rights, which is needed to read merge requests using the `glab-cli`.
114
+ > https://gitlab.cern.ch/cms-dqmdc/libraries/dials-py/-/settings/access_tokens
115
+
116
+ #### Manual
117
+
118
+ If you want to follow the manual approach, you need to first build and then publish.
119
+
120
+ ##### Build
121
+
122
+ You can use uv to build the package using:
123
+
124
+ ```bash
125
+ uv build
126
+ ```
127
+
128
+ The build system will automatically update the package version based on the git tag of the current commit.
129
+
130
+ ##### Publish
131
+
132
+ Provided you have already generate a PyPI api token in your account or in CMDQM org, you can publish using:
133
+
134
+ ```bash
135
+ UV_PUBLISH_TOKEN=... uv publish
136
+ ```
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '2.4.0'
22
- __version_tuple__ = version_tuple = (2, 4, 0)
21
+ __version__ = version = '3.0.0'
22
+ __version_tuple__ = version_tuple = (3, 0, 0)
23
23
 
24
- __commit_id__ = commit_id = 'g9cd07880c'
24
+ __commit_id__ = commit_id = 'g3b39a8c48'
@@ -1,5 +1,4 @@
1
1
  import time
2
- import warnings
3
2
  from datetime import datetime, timedelta
4
3
  from typing import Optional
5
4
 
@@ -48,24 +47,17 @@ class AuthClient(BaseAPIClient):
48
47
  audience: Optional[str] = None,
49
48
  **kwargs,
50
49
  ) -> None:
51
- # Leftovers from releases that logged in through DIALS: tokens are now
50
+ # Leftovers from releases that logged in through DIALS: tokens are
52
51
  # issued by Keycloak, and the instance is selected by client_id and
53
52
  # audience, so these would silently target production.
54
- ignored = [
55
- name
56
- for name in ("base_url", "route", "version")
57
- if kwargs.get(name) is not None
58
- ]
59
- if args or ignored:
60
- warnings.warn(
61
- "AuthClient ignores base_url, route and version, which will "
62
- "raise TypeError in dials-py 3.0.0. Tokens are issued by CERN "
63
- "Keycloak: to target another DIALS instance, pass its "
64
- "client_id and audience instead.",
65
- DeprecationWarning,
66
- stacklevel=2,
53
+ if args or kwargs:
54
+ raise TypeError(
55
+ "AuthClient does not accept base_url, route, version or other "
56
+ "API client arguments. Tokens are issued by CERN Keycloak: to "
57
+ "target another DIALS instance, pass its client_id and "
58
+ "audience instead."
67
59
  )
68
- super().__init__(*args, **kwargs)
60
+ super().__init__()
69
61
  keycloak_url = keycloak_url or self.PRODUCTION_KEYCLOAK_URL
70
62
  if not keycloak_url.endswith("/"):
71
63
  keycloak_url += "/"
@@ -24,10 +24,9 @@ class MLBadLumisectionClient(
24
24
  dataset_id: int,
25
25
  run_number: int,
26
26
  ls_number: int,
27
- me_id: int,
28
27
  **kwargs,
29
28
  ):
30
- edp = f"{model_id}/{dataset_id}/{run_number}/{ls_number}/{me_id}/"
29
+ edp = f"{model_id}/{dataset_id}/{run_number}/{ls_number}/"
31
30
  return super()._get(edp, **kwargs)
32
31
 
33
32
  def __json_body_builder(
@@ -9,7 +9,6 @@ from .clients.lumisection.client import LumisectionClient
9
9
  from .clients.mes.client import MonitoringElementClient
10
10
  from .clients.ml_bad_lumisection.client import MLBadLumisectionClient
11
11
  from .clients.ml_models_index.client import MLModelsIndexClient
12
- from .clients.oms_proxy.client import OMSProxyClient
13
12
  from .clients.run.client import RunClient
14
13
  from .clients.workspace.client import WorkspaceClient
15
14
 
@@ -35,7 +34,6 @@ class Dials:
35
34
  self.lumi = LumisectionClient(creds, workspace, *args, **kwargs)
36
35
  self.run = RunClient(creds, workspace, *args, **kwargs)
37
36
  self.mes = MonitoringElementClient(creds, workspace, *args, **kwargs)
38
- self.oms = OMSProxyClient(creds, *args, **kwargs)
39
37
  self.ml_bad_lumis = MLBadLumisectionClient(
40
38
  creds, workspace, *args, **kwargs
41
39
  )
@@ -6,7 +6,6 @@ from .clients.lumisection.models import LumisectionFilters
6
6
  from .clients.mes.models import MEFilters
7
7
  from .clients.ml_bad_lumisection.models import MLBadLumisectionFilters
8
8
  from .clients.ml_models_index.models import MLModelsIndexFilters
9
- from .clients.oms_proxy.models import OMSFilter, OMSPage
10
9
  from .clients.run.models import RunFilters
11
10
 
12
11
 
@@ -19,7 +18,5 @@ __all__ = [
19
18
  "MEFilters",
20
19
  "MLBadLumisectionFilters",
21
20
  "MLModelsIndexFilters",
22
- "OMSFilter",
23
- "OMSPage",
24
21
  "RunFilters",
25
22
  ]
@@ -0,0 +1,159 @@
1
+ Metadata-Version: 2.4
2
+ Name: cmsdials
3
+ Version: 3.0.0
4
+ Summary: The Python api client interface to DIALS service
5
+ Author-email: Gabriel Moreira <gabriel.moreira@cern.ch>
6
+ Project-URL: Repository, https://gitlab.cern.ch/cms-dqmdc/libraries/dials-py
7
+ Classifier: Development Status :: 5 - Production/Stable
8
+ Classifier: Programming Language :: Python :: 3.9
9
+ Classifier: Programming Language :: Python :: 3.10
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Requires-Python: >=3.9
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Requires-Dist: requests<3.0.0,>=2.31.0
16
+ Requires-Dist: urllib3<2.0.0,>=1.26.16
17
+ Requires-Dist: pydantic<3.0.0,>=2.8.2
18
+ Provides-Extra: pandas
19
+ Requires-Dist: pandas>=1.5.3; extra == "pandas"
20
+ Provides-Extra: tqdm
21
+ Requires-Dist: tqdm>=4.66.1; extra == "tqdm"
22
+ Dynamic: license-file
23
+
24
+ ![Build Status](https://gitlab.cern.ch/cms-ppd/technical-support/libraries/dials-py/badges/develop/pipeline.svg)
25
+ ![Coverage](https://gitlab.cern.ch/cms-ppd/technical-support/libraries/dials-py/badges/develop/coverage.svg)
26
+ ![Latest Release](https://gitlab.cern.ch/cms-ppd/technical-support/libraries/dials-py/-/badges/release.svg)
27
+ [![PyPI version](https://badge.fury.io/py/cmsdials.png)](https://badge.fury.io/py/cmsdials)
28
+
29
+ # dials-py
30
+
31
+ The Python client of the [DIALS](https://cms-ppd.docs.cern.ch/ts/software/DIALS/index.html) API.
32
+
33
+ The full documentation, with every endpoint, filters, pandas and progress bar support, retrying and resuming long queries, ML certification JSONs and the development instance, is in the [dials-py user guide](https://cms-ppd.docs.cern.ch/ts/software/DIALS/user_guide/dials_py.html).
34
+
35
+ ## Installation
36
+
37
+ ```bash
38
+ pip install cmsdials
39
+ ```
40
+
41
+ The `pandas` and `tqdm` extras enable conversion to DataFrames and progress bars:
42
+
43
+ ```bash
44
+ pip install "cmsdials[pandas,tqdm]"
45
+ ```
46
+
47
+ ## Usage
48
+
49
+ Tokens are issued by CERN's Keycloak directly, dials-py never sends your password or a client secret to DIALS.
50
+
51
+ To log in as yourself, with the device flow (interactive, the credentials are cached in `.cache/` and renewed automatically):
52
+
53
+ ```python
54
+ from cmsdials.auth.device import Credentials
55
+
56
+ creds = Credentials.from_creds_file()
57
+ ```
58
+
59
+ To log in as an application, with its client id and secret (unattended scripts, the application must be granted [API access](https://cms-ppd.docs.cern.ch/ts/software/DIALS/user_guide/api_access.html)):
60
+
61
+ ```python
62
+ import os
63
+
64
+ from cmsdials.auth.client_credentials import Credentials
65
+
66
+ creds = Credentials(client_id="my-application", client_secret=os.environ["CLIENT_SECRET"])
67
+ ```
68
+
69
+ Then query DIALS, optionally in another workspace than the one picked from your e-groups:
70
+
71
+ ```python
72
+ from cmsdials import Dials
73
+ from cmsdials.filters import LumisectionHistogram1DFilters
74
+
75
+ dials = Dials(creds, workspace="tracker")
76
+
77
+ data = dials.h1d.list_all(
78
+ LumisectionHistogram1DFilters(me="PixelPhase1/Tracks/PXBarrel/charge_PXLayer_2"),
79
+ max_pages=5,
80
+ )
81
+ ```
82
+
83
+ ## Development
84
+
85
+ Install the dependencies and the package using `uv`:
86
+
87
+ ```shell
88
+ uv sync --all-groups --extra pandas --extra tqdm
89
+ uv run pre-commit install
90
+ uv pip install -e .
91
+ ```
92
+
93
+ ### Running tests
94
+
95
+ The repository has some tests written to make sure DIALS responses are compatible with pydantic metaclasses, you can use pytest to run all tests but you need to specify the client id and secret of an application to authenticate non-interactively against DIALS api:
96
+
97
+ ```bash
98
+ CLIENT_SECRET=... CLIENT_ID=... uv run pytest tests
99
+ ```
100
+
101
+ Any application granted API access in DIALS can be used: `CLIENT_ID` is its client id and `CLIENT_SECRET` its client secret, both obtained from the applications portal. Tests target the dev Keycloak applications by default, overwrite them with `AUTH_CLIENT_ID` and `AUTH_AUDIENCE`. The interactive authentication flow should be tested manually, an example for this can be found in [test_auth_client.py](/tests/integration/test_auth_client.py).
102
+
103
+ If testing against a local version of DIALS you need to specify the BASE_URL:
104
+
105
+ ```bash
106
+ CLIENT_SECRET=... CLIENT_ID=... BASE_URL=http://localhost:8000 uv run pytest tests
107
+ ```
108
+
109
+ #### Tox
110
+
111
+ Tox is pre-configured in `tox.ini`, so you can run the following to test against multiple python versions locally:
112
+
113
+ ```bash
114
+ CLIENT_SECRET=... CLIENT_ID=... uv run tox
115
+ ```
116
+
117
+ **[asdf](https://asdf-vm.com/) users**
118
+
119
+ tox requires multiple versions of Python to be installed. Using `asdf`, you have multiple versions installed, but they aren’t normally exposed to the current shell. You can use the following command to expose multiple versions of Python in the current directory:
120
+
121
+ ```bash
122
+ asdf set python 3.12.9 3.11.10 3.10.13 3.9.19
123
+ ```
124
+
125
+ This will use `3.12.9` by default (if you just run `python`), but it will also put `python3.11`, `python3.10` and `python3.9` symlinks in your path so you can run those too (which is exactly what tox is looking for).
126
+
127
+ ### Releasing the package on PyPI
128
+
129
+ The package is available in PyPI at [cmsdials](https://pypi.org/project/cmsdials/), under the [cmsdqm](https://pypi.org/org/cms-dqm/) organization. You'll need at leat Mantainer rights to be able to push new versions.
130
+
131
+ #### CI
132
+
133
+ Do not worry. The GitLab CI is configured to automatically publish the package on PyPI and the release notes in GitLab whever a tag is pushed to the repo.
134
+
135
+ > [!NOTE]
136
+ > For this to work the CI/CD variables named `UV_PUBLISH_TOKEN`, `GITLAB_TOKEN` should be registered in gitlab. The `UV_PUBLISH_TOKEN` is a api token access of CMSDQM organization and the `GITLAB_TOKEN` is a Project Access Token with api read/write rights, which is needed to read merge requests using the `glab-cli`.
137
+ > https://gitlab.cern.ch/cms-dqmdc/libraries/dials-py/-/settings/access_tokens
138
+
139
+ #### Manual
140
+
141
+ If you want to follow the manual approach, you need to first build and then publish.
142
+
143
+ ##### Build
144
+
145
+ You can use uv to build the package using:
146
+
147
+ ```bash
148
+ uv build
149
+ ```
150
+
151
+ The build system will automatically update the package version based on the git tag of the current commit.
152
+
153
+ ##### Publish
154
+
155
+ Provided you have already generate a PyPI api token in your account or in CMDQM org, you can publish using:
156
+
157
+ ```bash
158
+ UV_PUBLISH_TOKEN=... uv publish
159
+ ```
@@ -26,13 +26,11 @@ cmsdials.egg-info/scm_version.json
26
26
  cmsdials.egg-info/top_level.txt
27
27
  cmsdials/auth/__init__.py
28
28
  cmsdials/auth/_base.py
29
- cmsdials/auth/bearer.py
30
29
  cmsdials/auth/client.py
31
30
  cmsdials/auth/client_credentials.py
32
31
  cmsdials/auth/device.py
33
32
  cmsdials/auth/exceptions.py
34
33
  cmsdials/auth/models.py
35
- cmsdials/auth/secret_key.py
36
34
  cmsdials/clients/__init__.py
37
35
  cmsdials/clients/dataset_index/__init__.py
38
36
  cmsdials/clients/dataset_index/client.py
@@ -58,9 +56,6 @@ cmsdials/clients/ml_bad_lumisection/models.py
58
56
  cmsdials/clients/ml_models_index/__init__.py
59
57
  cmsdials/clients/ml_models_index/client.py
60
58
  cmsdials/clients/ml_models_index/models.py
61
- cmsdials/clients/oms_proxy/__init__.py
62
- cmsdials/clients/oms_proxy/client.py
63
- cmsdials/clients/oms_proxy/models.py
64
59
  cmsdials/clients/run/__init__.py
65
60
  cmsdials/clients/run/client.py
66
61
  cmsdials/clients/run/models.py
@@ -79,7 +74,6 @@ tests/integration/test_h1d_client.py
79
74
  tests/integration/test_h2d_client.py
80
75
  tests/integration/test_lumisection_client.py
81
76
  tests/integration/test_mes_client.py
82
- tests/integration/test_oms_proxy_client.py
83
77
  tests/integration/test_resume.py
84
78
  tests/integration/test_run_client.py
85
79
  tests/integration/utils.py
@@ -12,13 +12,11 @@
12
12
  "cmsdials/__init__.py",
13
13
  "cmsdials/auth/__init__.py",
14
14
  "cmsdials/auth/_base.py",
15
- "cmsdials/auth/bearer.py",
16
15
  "cmsdials/auth/client.py",
17
16
  "cmsdials/auth/client_credentials.py",
18
17
  "cmsdials/auth/device.py",
19
18
  "cmsdials/auth/exceptions.py",
20
19
  "cmsdials/auth/models.py",
21
- "cmsdials/auth/secret_key.py",
22
20
  "cmsdials/clients/__init__.py",
23
21
  "cmsdials/clients/dataset_index/__init__.py",
24
22
  "cmsdials/clients/dataset_index/client.py",
@@ -44,9 +42,6 @@
44
42
  "cmsdials/clients/ml_models_index/__init__.py",
45
43
  "cmsdials/clients/ml_models_index/client.py",
46
44
  "cmsdials/clients/ml_models_index/models.py",
47
- "cmsdials/clients/oms_proxy/__init__.py",
48
- "cmsdials/clients/oms_proxy/client.py",
49
- "cmsdials/clients/oms_proxy/models.py",
50
45
  "cmsdials/clients/run/__init__.py",
51
46
  "cmsdials/clients/run/client.py",
52
47
  "cmsdials/clients/run/models.py",
@@ -71,7 +66,6 @@
71
66
  "tests/integration/test_h2d_client.py",
72
67
  "tests/integration/test_lumisection_client.py",
73
68
  "tests/integration/test_mes_client.py",
74
- "tests/integration/test_oms_proxy_client.py",
75
69
  "tests/integration/test_resume.py",
76
70
  "tests/integration/test_run_client.py",
77
71
  "tests/integration/utils.py",
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "3.0.0",
3
+ "distance": 0,
4
+ "node": "g3b39a8c4892ceefba0c836cd524029d5116b005b",
5
+ "dirty": false,
6
+ "branch": "HEAD",
7
+ "node_date": "2026-11-12"
8
+ }
@@ -1,15 +1,18 @@
1
1
  import os
2
2
 
3
3
 
4
- _client_secret = os.getenv("CLIENT_SECRET")
5
- if not _client_secret:
6
- raise OSError("CLIENT_SECRET environment variable is not set.")
7
- CLIENT_SECRET: str = _client_secret
4
+ def _required(name: str) -> str:
5
+ value = os.getenv(name)
6
+ if not value:
7
+ raise OSError(f"{name} environment variable is not set.")
8
+ return value
9
+
10
+
11
+ CLIENT_SECRET = _required("CLIENT_SECRET")
8
12
 
9
13
  BASE_URL = os.getenv("BASE_URL", "https://dev-cmsdials-api.web.cern.ch/")
10
- # Client id of the application owning CLIENT_SECRET. When set, tests authenticate
11
- # with api-access tokens instead of the deprecated X-CLIENT-SECRET header.
12
- CLIENT_ID = os.getenv("CLIENT_ID") or None
14
+ # Client id of the application owning CLIENT_SECRET
15
+ CLIENT_ID = _required("CLIENT_ID")
13
16
  AUTH_CLIENT_ID = os.getenv("AUTH_CLIENT_ID", "cms-dials-dev-public-app")
14
17
  AUTH_AUDIENCE = os.getenv("AUTH_AUDIENCE", "cms-dials-dev-confidential-app")
15
18
  TEST_WORKSPACE = os.getenv("TEST_WORKSPACE", "global")
@@ -21,6 +24,3 @@ TEST_FILE_ID = int(
21
24
  ) # /store/data/Run2026A/ZeroBias/DQMIO/PromptReco-v1/000/401/605/00000/2D15036C-0CB4-4B76-AA85-D1DB7DC6981F.root
22
25
  TEST_RUN_NUMBER = int(os.getenv("TEST_RUN_NUMBER", 401605))
23
26
  TEST_LS_NUMBER = int(os.getenv("TEST_LS_NUMBER", 1))
24
- TEST_TRUTH_OMS_DATASETRATES_LENGTH = int(
25
- os.getenv("TEST_TRUTH_OMS_DATASETRATES_LENGTH", 242)
26
- )