digitalhub 0.9.0b0__py3-none-any.whl → 0.9.0b2__py3-none-any.whl

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.
@@ -12,7 +12,7 @@ from requests.exceptions import HTTPError, JSONDecodeError, RequestException
12
12
 
13
13
  from digitalhub.client._base.client import Client
14
14
  from digitalhub.client.dhcore.api_builder import ClientDHCoreApiBuilder
15
- from digitalhub.client.dhcore.enums import AuthType, EnvVar
15
+ from digitalhub.client.dhcore.enums import AuthType, DhcoreEnvVar
16
16
  from digitalhub.client.dhcore.env import ENV_FILE, FALLBACK_USER, LIB_VERSION, MAX_API_LEVEL, MIN_API_LEVEL
17
17
  from digitalhub.client.dhcore.models import BasicAuth, OAuth2TokenAuth
18
18
  from digitalhub.utils.exceptions import (
@@ -520,7 +520,6 @@ class ClientDHCore(Client):
520
520
  -------
521
521
  None
522
522
  """
523
-
524
523
  self._get_endpoints_from_env()
525
524
 
526
525
  if config is not None:
@@ -558,12 +557,12 @@ class ClientDHCore(Client):
558
557
  Exception
559
558
  If the endpoint of DHCore is not set in the env variables.
560
559
  """
561
- core_endpt = os.getenv(EnvVar.ENDPOINT.value)
560
+ core_endpt = os.getenv(DhcoreEnvVar.ENDPOINT.value)
562
561
  if core_endpt is None:
563
562
  raise BackendError("Endpoint not set as environment variables.")
564
563
  self._endpoint_core = self._sanitize_endpoint(core_endpt)
565
564
 
566
- issr_endpt = os.getenv(EnvVar.ISSUER.value)
565
+ issr_endpt = os.getenv(DhcoreEnvVar.ISSUER.value)
567
566
  if issr_endpt is not None:
568
567
  self._endpoint_issuer = self._sanitize_endpoint(issr_endpt)
569
568
 
@@ -589,17 +588,17 @@ class ClientDHCore(Client):
589
588
  -------
590
589
  None
591
590
  """
592
- self._user = os.getenv(EnvVar.USER.value, FALLBACK_USER)
593
- self._refresh_token = os.getenv(EnvVar.REFRESH_TOKEN.value)
594
- self._client_id = os.getenv(EnvVar.CLIENT_ID.value)
591
+ self._user = os.getenv(DhcoreEnvVar.USER.value, FALLBACK_USER)
592
+ self._refresh_token = os.getenv(DhcoreEnvVar.REFRESH_TOKEN.value)
593
+ self._client_id = os.getenv(DhcoreEnvVar.CLIENT_ID.value)
595
594
 
596
- token = os.getenv(EnvVar.ACCESS_TOKEN.value)
595
+ token = os.getenv(DhcoreEnvVar.ACCESS_TOKEN.value)
597
596
  if token is not None and token != "":
598
597
  self._auth_type = AuthType.OAUTH2.value
599
598
  self._access_token = token
600
599
  return
601
600
 
602
- password = os.getenv(EnvVar.PASSWORD.value)
601
+ password = os.getenv(DhcoreEnvVar.PASSWORD.value)
603
602
  if self._user is not None and password is not None:
604
603
  self._auth_type = AuthType.BASIC.value
605
604
  self._password = password
@@ -619,12 +618,12 @@ class ClientDHCore(Client):
619
618
 
620
619
  # Call refresh token endpoint
621
620
  # Try token from env
622
- refresh_token = os.getenv(EnvVar.REFRESH_TOKEN.value)
621
+ refresh_token = os.getenv(DhcoreEnvVar.REFRESH_TOKEN.value)
623
622
  response = self._call_refresh_token_endpoint(url, refresh_token)
624
623
 
625
624
  # Otherwise try token from file
626
625
  if response.status_code in (400, 401, 403):
627
- refresh_token = get_key(ENV_FILE, EnvVar.REFRESH_TOKEN.value)
626
+ refresh_token = get_key(ENV_FILE, DhcoreEnvVar.REFRESH_TOKEN.value)
628
627
  response = self._call_refresh_token_endpoint(url, refresh_token)
629
628
 
630
629
  response.raise_for_status()
@@ -694,9 +693,9 @@ class ClientDHCore(Client):
694
693
  """
695
694
  keys = {}
696
695
  if self._access_token is not None:
697
- keys[EnvVar.ACCESS_TOKEN.value] = self._access_token
696
+ keys[DhcoreEnvVar.ACCESS_TOKEN.value] = self._access_token
698
697
  if self._refresh_token is not None:
699
- keys[EnvVar.REFRESH_TOKEN.value] = self._refresh_token
698
+ keys[DhcoreEnvVar.REFRESH_TOKEN.value] = self._refresh_token
700
699
 
701
700
  for k, v in keys.items():
702
701
  set_key(dotenv_path=ENV_FILE, key_to_set=k, value_to_set=v)
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  from enum import Enum
4
4
 
5
5
 
6
- class EnvVar(Enum):
6
+ class DhcoreEnvVar(Enum):
7
7
  """
8
8
  Environment variables.
9
9
  """
@@ -15,6 +15,7 @@ class EnvVar(Enum):
15
15
  CLIENT_ID = "DHCORE_CLIENT_ID"
16
16
  ACCESS_TOKEN = "DHCORE_ACCESS_TOKEN"
17
17
  REFRESH_TOKEN = "DHCORE_REFRESH_TOKEN"
18
+ WORKFLOW_IMAGE = "DHCORE_WORKFLOW_IMAGE"
18
19
 
19
20
 
20
21
  class AuthType(Enum):
@@ -4,7 +4,7 @@ import os
4
4
  import typing
5
5
 
6
6
  from digitalhub.client.api import get_client
7
- from digitalhub.client.dhcore.enums import AuthType, EnvVar
7
+ from digitalhub.client.dhcore.enums import AuthType, DhcoreEnvVar
8
8
 
9
9
  if typing.TYPE_CHECKING:
10
10
  from digitalhub.client.dhcore.client import ClientDHCore
@@ -44,17 +44,17 @@ def set_dhcore_env(
44
44
  None
45
45
  """
46
46
  if endpoint is not None:
47
- os.environ[EnvVar.ENDPOINT.value] = endpoint
47
+ os.environ[DhcoreEnvVar.ENDPOINT.value] = endpoint
48
48
  if user is not None:
49
- os.environ[EnvVar.USER.value] = user
49
+ os.environ[DhcoreEnvVar.USER.value] = user
50
50
  if password is not None:
51
- os.environ[EnvVar.PASSWORD.value] = password
51
+ os.environ[DhcoreEnvVar.PASSWORD.value] = password
52
52
  if access_token is not None:
53
- os.environ[EnvVar.ACCESS_TOKEN.value] = access_token
53
+ os.environ[DhcoreEnvVar.ACCESS_TOKEN.value] = access_token
54
54
  if refresh_token is not None:
55
- os.environ[EnvVar.REFRESH_TOKEN.value] = refresh_token
55
+ os.environ[DhcoreEnvVar.REFRESH_TOKEN.value] = refresh_token
56
56
  if client_id is not None:
57
- os.environ[EnvVar.CLIENT_ID.value] = client_id
57
+ os.environ[DhcoreEnvVar.CLIENT_ID.value] = client_id
58
58
 
59
59
  update_client_from_env()
60
60
 
@@ -70,16 +70,16 @@ def update_client_from_env() -> None:
70
70
  client: ClientDHCore = get_client(local=False)
71
71
 
72
72
  # Update endpoint
73
- endpoint = os.getenv(EnvVar.ENDPOINT.value)
73
+ endpoint = os.getenv(DhcoreEnvVar.ENDPOINT.value)
74
74
  if endpoint is not None:
75
75
  client._endpoint_core = endpoint
76
76
 
77
77
  # Update auth
78
78
 
79
79
  # If token is set, it will override the other auth options
80
- access_token = os.getenv(EnvVar.ACCESS_TOKEN.value)
81
- refresh_token = os.getenv(EnvVar.REFRESH_TOKEN.value)
82
- client_id = os.getenv(EnvVar.CLIENT_ID.value)
80
+ access_token = os.getenv(DhcoreEnvVar.ACCESS_TOKEN.value)
81
+ refresh_token = os.getenv(DhcoreEnvVar.REFRESH_TOKEN.value)
82
+ client_id = os.getenv(DhcoreEnvVar.CLIENT_ID.value)
83
83
 
84
84
  if access_token is not None:
85
85
  if refresh_token is not None:
@@ -91,8 +91,8 @@ def update_client_from_env() -> None:
91
91
  return
92
92
 
93
93
  # Otherwise, if user and password are set, basic auth will be used
94
- username = os.getenv(EnvVar.USER.value)
95
- password = os.getenv(EnvVar.PASSWORD.value)
94
+ username = os.getenv(DhcoreEnvVar.USER.value)
95
+ password = os.getenv(DhcoreEnvVar.PASSWORD.value)
96
96
  if username is not None and password is not None:
97
97
  client._user = username
98
98
  client._password = password
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from pydantic import BaseModel, Field, ConfigDict
3
+ from pydantic import BaseModel, ConfigDict, Field
4
4
 
5
5
  from digitalhub.entities._base._base.entity import Base
6
6
  from digitalhub.entities._commons.enums import Relationship
@@ -538,7 +538,10 @@ class OperationsProcessor:
538
538
  new_obj = self._create_context_entity(context, obj.ENTITY_TYPE, obj.to_dict())
539
539
  return build_entity_from_dict(new_obj)
540
540
 
541
- def log_material_entity(self, **kwargs,) -> MaterialEntity:
541
+ def log_material_entity(
542
+ self,
543
+ **kwargs,
544
+ ) -> MaterialEntity:
542
545
  """
543
546
  Create object in backend and upload file.
544
547
 
@@ -79,11 +79,11 @@ class Function(ExecutableEntity):
79
79
  task = self._get_or_create_task(task_kind)
80
80
 
81
81
  # Run function from task
82
- run = task.run(run_kind, local_execution, **kwargs)
82
+ run = task.run(run_kind, save=False, local_execution=local_execution, **kwargs)
83
83
 
84
84
  # Set as run's parent
85
85
  run.add_relationship(Relationship.RUN_OF.value, run.key + ":" + run.id, self.key)
86
- run.save(update=True)
86
+ run.save()
87
87
 
88
88
  # If execution is done by DHCore backend, return the object
89
89
  if not local_execution:
@@ -21,6 +21,8 @@ class RunSpec(Spec):
21
21
  envs: list[dict] | None = None,
22
22
  secrets: list[str] | None = None,
23
23
  profile: str | None = None,
24
+ runtime_class: str | None = None,
25
+ priority_class: str | None = None,
24
26
  **kwargs,
25
27
  ) -> None:
26
28
  self.task = task
@@ -35,6 +37,8 @@ class RunSpec(Spec):
35
37
  self.envs = envs
36
38
  self.secrets = secrets
37
39
  self.profile = profile
40
+ self.runtime_class = runtime_class
41
+ self.priority_class = priority_class
38
42
 
39
43
 
40
44
  class RunValidator(SpecValidator, K8s):
@@ -4,8 +4,8 @@ import typing
4
4
 
5
5
  from digitalhub.entities._base.unversioned.entity import UnversionedEntity
6
6
  from digitalhub.entities._commons.enums import EntityTypes
7
- from digitalhub.entities.run.crud import delete_run, get_run, new_run
8
- from digitalhub.factory.api import get_entity_type_from_kind, get_executable_kind
7
+ from digitalhub.entities._operations.processor import processor
8
+ from digitalhub.factory.api import build_entity_from_params, get_entity_type_from_kind, get_executable_kind
9
9
 
10
10
  if typing.TYPE_CHECKING:
11
11
  from digitalhub.entities._base.entity.metadata import Metadata
@@ -42,6 +42,7 @@ class Task(UnversionedEntity):
42
42
  def run(
43
43
  self,
44
44
  run_kind: str,
45
+ save: bool = True,
45
46
  local_execution: bool = False,
46
47
  **kwargs,
47
48
  ) -> Run:
@@ -66,6 +67,7 @@ class Task(UnversionedEntity):
66
67
  exec_type = get_entity_type_from_kind(exec_kind)
67
68
  kwargs[exec_type] = getattr(self.spec, exec_type)
68
69
  return self.new_run(
70
+ save=save,
69
71
  project=self.project,
70
72
  task=self._get_task_string(),
71
73
  kind=run_kind,
@@ -88,21 +90,25 @@ class Task(UnversionedEntity):
88
90
  # CRUD Methods for Run
89
91
  ##############################
90
92
 
91
- def new_run(self, **kwargs) -> Run:
93
+ def new_run(self, save: bool = True, **kwargs) -> Run:
92
94
  """
93
95
  Create a new run.
94
96
 
95
97
  Parameters
96
98
  ----------
99
+ save : bool
100
+ Flag to indicate save.
97
101
  **kwargs : dict
98
- Keyword arguments.
102
+ Keyword arguments to build run. See new_run().
99
103
 
100
104
  Returns
101
105
  -------
102
106
  Run
103
107
  Run object.
104
108
  """
105
- return new_run(**kwargs)
109
+ if save:
110
+ return processor.create_context_entity(**kwargs)
111
+ return build_entity_from_params(**kwargs)
106
112
 
107
113
  def get_run(self, entity_key: str) -> Run:
108
114
  """
@@ -118,9 +124,9 @@ class Task(UnversionedEntity):
118
124
  Run
119
125
  Run object.
120
126
  """
121
- return get_run(entity_key)
127
+ return processor.read_context_entity(entity_key)
122
128
 
123
- def delete_run(self, entity_key: str) -> None:
129
+ def delete_run(self, entity_key: str) -> dict:
124
130
  """
125
131
  Delete run.
126
132
 
@@ -131,6 +137,7 @@ class Task(UnversionedEntity):
131
137
 
132
138
  Returns
133
139
  -------
134
- None
140
+ dict
141
+ Response from backend.
135
142
  """
136
- delete_run(entity_key)
143
+ return processor.delete_context_entity(entity_key)
@@ -210,6 +210,12 @@ class K8s(BaseModel):
210
210
  profile: str = None
211
211
  """Profile template."""
212
212
 
213
+ runtime_class: str = None
214
+ """Runtime class name."""
215
+
216
+ priority_class: str = None
217
+ """Priority class."""
218
+
213
219
 
214
220
  class CorePort(BaseModel):
215
221
  """
@@ -22,6 +22,8 @@ class TaskSpecFunction(TaskSpec):
22
22
  envs: list[dict] | None = None,
23
23
  secrets: list[str] | None = None,
24
24
  profile: str | None = None,
25
+ runtime_class: str | None = None,
26
+ priority_class: str | None = None,
25
27
  **kwargs,
26
28
  ) -> None:
27
29
  self.function = function
@@ -33,6 +35,8 @@ class TaskSpecFunction(TaskSpec):
33
35
  self.envs = envs
34
36
  self.secrets = secrets
35
37
  self.profile = profile
38
+ self.runtime_class = runtime_class
39
+ self.priority_class = priority_class
36
40
 
37
41
 
38
42
  class TaskSpecWorkflow(TaskSpec):
@@ -49,6 +53,8 @@ class TaskSpecWorkflow(TaskSpec):
49
53
  envs: list[dict] | None = None,
50
54
  secrets: list[str] | None = None,
51
55
  profile: str | None = None,
56
+ runtime_class: str | None = None,
57
+ priority_class: str | None = None,
52
58
  **kwargs,
53
59
  ) -> None:
54
60
  self.workflow = workflow
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import typing
4
4
 
5
5
  from digitalhub.entities._base.executable.entity import ExecutableEntity
6
- from digitalhub.entities._commons.enums import EntityTypes
6
+ from digitalhub.entities._commons.enums import EntityTypes, Relationship
7
7
  from digitalhub.factory.api import get_run_kind, get_task_kind_from_action
8
8
  from digitalhub.utils.exceptions import BackendError
9
9
 
@@ -76,7 +76,12 @@ class Workflow(ExecutableEntity):
76
76
  raise BackendError("Cannot run workflow with local backend.")
77
77
 
78
78
  # Run task
79
- run = task.run(run_kind, local_execution=False, **kwargs)
79
+ run = task.run(run_kind, save=False, local_execution=False, **kwargs)
80
+
81
+ # Set as run's parent
82
+ run.add_relationship(Relationship.RUN_OF.value, run.key + ":" + run.id, self.key)
83
+ run.save()
84
+
80
85
  if wait:
81
86
  return run.wait(log_info=log_info)
82
87
  return run
@@ -0,0 +1,12 @@
1
+ from __future__ import annotations
2
+
3
+ from enum import Enum
4
+
5
+
6
+ class RuntimeEnvVar(Enum):
7
+ """
8
+ Environment variables.
9
+ """
10
+
11
+ PROJECT = "PROJECT_NAME"
12
+ RUN_ID = "RUN_ID"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: digitalhub
3
- Version: 0.9.0b0
3
+ Version: 0.9.0b2
4
4
  Summary: Python SDK for Digitalhub
5
5
  Author-email: Fondazione Bruno Kessler <dslab@fbk.eu>, Matteo Martini <mmartini@fbk.eu>
6
6
  License: Apache License
@@ -7,11 +7,11 @@ digitalhub/client/_base/api_builder.py,sha256=kB0phBqaPTLayyXyA1GbHgnbo4bBkadBti
7
7
  digitalhub/client/_base/client.py,sha256=wXHfHQANnv_2AlW6yh7dnxI3i0bBASsP_gYSbc-YQHk,2063
8
8
  digitalhub/client/dhcore/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  digitalhub/client/dhcore/api_builder.py,sha256=IkRnANGG3dQmu4t1KmSnpDxGqkZDnJpBP9CcUhWZliQ,3652
10
- digitalhub/client/dhcore/client.py,sha256=GXAL1UQGO5wU_36KnlOTyjLIsYt9YdmeCJo3hw_jOUU,21078
11
- digitalhub/client/dhcore/enums.py,sha256=CSmLJxMNCLj7pjrG_On_cJ1f_g_yjCULpHhtJdCNI6c,472
10
+ digitalhub/client/dhcore/client.py,sha256=Vl0ZRX1CHxOg9awR-liFagTMkbNLcW2B4jGfxJt0udk,21149
11
+ digitalhub/client/dhcore/enums.py,sha256=kaVXZTTa2WmsFbcc1CKWNLOM0JtUtcjL-KpspnTOhEE,523
12
12
  digitalhub/client/dhcore/env.py,sha256=zBUNbK8G8PyMGAw_65BnX2Z_WUkrmTyQmYhLE6Jqgvk,618
13
13
  digitalhub/client/dhcore/models.py,sha256=KiTg5xR8EzI7Xa1pmYmzixabLdnqlnn5kn-IILZDGIw,900
14
- digitalhub/client/dhcore/utils.py,sha256=7nHGkDnSy4N-y3SX4UJ3KtAbOGPoDvhNql8p-u5y-Sw,3058
14
+ digitalhub/client/dhcore/utils.py,sha256=I6m26WiGMCEyPa6Yv5hk3nmqWV4jDFjYyI590f86Ebs,3136
15
15
  digitalhub/client/local/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  digitalhub/client/local/api_builder.py,sha256=WR24zuWguJqzUkD7xReO12LtvSkn020UG6LKFcKq77g,3592
17
17
  digitalhub/client/local/client.py,sha256=WLpEymgxysRLDdMGm9ds4kKOqHqEXk8MmrU01NR938o,17338
@@ -28,7 +28,7 @@ digitalhub/entities/_base/context/entity.py,sha256=4IWC6f0YKpEBPCXrKlkkvnOqT1urQ
28
28
  digitalhub/entities/_base/entity/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
29
  digitalhub/entities/_base/entity/builder.py,sha256=vegnR3aBLhuA371vFVQvMXX4KfpVFl-Z7h1ydt6r6Hg,4518
30
30
  digitalhub/entities/_base/entity/entity.py,sha256=5QP7ZFZ3fjdC6dL26J4TAc_gAsz4esTYR97PIRiwk04,3162
31
- digitalhub/entities/_base/entity/metadata.py,sha256=rQaDCJE5GfSSIJT5UgXcbUQth5b8BTbv8N_RLaEzLjI,2261
31
+ digitalhub/entities/_base/entity/metadata.py,sha256=_ogwoo7NOExxVPml9h1vbbAryFiAVpuEuSBQsd_VRjU,2261
32
32
  digitalhub/entities/_base/entity/spec.py,sha256=t0sPXHCb8zyWyMW_UvTfGyUkG_CUEGz427kvGhsQ8s0,1500
33
33
  digitalhub/entities/_base/entity/status.py,sha256=NHB1kLHefoMhhkt_2BFPNojbWMW_Nc8TTGFQNOiyOt0,1044
34
34
  digitalhub/entities/_base/entity/_constructors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -58,7 +58,7 @@ digitalhub/entities/_commons/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
58
58
  digitalhub/entities/_commons/enums.py,sha256=pjhbOMzAABRPbV6XNt-2Lyn2kLWIFBAwpeboCtvnz1w,1861
59
59
  digitalhub/entities/_commons/utils.py,sha256=_HL6zFSCL_2ug4LpXcxK1MJQQhWL34wj1B2q0Ie0TKU,1792
60
60
  digitalhub/entities/_operations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
61
- digitalhub/entities/_operations/processor.py,sha256=5RjHDkoI-IjdEL0HF9QOn_XH5mcmrWsA9OO0r5NejdE,46641
61
+ digitalhub/entities/_operations/processor.py,sha256=yi-L_mltue3WN8xM5Y-zpwUCb4x4psW5uwd1Lx7Rxo4,46663
62
62
  digitalhub/entities/artifact/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
63
63
  digitalhub/entities/artifact/crud.py,sha256=y69PyoWAYOx-Pl_wnds3M0xSLNbADpdV_xG4zElJ0aI,7824
64
64
  digitalhub/entities/artifact/utils.py,sha256=NNzD2AcIJzmV_Jo_8k5ZcSp2arKcZ07CCIYKn2lvoKM,1320
@@ -100,7 +100,7 @@ digitalhub/entities/function/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
100
100
  digitalhub/entities/function/crud.py,sha256=1-fRWVmOXVV305p0GW0n02FEcengw7QxLxxgxsCC7eM,6592
101
101
  digitalhub/entities/function/_base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
102
102
  digitalhub/entities/function/_base/builder.py,sha256=xTVOpH3GYU-BqtzMEuI3uMtLLvF9IYfrVYMVPkkJc2g,2035
103
- digitalhub/entities/function/_base/entity.py,sha256=VhUQsC5EyJQpCU6FMDRqLIrlJt18g8I6AKd1ZO7320U,3100
103
+ digitalhub/entities/function/_base/entity.py,sha256=ZQRbnHbD-pdESiTLCg5LHqF7vUHh800n2FFP3A_ZWcE,3117
104
104
  digitalhub/entities/function/_base/spec.py,sha256=SjCtp3JBUTPTLMY_TE8wM1HPKVl7jH_wFEqQXBj1rfo,274
105
105
  digitalhub/entities/function/_base/status.py,sha256=N-Z1hw13qV7kWFJLQPaH3rRZ2z7AvZeuWYER95lG344,170
106
106
  digitalhub/entities/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -146,7 +146,7 @@ digitalhub/entities/run/crud.py,sha256=0_9zlW4aId4x1rGlvjOdAHkNaJwpR5vgLCuMt7rE-
146
146
  digitalhub/entities/run/_base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
147
147
  digitalhub/entities/run/_base/builder.py,sha256=e4P4gegD1DjHv_-Rhe3bIkGfRwgRbC8J6hdSSw2M8b4,2454
148
148
  digitalhub/entities/run/_base/entity.py,sha256=-bQqY1vhEsAaBYwXIzQwiFKmwA9FPH3wJ9XtennWvKo,7549
149
- digitalhub/entities/run/_base/spec.py,sha256=EDF9oVjR7pkIc2Tp-K56pge5tLYNjiXVPrpmUSgRnNA,1500
149
+ digitalhub/entities/run/_base/spec.py,sha256=nAyIAcnIXgGEhyI1TvOhZfKxB2ZC25VuFhAECgG--KU,1673
150
150
  digitalhub/entities/run/_base/status.py,sha256=_oqF8AM-N6XGi-xc-xgthdmCpsuI_rGgVaNKgQ4UDJQ,160
151
151
  digitalhub/entities/secret/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
152
152
  digitalhub/entities/secret/crud.py,sha256=tKXNHqpxCsBMOYtHadQz70-mcExskdQ8Lt9lezmiZzU,6816
@@ -159,16 +159,16 @@ digitalhub/entities/task/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
159
159
  digitalhub/entities/task/crud.py,sha256=_TOgqPvD4bOcfxMPJLCzPe4fz_87AP27RG5cC2941oY,5199
160
160
  digitalhub/entities/task/_base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
161
161
  digitalhub/entities/task/_base/builder.py,sha256=21WEbycCR8yaOPcLLcAITaoQ4ZmBNXJXB-Oy0VfSPrg,2358
162
- digitalhub/entities/task/_base/entity.py,sha256=KGueJ64puhS7DAzG0_-XZSlUmVIOPOFJbtj1S8iWrpg,3179
163
- digitalhub/entities/task/_base/models.py,sha256=kfOclRdqrE_FJuYpp9VRcFXZIFOOhFoTHGX9fF8jewQ,4622
164
- digitalhub/entities/task/_base/spec.py,sha256=kocTiJHyl2z4te9t8ZDSU7bhQOjUXgvAnytMV8ZNZUA,2154
162
+ digitalhub/entities/task/_base/entity.py,sha256=hOTFxWgSrEs2UPrd9pDZAbdWnL_OrkHr6PwxnAkYG2A,3531
163
+ digitalhub/entities/task/_base/models.py,sha256=lrkQfKEqqMboiDgtqVdTdlFx4FCH_ksJ2Jku1nK6ARw,4741
164
+ digitalhub/entities/task/_base/spec.py,sha256=2p_QmhXdTXFrkwNyXtEgzUmc4YyedjS-zsnWsvxJDjw,2412
165
165
  digitalhub/entities/task/_base/status.py,sha256=FCSSQscQ0dHEpXdc5vSrIkTXon9FNNOr0M1KVh2ZVAA,162
166
166
  digitalhub/entities/task/_base/utils.py,sha256=P0ajA8SQcDaEC9BBIIc_M8UL1_qBcZE8loUTkP7xVYY,436
167
167
  digitalhub/entities/workflow/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
168
168
  digitalhub/entities/workflow/crud.py,sha256=O_Zq30NG-cy7RU1GG88XNi8ids7vrRJAR95PTMYncGM,6517
169
169
  digitalhub/entities/workflow/_base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
170
170
  digitalhub/entities/workflow/_base/builder.py,sha256=wRgot2pbXjc-Cw549uDo1zFOGKdE7wVqxCboeNoXe-Q,2035
171
- digitalhub/entities/workflow/_base/entity.py,sha256=TFteC2Bpg71qrQ0ni9qnowZUYT3WQ_toEmt2BJIdUeM,2228
171
+ digitalhub/entities/workflow/_base/entity.py,sha256=DsbyimpJj5Hqn0afLB_NgP2wmY4p55OAsUs4h4LQlZU,2395
172
172
  digitalhub/entities/workflow/_base/spec.py,sha256=UoKOUEqKDFACQwctDWfwhro77m3kvjhLDGOhhfRvEzQ,274
173
173
  digitalhub/entities/workflow/_base/status.py,sha256=W0j0CNdu9o2vbk0awpnDrpgwf_fZpgdtct4s0BxRdyk,170
174
174
  digitalhub/factory/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -189,6 +189,7 @@ digitalhub/readers/pandas/reader.py,sha256=pdBKUWiKettQmh6N48LYOfnwqrOWoo-GpHdSB
189
189
  digitalhub/runtimes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
190
190
  digitalhub/runtimes/_base.py,sha256=uDvSXAEytZr-BFpj1BA59vdERBk79j5pTDiG0__tazA,2510
191
191
  digitalhub/runtimes/builder.py,sha256=CtwutbxRdLo6Qj5PfvmYnCusRG89yS1jI4Qu-Ha3XGY,705
192
+ digitalhub/runtimes/enums.py,sha256=hhGNyuBcchqCcDKdR_foOyeNJn41nHCNEyRmoxE5dNA,182
192
193
  digitalhub/stores/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
193
194
  digitalhub/stores/api.py,sha256=TwD8WXVuEPwtrmcyhP9SC0i7xkVHov5fpu94nHhZRHg,994
194
195
  digitalhub/stores/builder.py,sha256=kraGDfgV5cZ2QivXTWwbyz1FgAehgjlL9dmI6dxEc0U,5927
@@ -221,8 +222,9 @@ test/local/CRUD/test_artifacts.py,sha256=Y3J_C7SDRSsQd2SGIZjPIOvyTL92B1sTFrUONG3
221
222
  test/local/CRUD/test_dataitems.py,sha256=LQqTzI59uwTGy4zoq8jL0yWVe2W9vXlatkgDU9aB6xg,2968
222
223
  test/local/CRUD/test_models.py,sha256=msosbZuRwIMbZtmi3ZaOva4TjQ4lrzkNu9AguIFhrSo,2929
223
224
  test/local/imports/test_imports.py,sha256=W-YugO0rpJwvtWp57MXaXfEmE-f5iWuCiLY-n0ZU4z8,1271
224
- digitalhub-0.9.0b0.dist-info/LICENSE.txt,sha256=_yVOtnbW7Ss28mp058UEEc1X4Rgj8-kQBP_kj8_Sc88,11585
225
- digitalhub-0.9.0b0.dist-info/METADATA,sha256=moaWh_7G0-OFP0ZOg2bjOlIUM_8XsasvBKFNxti4stw,15316
226
- digitalhub-0.9.0b0.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
227
- digitalhub-0.9.0b0.dist-info/top_level.txt,sha256=ae9pDfCF27ZoaVAxuBKONMP0lm5P-N_I-e-no1WlvD8,16
228
- digitalhub-0.9.0b0.dist-info/RECORD,,
225
+ test/local/instances/test_validate.py,sha256=bGPKRFR_Tb5nlzzmI_ty_6UVUvYGseE2-pkNVoGWeO0,1842
226
+ digitalhub-0.9.0b2.dist-info/LICENSE.txt,sha256=_yVOtnbW7Ss28mp058UEEc1X4Rgj8-kQBP_kj8_Sc88,11585
227
+ digitalhub-0.9.0b2.dist-info/METADATA,sha256=jmoukYGBnexueJ7RF8k-YxeZQ8SuzCjMdwxh8nyOPI0,15316
228
+ digitalhub-0.9.0b2.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
229
+ digitalhub-0.9.0b2.dist-info/top_level.txt,sha256=ae9pDfCF27ZoaVAxuBKONMP0lm5P-N_I-e-no1WlvD8,16
230
+ digitalhub-0.9.0b2.dist-info/RECORD,,
@@ -0,0 +1,55 @@
1
+ import os
2
+ import pytest
3
+ from glob import glob
4
+ from pathlib import Path
5
+ import json
6
+ from jsonschema import validate
7
+ from digitalhub.factory.factory import factory
8
+
9
+ entities_path = "test/local/instances/entities"
10
+ schemas_path = "test/local/instances/schemas"
11
+
12
+ # Build dict: kind -> path to schema file
13
+ schemas = {}
14
+ for path_to_schema in glob(f"{schemas_path}/**/*.json", recursive=True):
15
+ kind = Path(path_to_schema).stem
16
+ schemas[kind] = path_to_schema
17
+
18
+ # Build dict: name of file to validate -> full path to file
19
+ entity_paths = {}
20
+ for path_to_file in glob(f"{entities_path}/**/*.json", recursive=True):
21
+ file_name = os.path.basename(path_to_file)
22
+
23
+ # If a file in a nested directory causes a name collision, use its full path as name
24
+ if file_name in entity_paths:
25
+ file_name = path_to_file
26
+
27
+ entity_paths[file_name] = path_to_file
28
+
29
+ # Build object from JSON file using factory
30
+ def build_obj(entity_file_path):
31
+ with open(entity_file_path) as f:
32
+ entity = json.load(f)
33
+
34
+ kind = entity["kind"]
35
+ spec = entity["spec"]
36
+
37
+ built = factory.build_spec(kind, **spec)
38
+ return built.to_dict(), kind
39
+
40
+ # Validate built object against its kind's schema
41
+ def is_valid(built, kind):
42
+ with open(schemas[kind]) as schema_file:
43
+ schema = json.load(schema_file)
44
+
45
+ validate(instance=built, schema=schema)
46
+ return True
47
+
48
+ # Tests that each JSON file contained in the specified path can successfully be
49
+ # used to generate an object through the factory, and that each generated object,
50
+ # when exported to dict, validates (through jsonschema) against its kind's schema.
51
+ class TestValidate:
52
+ @pytest.mark.parametrize('file_name', list(entity_paths.keys()))
53
+ def test_validate(self, file_name):
54
+ built, kind = build_obj(f"{entity_paths[file_name]}")
55
+ assert is_valid(built, kind)