cornflow 1.1.5a1__py3-none-any.whl → 2.0.0a6__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.
@@ -2,6 +2,7 @@
2
2
  Endpoint to check the health of the services.
3
3
  It performs a health check to airflow and a health check to cornflow database
4
4
  """
5
+
5
6
  import os
6
7
 
7
8
  # Import from libraries
@@ -13,7 +14,14 @@ from flask_apispec import marshal_with, doc
13
14
  from cornflow.endpoints.meta_resource import BaseMetaResource
14
15
  from cornflow.models import UserModel
15
16
  from cornflow.schemas.health import HealthResponse
16
- from cornflow.shared.const import STATUS_HEALTHY, STATUS_UNHEALTHY
17
+ from cornflow.shared.const import (
18
+ AIRFLOW_BACKEND,
19
+ DATABRICKS_BACKEND,
20
+ STATUS_HEALTHY,
21
+ STATUS_UNHEALTHY,
22
+ )
23
+ from cornflow.shared.databricks import Databricks
24
+ from cornflow.shared.exceptions import EndpointNotImplemented
17
25
 
18
26
 
19
27
  class HealthEndpoint(BaseMetaResource):
@@ -27,11 +35,11 @@ class HealthEndpoint(BaseMetaResource):
27
35
  :rtype: dict
28
36
  :doc-author: baobab soluciones
29
37
  """
30
- af_client = Airflow.from_config(current_app.config)
31
- airflow_status = STATUS_UNHEALTHY
38
+
39
+ backend_status = self.check_backend_status()
40
+
32
41
  cornflow_status = STATUS_UNHEALTHY
33
- if af_client.is_alive():
34
- airflow_status = STATUS_HEALTHY
42
+
35
43
 
36
44
  if (
37
45
  UserModel.get_one_user_by_username(os.getenv("CORNFLOW_SERVICE_USER"))
@@ -40,6 +48,32 @@ class HealthEndpoint(BaseMetaResource):
40
48
  cornflow_status = STATUS_HEALTHY
41
49
 
42
50
  current_app.logger.info(
43
- f"Health check: cornflow {cornflow_status}, airflow {airflow_status}"
51
+ f"Health check: cornflow {cornflow_status}, backend {backend_status}"
44
52
  )
45
- return {"cornflow_status": cornflow_status, "airflow_status": airflow_status}
53
+ return {"cornflow_status": cornflow_status, "backend_status": backend_status}
54
+
55
+ def check_backend_status(self):
56
+ if current_app.config["CORNFLOW_BACKEND"] == AIRFLOW_BACKEND:
57
+ return self._check_airflow_status()
58
+ elif current_app.config["CORNFLOW_BACKEND"] == DATABRICKS_BACKEND:
59
+ return self._check_databricks_status()
60
+ else:
61
+ raise EndpointNotImplemented()
62
+
63
+ @staticmethod
64
+ def _check_airflow_status():
65
+ af_client = Airflow.from_config(current_app.config)
66
+ airflow_status = STATUS_UNHEALTHY
67
+ if af_client.is_alive():
68
+ airflow_status = STATUS_HEALTHY
69
+
70
+ return airflow_status
71
+
72
+ @staticmethod
73
+ def _check_databricks_status():
74
+ db_client = Databricks.from_config(current_app.config)
75
+ databricks_status = STATUS_UNHEALTHY
76
+ if db_client.is_alive():
77
+ databricks_status = STATUS_HEALTHY
78
+
79
+ return databricks_status
@@ -16,7 +16,7 @@ from werkzeug.utils import secure_filename
16
16
 
17
17
  # Import from internal modules
18
18
  from cornflow.endpoints.meta_resource import BaseMetaResource
19
- from cornflow.models import InstanceModel, DeployedDAG
19
+ from cornflow.models import InstanceModel, DeployedOrch
20
20
  from cornflow.schemas.instance import (
21
21
  InstanceSchema,
22
22
  InstanceEndpointResponse,
@@ -92,7 +92,7 @@ class InstanceEndpoint(BaseMetaResource):
92
92
  # We validate the instance data
93
93
  config = current_app.config
94
94
 
95
- instance_schema = DeployedDAG.get_one_schema(config, data_schema, INSTANCE_SCHEMA)
95
+ instance_schema = DeployedOrch.get_one_schema(config, data_schema, INSTANCE_SCHEMA)
96
96
  instance_errors = json_schema_validate_as_string(instance_schema, kwargs["data"])
97
97
 
98
98
  if instance_errors:
@@ -163,7 +163,7 @@ class InstanceDetailsEndpoint(InstanceDetailsEndpointBase):
163
163
 
164
164
  config = current_app.config
165
165
 
166
- instance_schema = DeployedDAG.get_one_schema(config, schema, INSTANCE_SCHEMA)
166
+ instance_schema = DeployedOrch.get_one_schema(config, schema, INSTANCE_SCHEMA)
167
167
  instance_errors = json_schema_validate_as_string(instance_schema, kwargs["data"])
168
168
 
169
169
  if instance_errors:
@@ -8,7 +8,7 @@ from flask_apispec import marshal_with, doc
8
8
 
9
9
  # Import from internal modules
10
10
  from cornflow.endpoints.meta_resource import BaseMetaResource
11
- from cornflow.models import PermissionsDAG, DeployedDAG
11
+ from cornflow.models import PermissionsDAG, DeployedOrch
12
12
  from cornflow.schemas.schemas import SchemaOneApp, SchemaListApp
13
13
  from cornflow.shared.authentication import Auth, authenticate
14
14
  from cornflow.shared.const import ALL_DEFAULT_ROLES
@@ -63,7 +63,7 @@ class SchemaDetailsEndpoint(BaseMetaResource):
63
63
  )
64
64
 
65
65
  if permission:
66
- deployed_dag = DeployedDAG.get_one_object(dag_name)
66
+ deployed_dag = DeployedOrch.get_one_object(dag_name)
67
67
  current_app.logger.info("User gets schema {}".format(dag_name))
68
68
  return {
69
69
  "instance": deployed_dag.instance_schema,
@@ -4,7 +4,7 @@ Initialization file for the models module
4
4
  from .action import ActionModel
5
5
  from .alarms import AlarmsModel
6
6
  from .case import CaseModel
7
- from .dag import DeployedDAG
7
+ from .dag import DeployedOrch
8
8
  from .dag_permissions import PermissionsDAG
9
9
  from .execution import ExecutionModel
10
10
  from .instance import InstanceModel
cornflow/models/dag.py CHANGED
@@ -16,8 +16,9 @@ from cornflow.models.meta_models import TraceAttributesModel
16
16
  from cornflow.shared import db
17
17
  from cornflow.shared.exceptions import ObjectDoesNotExist
18
18
 
19
-
20
- class DeployedDAG(TraceAttributesModel):
19
+ # TODO AGA: cambiar nombre a la clase para que sea general
20
+ # Aí como a los permisos etc
21
+ class DeployedOrch(TraceAttributesModel):
21
22
  """
22
23
  This model contains the registry of the DAGs that are deployed on the corresponding Airflow server
23
24
  """
@@ -35,7 +36,7 @@ class DeployedDAG(TraceAttributesModel):
35
36
  "PermissionsDAG",
36
37
  cascade="all,delete",
37
38
  backref="deployed_dags",
38
- primaryjoin="and_(DeployedDAG.id==PermissionsDAG.dag_id)",
39
+ primaryjoin="and_(DeployedOrch.id==PermissionsDAG.dag_id)",
39
40
  )
40
41
 
41
42
  def __init__(self, data):
@@ -53,7 +54,7 @@ class DeployedDAG(TraceAttributesModel):
53
54
 
54
55
  @staticmethod
55
56
  def get_one_schema(config, dag_name, schema=INSTANCE_SCHEMA):
56
- item = DeployedDAG.get_one_object(dag_name)
57
+ item = DeployedOrch.get_one_object(dag_name)
57
58
 
58
59
  if item is None:
59
60
  err = f"The DAG {dag_name} does not exist in the database."
@@ -1,4 +1,4 @@
1
- from cornflow.models.dag import DeployedDAG
1
+ from cornflow.models.dag import DeployedOrch
2
2
  from cornflow.models.meta_models import TraceAttributesModel
3
3
  from cornflow.shared import db
4
4
 
@@ -29,7 +29,7 @@ class PermissionsDAG(TraceAttributesModel):
29
29
 
30
30
  @staticmethod
31
31
  def add_all_permissions_to_user(user_id):
32
- dags = DeployedDAG.get_all_objects()
32
+ dags = DeployedOrch.get_all_objects()
33
33
  permissions = [
34
34
  PermissionsDAG({"dag_id": dag.id, "user_id": user_id}) for dag in dags
35
35
  ]
@@ -78,7 +78,7 @@ class ExecutionModel(BaseDataModel):
78
78
  + str(self.instance_id)
79
79
  ).encode()
80
80
  ).hexdigest()
81
-
81
+ # TODO AGA: modificar a run_id, tanto la columna como el parámetro.
82
82
  self.dag_run_id = data.get("dag_run_id")
83
83
  self.state = data.get("state", DEFAULT_EXECUTION_CODE)
84
84
  self.state_message = EXECUTION_STATE_MESSAGE_DICT[self.state]
@@ -117,6 +117,7 @@ class ExecutionModel(BaseDataModel):
117
117
  :param str message: Message for the error
118
118
  :return: nothing
119
119
  """
120
+ print("Updating state to ", code)
120
121
  self.state = code
121
122
  if message is None:
122
123
  self.state_message = EXECUTION_STATE_MESSAGE_DICT[code]
@@ -0,0 +1,12 @@
1
+ config_orchestrator = {
2
+ "airflow": {
3
+ "name":"Airflow",
4
+ "def_schema": "solve_model_dag",
5
+ "run_id":"dag_run_id"
6
+ },
7
+ "databricks": {
8
+ "name":"Databricks",
9
+ "def_schema": "979073949072767",
10
+ "run_id":"run_id"
11
+ }
12
+ }
@@ -4,4 +4,4 @@ from marshmallow import fields, Schema
4
4
  class HealthResponse(Schema):
5
5
 
6
6
  cornflow_status = fields.Str()
7
- airflow_status = fields.Str()
7
+ backend_status = fields.Str()
cornflow/shared/const.py CHANGED
@@ -2,6 +2,11 @@
2
2
  In this files we import the values for different constants on cornflow server
3
3
  """
4
4
 
5
+ # CORNFLOW BACKEND
6
+ AIRFLOW_BACKEND = 1
7
+ DATABRICKS_BACKEND = 2
8
+
9
+
5
10
  # endpoints responses for health check
6
11
  STATUS_HEALTHY = "healthy"
7
12
  STATUS_UNHEALTHY = "unhealthy"
@@ -42,7 +47,24 @@ AIRFLOW_TO_STATE_MAP = dict(
42
47
  failed=EXEC_STATE_ERROR,
43
48
  queued=EXEC_STATE_QUEUED,
44
49
  )
50
+ # TODO AGA : revisar si la correspondencia de estados es correcta
51
+ DATABRICKS_TO_STATE_MAP = dict(
52
+ BLOCKED=EXEC_STATE_QUEUED,
53
+ PENDING=EXEC_STATE_QUEUED,
54
+ QUEUED=EXEC_STATE_QUEUED,
55
+ RUNNING=EXEC_STATE_RUNNING,
56
+ TERMINATING=EXEC_STATE_RUNNING,
57
+ SUCCESS=EXEC_STATE_CORRECT,
58
+ USER_CANCELED=EXEC_STATE_STOPPED,
59
+ OTHER_FINISH_ERROR=EXEC_STATE_ERROR,
60
+ )
45
61
 
62
+ DATABRICKS_FINISH_TO_STATE_MAP = dict(
63
+ SUCCESS=EXEC_STATE_CORRECT,
64
+ USER_CANCELED=EXEC_STATE_STOPPED,
65
+ )
66
+
67
+ DATABRICKS_TERMINATE_STATE = "TERMINATED"
46
68
  # These codes and names are inherited from flask app builder in order to have the same names and values
47
69
  # as this library that is the base of airflow
48
70
  AUTH_DB = 1
@@ -55,6 +77,7 @@ OID_NONE = 0
55
77
  OID_AZURE = 1
56
78
  OID_GOOGLE = 2
57
79
 
80
+
58
81
  # AZURE OPEN ID URLS
59
82
  OID_AZURE_DISCOVERY_COMMON_URL = (
60
83
  "https://login.microsoftonline.com/common/.well-known/openid-configuration"
@@ -0,0 +1,111 @@
1
+ """
2
+ Python class to implement the Databricks client wrapper
3
+ """
4
+ import requests
5
+ from databricks.sdk import WorkspaceClient
6
+ from flask import current_app
7
+ from cornflow.orchestrator_constants import config_orchestrator
8
+ # TODO AGA: CODIGO REPETIDO
9
+ # TODO AGA: revisar si el import está bien
10
+ from cornflow_client.constants import DatabricksError
11
+ from cornflow.shared.const import DATABRICKS_TO_STATE_MAP,DATABRICKS_TERMINATE_STATE, DATABRICKS_FINISH_TO_STATE_MAP
12
+
13
+ class Databricks:
14
+ def __init__(self, url, auth_secret, token_endpoint, ep_clusters, client_id):
15
+ self.url = url
16
+ self.constants=config_orchestrator["databricks"]
17
+ self.auth_secret=auth_secret
18
+ self.token_endpoint=token_endpoint
19
+ self.ep_clusters=ep_clusters
20
+ self.client_id = client_id
21
+
22
+ @classmethod
23
+ def from_config(cls, config):
24
+ data = dict(
25
+ url=config["DATABRICKS_URL"],
26
+ auth_secret=config["DATABRICKS_AUTH_SECRET"],
27
+ token_endpoint=config["DATABRICKS_TOKEN_ENDPOINT"],
28
+ ep_clusters=config["DATABRICKS_EP_CLUSTERS"],
29
+ client_id=config["DATABRICKS_CLIENT_ID"],
30
+ )
31
+ return cls(**data)
32
+
33
+ def get_token(self):
34
+ import requests
35
+ url = f'{self.url}{self.token_endpoint}'
36
+ data = {
37
+ "grant_type": "client_credentials",
38
+ "scope": "all-apis"
39
+ }
40
+ auth = (self.client_id,self.auth_secret)
41
+ oauth_response = requests.post(url,data=data,auth=auth)
42
+ oauth_response.json()
43
+ oauth_token = oauth_response.json()["access_token"]
44
+ return oauth_token
45
+
46
+ def is_alive(self):
47
+ try:
48
+ # TODO: this url is project specific. Either it has to be a config option or some other way has to be found
49
+ path="/Workspace/Repos/nippon/nippon_production_scheduling/requirements.txt"
50
+ url = f"{self.url}/api/2.0/workspace/get-status?path={path}"
51
+ response = self.request_headers_auth(method="GET", url=url)
52
+ if "error_code" in response.json().keys():
53
+ return False
54
+ return True
55
+
56
+ except Exception as err:
57
+ current_app.logger.error(f"Error: {err}")
58
+ return False
59
+
60
+ def get_orch_info(self, orch_name, method="GET"):
61
+ """
62
+ Get information about a job in Databricks
63
+ https://docs.databricks.com/api/workspace/jobs/get
64
+ """
65
+ url = f"{self.url}/api/2.1/jobs/get/?job_id={orch_name}"
66
+ schema_info = self.request_headers_auth(method=method, url=url)
67
+ if "error_code" in schema_info.json().keys():
68
+ raise DatabricksError("JOB not available")
69
+ return schema_info
70
+ # TODO AGA: incluir un id de job por defecto o hacer obligatorio el uso el parámetro.
71
+ # Revisar los efectos secundarios de eliminar execution_id y usar el predeterminado
72
+ def run_workflow(
73
+ self, execution_id, orch_name=config_orchestrator["databricks"]["def_schema"], checks_only=False, case_id=None
74
+ ):
75
+ """
76
+ Run a job in Databricks
77
+ """
78
+ # TODO AGA: revisar si la url esta bien/si acepta asi los parámetros
79
+ url = f"{self.url}/api/2.1/jobs/run-now/"
80
+ # TODO AGA: revisar si deben ser notebook parameters o job parameters.
81
+ # Entender cómo se usa checks_only
82
+ payload = dict(job_id=orch_name, notebook_parameters=dict(checks_only=checks_only))
83
+ return self.request_headers_auth(method="POST", url=url, json=payload)
84
+
85
+ def get_run_status(self, run_id):
86
+ """
87
+ Get the status of a run in Databricks
88
+ """
89
+ print( "asking for run id ", run_id)
90
+ url = f"{self.url}/api/2.1/jobs/runs/get"
91
+ payload = dict(run_id=run_id)
92
+ info = self.request_headers_auth(method="GET", url=url, json=payload)
93
+ info = info.json()
94
+ print("info is ", info)
95
+ state = info["status"]["state"]
96
+ if state == DATABRICKS_TERMINATE_STATE:
97
+ if info["status"]["termination_details"]["code"] in DATABRICKS_FINISH_TO_STATE_MAP.keys():
98
+ return info["status"]["termination_details"]["code"]
99
+ else:
100
+ return "OTHER_FINISH_ERROR"
101
+ return state
102
+ def request_headers_auth(self, status=200, **kwargs):
103
+ token =self.get_token()
104
+ def_headers = {"Authorization": "Bearer "+ str(token)}
105
+ headers = kwargs.get("headers", def_headers)
106
+ response = requests.request(headers=headers, **kwargs)
107
+ if status is None:
108
+ return response
109
+ if response.status_code != status:
110
+ raise DatabricksError(error=response.text, status_code=response.status_code)
111
+ return response
@@ -5,7 +5,7 @@ on a flask REST API server
5
5
 
6
6
  from flask import jsonify
7
7
  from webargs.flaskparser import parser
8
- from cornflow_client.constants import AirflowError
8
+ from cornflow_client.constants import AirflowError, DatabricksError
9
9
  from werkzeug.exceptions import HTTPException
10
10
  import traceback
11
11
 
@@ -146,6 +146,8 @@ def initialize_errorhandlers(app):
146
146
  @app.errorhandler(InvalidCredentials)
147
147
  @app.errorhandler(EndpointNotImplemented)
148
148
  @app.errorhandler(AirflowError)
149
+ # TODO AGA: revisar si está bien implementado el nuevo error
150
+ @app.errorhandler(DatabricksError)
149
151
  @app.errorhandler(InvalidData)
150
152
  @app.errorhandler(InvalidPatch)
151
153
  @app.errorhandler(ConfigurationError)
@@ -1,7 +1,7 @@
1
1
  from flask import current_app
2
2
 
3
3
  from cornflow.commands.dag import register_deployed_dags_command
4
- from cornflow.models import DeployedDAG
4
+ from cornflow.models import DeployedOrch
5
5
  from cornflow.tests.const import PUBLIC_DAGS
6
6
  from cornflow.tests.custom_liveServer import CustomTestCaseLive
7
7
 
@@ -15,7 +15,7 @@ class TestCornflowCommands(CustomTestCaseLive):
15
15
  register_deployed_dags_command(
16
16
  config["AIRFLOW_URL"], config["AIRFLOW_USER"], config["AIRFLOW_PWD"], False
17
17
  )
18
- dags = DeployedDAG.get_all_objects()
18
+ dags = DeployedOrch.get_all_objects()
19
19
 
20
20
  for dag in PUBLIC_DAGS:
21
21
  self.assertIn(dag, [d.id for d in dags])
@@ -39,7 +39,7 @@ from cornflow.models import (
39
39
  ViewModel,
40
40
  )
41
41
  from cornflow.models import (
42
- DeployedDAG,
42
+ DeployedOrch,
43
43
  PermissionsDAG,
44
44
  UserModel,
45
45
  )
@@ -356,7 +356,7 @@ class TestCommands(TestCase):
356
356
  - Presence of required DAGs
357
357
  """
358
358
  register_deployed_dags_command_test(verbose=True)
359
- dags = DeployedDAG.get_all_objects()
359
+ dags = DeployedOrch.get_all_objects()
360
360
  for dag in ["solve_model_dag", "gc", "timer"]:
361
361
  self.assertIn(dag, [d.id for d in dags])
362
362
 
@@ -24,7 +24,7 @@ from cornflow.commands.access import access_init_command
24
24
  from cornflow.commands.dag import register_deployed_dags_command_test
25
25
  from cornflow.commands.permissions import register_dag_permissions_command
26
26
  from cornflow.shared.const import ADMIN_ROLE, SERVICE_ROLE
27
- from cornflow.models import DeployedDAG, PermissionsDAG, UserModel, UserRoleModel
27
+ from cornflow.models import DeployedOrch, PermissionsDAG, UserModel, UserRoleModel
28
28
  from cornflow.shared.const import EXEC_STATE_CORRECT, EXEC_STATE_MANUAL
29
29
  from cornflow.shared import db
30
30
  from cornflow.tests.const import (
@@ -351,7 +351,7 @@ class TestDeployedDAG(TestCase):
351
351
  """
352
352
  before = PermissionsDAG.get_user_dag_permissions(self.admin["id"])
353
353
  self.assertIsNotNone(before)
354
- dag = DeployedDAG.query.get("solve_model_dag")
354
+ dag = DeployedOrch.query.get("solve_model_dag")
355
355
  dag.delete()
356
356
  after = PermissionsDAG.get_user_dag_permissions(self.admin["id"])
357
357
  self.assertNotEqual(before, after)
@@ -35,7 +35,7 @@ class TestExampleDataEndpoint(CustomTestCase):
35
35
  def patch_af_client(self, Airflow_mock):
36
36
  af_client = Airflow_mock.return_value
37
37
  af_client.is_alive.return_value = True
38
- af_client.get_dag_info.return_value = {}
38
+ af_client.get_orch_info.return_value = {}
39
39
  af_client.get_one_variable.return_value = {
40
40
  "value": json.dumps(self.example),
41
41
  "key": self.schema_name,
@@ -6,8 +6,8 @@ def patch_af_client(af_client_class):
6
6
  responses_mock = Mock()
7
7
  responses_mock.json.return_value = {"is_paused": False, "dag_run_id": "12345", "state": "success"}
8
8
  af_client_mock.is_alive.return_value = True
9
- af_client_mock.get_dag_info.return_value = responses_mock
10
- af_client_mock.run_dag.return_value = responses_mock
11
- af_client_mock.get_dag_run_status.return_value = responses_mock
9
+ af_client_mock.get_orch_info.return_value = responses_mock
10
+ af_client_mock.run_workflow.return_value = responses_mock
11
+ af_client_mock.get_run_status.return_value = responses_mock
12
12
  af_client_mock.set_dag_run_to_fail.return_value = None
13
13
  af_client_class.from_config.return_value = af_client_mock
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: cornflow
3
- Version: 1.1.5a1
3
+ Version: 2.0.0a6
4
4
  Summary: Cornflow is an open source multi-solver optimization server with a REST API built using flask.
5
5
  Home-page: https://github.com/baobabsoluciones/cornflow
6
6
  Author: baobab soluciones
@@ -13,8 +13,9 @@ Requires-Python: >=3.9
13
13
  Requires-Dist: alembic==1.9.2
14
14
  Requires-Dist: apispec<=6.3.0
15
15
  Requires-Dist: click<=8.1.7
16
- Requires-Dist: cornflow-client>=1.1.0
16
+ Requires-Dist: cornflow-client==2.0.0a6
17
17
  Requires-Dist: cryptography<=42.0.5
18
+ Requires-Dist: databricks-sdk==0.29.0
18
19
  Requires-Dist: disposable-email-domains>=0.0.86
19
20
  Requires-Dist: Flask==2.3.2
20
21
  Requires-Dist: flask-apispec<=0.11.4
@@ -6,8 +6,9 @@ airflow_config/plugins/XCom/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMp
6
6
  airflow_config/plugins/XCom/gce_xcom_backend.py,sha256=vCGvF2jbfZt5bOv-pk5Q_kUR6LomFUojIymimSJmj3o,1795
7
7
  cornflow/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  cornflow/app.py,sha256=X73N64o8OGEqVIRWbC13e_4xb1lxzOH_BV3F3fzAmXE,7312
9
- cornflow/config.py,sha256=IJg757HpjRgXdW1nINHMzWRxfGPW5_8ioV9ZW1aPSNs,5585
9
+ cornflow/config.py,sha256=x7Eu4gOaxdMD9_hzc1m2TcwTtOyFnXXRUjb49_Uc1Y4,6107
10
10
  cornflow/gunicorn.py,sha256=uO-Yk7w7nvQSWh12iDxsVvlG-_2BiKIIjm2UiTk4P9E,480
11
+ cornflow/orchestrator_constants.py,sha256=VO6EGcHhovH6nFpp3QGY_orYVJbjFrMavmemL-Gx_Vs,269
11
12
  cornflow/cli/__init__.py,sha256=5jBmSMpaE1S9rDaQjS8VHJ6x4FfJG8MhKzMzfw7G4Zc,743
12
13
  cornflow/cli/actions.py,sha256=BdTFucT6gZ0QJqo96Zu0C2G9acZ578tLkktKSfTybJ8,414
13
14
  cornflow/cli/arguments.py,sha256=9EEyyny5cJJ1t3WAs6zMgTDvTre0JdQ2N_oZfFQmixs,657
@@ -16,7 +17,7 @@ cornflow/cli/migrations.py,sha256=Stc8H99rG8vgo3yRJcck11zBY_EA4WqyVybglfl8zJE,16
16
17
  cornflow/cli/permissions.py,sha256=4KXKysH4g8YYQIZcPuXFS2g0xEErp-e8I_FAqMGaV7U,1006
17
18
  cornflow/cli/roles.py,sha256=NFG__qrlyOT0h4L4nwo9FSV4DKjGtMVh3gwiJxwM37w,411
18
19
  cornflow/cli/schemas.py,sha256=sxuJOZf12SBZAXDiAYNPB-n9LSxzSwkB3xyhgS_4K9A,6086
19
- cornflow/cli/service.py,sha256=7_va2Gv1qySldWtTHLL0b_Tg6tuYzAVduyeKmoiBgVs,9292
20
+ cornflow/cli/service.py,sha256=lCFOQXtBMYOm8sjntuyLhY_TshFOMMnEtysFy6zrgc8,10817
20
21
  cornflow/cli/users.py,sha256=nPnu8rQNLtwmeXLwYtJ_hjlsa_24XOnQLgBJRBP9bJw,2104
21
22
  cornflow/cli/utils.py,sha256=0tF41gTt6LL9XGOizTQg2GXuOXbqLg6gapCr-HWjJ0Q,733
22
23
  cornflow/cli/views.py,sha256=Xyx2l-Sm7panxQEfR3qksCIUoqF7woMKsYgZALkxUXM,636
@@ -31,30 +32,31 @@ cornflow/commands/__init__.py,sha256=_7mi2Sd8bnaSujU-L78z8Zrswz68NJ2xoocYpsEYmPM
31
32
  cornflow/commands/access.py,sha256=NTZJFF9la8TDuMcD_ISQtJTj-wtM2p1dddokQJHtkj0,748
32
33
  cornflow/commands/actions.py,sha256=4AwgAmyI6VeaugkISvTlNGrIzMMU_-ZB3MhwDD_CIEA,1544
33
34
  cornflow/commands/cleanup.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
- cornflow/commands/dag.py,sha256=KwCQwx9yvmjTG_fOsYKuZJluEYjvLOq014657eu7sPA,3715
35
- cornflow/commands/permissions.py,sha256=mDPqiY2r2YXlUg4wmZRoI4GAMVFC6AjNT3kqzPEKUw8,6627
35
+ cornflow/commands/dag.py,sha256=4c74pqtAg9y_qw_mOSQU1WULwdd9PnV0SmVqbY4T-uw,3721
36
+ cornflow/commands/permissions.py,sha256=TtKJcX219RecAytm8PCdVctaVLZSA7ilhBlPnWxYuFQ,6934
36
37
  cornflow/commands/roles.py,sha256=Oux-UkswkQ74zqaMEJYIEsZpQZGBcGaSahVzx9feAHU,1516
37
38
  cornflow/commands/schemas.py,sha256=QjLXLw5So3f8ZqTg5_uvXxwpo4vE0dMT4_gFMKZHGvQ,1828
38
39
  cornflow/commands/users.py,sha256=MEfqMm2ujso0NQgdUm-crOet-G0M43GNqVCx2Ls-2HY,2591
39
40
  cornflow/commands/views.py,sha256=K2Ld1-l1ZKn9m6e2W1LCxmN44QokwR-8u8rIrviiEf8,2276
40
- cornflow/endpoints/__init__.py,sha256=RI-cNRxYFCuYELPdM0kDDgJhopMMX88HJe-ArTTilNM,7346
41
+ cornflow/endpoints/__init__.py,sha256=JeETje5NDIoOohofogwQr_Q8NUxsK5FcI9tWN-UcDjE,7357
41
42
  cornflow/endpoints/action.py,sha256=ksHK3F919cjkONLcFV2tUIbG-eZw5XbYkqVjYx9iq5I,1359
42
43
  cornflow/endpoints/alarms.py,sha256=3FN7mosBFP_DcJQxfg1h5_phy755FYESXyQ62XpvFbs,1956
43
44
  cornflow/endpoints/apiview.py,sha256=cpxZFkWy6yrRHiAq2tseyVAK1r8uvjnFuOgJjGT0rKI,1370
44
- cornflow/endpoints/case.py,sha256=80Fpv9p8mwIXzjQFuyq1PnPTz3RaOUk932sCUfw7yGA,18670
45
- cornflow/endpoints/dag.py,sha256=MRthA2pnZCAFfoPbHCLDW2j1BsQ3WdjRGC17Szl4b28,10390
46
- cornflow/endpoints/data_check.py,sha256=ZyYR84IT9snjXxUrQfrlv_RzOec_AYeTsijuHYdLAcA,16496
47
- cornflow/endpoints/example_data.py,sha256=1_qAtZfp51N9sU8WCFDZCXOQiOlxCKJjWbXxDOFZ0C8,4372
48
- cornflow/endpoints/execution.py,sha256=5SWwgbxBUj_gDU6Yb7Z-iKNakr9vr3g5qU82Bw9y5wQ,27998
49
- cornflow/endpoints/health.py,sha256=TWmWjKdQOoDzpqwcfksuaAGOLIb2idxzPQcGMWrdkCY,1610
50
- cornflow/endpoints/instance.py,sha256=WAnloocXFxSW4vunBJo3CIHx4NzC_0GPJh5bj3ETd9U,11615
45
+ cornflow/endpoints/case.py,sha256=7mopDXp8RJzOcEvokvTGhT5YYGl2gZlhKry5K8DNya4,18674
46
+ cornflow/endpoints/dag.py,sha256=x_F9gGc1_9-zoAErPGPFBhwQKqIgGEoCjDVMmRKgZRg,10395
47
+ cornflow/endpoints/data_check.py,sha256=FrsBCzwXD_E5qCYkXt0Byc_UPC0APBSxbj8EriPVKxI,16520
48
+ cornflow/endpoints/example_data.py,sha256=e3Y_lZTKVQTkk_pzOnmd-VisuKo7kE-7IqhhLHV-6yw,4374
49
+ cornflow/endpoints/execution.py,sha256=2tX4UJ23e-phAFfgRpjFASr54OWIROuA6a9Uum2Cg48,28010
50
+ cornflow/endpoints/execution_databricks.py,sha256=m9hrSyMTC01xU45BYuKL-yUf8udAKaSmBx_S9PT7cyQ,34945
51
+ cornflow/endpoints/health.py,sha256=K1l8YK7t5nfVRi0WXMn124l8-ezvYAYqHlCtitLU9AY,2558
52
+ cornflow/endpoints/instance.py,sha256=YuB0TTs32eKFxd2GJc7WeVTVWZdv7tqNAtWLrOPsuXo,11618
51
53
  cornflow/endpoints/licenses.py,sha256=82hHWGYvVIiyw9mlwGtMwJMDJ-ShHOi9rvuM6KvfE4U,873
52
54
  cornflow/endpoints/login.py,sha256=rchsQBL60FQXoub4dznB_UjQ5r9CmJBGnI-HnQY37Mk,9413
53
55
  cornflow/endpoints/main_alarms.py,sha256=GUB-UdnvEFi7n6FGFKO9VtZeZb4Ox3NvBMhB7rdqNyI,2006
54
56
  cornflow/endpoints/meta_resource.py,sha256=eqC6U8IpY65Cbk2WpdphRtE6o5kes2lB4LhezfUB7xI,8471
55
57
  cornflow/endpoints/permission.py,sha256=FpEBIucfUl89UaJ80SC0VR6pFAdqdSsS43SdNkcXWtI,3751
56
58
  cornflow/endpoints/roles.py,sha256=54ra4MQ9JmrHDsiGczDAVqHgAT4zwhdTA1dLBOy66v8,6105
57
- cornflow/endpoints/schemas.py,sha256=lHyvSpPj0x7zVYDlEeRrz_Qqyp6WNimibs5gK4BHpKI,2933
59
+ cornflow/endpoints/schemas.py,sha256=gyyTgD5mQb7Nsacm8Mdjcz4GXNy9IY7ZEUW9myN-Nbo,2935
58
60
  cornflow/endpoints/signup.py,sha256=4Xle2aTd6fiblb2pFcTaBP3ykXSuXsrc7qD0JjpqeZY,3513
59
61
  cornflow/endpoints/tables.py,sha256=KI4sgkBHdiHbOnIRR_yoZ859ea3rnp_6ji_XvQbwsZ8,3071
60
62
  cornflow/endpoints/token.py,sha256=UEnsNNQAd6lJi2aF972d8uUWNJHT4ZcRr0eYpN458R4,1193
@@ -79,14 +81,14 @@ cornflow/migrations/versions/e1a50dae1ac9_.py,sha256=NIRKFg1hvo4F-YqMdsYoX9VwzKl
79
81
  cornflow/migrations/versions/e937a5234ce4_.py,sha256=460JyCKPN6XL5DDcJfC51WKr9V342ovVhuo8F7fwuo0,710
80
82
  cornflow/migrations/versions/ebdd955fcc5e_.py,sha256=MzLbzmiwMWWVkJWJ8EMmmBnCIOzvlwXKGFWxELnOQpE,1848
81
83
  cornflow/migrations/versions/f3bee20314a2_.py,sha256=pgfAeiPvFvPJXhWlFHq6Y7bjYFGvapsfHEFXXX8UJlE,1782
82
- cornflow/models/__init__.py,sha256=hvUe_9Xep1gl8hPKcWxCZN9sORH0Opskj_DnNs3bn24,500
84
+ cornflow/models/__init__.py,sha256=8ETJtAalmLu0yjv_B8dt8tNmg-NqlsngoZlhMTuftoE,501
83
85
  cornflow/models/action.py,sha256=8MYzQ2qX5bG0zk28OufypzThkR7AU1J1el-5ABoTurg,1200
84
86
  cornflow/models/alarms.py,sha256=R_g3tkWNSJaAG4gSvthgJlyrueY9VDuIZPoVHk5lDvU,1682
85
87
  cornflow/models/base_data_model.py,sha256=mVMHJpEoJeH6Wly_ZIfzLfTPd39nSYpCgmtA_ft2VPs,5577
86
88
  cornflow/models/case.py,sha256=GEs-xeo0bJ5qJETDnIur-2q2IyR3NSj1K0jP3Arz4Xs,9572
87
- cornflow/models/dag.py,sha256=DhHpBqJXrLzPoVSyrS_rYI7BotdzITopJDKsql3mQnQ,2930
88
- cornflow/models/dag_permissions.py,sha256=QkhPxSLKxH5elIMdf-rnRtV_CEZBQDFFKUOWv15RgwI,1716
89
- cornflow/models/execution.py,sha256=9sq_GXSAgFgTpDX3kbJGwsHwNQGXH9E_gfNYIfNtDOk,6022
89
+ cornflow/models/dag.py,sha256=a3X_WSuLj9nNv-c2qziQb9RSOULprTNbWm4G3k5jGAo,3021
90
+ cornflow/models/dag_permissions.py,sha256=LM2CacGyflwYbG8fbjRaaUry7pQDtvOXjfJpY9jj5EQ,1718
91
+ cornflow/models/execution.py,sha256=63wECEMQKehozS0Fnh6-bxnwe2BFCZ0qLDljnRbVxTI,6140
90
92
  cornflow/models/instance.py,sha256=2E9kBKv1a8soaEAvG8X4qXQ4BVC-IWYD5WQcPmZQw00,3979
91
93
  cornflow/models/main_alarms.py,sha256=9S-Ohr2kYFFWB0HomrpSdDIoUr85Eu1rt90Om_Pa8VY,1748
92
94
  cornflow/models/meta_models.py,sha256=qeliGdpw0_q0GCeZzansF-09Ay5pueaT-QQPVPZ5aj4,12000
@@ -103,7 +105,7 @@ cornflow/schemas/common.py,sha256=QYuxWcOl4smXFZr_vL07OVgH9H50ZywCrXxycVNr1qA,47
103
105
  cornflow/schemas/dag.py,sha256=0ENA75X9L8YqjJW6ZO1Sb4zE8OxB15_O49_nwA6eAVw,901
104
106
  cornflow/schemas/example_data.py,sha256=hbE8TJakFqOweHXiA3mduNETM6FCX6xLTiQuH3EkSTc,281
105
107
  cornflow/schemas/execution.py,sha256=GSRHzikVPlhxMdiKrGnTuGfen8_Lf4wSfheJwvcavTs,4718
106
- cornflow/schemas/health.py,sha256=D2NsP9i6nA1hLema-bvegrrdH4JY7pZlYxPcqRJOvao,141
108
+ cornflow/schemas/health.py,sha256=8ptyAJc23HTgb-dgtFFEtowFrlwILgkZdgezJ-JSMDY,141
107
109
  cornflow/schemas/instance.py,sha256=qr4km0AlAhoNf9G1Il-pfHphT_vAiiLDpv7A9S3FKAw,1870
108
110
  cornflow/schemas/main_alarms.py,sha256=cC1_Vb1dmo_vdZpZQrA7jH-hRCjVtLRy6Z2JFBlTrlo,604
109
111
  cornflow/schemas/model_json.py,sha256=qUsdd1XmxhcsAmb1JB0xAsvucZoAeQhAQD_3wiY-rVo,202
@@ -119,9 +121,10 @@ cornflow/schemas/user_role.py,sha256=e5y6RgdZZtLqD-h2B3sa5WokI5-pT78tWw85IG34I74
119
121
  cornflow/schemas/view.py,sha256=ctq9Y1TmjrWdyOqgDYeEx7qbbuNLKfSiNOlFTlXmpaw,429
120
122
  cornflow/shared/__init__.py,sha256=1ahcBwWOsSjGI4FEm77JBQjitBdBszOncKcEMjzwGYE,29
121
123
  cornflow/shared/compress.py,sha256=pohQaGs1xbH8CN6URIH6BAHA--pFq7Hmjz8oI3c3B5c,1347
122
- cornflow/shared/const.py,sha256=nRZElCjbuJIpjzVlCfZjTN4mAbqDTXIyAbSMlkNL3n8,3440
124
+ cornflow/shared/const.py,sha256=FQQQz-LekFN81YPh1KTHwyLaikddPYqQJHdzTHhvTfw,4034
125
+ cornflow/shared/databricks.py,sha256=DYhF99DJCxAcTQjB3ih4w9qc_yb_3iG1bpx-eerumvE,4731
123
126
  cornflow/shared/email.py,sha256=QNDDMv86LZObkevSCyUbLQeR2UD3zWScPIr82NDzYHQ,3437
124
- cornflow/shared/exceptions.py,sha256=tjXd4Hl-QPJviE2NviapS1rwd2NImFd3vMzmp6OTg28,6911
127
+ cornflow/shared/exceptions.py,sha256=bD_Eo1T2baSrgfGMKb6r9GZ1fCJbitykEEMy9wOnk4A,7033
125
128
  cornflow/shared/licenses.py,sha256=Lc71Jw2NxVTFWtoXdQ9wJX_o3BDfYg1xVoehDXvnCkQ,1328
126
129
  cornflow/shared/log_config.py,sha256=FM2ajjp2MB4BlFbUHklnWInT7-LLjtrqQ0mo3k_HRmE,621
127
130
  cornflow/shared/query_tools.py,sha256=6yGLCWjv-I2a_ZU4A0IymyJq67fZPZdRcCGOGQQpSXg,1199
@@ -137,7 +140,7 @@ cornflow/tests/const.py,sha256=_5BYFGN42Xg0PXMR8UU5DBL6dYmYn5rgRBgPyptrKso,2499
137
140
  cornflow/tests/custom_liveServer.py,sha256=I_0YNrcKIwVmRov3zCQMWwcCWkMe5V246Hpa4gS8AZE,3079
138
141
  cornflow/tests/custom_test_case.py,sha256=X1j-cy9QKhF4W6_7jcJsTm-0Jn6lluq6gj-g126dFpQ,35945
139
142
  cornflow/tests/integration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
140
- cornflow/tests/integration/test_commands.py,sha256=FZcoEM-05D4MBMe0L0V-0sxk_L0zMbzQxb9UCd7iBe0,695
143
+ cornflow/tests/integration/test_commands.py,sha256=mGiMfqIqwvRx08Al6LcHXEKPgEQEJ33EoPIZhGcReX0,697
141
144
  cornflow/tests/integration/test_cornflowclient.py,sha256=ioAQmQKWW6mXVJhdF4LECZcGIOa_N0xPkFaGWGtxOO8,20963
142
145
  cornflow/tests/ldap/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
143
146
  cornflow/tests/ldap/test_ldap_authentication.py,sha256=6Gu1WkF7MQmcV_10IJkpo2qEloZZ9zjpV18ANDD0HRw,4286
@@ -148,10 +151,10 @@ cornflow/tests/unit/test_apiview.py,sha256=ws74KU4O1VvKWsgLeFFpgDJxrTFf0cvB4NBX6
148
151
  cornflow/tests/unit/test_application.py,sha256=ZVmTQDUOkPRxHqt6mWU9G_lQ3jJNMJR0cx7IkLMFGrU,1715
149
152
  cornflow/tests/unit/test_cases.py,sha256=KnkvLsEOZXvosuE2fH8_i6iETlvWF3u04363rmmj8mM,38089
150
153
  cornflow/tests/unit/test_cli.py,sha256=0l1_fYvJg-f_wA1SFgtMTzdBRy6uLhp58xWkNIR-tXQ,18602
151
- cornflow/tests/unit/test_commands.py,sha256=kvO8Vn60rj3WBG2oXw7NpDSEYoGLNe806txbJPhtNJo,14722
152
- cornflow/tests/unit/test_dags.py,sha256=-QSQpdQZywGTnCRxhpoe9ilT0D0BLQRfnh_OMD9tx0Q,13401
154
+ cornflow/tests/unit/test_commands.py,sha256=HjeR7vytN_IQhkmKFJw5St4bSEOIXuTeLPuu75ZGsaY,14724
155
+ cornflow/tests/unit/test_dags.py,sha256=Q8l0K1FoMI6Yn4tuzxfiZp2azCpIWclbUneQnkOattA,13403
153
156
  cornflow/tests/unit/test_data_checks.py,sha256=6s50d1iuRTUcAYn14oEcRS39ZZ6E9ussU4YpkpYhtC4,8612
154
- cornflow/tests/unit/test_example_data.py,sha256=D-Tgnqw7NZlnBXaDcUU0reNhAca5JlJP2Sdn3KdS4Sw,4127
157
+ cornflow/tests/unit/test_example_data.py,sha256=rCj3wNW4OMHyLfuPdIKxBa7-eRuFsymij-9Nk27_Z3o,4128
155
158
  cornflow/tests/unit/test_executions.py,sha256=_hIaiZri7Blyx4DYhBDHh-0peU1HQh66RSPqQJFveE8,17501
156
159
  cornflow/tests/unit/test_generate_from_schema.py,sha256=L1EdnASbDJ8SjrX1V4WnUKKwV0sRTwVnNYnxSpyeSeQ,15376
157
160
  cornflow/tests/unit/test_health.py,sha256=0E0HXMb63_Z8drbLZdxnJwtTbQyaZS9ZEHut6qsDbh8,1033
@@ -168,9 +171,9 @@ cornflow/tests/unit/test_sign_up.py,sha256=-i6VO9z1FwqRHFvaSrpWAzOZx6qa8mHUEmmsj
168
171
  cornflow/tests/unit/test_tables.py,sha256=dY55YgaCkyqwJnqn0LbZHNeXBoL4ZxXWwKkCoTF4WVE,8947
169
172
  cornflow/tests/unit/test_token.py,sha256=OEVPgG8swSMkUbuGJGfGF5Z27utMLICn1eIyma1cM9E,3760
170
173
  cornflow/tests/unit/test_users.py,sha256=WfaMcybPpR7rspXyvzHGgw25p751hMPAV0DOp_caSPM,22430
171
- cornflow/tests/unit/tools.py,sha256=ag3sWv2WLi498R1GL5AOUnXqSsszD3UugzLZLC5NqAw,585
172
- cornflow-1.1.5a1.dist-info/METADATA,sha256=x8cJzw5PEPdf64vx-u6tgsUiHvDGwRlIBMYmFBmFkm0,9496
173
- cornflow-1.1.5a1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
174
- cornflow-1.1.5a1.dist-info/entry_points.txt,sha256=q9cPKAFBsmHkERCqQ2JcOTM-tVBLHTl-DGxwCXowAWM,46
175
- cornflow-1.1.5a1.dist-info/top_level.txt,sha256=Qj9kLFJW1PLb-ZV2s_aCkQ-Wi5W6KC6fFR-LTBrx-rU,24
176
- cornflow-1.1.5a1.dist-info/RECORD,,
174
+ cornflow/tests/unit/tools.py,sha256=BCAm_KGVgZO-CCb_rkaZlbK4SID_F2ab8FiBJzGwKtc,587
175
+ cornflow-2.0.0a6.dist-info/METADATA,sha256=xTGBzk0AkwPEbaJRLAvh0_B4iwNTycFctFxw4c4v06Q,9536
176
+ cornflow-2.0.0a6.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
177
+ cornflow-2.0.0a6.dist-info/entry_points.txt,sha256=q9cPKAFBsmHkERCqQ2JcOTM-tVBLHTl-DGxwCXowAWM,46
178
+ cornflow-2.0.0a6.dist-info/top_level.txt,sha256=Qj9kLFJW1PLb-ZV2s_aCkQ-Wi5W6KC6fFR-LTBrx-rU,24
179
+ cornflow-2.0.0a6.dist-info/RECORD,,