agenta 0.52.6__py3-none-any.whl → 0.63.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.
- agenta/__init__.py +12 -3
- agenta/client/__init__.py +4 -4
- agenta/client/backend/__init__.py +4 -4
- agenta/client/backend/api_keys/client.py +2 -2
- agenta/client/backend/billing/client.py +2 -2
- agenta/client/backend/billing/raw_client.py +2 -2
- agenta/client/backend/client.py +56 -48
- agenta/client/backend/core/client_wrapper.py +2 -2
- agenta/client/backend/core/file.py +3 -1
- agenta/client/backend/core/http_client.py +3 -3
- agenta/client/backend/core/pydantic_utilities.py +13 -3
- agenta/client/backend/human_evaluations/client.py +2 -2
- agenta/client/backend/human_evaluations/raw_client.py +2 -2
- agenta/client/backend/organization/client.py +46 -34
- agenta/client/backend/organization/raw_client.py +32 -26
- agenta/client/backend/raw_client.py +26 -26
- agenta/client/backend/testsets/client.py +18 -18
- agenta/client/backend/testsets/raw_client.py +30 -30
- agenta/client/backend/types/__init__.py +4 -4
- agenta/client/backend/types/account_request.py +3 -1
- agenta/client/backend/types/account_response.py +3 -1
- agenta/client/backend/types/agenta_node_dto.py +3 -1
- agenta/client/backend/types/agenta_nodes_response.py +3 -1
- agenta/client/backend/types/agenta_root_dto.py +3 -1
- agenta/client/backend/types/agenta_roots_response.py +3 -1
- agenta/client/backend/types/agenta_tree_dto.py +3 -1
- agenta/client/backend/types/agenta_trees_response.py +3 -1
- agenta/client/backend/types/aggregated_result.py +3 -1
- agenta/client/backend/types/analytics_response.py +3 -1
- agenta/client/backend/types/annotation.py +6 -4
- agenta/client/backend/types/annotation_create.py +3 -1
- agenta/client/backend/types/annotation_edit.py +3 -1
- agenta/client/backend/types/annotation_link.py +3 -1
- agenta/client/backend/types/annotation_link_response.py +3 -1
- agenta/client/backend/types/annotation_query.py +3 -1
- agenta/client/backend/types/annotation_query_request.py +3 -1
- agenta/client/backend/types/annotation_reference.py +3 -1
- agenta/client/backend/types/annotation_references.py +3 -1
- agenta/client/backend/types/annotation_response.py +3 -1
- agenta/client/backend/types/annotations_response.py +3 -1
- agenta/client/backend/types/app.py +3 -1
- agenta/client/backend/types/app_variant_response.py +3 -1
- agenta/client/backend/types/app_variant_revision.py +3 -1
- agenta/client/backend/types/artifact.py +6 -4
- agenta/client/backend/types/base_output.py +3 -1
- agenta/client/backend/types/body_fetch_workflow_revision.py +3 -1
- agenta/client/backend/types/body_import_testset.py +3 -1
- agenta/client/backend/types/bucket_dto.py +3 -1
- agenta/client/backend/types/collect_status_response.py +3 -1
- agenta/client/backend/types/config_db.py +3 -1
- agenta/client/backend/types/config_dto.py +3 -1
- agenta/client/backend/types/config_response_model.py +3 -1
- agenta/client/backend/types/correct_answer.py +3 -1
- agenta/client/backend/types/create_app_output.py +3 -1
- agenta/client/backend/types/custom_model_settings_dto.py +3 -1
- agenta/client/backend/types/custom_provider_dto.py +3 -1
- agenta/client/backend/types/custom_provider_kind.py +1 -1
- agenta/client/backend/types/custom_provider_settings_dto.py +3 -1
- agenta/client/backend/types/delete_evaluation.py +3 -1
- agenta/client/backend/types/environment_output.py +3 -1
- agenta/client/backend/types/environment_output_extended.py +3 -1
- agenta/client/backend/types/environment_revision.py +3 -1
- agenta/client/backend/types/error.py +3 -1
- agenta/client/backend/types/evaluation.py +3 -1
- agenta/client/backend/types/evaluation_scenario.py +3 -1
- agenta/client/backend/types/evaluation_scenario_input.py +3 -1
- agenta/client/backend/types/evaluation_scenario_output.py +3 -1
- agenta/client/backend/types/evaluation_scenario_result.py +3 -1
- agenta/client/backend/types/evaluator.py +6 -4
- agenta/client/backend/types/evaluator_config.py +6 -4
- agenta/client/backend/types/evaluator_flags.py +3 -1
- agenta/client/backend/types/evaluator_mapping_output_interface.py +3 -1
- agenta/client/backend/types/evaluator_output_interface.py +3 -1
- agenta/client/backend/types/evaluator_query.py +3 -1
- agenta/client/backend/types/evaluator_query_request.py +3 -1
- agenta/client/backend/types/evaluator_request.py +3 -1
- agenta/client/backend/types/evaluator_response.py +3 -1
- agenta/client/backend/types/evaluators_response.py +3 -1
- agenta/client/backend/types/exception_dto.py +3 -1
- agenta/client/backend/types/extended_o_tel_tracing_response.py +3 -1
- agenta/client/backend/types/get_config_response.py +3 -1
- agenta/client/backend/types/header.py +3 -1
- agenta/client/backend/types/http_validation_error.py +3 -1
- agenta/client/backend/types/human_evaluation.py +3 -1
- agenta/client/backend/types/human_evaluation_scenario.py +3 -1
- agenta/client/backend/types/human_evaluation_scenario_input.py +3 -1
- agenta/client/backend/types/human_evaluation_scenario_output.py +3 -1
- agenta/client/backend/types/invite_request.py +3 -1
- agenta/client/backend/types/legacy_analytics_response.py +3 -1
- agenta/client/backend/types/legacy_data_point.py +3 -1
- agenta/client/backend/types/legacy_evaluator.py +3 -1
- agenta/client/backend/types/legacy_scope_request.py +3 -1
- agenta/client/backend/types/legacy_scopes_response.py +3 -1
- agenta/client/backend/types/legacy_subscription_request.py +3 -1
- agenta/client/backend/types/legacy_user_request.py +3 -1
- agenta/client/backend/types/legacy_user_response.py +3 -1
- agenta/client/backend/types/lifecycle_dto.py +3 -1
- agenta/client/backend/types/link_dto.py +3 -1
- agenta/client/backend/types/list_api_keys_response.py +3 -1
- agenta/client/backend/types/llm_run_rate_limit.py +3 -1
- agenta/client/backend/types/meta_request.py +3 -1
- agenta/client/backend/types/metrics_dto.py +3 -1
- agenta/client/backend/types/new_testset.py +3 -1
- agenta/client/backend/types/node_dto.py +3 -1
- agenta/client/backend/types/o_tel_context_dto.py +3 -1
- agenta/client/backend/types/o_tel_event.py +6 -4
- agenta/client/backend/types/o_tel_event_dto.py +3 -1
- agenta/client/backend/types/o_tel_extra_dto.py +3 -1
- agenta/client/backend/types/o_tel_flat_span.py +6 -4
- agenta/client/backend/types/o_tel_link.py +6 -4
- agenta/client/backend/types/o_tel_link_dto.py +3 -1
- agenta/client/backend/types/o_tel_links_response.py +3 -1
- agenta/client/backend/types/o_tel_span.py +1 -1
- agenta/client/backend/types/o_tel_span_dto.py +3 -1
- agenta/client/backend/types/o_tel_spans_tree.py +3 -1
- agenta/client/backend/types/o_tel_tracing_data_response.py +3 -1
- agenta/client/backend/types/o_tel_tracing_request.py +3 -1
- agenta/client/backend/types/o_tel_tracing_response.py +3 -1
- agenta/client/backend/types/organization.py +3 -1
- agenta/client/backend/types/organization_details.py +3 -1
- agenta/client/backend/types/organization_membership_request.py +3 -1
- agenta/client/backend/types/organization_output.py +3 -1
- agenta/client/backend/types/organization_request.py +3 -1
- agenta/client/backend/types/parent_dto.py +3 -1
- agenta/client/backend/types/project_membership_request.py +3 -1
- agenta/client/backend/types/project_request.py +3 -1
- agenta/client/backend/types/project_scope.py +3 -1
- agenta/client/backend/types/projects_response.py +3 -1
- agenta/client/backend/types/reference.py +6 -4
- agenta/client/backend/types/reference_dto.py +3 -1
- agenta/client/backend/types/reference_request_model.py +3 -1
- agenta/client/backend/types/result.py +3 -1
- agenta/client/backend/types/root_dto.py +3 -1
- agenta/client/backend/types/scopes_response_model.py +3 -1
- agenta/client/backend/types/secret_dto.py +3 -1
- agenta/client/backend/types/secret_response_dto.py +3 -1
- agenta/client/backend/types/simple_evaluation_output.py +3 -1
- agenta/client/backend/types/span_dto.py +6 -4
- agenta/client/backend/types/standard_provider_dto.py +3 -1
- agenta/client/backend/types/standard_provider_settings_dto.py +3 -1
- agenta/client/backend/types/status_dto.py +3 -1
- agenta/client/backend/types/tags_request.py +3 -1
- agenta/client/backend/types/testcase_response.py +6 -4
- agenta/client/backend/types/testset.py +6 -4
- agenta/client/backend/types/{test_set_output_response.py → testset_output_response.py} +4 -2
- agenta/client/backend/types/testset_request.py +3 -1
- agenta/client/backend/types/testset_response.py +3 -1
- agenta/client/backend/types/{test_set_simple_response.py → testset_simple_response.py} +4 -2
- agenta/client/backend/types/testsets_response.py +3 -1
- agenta/client/backend/types/time_dto.py +3 -1
- agenta/client/backend/types/tree_dto.py +3 -1
- agenta/client/backend/types/update_app_output.py +3 -1
- agenta/client/backend/types/user_request.py +3 -1
- agenta/client/backend/types/validation_error.py +3 -1
- agenta/client/backend/types/workflow_artifact.py +6 -4
- agenta/client/backend/types/workflow_data.py +3 -1
- agenta/client/backend/types/workflow_flags.py +3 -1
- agenta/client/backend/types/workflow_request.py +3 -1
- agenta/client/backend/types/workflow_response.py +3 -1
- agenta/client/backend/types/workflow_revision.py +6 -4
- agenta/client/backend/types/workflow_revision_request.py +3 -1
- agenta/client/backend/types/workflow_revision_response.py +3 -1
- agenta/client/backend/types/workflow_revisions_response.py +3 -1
- agenta/client/backend/types/workflow_variant.py +6 -4
- agenta/client/backend/types/workflow_variant_request.py +3 -1
- agenta/client/backend/types/workflow_variant_response.py +3 -1
- agenta/client/backend/types/workflow_variants_response.py +3 -1
- agenta/client/backend/types/workflows_response.py +3 -1
- agenta/client/backend/types/workspace.py +3 -1
- agenta/client/backend/types/workspace_member_response.py +3 -1
- agenta/client/backend/types/workspace_membership_request.py +3 -1
- agenta/client/backend/types/workspace_permission.py +3 -1
- agenta/client/backend/types/workspace_request.py +3 -1
- agenta/client/backend/types/workspace_response.py +3 -1
- agenta/client/backend/vault/raw_client.py +4 -4
- agenta/client/backend/workspace/client.py +2 -2
- agenta/client/client.py +102 -88
- agenta/sdk/__init__.py +52 -3
- agenta/sdk/agenta_init.py +43 -16
- agenta/sdk/assets.py +23 -15
- agenta/sdk/context/serving.py +20 -8
- agenta/sdk/context/tracing.py +40 -22
- agenta/sdk/contexts/__init__.py +0 -0
- agenta/sdk/contexts/routing.py +38 -0
- agenta/sdk/contexts/running.py +57 -0
- agenta/sdk/contexts/tracing.py +86 -0
- agenta/sdk/decorators/__init__.py +1 -0
- agenta/sdk/decorators/routing.py +284 -0
- agenta/sdk/decorators/running.py +692 -98
- agenta/sdk/decorators/serving.py +20 -21
- agenta/sdk/decorators/tracing.py +176 -131
- agenta/sdk/engines/__init__.py +0 -0
- agenta/sdk/engines/running/__init__.py +0 -0
- agenta/sdk/engines/running/utils.py +17 -0
- agenta/sdk/engines/tracing/__init__.py +1 -0
- agenta/sdk/engines/tracing/attributes.py +185 -0
- agenta/sdk/engines/tracing/conventions.py +49 -0
- agenta/sdk/engines/tracing/exporters.py +130 -0
- agenta/sdk/engines/tracing/inline.py +1154 -0
- agenta/sdk/engines/tracing/processors.py +190 -0
- agenta/sdk/engines/tracing/propagation.py +102 -0
- agenta/sdk/engines/tracing/spans.py +136 -0
- agenta/sdk/engines/tracing/tracing.py +324 -0
- agenta/sdk/evaluations/__init__.py +2 -0
- agenta/sdk/evaluations/metrics.py +37 -0
- agenta/sdk/evaluations/preview/__init__.py +0 -0
- agenta/sdk/evaluations/preview/evaluate.py +765 -0
- agenta/sdk/evaluations/preview/utils.py +861 -0
- agenta/sdk/evaluations/results.py +66 -0
- agenta/sdk/evaluations/runs.py +153 -0
- agenta/sdk/evaluations/scenarios.py +48 -0
- agenta/sdk/litellm/litellm.py +12 -0
- agenta/sdk/litellm/mockllm.py +6 -8
- agenta/sdk/litellm/mocks/__init__.py +5 -5
- agenta/sdk/managers/applications.py +304 -0
- agenta/sdk/managers/config.py +2 -2
- agenta/sdk/managers/evaluations.py +0 -0
- agenta/sdk/managers/evaluators.py +303 -0
- agenta/sdk/managers/secrets.py +161 -24
- agenta/sdk/managers/shared.py +3 -1
- agenta/sdk/managers/testsets.py +441 -0
- agenta/sdk/managers/vault.py +3 -3
- agenta/sdk/middleware/auth.py +0 -176
- agenta/sdk/middleware/config.py +27 -9
- agenta/sdk/middleware/vault.py +204 -9
- agenta/sdk/middlewares/__init__.py +0 -0
- agenta/sdk/middlewares/routing/__init__.py +0 -0
- agenta/sdk/middlewares/routing/auth.py +263 -0
- agenta/sdk/middlewares/routing/cors.py +30 -0
- agenta/sdk/middlewares/routing/otel.py +29 -0
- agenta/sdk/middlewares/running/__init__.py +0 -0
- agenta/sdk/middlewares/running/normalizer.py +321 -0
- agenta/sdk/middlewares/running/resolver.py +161 -0
- agenta/sdk/middlewares/running/vault.py +140 -0
- agenta/sdk/models/__init__.py +0 -0
- agenta/sdk/models/blobs.py +33 -0
- agenta/sdk/models/evaluations.py +119 -0
- agenta/sdk/models/git.py +126 -0
- agenta/sdk/models/shared.py +167 -0
- agenta/sdk/models/testsets.py +163 -0
- agenta/sdk/models/tracing.py +202 -0
- agenta/sdk/models/workflows.py +753 -0
- agenta/sdk/tracing/attributes.py +4 -4
- agenta/sdk/tracing/exporters.py +67 -17
- agenta/sdk/tracing/inline.py +37 -45
- agenta/sdk/tracing/processors.py +97 -0
- agenta/sdk/tracing/propagation.py +3 -1
- agenta/sdk/tracing/spans.py +4 -0
- agenta/sdk/tracing/tracing.py +13 -15
- agenta/sdk/types.py +222 -22
- agenta/sdk/utils/cache.py +1 -1
- agenta/sdk/utils/client.py +38 -0
- agenta/sdk/utils/helpers.py +13 -12
- agenta/sdk/utils/logging.py +18 -78
- agenta/sdk/utils/references.py +23 -0
- agenta/sdk/workflows/builtin.py +600 -0
- agenta/sdk/workflows/configurations.py +22 -0
- agenta/sdk/workflows/errors.py +292 -0
- agenta/sdk/workflows/handlers.py +1791 -0
- agenta/sdk/workflows/interfaces.py +948 -0
- agenta/sdk/workflows/sandbox.py +118 -0
- agenta/sdk/workflows/utils.py +303 -6
- {agenta-0.52.6.dist-info → agenta-0.63.2.dist-info}/METADATA +37 -33
- agenta-0.63.2.dist-info/RECORD +421 -0
- {agenta-0.52.6.dist-info → agenta-0.63.2.dist-info}/WHEEL +1 -1
- agenta/sdk/middleware/adapt.py +0 -253
- agenta/sdk/middleware/base.py +0 -40
- agenta/sdk/middleware/flags.py +0 -40
- agenta/sdk/workflows/types.py +0 -472
- agenta-0.52.6.dist-info/RECORD +0 -371
- /agenta/sdk/{workflows → engines/running}/registry.py +0 -0
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
from typing import List, Dict, Any, Optional
|
|
2
|
+
from uuid import UUID
|
|
3
|
+
|
|
4
|
+
from agenta.sdk.utils.client import authed_api
|
|
5
|
+
from agenta.sdk.utils.references import get_slug_from_name_and_id
|
|
6
|
+
from agenta.sdk.models.testsets import (
|
|
7
|
+
LegacyTestset,
|
|
8
|
+
#
|
|
9
|
+
Testcase,
|
|
10
|
+
TestsetRevisionData,
|
|
11
|
+
TestsetRevision,
|
|
12
|
+
#
|
|
13
|
+
TestsetRevisionResponse,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
async def _create_legacy_testset(
|
|
18
|
+
*,
|
|
19
|
+
csvdata: List[Dict[str, Any]],
|
|
20
|
+
name: str,
|
|
21
|
+
testset_id: Optional[UUID] = None,
|
|
22
|
+
) -> Optional[TestsetRevision]:
|
|
23
|
+
response = authed_api()(
|
|
24
|
+
method="POST",
|
|
25
|
+
endpoint="/testsets/",
|
|
26
|
+
json={
|
|
27
|
+
"testset_id": str(testset_id) if testset_id else None,
|
|
28
|
+
"name": name,
|
|
29
|
+
"csvdata": csvdata,
|
|
30
|
+
},
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
if response.status_code != 200:
|
|
34
|
+
print("Failed to create testset:", response.status_code, response.text)
|
|
35
|
+
return None
|
|
36
|
+
|
|
37
|
+
legacy_testset = LegacyTestset(**response.json())
|
|
38
|
+
|
|
39
|
+
# print(" --- legacy_testset:", legacy_testset)
|
|
40
|
+
|
|
41
|
+
if not legacy_testset.id or not legacy_testset.name:
|
|
42
|
+
return None
|
|
43
|
+
|
|
44
|
+
testset_revision = TestsetRevision(
|
|
45
|
+
id=UUID(legacy_testset.id),
|
|
46
|
+
slug=get_slug_from_name_and_id(
|
|
47
|
+
name=legacy_testset.name,
|
|
48
|
+
id=UUID(legacy_testset.id),
|
|
49
|
+
),
|
|
50
|
+
name=legacy_testset.name,
|
|
51
|
+
data=TestsetRevisionData(
|
|
52
|
+
testcases=[
|
|
53
|
+
Testcase(
|
|
54
|
+
data=testcase_data,
|
|
55
|
+
testset_id=UUID(legacy_testset.id),
|
|
56
|
+
)
|
|
57
|
+
for testcase_data in csvdata
|
|
58
|
+
]
|
|
59
|
+
),
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
# print(" --- testset_revision:", testset_revision)
|
|
63
|
+
|
|
64
|
+
return testset_revision
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
async def _fetch_legacy_testset(
|
|
68
|
+
testset_id: Optional[UUID] = None,
|
|
69
|
+
#
|
|
70
|
+
name: Optional[str] = None,
|
|
71
|
+
) -> Optional[TestsetRevision]:
|
|
72
|
+
legacy_testset = None
|
|
73
|
+
|
|
74
|
+
if testset_id:
|
|
75
|
+
response = authed_api()(
|
|
76
|
+
method="GET",
|
|
77
|
+
endpoint=f"/testsets/{testset_id}",
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
if response.status_code != 200:
|
|
81
|
+
if response.status_code != 404:
|
|
82
|
+
print("Failed to fetch testset:", response.status_code, response.text)
|
|
83
|
+
return None
|
|
84
|
+
|
|
85
|
+
legacy_testset = LegacyTestset(**response.json())
|
|
86
|
+
elif name:
|
|
87
|
+
response = authed_api()(
|
|
88
|
+
method="GET",
|
|
89
|
+
endpoint="/testsets/",
|
|
90
|
+
params={"name": name},
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
if response.status_code != 200:
|
|
94
|
+
print("Failed to list testsets:", response.status_code, response.text)
|
|
95
|
+
return None
|
|
96
|
+
|
|
97
|
+
_testsets = response.json()
|
|
98
|
+
|
|
99
|
+
for testset in _testsets:
|
|
100
|
+
_id = testset.pop("_id", None)
|
|
101
|
+
testset["id"] = _id
|
|
102
|
+
|
|
103
|
+
legacy_testsets = [LegacyTestset(**testset) for testset in _testsets]
|
|
104
|
+
|
|
105
|
+
if len(legacy_testsets) != 1:
|
|
106
|
+
print("Expected exactly one testset with name:", name)
|
|
107
|
+
return None
|
|
108
|
+
|
|
109
|
+
legacy_testset = legacy_testsets[0]
|
|
110
|
+
|
|
111
|
+
# print(" --- legacy_testset:", legacy_testset)
|
|
112
|
+
|
|
113
|
+
if not legacy_testset.id or not legacy_testset.name:
|
|
114
|
+
return None
|
|
115
|
+
|
|
116
|
+
testset_revision = TestsetRevision(
|
|
117
|
+
testset_id=UUID(legacy_testset.id),
|
|
118
|
+
slug=get_slug_from_name_and_id(
|
|
119
|
+
name=legacy_testset.name,
|
|
120
|
+
id=UUID(legacy_testset.id),
|
|
121
|
+
),
|
|
122
|
+
name=legacy_testset.name,
|
|
123
|
+
data=(
|
|
124
|
+
TestsetRevisionData(
|
|
125
|
+
testcases=[
|
|
126
|
+
Testcase(
|
|
127
|
+
data=testcase_data,
|
|
128
|
+
testset_id=UUID(legacy_testset.id),
|
|
129
|
+
)
|
|
130
|
+
for testcase_data in legacy_testset.csvdata
|
|
131
|
+
]
|
|
132
|
+
)
|
|
133
|
+
if legacy_testset.csvdata
|
|
134
|
+
else None
|
|
135
|
+
),
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
# print(" --- testset_revision:", testset_revision)
|
|
139
|
+
|
|
140
|
+
return testset_revision
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
async def _edit_legacy_testset(
|
|
144
|
+
*,
|
|
145
|
+
testset_id: UUID,
|
|
146
|
+
csvdata: List[Dict[str, Any]],
|
|
147
|
+
name: Optional[str] = None,
|
|
148
|
+
) -> Optional[TestsetRevision]:
|
|
149
|
+
response = authed_api()(
|
|
150
|
+
method="PUT",
|
|
151
|
+
endpoint=f"/testsets/{testset_id}",
|
|
152
|
+
json={
|
|
153
|
+
"name": name,
|
|
154
|
+
"csvdata": csvdata,
|
|
155
|
+
},
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
if response.status_code != 200:
|
|
159
|
+
print("Failed to edit testset:", response.status_code, response.text)
|
|
160
|
+
return None
|
|
161
|
+
|
|
162
|
+
response = authed_api()(
|
|
163
|
+
method="GET",
|
|
164
|
+
endpoint=f"/testsets/{testset_id}",
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
legacy_testset = LegacyTestset(**response.json())
|
|
168
|
+
|
|
169
|
+
# print(" --- legacy_testset:", legacy_testset)
|
|
170
|
+
|
|
171
|
+
if not legacy_testset.id or not legacy_testset.name:
|
|
172
|
+
return None
|
|
173
|
+
|
|
174
|
+
testset_revision = TestsetRevision(
|
|
175
|
+
id=UUID(legacy_testset.id),
|
|
176
|
+
slug=get_slug_from_name_and_id(
|
|
177
|
+
name=legacy_testset.name,
|
|
178
|
+
id=UUID(legacy_testset.id),
|
|
179
|
+
),
|
|
180
|
+
name=legacy_testset.name,
|
|
181
|
+
data=(
|
|
182
|
+
TestsetRevisionData(
|
|
183
|
+
testcases=[
|
|
184
|
+
Testcase(
|
|
185
|
+
data=testcase_data,
|
|
186
|
+
testset_id=UUID(legacy_testset.id),
|
|
187
|
+
)
|
|
188
|
+
for testcase_data in legacy_testset.csvdata
|
|
189
|
+
]
|
|
190
|
+
)
|
|
191
|
+
if legacy_testset.csvdata
|
|
192
|
+
else None
|
|
193
|
+
),
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
# print(" --- testset_revision:", testset_revision)
|
|
197
|
+
|
|
198
|
+
return testset_revision
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
async def _list_legacy_testsets(
|
|
202
|
+
#
|
|
203
|
+
) -> List[TestsetRevision]:
|
|
204
|
+
response = authed_api()(
|
|
205
|
+
method="GET",
|
|
206
|
+
endpoint="/testsets/",
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
if response.status_code != 200:
|
|
210
|
+
print("Failed to list testsets:", response.status_code, response.text)
|
|
211
|
+
return []
|
|
212
|
+
|
|
213
|
+
legacy_testsets = [LegacyTestset(**testset) for testset in response.json()]
|
|
214
|
+
|
|
215
|
+
# print(" --- legacy_testsets:", legacy_testsets)
|
|
216
|
+
|
|
217
|
+
testset_revisions = [
|
|
218
|
+
TestsetRevision(
|
|
219
|
+
id=UUID(legacy_testset.id),
|
|
220
|
+
slug=get_slug_from_name_and_id(
|
|
221
|
+
name=legacy_testset.name,
|
|
222
|
+
id=UUID(legacy_testset.id),
|
|
223
|
+
),
|
|
224
|
+
name=legacy_testset.name,
|
|
225
|
+
data=(
|
|
226
|
+
TestsetRevisionData(
|
|
227
|
+
testcases=[
|
|
228
|
+
Testcase(
|
|
229
|
+
data=testcase_data,
|
|
230
|
+
testset_id=UUID(legacy_testset.id),
|
|
231
|
+
)
|
|
232
|
+
for testcase_data in legacy_testset.csvdata
|
|
233
|
+
]
|
|
234
|
+
)
|
|
235
|
+
if legacy_testset.csvdata
|
|
236
|
+
else None
|
|
237
|
+
),
|
|
238
|
+
)
|
|
239
|
+
for legacy_testset in legacy_testsets
|
|
240
|
+
if legacy_testset.id and legacy_testset.name
|
|
241
|
+
]
|
|
242
|
+
|
|
243
|
+
# print(" --- testset_revisions:", testset_revisions)
|
|
244
|
+
|
|
245
|
+
return testset_revisions
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
async def _retrieve_testset(
|
|
249
|
+
testset_id: Optional[UUID] = None,
|
|
250
|
+
testset_revision_id: Optional[UUID] = None,
|
|
251
|
+
) -> Optional[TestsetRevision]:
|
|
252
|
+
payload = {
|
|
253
|
+
"testset_ref": (
|
|
254
|
+
{
|
|
255
|
+
"id": str(testset_id) if testset_id else None,
|
|
256
|
+
}
|
|
257
|
+
if testset_id
|
|
258
|
+
else None
|
|
259
|
+
),
|
|
260
|
+
"testset_revision_ref": (
|
|
261
|
+
{
|
|
262
|
+
"id": str(testset_revision_id) if testset_revision_id else None,
|
|
263
|
+
}
|
|
264
|
+
if testset_revision_id
|
|
265
|
+
else None
|
|
266
|
+
),
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
# print(" --- payload:", payload)
|
|
270
|
+
|
|
271
|
+
response = authed_api()(
|
|
272
|
+
method="POST",
|
|
273
|
+
endpoint="/preview/testsets/revisions/retrieve",
|
|
274
|
+
json=payload,
|
|
275
|
+
)
|
|
276
|
+
response.raise_for_status()
|
|
277
|
+
|
|
278
|
+
testset_revision_response = TestsetRevisionResponse(**response.json())
|
|
279
|
+
|
|
280
|
+
testset_revision = testset_revision_response.testset_revision
|
|
281
|
+
|
|
282
|
+
# print(" --- testset_revision:", testset_revision)
|
|
283
|
+
|
|
284
|
+
return testset_revision
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
async def _sync_legacy_testset(
|
|
288
|
+
*,
|
|
289
|
+
testset_id: Optional[UUID] = None,
|
|
290
|
+
#
|
|
291
|
+
csvdata: List[Dict[str, Any]],
|
|
292
|
+
#
|
|
293
|
+
name: Optional[str] = None,
|
|
294
|
+
) -> Optional[TestsetRevision]:
|
|
295
|
+
try:
|
|
296
|
+
# print("\n--------- UPSERT TESTSET")
|
|
297
|
+
|
|
298
|
+
# print(" ---:", testset_revision_data.model_dump(mode="json", exclude_none=True))
|
|
299
|
+
|
|
300
|
+
testset_revision = await _fetch_legacy_testset(
|
|
301
|
+
testset_id=testset_id,
|
|
302
|
+
name=name,
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
except Exception as e:
|
|
306
|
+
print("[ERROR]: Failed to prepare testset:", e)
|
|
307
|
+
return None
|
|
308
|
+
|
|
309
|
+
# print("Fetch response:", testset_revision)
|
|
310
|
+
|
|
311
|
+
if testset_revision and testset_revision.testset_id:
|
|
312
|
+
# print(" --- Editing testset...", testset_id)
|
|
313
|
+
|
|
314
|
+
testset_revision = await _edit_legacy_testset(
|
|
315
|
+
testset_id=testset_revision.testset_id,
|
|
316
|
+
name=name,
|
|
317
|
+
csvdata=csvdata,
|
|
318
|
+
)
|
|
319
|
+
|
|
320
|
+
# print("Edit response:", testset_revision)
|
|
321
|
+
|
|
322
|
+
else:
|
|
323
|
+
# print(" --- Creating testset...", name, data)
|
|
324
|
+
|
|
325
|
+
testset_revision = await _create_legacy_testset(
|
|
326
|
+
testset_id=testset_id,
|
|
327
|
+
name=name,
|
|
328
|
+
csvdata=csvdata,
|
|
329
|
+
)
|
|
330
|
+
|
|
331
|
+
if not testset_revision or not testset_revision.id:
|
|
332
|
+
return None
|
|
333
|
+
|
|
334
|
+
# print(" --- testset_revision:", testset_revision)
|
|
335
|
+
|
|
336
|
+
return testset_revision
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
async def aupsert(
|
|
340
|
+
*,
|
|
341
|
+
testset_id: Optional[UUID] = None,
|
|
342
|
+
#
|
|
343
|
+
name: Optional[str] = None,
|
|
344
|
+
#
|
|
345
|
+
data: List[Dict[str, Any]] | TestsetRevisionData,
|
|
346
|
+
) -> Optional[TestsetRevision]:
|
|
347
|
+
csvdata = list()
|
|
348
|
+
if isinstance(data, TestsetRevisionData) and data.testcases:
|
|
349
|
+
csvdata = [testcase.data for testcase in data.testcases]
|
|
350
|
+
elif isinstance(data, list):
|
|
351
|
+
csvdata = data
|
|
352
|
+
else:
|
|
353
|
+
csvdata = list()
|
|
354
|
+
|
|
355
|
+
return await _sync_legacy_testset(
|
|
356
|
+
testset_id=testset_id,
|
|
357
|
+
name=name,
|
|
358
|
+
csvdata=csvdata, # type: ignore
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
async def acreate(
|
|
363
|
+
*,
|
|
364
|
+
testset_id: Optional[UUID | str] = None,
|
|
365
|
+
#
|
|
366
|
+
name: Optional[str] = None,
|
|
367
|
+
#
|
|
368
|
+
data: List[Dict[str, Any]] | TestsetRevisionData,
|
|
369
|
+
) -> Optional[TestsetRevision]:
|
|
370
|
+
csvdata = list()
|
|
371
|
+
if isinstance(data, TestsetRevisionData) and data.testcases:
|
|
372
|
+
csvdata = [testcase.data for testcase in data.testcases]
|
|
373
|
+
elif isinstance(data, list):
|
|
374
|
+
csvdata = data
|
|
375
|
+
else:
|
|
376
|
+
csvdata = list()
|
|
377
|
+
|
|
378
|
+
return await _create_legacy_testset(
|
|
379
|
+
testset_id=(
|
|
380
|
+
testset_id
|
|
381
|
+
if isinstance(testset_id, UUID)
|
|
382
|
+
else UUID(testset_id)
|
|
383
|
+
if testset_id
|
|
384
|
+
else None
|
|
385
|
+
),
|
|
386
|
+
name=name,
|
|
387
|
+
csvdata=csvdata, # type: ignore
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
async def aedit(
|
|
392
|
+
*,
|
|
393
|
+
testset_id: UUID | str,
|
|
394
|
+
#
|
|
395
|
+
name: Optional[str] = None,
|
|
396
|
+
#
|
|
397
|
+
data: List[Dict[str, Any]] | TestsetRevisionData,
|
|
398
|
+
) -> Optional[TestsetRevision]:
|
|
399
|
+
csvdata = list()
|
|
400
|
+
if isinstance(data, TestsetRevisionData) and data.testcases:
|
|
401
|
+
csvdata = [testcase.data for testcase in data.testcases]
|
|
402
|
+
elif isinstance(data, list):
|
|
403
|
+
csvdata = data
|
|
404
|
+
else:
|
|
405
|
+
csvdata = list()
|
|
406
|
+
|
|
407
|
+
return await _edit_legacy_testset(
|
|
408
|
+
testset_id=testset_id if isinstance(testset_id, UUID) else UUID(testset_id),
|
|
409
|
+
name=name,
|
|
410
|
+
csvdata=csvdata, # type: ignore
|
|
411
|
+
)
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
async def afetch(
|
|
415
|
+
*,
|
|
416
|
+
testset_id: UUID | str,
|
|
417
|
+
) -> Optional[TestsetRevision]:
|
|
418
|
+
return await _fetch_legacy_testset(
|
|
419
|
+
testset_id=testset_id if isinstance(testset_id, UUID) else UUID(testset_id)
|
|
420
|
+
)
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
async def alist(
|
|
424
|
+
#
|
|
425
|
+
) -> List[TestsetRevision]:
|
|
426
|
+
return await _list_legacy_testsets()
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
async def aretrieve(
|
|
430
|
+
testset_id: Optional[UUID] = None,
|
|
431
|
+
#
|
|
432
|
+
testset_revision_id: Optional[UUID] = None,
|
|
433
|
+
) -> Optional[TestsetRevision]:
|
|
434
|
+
# print("\n--------- RETRIEVE TESTSET")
|
|
435
|
+
|
|
436
|
+
response = await _retrieve_testset(
|
|
437
|
+
testset_id=testset_id,
|
|
438
|
+
testset_revision_id=testset_revision_id,
|
|
439
|
+
)
|
|
440
|
+
|
|
441
|
+
return response
|
agenta/sdk/managers/vault.py
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
from typing import Optional, Dict, Any
|
|
2
2
|
|
|
3
|
-
from agenta.sdk.
|
|
3
|
+
from agenta.sdk.contexts.routing import RoutingContext
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class VaultManager:
|
|
7
7
|
@staticmethod
|
|
8
8
|
def get_from_route() -> Optional[Dict[str, Any]]:
|
|
9
|
-
context =
|
|
9
|
+
context = RoutingContext.get()
|
|
10
10
|
|
|
11
11
|
secrets = context.secrets
|
|
12
12
|
|
|
13
13
|
if not secrets:
|
|
14
|
-
return
|
|
14
|
+
return []
|
|
15
15
|
|
|
16
16
|
return secrets
|
agenta/sdk/middleware/auth.py
CHANGED
|
@@ -15,17 +15,6 @@ from agenta.sdk.utils.logging import get_module_logger
|
|
|
15
15
|
|
|
16
16
|
import agenta as ag
|
|
17
17
|
|
|
18
|
-
from agenta.sdk.middleware.base import (
|
|
19
|
-
WorkflowMiddleware,
|
|
20
|
-
middleware_as_decorator,
|
|
21
|
-
)
|
|
22
|
-
from agenta.sdk.workflows.types import (
|
|
23
|
-
WorkflowServiceRequest,
|
|
24
|
-
WorkflowServiceResponse,
|
|
25
|
-
WorkflowRevision,
|
|
26
|
-
WorkflowServiceHandler,
|
|
27
|
-
)
|
|
28
|
-
|
|
29
18
|
log = get_module_logger(__name__)
|
|
30
19
|
|
|
31
20
|
AGENTA_RUNTIME_PREFIX = getenv("AGENTA_RUNTIME_PREFIX", "")
|
|
@@ -264,168 +253,3 @@ class AuthHTTPMiddleware(BaseHTTPMiddleware):
|
|
|
264
253
|
status_code=500,
|
|
265
254
|
content=f"Could not verify credentials: unexpected error - {str(exc)}. Please try again later or contact support if the issue persists.",
|
|
266
255
|
) from exc
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
from agenta.sdk.context.tracing import (
|
|
270
|
-
tracing_context_manager,
|
|
271
|
-
tracing_context,
|
|
272
|
-
TracingContext,
|
|
273
|
-
)
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
@middleware_as_decorator
|
|
277
|
-
class AuthMiddleware(WorkflowMiddleware):
|
|
278
|
-
def __init__(self):
|
|
279
|
-
pass
|
|
280
|
-
|
|
281
|
-
async def __call__(
|
|
282
|
-
self,
|
|
283
|
-
request: WorkflowServiceRequest,
|
|
284
|
-
revision: WorkflowRevision,
|
|
285
|
-
handler: WorkflowServiceHandler,
|
|
286
|
-
) -> WorkflowServiceResponse:
|
|
287
|
-
ctx = tracing_context.get()
|
|
288
|
-
|
|
289
|
-
ctx.credentials = request.credentials
|
|
290
|
-
|
|
291
|
-
with tracing_context_manager(context=ctx):
|
|
292
|
-
return await handler(request, revision)
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
# @middleware_as_decorator
|
|
296
|
-
# class AuthMiddleware(WorkflowMiddleware):
|
|
297
|
-
# def __init__(self):
|
|
298
|
-
# self.host = ag.DEFAULT_AGENTA_SINGLETON_INSTANCE.host
|
|
299
|
-
# self.scope_type = ag.DEFAULT_AGENTA_SINGLETON_INSTANCE.scope_type
|
|
300
|
-
# self.scope_id = ag.DEFAULT_AGENTA_SINGLETON_INSTANCE.scope_id
|
|
301
|
-
|
|
302
|
-
# async def __call__(
|
|
303
|
-
# self,
|
|
304
|
-
# request: WorkflowServiceRequest,
|
|
305
|
-
# revision: WorkflowRevision,
|
|
306
|
-
# handler: WorkflowServiceHandler,
|
|
307
|
-
# ) -> WorkflowServiceResponse:
|
|
308
|
-
# try:
|
|
309
|
-
# request.credentials = await self._get_credentials(request)
|
|
310
|
-
|
|
311
|
-
# except DenyException as deny:
|
|
312
|
-
# display_exception("Auth Middleware Exception")
|
|
313
|
-
|
|
314
|
-
# raise deny
|
|
315
|
-
|
|
316
|
-
# except Exception as exc:
|
|
317
|
-
# display_exception("Auth Middleware Exception")
|
|
318
|
-
|
|
319
|
-
# raise DenyException(
|
|
320
|
-
# status_code=500,
|
|
321
|
-
# content="Auth Middleware Unexpected Error.",
|
|
322
|
-
# ) from exc
|
|
323
|
-
|
|
324
|
-
# return await handler(request, revision)
|
|
325
|
-
|
|
326
|
-
# async def _get_credentials(
|
|
327
|
-
# self,
|
|
328
|
-
# request: WorkflowServiceRequest,
|
|
329
|
-
# ) -> Optional[str]:
|
|
330
|
-
# credentials = request.credentials
|
|
331
|
-
|
|
332
|
-
# headers = {"Authorization": credentials} if credentials else None
|
|
333
|
-
|
|
334
|
-
# params = {
|
|
335
|
-
# "action": "run_workflow",
|
|
336
|
-
# "resource_type": "workflow",
|
|
337
|
-
# }
|
|
338
|
-
# if self.scope_type and self.scope_id:
|
|
339
|
-
# params["scope_type"] = self.scope_type
|
|
340
|
-
# params["scope_id"] = self.scope_id
|
|
341
|
-
|
|
342
|
-
# _hash = dumps(
|
|
343
|
-
# {
|
|
344
|
-
# "headers": headers,
|
|
345
|
-
# "params": params,
|
|
346
|
-
# },
|
|
347
|
-
# sort_keys=True,
|
|
348
|
-
# )
|
|
349
|
-
|
|
350
|
-
# if _CACHE_ENABLED:
|
|
351
|
-
# cached = _cache.get(_hash)
|
|
352
|
-
# if cached:
|
|
353
|
-
# return cached
|
|
354
|
-
|
|
355
|
-
# try:
|
|
356
|
-
# async with httpx.AsyncClient() as client:
|
|
357
|
-
# response = await client.get(
|
|
358
|
-
# f"{self.host}/api/permissions/verify",
|
|
359
|
-
# params=params,
|
|
360
|
-
# headers=headers,
|
|
361
|
-
# timeout=5 * 60,
|
|
362
|
-
# )
|
|
363
|
-
|
|
364
|
-
# except httpx.TimeoutException as exc:
|
|
365
|
-
# raise DenyException(
|
|
366
|
-
# status_code=504,
|
|
367
|
-
# content=f"Could not verify credentials: connection to {self.host} timed out. Please check your network connection.",
|
|
368
|
-
# ) from exc
|
|
369
|
-
# except httpx.ConnectError as exc:
|
|
370
|
-
# raise DenyException(
|
|
371
|
-
# status_code=503,
|
|
372
|
-
# content=f"Could not verify credentials: connection to {self.host} failed. Please check if agenta is available.",
|
|
373
|
-
# ) from exc
|
|
374
|
-
# except httpx.NetworkError as exc:
|
|
375
|
-
# raise DenyException(
|
|
376
|
-
# status_code=503,
|
|
377
|
-
# content=f"Could not verify credentials: connection to {self.host} failed. Please check your network connection.",
|
|
378
|
-
# ) from exc
|
|
379
|
-
# except httpx.HTTPError as exc:
|
|
380
|
-
# raise DenyException(
|
|
381
|
-
# status_code=502,
|
|
382
|
-
# content=f"Could not verify credentials: connection to {self.host} failed. Please check if agenta is available.",
|
|
383
|
-
# ) from exc
|
|
384
|
-
# except Exception as exc:
|
|
385
|
-
# raise DenyException(
|
|
386
|
-
# 500,
|
|
387
|
-
# f"Could not verify credentials: unexpected error.\n {exc}",
|
|
388
|
-
# ) from exc
|
|
389
|
-
|
|
390
|
-
# if response.status_code == 401:
|
|
391
|
-
# raise DenyException(
|
|
392
|
-
# status_code=401,
|
|
393
|
-
# content="Invalid credentials. Please check your credentials or login again.",
|
|
394
|
-
# )
|
|
395
|
-
# if response.status_code == 403:
|
|
396
|
-
# raise DenyException(
|
|
397
|
-
# status_code=403,
|
|
398
|
-
# content="Permission denied. Please check your permissions or contact your administrator.",
|
|
399
|
-
# )
|
|
400
|
-
# if response.status_code != 200:
|
|
401
|
-
# raise DenyException(
|
|
402
|
-
# status_code=500,
|
|
403
|
-
# content=f"Could not verify credentials: {self.host} returned unexpected status code {response.status_code}. Please try again later or contact support if the issue persists.",
|
|
404
|
-
# )
|
|
405
|
-
|
|
406
|
-
# try:
|
|
407
|
-
# auth = response.json()
|
|
408
|
-
# except ValueError as exc:
|
|
409
|
-
# raise DenyException(
|
|
410
|
-
# status_code=500,
|
|
411
|
-
# content=f"Could not verify credentials: {self.host} returned unexpected invalid JSON response. Please try again later or contact support if the issue persists.",
|
|
412
|
-
# ) from exc
|
|
413
|
-
|
|
414
|
-
# if not isinstance(auth, dict):
|
|
415
|
-
# raise DenyException(
|
|
416
|
-
# status_code=500,
|
|
417
|
-
# content=f"Could not verify credentials: {self.host} returned unexpected invalid response format. Please try again later or contact support if the issue persists.",
|
|
418
|
-
# )
|
|
419
|
-
|
|
420
|
-
# if auth.get("effect") != "allow":
|
|
421
|
-
# raise DenyException(
|
|
422
|
-
# status_code=403,
|
|
423
|
-
# content="Permission denied. Please check your permissions or contact your administrator.",
|
|
424
|
-
# )
|
|
425
|
-
|
|
426
|
-
# credentials: str = auth.get("credentials")
|
|
427
|
-
|
|
428
|
-
# if credentials is not None:
|
|
429
|
-
# _cache.put(_hash, credentials)
|
|
430
|
-
|
|
431
|
-
# return credentials
|
agenta/sdk/middleware/config.py
CHANGED
|
@@ -93,13 +93,18 @@ class ConfigMiddleware(BaseHTTPMiddleware):
|
|
|
93
93
|
|
|
94
94
|
return parameters, references
|
|
95
95
|
|
|
96
|
-
config =
|
|
96
|
+
config = dict()
|
|
97
|
+
app_ref = None
|
|
97
98
|
|
|
98
99
|
is_test_path = request.url.path.endswith("/test")
|
|
99
100
|
are_refs_missing = not variant_ref and not environment_ref
|
|
100
|
-
|
|
101
|
+
should_fetch_application_revision = not is_test_path or not are_refs_missing
|
|
102
|
+
is_app_ref_incomplete = (
|
|
103
|
+
application_ref and application_ref.id and not application_ref.slug
|
|
104
|
+
)
|
|
105
|
+
should_fetch_application = is_app_ref_incomplete
|
|
101
106
|
|
|
102
|
-
if
|
|
107
|
+
if should_fetch_application_revision:
|
|
103
108
|
async with httpx.AsyncClient() as client:
|
|
104
109
|
response = await client.post(
|
|
105
110
|
f"{self.host}/api/variants/configs/fetch",
|
|
@@ -110,13 +115,26 @@ class ConfigMiddleware(BaseHTTPMiddleware):
|
|
|
110
115
|
if response.status_code == 200:
|
|
111
116
|
config = response.json()
|
|
112
117
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
118
|
+
elif should_fetch_application:
|
|
119
|
+
async with httpx.AsyncClient() as client:
|
|
120
|
+
response = await client.get(
|
|
121
|
+
f"{self.host}/api/apps/{application_ref.id}",
|
|
122
|
+
headers=headers,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
if response.status_code == 200:
|
|
126
|
+
app = response.json()
|
|
127
|
+
app_ref = {
|
|
128
|
+
"id": app.get("app_id"),
|
|
129
|
+
"slug": app.get("app_name"),
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if config:
|
|
119
133
|
parameters = config.get("params")
|
|
134
|
+
else:
|
|
135
|
+
# by default, application_ref will always have an id
|
|
136
|
+
config["application_ref"] = app_ref or refs["application_ref"]
|
|
137
|
+
parameters = None
|
|
120
138
|
|
|
121
139
|
references = {}
|
|
122
140
|
|