Skip to content

Commit b03406b

Browse files
committed
feat: add diracx-logic between diracx-routers and diracx-db
1 parent 58fc23f commit b03406b

File tree

85 files changed

+3146
-2406
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+3146
-2406
lines changed

.github/workflows/extensions.yml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,13 @@ jobs:
2727
- package: "./extensions/gubbins/gubbins-core"
2828
dependencies: "./extensions/gubbins/gubbins-testing ./diracx-testing ./diracx-core"
2929
- package: "./extensions/gubbins/gubbins-db"
30-
dependencies: "./extensions/gubbins/gubbins-testing ./extensions/gubbins/gubbins-core ./diracx-testing ./diracx-db ./diracx-core "
30+
dependencies: "./extensions/gubbins/gubbins-testing ./extensions/gubbins/gubbins-core ./diracx-testing ./diracx-db ./diracx-core"
31+
- package: "./extensions/gubbins/gubbins-logic"
32+
dependencies: "./extensions/gubbins/gubbins-db ./extensions/gubbins/gubbins-core ./diracx-db ./diracx-core ./diracx-logic"
3133
- package: "./extensions/gubbins/gubbins-routers"
32-
dependencies: "./extensions/gubbins/gubbins-testing ./extensions/gubbins/gubbins-db ./extensions/gubbins/gubbins-core ./diracx-testing ./diracx-db ./diracx-core ./diracx-routers"
34+
dependencies: "./extensions/gubbins/gubbins-testing ./extensions/gubbins/gubbins-db ./extensions/gubbins/gubbins-logic ./extensions/gubbins/gubbins-core ./diracx-testing ./diracx-db ./diracx-logic ./diracx-core ./diracx-routers"
3335
- package: "./extensions/gubbins/gubbins-client"
34-
dependencies: "./extensions/gubbins/gubbins-testing ./diracx-testing ./extensions/gubbins/gubbins-client ./extensions/gubbins/gubbins-core ./diracx-client ./diracx-core "
36+
dependencies: "./extensions/gubbins/gubbins-testing ./diracx-testing ./extensions/gubbins/gubbins-client ./extensions/gubbins/gubbins-core ./diracx-client ./diracx-core"
3537
- package: "./extensions/gubbins/gubbins-cli"
3638
dependencies: "./extensions/gubbins/gubbins-testing ./extensions/gubbins/gubbins-client ./extensions/gubbins/gubbins-core ./diracx-testing ./diracx-cli ./diracx-client ./diracx-core ./diracx-api"
3739
steps:
@@ -58,6 +60,7 @@ jobs:
5860
run: |
5961
mypy ${{ matrix.package }}/src
6062
- name: Run pytest
63+
if: ${{ matrix.package != './extensions/gubbins/gubbins-logic' }}
6164
run: |
6265
cd ${{ matrix.package }}
6366
pip install .[testing]
@@ -147,7 +150,7 @@ jobs:
147150
outputs: type=docker,dest=/tmp/gubbins_services_image.tar
148151
build-args: |
149152
EXTRA_PACKAGES_TO_INSTALL=git+https://github.com/DIRACGrid/DIRAC.git@integration
150-
EXTENSION_CUSTOM_SOURCES_TO_INSTALL=/bindmount/gubbins_db*.whl,/bindmount/gubbins_routers*.whl,/bindmount/gubbins_client*.whl
153+
EXTENSION_CUSTOM_SOURCES_TO_INSTALL=/bindmount/gubbins_db*.whl,/bindmount/gubbins_logic*.whl,/bindmount/gubbins_routers*.whl,/bindmount/gubbins_client*.whl
151154
- name: Build and export client
152155
uses: docker/build-push-action@v6
153156
with:
@@ -185,7 +188,7 @@ jobs:
185188
run: |
186189
pip install pytest-github-actions-annotate-failures
187190
pip install git+https://github.com/DIRACGrid/DIRAC.git@integration
188-
pip install ./diracx-core/[testing] ./diracx-api/[testing] ./diracx-cli/[testing] ./diracx-client/[testing] ./diracx-routers/[testing] ./diracx-db/[testing] ./diracx-testing/[testing] ./extensions/gubbins/gubbins-testing[testing] ./extensions/gubbins/gubbins-db[testing] ./extensions/gubbins/gubbins-routers/[testing] ./extensions/gubbins/gubbins-client/[testing] ./extensions/gubbins/gubbins-cli/[testing] ./extensions/gubbins/gubbins-core/[testing]
191+
pip install ./diracx-core/[testing] ./diracx-api/[testing] ./diracx-cli/[testing] ./diracx-client/[testing] ./diracx-routers/[testing] ./diracx-logic/[testing] ./diracx-db/[testing] ./diracx-testing/[testing] ./extensions/gubbins/gubbins-testing[testing] ./extensions/gubbins/gubbins-db[testing] ./extensions/gubbins/gubbins-logic/[testing] ./extensions/gubbins/gubbins-routers/[testing] ./extensions/gubbins/gubbins-client/[testing] ./extensions/gubbins/gubbins-cli/[testing] ./extensions/gubbins/gubbins-core/[testing]
189192
- name: Start demo
190193
run: |
191194
git clone https://github.com/DIRACGrid/diracx-charts.git ../diracx-charts
@@ -274,7 +277,7 @@ jobs:
274277
run: |
275278
micromamba install -c conda-forge nodejs pre-commit
276279
pip install git+https://github.com/DIRACGrid/DIRAC.git@integration
277-
pip install ./diracx-core/[testing] ./diracx-api/[testing] ./diracx-cli/[testing] ./diracx-client/[testing] ./diracx-routers/[testing] ./diracx-db/[testing] ./diracx-testing/[testing] ./extensions/gubbins/gubbins-testing[testing] ./extensions/gubbins/gubbins-db[testing] ./extensions/gubbins/gubbins-routers/[testing] ./extensions/gubbins/gubbins-testing/[testing] -e ./extensions/gubbins/gubbins-client/[testing] ./extensions/gubbins/gubbins-core/[testing]
280+
pip install ./diracx-core/[testing] ./diracx-api/[testing] ./diracx-cli/[testing] ./diracx-client/[testing] ./diracx-routers/[testing] ./diracx-logic/[testing] ./diracx-logic/[testing] ./diracx-db/[testing] ./diracx-testing/[testing] ./extensions/gubbins/gubbins-testing[testing] ./extensions/gubbins/gubbins-db[testing] ./extensions/gubbins/gubbins-logic[testing] ./extensions/gubbins/gubbins-routers/[testing] ./extensions/gubbins/gubbins-testing/[testing] -e ./extensions/gubbins/gubbins-client/[testing] ./extensions/gubbins/gubbins-core/[testing]
278281
npm install -g autorest
279282
- name: Run autorest
280283
run: |

.github/workflows/main.yml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ jobs:
2929
run: |
3030
find -name '*.sh' -print0 | xargs -0 -n1 shellcheck --exclude=SC1090,SC1091 --external-source
3131
32-
3332
unittest:
3433
name: Unit test - ${{ matrix.package }}
3534
runs-on: ubuntu-latest
@@ -41,8 +40,10 @@ jobs:
4140
dependencies: "./diracx-testing"
4241
- package: "./diracx-db"
4342
dependencies: "./diracx-testing ./diracx-core"
43+
- package: "./diracx-logic"
44+
dependencies: "./diracx-core ./diracx-db"
4445
- package: "./diracx-routers"
45-
dependencies: "./diracx-testing ./diracx-core ./diracx-db"
46+
dependencies: "./diracx-testing ./diracx-core ./diracx-db ./diracx-logic"
4647
- package: "./diracx-client"
4748
dependencies: "./diracx-testing ./diracx-core"
4849
- package: "./diracx-api"
@@ -68,6 +69,7 @@ jobs:
6869
pip install git+https://github.com/DIRACGrid/DIRAC.git@integration
6970
pip install ${{ matrix.dependencies }}
7071
- name: Run pytest
72+
if: ${{ matrix.package != './diracx-logic' }}
7173
run: |
7274
cd ${{ matrix.package }}
7375
pip install .[testing]
@@ -93,7 +95,7 @@ jobs:
9395
run: |
9496
pip install pytest-github-actions-annotate-failures
9597
pip install git+https://github.com/DIRACGrid/DIRAC.git@integration
96-
pip install ./diracx-core/[testing] ./diracx-api/[testing] ./diracx-cli/[testing] ./diracx-client/[testing] ./diracx-routers/[testing] ./diracx-db/[testing] ./diracx-testing/
98+
pip install ./diracx-core/[testing] ./diracx-api/[testing] ./diracx-cli/[testing] ./diracx-client/[testing] ./diracx-routers/[testing] ./diracx-logic/[testing] ./diracx-db/[testing] ./diracx-testing/
9799
- name: Start demo
98100
run: |
99101
git clone https://github.com/DIRACGrid/diracx-charts.git ../diracx-charts
@@ -162,7 +164,7 @@ jobs:
162164
run: |
163165
micromamba install -c conda-forge nodejs pre-commit
164166
pip install git+https://github.com/DIRACGrid/DIRAC.git@integration
165-
pip install ./diracx-core/ ./diracx-api/ ./diracx-cli/ -e ./diracx-client/[testing] ./diracx-routers/[testing] ./diracx-db/ ./diracx-testing/
167+
pip install ./diracx-core/ ./diracx-api/ ./diracx-cli/ -e ./diracx-client/[testing] ./diracx-routers/[testing] ./diracx-logic/[testing] ./diracx-db/ ./diracx-testing/
166168
npm install -g autorest
167169
- name: Run autorest
168170
run: |

diracx-core/pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ testing = [
3333
]
3434
types = [
3535
"botocore-stubs",
36+
"types-aiobotocore[essential]",
3637
"types-aiobotocore-s3",
3738
"types-cachetools",
3839
"types-PyYAML",

diracx-core/src/diracx/core/exceptions.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,18 @@ class ExpiredFlowError(AuthorizationError):
2828
"""Used only for the Device Flow when the polling is expired."""
2929

3030

31+
class IAMServerError(DiracError):
32+
"""Used whenever we encounter a server problem with the IAM server."""
33+
34+
35+
class IAMClientError(DiracError):
36+
"""Used whenever we encounter a client problem with the IAM server."""
37+
38+
39+
class InvalidCredentialsError(DiracError):
40+
"""Used whenever the credentials are invalid."""
41+
42+
3143
class ConfigurationError(DiracError):
3244
"""Used whenever we encounter a problem with the configuration."""
3345

@@ -40,6 +52,12 @@ class InvalidQueryError(DiracError):
4052
"""It was not possible to build a valid database query from the given input."""
4153

4254

55+
class TokenNotFoundError(Exception):
56+
def __init__(self, jti: str, detail: str | None = None):
57+
self.jti: str = jti
58+
super().__init__(f"Token {jti} not found" + (" ({detail})" if detail else ""))
59+
60+
4361
class JobNotFoundError(Exception):
4462
def __init__(self, job_id: int, detail: str | None = None):
4563
self.job_id: int = job_id
@@ -66,6 +84,16 @@ def __init__(self, pfn: str, se_name: str, detail: str | None = None):
6684
)
6785

6886

87+
class SandboxAlreadyInsertedError(Exception):
88+
def __init__(self, pfn: str, se_name: str, detail: str | None = None):
89+
self.pfn: str = pfn
90+
self.se_name: str = se_name
91+
super().__init__(
92+
f"Sandbox with {pfn} and {se_name} already inserted"
93+
+ (" ({detail})" if detail else "")
94+
)
95+
96+
6997
class JobError(Exception):
7098
def __init__(self, job_id, detail: str | None = None):
7199
self.job_id: int = job_id

diracx-core/src/diracx/core/models.py

Lines changed: 118 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,25 @@ class SortSpec(TypedDict):
4646
direction: SortDirection
4747

4848

49-
class TokenResponse(BaseModel):
50-
# Based on RFC 6749
51-
access_token: str
52-
expires_in: int
53-
token_type: str = "Bearer" # noqa: S105
54-
refresh_token: str | None = None
49+
class InsertedJob(TypedDict):
50+
JobID: int
51+
Status: str
52+
MinorStatus: str
53+
TimeStamp: datetime
54+
55+
56+
class JobSummaryParams(BaseModel):
57+
grouping: list[str]
58+
search: list[SearchSpec] = []
59+
# TODO: Add more validation
60+
61+
62+
class JobSearchParams(BaseModel):
63+
parameters: list[str] | None = None
64+
search: list[SearchSpec] = []
65+
sort: list[SortSpec] = []
66+
distinct: bool = False
67+
# TODO: Add more validation
5568

5669

5770
class JobStatus(StrEnum):
@@ -77,6 +90,15 @@ class JobMinorStatus(StrEnum):
7790
RESCHEDULED = "Job Rescheduled"
7891

7992

93+
class JobLoggingRecord(BaseModel):
94+
job_id: int
95+
status: JobStatus
96+
minor_status: str
97+
application_status: str
98+
date: datetime
99+
source: str
100+
101+
80102
class JobStatusUpdate(BaseModel):
81103
Status: JobStatus | None = None
82104
MinorStatus: str | None = None
@@ -136,3 +158,93 @@ class SandboxInfo(BaseModel):
136158
class SandboxType(StrEnum):
137159
Input = "Input"
138160
Output = "Output"
161+
162+
163+
class SandboxDownloadResponse(BaseModel):
164+
url: str
165+
expires_in: int
166+
167+
168+
class SandboxUploadResponse(BaseModel):
169+
pfn: str
170+
url: str | None = None
171+
fields: dict[str, str] = {}
172+
173+
174+
class GrantType(StrEnum):
175+
"""Grant types for OAuth2."""
176+
177+
authorization_code = "authorization_code"
178+
device_code = "urn:ietf:params:oauth:grant-type:device_code"
179+
refresh_token = "refresh_token" # noqa: S105 # False positive of Bandit about hard coded password
180+
181+
182+
class InitiateDeviceFlowResponse(TypedDict):
183+
"""Response for the device flow initiation."""
184+
185+
user_code: str
186+
device_code: str
187+
verification_uri_complete: str
188+
verification_uri: str
189+
expires_in: int
190+
191+
192+
class OpenIDConfiguration(TypedDict):
193+
issuer: str
194+
token_endpoint: str
195+
userinfo_endpoint: str
196+
authorization_endpoint: str
197+
device_authorization_endpoint: str
198+
grant_types_supported: list[str]
199+
scopes_supported: list[str]
200+
response_types_supported: list[str]
201+
token_endpoint_auth_signing_alg_values_supported: list[str]
202+
token_endpoint_auth_methods_supported: list[str]
203+
code_challenge_methods_supported: list[str]
204+
205+
206+
class TokenPayload(TypedDict):
207+
jti: str
208+
exp: datetime
209+
dirac_policies: dict
210+
211+
212+
class TokenResponse(BaseModel):
213+
# Based on RFC 6749
214+
access_token: str
215+
expires_in: int
216+
token_type: str = "Bearer" # noqa: S105
217+
refresh_token: str | None = None
218+
219+
220+
class AccessTokenPayload(TokenPayload):
221+
sub: str
222+
vo: str
223+
iss: str
224+
dirac_properties: list[str]
225+
preferred_username: str
226+
dirac_group: str
227+
228+
229+
class RefreshTokenPayload(TokenPayload):
230+
legacy_exchange: bool
231+
232+
233+
class SupportInfo(TypedDict):
234+
message: str
235+
webpage: str | None
236+
email: str | None
237+
238+
239+
class GroupInfo(TypedDict):
240+
properties: list[str]
241+
242+
243+
class VOInfo(TypedDict):
244+
groups: dict[str, GroupInfo]
245+
support: SupportInfo
246+
default_group: str
247+
248+
249+
class Metadata(TypedDict):
250+
virtual_organizations: dict[str, VOInfo]

0 commit comments

Comments
 (0)