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.
- cornflow/cli/service.py +91 -42
- cornflow/commands/dag.py +7 -7
- cornflow/commands/permissions.py +9 -5
- cornflow/config.py +23 -3
- cornflow/endpoints/case.py +37 -21
- cornflow/endpoints/dag.py +5 -5
- cornflow/endpoints/data_check.py +8 -7
- cornflow/endpoints/example_data.py +4 -2
- cornflow/endpoints/execution.py +215 -127
- cornflow/endpoints/health.py +30 -11
- cornflow/endpoints/instance.py +3 -3
- cornflow/endpoints/login.py +9 -2
- cornflow/endpoints/schemas.py +3 -3
- cornflow/migrations/versions/999b98e24225.py +34 -0
- cornflow/migrations/versions/cef1df240b27_.py +34 -0
- cornflow/models/__init__.py +2 -1
- cornflow/models/dag.py +8 -9
- cornflow/models/dag_permissions.py +3 -3
- cornflow/models/execution.py +2 -3
- cornflow/models/permissions.py +1 -0
- cornflow/models/user.py +1 -1
- cornflow/schemas/execution.py +14 -1
- cornflow/schemas/health.py +1 -1
- cornflow/shared/authentication/auth.py +14 -1
- cornflow/shared/authentication/decorators.py +0 -1
- cornflow/shared/const.py +44 -1
- cornflow/shared/exceptions.py +2 -1
- cornflow/tests/base_test_execution.py +798 -0
- cornflow/tests/const.py +1 -0
- cornflow/tests/integration/test_commands.py +2 -2
- cornflow/tests/integration/test_cornflowclient.py +2 -1
- cornflow/tests/unit/test_cases.py +1 -1
- cornflow/tests/unit/test_commands.py +5 -5
- cornflow/tests/unit/test_dags.py +3 -3
- cornflow/tests/unit/test_example_data.py +1 -1
- cornflow/tests/unit/test_executions.py +115 -535
- cornflow/tests/unit/test_health.py +84 -3
- cornflow/tests/unit/test_main_alarms.py +1 -1
- cornflow/tests/unit/test_roles.py +2 -1
- cornflow/tests/unit/test_schema_from_models.py +1 -1
- cornflow/tests/unit/test_schemas.py +1 -1
- cornflow/tests/unit/tools.py +93 -10
- {cornflow-1.2.4.dist-info → cornflow-1.3.0rc1.dist-info}/METADATA +2 -2
- {cornflow-1.2.4.dist-info → cornflow-1.3.0rc1.dist-info}/RECORD +47 -44
- {cornflow-1.2.4.dist-info → cornflow-1.3.0rc1.dist-info}/WHEEL +0 -0
- {cornflow-1.2.4.dist-info → cornflow-1.3.0rc1.dist-info}/entry_points.txt +0 -0
- {cornflow-1.2.4.dist-info → cornflow-1.3.0rc1.dist-info}/top_level.txt +0 -0
cornflow/endpoints/health.py
CHANGED
@@ -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
|
-
|
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},
|
50
|
+
f"Health check: cornflow {cornflow_status}, backend {backend_status}"
|
44
51
|
)
|
45
|
-
return {"cornflow_status": cornflow_status, "
|
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
|
cornflow/endpoints/instance.py
CHANGED
@@ -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,
|
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 =
|
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 =
|
169
|
+
instance_schema = DeployedWorkflow.get_one_schema(
|
170
170
|
config, schema, INSTANCE_SCHEMA
|
171
171
|
)
|
172
172
|
instance_errors = json_schema_validate_as_string(
|
cornflow/endpoints/login.py
CHANGED
@@ -188,8 +188,15 @@ class LoginBaseEndpoint(BaseMetaResource):
|
|
188
188
|
)
|
189
189
|
|
190
190
|
email = decoded_token.get("email", f"{username}@cornflow.org")
|
191
|
-
|
192
|
-
|
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,
|
cornflow/endpoints/schemas.py
CHANGED
@@ -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,
|
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 =
|
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 ###
|
cornflow/models/__init__.py
CHANGED
@@ -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
|
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
|
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__ = "
|
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="
|
38
|
-
primaryjoin="and_(
|
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 =
|
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
|
-
|
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
|
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("
|
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 =
|
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
|
]
|
cornflow/models/execution.py
CHANGED
@@ -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
|
-
|
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")
|
cornflow/models/permissions.py
CHANGED
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
|
8
|
+
from datetime import datetime, timezone
|
9
9
|
|
10
10
|
# Imports from internal modules
|
11
11
|
from cornflow.models.meta_models import TraceAttributesModel
|
cornflow/schemas/execution.py
CHANGED
@@ -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
|
-
|
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(
|
cornflow/schemas/health.py
CHANGED
@@ -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
|
-
|
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()
|
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
|
-
|
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
|
+
}
|
cornflow/shared/exceptions.py
CHANGED
@@ -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)
|