cornflow 1.2.0a3__py3-none-any.whl → 1.2.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cornflow/app.py +3 -1
- cornflow/cli/__init__.py +4 -0
- cornflow/cli/actions.py +4 -0
- cornflow/cli/config.py +4 -0
- cornflow/cli/migrations.py +13 -8
- cornflow/cli/permissions.py +4 -0
- cornflow/cli/roles.py +4 -0
- cornflow/cli/schemas.py +5 -0
- cornflow/cli/service.py +235 -131
- cornflow/cli/tools/api_generator.py +13 -10
- cornflow/cli/tools/endpoint_tools.py +191 -196
- cornflow/cli/tools/models_tools.py +87 -60
- cornflow/cli/tools/schema_generator.py +161 -67
- cornflow/cli/tools/schemas_tools.py +4 -5
- cornflow/cli/users.py +8 -0
- cornflow/cli/views.py +4 -0
- cornflow/commands/dag.py +3 -2
- cornflow/commands/schemas.py +6 -4
- cornflow/commands/users.py +12 -17
- cornflow/endpoints/dag.py +27 -25
- cornflow/endpoints/data_check.py +128 -165
- cornflow/endpoints/example_data.py +9 -3
- cornflow/endpoints/execution.py +40 -34
- cornflow/endpoints/health.py +7 -7
- cornflow/endpoints/instance.py +39 -12
- cornflow/endpoints/meta_resource.py +4 -5
- cornflow/schemas/execution.py +9 -1
- cornflow/schemas/health.py +1 -0
- cornflow/shared/authentication/auth.py +73 -42
- cornflow/shared/const.py +10 -1
- cornflow/shared/exceptions.py +3 -1
- cornflow/shared/utils_tables.py +36 -8
- cornflow/shared/validators.py +1 -1
- cornflow/tests/const.py +1 -0
- cornflow/tests/custom_test_case.py +4 -4
- cornflow/tests/unit/test_alarms.py +1 -2
- cornflow/tests/unit/test_cases.py +4 -7
- cornflow/tests/unit/test_executions.py +22 -1
- cornflow/tests/unit/test_health.py +4 -1
- cornflow/tests/unit/test_log_in.py +46 -9
- cornflow/tests/unit/test_tables.py +3 -3
- {cornflow-1.2.0a3.dist-info → cornflow-1.2.2.dist-info}/METADATA +5 -5
- {cornflow-1.2.0a3.dist-info → cornflow-1.2.2.dist-info}/RECORD +46 -46
- {cornflow-1.2.0a3.dist-info → cornflow-1.2.2.dist-info}/WHEEL +1 -1
- {cornflow-1.2.0a3.dist-info → cornflow-1.2.2.dist-info}/entry_points.txt +0 -0
- {cornflow-1.2.0a3.dist-info → cornflow-1.2.2.dist-info}/top_level.txt +0 -0
cornflow/shared/utils_tables.py
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
import inspect
|
3
3
|
import os
|
4
4
|
import sys
|
5
|
+
import collections
|
5
6
|
|
6
7
|
from importlib import import_module
|
7
8
|
from sqlalchemy.dialects.postgresql import TEXT
|
@@ -31,14 +32,42 @@ def import_models():
|
|
31
32
|
|
32
33
|
|
33
34
|
def all_subclasses(cls, models=None):
|
34
|
-
subclasses
|
35
|
+
"""Finds all direct and indirect subclasses of a given class.
|
36
|
+
|
37
|
+
Optionally filters a provided list of models first.
|
38
|
+
|
39
|
+
Args:
|
40
|
+
cls: The base class to find subclasses for.
|
41
|
+
models: An optional iterable of classes to pre-filter.
|
42
|
+
|
43
|
+
Returns:
|
44
|
+
A set containing all subclasses found.
|
45
|
+
"""
|
46
|
+
filtered_subclasses = set()
|
35
47
|
if models is not None:
|
36
48
|
for val in models:
|
37
|
-
|
38
|
-
|
49
|
+
# Ensure val is a class before checking issubclass
|
50
|
+
if isinstance(val, type) and issubclass(val, cls):
|
51
|
+
filtered_subclasses.add(val)
|
52
|
+
|
53
|
+
all_descendants = set()
|
54
|
+
# Use a deque for efficient pop(0)
|
55
|
+
queue = collections.deque(cls.__subclasses__())
|
56
|
+
# Keep track of visited classes during the traversal to handle potential complex hierarchies
|
57
|
+
# (though direct subclass relationships shouldn't form cycles)
|
58
|
+
# Initialize with direct subclasses as they are the starting point.
|
59
|
+
visited_for_queue = set(cls.__subclasses__())
|
60
|
+
|
61
|
+
while queue:
|
62
|
+
current_sub = queue.popleft()
|
63
|
+
all_descendants.add(current_sub)
|
64
|
+
|
65
|
+
for grandchild in current_sub.__subclasses__():
|
66
|
+
if grandchild not in visited_for_queue:
|
67
|
+
visited_for_queue.add(grandchild)
|
68
|
+
queue.append(grandchild)
|
39
69
|
|
40
|
-
return
|
41
|
-
[s for c in cls.__subclasses__() for s in all_subclasses(c)]))
|
70
|
+
return filtered_subclasses.union(all_descendants)
|
42
71
|
|
43
72
|
|
44
73
|
type_converter = {
|
@@ -76,6 +105,5 @@ def item_as_dict(item):
|
|
76
105
|
|
77
106
|
def items_as_dict_list(ls):
|
78
107
|
return [
|
79
|
-
{c.name: getattr(item, c.name) for c in item.__table__.columns}
|
80
|
-
|
81
|
-
]
|
108
|
+
{c.name: getattr(item, c.name) for c in item.__table__.columns} for item in ls
|
109
|
+
]
|
cornflow/shared/validators.py
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
"""
|
2
2
|
This file has several validators
|
3
3
|
"""
|
4
|
+
|
4
5
|
import re
|
5
6
|
from typing import Tuple, Union
|
6
7
|
|
7
8
|
from jsonschema import Draft7Validator, validators
|
8
9
|
from disposable_email_domains import blocklist
|
9
|
-
from jsonschema.protocols import Validator
|
10
10
|
|
11
11
|
|
12
12
|
def is_special_character(character):
|
cornflow/tests/const.py
CHANGED
@@ -17,6 +17,7 @@ INSTANCE_GC_20 = _get_file("./data/gc_20_7.json")
|
|
17
17
|
INSTANCE_FILE_FAIL = _get_file("./unit/test_instances.py")
|
18
18
|
|
19
19
|
EXECUTION_PATH = _get_file("./data/new_execution.json")
|
20
|
+
CUSTOM_CONFIG_PATH = _get_file("./data/new_execution_custom_config.json")
|
20
21
|
BAD_EXECUTION_PATH = _get_file("./data/bad_execution.json")
|
21
22
|
EXECUTION_SOLUTION_PATH = _get_file("./data/new_execution_solution.json")
|
22
23
|
EXECUTIONS_LIST = [EXECUTION_PATH, _get_file("./data/new_execution_2.json")]
|
@@ -635,9 +635,9 @@ class BaseTestCases:
|
|
635
635
|
# (we patch the request to airflow to check if the schema is valid)
|
636
636
|
# we create 4 instances
|
637
637
|
data_many = [self.payload for _ in range(4)]
|
638
|
-
|
639
|
-
|
640
|
-
self.apply_filter(self.url, dict(schema="timer"),
|
638
|
+
|
639
|
+
self.get_rows(self.url, data_many)
|
640
|
+
self.apply_filter(self.url, dict(schema="timer"), [])
|
641
641
|
|
642
642
|
def test_opt_filters_date_lte(self):
|
643
643
|
"""
|
@@ -1117,7 +1117,7 @@ class LoginTestCases:
|
|
1117
1117
|
|
1118
1118
|
self.assertEqual(400, response.status_code)
|
1119
1119
|
self.assertEqual(
|
1120
|
-
"Invalid token
|
1120
|
+
"Invalid token format or signature",
|
1121
1121
|
response.json["error"],
|
1122
1122
|
)
|
1123
1123
|
|
@@ -91,7 +91,6 @@ class TestAlarmsEndpoint(CustomTestCase):
|
|
91
91
|
class TestAlarmsDetailEndpoint(TestAlarmsEndpoint, BaseTestCases.DetailEndpoint):
|
92
92
|
def setUp(self):
|
93
93
|
super().setUp()
|
94
|
-
self.url = self.url
|
95
94
|
self.idx = 0
|
96
95
|
self.payload = {
|
97
96
|
"name": "Alarm 1",
|
@@ -138,4 +137,4 @@ class TestAlarmsDetailEndpoint(TestAlarmsEndpoint, BaseTestCases.DetailEndpoint)
|
|
138
137
|
# We check deleted at has a value
|
139
138
|
self.assertIsNotNone(row.deleted_at)
|
140
139
|
else:
|
141
|
-
self.assertIsNone(row.deleted_at)
|
140
|
+
self.assertIsNone(row.deleted_at)
|
@@ -42,6 +42,7 @@ import zlib
|
|
42
42
|
|
43
43
|
# Import from internal modules
|
44
44
|
from cornflow.models import CaseModel, ExecutionModel, InstanceModel, UserModel
|
45
|
+
from cornflow.shared.const import DATA_DOES_NOT_EXIST_MSG
|
45
46
|
from cornflow.shared.utils import hash_json_256
|
46
47
|
from cornflow.tests.const import (
|
47
48
|
INSTANCE_URL,
|
@@ -227,12 +228,8 @@ class TestCasesFromInstanceExecutionEndpoint(CustomTestCase):
|
|
227
228
|
"execution_id": execution_id,
|
228
229
|
"schema": "solve_model_dag",
|
229
230
|
}
|
230
|
-
self.instance = InstanceModel.get_one_object(
|
231
|
-
|
232
|
-
)
|
233
|
-
self.execution = ExecutionModel.get_one_object(
|
234
|
-
user=self.user, idx=execution_id
|
235
|
-
)
|
231
|
+
self.instance = InstanceModel.get_one_object(user=self.user, idx=instance_id)
|
232
|
+
self.execution = ExecutionModel.get_one_object(user=self.user, idx=execution_id)
|
236
233
|
|
237
234
|
def test_new_case_execution(self):
|
238
235
|
"""
|
@@ -729,7 +726,7 @@ class TestCaseToInstanceEndpoint(CustomTestCase):
|
|
729
726
|
headers=self.get_header_with_auth(self.token),
|
730
727
|
)
|
731
728
|
self.assertEqual(response.status_code, 404)
|
732
|
-
self.assertEqual(response.json["error"],
|
729
|
+
self.assertEqual(response.json["error"], DATA_DOES_NOT_EXIST_MSG)
|
733
730
|
|
734
731
|
|
735
732
|
class TestCaseJsonPatch(CustomTestCase):
|
@@ -18,6 +18,7 @@ from cornflow.tests.const import (
|
|
18
18
|
DAG_URL,
|
19
19
|
BAD_EXECUTION_PATH,
|
20
20
|
EXECUTION_SOLUTION_PATH,
|
21
|
+
CUSTOM_CONFIG_PATH,
|
21
22
|
)
|
22
23
|
from cornflow.tests.custom_test_case import CustomTestCase, BaseTestCases
|
23
24
|
from cornflow.tests.unit.tools import patch_af_client
|
@@ -43,6 +44,7 @@ class TestExecutionsListEndpoint(BaseTestCases.ListFilters):
|
|
43
44
|
self.bad_payload = load_file_fk(BAD_EXECUTION_PATH)
|
44
45
|
self.payloads = [load_file_fk(f) for f in EXECUTIONS_LIST]
|
45
46
|
self.solution = load_file_fk(EXECUTION_SOLUTION_PATH)
|
47
|
+
self.custom_config_payload = load_file_fk(CUSTOM_CONFIG_PATH)
|
46
48
|
self.keys_to_check = [
|
47
49
|
"data_hash",
|
48
50
|
"created_at",
|
@@ -57,11 +59,25 @@ class TestExecutionsListEndpoint(BaseTestCases.ListFilters):
|
|
57
59
|
"instance_id",
|
58
60
|
"name",
|
59
61
|
"indicators",
|
62
|
+
"username",
|
63
|
+
"updated_at"
|
60
64
|
]
|
61
65
|
|
62
66
|
def test_new_execution(self):
|
63
67
|
self.create_new_row(self.url, self.model, payload=self.payload)
|
64
68
|
|
69
|
+
def test_get_custom_config(self):
|
70
|
+
id = self.create_new_row(
|
71
|
+
self.url, self.model, payload=self.custom_config_payload
|
72
|
+
)
|
73
|
+
url = EXECUTION_URL + "/" + str(id) + "/" + "?run=0"
|
74
|
+
|
75
|
+
response = self.get_one_row(
|
76
|
+
url,
|
77
|
+
payload={**self.custom_config_payload, **dict(id=id)},
|
78
|
+
)
|
79
|
+
self.assertEqual(response["config"]["block_model"]["solver"], "mip.gurobi")
|
80
|
+
|
65
81
|
@patch("cornflow.endpoints.execution.Airflow")
|
66
82
|
def test_new_execution_run(self, af_client_class):
|
67
83
|
patch_af_client(af_client_class)
|
@@ -260,6 +276,8 @@ class TestExecutionsDetailEndpointMock(CustomTestCase):
|
|
260
276
|
"schema",
|
261
277
|
"user_id",
|
262
278
|
"indicators",
|
279
|
+
"username",
|
280
|
+
"updated_at"
|
263
281
|
}
|
264
282
|
# we only check the following because this endpoint does not return data
|
265
283
|
self.items_to_check = ["name", "description"]
|
@@ -274,7 +292,6 @@ class TestExecutionsDetailEndpoint(
|
|
274
292
|
):
|
275
293
|
def setUp(self):
|
276
294
|
super().setUp()
|
277
|
-
self.url = self.url
|
278
295
|
self.query_arguments = {"run": 0}
|
279
296
|
|
280
297
|
# TODO: this test should be moved as it is not using the detail endpoint
|
@@ -303,6 +320,8 @@ class TestExecutionsDetailEndpoint(
|
|
303
320
|
"name",
|
304
321
|
"created_at",
|
305
322
|
"state",
|
323
|
+
"username",
|
324
|
+
"updated_at"
|
306
325
|
]
|
307
326
|
execution = self.get_one_row(
|
308
327
|
self.url + idx,
|
@@ -450,6 +469,8 @@ class TestExecutionsLogEndpoint(TestExecutionsDetailEndpointMock):
|
|
450
469
|
"user_id",
|
451
470
|
"config",
|
452
471
|
"indicators",
|
472
|
+
"username",
|
473
|
+
"updated_at"
|
453
474
|
]
|
454
475
|
|
455
476
|
def test_get_one_execution(self):
|
@@ -4,7 +4,7 @@ from cornflow.shared import db
|
|
4
4
|
|
5
5
|
from cornflow.app import create_app
|
6
6
|
from cornflow.commands import access_init_command
|
7
|
-
from cornflow.shared.const import STATUS_HEALTHY
|
7
|
+
from cornflow.shared.const import STATUS_HEALTHY, CORNFLOW_VERSION
|
8
8
|
from cornflow.tests.const import HEALTH_URL
|
9
9
|
from cornflow.tests.custom_test_case import CustomTestCase
|
10
10
|
|
@@ -29,6 +29,9 @@ class TestHealth(CustomTestCase):
|
|
29
29
|
self.assertEqual(200, response.status_code)
|
30
30
|
cf_status = response.json["cornflow_status"]
|
31
31
|
af_status = response.json["airflow_status"]
|
32
|
+
cf_version = response.json["cornflow_version"]
|
33
|
+
expected_version = CORNFLOW_VERSION
|
32
34
|
self.assertEqual(str, type(cf_status))
|
33
35
|
self.assertEqual(str, type(af_status))
|
34
36
|
self.assertEqual(cf_status, STATUS_HEALTHY)
|
37
|
+
self.assertEqual(cf_version, expected_version)
|
@@ -135,11 +135,20 @@ class TestLogInOpenAuth(CustomTestCase):
|
|
135
135
|
Tests token validation failure when the kid is not found in public keys
|
136
136
|
"""
|
137
137
|
# Import the real exceptions to ensure they are preserved
|
138
|
-
from jwt.exceptions import
|
138
|
+
from jwt.exceptions import (
|
139
|
+
InvalidTokenError,
|
140
|
+
ExpiredSignatureError,
|
141
|
+
InvalidIssuerError,
|
142
|
+
InvalidSignatureError,
|
143
|
+
DecodeError,
|
144
|
+
)
|
139
145
|
|
140
146
|
# Keep the real exception classes in the mock
|
141
147
|
mock_jwt.ExpiredSignatureError = ExpiredSignatureError
|
142
148
|
mock_jwt.InvalidTokenError = InvalidTokenError
|
149
|
+
mock_jwt.InvalidIssuerError = InvalidIssuerError
|
150
|
+
mock_jwt.InvalidSignatureError = InvalidSignatureError
|
151
|
+
mock_jwt.DecodeError = DecodeError
|
143
152
|
|
144
153
|
mock_jwt.get_unverified_header.return_value = {"kid": "test_kid"}
|
145
154
|
|
@@ -165,7 +174,7 @@ class TestLogInOpenAuth(CustomTestCase):
|
|
165
174
|
|
166
175
|
self.assertEqual(400, response.status_code)
|
167
176
|
self.assertEqual(
|
168
|
-
response.json["error"], "Invalid token
|
177
|
+
response.json["error"], "Invalid token format, signature, or configuration"
|
169
178
|
)
|
170
179
|
|
171
180
|
@mock.patch("cornflow.shared.authentication.auth.jwt")
|
@@ -174,11 +183,20 @@ class TestLogInOpenAuth(CustomTestCase):
|
|
174
183
|
Tests token validation failure when the token header is missing the kid
|
175
184
|
"""
|
176
185
|
# Import the real exceptions to ensure they are preserved
|
177
|
-
from jwt.exceptions import
|
186
|
+
from jwt.exceptions import (
|
187
|
+
InvalidTokenError,
|
188
|
+
ExpiredSignatureError,
|
189
|
+
InvalidIssuerError,
|
190
|
+
InvalidSignatureError,
|
191
|
+
DecodeError,
|
192
|
+
)
|
178
193
|
|
179
194
|
# Keep the real exception classes in the mock
|
180
195
|
mock_jwt.ExpiredSignatureError = ExpiredSignatureError
|
181
196
|
mock_jwt.InvalidTokenError = InvalidTokenError
|
197
|
+
mock_jwt.InvalidIssuerError = InvalidIssuerError
|
198
|
+
mock_jwt.InvalidSignatureError = InvalidSignatureError
|
199
|
+
mock_jwt.DecodeError = DecodeError
|
182
200
|
|
183
201
|
# Mock jwt.get_unverified_header to return a header without kid
|
184
202
|
mock_jwt.get_unverified_header.return_value = {"alg": "RS256"}
|
@@ -194,8 +212,7 @@ class TestLogInOpenAuth(CustomTestCase):
|
|
194
212
|
|
195
213
|
self.assertEqual(400, response.status_code)
|
196
214
|
self.assertEqual(
|
197
|
-
response.json["error"]
|
198
|
-
"Invalid token: Missing key identifier (kid) in token header",
|
215
|
+
"Invalid token format, signature, or configuration", response.json["error"]
|
199
216
|
)
|
200
217
|
|
201
218
|
@mock.patch("cornflow.shared.authentication.auth.requests.get")
|
@@ -205,11 +222,20 @@ class TestLogInOpenAuth(CustomTestCase):
|
|
205
222
|
Tests failure when trying to fetch public keys from the OIDC provider
|
206
223
|
"""
|
207
224
|
# Import the real exceptions to ensure they are preserved
|
208
|
-
from jwt.exceptions import
|
225
|
+
from jwt.exceptions import (
|
226
|
+
InvalidTokenError,
|
227
|
+
ExpiredSignatureError,
|
228
|
+
InvalidIssuerError,
|
229
|
+
InvalidSignatureError,
|
230
|
+
DecodeError,
|
231
|
+
)
|
209
232
|
|
210
233
|
# Keep the real exception classes in the mock
|
211
234
|
mock_jwt.ExpiredSignatureError = ExpiredSignatureError
|
212
235
|
mock_jwt.InvalidTokenError = InvalidTokenError
|
236
|
+
mock_jwt.InvalidIssuerError = InvalidIssuerError
|
237
|
+
mock_jwt.InvalidSignatureError = InvalidSignatureError
|
238
|
+
mock_jwt.DecodeError = DecodeError
|
213
239
|
|
214
240
|
# Clear the cache
|
215
241
|
from cornflow.shared.authentication.auth import public_keys_cache
|
@@ -240,8 +266,8 @@ class TestLogInOpenAuth(CustomTestCase):
|
|
240
266
|
|
241
267
|
self.assertEqual(400, response.status_code)
|
242
268
|
self.assertEqual(
|
269
|
+
"Invalid token format, signature, or configuration",
|
243
270
|
response.json["error"],
|
244
|
-
"Failed to fetch public keys from authentication provider",
|
245
271
|
)
|
246
272
|
|
247
273
|
@mock.patch("cornflow.shared.authentication.Auth.decode_token")
|
@@ -289,11 +315,20 @@ class TestLogInOpenAuth(CustomTestCase):
|
|
289
315
|
the system fetches fresh keys from the provider.
|
290
316
|
"""
|
291
317
|
# Import the real exceptions to ensure they are preserved
|
292
|
-
from jwt.exceptions import
|
318
|
+
from jwt.exceptions import (
|
319
|
+
InvalidTokenError,
|
320
|
+
ExpiredSignatureError,
|
321
|
+
InvalidIssuerError,
|
322
|
+
InvalidSignatureError,
|
323
|
+
DecodeError,
|
324
|
+
)
|
293
325
|
|
294
326
|
# Keep the real exception classes in the mock
|
295
327
|
mock_jwt.ExpiredSignatureError = ExpiredSignatureError
|
296
328
|
mock_jwt.InvalidTokenError = InvalidTokenError
|
329
|
+
mock_jwt.InvalidIssuerError = InvalidIssuerError
|
330
|
+
mock_jwt.InvalidSignatureError = InvalidSignatureError
|
331
|
+
mock_jwt.DecodeError = DecodeError
|
297
332
|
|
298
333
|
# Mock jwt to return valid unverified header and payload
|
299
334
|
mock_jwt.get_unverified_header.return_value = {"kid": "test_kid"}
|
@@ -531,4 +566,6 @@ class TestLogInOpenAuthService(CustomTestCase):
|
|
531
566
|
)
|
532
567
|
|
533
568
|
self.assertEqual(400, response.status_code)
|
534
|
-
self.assertEqual(
|
569
|
+
self.assertEqual(
|
570
|
+
response.json["error"], "Invalid token format, signature, or configuration"
|
571
|
+
)
|
@@ -11,7 +11,7 @@ from cornflow.app import create_app
|
|
11
11
|
from cornflow.commands.access import access_init_command
|
12
12
|
from cornflow.models import UserRoleModel
|
13
13
|
from cornflow.shared import db
|
14
|
-
from cornflow.shared.const import ADMIN_ROLE, SERVICE_ROLE
|
14
|
+
from cornflow.shared.const import ADMIN_ROLE, SERVICE_ROLE, DATA_DOES_NOT_EXIST_MSG
|
15
15
|
from cornflow.tests.const import LOGIN_URL, SIGNUP_URL, TABLES_URL
|
16
16
|
|
17
17
|
|
@@ -220,7 +220,7 @@ class TestTablesDetailEndpoint(TestCase):
|
|
220
220
|
},
|
221
221
|
)
|
222
222
|
self.assertEqual(response.status_code, 404)
|
223
|
-
self.assertEqual(response.json["error"],
|
223
|
+
self.assertEqual(response.json["error"], DATA_DOES_NOT_EXIST_MSG)
|
224
224
|
|
225
225
|
|
226
226
|
class TestTablesEndpointAdmin(TestCase):
|
@@ -291,4 +291,4 @@ class TestTablesEndpointAdmin(TestCase):
|
|
291
291
|
self.assertEqual(response.status_code, 403)
|
292
292
|
self.assertEqual(
|
293
293
|
response.json["error"], "You do not have permission to access this endpoint"
|
294
|
-
)
|
294
|
+
)
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: cornflow
|
3
|
-
Version: 1.2.
|
3
|
+
Version: 1.2.2
|
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.2.
|
18
|
-
Requires-Dist: cryptography<=
|
17
|
+
Requires-Dist: cornflow-client>=1.2.2
|
18
|
+
Requires-Dist: cryptography<=44.0.1
|
19
19
|
Requires-Dist: disposable-email-domains>=0.0.86
|
20
20
|
Requires-Dist: Flask==2.3.2
|
21
21
|
Requires-Dist: flask-apispec<=0.11.4
|
@@ -29,7 +29,7 @@ Requires-Dist: Flask-SQLAlchemy==2.5.1
|
|
29
29
|
Requires-Dist: gevent==23.9.1
|
30
30
|
Requires-Dist: greenlet<=2.0.2; python_version < "3.11"
|
31
31
|
Requires-Dist: greenlet==3.0.3; python_version >= "3.11"
|
32
|
-
Requires-Dist: gunicorn<=
|
32
|
+
Requires-Dist: gunicorn<=23.0.0
|
33
33
|
Requires-Dist: jsonpatch<=1.33
|
34
34
|
Requires-Dist: ldap3<=2.9.1
|
35
35
|
Requires-Dist: marshmallow<=3.20.2
|
@@ -5,53 +5,53 @@ airflow_config/plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
|
|
5
5
|
airflow_config/plugins/XCom/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
6
6
|
airflow_config/plugins/XCom/gce_xcom_backend.py,sha256=vCGvF2jbfZt5bOv-pk5Q_kUR6LomFUojIymimSJmj3o,1795
|
7
7
|
cornflow/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
|
-
cornflow/app.py,sha256
|
8
|
+
cornflow/app.py,sha256=SHHShEmTqvzZtNShn5AInJxSvwnUmgILwUNpzxNtlNs,7690
|
9
9
|
cornflow/config.py,sha256=c3CNu6wzm5mDJLF6GjrnBKQSNKsRr69S2vQ9jCSAhYw,5628
|
10
10
|
cornflow/gunicorn.py,sha256=uO-Yk7w7nvQSWh12iDxsVvlG-_2BiKIIjm2UiTk4P9E,480
|
11
|
-
cornflow/cli/__init__.py,sha256=
|
12
|
-
cornflow/cli/actions.py,sha256
|
11
|
+
cornflow/cli/__init__.py,sha256=2QfFLxLcX5zYt3Ok3QKNWQvUvAeEnLsH7xiGN3GjwFU,853
|
12
|
+
cornflow/cli/actions.py,sha256=-vm7hUrRTtJA6y0ZK2cIeTKFQi8Wl2Z6ico2px9Fiuk,524
|
13
13
|
cornflow/cli/arguments.py,sha256=9EEyyny5cJJ1t3WAs6zMgTDvTre0JdQ2N_oZfFQmixs,657
|
14
|
-
cornflow/cli/config.py,sha256=
|
15
|
-
cornflow/cli/migrations.py,sha256=
|
16
|
-
cornflow/cli/permissions.py,sha256=
|
17
|
-
cornflow/cli/roles.py,sha256=
|
18
|
-
cornflow/cli/schemas.py,sha256=
|
19
|
-
cornflow/cli/service.py,sha256=
|
20
|
-
cornflow/cli/users.py,sha256=
|
14
|
+
cornflow/cli/config.py,sha256=AWWoLj3AIbKISIJ58Q89OdC_Ocjs_TPLCMF2jTEb5Sw,1258
|
15
|
+
cornflow/cli/migrations.py,sha256=nJbmulqwFxuaSPmo9hJiTl1pUSojeXfAdd9aGM_g9ic,2426
|
16
|
+
cornflow/cli/permissions.py,sha256=fyIp5M0ZpJWVf_tGZG0DN0Gnk1geruadkdKK11cmRk8,1116
|
17
|
+
cornflow/cli/roles.py,sha256=o7P3yt1g2us2B-vv5R7sXNDgUagPsvPGc7ABL0lCBOQ,521
|
18
|
+
cornflow/cli/schemas.py,sha256=s9IUJWa2G0kpqJaN6PcwbwZtGChTaqq451QqWEyWPBI,6197
|
19
|
+
cornflow/cli/service.py,sha256=YGp30zEdrCZg2IIonA0aF2nh2d_0-Q_Cv17HjUQGkXY,12412
|
20
|
+
cornflow/cli/users.py,sha256=VBUqOrS80qdp9E4XLn4ihocHVNWVhWSt19tp0o8mZII,2324
|
21
21
|
cornflow/cli/utils.py,sha256=p54xJEnYWda6rqSQDoZU2qZrFu9kTs4FoF0y3pJLQvI,1377
|
22
|
-
cornflow/cli/views.py,sha256=
|
22
|
+
cornflow/cli/views.py,sha256=BjJRIQ5T3C8zl3-pVVkToVjQ6xdAGwnuT9LVEnn_jqM,746
|
23
23
|
cornflow/cli/tools/__init__.py,sha256=JtyhYfUfirw78BV1mCsdeY0W25fDPWTmZhNBWdDh0wA,19
|
24
|
-
cornflow/cli/tools/api_generator.py,sha256=
|
25
|
-
cornflow/cli/tools/endpoint_tools.py,sha256=
|
26
|
-
cornflow/cli/tools/models_tools.py,sha256=
|
27
|
-
cornflow/cli/tools/schema_generator.py,sha256=
|
28
|
-
cornflow/cli/tools/schemas_tools.py,sha256=
|
24
|
+
cornflow/cli/tools/api_generator.py,sha256=rUafgcpZttjkBkiOv4wwY6JVixo426O18S9VDiWJJZc,16329
|
25
|
+
cornflow/cli/tools/endpoint_tools.py,sha256=xGWaR-o67ZECZhWUcVhNjdjRLjyWfo5_Yt9FcnrXEGc,11610
|
26
|
+
cornflow/cli/tools/models_tools.py,sha256=ZutiYbv8g_rA38Du3IodpSIDIrGZCl2g_nlqamUYtY0,6041
|
27
|
+
cornflow/cli/tools/schema_generator.py,sha256=BQxfB4RvA010BjrXZ4D33AvWU9e7jfZ_m2A-KRupgyg,11219
|
28
|
+
cornflow/cli/tools/schemas_tools.py,sha256=cTAM4_-0uu7dNlv95Oo2edM5qWEnfNKzIt_EhP6qx4c,2232
|
29
29
|
cornflow/cli/tools/tools.py,sha256=Qm0X-wHN12vXYJNRHONGjqDZewwXyXy4R_j4UT_XMLs,929
|
30
30
|
cornflow/commands/__init__.py,sha256=_7mi2Sd8bnaSujU-L78z8Zrswz68NJ2xoocYpsEYmPM,544
|
31
31
|
cornflow/commands/access.py,sha256=NTZJFF9la8TDuMcD_ISQtJTj-wtM2p1dddokQJHtkj0,748
|
32
32
|
cornflow/commands/actions.py,sha256=4AwgAmyI6VeaugkISvTlNGrIzMMU_-ZB3MhwDD_CIEA,1544
|
33
33
|
cornflow/commands/cleanup.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
34
|
-
cornflow/commands/dag.py,sha256=
|
34
|
+
cornflow/commands/dag.py,sha256=AtagFGnB_ucfO0qUawDgd4iRoBCVc-RiOs08DqXSwXM,3786
|
35
35
|
cornflow/commands/permissions.py,sha256=mDPqiY2r2YXlUg4wmZRoI4GAMVFC6AjNT3kqzPEKUw8,6627
|
36
36
|
cornflow/commands/roles.py,sha256=Oux-UkswkQ74zqaMEJYIEsZpQZGBcGaSahVzx9feAHU,1516
|
37
|
-
cornflow/commands/schemas.py,sha256=
|
38
|
-
cornflow/commands/users.py,sha256=
|
37
|
+
cornflow/commands/schemas.py,sha256=40dZSJ2nEqBa7Crb6DbFmnclT5e8ljAIjscOgHr9lhk,1970
|
38
|
+
cornflow/commands/users.py,sha256=2YTbNYY5kZL6ujxGP4fyYgqtv5uuVGdkLR31n7OFFaE,2477
|
39
39
|
cornflow/commands/views.py,sha256=K2Ld1-l1ZKn9m6e2W1LCxmN44QokwR-8u8rIrviiEf8,2276
|
40
40
|
cornflow/endpoints/__init__.py,sha256=ZlwhY8MiynQ0BdATkrsikGM2Kqo4DPxkVTc3faNfzRY,7492
|
41
41
|
cornflow/endpoints/action.py,sha256=ksHK3F919cjkONLcFV2tUIbG-eZw5XbYkqVjYx9iq5I,1359
|
42
42
|
cornflow/endpoints/alarms.py,sha256=M-fpRAm5ZgYyZXvcgS0NHkeMGnvcbfQh2O5qQJUaeoM,4372
|
43
43
|
cornflow/endpoints/apiview.py,sha256=cpxZFkWy6yrRHiAq2tseyVAK1r8uvjnFuOgJjGT0rKI,1370
|
44
44
|
cornflow/endpoints/case.py,sha256=80Fpv9p8mwIXzjQFuyq1PnPTz3RaOUk932sCUfw7yGA,18670
|
45
|
-
cornflow/endpoints/dag.py,sha256=
|
46
|
-
cornflow/endpoints/data_check.py,sha256=
|
47
|
-
cornflow/endpoints/example_data.py,sha256=
|
48
|
-
cornflow/endpoints/execution.py,sha256=
|
49
|
-
cornflow/endpoints/health.py,sha256=
|
50
|
-
cornflow/endpoints/instance.py,sha256=
|
45
|
+
cornflow/endpoints/dag.py,sha256=fWDLfo42mtARZBzXqDrK5JMiIOyrEkYGh4GzKYJLGWk,10087
|
46
|
+
cornflow/endpoints/data_check.py,sha256=6G2XIoyYn0Xh5Fx6rQIgrtiv6M6_xpxHcdVTNi-n4ug,13532
|
47
|
+
cornflow/endpoints/example_data.py,sha256=DiZ7gSilX8XqgJVm4RN5Xto6fWCaMMx12kenfw8pJD0,4427
|
48
|
+
cornflow/endpoints/execution.py,sha256=MjiAan8vLcuWh6l4BO1l9rB_uDbEd4EwowN8XFR7z70,27890
|
49
|
+
cornflow/endpoints/health.py,sha256=l7Xoh5GiqOJv1CiSKkFikUGnNP1NRAD-2xHzeg3Qyjo,1708
|
50
|
+
cornflow/endpoints/instance.py,sha256=KRWXmh5FaCPe-xalbl7fTlb1WUNrEMLSCpK791Dg1eM,12740
|
51
51
|
cornflow/endpoints/licenses.py,sha256=82hHWGYvVIiyw9mlwGtMwJMDJ-ShHOi9rvuM6KvfE4U,873
|
52
52
|
cornflow/endpoints/login.py,sha256=ini7w9kFNoVw981UOvlFIaf45rsnpx6nKFnKrM2uDpo,10698
|
53
53
|
cornflow/endpoints/main_alarms.py,sha256=GUB-UdnvEFi7n6FGFKO9VtZeZb4Ox3NvBMhB7rdqNyI,2006
|
54
|
-
cornflow/endpoints/meta_resource.py,sha256=
|
54
|
+
cornflow/endpoints/meta_resource.py,sha256=hqzOgmYFAzGsXVo0BIb5rjS71uNKVMuyLi-QkAQnb34,8639
|
55
55
|
cornflow/endpoints/permission.py,sha256=FpEBIucfUl89UaJ80SC0VR6pFAdqdSsS43SdNkcXWtI,3751
|
56
56
|
cornflow/endpoints/roles.py,sha256=54ra4MQ9JmrHDsiGczDAVqHgAT4zwhdTA1dLBOy66v8,6105
|
57
57
|
cornflow/endpoints/schemas.py,sha256=lHyvSpPj0x7zVYDlEeRrz_Qqyp6WNimibs5gK4BHpKI,2933
|
@@ -102,8 +102,8 @@ cornflow/schemas/case.py,sha256=OXRsDi_sdB47MQJ59S_1eMjDmLlpUtG7kTFNInV2-cI,2909
|
|
102
102
|
cornflow/schemas/common.py,sha256=QYuxWcOl4smXFZr_vL07OVgH9H50ZywCrXxycVNr1qA,473
|
103
103
|
cornflow/schemas/dag.py,sha256=0ENA75X9L8YqjJW6ZO1Sb4zE8OxB15_O49_nwA6eAVw,901
|
104
104
|
cornflow/schemas/example_data.py,sha256=hbE8TJakFqOweHXiA3mduNETM6FCX6xLTiQuH3EkSTc,281
|
105
|
-
cornflow/schemas/execution.py,sha256=
|
106
|
-
cornflow/schemas/health.py,sha256=
|
105
|
+
cornflow/schemas/execution.py,sha256=Qb2is-EfFDG-S4_9i-37-M6jPO6Et4bLqNm5z9byNOw,4939
|
106
|
+
cornflow/schemas/health.py,sha256=OpK94HNZomv4as_9cM6vBT9eCkn6NY9RmWswXg2qKcA,177
|
107
107
|
cornflow/schemas/instance.py,sha256=qr4km0AlAhoNf9G1Il-pfHphT_vAiiLDpv7A9S3FKAw,1870
|
108
108
|
cornflow/schemas/main_alarms.py,sha256=cC1_Vb1dmo_vdZpZQrA7jH-hRCjVtLRy6Z2JFBlTrlo,604
|
109
109
|
cornflow/schemas/model_json.py,sha256=qUsdd1XmxhcsAmb1JB0xAsvucZoAeQhAQD_3wiY-rVo,202
|
@@ -119,23 +119,23 @@ cornflow/schemas/user_role.py,sha256=e5y6RgdZZtLqD-h2B3sa5WokI5-pT78tWw85IG34I74
|
|
119
119
|
cornflow/schemas/view.py,sha256=ctq9Y1TmjrWdyOqgDYeEx7qbbuNLKfSiNOlFTlXmpaw,429
|
120
120
|
cornflow/shared/__init__.py,sha256=1ahcBwWOsSjGI4FEm77JBQjitBdBszOncKcEMjzwGYE,29
|
121
121
|
cornflow/shared/compress.py,sha256=pohQaGs1xbH8CN6URIH6BAHA--pFq7Hmjz8oI3c3B5c,1347
|
122
|
-
cornflow/shared/const.py,sha256=
|
122
|
+
cornflow/shared/const.py,sha256=ndYbK94cs5tmwX1mFs6S_t5v_mC7il24IcicmNHL9Zw,3553
|
123
123
|
cornflow/shared/email.py,sha256=QNDDMv86LZObkevSCyUbLQeR2UD3zWScPIr82NDzYHQ,3437
|
124
|
-
cornflow/shared/exceptions.py,sha256=
|
124
|
+
cornflow/shared/exceptions.py,sha256=E82488IiwTXCv8iwrnGvkTonhJcwbeE5ARO4Zsmhl2c,6966
|
125
125
|
cornflow/shared/licenses.py,sha256=Lc71Jw2NxVTFWtoXdQ9wJX_o3BDfYg1xVoehDXvnCkQ,1328
|
126
126
|
cornflow/shared/log_config.py,sha256=FM2ajjp2MB4BlFbUHklnWInT7-LLjtrqQ0mo3k_HRmE,621
|
127
127
|
cornflow/shared/query_tools.py,sha256=6yGLCWjv-I2a_ZU4A0IymyJq67fZPZdRcCGOGQQpSXg,1199
|
128
128
|
cornflow/shared/utils.py,sha256=g2ZsD3SwsqIHXZ7GWVAVB0F9gX7mT9dQkPgR2Ahsh6M,860
|
129
|
-
cornflow/shared/utils_tables.py,sha256=
|
130
|
-
cornflow/shared/validators.py,sha256=
|
129
|
+
cornflow/shared/utils_tables.py,sha256=JnyaQ-5d1alj230nir-6elC2i0QX-u-_32SAs2eDtC0,3298
|
130
|
+
cornflow/shared/validators.py,sha256=Iy2jaGzS9ojqlTE_-vKH4oQKD89GN5C0EPEZMg6UZgc,4761
|
131
131
|
cornflow/shared/authentication/__init__.py,sha256=cJIChk5X6hbA_16usEvfHr8g4JDFI6WKo0GPVOOiYHA,137
|
132
|
-
cornflow/shared/authentication/auth.py,sha256=
|
132
|
+
cornflow/shared/authentication/auth.py,sha256=Am4981BchXnwGCUaBg6DlG50TDaT-900KAQ8V-F6umE,18220
|
133
133
|
cornflow/shared/authentication/decorators.py,sha256=_QpwOU1kYzpaK85Dl0Btdj5hG8Ps47PFgySp_gqhlgk,1276
|
134
134
|
cornflow/shared/authentication/ldap.py,sha256=QfdC2X_ZMcIJabKC5pYWDGMhS5pIOJJvdZXuuiruq-M,4853
|
135
135
|
cornflow/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
136
|
-
cornflow/tests/const.py,sha256=
|
136
|
+
cornflow/tests/const.py,sha256=2TT-i8mB31rbo0U4GKWzUbPJya0hEURME_N3yzGhGM8,2635
|
137
137
|
cornflow/tests/custom_liveServer.py,sha256=I_0YNrcKIwVmRov3zCQMWwcCWkMe5V246Hpa4gS8AZE,3079
|
138
|
-
cornflow/tests/custom_test_case.py,sha256=
|
138
|
+
cornflow/tests/custom_test_case.py,sha256=tu8QS_TMdmoPfKQzr9eHSYNC_7T4cmrOjGxxufZ7U04,37797
|
139
139
|
cornflow/tests/integration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
140
140
|
cornflow/tests/integration/test_commands.py,sha256=FZcoEM-05D4MBMe0L0V-0sxk_L0zMbzQxb9UCd7iBe0,695
|
141
141
|
cornflow/tests/integration/test_cornflowclient.py,sha256=ioAQmQKWW6mXVJhdF4LECZcGIOa_N0xPkFaGWGtxOO8,20963
|
@@ -143,34 +143,34 @@ cornflow/tests/ldap/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
|
|
143
143
|
cornflow/tests/ldap/test_ldap_authentication.py,sha256=6Gu1WkF7MQmcV_10IJkpo2qEloZZ9zjpV18ANDD0HRw,4286
|
144
144
|
cornflow/tests/unit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
145
145
|
cornflow/tests/unit/test_actions.py,sha256=plgnzBJnDiZRdVxt1sNJNL2KbW5ijPZ6MHdIUWO0_As,3167
|
146
|
-
cornflow/tests/unit/test_alarms.py,sha256=
|
146
|
+
cornflow/tests/unit/test_alarms.py,sha256=P1QsbT09HuRWCDOALsvPFux9UJg2PgWmGX6pb2hmTXA,4529
|
147
147
|
cornflow/tests/unit/test_apiview.py,sha256=03M1GsQRVK7zqmslhOJXr4lLDLY2gMAgg86nk1lyaKU,7620
|
148
148
|
cornflow/tests/unit/test_application.py,sha256=ZVmTQDUOkPRxHqt6mWU9G_lQ3jJNMJR0cx7IkLMFGrU,1715
|
149
|
-
cornflow/tests/unit/test_cases.py,sha256=
|
149
|
+
cornflow/tests/unit/test_cases.py,sha256=Ez9dxlZL-SUf9DW9b_A_qPowHqUZ-TA73DMOzeBeLIU,37718
|
150
150
|
cornflow/tests/unit/test_cli.py,sha256=E2w-Lzgx_k__0mYwlbg2z80_z9nwPZKI0CbgyGmpQRY,18775
|
151
151
|
cornflow/tests/unit/test_commands.py,sha256=kvO8Vn60rj3WBG2oXw7NpDSEYoGLNe806txbJPhtNJo,14722
|
152
152
|
cornflow/tests/unit/test_dags.py,sha256=XsOi5bBJQdQz3DmYAVJf1myoAsRyBBdmku-xBr0Bku0,13386
|
153
153
|
cornflow/tests/unit/test_data_checks.py,sha256=6s50d1iuRTUcAYn14oEcRS39ZZ6E9ussU4YpkpYhtC4,8612
|
154
154
|
cornflow/tests/unit/test_example_data.py,sha256=D-Tgnqw7NZlnBXaDcUU0reNhAca5JlJP2Sdn3KdS4Sw,4127
|
155
|
-
cornflow/tests/unit/test_executions.py,sha256=
|
155
|
+
cornflow/tests/unit/test_executions.py,sha256=fC9kMRqU3qMGQ9eH6WXlOkU8CKJe6l-DlAKln4ImCSU,18192
|
156
156
|
cornflow/tests/unit/test_generate_from_schema.py,sha256=L1EdnASbDJ8SjrX1V4WnUKKwV0sRTwVnNYnxSpyeSeQ,15376
|
157
|
-
cornflow/tests/unit/test_health.py,sha256=
|
157
|
+
cornflow/tests/unit/test_health.py,sha256=xT0OcnpxbxE0QJlyg4r1qCYDn-hwuk0Ynw5JA4cJtsY,1205
|
158
158
|
cornflow/tests/unit/test_instances.py,sha256=Mf9jijQOcDE3ylPfMTnVRocRegcugEdCnoMCqSmKKqQ,11083
|
159
159
|
cornflow/tests/unit/test_instances_file.py,sha256=sbodxnuoT7n7jdELz-wpVXWt76E5UzUrQYyVpvnfbco,1986
|
160
160
|
cornflow/tests/unit/test_licenses.py,sha256=oj1YdqdxzEdRtxyQiFmRyXyvLzNbl6BeiGCCZH_Y42c,1534
|
161
|
-
cornflow/tests/unit/test_log_in.py,sha256=
|
161
|
+
cornflow/tests/unit/test_log_in.py,sha256=JfAy1GWEL145njCVEf00Eb_MpAzEiyXFwI3H_8prOrw,19289
|
162
162
|
cornflow/tests/unit/test_main_alarms.py,sha256=y--A4Ap2X38TCCRgbimzaZ-QvnTqZY8KHCv7C8kTTwc,2060
|
163
163
|
cornflow/tests/unit/test_permissions.py,sha256=Jd-4PtqBcWGrSZAuTlJD82qE65D9ZtGWBM6sJY1f_yA,8782
|
164
164
|
cornflow/tests/unit/test_roles.py,sha256=1-EON_JsPAM3sVL8AUfgJYLLfb0s1FXL8LJS4nilF-g,18166
|
165
165
|
cornflow/tests/unit/test_schema_from_models.py,sha256=7IfycOGO3U06baX8I-OPJfu-3ZAn5cv8RCdj9wvalMk,4421
|
166
166
|
cornflow/tests/unit/test_schemas.py,sha256=6SpkeYsS3oWntUZEF3GldLqmNa-hpxg-WrKJVTgc-B4,7468
|
167
167
|
cornflow/tests/unit/test_sign_up.py,sha256=-i6VO9z1FwqRHFvaSrpWAzOZx6qa8mHUEmmsjuMXjn8,3481
|
168
|
-
cornflow/tests/unit/test_tables.py,sha256=
|
168
|
+
cornflow/tests/unit/test_tables.py,sha256=SW_K8LRLwR1nB0uH8CPQCjeN8Gei-TasAgkOinnAjLk,8969
|
169
169
|
cornflow/tests/unit/test_token.py,sha256=PZ11b46UCQpCESsRiAPhpgWkGAsAwKCVNxVQai_kxXM,4199
|
170
170
|
cornflow/tests/unit/test_users.py,sha256=N5tcF5nSncD0F_ZlBxGuS87p6kNS4hUzRLr3_AcnK-o,22802
|
171
171
|
cornflow/tests/unit/tools.py,sha256=ag3sWv2WLi498R1GL5AOUnXqSsszD3UugzLZLC5NqAw,585
|
172
|
-
cornflow-1.2.
|
173
|
-
cornflow-1.2.
|
174
|
-
cornflow-1.2.
|
175
|
-
cornflow-1.2.
|
176
|
-
cornflow-1.2.
|
172
|
+
cornflow-1.2.2.dist-info/METADATA,sha256=PMSZtEpia3rytt8MfgpZn2zUEzh-Lwi2LtEVXYBt394,9527
|
173
|
+
cornflow-1.2.2.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
|
174
|
+
cornflow-1.2.2.dist-info/entry_points.txt,sha256=q9cPKAFBsmHkERCqQ2JcOTM-tVBLHTl-DGxwCXowAWM,46
|
175
|
+
cornflow-1.2.2.dist-info/top_level.txt,sha256=Qj9kLFJW1PLb-ZV2s_aCkQ-Wi5W6KC6fFR-LTBrx-rU,24
|
176
|
+
cornflow-1.2.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|