cornflow 2.0.0a10__tar.gz → 2.0.0a12__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-2.0.0a10/cornflow.egg-info → cornflow-2.0.0a12}/PKG-INFO +16 -15
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/README.rst +9 -9
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/airflow_config/airflow_local_settings.py +1 -1
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/app.py +8 -3
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/cli/migrations.py +23 -3
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/cli/service.py +18 -18
- cornflow-2.0.0a12/cornflow/cli/utils.py +41 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/commands/dag.py +1 -1
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/config.py +13 -8
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/endpoints/__init__.py +8 -2
- cornflow-2.0.0a12/cornflow/endpoints/alarms.py +123 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/endpoints/data_check.py +53 -26
- cornflow-2.0.0a10/cornflow/endpoints/execution_databricks.py → cornflow-2.0.0a12/cornflow/endpoints/execution.py +259 -139
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/endpoints/login.py +81 -63
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/endpoints/meta_resource.py +11 -3
- cornflow-2.0.0a12/cornflow/migrations/versions/999b98e24225.py +34 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/models/base_data_model.py +4 -32
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/models/execution.py +2 -3
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/models/meta_models.py +28 -22
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/models/user.py +7 -10
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/schemas/alarms.py +8 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/schemas/execution.py +1 -1
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/schemas/query.py +2 -1
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/schemas/user.py +5 -20
- cornflow-2.0.0a12/cornflow/shared/authentication/auth.py +458 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/shared/const.py +3 -14
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/shared/databricks.py +5 -1
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/const.py +1 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/custom_test_case.py +77 -26
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/unit/test_actions.py +2 -2
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/unit/test_alarms.py +55 -1
- cornflow-2.0.0a12/cornflow/tests/unit/test_apiview.py +209 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/unit/test_cases.py +20 -29
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/unit/test_cli.py +6 -5
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/unit/test_commands.py +3 -3
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/unit/test_dags.py +5 -6
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/unit/test_executions.py +443 -123
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/unit/test_instances.py +14 -2
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/unit/test_instances_file.py +1 -1
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/unit/test_licenses.py +1 -1
- cornflow-2.0.0a12/cornflow/tests/unit/test_log_in.py +534 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/unit/test_permissions.py +8 -8
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/unit/test_roles.py +48 -10
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/unit/test_schemas.py +1 -1
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/unit/test_tables.py +7 -7
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/unit/test_token.py +19 -5
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/unit/test_users.py +22 -6
- cornflow-2.0.0a12/cornflow/tests/unit/tools.py +78 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12/cornflow.egg-info}/PKG-INFO +16 -15
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow.egg-info/SOURCES.txt +1 -1
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow.egg-info/requires.txt +4 -3
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/requirements.txt +4 -3
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/setup.py +2 -2
- cornflow-2.0.0a10/cornflow/cli/utils.py +0 -26
- cornflow-2.0.0a10/cornflow/endpoints/alarms.py +0 -59
- cornflow-2.0.0a10/cornflow/endpoints/execution.py +0 -673
- cornflow-2.0.0a10/cornflow/shared/authentication/auth.py +0 -521
- cornflow-2.0.0a10/cornflow/tests/unit/test_apiview.py +0 -104
- cornflow-2.0.0a10/cornflow/tests/unit/test_log_in.py +0 -511
- cornflow-2.0.0a10/cornflow/tests/unit/tools.py +0 -13
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/MANIFEST.in +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/airflow_config/__init__.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/airflow_config/plugins/XCom/__init__.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/airflow_config/plugins/XCom/gce_xcom_backend.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/airflow_config/plugins/__init__.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/airflow_config/webserver_ldap.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/__init__.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/cli/__init__.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/cli/actions.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/cli/arguments.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/cli/config.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/cli/permissions.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/cli/roles.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/cli/schemas.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/cli/tools/__init__.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/cli/tools/api_generator.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/cli/tools/endpoint_tools.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/cli/tools/models_tools.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/cli/tools/schema_generator.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/cli/tools/schemas_tools.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/cli/tools/tools.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/cli/users.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/cli/views.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/commands/__init__.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/commands/access.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/commands/actions.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/commands/cleanup.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/commands/permissions.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/commands/roles.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/commands/schemas.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/commands/users.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/commands/views.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/endpoints/action.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/endpoints/apiview.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/endpoints/case.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/endpoints/dag.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/endpoints/example_data.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/endpoints/health.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/endpoints/instance.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/endpoints/licenses.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/endpoints/main_alarms.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/endpoints/permission.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/endpoints/roles.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/endpoints/schemas.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/endpoints/signup.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/endpoints/tables.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/endpoints/token.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/endpoints/user.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/endpoints/user_role.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/gunicorn.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/migrations/README +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/migrations/alembic.ini +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/migrations/env.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/migrations/script.py.mako +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/migrations/versions/00757b557b02_.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/migrations/versions/1af47a419bbd_.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/migrations/versions/4aac5e0c6e66_.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/migrations/versions/7c3ea5ab5501_.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/migrations/versions/991b98e24225_.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/migrations/versions/a472b5ad50b7_.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/migrations/versions/c2db9409cb5f_.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/migrations/versions/c8a6c762e818_.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/migrations/versions/ca449af8034c_.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/migrations/versions/d0e0700dcd8e_.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/migrations/versions/d1b5be1f0549_.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/migrations/versions/e1a50dae1ac9_.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/migrations/versions/e937a5234ce4_.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/migrations/versions/ebdd955fcc5e_.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/migrations/versions/f3bee20314a2_.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/models/__init__.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/models/action.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/models/alarms.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/models/case.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/models/dag.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/models/dag_permissions.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/models/instance.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/models/main_alarms.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/models/permissions.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/models/role.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/models/user_role.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/models/view.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/orchestrator_constants.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/schemas/__init__.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/schemas/action.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/schemas/case.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/schemas/common.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/schemas/dag.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/schemas/example_data.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/schemas/health.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/schemas/instance.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/schemas/main_alarms.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/schemas/model_json.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/schemas/patch.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/schemas/permissions.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/schemas/role.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/schemas/schemas.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/schemas/solution_log.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/schemas/tables.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/schemas/user_role.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/schemas/view.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/shared/__init__.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/shared/authentication/__init__.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/shared/authentication/decorators.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/shared/authentication/ldap.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/shared/compress.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/shared/email.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/shared/exceptions.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/shared/licenses.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/shared/log_config.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/shared/query_tools.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/shared/utils.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/shared/utils_tables.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/shared/validators.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/__init__.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/custom_liveServer.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/integration/__init__.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/integration/test_commands.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/integration/test_cornflowclient.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/ldap/__init__.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/ldap/test_ldap_authentication.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/unit/__init__.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/unit/test_application.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/unit/test_data_checks.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/unit/test_example_data.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/unit/test_generate_from_schema.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/unit/test_health.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/unit/test_main_alarms.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/unit/test_schema_from_models.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow/tests/unit/test_sign_up.py +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow.egg-info/dependency_links.txt +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow.egg-info/entry_points.txt +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/cornflow.egg-info/top_level.txt +0 -0
- {cornflow-2.0.0a10 → cornflow-2.0.0a12}/setup.cfg +0 -0
@@ -1,7 +1,7 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: cornflow
|
3
|
-
Version: 2.0.
|
4
|
-
Summary:
|
3
|
+
Version: 2.0.0a12
|
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
|
7
7
|
Author-email: cornflow@baobabsoluciones.es
|
@@ -12,9 +12,10 @@ Classifier: Development Status :: 5 - Production/Stable
|
|
12
12
|
Requires-Python: >=3.9
|
13
13
|
Requires-Dist: alembic==1.9.2
|
14
14
|
Requires-Dist: apispec<=6.3.0
|
15
|
+
Requires-Dist: cachetools==5.3.3
|
15
16
|
Requires-Dist: click<=8.1.7
|
16
|
-
Requires-Dist: cornflow-client==2.0.
|
17
|
-
Requires-Dist: cryptography<=
|
17
|
+
Requires-Dist: cornflow-client==2.0.0a12
|
18
|
+
Requires-Dist: cryptography<=44.0.1
|
18
19
|
Requires-Dist: databricks-sdk==0.29.0
|
19
20
|
Requires-Dist: disposable-email-domains>=0.0.86
|
20
21
|
Requires-Dist: Flask==2.3.2
|
@@ -29,7 +30,7 @@ Requires-Dist: Flask-SQLAlchemy==2.5.1
|
|
29
30
|
Requires-Dist: gevent==23.9.1
|
30
31
|
Requires-Dist: greenlet<=2.0.2; python_version < "3.11"
|
31
32
|
Requires-Dist: greenlet==3.0.3; python_version >= "3.11"
|
32
|
-
Requires-Dist: gunicorn<=
|
33
|
+
Requires-Dist: gunicorn<=23.0.0
|
33
34
|
Requires-Dist: jsonpatch<=1.33
|
34
35
|
Requires-Dist: ldap3<=2.9.1
|
35
36
|
Requires-Dist: marshmallow<=3.20.2
|
@@ -50,7 +51,7 @@ Dynamic: requires-dist
|
|
50
51
|
Dynamic: requires-python
|
51
52
|
Dynamic: summary
|
52
53
|
|
53
|
-
|
54
|
+
cornflow
|
54
55
|
=========
|
55
56
|
|
56
57
|
.. image:: https://github.com/baobabsoluciones/cornflow/workflows/build/badge.svg?style=svg
|
@@ -70,13 +71,13 @@ Cornflow
|
|
70
71
|
|
71
72
|
.. image:: https://img.shields.io/badge/License-Apache2.0-blue
|
72
73
|
|
73
|
-
|
74
|
+
cornflow is an open source multi-solver optimization server with a REST API built using `flask <https://flask.palletsprojects.com>`_, `airflow <https://airflow.apache.org/>`_ and `pulp <https://coin-or.github.io/pulp/>`_.
|
74
75
|
|
75
|
-
While most deployment servers are based on the solving technique (MIP, CP, NLP, etc.),
|
76
|
+
While most deployment servers are based on the solving technique (MIP, CP, NLP, etc.), cornflow focuses on the optimization problems themselves. However, it does not impose any constraint on the type of problem and solution method to use.
|
76
77
|
|
77
|
-
With
|
78
|
+
With cornflow you can deploy a Traveling Salesman Problem solver next to a Knapsack solver or a Nurse Rostering Problem solver. As long as you describe the input and output data, you can upload any solution method for any problem and then use it with any data you want.
|
78
79
|
|
79
|
-
|
80
|
+
cornflow helps you formalize your problem by proposing development guidelines. It also provides a range of functionalities around your deployed solution method, namely:
|
80
81
|
|
81
82
|
* storage of users, instances, solutions and solution logs.
|
82
83
|
* deployment and maintenance of models, solvers and algorithms.
|
@@ -92,9 +93,9 @@ Cornflow helps you formalize your problem by proposing development guidelines. I
|
|
92
93
|
Installation instructions
|
93
94
|
-------------------------------
|
94
95
|
|
95
|
-
|
96
|
+
cornflow is tested with Ubuntu 20.04, python >= 3.8 and git.
|
96
97
|
|
97
|
-
Download the
|
98
|
+
Download the cornflow project and install requirements::
|
98
99
|
|
99
100
|
python3 -m venv venv
|
100
101
|
venv/bin/pip3 install cornflow
|
@@ -110,7 +111,7 @@ initialize the sqlite database::
|
|
110
111
|
flask create_admin_user -u cornflow -e cornflow_admin@admin.com -p cornflow_admin_password
|
111
112
|
|
112
113
|
|
113
|
-
activate the virtual environment and run
|
114
|
+
activate the virtual environment and run cornflow::
|
114
115
|
|
115
116
|
source venv/bin/activate
|
116
117
|
export FLASK_APP=cornflow.app
|
@@ -121,7 +122,7 @@ activate the virtual environment and run Cornflow::
|
|
121
122
|
export AIRFLOW_PWD=airflow_pwd
|
122
123
|
flask run
|
123
124
|
|
124
|
-
**
|
125
|
+
**cornflow needs a running installation of Airflow to operate and more configuration**. Check `the installation docs <https://baobabsoluciones.github.io/cornflow/main/install.html>`_ for more details on installing airflow, configuring the application and initializing the database.
|
125
126
|
|
126
127
|
Using cornflow to solve a PuLP model
|
127
128
|
---------------------------------------
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
cornflow
|
2
2
|
=========
|
3
3
|
|
4
4
|
.. image:: https://github.com/baobabsoluciones/cornflow/workflows/build/badge.svg?style=svg
|
@@ -18,13 +18,13 @@ Cornflow
|
|
18
18
|
|
19
19
|
.. image:: https://img.shields.io/badge/License-Apache2.0-blue
|
20
20
|
|
21
|
-
|
21
|
+
cornflow is an open source multi-solver optimization server with a REST API built using `flask <https://flask.palletsprojects.com>`_, `airflow <https://airflow.apache.org/>`_ and `pulp <https://coin-or.github.io/pulp/>`_.
|
22
22
|
|
23
|
-
While most deployment servers are based on the solving technique (MIP, CP, NLP, etc.),
|
23
|
+
While most deployment servers are based on the solving technique (MIP, CP, NLP, etc.), cornflow focuses on the optimization problems themselves. However, it does not impose any constraint on the type of problem and solution method to use.
|
24
24
|
|
25
|
-
With
|
25
|
+
With cornflow you can deploy a Traveling Salesman Problem solver next to a Knapsack solver or a Nurse Rostering Problem solver. As long as you describe the input and output data, you can upload any solution method for any problem and then use it with any data you want.
|
26
26
|
|
27
|
-
|
27
|
+
cornflow helps you formalize your problem by proposing development guidelines. It also provides a range of functionalities around your deployed solution method, namely:
|
28
28
|
|
29
29
|
* storage of users, instances, solutions and solution logs.
|
30
30
|
* deployment and maintenance of models, solvers and algorithms.
|
@@ -40,9 +40,9 @@ Cornflow helps you formalize your problem by proposing development guidelines. I
|
|
40
40
|
Installation instructions
|
41
41
|
-------------------------------
|
42
42
|
|
43
|
-
|
43
|
+
cornflow is tested with Ubuntu 20.04, python >= 3.8 and git.
|
44
44
|
|
45
|
-
Download the
|
45
|
+
Download the cornflow project and install requirements::
|
46
46
|
|
47
47
|
python3 -m venv venv
|
48
48
|
venv/bin/pip3 install cornflow
|
@@ -58,7 +58,7 @@ initialize the sqlite database::
|
|
58
58
|
flask create_admin_user -u cornflow -e cornflow_admin@admin.com -p cornflow_admin_password
|
59
59
|
|
60
60
|
|
61
|
-
activate the virtual environment and run
|
61
|
+
activate the virtual environment and run cornflow::
|
62
62
|
|
63
63
|
source venv/bin/activate
|
64
64
|
export FLASK_APP=cornflow.app
|
@@ -69,7 +69,7 @@ activate the virtual environment and run Cornflow::
|
|
69
69
|
export AIRFLOW_PWD=airflow_pwd
|
70
70
|
flask run
|
71
71
|
|
72
|
-
**
|
72
|
+
**cornflow needs a running installation of Airflow to operate and more configuration**. Check `the installation docs <https://baobabsoluciones.github.io/cornflow/main/install.html>`_ for more details on installing airflow, configuring the application and initializing the database.
|
73
73
|
|
74
74
|
Using cornflow to solve a PuLP model
|
75
75
|
---------------------------------------
|
@@ -19,5 +19,5 @@ STATE_COLORS = {
|
|
19
19
|
from airflow.www.utils import UIAlert
|
20
20
|
|
21
21
|
DASHBOARD_UIALERTS = [
|
22
|
-
UIAlert("Welcome! This is the backend of your
|
22
|
+
UIAlert("Welcome! This is the backend of your cornflow environment. Airflow™ is a platform created by the community to programmatically author, schedule and monitor workflows."),
|
23
23
|
]
|
@@ -37,7 +37,7 @@ from cornflow.endpoints.signup import SignUpEndpoint
|
|
37
37
|
from cornflow.shared import db, bcrypt
|
38
38
|
from cornflow.shared.compress import init_compress
|
39
39
|
from cornflow.shared.const import AUTH_DB, AUTH_LDAP, AUTH_OID
|
40
|
-
from cornflow.shared.exceptions import initialize_errorhandlers
|
40
|
+
from cornflow.shared.exceptions import initialize_errorhandlers, ConfigurationError
|
41
41
|
from cornflow.shared.log_config import log_config
|
42
42
|
|
43
43
|
|
@@ -62,11 +62,11 @@ def create_app(env_name="development", dataconn=None):
|
|
62
62
|
CORS(app)
|
63
63
|
bcrypt.init_app(app)
|
64
64
|
db.init_app(app)
|
65
|
-
|
65
|
+
Migrate(app=app, db=db)
|
66
66
|
|
67
67
|
if "sqlite" in app.config["SQLALCHEMY_DATABASE_URI"]:
|
68
68
|
|
69
|
-
def _fk_pragma_on_connect(dbapi_con,
|
69
|
+
def _fk_pragma_on_connect(dbapi_con, _con_record):
|
70
70
|
dbapi_con.execute("pragma foreign_keys=ON")
|
71
71
|
|
72
72
|
with app.app_context():
|
@@ -100,6 +100,11 @@ def create_app(env_name="development", dataconn=None):
|
|
100
100
|
api.add_resource(LoginEndpoint, "/login/", endpoint="login")
|
101
101
|
elif auth_type == AUTH_OID:
|
102
102
|
api.add_resource(LoginOpenAuthEndpoint, "/login/", endpoint="login")
|
103
|
+
else:
|
104
|
+
raise ConfigurationError(
|
105
|
+
error="Invalid authentication type",
|
106
|
+
log_txt="Error while configuring authentication. The authentication type is not valid."
|
107
|
+
)
|
103
108
|
|
104
109
|
initialize_errorhandlers(app)
|
105
110
|
init_compress(app)
|
@@ -3,7 +3,7 @@ import os.path
|
|
3
3
|
|
4
4
|
import click
|
5
5
|
from cornflow.shared import db
|
6
|
-
from flask_migrate import Migrate, migrate, upgrade, init
|
6
|
+
from flask_migrate import Migrate, migrate, upgrade, downgrade, init
|
7
7
|
|
8
8
|
from .utils import get_app
|
9
9
|
|
@@ -28,7 +28,27 @@ def migrate_migrations():
|
|
28
28
|
|
29
29
|
|
30
30
|
@migrations.command(name="upgrade", help="Apply migrations")
|
31
|
-
|
31
|
+
@click.option(
|
32
|
+
"-r", "--revision", type=str, help="The revision to upgrade to", default="head"
|
33
|
+
)
|
34
|
+
def upgrade_migrations(revision="head"):
|
35
|
+
app = get_app()
|
36
|
+
external = int(os.getenv("EXTERNAL_APP", 0))
|
37
|
+
if external == 0:
|
38
|
+
path = "./cornflow/migrations"
|
39
|
+
else:
|
40
|
+
path = f"./{os.getenv('EXTERNAL_APP_MODULE', 'external_app')}/migrations"
|
41
|
+
|
42
|
+
with app.app_context():
|
43
|
+
migration_client = Migrate(app=app, db=db, directory=path)
|
44
|
+
upgrade(revision=revision)
|
45
|
+
|
46
|
+
|
47
|
+
@migrations.command(name="downgrade", help="Downgrade migrations")
|
48
|
+
@click.option(
|
49
|
+
"-r", "--revision", type=str, help="The revision to downgrade to", default="-1"
|
50
|
+
)
|
51
|
+
def downgrade_migrations(revision="-1"):
|
32
52
|
app = get_app()
|
33
53
|
external = int(os.getenv("EXTERNAL_APP", 0))
|
34
54
|
if external == 0:
|
@@ -38,7 +58,7 @@ def upgrade_migrations():
|
|
38
58
|
|
39
59
|
with app.app_context():
|
40
60
|
migration_client = Migrate(app=app, db=db, directory=path)
|
41
|
-
|
61
|
+
downgrade(revision=revision)
|
42
62
|
|
43
63
|
|
44
64
|
@migrations.command(
|
@@ -6,6 +6,7 @@ from logging import error
|
|
6
6
|
|
7
7
|
|
8
8
|
import click
|
9
|
+
from .utils import get_db_conn
|
9
10
|
import cornflow
|
10
11
|
from cornflow.app import create_app
|
11
12
|
from cornflow.commands import (
|
@@ -18,9 +19,12 @@ from cornflow.commands import (
|
|
18
19
|
)
|
19
20
|
from cornflow.shared.const import (
|
20
21
|
AUTH_DB,
|
22
|
+
AUTH_LDAP,
|
23
|
+
AUTH_OID,
|
21
24
|
ADMIN_ROLE,
|
22
|
-
DATABRICKS_BACKEND,
|
23
25
|
SERVICE_ROLE,
|
26
|
+
PLANNER_ROLE,
|
27
|
+
DATABRICKS_BACKEND,
|
24
28
|
AIRFLOW_BACKEND,
|
25
29
|
)
|
26
30
|
from cornflow.shared import db
|
@@ -44,7 +48,7 @@ def init_cornflow_service():
|
|
44
48
|
# Global defaults and back-compat #
|
45
49
|
###################################
|
46
50
|
# cornflow backend selection
|
47
|
-
cornflow_backend = os.getenv("CORNFLOW_BACKEND", AIRFLOW_BACKEND)
|
51
|
+
cornflow_backend = os.getenv("CORNFLOW_BACKEND", str(AIRFLOW_BACKEND))
|
48
52
|
os.environ["CORNFLOW_BACKEND"] = cornflow_backend
|
49
53
|
cornflow_backend = int(cornflow_backend)
|
50
54
|
# Airflow global default conn
|
@@ -73,15 +77,8 @@ def init_cornflow_service():
|
|
73
77
|
os.environ["SECRET_KEY"] = os.getenv("FERNET_KEY", Fernet.generate_key().decode())
|
74
78
|
|
75
79
|
# Cornflow db defaults
|
76
|
-
|
77
|
-
|
78
|
-
cornflow_db_user = os.getenv("CORNFLOW_DB_USER", "cornflow")
|
79
|
-
cornflow_db_password = os.getenv("CORNFLOW_DB_PASSWORD", "cornflow")
|
80
|
-
cornflow_db = os.getenv("CORNFLOW_DB", "cornflow")
|
81
|
-
cornflow_db_conn = os.getenv(
|
82
|
-
"cornflow_db_conn",
|
83
|
-
f"postgresql://{cornflow_db_user}:{cornflow_db_password}@{cornflow_db_host}:{cornflow_db_port}/{cornflow_db}",
|
84
|
-
)
|
80
|
+
os.environ["DEFAULT_POSTGRES"] = "1"
|
81
|
+
cornflow_db_conn = get_db_conn()
|
85
82
|
os.environ["DATABASE_URL"] = cornflow_db_conn
|
86
83
|
|
87
84
|
# Platform auth config and service users
|
@@ -107,12 +104,12 @@ def init_cornflow_service():
|
|
107
104
|
os.environ["SIGNUP_ACTIVATED"] = str(signup_activated)
|
108
105
|
user_access_all_objects = os.getenv("USER_ACCESS_ALL_OBJECTS", 0)
|
109
106
|
os.environ["USER_ACCESS_ALL_OBJECTS"] = str(user_access_all_objects)
|
110
|
-
default_role = os.getenv("DEFAULT_ROLE",
|
107
|
+
default_role = int(os.getenv("DEFAULT_ROLE", PLANNER_ROLE))
|
111
108
|
os.environ["DEFAULT_ROLE"] = str(default_role)
|
112
109
|
|
113
110
|
# Check LDAP parameters for active directory and show message
|
114
|
-
if os.getenv("AUTH_TYPE") ==
|
115
|
-
|
111
|
+
if os.getenv("AUTH_TYPE") == AUTH_LDAP:
|
112
|
+
print(
|
116
113
|
"WARNING: Cornflow will be deployed with LDAP Authorization. Please review your ldap auth configuration."
|
117
114
|
)
|
118
115
|
|
@@ -153,10 +150,11 @@ def init_cornflow_service():
|
|
153
150
|
app = create_app(environment, cornflow_db_conn)
|
154
151
|
with app.app_context():
|
155
152
|
path = f"{os.path.dirname(cornflow.__file__)}/migrations"
|
156
|
-
|
153
|
+
Migrate(app=app, db=db, directory=path)
|
157
154
|
upgrade()
|
158
155
|
access_init_command(verbose=False)
|
159
|
-
if auth ==
|
156
|
+
if auth == AUTH_DB or auth == AUTH_OID:
|
157
|
+
# create cornflow admin user
|
160
158
|
create_user_with_role(
|
161
159
|
cornflow_admin_user,
|
162
160
|
cornflow_admin_email,
|
@@ -218,7 +216,7 @@ def init_cornflow_service():
|
|
218
216
|
migrate = Migrate(app=app, db=db, directory=path)
|
219
217
|
upgrade()
|
220
218
|
access_init_command(verbose=False)
|
221
|
-
if auth ==
|
219
|
+
if auth == AUTH_DB or auth == AUTH_OID:
|
222
220
|
# create cornflow admin user
|
223
221
|
create_user_with_role(
|
224
222
|
cornflow_admin_user,
|
@@ -251,8 +249,10 @@ def init_cornflow_service():
|
|
251
249
|
update_dag_registry_command(
|
252
250
|
airflow_url, airflow_user, airflow_pwd, verbose=True
|
253
251
|
)
|
254
|
-
|
252
|
+
elif cornflow_backend == DATABRICKS_BACKEND:
|
255
253
|
register_dag_permissions_command(open_deployment, verbose=True)
|
254
|
+
else:
|
255
|
+
raise Exception("Selected backend not among valid options")
|
256
256
|
|
257
257
|
os.system(
|
258
258
|
f"/usr/local/bin/gunicorn -c python:cornflow.gunicorn "
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import os
|
2
|
+
import sys
|
3
|
+
from importlib import import_module
|
4
|
+
import warnings
|
5
|
+
|
6
|
+
|
7
|
+
def get_app():
|
8
|
+
env = os.getenv("FLASK_ENV", "development")
|
9
|
+
data_conn = get_db_conn()
|
10
|
+
if env == "production":
|
11
|
+
warnings.filterwarnings("ignore")
|
12
|
+
external = int(os.getenv("EXTERNAL_APP", 0))
|
13
|
+
if external == 0:
|
14
|
+
from cornflow.app import create_app
|
15
|
+
else:
|
16
|
+
sys.path.append("./")
|
17
|
+
external_app = os.getenv("EXTERNAL_APP_MODULE", "external_app")
|
18
|
+
external_module = import_module(external_app)
|
19
|
+
create_app = external_module.create_wsgi_app
|
20
|
+
|
21
|
+
if data_conn is None:
|
22
|
+
app = create_app(env)
|
23
|
+
else:
|
24
|
+
app = create_app(env, data_conn)
|
25
|
+
|
26
|
+
return app
|
27
|
+
|
28
|
+
|
29
|
+
def get_db_conn():
|
30
|
+
if int(os.getenv("DEFAULT_POSTGRES", 0)) == 0:
|
31
|
+
return os.getenv("DATABASE_URL", "sqlite:///cornflow.db")
|
32
|
+
else:
|
33
|
+
cornflow_db_host = os.getenv("CORNFLOW_DB_HOST", "cornflow_db")
|
34
|
+
cornflow_db_port = os.getenv("CORNFLOW_DB_PORT", "5432")
|
35
|
+
cornflow_db_user = os.getenv("CORNFLOW_DB_USER", "cornflow")
|
36
|
+
cornflow_db_password = os.getenv("CORNFLOW_DB_PASSWORD", "cornflow")
|
37
|
+
cornflow_db = os.getenv("CORNFLOW_DB", "cornflow")
|
38
|
+
return os.getenv(
|
39
|
+
"cornflow_db_conn",
|
40
|
+
f"postgresql://{cornflow_db_user}:{cornflow_db_password}@{cornflow_db_host}:{cornflow_db_port}/{cornflow_db}",
|
41
|
+
)
|
@@ -80,7 +80,7 @@ def register_deployed_dags_command_test(dags: list = None, verbose: bool = False
|
|
80
80
|
from cornflow_client import get_pulp_jsonschema, get_empty_schema
|
81
81
|
|
82
82
|
if dags is None:
|
83
|
-
dags = ["solve_model_dag", "gc", "timer"]
|
83
|
+
dags = ["solve_model_dag", "gc", "timer", "979073949072767" ]
|
84
84
|
|
85
85
|
deployed_dag = [
|
86
86
|
DeployedOrch(
|
@@ -1,7 +1,8 @@
|
|
1
1
|
import os
|
2
|
-
from .shared.const import AUTH_DB, PLANNER_ROLE,
|
2
|
+
from .shared.const import AUTH_DB, PLANNER_ROLE, AUTH_OID
|
3
3
|
from apispec import APISpec
|
4
4
|
from apispec.ext.marshmallow import MarshmallowPlugin
|
5
|
+
from cornflow.shared.const import AIRFLOW_BACKEND, DATABRICKS_BACKEND
|
5
6
|
|
6
7
|
|
7
8
|
class DefaultConfig(object):
|
@@ -72,15 +73,13 @@ class DefaultConfig(object):
|
|
72
73
|
LDAP_PROTOCOL_VERSION = int(os.getenv("LDAP_PROTOCOL_VERSION", 3))
|
73
74
|
LDAP_USE_TLS = os.getenv("LDAP_USE_TLS", "False")
|
74
75
|
|
75
|
-
# OpenID
|
76
|
-
OID_PROVIDER = os.getenv("OID_PROVIDER"
|
77
|
-
|
78
|
-
OID_TENANT_ID = os.getenv("OID_TENANT_ID")
|
79
|
-
OID_ISSUER = os.getenv("OID_ISSUER")
|
76
|
+
# OpenID Connect configuration
|
77
|
+
OID_PROVIDER = os.getenv("OID_PROVIDER")
|
78
|
+
OID_EXPECTED_AUDIENCE = os.getenv("OID_EXPECTED_AUDIENCE")
|
80
79
|
|
81
80
|
# APISPEC:
|
82
81
|
APISPEC_SPEC = APISpec(
|
83
|
-
title="
|
82
|
+
title="cornflow API docs",
|
84
83
|
version="v1",
|
85
84
|
plugins=[MarshmallowPlugin()],
|
86
85
|
openapi_version="2.0.0",
|
@@ -135,13 +134,18 @@ class Testing(DefaultConfig):
|
|
135
134
|
OPEN_DEPLOYMENT = 1
|
136
135
|
LOG_LEVEL = int(os.getenv("LOG_LEVEL", 10))
|
137
136
|
|
137
|
+
class TestingDatabricks(Testing):
|
138
|
+
CORNFLOW_BACKEND = DATABRICKS_BACKEND
|
139
|
+
|
138
140
|
|
139
141
|
class TestingOpenAuth(Testing):
|
140
142
|
"""
|
141
143
|
Configuration class for testing some edge cases with Open Auth login
|
142
144
|
"""
|
143
145
|
|
144
|
-
AUTH_TYPE =
|
146
|
+
AUTH_TYPE = AUTH_OID
|
147
|
+
OID_PROVIDER = "https://test-provider.example.com"
|
148
|
+
OID_EXPECTED_AUDIENCE = "test-audience-id"
|
145
149
|
|
146
150
|
|
147
151
|
class TestingApplicationRoot(Testing):
|
@@ -172,4 +176,5 @@ app_config = {
|
|
172
176
|
"production": Production,
|
173
177
|
"testing-oauth": TestingOpenAuth,
|
174
178
|
"testing-root": TestingApplicationRoot,
|
179
|
+
"testing-databricks" : TestingDatabricks
|
175
180
|
}
|
@@ -3,8 +3,9 @@ Initialization file for the endpoints module
|
|
3
3
|
All references to endpoints should be imported from here
|
4
4
|
The login resource gets created on app startup as it depends on configuration
|
5
5
|
"""
|
6
|
+
|
6
7
|
from .action import ActionListEndpoint
|
7
|
-
from .alarms import AlarmsEndpoint
|
8
|
+
from .alarms import AlarmsEndpoint, AlarmDetailEndpoint
|
8
9
|
from .apiview import ApiViewListEndpoint
|
9
10
|
from .case import (
|
10
11
|
CaseEndpoint,
|
@@ -29,7 +30,7 @@ from .data_check import (
|
|
29
30
|
DataCheckCaseEndpoint,
|
30
31
|
)
|
31
32
|
from .example_data import ExampleDataListEndpoint, ExampleDataDetailEndpoint
|
32
|
-
from .
|
33
|
+
from .execution import (
|
33
34
|
ExecutionEndpoint,
|
34
35
|
ExecutionDetailsEndpoint,
|
35
36
|
ExecutionStatusEndpoint,
|
@@ -225,6 +226,11 @@ alarms_resources = [
|
|
225
226
|
urls="/alarms/",
|
226
227
|
endpoint="alarms",
|
227
228
|
),
|
229
|
+
dict(
|
230
|
+
resource=AlarmDetailEndpoint,
|
231
|
+
urls="/alarms/<int:idx>/",
|
232
|
+
endpoint="alarms-detail",
|
233
|
+
),
|
228
234
|
dict(
|
229
235
|
resource=MainAlarmsEndpoint,
|
230
236
|
urls="/main-alarms/",
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# Imports from libraries
|
2
|
+
from flask import current_app
|
3
|
+
from flask_apispec import doc, marshal_with, use_kwargs
|
4
|
+
|
5
|
+
# Import from internal modules
|
6
|
+
from cornflow.endpoints.meta_resource import BaseMetaResource
|
7
|
+
from cornflow.models import AlarmsModel
|
8
|
+
from cornflow.schemas.alarms import (
|
9
|
+
AlarmEditRequest,
|
10
|
+
AlarmsResponse,
|
11
|
+
AlarmsPostRequest,
|
12
|
+
QueryFiltersAlarms,
|
13
|
+
)
|
14
|
+
from cornflow.shared.authentication import Auth, authenticate
|
15
|
+
from cornflow.shared.exceptions import AirflowError, ObjectDoesNotExist, InvalidData
|
16
|
+
from cornflow.shared.const import SERVICE_ROLE
|
17
|
+
|
18
|
+
|
19
|
+
class AlarmsEndpoint(BaseMetaResource):
|
20
|
+
"""
|
21
|
+
Endpoint used to manage the table alarms.
|
22
|
+
Available methods: [get, post]
|
23
|
+
"""
|
24
|
+
|
25
|
+
def __init__(self):
|
26
|
+
super().__init__()
|
27
|
+
self.data_model = AlarmsModel
|
28
|
+
self.unique = ["id"]
|
29
|
+
|
30
|
+
@doc(
|
31
|
+
description="Get list of all the elements in the table",
|
32
|
+
tags=["None"],
|
33
|
+
)
|
34
|
+
@authenticate(auth_class=Auth())
|
35
|
+
@marshal_with(AlarmsResponse(many=True))
|
36
|
+
@use_kwargs(QueryFiltersAlarms, location="query")
|
37
|
+
def get(self, **kwargs):
|
38
|
+
"""
|
39
|
+
API method to get all the rows of the table.
|
40
|
+
It requires authentication to be passed in the form of a token that has to be linked to
|
41
|
+
an existing session (login) made by a user.
|
42
|
+
:return: A list of objects with the data, and an integer with the HTTP status code.
|
43
|
+
:rtype: Tuple(dict, integer)
|
44
|
+
"""
|
45
|
+
return self.get_list(**kwargs)
|
46
|
+
|
47
|
+
@doc(
|
48
|
+
description="Add a new row to the table",
|
49
|
+
tags=["None"],
|
50
|
+
)
|
51
|
+
@authenticate(auth_class=Auth())
|
52
|
+
@marshal_with(AlarmsResponse)
|
53
|
+
@use_kwargs(AlarmsPostRequest, location="json")
|
54
|
+
def post(self, **kwargs):
|
55
|
+
"""
|
56
|
+
API method to add a row to the table.
|
57
|
+
It requires authentication to be passed in the form of a token that has to be linked to
|
58
|
+
an existing session (login) made by a user.
|
59
|
+
:return: An object with the data for the created row,
|
60
|
+
and an integer with the HTTP status code.
|
61
|
+
:rtype: Tuple(dict, integer)
|
62
|
+
"""
|
63
|
+
return self.post_list(data=kwargs)
|
64
|
+
|
65
|
+
|
66
|
+
class AlarmDetailEndpointBase(BaseMetaResource):
|
67
|
+
"""
|
68
|
+
Endpoint used to get the information of a certain alarm. But not the data!
|
69
|
+
"""
|
70
|
+
|
71
|
+
def __init__(self):
|
72
|
+
super().__init__()
|
73
|
+
self.data_model = AlarmsModel
|
74
|
+
self.unique = ["id"]
|
75
|
+
|
76
|
+
|
77
|
+
class AlarmDetailEndpoint(AlarmDetailEndpointBase):
|
78
|
+
@doc(description="Get details of an alarm", tags=["None"], inherit=False)
|
79
|
+
@authenticate(auth_class=Auth())
|
80
|
+
@marshal_with(AlarmsResponse)
|
81
|
+
@BaseMetaResource.get_data_or_404
|
82
|
+
def get(self, idx):
|
83
|
+
"""
|
84
|
+
API method to get an execution created by the user and its related info.
|
85
|
+
It requires authentication to be passed in the form of a token that has to be linked to
|
86
|
+
an existing session (login) made by a user.
|
87
|
+
|
88
|
+
:param str idx: ID of the execution.
|
89
|
+
:return: A dictionary with a message (error if authentication failed, or the execution does not exist or
|
90
|
+
the data of the execution) and an integer with the HTTP status code.
|
91
|
+
:rtype: Tuple(dict, integer)
|
92
|
+
"""
|
93
|
+
current_app.logger.info(
|
94
|
+
f"User {self.get_user()} gets details of execution {idx}"
|
95
|
+
)
|
96
|
+
return self.get_detail(idx=idx)
|
97
|
+
|
98
|
+
@doc(description="Edit an execution", tags=["Executions"], inherit=False)
|
99
|
+
@authenticate(auth_class=Auth())
|
100
|
+
@use_kwargs(AlarmEditRequest, location="json")
|
101
|
+
def put(self, idx, **data):
|
102
|
+
"""
|
103
|
+
Edit an existing alarm
|
104
|
+
|
105
|
+
:param string idx: ID of the alarm.
|
106
|
+
:return: A dictionary with a message (error if authentication failed, or the alarm does not exist or
|
107
|
+
a message) and an integer with the HTTP status code.
|
108
|
+
:rtype: Tuple(dict, integer)
|
109
|
+
"""
|
110
|
+
current_app.logger.info(f"User {self.get_user()} edits alarm {idx}")
|
111
|
+
return self.put_detail(data, track_user=False, idx=idx)
|
112
|
+
|
113
|
+
@doc(description="Disable an alarm", tags=["None"])
|
114
|
+
@authenticate(auth_class=Auth())
|
115
|
+
def delete(self, idx):
|
116
|
+
"""
|
117
|
+
:param int alarm_id: Alarm id.
|
118
|
+
:return:
|
119
|
+
:rtype: Tuple(dict, integer)
|
120
|
+
"""
|
121
|
+
|
122
|
+
current_app.logger.info(f"Alarm {idx} was disabled by user {self.get_user()}")
|
123
|
+
return self.disable_detail(idx=idx)
|