airflow-unicore-integration 0.1.11__py3-none-any.whl → 0.1.13__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.
@@ -1,8 +1,14 @@
1
1
  from __future__ import annotations
2
2
 
3
- from airflow.hooks.base import BaseHook
3
+ import logging
4
+ from typing import Any
5
+
6
+ from airflow.providers.common.compat.sdk import BaseHook
4
7
  from pyunicore import client
5
8
  from pyunicore import credentials
9
+ from wtforms import StringField
10
+
11
+ logger = logging.getLogger(__name__)
6
12
 
7
13
 
8
14
  class UnicoreHook(BaseHook):
@@ -23,22 +29,43 @@ class UnicoreHook(BaseHook):
23
29
  super().__init__()
24
30
  self.uc_conn_id = uc_conn_id
25
31
 
32
+ @classmethod
33
+ def get_connection_form_fields(cls):
34
+ return {"auth_token": StringField("Auth Token")}
35
+
36
+ @classmethod
37
+ def get_ui_field_behaviour(cls) -> dict[str, Any]:
38
+ """Return custom UI field behaviour for UNICORE connection."""
39
+ return {
40
+ "hidden_fields": ["schema", "port", "extra"],
41
+ "relabeling": {
42
+ "login": "Username",
43
+ },
44
+ "placeholder": {"auth_token": "UNICORE auth token"},
45
+ }
46
+
26
47
  def get_conn(
27
48
  self,
28
49
  overwrite_base_url: str | None = None,
29
50
  overwrite_credential: credentials.Credential | None = None,
30
51
  ) -> client.Client:
31
52
  """Return a Unicore Client. base_url and credentials may be overwritten."""
32
- self.log.debug(
53
+ logger.debug(
33
54
  f"Gettig connection with id '{self.uc_conn_id}' from secrets backend. Will be modified with user input for UNICORE."
34
55
  )
35
56
  params = self.get_connection(self.uc_conn_id)
36
57
  base_url = params.host
37
58
  credential = credentials.UsernamePassword(params.login, params.password)
59
+ auth_token = params.extra_dejson.get("auth_token", None)
60
+ if auth_token is not None:
61
+ credential = credentials.create_credential(token=auth_token)
38
62
  if overwrite_base_url is not None:
39
63
  base_url = overwrite_base_url
40
64
  if overwrite_credential is not None:
41
65
  credential = overwrite_credential
66
+ if not base_url:
67
+ raise TypeError()
68
+ logger.info(f"Using credential {credential} for SITE {base_url}.")
42
69
  conn = client.Client(credential, base_url)
43
70
  return conn
44
71
 
@@ -0,0 +1,22 @@
1
+ from typing import Dict
2
+ from typing import List
3
+
4
+ from airflow_unicore_integration.operators.unicore_operators import (
5
+ UnicoreGenericOperator,
6
+ )
7
+
8
+
9
+ class UnicoreContainerOperator(UnicoreGenericOperator):
10
+ def __init__(
11
+ self, name: str, docker_image_url: str, command: str, options: str | None = None, **kwargs
12
+ ):
13
+ params: Dict[str, str | List[str]] = {"COMMAND": command, "IMAGE_URL": docker_image_url}
14
+ if options is not None:
15
+ params["OPTIONS"] = options
16
+ super().__init__(
17
+ name=name,
18
+ application_name="CONTAINER",
19
+ application_version="1.0",
20
+ parameters=params,
21
+ **kwargs,
22
+ )
@@ -6,7 +6,7 @@ from typing import Sequence
6
6
 
7
7
  import pyunicore.client as uc_client
8
8
  import pyunicore.credentials as uc_credentials
9
- from airflow.models.baseoperator import BaseOperator
9
+ from airflow.sdk.bases.operator import BaseOperator
10
10
  from airflow.utils.context import Context
11
11
 
12
12
  from airflow_unicore_integration.hooks import unicore_hooks
@@ -62,6 +62,7 @@ class UnicoreGenericOperator(BaseOperator):
62
62
  credential_username: str | None = None,
63
63
  credential_password: str | None = None,
64
64
  credential_token: str | None = None,
65
+ conn_id: str | None = None,
65
66
  **kwargs,
66
67
  ):
67
68
  """
@@ -114,6 +115,7 @@ class UnicoreGenericOperator(BaseOperator):
114
115
  self.credential_username = credential_username
115
116
  self.credential_password = credential_password
116
117
  self.credential_token = credential_token
118
+ self.conn_id = conn_id
117
119
 
118
120
  self.validate_job_description()
119
121
  logger.debug("created Unicore Job Task")
@@ -262,7 +264,7 @@ class UnicoreGenericOperator(BaseOperator):
262
264
 
263
265
  def execute_async(self, context: Context) -> Any:
264
266
  """Submits the job and returns the job object without waiting for it to finish."""
265
- client = self.get_uc_client()
267
+ client = self.get_uc_client(self.conn_id)
266
268
  job = client.new_job(job_description=self.get_job_description(), inputs=[])
267
269
  return job
268
270
 
@@ -25,6 +25,7 @@ class JobDescriptionGenerator:
25
25
  EXECUTOR_CONFIG_PROJECT = "Project" # gets added to the unicore job description
26
26
  EXECUTOR_CONFIG_PRE_COMMANDS = "precommands" # gets added to the unicore job description
27
27
  EXECUTOR_CONFIG_POST_COMMANDS = "postcommands" # gets added to the unicore job descirption
28
+ EXECUTOR_CONFIG_JOB_TYPE = "job_type"
28
29
  EXECUTOR_CONFIG_UNICORE_CONN_KEY = (
29
30
  "unicore_connection_id" # alternative connection id for the Unicore connection to use
30
31
  )
@@ -59,6 +60,7 @@ class NaiveJobDescriptionGenerator(JobDescriptionGenerator):
59
60
  user_added_pre_commands: list[str] = executor_config.get(JobDescriptionGenerator.EXECUTOR_CONFIG_PRE_COMMANDS, []) # type: ignore
60
61
  user_defined_python_env: str = workload.ti.executor_config.get(JobDescriptionGenerator.EXECUTOR_CONFIG_PYTHON_ENV_KEY, None) # type: ignore
61
62
  user_added_post_commands: list[str] = executor_config.get(JobDescriptionGenerator.EXECUTOR_CONFIG_POST_COMMANDS, []) # type: ignore
63
+ user_defined_job_type: str = executor_config.get(JobDescriptionGenerator.EXECUTOR_CONFIG_JOB_TYPE, None) # type: ignore
62
64
  # get local dag path from cmd and fix dag path in arguments
63
65
  dag_rel_path = str(workload.dag_rel_path)
64
66
  if dag_rel_path.startswith("DAG_FOLDER"):
@@ -71,6 +73,10 @@ class NaiveJobDescriptionGenerator(JobDescriptionGenerator):
71
73
  )
72
74
  logger.debug(f"Server is {server}")
73
75
 
76
+ # set job type
77
+ if user_defined_job_type:
78
+ job_descr_dict["Job type"] = user_defined_job_type
79
+
74
80
  # check which python virtualenv to use
75
81
  if user_defined_python_env:
76
82
  python_env = user_defined_python_env
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: airflow-unicore-integration
3
- Version: 0.1.11
3
+ Version: 0.1.13
4
4
  Summary: Running Unicore Jobs from airflow DAGs.
5
5
  Author-email: Christian Böttcher <c.boettcher@fz-juelich.de>
6
6
  License-Expression: BSD-3-Clause
@@ -3,15 +3,16 @@ airflow_unicore_integration/executors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCe
3
3
  airflow_unicore_integration/executors/run_task_via_supervisor.py,sha256=3ErgPf-Oy3B4Di5yNXhhPkaojIJykvCxMZ9MlKSYPI8,2756
4
4
  airflow_unicore_integration/executors/unicore_executor.py,sha256=E1nOskWSBmC-ReLRvA8E3bY-G0lpxP403tazlBNhgFQ,5919
5
5
  airflow_unicore_integration/hooks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- airflow_unicore_integration/hooks/unicore_hooks.py,sha256=JjcjogWtN1xveagpkraQuYOdXjkp2lSnEdQc0waqhU4,1662
6
+ airflow_unicore_integration/hooks/unicore_hooks.py,sha256=NAR5YmnPVzSsqpNVpRHt1sS3_HkEP_e8qoCv7daUZAA,2579
7
7
  airflow_unicore_integration/operators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- airflow_unicore_integration/operators/unicore_operators.py,sha256=xYX1t_QzjpqHZDoEu6jJNNXVmBEnjIlApFWvgYoYoB0,16790
8
+ airflow_unicore_integration/operators/container.py,sha256=D-2La59XZazXvBDVn-_wFIZ0IrCYeGy18miK8S5Usmc,693
9
+ airflow_unicore_integration/operators/unicore_operators.py,sha256=PrcB-riakRUt8DHR9Hkk0ccOe-xk6NjJmNAmDpNgpN4,16868
9
10
  airflow_unicore_integration/policies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- airflow_unicore_integration/util/job.py,sha256=IsVjDiq3Jj-Eky0mET3awC3yBloHR9Duvm1KFiAPKpU,10264
11
+ airflow_unicore_integration/util/job.py,sha256=vYyaNzGw2EQWQlDTGO6q4T1gZTHoB9-RIb5KYYd6pAc,10556
11
12
  airflow_unicore_integration/util/launch_script_content.py,sha256=42_aFpaCMmvFmmUxQDGcudkleX1YSK_yYWE8T41NOy0,2915
12
- airflow_unicore_integration-0.1.11.dist-info/licenses/LICENSE,sha256=hZ5ouAedeNr8ClHrQE-RLsgMsARcmv3kSZz7tE2BTJE,1526
13
- airflow_unicore_integration-0.1.11.dist-info/METADATA,sha256=a6vLdzCg5UYaxOIsKCPfxQPDZ-sBg6rwJQWCVRoupWM,11189
14
- airflow_unicore_integration-0.1.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
15
- airflow_unicore_integration-0.1.11.dist-info/entry_points.txt,sha256=PzEfCLYLSawjiYR-HNBzw8-YGfJxs1nPBULevgBQjoY,147
16
- airflow_unicore_integration-0.1.11.dist-info/top_level.txt,sha256=j45X-uIuOk3oL78iwlpHakMWtUkg__B7zUlJLwmZx6w,28
17
- airflow_unicore_integration-0.1.11.dist-info/RECORD,,
13
+ airflow_unicore_integration-0.1.13.dist-info/licenses/LICENSE,sha256=hZ5ouAedeNr8ClHrQE-RLsgMsARcmv3kSZz7tE2BTJE,1526
14
+ airflow_unicore_integration-0.1.13.dist-info/METADATA,sha256=KXZXAPP9dv8EN2UheZDJ9TeXiIb5jL-t6AggYOJFDPU,11189
15
+ airflow_unicore_integration-0.1.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
16
+ airflow_unicore_integration-0.1.13.dist-info/entry_points.txt,sha256=PzEfCLYLSawjiYR-HNBzw8-YGfJxs1nPBULevgBQjoY,147
17
+ airflow_unicore_integration-0.1.13.dist-info/top_level.txt,sha256=j45X-uIuOk3oL78iwlpHakMWtUkg__B7zUlJLwmZx6w,28
18
+ airflow_unicore_integration-0.1.13.dist-info/RECORD,,