cornflow 1.2.4__py3-none-any.whl → 1.3.0rc1__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.
Files changed (47) hide show
  1. cornflow/cli/service.py +91 -42
  2. cornflow/commands/dag.py +7 -7
  3. cornflow/commands/permissions.py +9 -5
  4. cornflow/config.py +23 -3
  5. cornflow/endpoints/case.py +37 -21
  6. cornflow/endpoints/dag.py +5 -5
  7. cornflow/endpoints/data_check.py +8 -7
  8. cornflow/endpoints/example_data.py +4 -2
  9. cornflow/endpoints/execution.py +215 -127
  10. cornflow/endpoints/health.py +30 -11
  11. cornflow/endpoints/instance.py +3 -3
  12. cornflow/endpoints/login.py +9 -2
  13. cornflow/endpoints/schemas.py +3 -3
  14. cornflow/migrations/versions/999b98e24225.py +34 -0
  15. cornflow/migrations/versions/cef1df240b27_.py +34 -0
  16. cornflow/models/__init__.py +2 -1
  17. cornflow/models/dag.py +8 -9
  18. cornflow/models/dag_permissions.py +3 -3
  19. cornflow/models/execution.py +2 -3
  20. cornflow/models/permissions.py +1 -0
  21. cornflow/models/user.py +1 -1
  22. cornflow/schemas/execution.py +14 -1
  23. cornflow/schemas/health.py +1 -1
  24. cornflow/shared/authentication/auth.py +14 -1
  25. cornflow/shared/authentication/decorators.py +0 -1
  26. cornflow/shared/const.py +44 -1
  27. cornflow/shared/exceptions.py +2 -1
  28. cornflow/tests/base_test_execution.py +798 -0
  29. cornflow/tests/const.py +1 -0
  30. cornflow/tests/integration/test_commands.py +2 -2
  31. cornflow/tests/integration/test_cornflowclient.py +2 -1
  32. cornflow/tests/unit/test_cases.py +1 -1
  33. cornflow/tests/unit/test_commands.py +5 -5
  34. cornflow/tests/unit/test_dags.py +3 -3
  35. cornflow/tests/unit/test_example_data.py +1 -1
  36. cornflow/tests/unit/test_executions.py +115 -535
  37. cornflow/tests/unit/test_health.py +84 -3
  38. cornflow/tests/unit/test_main_alarms.py +1 -1
  39. cornflow/tests/unit/test_roles.py +2 -1
  40. cornflow/tests/unit/test_schema_from_models.py +1 -1
  41. cornflow/tests/unit/test_schemas.py +1 -1
  42. cornflow/tests/unit/tools.py +93 -10
  43. {cornflow-1.2.4.dist-info → cornflow-1.3.0rc1.dist-info}/METADATA +2 -2
  44. {cornflow-1.2.4.dist-info → cornflow-1.3.0rc1.dist-info}/RECORD +47 -44
  45. {cornflow-1.2.4.dist-info → cornflow-1.3.0rc1.dist-info}/WHEEL +0 -0
  46. {cornflow-1.2.4.dist-info → cornflow-1.3.0rc1.dist-info}/entry_points.txt +0 -0
  47. {cornflow-1.2.4.dist-info → cornflow-1.3.0rc1.dist-info}/top_level.txt +0 -0
@@ -2,18 +2,28 @@
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
- # Import from internal modules
8
- from cornflow.endpoints.meta_resource import BaseMetaResource
9
- from cornflow.models import UserModel
10
- from cornflow.schemas.health import HealthResponse
11
- from cornflow.shared.const import STATUS_HEALTHY, STATUS_UNHEALTHY, CORNFLOW_VERSION
12
8
  # Import from libraries
13
9
  from cornflow_client.airflow.api import Airflow
14
10
  from flask import current_app
15
11
  from flask_apispec import marshal_with, doc
16
12
 
13
+ # Import from internal modules
14
+ from cornflow.endpoints.meta_resource import BaseMetaResource
15
+ from cornflow.models import UserModel
16
+ from cornflow.schemas.health import HealthResponse
17
+ from cornflow.shared.const import (
18
+ AIRFLOW_BACKEND,
19
+ DATABRICKS_BACKEND,
20
+ STATUS_HEALTHY,
21
+ STATUS_UNHEALTHY,
22
+ CORNFLOW_VERSION
23
+ )
24
+ from cornflow_client.databricks.api import Databricks
25
+ from cornflow.shared.exceptions import EndpointNotImplemented
26
+
17
27
 
18
28
  class HealthEndpoint(BaseMetaResource):
19
29
  @doc(description="Health check", tags=["Health"])
@@ -26,12 +36,9 @@ class HealthEndpoint(BaseMetaResource):
26
36
  :rtype: dict
27
37
  :doc-author: baobab soluciones
28
38
  """
29
- af_client = Airflow.from_config(current_app.config)
30
- airflow_status = STATUS_UNHEALTHY
39
+ backend_status = self.check_backend_status()
31
40
  cornflow_status = STATUS_UNHEALTHY
32
41
  cornflow_version = CORNFLOW_VERSION
33
- if af_client.is_alive():
34
- airflow_status = STATUS_HEALTHY
35
42
 
36
43
  if (
37
44
  UserModel.get_one_user_by_username(os.getenv("CORNFLOW_SERVICE_USER"))
@@ -40,6 +47,18 @@ class HealthEndpoint(BaseMetaResource):
40
47
  cornflow_status = STATUS_HEALTHY
41
48
 
42
49
  current_app.logger.info(
43
- f"Health check: cornflow {cornflow_status}, airflow {airflow_status}"
50
+ f"Health check: cornflow {cornflow_status}, backend {backend_status}"
44
51
  )
45
- return {"cornflow_status": cornflow_status, "airflow_status": airflow_status, "cornflow_version":cornflow_version}
52
+ return {"cornflow_status": cornflow_status, "backend_status": backend_status,
53
+ "cornflow_version": cornflow_version}
54
+
55
+ def check_backend_status(self):
56
+ if current_app.config["CORNFLOW_BACKEND"] == AIRFLOW_BACKEND:
57
+ client = Airflow.from_config(current_app.config)
58
+ elif current_app.config["CORNFLOW_BACKEND"] == DATABRICKS_BACKEND:
59
+ client = Databricks.from_config(current_app.config)
60
+ else:
61
+ raise EndpointNotImplemented()
62
+ if client.is_alive():
63
+ return STATUS_HEALTHY
64
+ return STATUS_UNHEALTHY
@@ -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, DeployedWorkflow
20
20
  from cornflow.schemas.instance import (
21
21
  InstanceSchema,
22
22
  InstanceEndpointResponse,
@@ -91,7 +91,7 @@ class InstanceEndpoint(BaseMetaResource):
91
91
  # We validate the instance data
92
92
  config = current_app.config
93
93
 
94
- instance_schema = DeployedDAG.get_one_schema(
94
+ instance_schema = DeployedWorkflow.get_one_schema(
95
95
  config, data_schema, INSTANCE_SCHEMA
96
96
  )
97
97
  instance_errors = json_schema_validate_as_string(
@@ -166,7 +166,7 @@ class InstanceDetailsEndpoint(InstanceDetailsEndpointBase):
166
166
 
167
167
  config = current_app.config
168
168
 
169
- instance_schema = DeployedDAG.get_one_schema(
169
+ instance_schema = DeployedWorkflow.get_one_schema(
170
170
  config, schema, INSTANCE_SCHEMA
171
171
  )
172
172
  instance_errors = json_schema_validate_as_string(
@@ -188,8 +188,15 @@ class LoginBaseEndpoint(BaseMetaResource):
188
188
  )
189
189
 
190
190
  email = decoded_token.get("email", f"{username}@cornflow.org")
191
- first_name = decoded_token.get("given_name", "")
192
- last_name = decoded_token.get("family_name", "")
191
+
192
+ email_names = email.split("@")[0]
193
+ if "." in email_names:
194
+ default_first_name, default_last_name = email_names.split(".")[0:2]
195
+ else:
196
+ default_first_name, default_last_name = email_names, ""
197
+
198
+ first_name = decoded_token.get("given_name", default_first_name)
199
+ last_name = decoded_token.get("family_name", default_last_name)
193
200
 
194
201
  data = {
195
202
  "username": username,
@@ -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, DeployedWorkflow
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 = DeployedWorkflow.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,
@@ -71,7 +71,7 @@ class SchemaDetailsEndpoint(BaseMetaResource):
71
71
  "instance_checks": deployed_dag.instance_checks_schema,
72
72
  "solution_checks": deployed_dag.solution_checks_schema,
73
73
  "config": deployed_dag.config_schema,
74
- "name": dag_name
74
+ "name": dag_name,
75
75
  }, 200
76
76
  else:
77
77
  err = "User does not have permission to access this dag"
@@ -0,0 +1,34 @@
1
+ """
2
+ Rename dag_run_id column to run_id in executions table
3
+
4
+ Revision ID: 999b98e24225
5
+ Revises: 991b98e24225
6
+ Create Date: 2024-04-08 12:00:00.000000
7
+
8
+ """
9
+
10
+ from alembic import op
11
+ import sqlalchemy as sa
12
+
13
+
14
+ # revision identifiers, used by Alembic.
15
+ revision = "abc123456789"
16
+ down_revision = "991b98e24225"
17
+ branch_labels = None
18
+ depends_on = None
19
+
20
+
21
+ def upgrade():
22
+ # ### commands auto generated by Alembic - please adjust! ###
23
+ with op.batch_alter_table("executions", schema=None) as batch_op:
24
+ batch_op.alter_column("dag_run_id", new_column_name="run_id")
25
+
26
+ # ### end Alembic commands ###
27
+
28
+
29
+ def downgrade():
30
+ # ### commands auto generated by Alembic - please adjust! ###
31
+ with op.batch_alter_table("executions", schema=None) as batch_op:
32
+ batch_op.alter_column("run_id", new_column_name="dag_run_id")
33
+
34
+ # ### end Alembic commands ###
@@ -0,0 +1,34 @@
1
+ """empty message
2
+
3
+ Revision ID: cef1df240b27
4
+ Revises: abc123456789
5
+ Create Date: 2025-07-22 19:05:11.146449
6
+
7
+ """
8
+
9
+ from alembic import op
10
+ import sqlalchemy as sa
11
+
12
+
13
+ # revision identifiers, used by Alembic.
14
+ revision = 'cef1df240b27'
15
+ down_revision = 'abc123456789'
16
+ branch_labels = None
17
+ depends_on = None
18
+
19
+
20
+ def upgrade():
21
+ # ### commands auto generated by Alembic - please adjust! ###
22
+
23
+ op.rename_table("deployed_dags", "deployed_workflows")
24
+
25
+ # ### end Alembic commands ###
26
+
27
+
28
+ def downgrade():
29
+ # ### commands auto generated by Alembic - please adjust! ###
30
+
31
+ # Rename table back from deployed_workflows to deployed_dags
32
+ op.rename_table("deployed_workflows", "deployed_dags")
33
+
34
+ # ### end Alembic commands ###
@@ -1,10 +1,11 @@
1
1
  """
2
2
  Initialization file for the models module
3
3
  """
4
+
4
5
  from .action import ActionModel
5
6
  from .alarms import AlarmsModel
6
7
  from .case import CaseModel
7
- from .dag import DeployedDAG
8
+ from .dag import DeployedWorkflow
8
9
  from .dag_permissions import PermissionsDAG
9
10
  from .execution import ExecutionModel
10
11
  from .instance import InstanceModel
cornflow/models/dag.py CHANGED
@@ -1,13 +1,12 @@
1
- """
1
+ """ """
2
2
 
3
- """
4
3
  # Import from libraries
5
4
  from cornflow_client.airflow.api import Airflow
6
5
  from cornflow_client.constants import (
7
6
  INSTANCE_SCHEMA,
8
7
  SOLUTION_SCHEMA,
9
8
  INSTANCE_CHECKS_SCHEMA,
10
- SOLUTION_CHECKS_SCHEMA
9
+ SOLUTION_CHECKS_SCHEMA,
11
10
  )
12
11
  from sqlalchemy.dialects.postgresql import TEXT, JSON
13
12
 
@@ -17,12 +16,12 @@ from cornflow.shared import db
17
16
  from cornflow.shared.exceptions import ObjectDoesNotExist
18
17
 
19
18
 
20
- class DeployedDAG(TraceAttributesModel):
19
+ class DeployedWorkflow(TraceAttributesModel):
21
20
  """
22
21
  This model contains the registry of the DAGs that are deployed on the corresponding Airflow server
23
22
  """
24
23
 
25
- __tablename__ = "deployed_dags"
24
+ __tablename__ = "deployed_workflows"
26
25
  id = db.Column(db.String(128), primary_key=True)
27
26
  description = db.Column(TEXT, nullable=True)
28
27
  instance_schema = db.Column(JSON, nullable=True)
@@ -34,8 +33,8 @@ class DeployedDAG(TraceAttributesModel):
34
33
  dag_permissions = db.relationship(
35
34
  "PermissionsDAG",
36
35
  cascade="all,delete",
37
- backref="deployed_dags",
38
- primaryjoin="and_(DeployedDAG.id==PermissionsDAG.dag_id)",
36
+ backref="deployed_workflows",
37
+ primaryjoin="and_(DeployedWorkflow.id==PermissionsDAG.dag_id)",
39
38
  )
40
39
 
41
40
  def __init__(self, data):
@@ -53,14 +52,14 @@ class DeployedDAG(TraceAttributesModel):
53
52
 
54
53
  @staticmethod
55
54
  def get_one_schema(config, dag_name, schema=INSTANCE_SCHEMA):
56
- item = DeployedDAG.get_one_object(dag_name)
55
+ item = DeployedWorkflow.get_one_object(dag_name)
57
56
 
58
57
  if item is None:
59
58
  err = f"The DAG {dag_name} does not exist in the database."
60
59
  raise ObjectDoesNotExist(
61
60
  err,
62
61
  log_txt=f"Error while user tries to register data for DAG {dag_name} "
63
- f"from instance and execution. " + err
62
+ f"from instance and execution. " + err,
64
63
  )
65
64
 
66
65
  if schema == INSTANCE_SCHEMA:
@@ -1,4 +1,4 @@
1
- from cornflow.models.dag import DeployedDAG
1
+ from cornflow.models.dag import DeployedWorkflow
2
2
  from cornflow.models.meta_models import TraceAttributesModel
3
3
  from cornflow.shared import db
4
4
 
@@ -10,7 +10,7 @@ class PermissionsDAG(TraceAttributesModel):
10
10
  id = db.Column(db.Integer, primary_key=True, autoincrement=True)
11
11
 
12
12
  dag_id = db.Column(
13
- db.String(128), db.ForeignKey("deployed_dags.id"), nullable=False
13
+ db.String(128), db.ForeignKey("deployed_workflows.id"), nullable=False
14
14
  )
15
15
  user_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=False)
16
16
  user = db.relationship("UserModel", viewonly=True)
@@ -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 = DeployedWorkflow.get_all_objects()
33
33
  permissions = [
34
34
  PermissionsDAG({"dag_id": dag.id, "user_id": user_id}) for dag in dags
35
35
  ]
@@ -55,7 +55,7 @@ class ExecutionModel(BaseDataModel):
55
55
  db.String(256), db.ForeignKey("instances.id"), nullable=False
56
56
  )
57
57
  config = db.Column(JSON, nullable=False)
58
- dag_run_id = db.Column(db.String(256), nullable=True)
58
+ run_id = db.Column(db.String(256), nullable=True)
59
59
  log_text = db.Column(TEXT, nullable=True)
60
60
  log_json = db.Column(JSON, nullable=True)
61
61
  state = db.Column(db.SmallInteger, default=DEFAULT_EXECUTION_CODE, nullable=False)
@@ -78,8 +78,7 @@ class ExecutionModel(BaseDataModel):
78
78
  + str(self.instance_id)
79
79
  ).encode()
80
80
  ).hexdigest()
81
-
82
- self.dag_run_id = data.get("dag_run_id")
81
+ self.run_id = data.get("run_id")
83
82
  self.state = data.get("state", DEFAULT_EXECUTION_CODE)
84
83
  self.state_message = EXECUTION_STATE_MESSAGE_DICT[self.state]
85
84
  self.config = data.get("config")
@@ -1,6 +1,7 @@
1
1
  """
2
2
  This file contains the PermissionViewRoleModel
3
3
  """
4
+
4
5
  # Imports from internal modules
5
6
  from cornflow.models.meta_models import TraceAttributesModel
6
7
  from cornflow.shared import db
cornflow/models/user.py CHANGED
@@ -5,7 +5,7 @@ This file contains the UserModel
5
5
  # Imports from external libraries
6
6
  import random
7
7
  import string
8
- from datetime import datetime, timezone, timedelta
8
+ from datetime import datetime, timezone
9
9
 
10
10
  # Imports from internal modules
11
11
  from cornflow.models.meta_models import TraceAttributesModel
@@ -43,7 +43,7 @@ class ExecutionSchema(Schema):
43
43
  name = fields.Str()
44
44
  description = fields.Str()
45
45
  schema = fields.Str(required=False)
46
- dag_run_id = fields.Str(required=False, dump_only=True)
46
+ run_id = fields.Str(required=False, dump_only=True)
47
47
  config = fields.Nested(ConfigSchema, required=True)
48
48
  data = fields.Raw(dump_only=True)
49
49
  checks = fields.Raw(required=False, allow_none=True)
@@ -78,6 +78,7 @@ class ExecutionEditRequest(Schema):
78
78
  name = fields.Str()
79
79
  description = fields.Str()
80
80
  data = fields.Raw()
81
+ instance_id = fields.Str(required=False)
81
82
 
82
83
 
83
84
  class ExecutionDagRequest(Schema):
@@ -119,7 +120,19 @@ class ExecutionDetailsEndpointWithIndicatorsResponse(ExecutionDetailsEndpointRes
119
120
  return obj.user.username
120
121
  return None
121
122
 
123
+ def get_first_name(self, obj):
124
+ if hasattr(obj, "user") and obj.user is not None:
125
+ return obj.user.first_name
126
+ return None
127
+
128
+ def get_last_name(self, obj):
129
+ if hasattr(obj, "user") and obj.user is not None:
130
+ return obj.user.last_name
131
+ return None
132
+
122
133
  username = fields.Method("get_username")
134
+ first_name = fields.Method("get_first_name")
135
+ last_name = fields.Method("get_last_name")
123
136
 
124
137
 
125
138
  class ExecutionDetailsWithIndicatorsAndLogResponse(
@@ -4,5 +4,5 @@ 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()
8
8
  cornflow_version = fields.Str()
@@ -25,6 +25,7 @@ from cornflow.shared.const import (
25
25
  AUTH_OID,
26
26
  PERMISSION_METHOD_MAP,
27
27
  INTERNAL_TOKEN_ISSUER,
28
+ OID_PROVIDER_AZURE,
28
29
  )
29
30
  from cornflow.shared.exceptions import (
30
31
  CommunicationError,
@@ -300,7 +301,19 @@ class Auth:
300
301
  :rtype: dict
301
302
  """
302
303
  # Fetch keys from provider
303
- jwks_url = f"{provider_url.rstrip('/')}/.well-known/jwks.json"
304
+ # For Azure AD, we need to use the discovery endpoint to get the jwks_uri
305
+ oid_provider = current_app.config["OID_PROVIDER"]
306
+ if oid_provider == OID_PROVIDER_AZURE:
307
+ tenant_id = provider_url.split("/")[
308
+ 3
309
+ ] # Extract tenant ID from provider URL
310
+ jwks_url = (
311
+ f"https://login.microsoftonline.com/{tenant_id}/discovery/v2.0/keys"
312
+ )
313
+ else:
314
+ # For other providers, use the standard well-known endpoint
315
+ jwks_url = f"{provider_url.rstrip('/')}/.well-known/jwks.json"
316
+
304
317
  try:
305
318
  response = requests.get(jwks_url)
306
319
  response.raise_for_status()
@@ -6,7 +6,6 @@ from functools import wraps
6
6
  from .auth import Auth
7
7
  from cornflow.shared.exceptions import InvalidCredentials
8
8
  from flask import current_app
9
- import os
10
9
 
11
10
 
12
11
  def authenticate(
cornflow/shared/const.py CHANGED
@@ -2,7 +2,12 @@
2
2
  In this file we import the values for different constants on cornflow server
3
3
  """
4
4
 
5
- CORNFLOW_VERSION = "1.2.4"
5
+ # CORNFLOW BACKEND
6
+ AIRFLOW_BACKEND = 1
7
+ DATABRICKS_BACKEND = 2
8
+
9
+
10
+ CORNFLOW_VERSION = "1.3.0rc1"
6
11
  INTERNAL_TOKEN_ISSUER = "cornflow"
7
12
 
8
13
  # endpoints responses for health check
@@ -53,6 +58,24 @@ NO_SIGNUP = 0
53
58
  SIGNUP_WITH_NO_AUTH = 1
54
59
  SIGNUP_WITH_AUTH = 2
55
60
 
61
+ DATABRICKS_TO_STATE_MAP = dict(
62
+ BLOCKED=EXEC_STATE_QUEUED,
63
+ PENDING=EXEC_STATE_QUEUED,
64
+ QUEUED=EXEC_STATE_QUEUED,
65
+ RUNNING=EXEC_STATE_RUNNING,
66
+ TERMINATING=EXEC_STATE_RUNNING,
67
+ SUCCESS=EXEC_STATE_CORRECT,
68
+ USER_CANCELED=EXEC_STATE_STOPPED,
69
+ OTHER_FINISH_ERROR=EXEC_STATE_ERROR,
70
+ RUN_EXECUTION_ERROR=EXEC_STATE_ERROR,
71
+ )
72
+
73
+ DATABRICKS_FINISH_TO_STATE_MAP = dict(
74
+ SUCCESS=EXEC_STATE_CORRECT,
75
+ USER_CANCELED=EXEC_STATE_STOPPED,
76
+ )
77
+
78
+ DATABRICKS_TERMINATE_STATE = "TERMINATED"
56
79
  # These codes and names are inherited from flask app builder in order to have the same names and values
57
80
  # as this library that is the base of airflow
58
81
  AUTH_DB = 1
@@ -60,6 +83,11 @@ AUTH_LDAP = 2
60
83
  AUTH_OAUTH = 4
61
84
  AUTH_OID = 0
62
85
 
86
+ # OID possible providers
87
+ OID_PROVIDER_AWS = 0
88
+ OID_PROVIDER_AZURE = 1
89
+ OID_OTHER = 2
90
+
63
91
  GET_ACTION = 1
64
92
  PATCH_ACTION = 2
65
93
  POST_ACTION = 3
@@ -135,3 +163,18 @@ CONDITIONAL_ENDPOINTS = {
135
163
  "signup": "/signup/",
136
164
  "login": "/login/",
137
165
  }
166
+
167
+
168
+ # Orchestrator constants
169
+ config_orchestrator = {
170
+ "airflow": {
171
+ "name": "Airflow",
172
+ "def_schema": "solve_model_dag",
173
+ "run_id": "dag_run_id",
174
+ },
175
+ "databricks": {
176
+ "name": "Databricks",
177
+ "def_schema": "979073949072767",
178
+ "run_id": "run_id",
179
+ },
180
+ }
@@ -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
 
@@ -148,6 +148,7 @@ def initialize_errorhandlers(app):
148
148
  @app.errorhandler(InvalidCredentials)
149
149
  @app.errorhandler(EndpointNotImplemented)
150
150
  @app.errorhandler(AirflowError)
151
+ @app.errorhandler(DatabricksError)
151
152
  @app.errorhandler(InvalidData)
152
153
  @app.errorhandler(InvalidPatch)
153
154
  @app.errorhandler(ConfigurationError)