cornflow 1.1.5a1__tar.gz → 1.2.0__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.
Files changed (188) hide show
  1. {cornflow-1.1.5a1/cornflow.egg-info → cornflow-1.2.0}/PKG-INFO +13 -12
  2. {cornflow-1.1.5a1 → cornflow-1.2.0}/README.rst +9 -9
  3. {cornflow-1.1.5a1 → cornflow-1.2.0}/airflow_config/airflow_local_settings.py +1 -1
  4. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/app.py +8 -3
  5. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/cli/migrations.py +23 -3
  6. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/cli/service.py +17 -15
  7. cornflow-1.2.0/cornflow/cli/utils.py +41 -0
  8. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/config.py +10 -11
  9. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/endpoints/__init__.py +7 -1
  10. cornflow-1.2.0/cornflow/endpoints/alarms.py +123 -0
  11. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/endpoints/login.py +81 -63
  12. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/endpoints/meta_resource.py +11 -3
  13. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/models/base_data_model.py +4 -32
  14. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/models/meta_models.py +28 -22
  15. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/models/user.py +7 -10
  16. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/schemas/alarms.py +8 -0
  17. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/schemas/query.py +2 -1
  18. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/schemas/user.py +5 -20
  19. cornflow-1.2.0/cornflow/shared/authentication/auth.py +458 -0
  20. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/shared/const.py +3 -14
  21. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/const.py +1 -0
  22. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/custom_test_case.py +77 -26
  23. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/unit/test_actions.py +2 -2
  24. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/unit/test_alarms.py +55 -1
  25. cornflow-1.2.0/cornflow/tests/unit/test_apiview.py +209 -0
  26. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/unit/test_cases.py +20 -29
  27. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/unit/test_cli.py +6 -5
  28. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/unit/test_dags.py +5 -6
  29. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/unit/test_instances.py +14 -2
  30. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/unit/test_instances_file.py +1 -1
  31. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/unit/test_licenses.py +1 -1
  32. cornflow-1.2.0/cornflow/tests/unit/test_log_in.py +534 -0
  33. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/unit/test_permissions.py +8 -8
  34. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/unit/test_roles.py +48 -10
  35. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/unit/test_tables.py +7 -7
  36. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/unit/test_token.py +19 -5
  37. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/unit/test_users.py +22 -6
  38. {cornflow-1.1.5a1 → cornflow-1.2.0/cornflow.egg-info}/PKG-INFO +13 -12
  39. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow.egg-info/requires.txt +2 -1
  40. {cornflow-1.1.5a1 → cornflow-1.2.0}/requirements.txt +2 -1
  41. {cornflow-1.1.5a1 → cornflow-1.2.0}/setup.py +2 -2
  42. cornflow-1.1.5a1/cornflow/cli/utils.py +0 -26
  43. cornflow-1.1.5a1/cornflow/endpoints/alarms.py +0 -59
  44. cornflow-1.1.5a1/cornflow/shared/authentication/auth.py +0 -521
  45. cornflow-1.1.5a1/cornflow/tests/unit/test_apiview.py +0 -104
  46. cornflow-1.1.5a1/cornflow/tests/unit/test_log_in.py +0 -511
  47. {cornflow-1.1.5a1 → cornflow-1.2.0}/MANIFEST.in +0 -0
  48. {cornflow-1.1.5a1 → cornflow-1.2.0}/airflow_config/__init__.py +0 -0
  49. {cornflow-1.1.5a1 → cornflow-1.2.0}/airflow_config/plugins/XCom/__init__.py +0 -0
  50. {cornflow-1.1.5a1 → cornflow-1.2.0}/airflow_config/plugins/XCom/gce_xcom_backend.py +0 -0
  51. {cornflow-1.1.5a1 → cornflow-1.2.0}/airflow_config/plugins/__init__.py +0 -0
  52. {cornflow-1.1.5a1 → cornflow-1.2.0}/airflow_config/webserver_ldap.py +0 -0
  53. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/__init__.py +0 -0
  54. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/cli/__init__.py +0 -0
  55. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/cli/actions.py +0 -0
  56. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/cli/arguments.py +0 -0
  57. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/cli/config.py +0 -0
  58. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/cli/permissions.py +0 -0
  59. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/cli/roles.py +0 -0
  60. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/cli/schemas.py +0 -0
  61. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/cli/tools/__init__.py +0 -0
  62. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/cli/tools/api_generator.py +0 -0
  63. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/cli/tools/endpoint_tools.py +0 -0
  64. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/cli/tools/models_tools.py +0 -0
  65. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/cli/tools/schema_generator.py +0 -0
  66. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/cli/tools/schemas_tools.py +0 -0
  67. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/cli/tools/tools.py +0 -0
  68. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/cli/users.py +0 -0
  69. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/cli/views.py +0 -0
  70. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/commands/__init__.py +0 -0
  71. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/commands/access.py +0 -0
  72. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/commands/actions.py +0 -0
  73. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/commands/cleanup.py +0 -0
  74. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/commands/dag.py +0 -0
  75. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/commands/permissions.py +0 -0
  76. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/commands/roles.py +0 -0
  77. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/commands/schemas.py +0 -0
  78. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/commands/users.py +0 -0
  79. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/commands/views.py +0 -0
  80. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/endpoints/action.py +0 -0
  81. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/endpoints/apiview.py +0 -0
  82. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/endpoints/case.py +0 -0
  83. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/endpoints/dag.py +0 -0
  84. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/endpoints/data_check.py +0 -0
  85. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/endpoints/example_data.py +0 -0
  86. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/endpoints/execution.py +0 -0
  87. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/endpoints/health.py +0 -0
  88. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/endpoints/instance.py +0 -0
  89. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/endpoints/licenses.py +0 -0
  90. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/endpoints/main_alarms.py +0 -0
  91. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/endpoints/permission.py +0 -0
  92. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/endpoints/roles.py +0 -0
  93. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/endpoints/schemas.py +0 -0
  94. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/endpoints/signup.py +0 -0
  95. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/endpoints/tables.py +0 -0
  96. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/endpoints/token.py +0 -0
  97. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/endpoints/user.py +0 -0
  98. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/endpoints/user_role.py +0 -0
  99. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/gunicorn.py +0 -0
  100. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/migrations/README +0 -0
  101. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/migrations/alembic.ini +0 -0
  102. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/migrations/env.py +0 -0
  103. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/migrations/script.py.mako +0 -0
  104. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/migrations/versions/00757b557b02_.py +0 -0
  105. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/migrations/versions/1af47a419bbd_.py +0 -0
  106. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/migrations/versions/4aac5e0c6e66_.py +0 -0
  107. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/migrations/versions/7c3ea5ab5501_.py +0 -0
  108. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/migrations/versions/991b98e24225_.py +0 -0
  109. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/migrations/versions/a472b5ad50b7_.py +0 -0
  110. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/migrations/versions/c2db9409cb5f_.py +0 -0
  111. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/migrations/versions/c8a6c762e818_.py +0 -0
  112. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/migrations/versions/ca449af8034c_.py +0 -0
  113. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/migrations/versions/d0e0700dcd8e_.py +0 -0
  114. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/migrations/versions/d1b5be1f0549_.py +0 -0
  115. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/migrations/versions/e1a50dae1ac9_.py +0 -0
  116. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/migrations/versions/e937a5234ce4_.py +0 -0
  117. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/migrations/versions/ebdd955fcc5e_.py +0 -0
  118. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/migrations/versions/f3bee20314a2_.py +0 -0
  119. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/models/__init__.py +0 -0
  120. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/models/action.py +0 -0
  121. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/models/alarms.py +0 -0
  122. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/models/case.py +0 -0
  123. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/models/dag.py +0 -0
  124. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/models/dag_permissions.py +0 -0
  125. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/models/execution.py +0 -0
  126. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/models/instance.py +0 -0
  127. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/models/main_alarms.py +0 -0
  128. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/models/permissions.py +0 -0
  129. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/models/role.py +0 -0
  130. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/models/user_role.py +0 -0
  131. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/models/view.py +0 -0
  132. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/schemas/__init__.py +0 -0
  133. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/schemas/action.py +0 -0
  134. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/schemas/case.py +0 -0
  135. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/schemas/common.py +0 -0
  136. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/schemas/dag.py +0 -0
  137. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/schemas/example_data.py +0 -0
  138. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/schemas/execution.py +0 -0
  139. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/schemas/health.py +0 -0
  140. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/schemas/instance.py +0 -0
  141. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/schemas/main_alarms.py +0 -0
  142. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/schemas/model_json.py +0 -0
  143. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/schemas/patch.py +0 -0
  144. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/schemas/permissions.py +0 -0
  145. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/schemas/role.py +0 -0
  146. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/schemas/schemas.py +0 -0
  147. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/schemas/solution_log.py +0 -0
  148. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/schemas/tables.py +0 -0
  149. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/schemas/user_role.py +0 -0
  150. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/schemas/view.py +0 -0
  151. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/shared/__init__.py +0 -0
  152. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/shared/authentication/__init__.py +0 -0
  153. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/shared/authentication/decorators.py +0 -0
  154. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/shared/authentication/ldap.py +0 -0
  155. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/shared/compress.py +0 -0
  156. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/shared/email.py +0 -0
  157. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/shared/exceptions.py +0 -0
  158. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/shared/licenses.py +0 -0
  159. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/shared/log_config.py +0 -0
  160. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/shared/query_tools.py +0 -0
  161. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/shared/utils.py +0 -0
  162. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/shared/utils_tables.py +0 -0
  163. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/shared/validators.py +0 -0
  164. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/__init__.py +0 -0
  165. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/custom_liveServer.py +0 -0
  166. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/integration/__init__.py +0 -0
  167. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/integration/test_commands.py +0 -0
  168. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/integration/test_cornflowclient.py +0 -0
  169. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/ldap/__init__.py +0 -0
  170. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/ldap/test_ldap_authentication.py +0 -0
  171. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/unit/__init__.py +0 -0
  172. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/unit/test_application.py +0 -0
  173. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/unit/test_commands.py +0 -0
  174. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/unit/test_data_checks.py +0 -0
  175. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/unit/test_example_data.py +0 -0
  176. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/unit/test_executions.py +0 -0
  177. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/unit/test_generate_from_schema.py +0 -0
  178. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/unit/test_health.py +0 -0
  179. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/unit/test_main_alarms.py +0 -0
  180. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/unit/test_schema_from_models.py +0 -0
  181. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/unit/test_schemas.py +0 -0
  182. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/unit/test_sign_up.py +0 -0
  183. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow/tests/unit/tools.py +0 -0
  184. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow.egg-info/SOURCES.txt +0 -0
  185. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow.egg-info/dependency_links.txt +0 -0
  186. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow.egg-info/entry_points.txt +0 -0
  187. {cornflow-1.1.5a1 → cornflow-1.2.0}/cornflow.egg-info/top_level.txt +0 -0
  188. {cornflow-1.1.5a1 → cornflow-1.2.0}/setup.cfg +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: cornflow
3
- Version: 1.1.5a1
4
- Summary: Cornflow is an open source multi-solver optimization server with a REST API built using flask.
3
+ Version: 1.2.0
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,8 +12,9 @@ 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>=1.1.0
17
+ Requires-Dist: cornflow-client>=1.2.0
17
18
  Requires-Dist: cryptography<=42.0.5
18
19
  Requires-Dist: disposable-email-domains>=0.0.86
19
20
  Requires-Dist: Flask==2.3.2
@@ -49,7 +50,7 @@ Dynamic: requires-dist
49
50
  Dynamic: requires-python
50
51
  Dynamic: summary
51
52
 
52
- Cornflow
53
+ cornflow
53
54
  =========
54
55
 
55
56
  .. image:: https://github.com/baobabsoluciones/cornflow/workflows/build/badge.svg?style=svg
@@ -69,13 +70,13 @@ Cornflow
69
70
 
70
71
  .. image:: https://img.shields.io/badge/License-Apache2.0-blue
71
72
 
72
- 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/>`_.
73
+ 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/>`_.
73
74
 
74
- 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.
75
+ 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.
75
76
 
76
- 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.
77
+ 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.
77
78
 
78
- Cornflow helps you formalize your problem by proposing development guidelines. It also provides a range of functionalities around your deployed solution method, namely:
79
+ cornflow helps you formalize your problem by proposing development guidelines. It also provides a range of functionalities around your deployed solution method, namely:
79
80
 
80
81
  * storage of users, instances, solutions and solution logs.
81
82
  * deployment and maintenance of models, solvers and algorithms.
@@ -91,9 +92,9 @@ Cornflow helps you formalize your problem by proposing development guidelines. I
91
92
  Installation instructions
92
93
  -------------------------------
93
94
 
94
- Cornflow is tested with Ubuntu 20.04, python >= 3.8 and git.
95
+ cornflow is tested with Ubuntu 20.04, python >= 3.8 and git.
95
96
 
96
- Download the Cornflow project and install requirements::
97
+ Download the cornflow project and install requirements::
97
98
 
98
99
  python3 -m venv venv
99
100
  venv/bin/pip3 install cornflow
@@ -109,7 +110,7 @@ initialize the sqlite database::
109
110
  flask create_admin_user -u cornflow -e cornflow_admin@admin.com -p cornflow_admin_password
110
111
 
111
112
 
112
- activate the virtual environment and run Cornflow::
113
+ activate the virtual environment and run cornflow::
113
114
 
114
115
  source venv/bin/activate
115
116
  export FLASK_APP=cornflow.app
@@ -120,7 +121,7 @@ activate the virtual environment and run Cornflow::
120
121
  export AIRFLOW_PWD=airflow_pwd
121
122
  flask run
122
123
 
123
- **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.
124
+ **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.
124
125
 
125
126
  Using cornflow to solve a PuLP model
126
127
  ---------------------------------------
@@ -1,4 +1,4 @@
1
- Cornflow
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
- 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/>`_.
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.), Cornflow focuses on the optimization problems themselves. However, it does not impose any constraint on the type of problem and solution method to use.
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 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.
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
- Cornflow helps you formalize your problem by proposing development guidelines. It also provides a range of functionalities around your deployed solution method, namely:
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
- Cornflow is tested with Ubuntu 20.04, python >= 3.8 and git.
43
+ cornflow is tested with Ubuntu 20.04, python >= 3.8 and git.
44
44
 
45
- Download the Cornflow project and install requirements::
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 Cornflow::
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
- **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.
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 Cornflow environment. Airflow™ is a platform created by the community to programmatically author, schedule and monitor workflows."),
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
- migrate = Migrate(app=app, db=db)
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, con_record):
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
- def upgrade_migrations():
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
- upgrade()
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 (
@@ -16,7 +17,14 @@ from cornflow.commands import (
16
17
  update_schemas_command,
17
18
  update_dag_registry_command,
18
19
  )
19
- from cornflow.shared.const import AUTH_DB, ADMIN_ROLE, SERVICE_ROLE
20
+ from cornflow.shared.const import (
21
+ AUTH_DB,
22
+ AUTH_LDAP,
23
+ AUTH_OID,
24
+ ADMIN_ROLE,
25
+ SERVICE_ROLE,
26
+ PLANNER_ROLE,
27
+ )
20
28
  from cornflow.shared import db
21
29
  from cryptography.fernet import Fernet
22
30
  from flask_migrate import Migrate, upgrade
@@ -49,15 +57,8 @@ def init_cornflow_service():
49
57
  os.environ["SECRET_KEY"] = os.getenv("FERNET_KEY", Fernet.generate_key().decode())
50
58
 
51
59
  # Cornflow db defaults
52
- cornflow_db_host = os.getenv("CORNFLOW_DB_HOST", "cornflow_db")
53
- cornflow_db_port = os.getenv("CORNFLOW_DB_PORT", "5432")
54
- cornflow_db_user = os.getenv("CORNFLOW_DB_USER", "cornflow")
55
- cornflow_db_password = os.getenv("CORNFLOW_DB_PASSWORD", "cornflow")
56
- cornflow_db = os.getenv("CORNFLOW_DB", "cornflow")
57
- cornflow_db_conn = os.getenv(
58
- "cornflow_db_conn",
59
- f"postgresql://{cornflow_db_user}:{cornflow_db_password}@{cornflow_db_host}:{cornflow_db_port}/{cornflow_db}",
60
- )
60
+ os.environ["DEFAULT_POSTGRES"] = "1"
61
+ cornflow_db_conn = get_db_conn()
61
62
  os.environ["DATABASE_URL"] = cornflow_db_conn
62
63
 
63
64
  # Platform auth config and service users
@@ -83,11 +84,11 @@ def init_cornflow_service():
83
84
  os.environ["SIGNUP_ACTIVATED"] = str(signup_activated)
84
85
  user_access_all_objects = os.getenv("USER_ACCESS_ALL_OBJECTS", 0)
85
86
  os.environ["USER_ACCESS_ALL_OBJECTS"] = str(user_access_all_objects)
86
- default_role = os.getenv("DEFAULT_ROLE", 2)
87
+ default_role = int(os.getenv("DEFAULT_ROLE", PLANNER_ROLE))
87
88
  os.environ["DEFAULT_ROLE"] = str(default_role)
88
89
 
89
90
  # Check LDAP parameters for active directory and show message
90
- if os.getenv("AUTH_TYPE") == 2:
91
+ if os.getenv("AUTH_TYPE") == AUTH_LDAP:
91
92
  print(
92
93
  "WARNING: Cornflow will be deployed with LDAP Authorization. Please review your ldap auth configuration."
93
94
  )
@@ -129,10 +130,11 @@ def init_cornflow_service():
129
130
  app = create_app(environment, cornflow_db_conn)
130
131
  with app.app_context():
131
132
  path = f"{os.path.dirname(cornflow.__file__)}/migrations"
132
- migrate = Migrate(app=app, db=db, directory=path)
133
+ Migrate(app=app, db=db, directory=path)
133
134
  upgrade()
134
135
  access_init_command(verbose=False)
135
- if auth == 1 or auth == 0:
136
+ if auth == AUTH_DB or auth == AUTH_OID:
137
+ # create cornflow admin user
136
138
  create_user_with_role(
137
139
  cornflow_admin_user,
138
140
  cornflow_admin_email,
@@ -188,7 +190,7 @@ def init_cornflow_service():
188
190
  migrate = Migrate(app=app, db=db, directory=path)
189
191
  upgrade()
190
192
  access_init_command(verbose=False)
191
- if auth == 1 or auth == 0:
193
+ if auth == AUTH_DB or auth == AUTH_OID:
192
194
  # create cornflow admin user
193
195
  create_user_with_role(
194
196
  cornflow_admin_user,
@@ -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
+ )
@@ -1,5 +1,5 @@
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
5
 
@@ -28,7 +28,7 @@ class DefaultConfig(object):
28
28
  SIGNUP_ACTIVATED = int(os.getenv("SIGNUP_ACTIVATED", 1))
29
29
  CORNFLOW_SERVICE_USER = os.getenv("CORNFLOW_SERVICE_USER", "service_user")
30
30
 
31
- # If service user is allow to log with username and password
31
+ # If service user is allowed to log with username and password
32
32
  SERVICE_USER_ALLOW_PASSWORD_LOGIN = int(
33
33
  os.getenv("SERVICE_USER_ALLOW_PASSWORD_LOGIN", 1)
34
34
  )
@@ -59,15 +59,13 @@ class DefaultConfig(object):
59
59
  LDAP_PROTOCOL_VERSION = int(os.getenv("LDAP_PROTOCOL_VERSION", 3))
60
60
  LDAP_USE_TLS = os.getenv("LDAP_USE_TLS", "False")
61
61
 
62
- # OpenID login -> Default Azure
63
- OID_PROVIDER = os.getenv("OID_PROVIDER", 0)
64
- OID_CLIENT_ID = os.getenv("OID_CLIENT_ID")
65
- OID_TENANT_ID = os.getenv("OID_TENANT_ID")
66
- OID_ISSUER = os.getenv("OID_ISSUER")
62
+ # OpenID Connect configuration
63
+ OID_PROVIDER = os.getenv("OID_PROVIDER")
64
+ OID_EXPECTED_AUDIENCE = os.getenv("OID_EXPECTED_AUDIENCE")
67
65
 
68
66
  # APISPEC:
69
67
  APISPEC_SPEC = APISpec(
70
- title="Cornflow API docs",
68
+ title="cornflow API docs",
71
69
  version="v1",
72
70
  plugins=[MarshmallowPlugin()],
73
71
  openapi_version="2.0.0",
@@ -127,8 +125,9 @@ class TestingOpenAuth(Testing):
127
125
  """
128
126
  Configuration class for testing some edge cases with Open Auth login
129
127
  """
130
-
131
- AUTH_TYPE = 0
128
+ AUTH_TYPE = AUTH_OID
129
+ OID_PROVIDER = "https://test-provider.example.com"
130
+ OID_EXPECTED_AUDIENCE = "test-audience-id"
132
131
 
133
132
 
134
133
  class TestingApplicationRoot(Testing):
@@ -158,5 +157,5 @@ app_config = {
158
157
  "testing": Testing,
159
158
  "production": Production,
160
159
  "testing-oauth": TestingOpenAuth,
161
- "testing-root": TestingApplicationRoot,
160
+ "testing-root": TestingApplicationRoot
162
161
  }
@@ -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,
@@ -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)