diracx-db 0.0.1a18__tar.gz → 0.0.1a19__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/PKG-INFO +1 -1
  2. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/pyproject.toml +2 -0
  3. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx/db/__main__.py +1 -0
  4. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx/db/sql/__init__.py +9 -1
  5. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx/db/sql/job/schema.py +1 -46
  6. diracx_db-0.0.1a19/src/diracx/db/sql/pilot_agents/db.py +46 -0
  7. diracx_db-0.0.1a19/src/diracx/db/sql/pilot_agents/schema.py +58 -0
  8. diracx_db-0.0.1a19/src/diracx/db/sql/task_queue/__init__.py +0 -0
  9. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx/db/sql/utils/__init__.py +27 -0
  10. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx_db.egg-info/PKG-INFO +1 -1
  11. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx_db.egg-info/SOURCES.txt +6 -1
  12. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx_db.egg-info/entry_points.txt +1 -0
  13. diracx_db-0.0.1a19/tests/pilot_agents/__init__.py +0 -0
  14. diracx_db-0.0.1a19/tests/pilot_agents/test_pilotAgentsDB.py +31 -0
  15. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/README.md +0 -0
  16. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/setup.cfg +0 -0
  17. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx/db/__init__.py +0 -0
  18. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx/db/exceptions.py +0 -0
  19. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx/db/os/__init__.py +0 -0
  20. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx/db/os/job_parameters.py +0 -0
  21. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx/db/os/utils.py +0 -0
  22. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx/db/py.typed +0 -0
  23. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx/db/sql/auth/__init__.py +0 -0
  24. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx/db/sql/auth/db.py +0 -0
  25. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx/db/sql/auth/schema.py +0 -0
  26. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx/db/sql/dummy/__init__.py +0 -0
  27. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx/db/sql/dummy/db.py +0 -0
  28. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx/db/sql/dummy/schema.py +0 -0
  29. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx/db/sql/job/__init__.py +0 -0
  30. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx/db/sql/job/db.py +0 -0
  31. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx/db/sql/job_logging/__init__.py +0 -0
  32. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx/db/sql/job_logging/db.py +0 -0
  33. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx/db/sql/job_logging/schema.py +0 -0
  34. {diracx_db-0.0.1a18/src/diracx/db/sql/sandbox_metadata → diracx_db-0.0.1a19/src/diracx/db/sql/pilot_agents}/__init__.py +0 -0
  35. {diracx_db-0.0.1a18/src/diracx/db/sql/task_queue → diracx_db-0.0.1a19/src/diracx/db/sql/sandbox_metadata}/__init__.py +0 -0
  36. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx/db/sql/sandbox_metadata/db.py +0 -0
  37. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx/db/sql/sandbox_metadata/schema.py +0 -0
  38. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx/db/sql/task_queue/db.py +0 -0
  39. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx/db/sql/task_queue/schema.py +0 -0
  40. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx/db/sql/utils/job_status.py +0 -0
  41. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx_db.egg-info/dependency_links.txt +0 -0
  42. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx_db.egg-info/requires.txt +0 -0
  43. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/src/diracx_db.egg-info/top_level.txt +0 -0
  44. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/tests/auth/test_authorization_flow.py +0 -0
  45. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/tests/auth/test_device_flow.py +0 -0
  46. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/tests/auth/test_refresh_token.py +0 -0
  47. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/tests/jobs/test_jobDB.py +0 -0
  48. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/tests/jobs/test_jobLoggingDB.py +0 -0
  49. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/tests/jobs/test_sandbox_metadata.py +0 -0
  50. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/tests/opensearch/test_connection.py +0 -0
  51. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/tests/opensearch/test_index_template.py +0 -0
  52. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/tests/opensearch/test_search.py +0 -0
  53. {diracx_db-0.0.1a18 → diracx_db-0.0.1a19}/tests/test_dummyDB.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: diracx-db
3
- Version: 0.0.1a18
3
+ Version: 0.0.1a19
4
4
  Summary: TODO
5
5
  License: GPL-3.0-only
6
6
  Classifier: Intended Audience :: Science/Research
@@ -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__ = ("AuthDB", "JobDB", "JobLoggingDB", "SandboxMetadataDB", "TaskQueueDB")
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)
@@ -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
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: diracx-db
3
- Version: 0.0.1a18
3
+ Version: 0.0.1a19
4
4
  Summary: TODO
5
5
  License: GPL-3.0-only
6
6
  Classifier: Intended Audience :: Science/Research
@@ -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