diracx-db 0.0.1a18__tar.gz → 0.0.1a20__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/PKG-INFO +1 -1
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/pyproject.toml +2 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx/db/__main__.py +1 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx/db/sql/__init__.py +9 -1
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx/db/sql/job/schema.py +1 -46
- diracx_db-0.0.1a20/src/diracx/db/sql/pilot_agents/db.py +46 -0
- diracx_db-0.0.1a20/src/diracx/db/sql/pilot_agents/schema.py +58 -0
- diracx_db-0.0.1a20/src/diracx/db/sql/task_queue/__init__.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx/db/sql/utils/__init__.py +27 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx_db.egg-info/PKG-INFO +1 -1
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx_db.egg-info/SOURCES.txt +6 -1
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx_db.egg-info/entry_points.txt +1 -0
- diracx_db-0.0.1a20/tests/pilot_agents/__init__.py +0 -0
- diracx_db-0.0.1a20/tests/pilot_agents/test_pilotAgentsDB.py +31 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/README.md +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/setup.cfg +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx/db/__init__.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx/db/exceptions.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx/db/os/__init__.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx/db/os/job_parameters.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx/db/os/utils.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx/db/py.typed +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx/db/sql/auth/__init__.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx/db/sql/auth/db.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx/db/sql/auth/schema.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx/db/sql/dummy/__init__.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx/db/sql/dummy/db.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx/db/sql/dummy/schema.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx/db/sql/job/__init__.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx/db/sql/job/db.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx/db/sql/job_logging/__init__.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx/db/sql/job_logging/db.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx/db/sql/job_logging/schema.py +0 -0
- {diracx_db-0.0.1a18/src/diracx/db/sql/sandbox_metadata → diracx_db-0.0.1a20/src/diracx/db/sql/pilot_agents}/__init__.py +0 -0
- {diracx_db-0.0.1a18/src/diracx/db/sql/task_queue → diracx_db-0.0.1a20/src/diracx/db/sql/sandbox_metadata}/__init__.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx/db/sql/sandbox_metadata/db.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx/db/sql/sandbox_metadata/schema.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx/db/sql/task_queue/db.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx/db/sql/task_queue/schema.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx/db/sql/utils/job_status.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx_db.egg-info/dependency_links.txt +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx_db.egg-info/requires.txt +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/src/diracx_db.egg-info/top_level.txt +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/tests/auth/test_authorization_flow.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/tests/auth/test_device_flow.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/tests/auth/test_refresh_token.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/tests/jobs/test_jobDB.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/tests/jobs/test_jobLoggingDB.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/tests/jobs/test_sandbox_metadata.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/tests/opensearch/test_connection.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/tests/opensearch/test_index_template.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/tests/opensearch/test_search.py +0 -0
- {diracx_db-0.0.1a18 → diracx_db-0.0.1a20}/tests/test_dummyDB.py +0 -0
@@ -31,6 +31,7 @@ testing = [
|
|
31
31
|
AuthDB = "diracx.db.sql:AuthDB"
|
32
32
|
JobDB = "diracx.db.sql:JobDB"
|
33
33
|
JobLoggingDB = "diracx.db.sql:JobLoggingDB"
|
34
|
+
PilotAgentsDB = "diracx.db.sql:PilotAgentsDB"
|
34
35
|
SandboxMetadataDB = "diracx.db.sql:SandboxMetadataDB"
|
35
36
|
TaskQueueDB = "diracx.db.sql:TaskQueueDB"
|
36
37
|
|
@@ -47,6 +48,7 @@ build-backend = "setuptools.build_meta"
|
|
47
48
|
[tool.setuptools_scm]
|
48
49
|
root = ".."
|
49
50
|
|
51
|
+
|
50
52
|
[tool.pytest.ini_options]
|
51
53
|
testpaths = ["tests"]
|
52
54
|
addopts = [
|
@@ -31,6 +31,7 @@ async def init_sql():
|
|
31
31
|
from diracx.db.sql.utils import BaseSQLDB
|
32
32
|
|
33
33
|
for db_name, db_url in BaseSQLDB.available_urls().items():
|
34
|
+
|
34
35
|
logger.info("Initialising %s", db_name)
|
35
36
|
db = BaseSQLDB.available_implementations(db_name)[0](db_url)
|
36
37
|
async with db.engine_context():
|
@@ -1,9 +1,17 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
__all__ = (
|
3
|
+
__all__ = (
|
4
|
+
"AuthDB",
|
5
|
+
"JobDB",
|
6
|
+
"JobLoggingDB",
|
7
|
+
"PilotAgentsDB",
|
8
|
+
"SandboxMetadataDB",
|
9
|
+
"TaskQueueDB",
|
10
|
+
)
|
4
11
|
|
5
12
|
from .auth.db import AuthDB
|
6
13
|
from .job.db import JobDB
|
7
14
|
from .job_logging.db import JobLoggingDB
|
15
|
+
from .pilot_agents.db import PilotAgentsDB
|
8
16
|
from .sandbox_metadata.db import SandboxMetadataDB
|
9
17
|
from .task_queue.db import TaskQueueDB
|
@@ -1,4 +1,3 @@
|
|
1
|
-
import sqlalchemy.types as types
|
2
1
|
from sqlalchemy import (
|
3
2
|
DateTime,
|
4
3
|
Enum,
|
@@ -10,37 +9,11 @@ from sqlalchemy import (
|
|
10
9
|
)
|
11
10
|
from sqlalchemy.orm import declarative_base
|
12
11
|
|
13
|
-
from ..utils import Column, NullColumn
|
12
|
+
from ..utils import Column, EnumBackedBool, NullColumn
|
14
13
|
|
15
14
|
JobDBBase = declarative_base()
|
16
15
|
|
17
16
|
|
18
|
-
class EnumBackedBool(types.TypeDecorator):
|
19
|
-
"""Maps a ``EnumBackedBool()`` column to True/False in Python."""
|
20
|
-
|
21
|
-
impl = types.Enum
|
22
|
-
cache_ok: bool = True
|
23
|
-
|
24
|
-
def __init__(self) -> None:
|
25
|
-
super().__init__("True", "False")
|
26
|
-
|
27
|
-
def process_bind_param(self, value, dialect) -> str:
|
28
|
-
if value is True:
|
29
|
-
return "True"
|
30
|
-
elif value is False:
|
31
|
-
return "False"
|
32
|
-
else:
|
33
|
-
raise NotImplementedError(value, dialect)
|
34
|
-
|
35
|
-
def process_result_value(self, value, dialect) -> bool:
|
36
|
-
if value == "True":
|
37
|
-
return True
|
38
|
-
elif value == "False":
|
39
|
-
return False
|
40
|
-
else:
|
41
|
-
raise NotImplementedError(f"Unknown {value=}")
|
42
|
-
|
43
|
-
|
44
17
|
class Jobs(JobDBBase):
|
45
18
|
__tablename__ = "Jobs"
|
46
19
|
|
@@ -134,24 +107,6 @@ class AtticJobParameters(JobDBBase):
|
|
134
107
|
RescheduleCycle = Column(Integer)
|
135
108
|
|
136
109
|
|
137
|
-
class SiteMask(JobDBBase):
|
138
|
-
__tablename__ = "SiteMask"
|
139
|
-
Site = Column(String(64), primary_key=True)
|
140
|
-
Status = Column(String(64))
|
141
|
-
LastUpdateTime = Column(DateTime)
|
142
|
-
Author = Column(String(255))
|
143
|
-
Comment = Column(Text)
|
144
|
-
|
145
|
-
|
146
|
-
class SiteMaskLogging(JobDBBase):
|
147
|
-
__tablename__ = "SiteMaskLogging"
|
148
|
-
Site = Column(String(64), primary_key=True)
|
149
|
-
UpdateTime = Column(DateTime, primary_key=True)
|
150
|
-
Status = Column(String(64))
|
151
|
-
Author = Column(String(255))
|
152
|
-
Comment = Column(Text)
|
153
|
-
|
154
|
-
|
155
110
|
class HeartBeatLoggingInfo(JobDBBase):
|
156
111
|
__tablename__ = "HeartBeatLoggingInfo"
|
157
112
|
JobID = Column(
|
@@ -0,0 +1,46 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from datetime import datetime, timezone
|
4
|
+
|
5
|
+
from sqlalchemy import insert
|
6
|
+
|
7
|
+
from ..utils import BaseSQLDB
|
8
|
+
from .schema import PilotAgents, PilotAgentsDBBase
|
9
|
+
|
10
|
+
|
11
|
+
class PilotAgentsDB(BaseSQLDB):
|
12
|
+
"""PilotAgentsDB class is a front-end to the PilotAgents Database."""
|
13
|
+
|
14
|
+
metadata = PilotAgentsDBBase.metadata
|
15
|
+
|
16
|
+
async def add_pilot_references(
|
17
|
+
self,
|
18
|
+
pilot_ref: list[str],
|
19
|
+
vo: str,
|
20
|
+
grid_type: str = "DIRAC",
|
21
|
+
pilot_stamps: dict | None = None,
|
22
|
+
) -> None:
|
23
|
+
|
24
|
+
if pilot_stamps is None:
|
25
|
+
pilot_stamps = {}
|
26
|
+
|
27
|
+
now = datetime.now(tz=timezone.utc)
|
28
|
+
|
29
|
+
# Prepare the list of dictionaries for bulk insertion
|
30
|
+
values = [
|
31
|
+
{
|
32
|
+
"PilotJobReference": ref,
|
33
|
+
"VO": vo,
|
34
|
+
"GridType": grid_type,
|
35
|
+
"SubmissionTime": now,
|
36
|
+
"LastUpdateTime": now,
|
37
|
+
"Status": "Submitted",
|
38
|
+
"PilotStamp": pilot_stamps.get(ref, ""),
|
39
|
+
}
|
40
|
+
for ref in pilot_ref
|
41
|
+
]
|
42
|
+
|
43
|
+
# Insert multiple rows in a single execute call
|
44
|
+
stmt = insert(PilotAgents).values(values)
|
45
|
+
await self.conn.execute(stmt)
|
46
|
+
return
|
@@ -0,0 +1,58 @@
|
|
1
|
+
from sqlalchemy import (
|
2
|
+
DateTime,
|
3
|
+
Double,
|
4
|
+
Index,
|
5
|
+
Integer,
|
6
|
+
String,
|
7
|
+
Text,
|
8
|
+
)
|
9
|
+
from sqlalchemy.orm import declarative_base
|
10
|
+
|
11
|
+
from ..utils import Column, EnumBackedBool, NullColumn
|
12
|
+
|
13
|
+
PilotAgentsDBBase = declarative_base()
|
14
|
+
|
15
|
+
|
16
|
+
class PilotAgents(PilotAgentsDBBase):
|
17
|
+
__tablename__ = "PilotAgents"
|
18
|
+
|
19
|
+
PilotID = Column("PilotID", Integer, autoincrement=True, primary_key=True)
|
20
|
+
InitialJobID = Column("InitialJobID", Integer, default=0)
|
21
|
+
CurrentJobID = Column("CurrentJobID", Integer, default=0)
|
22
|
+
PilotJobReference = Column("PilotJobReference", String(255), default="Unknown")
|
23
|
+
PilotStamp = Column("PilotStamp", String(32), default="")
|
24
|
+
DestinationSite = Column("DestinationSite", String(128), default="NotAssigned")
|
25
|
+
Queue = Column("Queue", String(128), default="Unknown")
|
26
|
+
GridSite = Column("GridSite", String(128), default="Unknown")
|
27
|
+
VO = Column("VO", String(128))
|
28
|
+
GridType = Column("GridType", String(32), default="LCG")
|
29
|
+
BenchMark = Column("BenchMark", Double, default=0.0)
|
30
|
+
SubmissionTime = NullColumn("SubmissionTime", DateTime)
|
31
|
+
LastUpdateTime = NullColumn("LastUpdateTime", DateTime)
|
32
|
+
Status = Column("Status", String(32), default="Unknown")
|
33
|
+
StatusReason = Column("StatusReason", String(255), default="Unknown")
|
34
|
+
AccountingSent = Column("AccountingSent", EnumBackedBool(), default=False)
|
35
|
+
|
36
|
+
__table_args__ = (
|
37
|
+
Index("PilotJobReference", "PilotJobReference"),
|
38
|
+
Index("Status", "Status"),
|
39
|
+
Index("Statuskey", "GridSite", "DestinationSite", "Status"),
|
40
|
+
)
|
41
|
+
|
42
|
+
|
43
|
+
class JobToPilotMapping(PilotAgentsDBBase):
|
44
|
+
__tablename__ = "JobToPilotMapping"
|
45
|
+
|
46
|
+
PilotID = Column("PilotID", Integer, primary_key=True)
|
47
|
+
JobID = Column("JobID", Integer, primary_key=True)
|
48
|
+
StartTime = Column("StartTime", DateTime)
|
49
|
+
|
50
|
+
__table_args__ = (Index("JobID", "JobID"), Index("PilotID", "PilotID"))
|
51
|
+
|
52
|
+
|
53
|
+
class PilotOutput(PilotAgentsDBBase):
|
54
|
+
__tablename__ = "PilotOutput"
|
55
|
+
|
56
|
+
PilotID = Column("PilotID", Integer, primary_key=True)
|
57
|
+
StdOutput = Column("StdOutput", Text)
|
58
|
+
StdError = Column("StdError", Text)
|
File without changes
|
@@ -13,6 +13,7 @@ from datetime import datetime, timedelta, timezone
|
|
13
13
|
from functools import partial
|
14
14
|
from typing import TYPE_CHECKING, Self, cast
|
15
15
|
|
16
|
+
import sqlalchemy.types as types
|
16
17
|
from pydantic import TypeAdapter
|
17
18
|
from sqlalchemy import Column as RawColumn
|
18
19
|
from sqlalchemy import DateTime, Enum, MetaData, select
|
@@ -128,6 +129,32 @@ def EnumColumn(enum_type, **kwargs):
|
|
128
129
|
return Column(Enum(enum_type, native_enum=False, length=16), **kwargs)
|
129
130
|
|
130
131
|
|
132
|
+
class EnumBackedBool(types.TypeDecorator):
|
133
|
+
"""Maps a ``EnumBackedBool()`` column to True/False in Python."""
|
134
|
+
|
135
|
+
impl = types.Enum
|
136
|
+
cache_ok: bool = True
|
137
|
+
|
138
|
+
def __init__(self) -> None:
|
139
|
+
super().__init__("True", "False")
|
140
|
+
|
141
|
+
def process_bind_param(self, value, dialect) -> str:
|
142
|
+
if value is True:
|
143
|
+
return "True"
|
144
|
+
elif value is False:
|
145
|
+
return "False"
|
146
|
+
else:
|
147
|
+
raise NotImplementedError(value, dialect)
|
148
|
+
|
149
|
+
def process_result_value(self, value, dialect) -> bool:
|
150
|
+
if value == "True":
|
151
|
+
return True
|
152
|
+
elif value == "False":
|
153
|
+
return False
|
154
|
+
else:
|
155
|
+
raise NotImplementedError(f"Unknown {value=}")
|
156
|
+
|
157
|
+
|
131
158
|
class SQLDBError(Exception):
|
132
159
|
pass
|
133
160
|
|
@@ -20,6 +20,9 @@ src/diracx/db/sql/job/schema.py
|
|
20
20
|
src/diracx/db/sql/job_logging/__init__.py
|
21
21
|
src/diracx/db/sql/job_logging/db.py
|
22
22
|
src/diracx/db/sql/job_logging/schema.py
|
23
|
+
src/diracx/db/sql/pilot_agents/__init__.py
|
24
|
+
src/diracx/db/sql/pilot_agents/db.py
|
25
|
+
src/diracx/db/sql/pilot_agents/schema.py
|
23
26
|
src/diracx/db/sql/sandbox_metadata/__init__.py
|
24
27
|
src/diracx/db/sql/sandbox_metadata/db.py
|
25
28
|
src/diracx/db/sql/sandbox_metadata/schema.py
|
@@ -43,4 +46,6 @@ tests/jobs/test_jobLoggingDB.py
|
|
43
46
|
tests/jobs/test_sandbox_metadata.py
|
44
47
|
tests/opensearch/test_connection.py
|
45
48
|
tests/opensearch/test_index_template.py
|
46
|
-
tests/opensearch/test_search.py
|
49
|
+
tests/opensearch/test_search.py
|
50
|
+
tests/pilot_agents/__init__.py
|
51
|
+
tests/pilot_agents/test_pilotAgentsDB.py
|
@@ -5,5 +5,6 @@ JobParametersDB = diracx.db.os:JobParametersDB
|
|
5
5
|
AuthDB = diracx.db.sql:AuthDB
|
6
6
|
JobDB = diracx.db.sql:JobDB
|
7
7
|
JobLoggingDB = diracx.db.sql:JobLoggingDB
|
8
|
+
PilotAgentsDB = diracx.db.sql:PilotAgentsDB
|
8
9
|
SandboxMetadataDB = diracx.db.sql:SandboxMetadataDB
|
9
10
|
TaskQueueDB = diracx.db.sql:TaskQueueDB
|
File without changes
|
@@ -0,0 +1,31 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import pytest
|
4
|
+
|
5
|
+
from diracx.db.sql.pilot_agents.db import PilotAgentsDB
|
6
|
+
|
7
|
+
|
8
|
+
@pytest.fixture
|
9
|
+
async def pilot_agents_db(tmp_path) -> PilotAgentsDB:
|
10
|
+
agents_db = PilotAgentsDB("sqlite+aiosqlite:///:memory:")
|
11
|
+
async with agents_db.engine_context():
|
12
|
+
async with agents_db.engine.begin() as conn:
|
13
|
+
await conn.run_sync(agents_db.metadata.create_all)
|
14
|
+
yield agents_db
|
15
|
+
|
16
|
+
|
17
|
+
async def test_insert_and_select(pilot_agents_db: PilotAgentsDB):
|
18
|
+
|
19
|
+
async with pilot_agents_db as pilot_agents_db:
|
20
|
+
# Add a pilot reference
|
21
|
+
refs = [f"ref_{i}" for i in range(10)]
|
22
|
+
stamps = [f"stamp_{i}" for i in range(10)]
|
23
|
+
stamp_dict = dict(zip(refs, stamps))
|
24
|
+
|
25
|
+
await pilot_agents_db.add_pilot_references(
|
26
|
+
refs, "test_vo", grid_type="DIRAC", pilot_stamps=stamp_dict
|
27
|
+
)
|
28
|
+
|
29
|
+
await pilot_agents_db.add_pilot_references(
|
30
|
+
refs, "test_vo", grid_type="DIRAC", pilot_stamps=None
|
31
|
+
)
|
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
|
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
|
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
|
File without changes
|
File without changes
|
File without changes
|