cornflow 1.3.5rc4__tar.gz → 1.3.6__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 (193) hide show
  1. {cornflow-1.3.5rc4/cornflow.egg-info → cornflow-1.3.6}/PKG-INFO +4 -4
  2. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/commands/auxiliar.py +2 -2
  3. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/models/execution.py +2 -2
  4. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/schemas/execution.py +5 -0
  5. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/shared/const.py +6 -1
  6. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/base_test_execution.py +0 -1
  7. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_cli.py +5 -5
  8. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_executions.py +162 -0
  9. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_roles.py +13 -5
  10. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_users.py +93 -1
  11. {cornflow-1.3.5rc4 → cornflow-1.3.6/cornflow.egg-info}/PKG-INFO +4 -4
  12. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow.egg-info/requires.txt +3 -3
  13. {cornflow-1.3.5rc4 → cornflow-1.3.6}/requirements.txt +3 -3
  14. {cornflow-1.3.5rc4 → cornflow-1.3.6}/setup.py +1 -1
  15. {cornflow-1.3.5rc4 → cornflow-1.3.6}/MANIFEST.in +0 -0
  16. {cornflow-1.3.5rc4 → cornflow-1.3.6}/README.rst +0 -0
  17. {cornflow-1.3.5rc4 → cornflow-1.3.6}/airflow_config/__init__.py +0 -0
  18. {cornflow-1.3.5rc4 → cornflow-1.3.6}/airflow_config/airflow_local_settings.py +0 -0
  19. {cornflow-1.3.5rc4 → cornflow-1.3.6}/airflow_config/plugins/XCom/__init__.py +0 -0
  20. {cornflow-1.3.5rc4 → cornflow-1.3.6}/airflow_config/plugins/XCom/gce_xcom_backend.py +0 -0
  21. {cornflow-1.3.5rc4 → cornflow-1.3.6}/airflow_config/plugins/__init__.py +0 -0
  22. {cornflow-1.3.5rc4 → cornflow-1.3.6}/airflow_config/webserver_ldap.py +0 -0
  23. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/__init__.py +0 -0
  24. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/app.py +0 -0
  25. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/cli/__init__.py +0 -0
  26. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/cli/actions.py +0 -0
  27. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/cli/arguments.py +0 -0
  28. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/cli/config.py +0 -0
  29. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/cli/migrations.py +0 -0
  30. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/cli/permissions.py +0 -0
  31. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/cli/roles.py +0 -0
  32. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/cli/schemas.py +0 -0
  33. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/cli/service.py +0 -0
  34. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/cli/tools/__init__.py +0 -0
  35. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/cli/tools/api_generator.py +0 -0
  36. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/cli/tools/endpoint_tools.py +0 -0
  37. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/cli/tools/models_tools.py +0 -0
  38. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/cli/tools/schema_generator.py +0 -0
  39. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/cli/tools/schemas_tools.py +0 -0
  40. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/cli/tools/tools.py +0 -0
  41. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/cli/users.py +0 -0
  42. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/cli/utils.py +0 -0
  43. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/cli/views.py +0 -0
  44. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/commands/__init__.py +0 -0
  45. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/commands/access.py +0 -0
  46. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/commands/actions.py +0 -0
  47. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/commands/cleanup.py +0 -0
  48. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/commands/dag.py +0 -0
  49. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/commands/permissions.py +0 -0
  50. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/commands/roles.py +0 -0
  51. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/commands/schemas.py +0 -0
  52. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/commands/users.py +0 -0
  53. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/commands/views.py +0 -0
  54. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/config.py +0 -0
  55. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/endpoints/__init__.py +0 -0
  56. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/endpoints/action.py +0 -0
  57. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/endpoints/alarms.py +0 -0
  58. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/endpoints/apiview.py +0 -0
  59. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/endpoints/case.py +0 -0
  60. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/endpoints/dag.py +0 -0
  61. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/endpoints/data_check.py +0 -0
  62. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/endpoints/example_data.py +0 -0
  63. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/endpoints/execution.py +0 -0
  64. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/endpoints/health.py +0 -0
  65. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/endpoints/instance.py +0 -0
  66. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/endpoints/licenses.py +0 -0
  67. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/endpoints/login.py +0 -0
  68. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/endpoints/main_alarms.py +0 -0
  69. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/endpoints/meta_resource.py +0 -0
  70. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/endpoints/permission.py +0 -0
  71. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/endpoints/roles.py +0 -0
  72. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/endpoints/schemas.py +0 -0
  73. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/endpoints/signup.py +0 -0
  74. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/endpoints/tables.py +0 -0
  75. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/endpoints/token.py +0 -0
  76. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/endpoints/user.py +0 -0
  77. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/endpoints/user_role.py +0 -0
  78. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/gunicorn.py +0 -0
  79. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/migrations/README +0 -0
  80. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/migrations/alembic.ini +0 -0
  81. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/migrations/env.py +0 -0
  82. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/migrations/script.py.mako +0 -0
  83. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/migrations/versions/00757b557b02_.py +0 -0
  84. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/migrations/versions/1af47a419bbd_.py +0 -0
  85. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/migrations/versions/4729cd156460_.py +0 -0
  86. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/migrations/versions/4aac5e0c6e66_.py +0 -0
  87. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/migrations/versions/509d280698e4_.py +0 -0
  88. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/migrations/versions/7c3ea5ab5501_.py +0 -0
  89. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/migrations/versions/991b98e24225_.py +0 -0
  90. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/migrations/versions/999b98e24225.py +0 -0
  91. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/migrations/versions/9cacf194fa1c_.py +0 -0
  92. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/migrations/versions/a472b5ad50b7_.py +0 -0
  93. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/migrations/versions/c2db9409cb5f_.py +0 -0
  94. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/migrations/versions/c8a6c762e818_.py +0 -0
  95. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/migrations/versions/ca449af8034c_.py +0 -0
  96. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/migrations/versions/cef1df240b27_.py +0 -0
  97. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/migrations/versions/d0e0700dcd8e_.py +0 -0
  98. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/migrations/versions/d1b5be1f0549_.py +0 -0
  99. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/migrations/versions/e1a50dae1ac9_.py +0 -0
  100. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/migrations/versions/e937a5234ce4_.py +0 -0
  101. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/migrations/versions/ebdd955fcc5e_.py +0 -0
  102. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/migrations/versions/f3bee20314a2_.py +0 -0
  103. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/models/__init__.py +0 -0
  104. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/models/action.py +0 -0
  105. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/models/alarms.py +0 -0
  106. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/models/base_data_model.py +0 -0
  107. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/models/case.py +0 -0
  108. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/models/dag.py +0 -0
  109. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/models/dag_permissions.py +0 -0
  110. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/models/instance.py +0 -0
  111. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/models/main_alarms.py +0 -0
  112. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/models/meta_models.py +0 -0
  113. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/models/permissions.py +0 -0
  114. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/models/role.py +0 -0
  115. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/models/user.py +0 -0
  116. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/models/user_role.py +0 -0
  117. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/models/view.py +0 -0
  118. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/schemas/__init__.py +0 -0
  119. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/schemas/action.py +0 -0
  120. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/schemas/alarms.py +0 -0
  121. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/schemas/case.py +0 -0
  122. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/schemas/common.py +0 -0
  123. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/schemas/dag.py +0 -0
  124. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/schemas/example_data.py +0 -0
  125. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/schemas/health.py +0 -0
  126. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/schemas/instance.py +0 -0
  127. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/schemas/main_alarms.py +0 -0
  128. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/schemas/model_json.py +0 -0
  129. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/schemas/patch.py +0 -0
  130. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/schemas/permissions.py +0 -0
  131. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/schemas/query.py +0 -0
  132. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/schemas/role.py +0 -0
  133. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/schemas/schemas.py +0 -0
  134. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/schemas/solution_log.py +0 -0
  135. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/schemas/tables.py +0 -0
  136. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/schemas/user.py +0 -0
  137. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/schemas/user_role.py +0 -0
  138. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/schemas/view.py +0 -0
  139. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/shared/__init__.py +0 -0
  140. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/shared/authentication/__init__.py +0 -0
  141. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/shared/authentication/auth.py +0 -0
  142. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/shared/authentication/decorators.py +0 -0
  143. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/shared/authentication/ldap.py +0 -0
  144. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/shared/compress.py +0 -0
  145. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/shared/email.py +0 -0
  146. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/shared/exceptions.py +0 -0
  147. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/shared/licenses.py +0 -0
  148. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/shared/log_config.py +0 -0
  149. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/shared/query_tools.py +0 -0
  150. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/shared/utils.py +0 -0
  151. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/shared/utils_tables.py +0 -0
  152. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/shared/validators.py +0 -0
  153. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/__init__.py +0 -0
  154. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/const.py +0 -0
  155. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/custom_liveServer.py +0 -0
  156. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/custom_test_case.py +0 -0
  157. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/integration/__init__.py +0 -0
  158. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/integration/test_commands.py +0 -0
  159. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/integration/test_cornflowclient.py +0 -0
  160. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/integration/test_data_checks_kpis.py +0 -0
  161. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/ldap/__init__.py +0 -0
  162. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/ldap/test_ldap_authentication.py +0 -0
  163. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/__init__.py +0 -0
  164. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_actions.py +0 -0
  165. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_alarms.py +0 -0
  166. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_apiview.py +0 -0
  167. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_application.py +0 -0
  168. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_cases.py +0 -0
  169. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_commands.py +0 -0
  170. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_dags.py +0 -0
  171. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_data_checks.py +0 -0
  172. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_example_data.py +0 -0
  173. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_external_role_creation.py +0 -0
  174. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_generate_from_schema.py +0 -0
  175. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_get_resources.py +0 -0
  176. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_health.py +0 -0
  177. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_instances.py +0 -0
  178. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_instances_file.py +0 -0
  179. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_licenses.py +0 -0
  180. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_log_in.py +0 -0
  181. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_main_alarms.py +0 -0
  182. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_permissions.py +0 -0
  183. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_schema_from_models.py +0 -0
  184. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_schemas.py +0 -0
  185. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_sign_up.py +0 -0
  186. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_tables.py +0 -0
  187. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/test_token.py +0 -0
  188. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow/tests/unit/tools.py +0 -0
  189. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow.egg-info/SOURCES.txt +0 -0
  190. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow.egg-info/dependency_links.txt +0 -0
  191. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow.egg-info/entry_points.txt +0 -0
  192. {cornflow-1.3.5rc4 → cornflow-1.3.6}/cornflow.egg-info/top_level.txt +0 -0
  193. {cornflow-1.3.5rc4 → cornflow-1.3.6}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cornflow
3
- Version: 1.3.5rc4
3
+ Version: 1.3.6
4
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
@@ -14,8 +14,8 @@ Requires-Dist: alembic==1.9.2
14
14
  Requires-Dist: apispec==6.3.0
15
15
  Requires-Dist: cachetools==5.3.3
16
16
  Requires-Dist: click==8.1.7
17
- Requires-Dist: cornflow-client==1.3.5rc4
18
- Requires-Dist: cryptography==46.0.5
17
+ Requires-Dist: cornflow-client==1.3.6
18
+ Requires-Dist: cryptography==48.0.1
19
19
  Requires-Dist: disposable-email-domains==0.0.162
20
20
  Requires-Dist: Flask==2.3.2
21
21
  Requires-Dist: flask-apispec==0.11.4
@@ -35,7 +35,7 @@ Requires-Dist: ldap3==2.9.1
35
35
  Requires-Dist: marshmallow==3.26.2
36
36
  Requires-Dist: PuLP==2.9.0
37
37
  Requires-Dist: psycopg2==2.9.9
38
- Requires-Dist: PyJWT==2.12.0
38
+ Requires-Dist: PyJWT==2.13.0
39
39
  Requires-Dist: pytups==0.86.2
40
40
  Requires-Dist: requests==2.32.4
41
41
  Requires-Dist: SQLAlchemy==1.3.21
@@ -87,8 +87,8 @@ def get_new_roles_to_add(extra_permissions, resources_roles_with_access):
87
87
 
88
88
  for role_id in roles_with_access:
89
89
  if role_id not in existing_roles:
90
- if role_id in ALL_DEFAULT_ROLES:
91
- # Create standard role with predefined name
90
+ if role_id in ROLES_MAP:
91
+ # Create role with its predefined name from ROLES_MAP
92
92
  role_name = ROLES_MAP[role_id]
93
93
  new_role = RoleModel(
94
94
  {
@@ -7,6 +7,7 @@ from flask import current_app
7
7
  import hashlib
8
8
  from sqlalchemy.dialects.postgresql import JSON, TEXT
9
9
  from sqlalchemy import desc, or_
10
+ from sqlalchemy.orm import defer
10
11
  from sqlalchemy.sql.expression import false
11
12
 
12
13
  # Imports from internal modules
@@ -184,7 +185,7 @@ class ExecutionModel(BaseDataModel):
184
185
  :return: The objects
185
186
  :rtype: list(:class:`BaseDataModel`)
186
187
  """
187
- query = cls.query.filter(cls.deleted_at == None)
188
+ query = cls.query.options(defer(cls.data), defer(cls.checks)).filter(cls.deleted_at == None)
188
189
  user_access = int(current_app.config["USER_ACCESS_ALL_OBJECTS"])
189
190
  if (
190
191
  user is not None
@@ -207,7 +208,6 @@ class ExecutionModel(BaseDataModel):
207
208
  cls.checks_and_kpis_only.is_(None),
208
209
  )
209
210
  )
210
- # if airflow they also return total_entries = query.count(), for some reason
211
211
 
212
212
  return query.order_by(desc(cls.created_at)).offset(offset).limit(limit).all()
213
213
 
@@ -150,6 +150,11 @@ class ExecutionDetailsWithIndicatorsAndLogResponse(
150
150
  ):
151
151
  log = fields.Nested(BasicLogSchema, attribute="log_json")
152
152
 
153
+ class Meta:
154
+ # Exclude 'indicators' from the list endpoint schema: data is deferred in
155
+ # get_all_objects, so accessing obj.data here would trigger N+1 lazy loads.
156
+ exclude = ("indicators",)
157
+
153
158
 
154
159
  class ExecutionStatusEndpointResponse(Schema):
155
160
  id = fields.Str()
@@ -7,7 +7,7 @@ AIRFLOW_BACKEND = 1
7
7
  DATABRICKS_BACKEND = 2
8
8
 
9
9
 
10
- CORNFLOW_VERSION = "1.3.5rc4"
10
+ CORNFLOW_VERSION = "1.3.6"
11
11
  INTERNAL_TOKEN_ISSUER = "cornflow"
12
12
 
13
13
  # endpoints responses for health check
@@ -99,6 +99,7 @@ DELETE_ACTION = 5
99
99
 
100
100
  ALL_DEFAULT_ACTIONS = [GET_ACTION, PATCH_ACTION, POST_ACTION, PUT_ACTION, DELETE_ACTION]
101
101
 
102
+ DUMMY_ROLE = 0
102
103
  VIEWER_ROLE = 1
103
104
  PLANNER_ROLE = 2
104
105
  ADMIN_ROLE = 3
@@ -123,6 +124,7 @@ PERMISSION_METHOD_MAP = {
123
124
  }
124
125
 
125
126
  ROLES_MAP = {
127
+ DUMMY_ROLE: "dummy",
126
128
  PLANNER_ROLE: "planner",
127
129
  VIEWER_ROLE: "viewer",
128
130
  ADMIN_ROLE: "admin",
@@ -149,7 +151,10 @@ BASE_PERMISSION_ASSIGNATION = [
149
151
  ]
150
152
 
151
153
  EXTRA_PERMISSION_ASSIGNATION = [
154
+ (DUMMY_ROLE, GET_ACTION, "user-detail"),
155
+ (DUMMY_ROLE, PUT_ACTION, "user-detail"),
152
156
  (VIEWER_ROLE, PUT_ACTION, "user-detail"),
157
+ (DUMMY_ROLE, GET_ACTION, "user-roles"),
153
158
  (VIEWER_ROLE, GET_ACTION, "user-roles"),
154
159
  (PLANNER_ROLE, GET_ACTION, "user-roles"),
155
160
  (SERVICE_ROLE, GET_ACTION, "user-roles"),
@@ -104,7 +104,6 @@ class BaseExecutionList(BaseTestCases.ListFilters, ABC):
104
104
  "log",
105
105
  "instance_id",
106
106
  "name",
107
- "indicators",
108
107
  "username",
109
108
  "first_name",
110
109
  "last_name",
@@ -249,7 +249,7 @@ class CLITests(TestCase):
249
249
  result = runner.invoke(cli, ["roles", "init", "-v"])
250
250
  self.assertEqual(result.exit_code, 0)
251
251
  roles = RoleModel.get_all_objects().all()
252
- self.assertEqual(len(roles), 4)
252
+ self.assertEqual(len(roles), 5)
253
253
 
254
254
  def test_views_entrypoint(self):
255
255
  """
@@ -325,9 +325,9 @@ class CLITests(TestCase):
325
325
  views = ViewModel.get_all_objects().all()
326
326
  permissions = PermissionViewRoleModel.get_all_objects().all()
327
327
  self.assertEqual(len(actions), 5)
328
- self.assertEqual(len(roles), 4)
328
+ self.assertEqual(len(roles), 5)
329
329
  self.assertEqual(len(views), (len(resources) + len(alarms_resources)))
330
- self.assertEqual(len(permissions), 629)
330
+ self.assertEqual(len(permissions), 632)
331
331
 
332
332
  def test_permissions_base_command(self):
333
333
  """
@@ -351,9 +351,9 @@ class CLITests(TestCase):
351
351
  views = ViewModel.get_all_objects().all()
352
352
  permissions = PermissionViewRoleModel.get_all_objects().all()
353
353
  self.assertEqual(len(actions), 5)
354
- self.assertEqual(len(roles), 4)
354
+ self.assertEqual(len(roles), 5)
355
355
  self.assertEqual(len(views), (len(resources) + len(alarms_resources)))
356
- self.assertEqual(len(permissions), 629)
356
+ self.assertEqual(len(permissions), 632)
357
357
 
358
358
  def test_service_entrypoint(self):
359
359
  """
@@ -12,6 +12,7 @@ from datetime import datetime, timedelta, timezone
12
12
  from unittest.mock import patch
13
13
 
14
14
  from flask import current_app
15
+ from sqlalchemy import event, inspect as sa_inspect
15
16
  from cornflow.app import create_app
16
17
  from cornflow.tests import base_test_execution
17
18
 
@@ -30,9 +31,11 @@ from cornflow.shared.const import (
30
31
  VIEWER_ROLE,
31
32
  )
32
33
  from cornflow.tests.const import (
34
+ DAG_URL,
33
35
  EXECUTION_FILES_CLEANUP_URL,
34
36
  EXECUTION_FILES_URL,
35
37
  EXECUTION_PATH,
38
+ EXECUTION_SOLUTION_PATH,
36
39
  EXECUTION_URL_NORUN,
37
40
  INSTANCE_PATH,
38
41
  INSTANCE_URL,
@@ -492,3 +495,162 @@ class TestExecutionFilesEndpoint(CustomTestCase):
492
495
  self.assertEqual("0 files were deleted.", response.json["message"])
493
496
 
494
497
  # endregion
498
+
499
+
500
+ class TestExecutionListDataLoading(CustomTestCase):
501
+ """
502
+ Tests that the execution list endpoint does not load heavy columns from the
503
+ database and returns only the expected basic fields.
504
+ """
505
+
506
+ def setUp(self):
507
+ super().setUp()
508
+ # Load instance fixture and create a parent instance
509
+ with open(INSTANCE_PATH) as f:
510
+ instance_payload = json.load(f)
511
+ self.instance_id = self.create_new_row(
512
+ INSTANCE_URL, InstanceModel, instance_payload
513
+ )
514
+
515
+ # Load execution fixture and create the execution (without triggering a run)
516
+ with open(EXECUTION_PATH) as f:
517
+ execution_payload = json.load(f)
518
+ execution_payload["instance_id"] = self.instance_id
519
+ self.execution_id = self.create_new_row(
520
+ EXECUTION_URL_NORUN, ExecutionModel, execution_payload
521
+ )
522
+
523
+ # Use a service user to push solution data into the execution via the DAG
524
+ # endpoint so that the `data` column is non-NULL in the database.
525
+ service_token = self.create_service_user()
526
+ with open(EXECUTION_SOLUTION_PATH) as f:
527
+ solution_data = json.load(f)
528
+ self.update_row(
529
+ url=DAG_URL + self.execution_id + "/",
530
+ change={"data": solution_data},
531
+ payload_to_check={},
532
+ check_payload=False,
533
+ token=service_token,
534
+ )
535
+
536
+ def _capture_queries_for_get_all_objects(self):
537
+ captured_queries = []
538
+
539
+ def _listener(conn, cursor, statement, parameters, context, executemany):
540
+ captured_queries.append(statement)
541
+
542
+ engine = db.engine
543
+ event.listen(engine, "before_cursor_execute", _listener)
544
+ try:
545
+ executions = ExecutionModel.get_all_objects(user=self.user)
546
+ finally:
547
+ event.remove(engine, "before_cursor_execute", _listener)
548
+
549
+ return executions, captured_queries
550
+
551
+ def test_data_is_deferred_in_list_via_sqlalchemy_inspect(self):
552
+ executions = ExecutionModel.get_all_objects(user=self.user)
553
+
554
+ self.assertGreater(
555
+ len(executions),
556
+ 0,
557
+ "Expected at least one execution to be returned by get_all_objects",
558
+ )
559
+
560
+ for execution in executions:
561
+ state = sa_inspect(execution)
562
+ self.assertIn(
563
+ "data",
564
+ state.unloaded,
565
+ "'data' should be deferred (not loaded eagerly) in the list query.",
566
+ )
567
+
568
+ def test_data_is_not_in_select_via_sql_interception(self):
569
+ executions, captured_queries = self._capture_queries_for_get_all_objects()
570
+
571
+ self.assertGreater(
572
+ len(executions),
573
+ 0,
574
+ "Expected at least one execution to be returned by get_all_objects",
575
+ )
576
+
577
+ self.assertTrue(
578
+ len(captured_queries) > 0,
579
+ "No SQL queries were captured; the event listener may not have fired.",
580
+ )
581
+
582
+ data_in_query = any(
583
+ '"data"' in q or " data," in q.lower() or " data " in q.lower()
584
+ for q in captured_queries
585
+ )
586
+ self.assertFalse(
587
+ data_in_query,
588
+ "The SELECT generated by get_all_objects must not include the 'data' column. "
589
+ "Captured queries: " + str(captured_queries),
590
+ )
591
+
592
+ def test_list_endpoint_does_not_return_indicators(self):
593
+ from cornflow.tests.const import EXECUTION_URL
594
+
595
+ response = self.client.get(
596
+ EXECUTION_URL,
597
+ follow_redirects=True,
598
+ headers=self.get_header_with_auth(self.token),
599
+ )
600
+
601
+ self.assertEqual(
602
+ 200,
603
+ response.status_code,
604
+ f"GET /execution/ returned unexpected status {response.status_code}",
605
+ )
606
+
607
+ items = response.json
608
+ self.assertIsInstance(items, list)
609
+ self.assertGreater(len(items), 0, "Expected at least one execution in the list")
610
+
611
+ for item in items:
612
+ self.assertNotIn(
613
+ "indicators",
614
+ item,
615
+ "'indicators' must not appear in execution list items.",
616
+ )
617
+
618
+ def test_list_endpoint_returns_basic_fields(self):
619
+ from cornflow.tests.const import EXECUTION_URL
620
+
621
+ response = self.client.get(
622
+ EXECUTION_URL,
623
+ follow_redirects=True,
624
+ headers=self.get_header_with_auth(self.token),
625
+ )
626
+
627
+ self.assertEqual(200, response.status_code)
628
+
629
+ items = response.json
630
+ self.assertIsInstance(items, list)
631
+ self.assertGreater(len(items), 0, "Expected at least one execution in the list")
632
+
633
+ required_fields = [
634
+ "id",
635
+ "name",
636
+ "description",
637
+ "created_at",
638
+ "updated_at",
639
+ "user_id",
640
+ "username",
641
+ "data_hash",
642
+ "state",
643
+ "message",
644
+ "config",
645
+ "instance_id",
646
+ "schema",
647
+ "log",
648
+ ]
649
+
650
+ for item in items:
651
+ for field in required_fields:
652
+ self.assertIn(
653
+ field,
654
+ item,
655
+ f"Required field '{field}' is missing from the execution list response.",
656
+ )
@@ -19,6 +19,8 @@ from cornflow.models import (
19
19
  )
20
20
  from cornflow.shared.const import (
21
21
  ADMIN_ROLE,
22
+ ALL_DEFAULT_ROLES,
23
+ DUMMY_ROLE,
22
24
  PLANNER_ROLE,
23
25
  ROLES_MAP,
24
26
  SERVICE_ROLE,
@@ -82,7 +84,7 @@ class TestRolesListEndpoint(CustomTestCase):
82
84
  )
83
85
 
84
86
  self.assertEqual(200, response.status_code)
85
- self.assertEqual(5, len(response.json))
87
+ self.assertEqual(6, len(response.json))
86
88
 
87
89
  def test_get_no_roles(self):
88
90
  for role in ROLES_MAP:
@@ -254,7 +256,7 @@ class TestUserRolesListEndpoint(CustomTestCase):
254
256
  self.assertEqual(200, response.status_code)
255
257
  self.assertCountEqual(self.payload, response.json)
256
258
 
257
- for role in (VIEWER_ROLE, PLANNER_ROLE, SERVICE_ROLE):
259
+ for role in (VIEWER_ROLE, PLANNER_ROLE, SERVICE_ROLE, DUMMY_ROLE):
258
260
  self.token = self.create_user_with_role(role)
259
261
  user = UserModel.get_one_object(username=f"testuser{role}")
260
262
  response = self.client.get(
@@ -484,18 +486,24 @@ class TestRolesModelMethods(CustomTestCase):
484
486
  """
485
487
  Tests the get_all_objects method
486
488
  """
487
- # We expect 4 roles to be present (from ROLES_MAP constant)
489
+ # We expect 5 roles to be present (from ROLES_MAP constant)
488
490
  instances = RoleModel.get_all_objects().all()
489
- self.assertEqual(len(instances), 4)
491
+ self.assertEqual(len(instances), 5)
490
492
 
491
493
  # Check that all the roles from ROLES_MAP are present
492
494
  role_names = [role.name for role in instances]
493
495
  expected_names = list(ROLES_MAP.values())
494
496
  self.assertCountEqual(role_names, expected_names)
495
497
 
498
+ # The dummy role is registered with its ROLES_MAP name and is not a default role
499
+ dummy_role = RoleModel.get_one_object(idx=DUMMY_ROLE)
500
+ self.assertIsNotNone(dummy_role)
501
+ self.assertEqual(dummy_role.name, "dummy")
502
+ self.assertNotIn(DUMMY_ROLE, ALL_DEFAULT_ROLES)
503
+
496
504
  # Test offset parameter - should get all except the first role
497
505
  instances = RoleModel.get_all_objects(offset=1).all()
498
- self.assertEqual(len(instances), 3)
506
+ self.assertEqual(len(instances), 4)
499
507
 
500
508
  # Get the names of all roles except the first one
501
509
  remaining_roles = [role.name for role in instances]
@@ -30,7 +30,13 @@ from cornflow.models import (
30
30
  UserRoleModel,
31
31
  )
32
32
  from cornflow.shared import db
33
- from cornflow.shared.const import ADMIN_ROLE, SERVICE_ROLE, PLANNER_ROLE, VIEWER_ROLE
33
+ from cornflow.shared.const import (
34
+ ADMIN_ROLE,
35
+ DUMMY_ROLE,
36
+ SERVICE_ROLE,
37
+ PLANNER_ROLE,
38
+ VIEWER_ROLE,
39
+ )
34
40
  from cornflow.tests.const import (
35
41
  CASE_PATH,
36
42
  CASE_URL,
@@ -89,6 +95,12 @@ class TestUserEndpoint(TestCase):
89
95
  password="Tpass_service_user1",
90
96
  )
91
97
 
98
+ self.dummy = dict(
99
+ username="aDummyUser",
100
+ email="dummy@test.com",
101
+ password="Testpassword1!",
102
+ )
103
+
92
104
  self.login_keys = ["username", "password"]
93
105
  self.items_to_check = ["email", "username", "id"]
94
106
  self.modifiable_items = [
@@ -106,6 +118,7 @@ class TestUserEndpoint(TestCase):
106
118
  self.admin,
107
119
  self.admin_2,
108
120
  self.service_user,
121
+ self.dummy,
109
122
  ]
110
123
 
111
124
  for u_data in self.payloads:
@@ -142,6 +155,17 @@ class TestUserEndpoint(TestCase):
142
155
  )
143
156
  user_role.save()
144
157
 
158
+ if "dummy" in u_data["email"]:
159
+ user_role = UserRoleModel(
160
+ {"user_id": u_data["id"], "role_id": DUMMY_ROLE}
161
+ )
162
+ user_role.save()
163
+
164
+ UserRoleModel.query.filter_by(
165
+ user_id=u_data["id"], role_id=PLANNER_ROLE
166
+ ).delete()
167
+ db.session.commit()
168
+
145
169
  db.session.commit()
146
170
  register_dag_permissions_command(verbose=False)
147
171
 
@@ -391,6 +415,74 @@ class TestUserEndpoint(TestCase):
391
415
  response = self.log_in(self.planner)
392
416
  self.assertEqual(False, response.json["change_password"])
393
417
 
418
+ def test_dummy_gets_own_user_detail(self):
419
+ # the dummy role can read its own user info
420
+ response = self.get_user(self.dummy, self.dummy)
421
+ self.assertEqual(200, response.status_code)
422
+ self.assertEqual(self.dummy["id"], response.json["id"])
423
+
424
+ def test_dummy_cannot_get_other_user_detail(self):
425
+ # the dummy role can not read another user's info
426
+ response = self.get_user(self.dummy, self.planner)
427
+ self.assertEqual(400, response.status_code)
428
+ self.assertTrue("error" in response.json)
429
+
430
+ def test_dummy_edits_own_user_info(self):
431
+ # the dummy role can edit its own user info
432
+ payload = {"first_name": "Dummy", "last_name": "User"}
433
+ response = self.modify_info(self.dummy, self.dummy, payload)
434
+ self.assertEqual(200, response.status_code)
435
+ self.assertEqual("Updated correctly", response.json["message"])
436
+
437
+ response = self.get_user(self.dummy, self.dummy)
438
+ self.assertEqual(200, response.status_code)
439
+ self.assertEqual("Dummy", response.json["first_name"])
440
+
441
+ def test_dummy_cannot_edit_other_user_info(self):
442
+ # the dummy role can not edit another user's info
443
+ payload = {"first_name": "Nope"}
444
+ response = self.modify_info(self.dummy, self.planner, payload)
445
+ self.assertEqual(403, response.status_code)
446
+ self.assertTrue("error" in response.json)
447
+
448
+ def test_dummy_cannot_get_all_users(self):
449
+ # the dummy role can not list all the users
450
+ response = self.get_user(self.dummy)
451
+ self.assertEqual(403, response.status_code)
452
+ self.assertTrue("error" in response.json)
453
+
454
+ def test_dummy_cannot_delete_user(self):
455
+ # the dummy role has no delete permission, even on itself
456
+ response = self.delete_user(self.dummy, self.dummy)
457
+ self.assertEqual(403, response.status_code)
458
+
459
+ def test_dummy_cannot_get_instances(self):
460
+ # the dummy role can not access unrelated endpoints
461
+ token = self.log_in(self.dummy).json["token"]
462
+ response = self.client.get(
463
+ INSTANCE_URL,
464
+ follow_redirects=True,
465
+ headers={
466
+ "Content-Type": "application/json",
467
+ "Authorization": "Bearer " + token,
468
+ },
469
+ )
470
+ self.assertEqual(403, response.status_code)
471
+
472
+ def test_dummy_cannot_post_instance(self):
473
+ # permission is denied before any payload validation
474
+ token = self.log_in(self.dummy).json["token"]
475
+ response = self.client.post(
476
+ INSTANCE_URL,
477
+ data=json.dumps({}),
478
+ follow_redirects=True,
479
+ headers={
480
+ "Content-Type": "application/json",
481
+ "Authorization": "Bearer " + token,
482
+ },
483
+ )
484
+ self.assertEqual(403, response.status_code)
485
+
394
486
 
395
487
  class TestUserModel(TestCase):
396
488
  def create_app(self):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cornflow
3
- Version: 1.3.5rc4
3
+ Version: 1.3.6
4
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
@@ -14,8 +14,8 @@ Requires-Dist: alembic==1.9.2
14
14
  Requires-Dist: apispec==6.3.0
15
15
  Requires-Dist: cachetools==5.3.3
16
16
  Requires-Dist: click==8.1.7
17
- Requires-Dist: cornflow-client==1.3.5rc4
18
- Requires-Dist: cryptography==46.0.5
17
+ Requires-Dist: cornflow-client==1.3.6
18
+ Requires-Dist: cryptography==48.0.1
19
19
  Requires-Dist: disposable-email-domains==0.0.162
20
20
  Requires-Dist: Flask==2.3.2
21
21
  Requires-Dist: flask-apispec==0.11.4
@@ -35,7 +35,7 @@ Requires-Dist: ldap3==2.9.1
35
35
  Requires-Dist: marshmallow==3.26.2
36
36
  Requires-Dist: PuLP==2.9.0
37
37
  Requires-Dist: psycopg2==2.9.9
38
- Requires-Dist: PyJWT==2.12.0
38
+ Requires-Dist: PyJWT==2.13.0
39
39
  Requires-Dist: pytups==0.86.2
40
40
  Requires-Dist: requests==2.32.4
41
41
  Requires-Dist: SQLAlchemy==1.3.21
@@ -2,8 +2,8 @@ alembic==1.9.2
2
2
  apispec==6.3.0
3
3
  cachetools==5.3.3
4
4
  click==8.1.7
5
- cornflow-client==1.3.5rc4
6
- cryptography==46.0.5
5
+ cornflow-client==1.3.6
6
+ cryptography==48.0.1
7
7
  disposable-email-domains==0.0.162
8
8
  Flask==2.3.2
9
9
  flask-apispec==0.11.4
@@ -21,7 +21,7 @@ ldap3==2.9.1
21
21
  marshmallow==3.26.2
22
22
  PuLP==2.9.0
23
23
  psycopg2==2.9.9
24
- PyJWT==2.12.0
24
+ PyJWT==2.13.0
25
25
  pytups==0.86.2
26
26
  requests==2.32.4
27
27
  SQLAlchemy==1.3.21
@@ -2,8 +2,8 @@ alembic==1.9.2
2
2
  apispec==6.3.0
3
3
  cachetools==5.3.3
4
4
  click==8.1.7
5
- cornflow-client==1.3.5rc4
6
- cryptography==46.0.5
5
+ cornflow-client==1.3.6
6
+ cryptography==48.0.1
7
7
  disposable-email-domains==0.0.162
8
8
  Flask==2.3.2
9
9
  flask-apispec==0.11.4
@@ -23,7 +23,7 @@ ldap3==2.9.1
23
23
  marshmallow==3.26.2
24
24
  PuLP==2.9.0
25
25
  psycopg2==2.9.9
26
- PyJWT==2.12.0
26
+ PyJWT==2.13.0
27
27
  pytups==0.86.2
28
28
  requests==2.32.4
29
29
  SQLAlchemy==1.3.21
@@ -9,7 +9,7 @@ with open("requirements.txt", "r") as fh:
9
9
 
10
10
  setuptools.setup(
11
11
  name="cornflow",
12
- version="1.3.5rc4",
12
+ version="1.3.6",
13
13
  author="baobab soluciones",
14
14
  author_email="cornflow@baobabsoluciones.es",
15
15
  description="cornflow is an open source multi-solver optimization server with a REST API built using flask.",
File without changes
File without changes
File without changes