cornflow 1.1.1a1__tar.gz → 1.1.2__tar.gz
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-1.1.1a1 → cornflow-1.1.2}/MANIFEST.in +1 -2
- {cornflow-1.1.1a1/cornflow.egg-info → cornflow-1.1.2}/PKG-INFO +1 -1
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/app.py +0 -4
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/cli/utils.py +1 -1
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/config.py +2 -10
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/endpoints/__init__.py +0 -14
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/endpoints/execution.py +1 -1
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/endpoints/login.py +6 -26
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/models/__init__.py +0 -2
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/models/execution.py +0 -8
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/models/meta_models.py +12 -23
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/schemas/execution.py +0 -3
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/shared/const.py +0 -21
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/shared/exceptions.py +9 -20
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/const.py +0 -7
- cornflow-1.1.1a1/cornflow/tests/custom_live_server.py → cornflow-1.1.2/cornflow/tests/custom_liveServer.py +1 -3
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/custom_test_case.py +3 -2
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/integration/test_commands.py +1 -1
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/integration/test_cornflowclient.py +28 -116
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/unit/test_alarms.py +9 -22
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/unit/test_cli.py +5 -10
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/unit/test_commands.py +2 -6
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/unit/test_executions.py +0 -5
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/unit/test_main_alarms.py +0 -8
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/unit/test_users.py +2 -5
- {cornflow-1.1.1a1 → cornflow-1.1.2/cornflow.egg-info}/PKG-INFO +1 -1
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow.egg-info/SOURCES.txt +1 -8
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow.egg-info/requires.txt +6 -6
- {cornflow-1.1.1a1 → cornflow-1.1.2}/setup.py +1 -1
- cornflow-1.1.1a1/cornflow/endpoints/reports.py +0 -283
- cornflow-1.1.1a1/cornflow/migrations/versions/83164be03c23_.py +0 -40
- cornflow-1.1.1a1/cornflow/migrations/versions/96f00d0961d1_reports_table.py +0 -50
- cornflow-1.1.1a1/cornflow/models/reports.py +0 -119
- cornflow-1.1.1a1/cornflow/schemas/reports.py +0 -48
- cornflow-1.1.1a1/cornflow/static/v1.json +0 -3854
- cornflow-1.1.1a1/cornflow/tests/unit/test_reports.py +0 -308
- {cornflow-1.1.1a1 → cornflow-1.1.2}/README.rst +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/airflow_config/__init__.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/airflow_config/airflow_local_settings.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/airflow_config/plugins/XCom/__init__.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/airflow_config/plugins/XCom/gce_xcom_backend.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/airflow_config/plugins/__init__.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/airflow_config/webserver_ldap.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/__init__.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/cli/__init__.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/cli/actions.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/cli/arguments.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/cli/config.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/cli/migrations.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/cli/permissions.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/cli/roles.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/cli/schemas.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/cli/service.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/cli/tools/__init__.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/cli/tools/api_generator.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/cli/tools/endpoint_tools.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/cli/tools/models_tools.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/cli/tools/schema_generator.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/cli/tools/schemas_tools.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/cli/tools/tools.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/cli/users.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/cli/views.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/commands/__init__.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/commands/access.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/commands/actions.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/commands/cleanup.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/commands/dag.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/commands/permissions.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/commands/roles.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/commands/schemas.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/commands/users.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/commands/views.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/endpoints/action.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/endpoints/alarms.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/endpoints/apiview.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/endpoints/case.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/endpoints/dag.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/endpoints/data_check.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/endpoints/example_data.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/endpoints/health.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/endpoints/instance.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/endpoints/licenses.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/endpoints/main_alarms.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/endpoints/meta_resource.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/endpoints/permission.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/endpoints/roles.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/endpoints/schemas.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/endpoints/signup.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/endpoints/tables.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/endpoints/token.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/endpoints/user.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/endpoints/user_role.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/gunicorn.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/migrations/README +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/migrations/alembic.ini +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/migrations/env.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/migrations/script.py.mako +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/migrations/versions/00757b557b02_.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/migrations/versions/1af47a419bbd_.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/migrations/versions/4aac5e0c6e66_.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/migrations/versions/7c3ea5ab5501_.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/migrations/versions/991b98e24225_.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/migrations/versions/a472b5ad50b7_.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/migrations/versions/c2db9409cb5f_.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/migrations/versions/c8a6c762e818_.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/migrations/versions/ca449af8034c_.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/migrations/versions/d0e0700dcd8e_.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/migrations/versions/d1b5be1f0549_.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/migrations/versions/e1a50dae1ac9_.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/migrations/versions/e937a5234ce4_.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/migrations/versions/ebdd955fcc5e_.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/migrations/versions/f3bee20314a2_.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/models/action.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/models/alarms.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/models/base_data_model.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/models/case.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/models/dag.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/models/dag_permissions.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/models/instance.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/models/main_alarms.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/models/permissions.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/models/role.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/models/user.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/models/user_role.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/models/view.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/schemas/__init__.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/schemas/action.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/schemas/alarms.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/schemas/case.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/schemas/common.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/schemas/dag.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/schemas/example_data.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/schemas/health.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/schemas/instance.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/schemas/main_alarms.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/schemas/model_json.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/schemas/patch.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/schemas/permissions.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/schemas/query.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/schemas/role.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/schemas/schemas.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/schemas/solution_log.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/schemas/tables.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/schemas/user.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/schemas/user_role.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/schemas/view.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/shared/__init__.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/shared/authentication/__init__.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/shared/authentication/auth.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/shared/authentication/decorators.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/shared/authentication/ldap.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/shared/compress.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/shared/email.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/shared/licenses.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/shared/log_config.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/shared/query_tools.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/shared/utils.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/shared/utils_tables.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/shared/validators.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/__init__.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/integration/__init__.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/ldap/__init__.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/ldap/test_ldap_authentication.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/unit/__init__.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/unit/test_actions.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/unit/test_apiview.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/unit/test_cases.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/unit/test_dags.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/unit/test_data_checks.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/unit/test_example_data.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/unit/test_generate_from_schema.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/unit/test_health.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/unit/test_instances.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/unit/test_instances_file.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/unit/test_licenses.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/unit/test_log_in.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/unit/test_permissions.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/unit/test_roles.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/unit/test_schema_from_models.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/unit/test_schemas.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/unit/test_sign_up.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/unit/test_tables.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/unit/test_token.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow/tests/unit/tools.py +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow.egg-info/dependency_links.txt +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow.egg-info/entry_points.txt +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/cornflow.egg-info/top_level.txt +0 -0
- {cornflow-1.1.1a1 → cornflow-1.1.2}/setup.cfg +0 -0
@@ -46,9 +46,6 @@ def create_app(env_name="development", dataconn=None):
|
|
46
46
|
:return: the application that is going to be running :class:`Flask`
|
47
47
|
:rtype: :class:`Flask`
|
48
48
|
"""
|
49
|
-
if os.getenv("FLASK_ENV", None) is not None:
|
50
|
-
env_name = os.getenv("FLASK_ENV")
|
51
|
-
|
52
49
|
dictConfig(log_config(app_config[env_name].LOG_LEVEL))
|
53
50
|
|
54
51
|
app = Flask(__name__)
|
@@ -77,7 +74,6 @@ def create_app(env_name="development", dataconn=None):
|
|
77
74
|
api = Api(app)
|
78
75
|
for res in resources:
|
79
76
|
api.add_resource(res["resource"], res["urls"], endpoint=res["endpoint"])
|
80
|
-
|
81
77
|
if app.config["ALARMS_ENDPOINTS"]:
|
82
78
|
for res in alarms_resources:
|
83
79
|
api.add_resource(res["resource"], res["urls"], endpoint=res["endpoint"])
|
@@ -6,7 +6,7 @@ import warnings
|
|
6
6
|
|
7
7
|
def get_app():
|
8
8
|
env = os.getenv("FLASK_ENV", "development")
|
9
|
-
data_conn = os.getenv("DATABASE_URL")
|
9
|
+
data_conn = os.getenv("DATABASE_URL", "sqlite:///cornflow.db")
|
10
10
|
if env == "production":
|
11
11
|
warnings.filterwarnings("ignore")
|
12
12
|
external = int(os.getenv("EXTERNAL_APP", 0))
|
@@ -22,14 +22,6 @@ class DefaultConfig(object):
|
|
22
22
|
SIGNUP_ACTIVATED = int(os.getenv("SIGNUP_ACTIVATED", 1))
|
23
23
|
CORNFLOW_SERVICE_USER = os.getenv("CORNFLOW_SERVICE_USER", "service_user")
|
24
24
|
|
25
|
-
# file support for reports
|
26
|
-
FILE_BACKEND = os.getenv("FILE_BACKEND", "local")
|
27
|
-
UPLOAD_FOLDER = os.getenv(
|
28
|
-
"UPLOAD_FOLDER",
|
29
|
-
os.path.abspath(os.path.join(os.path.dirname(__file__), "./static")),
|
30
|
-
)
|
31
|
-
ALLOWED_EXTENSIONS = os.getenv("ALLOWED_EXTENSIONS", ["pdf", "html"])
|
32
|
-
|
33
25
|
# Open deployment (all dags accessible to all users)
|
34
26
|
OPEN_DEPLOYMENT = os.getenv("OPEN_DEPLOYMENT", 1)
|
35
27
|
|
@@ -92,6 +84,7 @@ class DefaultConfig(object):
|
|
92
84
|
|
93
85
|
|
94
86
|
class Development(DefaultConfig):
|
87
|
+
|
95
88
|
""" """
|
96
89
|
|
97
90
|
ENV = "development"
|
@@ -102,7 +95,7 @@ class Testing(DefaultConfig):
|
|
102
95
|
|
103
96
|
ENV = "testing"
|
104
97
|
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
105
|
-
DEBUG =
|
98
|
+
DEBUG = False
|
106
99
|
TESTING = True
|
107
100
|
PROPAGATE_EXCEPTIONS = True
|
108
101
|
SECRET_TOKEN_KEY = "TESTINGSECRETKEY"
|
@@ -126,7 +119,6 @@ class Production(DefaultConfig):
|
|
126
119
|
# needs to be on to avoid getting only 500 codes:
|
127
120
|
# and https://medium.com/@johanesriandy/flask-error-handler-not-working-on-production-mode-3adca4c7385c
|
128
121
|
PROPAGATE_EXCEPTIONS = True
|
129
|
-
UPLOAD_FOLDER = os.getenv("UPLOAD_FOLDER", "/usr/src/app/static")
|
130
122
|
|
131
123
|
|
132
124
|
app_config = {"development": Development, "testing": Testing, "production": Production}
|
@@ -37,8 +37,6 @@ from .execution import (
|
|
37
37
|
ExecutionLogEndpoint,
|
38
38
|
ExecutionRelaunchEndpoint,
|
39
39
|
)
|
40
|
-
|
41
|
-
from .reports import ReportEndpoint, ReportDetailsEndpoint, ReportDetailsEditEndpoint
|
42
40
|
from .health import HealthEndpoint
|
43
41
|
from .instance import (
|
44
42
|
InstanceEndpoint,
|
@@ -49,7 +47,6 @@ from .instance import (
|
|
49
47
|
from .licenses import LicensesEndpoint
|
50
48
|
from .main_alarms import MainAlarmsEndpoint
|
51
49
|
from .permission import PermissionsViewRoleEndpoint, PermissionsViewRoleDetailEndpoint
|
52
|
-
from .reports import ReportEndpoint, ReportDetailsEndpoint
|
53
50
|
from .roles import RolesListEndpoint, RoleDetailEndpoint
|
54
51
|
from .schemas import SchemaDetailsEndpoint, SchemaEndpoint
|
55
52
|
from .tables import TablesEndpoint, TablesDetailsEndpoint
|
@@ -219,17 +216,6 @@ resources = [
|
|
219
216
|
urls="/table/<string:table_name>/<string:idx>/",
|
220
217
|
endpoint="tables-detail",
|
221
218
|
),
|
222
|
-
dict(
|
223
|
-
resource=ReportDetailsEndpoint,
|
224
|
-
urls="/report/<int:idx>/",
|
225
|
-
endpoint="report-detail",
|
226
|
-
),
|
227
|
-
dict(
|
228
|
-
resource=ReportDetailsEditEndpoint,
|
229
|
-
urls="/report/<int:idx>/edit/",
|
230
|
-
endpoint="report-detail-edit",
|
231
|
-
),
|
232
|
-
dict(resource=ReportEndpoint, urls="/report/", endpoint="report"),
|
233
219
|
]
|
234
220
|
|
235
221
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
"""
|
2
2
|
External endpoints to manage the executions: create new ones, list all of them, get one in particular
|
3
3
|
or check the status of an ongoing one
|
4
|
-
These endpoints
|
4
|
+
These endpoints hve different access url, but manage the same data entities
|
5
5
|
"""
|
6
6
|
|
7
7
|
# Import from libraries
|
@@ -34,7 +34,6 @@ class LoginBaseEndpoint(BaseMetaResource):
|
|
34
34
|
"""
|
35
35
|
Base endpoint to perform a login action from a user
|
36
36
|
"""
|
37
|
-
|
38
37
|
def __init__(self):
|
39
38
|
super().__init__()
|
40
39
|
self.ldap_class = LDAPBase
|
@@ -64,7 +63,6 @@ class LoginBaseEndpoint(BaseMetaResource):
|
|
64
63
|
try:
|
65
64
|
token = self.auth_class.generate_token(user.id)
|
66
65
|
except Exception as e:
|
67
|
-
current_app.logger.error(f"Error in generating user token: {str(e)}")
|
68
66
|
raise InvalidUsage(f"Error in generating user token: {str(e)}", 400)
|
69
67
|
|
70
68
|
response.update({"token": token, "id": user.id})
|
@@ -83,11 +81,9 @@ class LoginBaseEndpoint(BaseMetaResource):
|
|
83
81
|
user = self.data_model.get_one_object(username=username)
|
84
82
|
|
85
83
|
if not user:
|
86
|
-
current_app.logger.error(f"Error on login user does not exist")
|
87
84
|
raise InvalidCredentials()
|
88
85
|
|
89
86
|
if not user.check_hash(password):
|
90
|
-
current_app.logger.error(f"Error on login invalid credentials")
|
91
87
|
raise InvalidCredentials()
|
92
88
|
|
93
89
|
return user
|
@@ -106,9 +102,7 @@ class LoginBaseEndpoint(BaseMetaResource):
|
|
106
102
|
raise InvalidCredentials()
|
107
103
|
user = self.data_model.get_one_object(username=username)
|
108
104
|
if not user:
|
109
|
-
current_app.logger.info(
|
110
|
-
f"LDAP user {username} does not exist and is created"
|
111
|
-
)
|
105
|
+
current_app.logger.info(f"LDAP user {username} does not exist and is created")
|
112
106
|
email = ldap_obj.get_user_email(username)
|
113
107
|
if not email:
|
114
108
|
email = ""
|
@@ -128,14 +122,10 @@ class LoginBaseEndpoint(BaseMetaResource):
|
|
128
122
|
|
129
123
|
except IntegrityError as e:
|
130
124
|
db.session.rollback()
|
131
|
-
current_app.logger.error(
|
132
|
-
f"Integrity error on user role assignment on log in: {e}"
|
133
|
-
)
|
125
|
+
current_app.logger.error(f"Integrity error on user role assignment on log in: {e}")
|
134
126
|
except DBAPIError as e:
|
135
127
|
db.session.rollback()
|
136
|
-
current_app.logger.error(
|
137
|
-
f"Unknown error on user role assignment on log in: {e}"
|
138
|
-
)
|
128
|
+
current_app.logger.error(f"Unknown error on user role assignment on log in: {e}")
|
139
129
|
|
140
130
|
return user
|
141
131
|
|
@@ -173,9 +163,7 @@ class LoginBaseEndpoint(BaseMetaResource):
|
|
173
163
|
user = self.data_model.get_one_object(username=username)
|
174
164
|
|
175
165
|
if not user:
|
176
|
-
current_app.logger.info(
|
177
|
-
f"OpenID user {username} does not exist and is created"
|
178
|
-
)
|
166
|
+
current_app.logger.info(f"OpenID user {username} does not exist and is created")
|
179
167
|
|
180
168
|
data = {"username": username, "email": username}
|
181
169
|
|
@@ -195,11 +183,7 @@ class LoginBaseEndpoint(BaseMetaResource):
|
|
195
183
|
|
196
184
|
def check_last_password_change(user):
|
197
185
|
if user.pwd_last_change:
|
198
|
-
if (
|
199
|
-
user.pwd_last_change
|
200
|
-
+ timedelta(days=int(current_app.config["PWD_ROTATION_TIME"]))
|
201
|
-
< datetime.utcnow()
|
202
|
-
):
|
186
|
+
if user.pwd_last_change + timedelta(days=int(current_app.config["PWD_ROTATION_TIME"])) < datetime.utcnow():
|
203
187
|
return True
|
204
188
|
return False
|
205
189
|
|
@@ -226,11 +210,7 @@ class LoginEndpoint(LoginBaseEndpoint):
|
|
226
210
|
:rtype: Tuple(dict, integer)
|
227
211
|
"""
|
228
212
|
|
229
|
-
|
230
|
-
return self.log_in(**kwargs)
|
231
|
-
except Exception as e:
|
232
|
-
current_app.logger.error(f"Final exception: {str(e)}")
|
233
|
-
raise e
|
213
|
+
return self.log_in(**kwargs)
|
234
214
|
|
235
215
|
|
236
216
|
class LoginOpenAuthEndpoint(LoginBaseEndpoint):
|
@@ -1,7 +1,6 @@
|
|
1
1
|
"""
|
2
2
|
Initialization file for the models module
|
3
3
|
"""
|
4
|
-
|
5
4
|
from .action import ActionModel
|
6
5
|
from .alarms import AlarmsModel
|
7
6
|
from .case import CaseModel
|
@@ -15,4 +14,3 @@ from .role import RoleModel
|
|
15
14
|
from .user import UserModel
|
16
15
|
from .user_role import UserRoleModel
|
17
16
|
from .view import ViewModel
|
18
|
-
from .reports import ReportModel
|
@@ -64,14 +64,6 @@ class ExecutionModel(BaseDataModel):
|
|
64
64
|
default=EXECUTION_STATE_MESSAGE_DICT[DEFAULT_EXECUTION_CODE],
|
65
65
|
nullable=True,
|
66
66
|
)
|
67
|
-
reports = db.relationship(
|
68
|
-
"ReportModel",
|
69
|
-
backref="executions",
|
70
|
-
lazy=True,
|
71
|
-
primaryjoin="and_(ExecutionModel.id==ReportModel.execution_id, "
|
72
|
-
"ReportModel.deleted_at==None)",
|
73
|
-
cascade="all,delete",
|
74
|
-
)
|
75
67
|
|
76
68
|
def __init__(self, data):
|
77
69
|
super().__init__(data)
|
@@ -33,29 +33,17 @@ class EmptyBaseModel(db.Model):
|
|
33
33
|
|
34
34
|
try:
|
35
35
|
db.session.commit()
|
36
|
-
current_app.logger.debug(
|
37
|
-
f"Transaction type: {action}, performed correctly on {self}"
|
38
|
-
)
|
39
|
-
|
36
|
+
current_app.logger.debug(f"Transaction type: {action}, performed correctly on {self}")
|
40
37
|
except IntegrityError as err:
|
41
38
|
db.session.rollback()
|
42
39
|
current_app.logger.error(f"Integrity error on {action} data: {err}")
|
43
40
|
current_app.logger.error(f"Data: {self.__dict__}")
|
44
|
-
|
45
|
-
if "FOREIGN KEY" in str(err):
|
46
|
-
message = f"Foreign key constraint error while {action} on {self.__class__.__tablename__} table"
|
47
|
-
raise InvalidData(message)
|
48
|
-
else:
|
49
|
-
raise InvalidData(f"Integrity error on {action} with data {self}")
|
50
|
-
|
41
|
+
raise InvalidData(f"Integrity error on {action} with data {self}")
|
51
42
|
except DBAPIError as err:
|
52
43
|
db.session.rollback()
|
53
|
-
current_app.logger.error(
|
54
|
-
f"Unknown database error on {action} data: {type(err)}"
|
55
|
-
)
|
44
|
+
current_app.logger.error(f"Unknown database error on {action} data: {err}")
|
56
45
|
current_app.logger.error(f"Data: {self.__dict__}")
|
57
46
|
raise InvalidData(f"Unknown database error on {action} with data {self}")
|
58
|
-
|
59
47
|
except Exception as err:
|
60
48
|
db.session.rollback()
|
61
49
|
current_app.logger.error(f"Unknown error on {action} data: {err}")
|
@@ -111,9 +99,7 @@ class EmptyBaseModel(db.Model):
|
|
111
99
|
action = "bulk create"
|
112
100
|
try:
|
113
101
|
db.session.commit()
|
114
|
-
current_app.logger.debug(
|
115
|
-
f"Transaction type: {action}, performed correctly on {cls}"
|
116
|
-
)
|
102
|
+
current_app.logger.debug(f"Transaction type: {action}, performed correctly on {cls}")
|
117
103
|
except IntegrityError as err:
|
118
104
|
db.session.rollback()
|
119
105
|
current_app.logger.error(f"Integrity error on {action} data: {err}")
|
@@ -134,9 +120,7 @@ class EmptyBaseModel(db.Model):
|
|
134
120
|
action = "bulk create update"
|
135
121
|
try:
|
136
122
|
db.session.commit()
|
137
|
-
current_app.logger.debug(
|
138
|
-
f"Transaction type: {action}, performed correctly on {cls}"
|
139
|
-
)
|
123
|
+
current_app.logger.debug(f"Transaction type: {action}, performed correctly on {cls}")
|
140
124
|
except IntegrityError as err:
|
141
125
|
db.session.rollback()
|
142
126
|
current_app.logger.error(f"Integrity error on {action} data: {err}")
|
@@ -152,7 +136,12 @@ class EmptyBaseModel(db.Model):
|
|
152
136
|
return instances
|
153
137
|
|
154
138
|
@classmethod
|
155
|
-
def get_all_objects(
|
139
|
+
def get_all_objects(
|
140
|
+
cls,
|
141
|
+
offset=0,
|
142
|
+
limit=None,
|
143
|
+
**kwargs
|
144
|
+
):
|
156
145
|
"""
|
157
146
|
Method to get all the objects from the database applying the filters passed as keyword arguments
|
158
147
|
|
@@ -272,7 +261,7 @@ class TraceAttributesModel(EmptyBaseModel):
|
|
272
261
|
update_date_lte=None,
|
273
262
|
offset=0,
|
274
263
|
limit=None,
|
275
|
-
**kwargs
|
264
|
+
**kwargs
|
276
265
|
):
|
277
266
|
"""
|
278
267
|
Method to get all the objects from the database applying the filters passed as keyword arguments
|
@@ -5,7 +5,6 @@ from marshmallow import fields, Schema, validate
|
|
5
5
|
from cornflow.shared.const import MIN_EXECUTION_STATUS_CODE, MAX_EXECUTION_STATUS_CODE
|
6
6
|
from .common import QueryFilters, BaseDataEndpointResponse
|
7
7
|
from .solution_log import LogSchema, BasicLogSchema
|
8
|
-
from .reports import ReportSchemaBase
|
9
8
|
|
10
9
|
|
11
10
|
class QueryFiltersExecution(QueryFilters):
|
@@ -31,7 +30,6 @@ class ConfigSchema(Schema):
|
|
31
30
|
threads = fields.Int(required=False)
|
32
31
|
logPath = fields.Str(required=False)
|
33
32
|
MIPGap = fields.Float(required=False)
|
34
|
-
report = fields.Raw(required=False)
|
35
33
|
|
36
34
|
|
37
35
|
class ConfigSchemaResponse(ConfigSchema):
|
@@ -97,7 +95,6 @@ class ExecutionDagPostRequest(ExecutionRequest, ExecutionDagRequest):
|
|
97
95
|
|
98
96
|
|
99
97
|
class ExecutionDetailsEndpointResponse(BaseDataEndpointResponse):
|
100
|
-
reports = fields.Nested(ReportSchemaBase, many=True)
|
101
98
|
config = fields.Nested(ConfigSchemaResponse)
|
102
99
|
instance_id = fields.Str()
|
103
100
|
state = fields.Int()
|
@@ -43,25 +43,6 @@ AIRFLOW_TO_STATE_MAP = dict(
|
|
43
43
|
queued=EXEC_STATE_QUEUED,
|
44
44
|
)
|
45
45
|
|
46
|
-
# Reports codes
|
47
|
-
|
48
|
-
|
49
|
-
class REPORT_STATE:
|
50
|
-
RUNNING = 0
|
51
|
-
CORRECT = 1
|
52
|
-
ERROR = -1
|
53
|
-
UNKNOWN = -5
|
54
|
-
ERROR_NO_QUARTO = -10
|
55
|
-
|
56
|
-
|
57
|
-
REPORT_STATE_MSG = {
|
58
|
-
REPORT_STATE.RUNNING: "The report is currently running.",
|
59
|
-
REPORT_STATE.CORRECT: "The report has been solved correctly.",
|
60
|
-
REPORT_STATE.ERROR: "The report has an error.",
|
61
|
-
REPORT_STATE.UNKNOWN: "The report has an unknown error.",
|
62
|
-
REPORT_STATE.ERROR_NO_QUARTO: "The report failed because Quarto was not found.",
|
63
|
-
}
|
64
|
-
|
65
46
|
# These codes and names are inherited from flask app builder in order to have the same names and values
|
66
47
|
# as this library that is the base of airflow
|
67
48
|
AUTH_DB = 1
|
@@ -141,6 +122,4 @@ BASE_PERMISSION_ASSIGNATION = [
|
|
141
122
|
|
142
123
|
EXTRA_PERMISSION_ASSIGNATION = [
|
143
124
|
(VIEWER_ROLE, PUT_ACTION, "user-detail"),
|
144
|
-
(VIEWER_ROLE, GET_ACTION, "report"),
|
145
|
-
(PLANNER_ROLE, GET_ACTION, "report"),
|
146
125
|
]
|
@@ -21,10 +21,7 @@ class InvalidUsage(Exception):
|
|
21
21
|
def __init__(self, error=None, status_code=None, payload=None, log_txt=None):
|
22
22
|
Exception.__init__(self, error)
|
23
23
|
if error is not None:
|
24
|
-
|
25
|
-
self.error = str(error)
|
26
|
-
else:
|
27
|
-
self.error = error
|
24
|
+
self.error = error
|
28
25
|
if status_code is not None:
|
29
26
|
self.status_code = status_code
|
30
27
|
self.payload = payload
|
@@ -125,21 +122,10 @@ class ConfigurationError(InvalidUsage):
|
|
125
122
|
error = "No authentication method configured on the server"
|
126
123
|
|
127
124
|
|
128
|
-
class FileError(InvalidUsage):
|
129
|
-
"""
|
130
|
-
Exception used when there is an error regarding the upload of a file to the server
|
131
|
-
"""
|
132
|
-
|
133
|
-
status_code = 400
|
134
|
-
error = "Error uploading the file"
|
135
|
-
|
136
|
-
|
137
125
|
INTERNAL_SERVER_ERROR_MESSAGE = "500 Internal Server Error"
|
138
|
-
INTERNAL_SERVER_ERROR_MESSAGE_DETAIL =
|
139
|
-
|
140
|
-
|
141
|
-
"there is an error in the application."
|
142
|
-
)
|
126
|
+
INTERNAL_SERVER_ERROR_MESSAGE_DETAIL = "The server encountered an internal error and was unable " \
|
127
|
+
"to complete your request. Either the server is overloaded or " \
|
128
|
+
"there is an error in the application."
|
143
129
|
|
144
130
|
|
145
131
|
def initialize_errorhandlers(app):
|
@@ -201,7 +187,10 @@ def initialize_errorhandlers(app):
|
|
201
187
|
status_code = error.code or status_code
|
202
188
|
error_msg = f"{status_code} {error.name or INTERNAL_SERVER_ERROR_MESSAGE}"
|
203
189
|
error_str = f"{error_msg}. {str(error.description or '') or INTERNAL_SERVER_ERROR_MESSAGE_DETAIL}"
|
204
|
-
response_dict = {
|
190
|
+
response_dict = {
|
191
|
+
"message": error_msg,
|
192
|
+
"error": error_str
|
193
|
+
}
|
205
194
|
response = jsonify(response_dict)
|
206
195
|
|
207
196
|
elif app.config["ENV"] == "production":
|
@@ -213,7 +202,7 @@ def initialize_errorhandlers(app):
|
|
213
202
|
|
214
203
|
response_dict = {
|
215
204
|
"message": INTERNAL_SERVER_ERROR_MESSAGE,
|
216
|
-
"error": INTERNAL_SERVER_ERROR_MESSAGE_DETAIL
|
205
|
+
"error": INTERNAL_SERVER_ERROR_MESSAGE_DETAIL
|
217
206
|
}
|
218
207
|
response = jsonify(response_dict)
|
219
208
|
else:
|
@@ -14,7 +14,6 @@ INSTANCE_URL = PREFIX + "/instance/"
|
|
14
14
|
INSTANCE_MPS = _get_file("./data/test_mps.mps")
|
15
15
|
INSTANCE_GC_20 = _get_file("./data/gc_20_7.json")
|
16
16
|
INSTANCE_FILE_FAIL = _get_file("./unit/test_instances.py")
|
17
|
-
INSTANCE_TSP = _get_file("./data/tsp_instance.json")
|
18
17
|
|
19
18
|
EXECUTION_PATH = _get_file("./data/new_execution.json")
|
20
19
|
BAD_EXECUTION_PATH = _get_file("./data/bad_execution.json")
|
@@ -35,12 +34,6 @@ CASE_INSTANCE_URL = PREFIX + "/case/instance/"
|
|
35
34
|
FULL_CASE_PATH = _get_file("./data/full_case_raw.json")
|
36
35
|
FULL_CASE_LIST = [FULL_CASE_PATH, _get_file("./data/full_case_raw_2.json")]
|
37
36
|
|
38
|
-
REPORT_PATH = _get_file("./data/new_report.json")
|
39
|
-
REPORT_HTML_FILE_PATH = _get_file("./data/new_report.html")
|
40
|
-
REPORT_PDF_FILE_PATH = _get_file("./data/new_report_2.pdf")
|
41
|
-
BAD_REPORT_PATH = _get_file("./data/bad_report.json")
|
42
|
-
REPORT_URL = PREFIX + "/report/"
|
43
|
-
|
44
37
|
JSON_PATCH_GOOD_PATH = _get_file("./data/json_patch_good.json")
|
45
38
|
JSON_PATCH_BAD_PATH = _get_file("./data/json_patch_bad.json")
|
46
39
|
FULL_CASE_JSON_PATCH_1 = _get_file("./data/full_case_patch.json")
|
@@ -39,9 +39,7 @@ class CustomTestCaseLive(LiveServerTestCase):
|
|
39
39
|
if create_all:
|
40
40
|
db.create_all()
|
41
41
|
access_init_command(False)
|
42
|
-
register_deployed_dags_command_test(
|
43
|
-
verbose=False, dags=["solve_model_dag", "gc", "timer", "tsp"]
|
44
|
-
)
|
42
|
+
register_deployed_dags_command_test(verbose=False)
|
45
43
|
user_data = dict(
|
46
44
|
username="testname",
|
47
45
|
email="test@test.com",
|
@@ -90,8 +90,8 @@ class CustomTestCase(TestCase):
|
|
90
90
|
self.roles_with_access = []
|
91
91
|
|
92
92
|
@staticmethod
|
93
|
-
def get_header_with_auth(token
|
94
|
-
return {"Content-Type":
|
93
|
+
def get_header_with_auth(token):
|
94
|
+
return {"Content-Type": "application/json", "Authorization": "Bearer " + token}
|
95
95
|
|
96
96
|
def create_user(self, data):
|
97
97
|
return self.client.post(
|
@@ -169,6 +169,7 @@ class CustomTestCase(TestCase):
|
|
169
169
|
self.assertEqual(row.id, response.json["id"])
|
170
170
|
|
171
171
|
for key in self.get_keys_to_check(payload):
|
172
|
+
getattr(row, key)
|
172
173
|
if key in payload:
|
173
174
|
self.assertEqual(getattr(row, key), payload[key])
|
174
175
|
return row.id
|
@@ -3,7 +3,7 @@ from flask import current_app
|
|
3
3
|
from cornflow.commands.dag import register_deployed_dags_command
|
4
4
|
from cornflow.models import DeployedDAG
|
5
5
|
from cornflow.tests.const import PUBLIC_DAGS
|
6
|
-
from cornflow.tests.
|
6
|
+
from cornflow.tests.custom_liveServer import CustomTestCaseLive
|
7
7
|
|
8
8
|
|
9
9
|
class TestCornflowCommands(CustomTestCaseLive):
|