cmsdials 0.3.0__tar.gz → 1.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.
- {cmsdials-0.3.0 → cmsdials-1.0.0}/PKG-INFO +24 -20
- {cmsdials-0.3.0 → cmsdials-1.0.0}/README.md +22 -18
- cmsdials-1.0.0/cmsdials/clients/file_index/models.py +35 -0
- {cmsdials-0.3.0 → cmsdials-1.0.0}/cmsdials/clients/h1d/client.py +1 -1
- cmsdials-1.0.0/cmsdials/clients/h1d/models.py +49 -0
- {cmsdials-0.3.0 → cmsdials-1.0.0}/cmsdials/clients/h2d/client.py +1 -1
- cmsdials-1.0.0/cmsdials/clients/h2d/models.py +52 -0
- cmsdials-1.0.0/cmsdials/clients/lumisection/client.py +27 -0
- cmsdials-1.0.0/cmsdials/clients/lumisection/models.py +34 -0
- cmsdials-1.0.0/cmsdials/clients/run/client.py +27 -0
- cmsdials-1.0.0/cmsdials/clients/run/models.py +28 -0
- cmsdials-1.0.0/cmsdials/cmsdials.py +17 -0
- {cmsdials-0.3.0 → cmsdials-1.0.0}/cmsdials/filters.py +0 -2
- {cmsdials-0.3.0 → cmsdials-1.0.0}/cmsdials/utils/api_client.py +27 -46
- cmsdials-1.0.0/pyproject.toml +126 -0
- cmsdials-0.3.0/cmsdials/clients/bad_file_index/client.py +0 -9
- cmsdials-0.3.0/cmsdials/clients/bad_file_index/models.py +0 -30
- cmsdials-0.3.0/cmsdials/clients/file_index/models.py +0 -44
- cmsdials-0.3.0/cmsdials/clients/h1d/models.py +0 -44
- cmsdials-0.3.0/cmsdials/clients/h2d/models.py +0 -50
- cmsdials-0.3.0/cmsdials/clients/lumisection/client.py +0 -20
- cmsdials-0.3.0/cmsdials/clients/lumisection/models.py +0 -35
- cmsdials-0.3.0/cmsdials/clients/run/client.py +0 -9
- cmsdials-0.3.0/cmsdials/clients/run/models.py +0 -31
- cmsdials-0.3.0/cmsdials/cmsdials.py +0 -19
- cmsdials-0.3.0/cmsdials/utils/__init__.py +0 -0
- cmsdials-0.3.0/pyproject.toml +0 -31
- {cmsdials-0.3.0 → cmsdials-1.0.0}/LICENSE +0 -0
- {cmsdials-0.3.0 → cmsdials-1.0.0}/cmsdials/__init__.py +0 -0
- {cmsdials-0.3.0 → cmsdials-1.0.0}/cmsdials/auth/__init__.py +0 -0
- {cmsdials-0.3.0 → cmsdials-1.0.0}/cmsdials/auth/_base.py +0 -0
- {cmsdials-0.3.0 → cmsdials-1.0.0}/cmsdials/auth/bearer.py +0 -0
- {cmsdials-0.3.0 → cmsdials-1.0.0}/cmsdials/auth/client.py +0 -0
- {cmsdials-0.3.0 → cmsdials-1.0.0}/cmsdials/auth/exceptions.py +0 -0
- {cmsdials-0.3.0 → cmsdials-1.0.0}/cmsdials/auth/models.py +0 -0
- {cmsdials-0.3.0 → cmsdials-1.0.0}/cmsdials/auth/secret_key.py +0 -0
- {cmsdials-0.3.0 → cmsdials-1.0.0}/cmsdials/clients/__init__.py +0 -0
- {cmsdials-0.3.0/cmsdials/clients/bad_file_index → cmsdials-1.0.0/cmsdials/clients/file_index}/__init__.py +0 -0
- {cmsdials-0.3.0 → cmsdials-1.0.0}/cmsdials/clients/file_index/client.py +0 -0
- {cmsdials-0.3.0/cmsdials/clients/file_index → cmsdials-1.0.0/cmsdials/clients/h1d}/__init__.py +0 -0
- {cmsdials-0.3.0/cmsdials/clients/h1d → cmsdials-1.0.0/cmsdials/clients/h2d}/__init__.py +0 -0
- {cmsdials-0.3.0/cmsdials/clients/h2d → cmsdials-1.0.0/cmsdials/clients/lumisection}/__init__.py +0 -0
- {cmsdials-0.3.0/cmsdials/clients/lumisection → cmsdials-1.0.0/cmsdials/clients/run}/__init__.py +0 -0
- {cmsdials-0.3.0/cmsdials/clients/run → cmsdials-1.0.0/cmsdials/utils}/__init__.py +0 -0
- {cmsdials-0.3.0 → cmsdials-1.0.0}/cmsdials/utils/_json.py +0 -0
- {cmsdials-0.3.0 → cmsdials-1.0.0}/cmsdials/utils/base_model.py +0 -0
- {cmsdials-0.3.0 → cmsdials-1.0.0}/cmsdials/utils/logger.py +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: cmsdials
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 1.0.0
|
|
4
4
|
Summary: The Python api client interface to DIALS service
|
|
5
5
|
Home-page: https://github.com/cms-DQM/dials-py
|
|
6
6
|
Author: Gabriel Moreira
|
|
7
7
|
Author-email: gabrielmscampos@gmail.com
|
|
8
8
|
Requires-Python: >=3.9,<4.0
|
|
9
|
-
Classifier: Development Status ::
|
|
9
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
10
10
|
Classifier: Operating System :: OS Independent
|
|
11
11
|
Classifier: Programming Language :: Python
|
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -76,10 +76,18 @@ from cmsdials import Dials
|
|
|
76
76
|
from cmsdials.filters import LumisectionHistogram1DFilters
|
|
77
77
|
|
|
78
78
|
creds = Credentials.from_creds_file()
|
|
79
|
-
dials = Dials(creds
|
|
79
|
+
dials = Dials(creds)
|
|
80
80
|
|
|
81
81
|
# Getting h1d data
|
|
82
|
-
data = dials.h1d.list_all(LumisectionHistogram1DFilters(
|
|
82
|
+
data = dials.h1d.list_all(LumisectionHistogram1DFilters(me="PixelPhase1/Tracks/PXBarrel/charge_PXLayer_2"), max_pages=5)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Workspace
|
|
86
|
+
|
|
87
|
+
Users are automatically routed to a workspace based on e-groups, but it is possible to overwrite this configuration and inspect data from others workspaces:
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
dials = Dials(creds, workspace="jetmet")
|
|
83
91
|
```
|
|
84
92
|
|
|
85
93
|
## Available endpoints
|
|
@@ -89,12 +97,11 @@ This package interacts with DIALS api endpoints using underlying classes in `Dia
|
|
|
89
97
|
### Retrieving a specific object using `get`
|
|
90
98
|
|
|
91
99
|
```python
|
|
92
|
-
dials.
|
|
93
|
-
dials.file_index.get(id=1)
|
|
100
|
+
dials.file_index.get(id=3386119397)
|
|
94
101
|
dials.h1d.get(id=1)
|
|
95
102
|
dials.h2d.get(id=1)
|
|
96
|
-
dials.lumi.get(
|
|
97
|
-
dials.run.get(
|
|
103
|
+
dials.lumi.get(dataset_id=14677060, run_number=367094, ls_number=1)
|
|
104
|
+
dials.run.get(dataset_id=14677060, run_number=367094)
|
|
98
105
|
```
|
|
99
106
|
|
|
100
107
|
### Retrieving a list of objects per page using `list`
|
|
@@ -102,7 +109,6 @@ dials.run.get(id=1)
|
|
|
102
109
|
It is possible to get a list of entries from those endpoint using the `list` and `list_all` methods, the `list` method will fetch only one page and the `list_all` will fetch all available pages:
|
|
103
110
|
|
|
104
111
|
```python
|
|
105
|
-
dials.bad_file_index.list()
|
|
106
112
|
dials.file_index.list()
|
|
107
113
|
dials.h1d.list()
|
|
108
114
|
dials.h2d.list()
|
|
@@ -112,8 +118,9 @@ dials.run.list()
|
|
|
112
118
|
|
|
113
119
|
### Retrieving all available pages of a list of objects using `list_all`
|
|
114
120
|
|
|
121
|
+
Note: Keep in mind that running `list_all` without any filter can take too much time, since you will be retrieving all rows in the database.
|
|
122
|
+
|
|
115
123
|
```python
|
|
116
|
-
dials.bad_file_index.list_all()
|
|
117
124
|
dials.file_index.list_all()
|
|
118
125
|
dials.h1d.list_all()
|
|
119
126
|
dials.h2d.list_all()
|
|
@@ -133,7 +140,6 @@ Keep in mind that calling those methods without any filter can take a lot of tim
|
|
|
133
140
|
|
|
134
141
|
```python
|
|
135
142
|
from cmsdials.filters import (
|
|
136
|
-
BadFileIndexFilters,
|
|
137
143
|
FileIndexFilters,
|
|
138
144
|
LumisectionHistogram1DFilters,
|
|
139
145
|
LumisectionHistogram2DFilters,
|
|
@@ -141,17 +147,15 @@ from cmsdials.filters import (
|
|
|
141
147
|
RunFilters
|
|
142
148
|
)
|
|
143
149
|
|
|
144
|
-
dials.
|
|
145
|
-
|
|
146
|
-
dials.file_index.list(FileIndexFilters(page="10"))
|
|
150
|
+
dials.file_index.list(FileIndexFilters(dataset__regex="2024B"))
|
|
147
151
|
|
|
148
|
-
dials.h1d.list(LumisectionHistogram1DFilters(
|
|
152
|
+
dials.h1d.list(LumisectionHistogram1DFilters(me="PixelPhase1/Tracks/PXBarrel/charge_PXLayer_2"))
|
|
149
153
|
|
|
150
|
-
dials.h2d.list_all(LumisectionHistogram2DFilters(
|
|
154
|
+
dials.h2d.list_all(LumisectionHistogram2DFilters(me__regex="PXBarrel", ls_number=78, entries__gte=100), max_pages=5)
|
|
151
155
|
|
|
152
156
|
dials.lumi.list_all(LumisectionFilters(run_number=360392), max_pages=5)
|
|
153
157
|
|
|
154
|
-
dials.run.list_all(RunFilters(
|
|
158
|
+
dials.run.list_all(RunFilters(run_number__gte=360392, run_number__lte=365000), max_pages=5)
|
|
155
159
|
```
|
|
156
160
|
|
|
157
161
|
### Dials MEs
|
|
@@ -173,12 +177,12 @@ from cmsdials import Dials
|
|
|
173
177
|
from cmsdials.filters import LumisectionHistogram2DFilters
|
|
174
178
|
|
|
175
179
|
DEV_URL = "http://localhost:8000/"
|
|
176
|
-
DEV_CACHE_DIR = ".cache-dev
|
|
180
|
+
DEV_CACHE_DIR = ".cache-dev"
|
|
177
181
|
|
|
178
182
|
auth = AuthClient(base_url=DEV_URL)
|
|
179
183
|
creds = Credentials.from_creds_file(cache_dir=DEV_CACHE_DIR, client=auth) # Make sure to specify the auth client with overwritten values, using another cache_dir is recommended
|
|
180
|
-
dials = Dials(creds,
|
|
184
|
+
dials = Dials(creds, base_url=DEV_URL)
|
|
181
185
|
|
|
182
|
-
dials.h2d.list_all(LumisectionHistogram2DFilters(
|
|
186
|
+
dials.h2d.list_all(LumisectionHistogram2DFilters(me__regex="EEOT digi occupancy EE +", entries__gte=100, run_number__gte=360392, run_number__lte=365000), max_pages=5)
|
|
183
187
|
```
|
|
184
188
|
|
|
@@ -53,10 +53,18 @@ from cmsdials import Dials
|
|
|
53
53
|
from cmsdials.filters import LumisectionHistogram1DFilters
|
|
54
54
|
|
|
55
55
|
creds = Credentials.from_creds_file()
|
|
56
|
-
dials = Dials(creds
|
|
56
|
+
dials = Dials(creds)
|
|
57
57
|
|
|
58
58
|
# Getting h1d data
|
|
59
|
-
data = dials.h1d.list_all(LumisectionHistogram1DFilters(
|
|
59
|
+
data = dials.h1d.list_all(LumisectionHistogram1DFilters(me="PixelPhase1/Tracks/PXBarrel/charge_PXLayer_2"), max_pages=5)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Workspace
|
|
63
|
+
|
|
64
|
+
Users are automatically routed to a workspace based on e-groups, but it is possible to overwrite this configuration and inspect data from others workspaces:
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
dials = Dials(creds, workspace="jetmet")
|
|
60
68
|
```
|
|
61
69
|
|
|
62
70
|
## Available endpoints
|
|
@@ -66,12 +74,11 @@ This package interacts with DIALS api endpoints using underlying classes in `Dia
|
|
|
66
74
|
### Retrieving a specific object using `get`
|
|
67
75
|
|
|
68
76
|
```python
|
|
69
|
-
dials.
|
|
70
|
-
dials.file_index.get(id=1)
|
|
77
|
+
dials.file_index.get(id=3386119397)
|
|
71
78
|
dials.h1d.get(id=1)
|
|
72
79
|
dials.h2d.get(id=1)
|
|
73
|
-
dials.lumi.get(
|
|
74
|
-
dials.run.get(
|
|
80
|
+
dials.lumi.get(dataset_id=14677060, run_number=367094, ls_number=1)
|
|
81
|
+
dials.run.get(dataset_id=14677060, run_number=367094)
|
|
75
82
|
```
|
|
76
83
|
|
|
77
84
|
### Retrieving a list of objects per page using `list`
|
|
@@ -79,7 +86,6 @@ dials.run.get(id=1)
|
|
|
79
86
|
It is possible to get a list of entries from those endpoint using the `list` and `list_all` methods, the `list` method will fetch only one page and the `list_all` will fetch all available pages:
|
|
80
87
|
|
|
81
88
|
```python
|
|
82
|
-
dials.bad_file_index.list()
|
|
83
89
|
dials.file_index.list()
|
|
84
90
|
dials.h1d.list()
|
|
85
91
|
dials.h2d.list()
|
|
@@ -89,8 +95,9 @@ dials.run.list()
|
|
|
89
95
|
|
|
90
96
|
### Retrieving all available pages of a list of objects using `list_all`
|
|
91
97
|
|
|
98
|
+
Note: Keep in mind that running `list_all` without any filter can take too much time, since you will be retrieving all rows in the database.
|
|
99
|
+
|
|
92
100
|
```python
|
|
93
|
-
dials.bad_file_index.list_all()
|
|
94
101
|
dials.file_index.list_all()
|
|
95
102
|
dials.h1d.list_all()
|
|
96
103
|
dials.h2d.list_all()
|
|
@@ -110,7 +117,6 @@ Keep in mind that calling those methods without any filter can take a lot of tim
|
|
|
110
117
|
|
|
111
118
|
```python
|
|
112
119
|
from cmsdials.filters import (
|
|
113
|
-
BadFileIndexFilters,
|
|
114
120
|
FileIndexFilters,
|
|
115
121
|
LumisectionHistogram1DFilters,
|
|
116
122
|
LumisectionHistogram2DFilters,
|
|
@@ -118,17 +124,15 @@ from cmsdials.filters import (
|
|
|
118
124
|
RunFilters
|
|
119
125
|
)
|
|
120
126
|
|
|
121
|
-
dials.
|
|
122
|
-
|
|
123
|
-
dials.file_index.list(FileIndexFilters(page="10"))
|
|
127
|
+
dials.file_index.list(FileIndexFilters(dataset__regex="2024B"))
|
|
124
128
|
|
|
125
|
-
dials.h1d.list(LumisectionHistogram1DFilters(
|
|
129
|
+
dials.h1d.list(LumisectionHistogram1DFilters(me="PixelPhase1/Tracks/PXBarrel/charge_PXLayer_2"))
|
|
126
130
|
|
|
127
|
-
dials.h2d.list_all(LumisectionHistogram2DFilters(
|
|
131
|
+
dials.h2d.list_all(LumisectionHistogram2DFilters(me__regex="PXBarrel", ls_number=78, entries__gte=100), max_pages=5)
|
|
128
132
|
|
|
129
133
|
dials.lumi.list_all(LumisectionFilters(run_number=360392), max_pages=5)
|
|
130
134
|
|
|
131
|
-
dials.run.list_all(RunFilters(
|
|
135
|
+
dials.run.list_all(RunFilters(run_number__gte=360392, run_number__lte=365000), max_pages=5)
|
|
132
136
|
```
|
|
133
137
|
|
|
134
138
|
### Dials MEs
|
|
@@ -150,11 +154,11 @@ from cmsdials import Dials
|
|
|
150
154
|
from cmsdials.filters import LumisectionHistogram2DFilters
|
|
151
155
|
|
|
152
156
|
DEV_URL = "http://localhost:8000/"
|
|
153
|
-
DEV_CACHE_DIR = ".cache-dev
|
|
157
|
+
DEV_CACHE_DIR = ".cache-dev"
|
|
154
158
|
|
|
155
159
|
auth = AuthClient(base_url=DEV_URL)
|
|
156
160
|
creds = Credentials.from_creds_file(cache_dir=DEV_CACHE_DIR, client=auth) # Make sure to specify the auth client with overwritten values, using another cache_dir is recommended
|
|
157
|
-
dials = Dials(creds,
|
|
161
|
+
dials = Dials(creds, base_url=DEV_URL)
|
|
158
162
|
|
|
159
|
-
dials.h2d.list_all(LumisectionHistogram2DFilters(
|
|
163
|
+
dials.h2d.list_all(LumisectionHistogram2DFilters(me__regex="EEOT digi occupancy EE +", entries__gte=100, run_number__gte=360392, run_number__lte=365000), max_pages=5)
|
|
160
164
|
```
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from typing import List, Optional
|
|
3
|
+
|
|
4
|
+
from pydantic import AnyUrl, BaseModel, Field
|
|
5
|
+
|
|
6
|
+
from ...utils.base_model import OBaseModel
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class FileIndex(BaseModel):
|
|
10
|
+
dataset_id: int
|
|
11
|
+
dataset: str = Field(..., max_length=255)
|
|
12
|
+
file_id: int
|
|
13
|
+
file_size: int
|
|
14
|
+
creation_date: datetime
|
|
15
|
+
last_modification_date: datetime
|
|
16
|
+
logical_file_name: str
|
|
17
|
+
status: str = Field(..., max_length=15)
|
|
18
|
+
err_trace: Optional[str] = Field(..., max_length=5000)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class PaginatedFileIndexList(BaseModel):
|
|
22
|
+
next: Optional[AnyUrl]
|
|
23
|
+
previous: Optional[AnyUrl]
|
|
24
|
+
results: List[FileIndex]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class FileIndexFilters(OBaseModel):
|
|
28
|
+
next_token: Optional[str] = None
|
|
29
|
+
dataset_id: Optional[int] = None
|
|
30
|
+
logical_file_name: Optional[str] = None
|
|
31
|
+
logical_file_name__regex: Optional[str] = None
|
|
32
|
+
status: Optional[str] = None
|
|
33
|
+
min_size: Optional[int] = None
|
|
34
|
+
dataset: Optional[str] = None
|
|
35
|
+
dataset__regex: Optional[str] = None
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from typing import List, Optional
|
|
2
|
+
|
|
3
|
+
from pydantic import AnyUrl, BaseModel, Field
|
|
4
|
+
|
|
5
|
+
from ...utils.base_model import OBaseModel
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class LumisectionHistogram1D(BaseModel):
|
|
9
|
+
hist_id: int
|
|
10
|
+
dataset: str = Field(..., max_length=255)
|
|
11
|
+
me: str = Field(..., max_length=255)
|
|
12
|
+
dataset_id: int
|
|
13
|
+
file_id: int
|
|
14
|
+
run_number: int
|
|
15
|
+
ls_number: int
|
|
16
|
+
me_id: int
|
|
17
|
+
ls_id: int
|
|
18
|
+
x_min: float
|
|
19
|
+
x_max: float
|
|
20
|
+
x_bin: float
|
|
21
|
+
entries: int
|
|
22
|
+
data: list[float]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class PaginatedLumisectionHistogram1DList(BaseModel):
|
|
26
|
+
next: Optional[AnyUrl]
|
|
27
|
+
previous: Optional[AnyUrl]
|
|
28
|
+
results: List[LumisectionHistogram1D]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class LumisectionHistogram1DFilters(OBaseModel):
|
|
32
|
+
next_token: Optional[str] = None
|
|
33
|
+
dataset_id: Optional[int] = None
|
|
34
|
+
file_id: Optional[int] = None
|
|
35
|
+
run_number: Optional[int] = None
|
|
36
|
+
run_number__lte: Optional[int] = None
|
|
37
|
+
run_number__gte: Optional[int] = None
|
|
38
|
+
ls_number: Optional[int] = None
|
|
39
|
+
ls_numbet__lte: Optional[int] = None
|
|
40
|
+
ls_number__gte: Optional[int] = None
|
|
41
|
+
me_id: Optional[int] = None
|
|
42
|
+
ls_id: Optional[int] = None
|
|
43
|
+
entries__gte: Optional[int] = None
|
|
44
|
+
dataset: Optional[str] = None
|
|
45
|
+
dataset__regex: Optional[str] = None
|
|
46
|
+
logical_file_name: Optional[str] = None
|
|
47
|
+
logical_file_name__regex: Optional[str] = None
|
|
48
|
+
me: Optional[str] = None
|
|
49
|
+
me__regex: Optional[str] = None
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from pydantic import AnyUrl, BaseModel, Field
|
|
4
|
+
|
|
5
|
+
from ...utils.base_model import OBaseModel
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class LumisectionHistogram2D(BaseModel):
|
|
9
|
+
hist_id: int
|
|
10
|
+
dataset: str = Field(..., max_length=255)
|
|
11
|
+
me: str = Field(..., max_length=255)
|
|
12
|
+
dataset_id: int
|
|
13
|
+
file_id: int
|
|
14
|
+
run_number: int
|
|
15
|
+
ls_number: int
|
|
16
|
+
me_id: int
|
|
17
|
+
ls_id: int
|
|
18
|
+
x_min: float
|
|
19
|
+
x_max: float
|
|
20
|
+
x_bin: float
|
|
21
|
+
y_min: float
|
|
22
|
+
y_max: float
|
|
23
|
+
y_bin: float
|
|
24
|
+
entries: int
|
|
25
|
+
data: list[list[float]]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class PaginatedLumisectionHistogram2DList(BaseModel):
|
|
29
|
+
next: Optional[AnyUrl]
|
|
30
|
+
previous: Optional[AnyUrl]
|
|
31
|
+
results: list[LumisectionHistogram2D]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class LumisectionHistogram2DFilters(OBaseModel):
|
|
35
|
+
next_token: Optional[str] = None
|
|
36
|
+
dataset_id: Optional[int] = None
|
|
37
|
+
file_id: Optional[int] = None
|
|
38
|
+
run_number: Optional[int] = None
|
|
39
|
+
run_number__lte: Optional[int] = None
|
|
40
|
+
run_number__gte: Optional[int] = None
|
|
41
|
+
ls_number: Optional[int] = None
|
|
42
|
+
ls_numbet__lte: Optional[int] = None
|
|
43
|
+
ls_number__gte: Optional[int] = None
|
|
44
|
+
me_id: Optional[int] = None
|
|
45
|
+
ls_id: Optional[int] = None
|
|
46
|
+
entries__gte: Optional[int] = None
|
|
47
|
+
dataset: Optional[str] = None
|
|
48
|
+
dataset__regex: Optional[str] = None
|
|
49
|
+
logical_file_name: Optional[str] = None
|
|
50
|
+
logical_file_name__regex: Optional[str] = None
|
|
51
|
+
me: Optional[str] = None
|
|
52
|
+
me__regex: Optional[str] = None
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
from requests.exceptions import HTTPError
|
|
3
|
+
|
|
4
|
+
from ...utils.api_client import BaseAuthorizedAPIClient
|
|
5
|
+
from ...utils.logger import logger
|
|
6
|
+
from .models import Lumisection, LumisectionFilters, PaginatedLumisectionList
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class LumisectionClient(BaseAuthorizedAPIClient):
|
|
10
|
+
data_model = Lumisection
|
|
11
|
+
pagination_model = PaginatedLumisectionList
|
|
12
|
+
filter_class = LumisectionFilters
|
|
13
|
+
lookup_url = "lumisection/"
|
|
14
|
+
|
|
15
|
+
def get(self, dataset_id: int, run_number: int, ls_number: int):
|
|
16
|
+
endpoint_url = f"{self.api_url}{self.lookup_url}{dataset_id}/{run_number}/{ls_number}/"
|
|
17
|
+
headers = self._build_headers()
|
|
18
|
+
response = requests.get(endpoint_url, headers=headers)
|
|
19
|
+
|
|
20
|
+
try:
|
|
21
|
+
response.raise_for_status()
|
|
22
|
+
except HTTPError as err:
|
|
23
|
+
logger.info(f"Api raw response: {response.text}")
|
|
24
|
+
raise err
|
|
25
|
+
|
|
26
|
+
response = response.json()
|
|
27
|
+
return self.data_model(**response)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from pydantic import AnyUrl, BaseModel, Field
|
|
4
|
+
|
|
5
|
+
from ...utils.base_model import OBaseModel
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Lumisection(BaseModel):
|
|
9
|
+
dataset_id: int
|
|
10
|
+
dataset: str = Field(..., max_length=255)
|
|
11
|
+
run_number: int
|
|
12
|
+
ls_number: int
|
|
13
|
+
ls_id: int
|
|
14
|
+
th1_count: int
|
|
15
|
+
th2_count: int
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class PaginatedLumisectionList(BaseModel):
|
|
19
|
+
next: Optional[AnyUrl]
|
|
20
|
+
previous: Optional[AnyUrl]
|
|
21
|
+
results: list[Lumisection]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class LumisectionFilters(OBaseModel):
|
|
25
|
+
next_token: Optional[str] = None
|
|
26
|
+
dataset_id: Optional[int] = None
|
|
27
|
+
run_number: Optional[int] = None
|
|
28
|
+
run_number__lte: Optional[int] = None
|
|
29
|
+
run_number__gte: Optional[int] = None
|
|
30
|
+
ls_number: Optional[int] = None
|
|
31
|
+
ls_number__lte: Optional[int] = None
|
|
32
|
+
ls_number__gte: Optional[int] = None
|
|
33
|
+
dataset: Optional[str] = None
|
|
34
|
+
dataset__regex: Optional[str] = None
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
from requests.exceptions import HTTPError
|
|
3
|
+
|
|
4
|
+
from ...utils.api_client import BaseAuthorizedAPIClient
|
|
5
|
+
from ...utils.logger import logger
|
|
6
|
+
from .models import PaginatedRunList, Run, RunFilters
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class RunClient(BaseAuthorizedAPIClient):
|
|
10
|
+
data_model = Run
|
|
11
|
+
pagination_model = PaginatedRunList
|
|
12
|
+
filter_class = RunFilters
|
|
13
|
+
lookup_url = "run/"
|
|
14
|
+
|
|
15
|
+
def get(self, dataset_id: int, run_number: int):
|
|
16
|
+
endpoint_url = f"{self.api_url}{self.lookup_url}{dataset_id}/{run_number}/"
|
|
17
|
+
headers = self._build_headers()
|
|
18
|
+
response = requests.get(endpoint_url, headers=headers)
|
|
19
|
+
|
|
20
|
+
try:
|
|
21
|
+
response.raise_for_status()
|
|
22
|
+
except HTTPError as err:
|
|
23
|
+
logger.info(f"Api raw response: {response.text}")
|
|
24
|
+
raise err
|
|
25
|
+
|
|
26
|
+
response = response.json()
|
|
27
|
+
return self.data_model(**response)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from pydantic import AnyUrl, BaseModel, Field
|
|
4
|
+
|
|
5
|
+
from ...utils.base_model import OBaseModel
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Run(BaseModel):
|
|
9
|
+
dataset_id: int
|
|
10
|
+
dataset: str = Field(..., max_length=255)
|
|
11
|
+
run_number: int
|
|
12
|
+
ls_count: int
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class PaginatedRunList(BaseModel):
|
|
16
|
+
next: Optional[AnyUrl]
|
|
17
|
+
previous: Optional[AnyUrl]
|
|
18
|
+
results: list[Run]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class RunFilters(OBaseModel):
|
|
22
|
+
next_token: Optional[str] = None
|
|
23
|
+
dataset_id: Optional[int] = None
|
|
24
|
+
run_number: Optional[int] = None
|
|
25
|
+
run_number__lte: Optional[int] = None
|
|
26
|
+
run_number__gte: Optional[int] = None
|
|
27
|
+
dataset: Optional[str] = None
|
|
28
|
+
dataset__regex: Optional[str] = None
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from .auth._base import BaseCredentials
|
|
4
|
+
from .clients.file_index.client import FileIndexClient
|
|
5
|
+
from .clients.h1d.client import LumisectionHistogram1DClient
|
|
6
|
+
from .clients.h2d.client import LumisectionHistogram2DClient
|
|
7
|
+
from .clients.lumisection.client import LumisectionClient
|
|
8
|
+
from .clients.run.client import RunClient
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Dials:
|
|
12
|
+
def __init__(self, creds: BaseCredentials, workspace: Optional[str] = None, *args, **kwargs) -> None:
|
|
13
|
+
self.file_index = FileIndexClient(creds, workspace, *args, **kwargs)
|
|
14
|
+
self.h1d = LumisectionHistogram1DClient(creds, workspace, *args, **kwargs)
|
|
15
|
+
self.h2d = LumisectionHistogram2DClient(creds, workspace, *args, **kwargs)
|
|
16
|
+
self.lumi = LumisectionClient(creds, workspace, *args, **kwargs)
|
|
17
|
+
self.run = RunClient(creds, workspace, *args, **kwargs)
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
from .clients.bad_file_index.models import BadFileIndexFilters
|
|
2
1
|
from .clients.file_index.models import FileIndexFilters
|
|
3
2
|
from .clients.h1d.models import LumisectionHistogram1DFilters
|
|
4
3
|
from .clients.h2d.models import LumisectionHistogram2DFilters
|
|
@@ -6,7 +5,6 @@ from .clients.lumisection.models import LumisectionFilters
|
|
|
6
5
|
from .clients.run.models import RunFilters
|
|
7
6
|
|
|
8
7
|
__all__ = [
|
|
9
|
-
"BadFileIndexFilters",
|
|
10
8
|
"FileIndexFilters",
|
|
11
9
|
"LumisectionHistogram1DFilters",
|
|
12
10
|
"LumisectionHistogram2DFilters",
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
from concurrent.futures import ThreadPoolExecutor
|
|
2
|
-
from math import ceil
|
|
3
1
|
from typing import Optional
|
|
2
|
+
from urllib.parse import parse_qs, urlparse
|
|
4
3
|
|
|
5
4
|
import requests
|
|
6
5
|
from requests.exceptions import HTTPError
|
|
@@ -38,15 +37,27 @@ class BaseAuthorizedAPIClient(BaseAPIClient):
|
|
|
38
37
|
filter_class = None
|
|
39
38
|
lookup_url = None
|
|
40
39
|
|
|
41
|
-
def __init__(
|
|
40
|
+
def __init__(
|
|
41
|
+
self,
|
|
42
|
+
creds: BaseCredentials,
|
|
43
|
+
workspace: Optional[str] = None,
|
|
44
|
+
*args: str,
|
|
45
|
+
**kwargs: str,
|
|
46
|
+
) -> None:
|
|
42
47
|
super().__init__(*args, **kwargs)
|
|
43
48
|
self.creds = creds
|
|
44
|
-
self.
|
|
49
|
+
self.workspace = workspace
|
|
45
50
|
|
|
46
|
-
def
|
|
51
|
+
def _build_headers(self) -> dict:
|
|
52
|
+
base = {"accept": "application/json"}
|
|
53
|
+
if self.workspace is not None:
|
|
54
|
+
base["Workspace"] = self.workspace
|
|
55
|
+
self.creds.before_request(base)
|
|
56
|
+
return base
|
|
57
|
+
|
|
58
|
+
def get(self, id: int):
|
|
47
59
|
endpoint_url = self.api_url + self.lookup_url + str(id) + "/"
|
|
48
|
-
headers =
|
|
49
|
-
self.creds.before_request(headers)
|
|
60
|
+
headers = self._build_headers()
|
|
50
61
|
response = requests.get(endpoint_url, headers=headers)
|
|
51
62
|
|
|
52
63
|
try:
|
|
@@ -61,8 +72,7 @@ class BaseAuthorizedAPIClient(BaseAPIClient):
|
|
|
61
72
|
def list(self, filters=None):
|
|
62
73
|
filters = filters or self.filter_class()
|
|
63
74
|
endpoint_url = self.api_url + self.lookup_url
|
|
64
|
-
headers =
|
|
65
|
-
self.creds.before_request(headers)
|
|
75
|
+
headers = self._build_headers()
|
|
66
76
|
response = requests.get(endpoint_url, headers=headers, params=filters.cleandict())
|
|
67
77
|
|
|
68
78
|
try:
|
|
@@ -75,54 +85,25 @@ class BaseAuthorizedAPIClient(BaseAPIClient):
|
|
|
75
85
|
return self.pagination_model(**response)
|
|
76
86
|
|
|
77
87
|
def __list_sync(self, filters, max_pages: Optional[int] = None):
|
|
78
|
-
|
|
88
|
+
next_token = None
|
|
79
89
|
results = []
|
|
80
90
|
is_last_page = False
|
|
91
|
+
total_pages = 0
|
|
81
92
|
|
|
82
93
|
while is_last_page is False:
|
|
83
94
|
curr_filters = self.filter_class(**filters.dict())
|
|
84
|
-
curr_filters.
|
|
95
|
+
curr_filters.next_token = next_token
|
|
85
96
|
response = self.list(curr_filters)
|
|
86
97
|
results.extend(response.results)
|
|
87
98
|
is_last_page = response.next is None
|
|
88
|
-
|
|
89
|
-
|
|
99
|
+
next_token = parse_qs(urlparse(response.next).query).get("next_token") if response.next else None
|
|
100
|
+
total_pages += 1
|
|
101
|
+
if max_pages and total_pages > max_pages:
|
|
90
102
|
break
|
|
91
103
|
|
|
92
104
|
return self.pagination_model(
|
|
93
|
-
|
|
105
|
+
next=None, previous=None, results=results # No problem re-using last response count
|
|
94
106
|
)
|
|
95
107
|
|
|
96
|
-
def __list_multithreaded(self, filters, max_pages: Optional[int] = None):
|
|
97
|
-
results = []
|
|
98
|
-
|
|
99
|
-
# Request the first page to compute number of pages
|
|
100
|
-
curr_filters = self.filter_class(**filters.dict())
|
|
101
|
-
curr_filters.page = "1"
|
|
102
|
-
response = self.list(curr_filters)
|
|
103
|
-
results.extend(response.results)
|
|
104
|
-
count = response.count
|
|
105
|
-
n_pages = ceil(response.count / 10)
|
|
106
|
-
n_pages = max_pages if max_pages is not None and n_pages > max_pages else n_pages
|
|
107
|
-
|
|
108
|
-
# If there isn't another page, just return current results
|
|
109
|
-
if response.next is None:
|
|
110
|
-
return response
|
|
111
|
-
|
|
112
|
-
# Request other pages
|
|
113
|
-
all_filters = [{**filters.dict(), "page": str(page)} for page in range(2, n_pages + 1)]
|
|
114
|
-
all_filters = [self.filter_class(**filter) for filter in all_filters]
|
|
115
|
-
with ThreadPoolExecutor(max_workers=self.nthreads) as executor:
|
|
116
|
-
jobs = executor.map(self.list, all_filters)
|
|
117
|
-
del all_filters
|
|
118
|
-
[results.extend(job_result.results) for job_result in jobs]
|
|
119
|
-
del jobs
|
|
120
|
-
|
|
121
|
-
return self.pagination_model(count=count, next=None, previous=None, results=results)
|
|
122
|
-
|
|
123
108
|
def list_all(self, filters, max_pages: Optional[int] = None):
|
|
124
|
-
return (
|
|
125
|
-
self.__list_sync(filters, max_pages)
|
|
126
|
-
if self.nthreads is None
|
|
127
|
-
else self.__list_multithreaded(filters, max_pages)
|
|
128
|
-
)
|
|
109
|
+
return self.__list_sync(filters, max_pages)
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "cmsdials"
|
|
3
|
+
version = "1.0.0"
|
|
4
|
+
description = "The Python api client interface to DIALS service"
|
|
5
|
+
authors = ["Gabriel Moreira <gabrielmscampos@gmail.com>"]
|
|
6
|
+
readme = "README.md"
|
|
7
|
+
include = ["LICENSE"]
|
|
8
|
+
repository = "https://github.com/cms-DQM/dials-py"
|
|
9
|
+
classifiers = [
|
|
10
|
+
"Development Status :: 5 - Production/Stable",
|
|
11
|
+
"Programming Language :: Python",
|
|
12
|
+
"Operating System :: OS Independent",
|
|
13
|
+
"Topic :: Software Development :: Libraries :: Python Modules"
|
|
14
|
+
]
|
|
15
|
+
packages = [
|
|
16
|
+
{ include = "cmsdials" }
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[tool.poetry.dependencies]
|
|
20
|
+
python = "^3.9"
|
|
21
|
+
requests = "^2.31.0"
|
|
22
|
+
pydantic = "<2, >=1"
|
|
23
|
+
typing-extensions = "<4.6.0, >=3.6.6"
|
|
24
|
+
|
|
25
|
+
[tool.poetry.group.dev.dependencies]
|
|
26
|
+
pre-commit = "^3.6.2"
|
|
27
|
+
ruff = "^0.4.2"
|
|
28
|
+
|
|
29
|
+
[tool.ruff]
|
|
30
|
+
exclude = [
|
|
31
|
+
".bzr",
|
|
32
|
+
".direnv",
|
|
33
|
+
".eggs",
|
|
34
|
+
".git",
|
|
35
|
+
".git-rewrite",
|
|
36
|
+
".hg",
|
|
37
|
+
".mypy_cache",
|
|
38
|
+
".nox",
|
|
39
|
+
".pants.d",
|
|
40
|
+
".pytype",
|
|
41
|
+
".ruff_cache",
|
|
42
|
+
".svn",
|
|
43
|
+
".tox",
|
|
44
|
+
".venv",
|
|
45
|
+
"__pypackages__",
|
|
46
|
+
"_build",
|
|
47
|
+
"buck-out",
|
|
48
|
+
"build",
|
|
49
|
+
"dist",
|
|
50
|
+
"venv",
|
|
51
|
+
"virtualenvs",
|
|
52
|
+
]
|
|
53
|
+
line-length = 120
|
|
54
|
+
indent-width = 4
|
|
55
|
+
target-version = "py310"
|
|
56
|
+
|
|
57
|
+
[tool.ruff.lint]
|
|
58
|
+
select = [
|
|
59
|
+
# pycodestyle
|
|
60
|
+
"E",
|
|
61
|
+
# Pyflakes
|
|
62
|
+
"F",
|
|
63
|
+
# pep8-naming
|
|
64
|
+
"N",
|
|
65
|
+
# pyupgrade
|
|
66
|
+
"UP",
|
|
67
|
+
# flake8-bugbear
|
|
68
|
+
"B",
|
|
69
|
+
# flake8-bandit
|
|
70
|
+
"S",
|
|
71
|
+
# flake8-blind-except
|
|
72
|
+
"BLE",
|
|
73
|
+
# flake8-builtins
|
|
74
|
+
"A",
|
|
75
|
+
# isort
|
|
76
|
+
"I",
|
|
77
|
+
# flake8-logging-format
|
|
78
|
+
"G",
|
|
79
|
+
# flake8-no-pep420
|
|
80
|
+
"INP",
|
|
81
|
+
# Ruff-specific rules
|
|
82
|
+
"RUF"
|
|
83
|
+
]
|
|
84
|
+
ignore = [
|
|
85
|
+
# Disable eradicate (commented code removal)
|
|
86
|
+
"ERA001",
|
|
87
|
+
# Disable Conflicting lint rules,
|
|
88
|
+
# see https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules
|
|
89
|
+
"W191",
|
|
90
|
+
"E501",
|
|
91
|
+
"E111",
|
|
92
|
+
"E117",
|
|
93
|
+
"D206",
|
|
94
|
+
"D300",
|
|
95
|
+
"Q000",
|
|
96
|
+
"Q001",
|
|
97
|
+
"Q002",
|
|
98
|
+
"Q003",
|
|
99
|
+
"COM812",
|
|
100
|
+
"COM819",
|
|
101
|
+
"ISC001",
|
|
102
|
+
"ISC002",
|
|
103
|
+
# Disable unused `noqa` directive
|
|
104
|
+
"RUF100",
|
|
105
|
+
]
|
|
106
|
+
# Allow unused variables when underscore-prefixed:
|
|
107
|
+
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
|
|
108
|
+
|
|
109
|
+
[tool.ruff.lint.pycodestyle]
|
|
110
|
+
ignore-overlong-task-comments = true
|
|
111
|
+
|
|
112
|
+
[tool.ruff.lint.isort]
|
|
113
|
+
section-order = ["future", "standard-library", "third-party", "first-party", "local-folder"]
|
|
114
|
+
lines-after-imports = 2
|
|
115
|
+
|
|
116
|
+
[tool.ruff.lint.per-file-ignores]
|
|
117
|
+
# Ignore "E402", "F403", "F405" (import violations) in __init__.py files.
|
|
118
|
+
# Ignore "S" (flake8-bandit) and "N802" (function name should be lowercase) in tests and docs.
|
|
119
|
+
# Ignore "RUF" (Ruff-specific rules) and "I" (isort) in migrations.
|
|
120
|
+
"__init__.py" = ["E402", "F403", "F405"]
|
|
121
|
+
"**/{tests,docs}/*" = ["E402", "F403", "F405", "S", "N802"]
|
|
122
|
+
"**/*test*.py" = ["E402", "F403", "F405", "S", "N802"]
|
|
123
|
+
|
|
124
|
+
[build-system]
|
|
125
|
+
requires = ["poetry-core"]
|
|
126
|
+
build-backend = "poetry.core.masonry.api"
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
from ...utils.api_client import BaseAuthorizedAPIClient
|
|
2
|
-
from .models import BadFileIndex, BadFileIndexFilters, PaginatedBadFileIndexList
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class BadFileIndexClient(BaseAuthorizedAPIClient):
|
|
6
|
-
data_model = BadFileIndex
|
|
7
|
-
pagination_model = PaginatedBadFileIndexList
|
|
8
|
-
filter_class = BadFileIndexFilters
|
|
9
|
-
lookup_url = "bad-file-index/"
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
from datetime import datetime
|
|
2
|
-
from typing import List, Optional
|
|
3
|
-
|
|
4
|
-
from pydantic import AnyUrl, BaseModel, Field
|
|
5
|
-
|
|
6
|
-
from ...utils.base_model import OBaseModel
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class BadFileIndex(BaseModel):
|
|
10
|
-
id: int
|
|
11
|
-
file_path: str = Field(..., description="Path where the file is stored", max_length=255)
|
|
12
|
-
data_era: str = Field(..., description="The era that the data refers to (e.g. 2018A)", max_length=7)
|
|
13
|
-
st_size: float = Field(..., description="The data file's size in bytes")
|
|
14
|
-
st_ctime: datetime = Field(..., description="Time of files's last status change in filesystem")
|
|
15
|
-
st_itime: datetime = Field(..., description="Time when file was indexed in database")
|
|
16
|
-
err: str = Field(..., description="Error message", max_length=255)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class PaginatedBadFileIndexList(BaseModel):
|
|
20
|
-
count: int
|
|
21
|
-
next: Optional[AnyUrl]
|
|
22
|
-
previous: Optional[AnyUrl]
|
|
23
|
-
results: List[BadFileIndex]
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
class BadFileIndexFilters(OBaseModel):
|
|
27
|
-
era: Optional[str] = None
|
|
28
|
-
min_size: Optional[float] = None
|
|
29
|
-
page: Optional[str] = None
|
|
30
|
-
path_contains: Optional[str] = None
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
from datetime import datetime
|
|
2
|
-
from typing import List, Optional
|
|
3
|
-
|
|
4
|
-
from pydantic import AnyUrl, BaseModel, Field
|
|
5
|
-
|
|
6
|
-
from ...utils.base_model import OBaseModel
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class FileIndex(BaseModel):
|
|
10
|
-
id: int
|
|
11
|
-
file_uuid: str = Field(..., description="ROOT TFile UUID", max_length=36)
|
|
12
|
-
file_path: str = Field(..., description="Path where the file is stored", max_length=255)
|
|
13
|
-
data_era: str = Field(..., description="The era that the data refers to (e.g. 2018A)", max_length=7)
|
|
14
|
-
n_entries: int = Field(
|
|
15
|
-
...,
|
|
16
|
-
description="Total number of entries contained in this histogram file",
|
|
17
|
-
)
|
|
18
|
-
n_entries_ingested: int = Field(
|
|
19
|
-
...,
|
|
20
|
-
description="Number of histogram entries that have been extracted from the file",
|
|
21
|
-
)
|
|
22
|
-
st_size: float = Field(..., description="The data file's size in bytes")
|
|
23
|
-
st_ctime: datetime = Field(..., description="Time of files's last status change in filesystem")
|
|
24
|
-
st_itime: datetime = Field(..., description="Time when file was indexed in database")
|
|
25
|
-
status: str = Field(
|
|
26
|
-
...,
|
|
27
|
-
description="Indicate the processing status of run-histogram within the file",
|
|
28
|
-
max_length=9,
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
class PaginatedFileIndexList(BaseModel):
|
|
33
|
-
count: int
|
|
34
|
-
next: Optional[AnyUrl]
|
|
35
|
-
previous: Optional[AnyUrl]
|
|
36
|
-
results: List[FileIndex]
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
class FileIndexFilters(OBaseModel):
|
|
40
|
-
era: Optional[str] = None
|
|
41
|
-
min_size: Optional[float] = None
|
|
42
|
-
page: Optional[str] = None
|
|
43
|
-
path_contains: Optional[str] = None
|
|
44
|
-
status: Optional[str] = None
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
from datetime import datetime
|
|
2
|
-
from typing import List, Optional
|
|
3
|
-
|
|
4
|
-
from pydantic import AnyUrl, BaseModel, Field
|
|
5
|
-
|
|
6
|
-
from ...utils.base_model import OBaseModel
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class LumisectionHistogram1D(BaseModel):
|
|
10
|
-
id: int
|
|
11
|
-
ls_number: int
|
|
12
|
-
run_number: int
|
|
13
|
-
date: datetime
|
|
14
|
-
title: str = Field(..., max_length=220)
|
|
15
|
-
entries: int
|
|
16
|
-
data: list[float]
|
|
17
|
-
x_min: float
|
|
18
|
-
x_max: float
|
|
19
|
-
x_bin: int
|
|
20
|
-
source_data_file: int
|
|
21
|
-
lumisection: int
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class PaginatedLumisectionHistogram1DList(BaseModel):
|
|
25
|
-
count: int
|
|
26
|
-
next: Optional[AnyUrl]
|
|
27
|
-
previous: Optional[AnyUrl]
|
|
28
|
-
results: List[LumisectionHistogram1D]
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
class LumisectionHistogram1DFilters(OBaseModel):
|
|
32
|
-
ls_number: Optional[int] = None
|
|
33
|
-
lumisection_id: Optional[int] = None
|
|
34
|
-
max_ls_number: Optional[int] = None
|
|
35
|
-
max_run_number: Optional[int] = None
|
|
36
|
-
min_entries: Optional[int] = None
|
|
37
|
-
min_ls_number: Optional[int] = None
|
|
38
|
-
min_run_number: Optional[int] = None
|
|
39
|
-
page: Optional[str] = None
|
|
40
|
-
run_number: Optional[int] = None
|
|
41
|
-
title: Optional[str] = None
|
|
42
|
-
title_contains: Optional[str] = None
|
|
43
|
-
era: Optional[str] = None
|
|
44
|
-
dqmio_filepath_contains: Optional[str] = None
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
from datetime import datetime
|
|
2
|
-
from typing import Optional
|
|
3
|
-
|
|
4
|
-
from pydantic import AnyUrl, BaseModel, Field
|
|
5
|
-
|
|
6
|
-
from ...utils.base_model import OBaseModel
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class LumisectionHistogram2D(BaseModel):
|
|
10
|
-
id: int
|
|
11
|
-
ls_number: int
|
|
12
|
-
run_number: int
|
|
13
|
-
date: datetime
|
|
14
|
-
title: str = Field(..., max_length=220)
|
|
15
|
-
entries: int
|
|
16
|
-
data: list[list[float]]
|
|
17
|
-
x_min: float
|
|
18
|
-
x_max: float
|
|
19
|
-
x_bin: int
|
|
20
|
-
y_max: float
|
|
21
|
-
y_min: float
|
|
22
|
-
y_bin: int
|
|
23
|
-
source_data_file: int = Field(
|
|
24
|
-
...,
|
|
25
|
-
description="Source data file that the specific Histogram was read from, if any",
|
|
26
|
-
)
|
|
27
|
-
lumisection: int
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
class PaginatedLumisectionHistogram2DList(BaseModel):
|
|
31
|
-
count: int
|
|
32
|
-
next: Optional[AnyUrl]
|
|
33
|
-
previous: Optional[AnyUrl]
|
|
34
|
-
results: list[LumisectionHistogram2D]
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
class LumisectionHistogram2DFilters(OBaseModel):
|
|
38
|
-
ls_number: Optional[int] = None
|
|
39
|
-
lumisection_id: Optional[int] = None
|
|
40
|
-
max_ls_number: Optional[int] = None
|
|
41
|
-
max_run_number: Optional[int] = None
|
|
42
|
-
min_entries: Optional[int] = None
|
|
43
|
-
min_ls_number: Optional[int] = None
|
|
44
|
-
min_run_number: Optional[int] = None
|
|
45
|
-
page: Optional[str] = None
|
|
46
|
-
run_number: Optional[int] = None
|
|
47
|
-
title: Optional[str] = None
|
|
48
|
-
title_contains: Optional[str] = None
|
|
49
|
-
era: Optional[str] = None
|
|
50
|
-
dqmio_filepath_contains: Optional[str] = None
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import requests
|
|
2
|
-
|
|
3
|
-
from ...utils.api_client import BaseAuthorizedAPIClient
|
|
4
|
-
from .models import ConfiguredMEs, Lumisection, LumisectionFilters, PaginatedLumisectionList
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class LumisectionClient(BaseAuthorizedAPIClient):
|
|
8
|
-
data_model = Lumisection
|
|
9
|
-
pagination_model = PaginatedLumisectionList
|
|
10
|
-
filter_class = LumisectionFilters
|
|
11
|
-
lookup_url = "lumisection/"
|
|
12
|
-
|
|
13
|
-
def configured_mes(self):
|
|
14
|
-
endpoint_url = self.api_url + self.lookup_url + "configured-mes/"
|
|
15
|
-
headers = {"accept": "application/json"}
|
|
16
|
-
self.creds.before_request(headers)
|
|
17
|
-
response = requests.get(endpoint_url, headers=headers)
|
|
18
|
-
response.raise_for_status()
|
|
19
|
-
response = response.json()
|
|
20
|
-
return ConfiguredMEs(**response)
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
from datetime import datetime
|
|
2
|
-
from typing import List, Optional
|
|
3
|
-
|
|
4
|
-
from pydantic import AnyUrl, BaseModel
|
|
5
|
-
|
|
6
|
-
from ...utils.base_model import OBaseModel
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class Lumisection(BaseModel):
|
|
10
|
-
id: int
|
|
11
|
-
ls_number: int
|
|
12
|
-
date: datetime
|
|
13
|
-
oms_zerobias_rate: Optional[float]
|
|
14
|
-
run: int
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class PaginatedLumisectionList(BaseModel):
|
|
18
|
-
count: int
|
|
19
|
-
next: Optional[AnyUrl]
|
|
20
|
-
previous: Optional[AnyUrl]
|
|
21
|
-
results: list[Lumisection]
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class LumisectionFilters(OBaseModel):
|
|
25
|
-
ls_number: Optional[int] = None
|
|
26
|
-
max_ls_number: Optional[int] = None
|
|
27
|
-
max_run_number: Optional[int] = None
|
|
28
|
-
min_ls_number: Optional[int] = None
|
|
29
|
-
min_run_number: Optional[int] = None
|
|
30
|
-
page: Optional[str] = None
|
|
31
|
-
run_number: Optional[int] = None
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
class ConfiguredMEs(BaseModel):
|
|
35
|
-
mes: List[str]
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
from ...utils.api_client import BaseAuthorizedAPIClient
|
|
2
|
-
from .models import PaginatedRunList, Run, RunFilters
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class RunClient(BaseAuthorizedAPIClient):
|
|
6
|
-
data_model = Run
|
|
7
|
-
pagination_model = PaginatedRunList
|
|
8
|
-
filter_class = RunFilters
|
|
9
|
-
lookup_url = "run/"
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
from datetime import datetime
|
|
2
|
-
from typing import Optional
|
|
3
|
-
|
|
4
|
-
from pydantic import AnyUrl, BaseModel, Field
|
|
5
|
-
|
|
6
|
-
from ...utils.base_model import OBaseModel
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class Run(BaseModel):
|
|
10
|
-
run_number: int
|
|
11
|
-
run_date: Optional[datetime]
|
|
12
|
-
year: Optional[int]
|
|
13
|
-
period: Optional[str] = Field(..., max_length=1)
|
|
14
|
-
date: datetime
|
|
15
|
-
oms_fill: Optional[int]
|
|
16
|
-
oms_lumisections: Optional[int]
|
|
17
|
-
oms_initial_lumi: Optional[float]
|
|
18
|
-
oms_end_lumi: Optional[float]
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class PaginatedRunList(BaseModel):
|
|
22
|
-
count: int
|
|
23
|
-
next: Optional[AnyUrl]
|
|
24
|
-
previous: Optional[AnyUrl]
|
|
25
|
-
results: list[Run]
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
class RunFilters(OBaseModel):
|
|
29
|
-
max_run_number: Optional[int] = None
|
|
30
|
-
min_run_number: Optional[int] = None
|
|
31
|
-
page: Optional[str] = None
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
from typing import Optional
|
|
2
|
-
|
|
3
|
-
from .auth._base import BaseCredentials
|
|
4
|
-
from .clients.bad_file_index.client import BadFileIndexClient
|
|
5
|
-
from .clients.file_index.client import FileIndexClient
|
|
6
|
-
from .clients.h1d.client import LumisectionHistogram1DClient
|
|
7
|
-
from .clients.h2d.client import LumisectionHistogram2DClient
|
|
8
|
-
from .clients.lumisection.client import LumisectionClient
|
|
9
|
-
from .clients.run.client import RunClient
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class Dials:
|
|
13
|
-
def __init__(self, creds: BaseCredentials, nthreads: Optional[int] = None, *args, **kwargs) -> None:
|
|
14
|
-
self.bad_file_index = BadFileIndexClient(creds, nthreads, *args, **kwargs)
|
|
15
|
-
self.file_index = FileIndexClient(creds, nthreads, *args, **kwargs)
|
|
16
|
-
self.h1d = LumisectionHistogram1DClient(creds, nthreads, *args, **kwargs)
|
|
17
|
-
self.h2d = LumisectionHistogram2DClient(creds, nthreads, *args, **kwargs)
|
|
18
|
-
self.lumi = LumisectionClient(creds, nthreads, *args, **kwargs)
|
|
19
|
-
self.run = RunClient(creds, nthreads, *args, **kwargs)
|
|
File without changes
|
cmsdials-0.3.0/pyproject.toml
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
[tool.poetry]
|
|
2
|
-
name = "cmsdials"
|
|
3
|
-
version = "0.3.0"
|
|
4
|
-
description = "The Python api client interface to DIALS service"
|
|
5
|
-
authors = ["Gabriel Moreira <gabrielmscampos@gmail.com>"]
|
|
6
|
-
readme = "README.md"
|
|
7
|
-
include = ["LICENSE"]
|
|
8
|
-
repository = "https://github.com/cms-DQM/dials-py"
|
|
9
|
-
classifiers = [
|
|
10
|
-
"Development Status :: 4 - Beta",
|
|
11
|
-
"Programming Language :: Python",
|
|
12
|
-
"Operating System :: OS Independent",
|
|
13
|
-
"Topic :: Software Development :: Libraries :: Python Modules"
|
|
14
|
-
]
|
|
15
|
-
packages = [
|
|
16
|
-
{ include = "cmsdials" }
|
|
17
|
-
]
|
|
18
|
-
|
|
19
|
-
[tool.poetry.dependencies]
|
|
20
|
-
python = "^3.9"
|
|
21
|
-
requests = "^2.31.0"
|
|
22
|
-
pydantic = "<2, >=1"
|
|
23
|
-
typing-extensions = "<4.6.0, >=3.6.6"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
[tool.poetry.group.dev.dependencies]
|
|
27
|
-
pre-commit = "^3.6.2"
|
|
28
|
-
|
|
29
|
-
[build-system]
|
|
30
|
-
requires = ["poetry-core"]
|
|
31
|
-
build-backend = "poetry.core.masonry.api"
|
|
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
|
{cmsdials-0.3.0/cmsdials/clients/file_index → cmsdials-1.0.0/cmsdials/clients/h1d}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{cmsdials-0.3.0/cmsdials/clients/h2d → cmsdials-1.0.0/cmsdials/clients/lumisection}/__init__.py
RENAMED
|
File without changes
|
{cmsdials-0.3.0/cmsdials/clients/lumisection → cmsdials-1.0.0/cmsdials/clients/run}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|