octostar-python-client 0.1.759__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.
- octostar/__init__.py +9 -0
- octostar/api/__init__.py +1 -0
- octostar/api/apps/__init__.py +0 -0
- octostar/api/apps/deploy_app.py +210 -0
- octostar/api/apps/execute_app_job.py +188 -0
- octostar/api/apps/get_app_logs.py +210 -0
- octostar/api/apps/get_apps_url.py +188 -0
- octostar/api/apps/get_job_logs.py +210 -0
- octostar/api/apps/get_job_progress.py +162 -0
- octostar/api/apps/kill_job.py +160 -0
- octostar/api/apps/list_app_jobs.py +276 -0
- octostar/api/apps/list_apps.py +251 -0
- octostar/api/apps/set_job_progress.py +216 -0
- octostar/api/apps/undeploy_app.py +160 -0
- octostar/api/metadata/__init__.py +0 -0
- octostar/api/metadata/get_version.py +232 -0
- octostar/api/metadata/get_whoami.py +232 -0
- octostar/api/notifications/__init__.py +0 -0
- octostar/api/notifications/delete_stream.py +222 -0
- octostar/api/notifications/get_subscriptions.py +240 -0
- octostar/api/notifications/publish_notification.py +275 -0
- octostar/api/notifications/pull_events_from_stream.py +282 -0
- octostar/api/notifications/push_event_to_stream.py +265 -0
- octostar/api/notifications/toast.py +264 -0
- octostar/api/ontology/__init__.py +0 -0
- octostar/api/ontology/fetch_ontology_data.py +275 -0
- octostar/api/ontology/get_ontologies.py +237 -0
- octostar/api/ontology/multi_query.py +297 -0
- octostar/api/ontology/query.py +276 -0
- octostar/api/pipeline/__init__.py +1 -0
- octostar/api/pipeline/get_processing_status.py +185 -0
- octostar/api/pipeline/update_processing_status.py +164 -0
- octostar/api/search/__init__.py +0 -0
- octostar/api/search/get_annotations.py +153 -0
- octostar/api/workspace_data/__init__.py +0 -0
- octostar/api/workspace_data/delete_blob.py +212 -0
- octostar/api/workspace_data/delete_entities.py +326 -0
- octostar/api/workspace_data/download_blob.py +235 -0
- octostar/api/workspace_data/get_attachment.py +336 -0
- octostar/api/workspace_data/get_files_tree.py +397 -0
- octostar/api/workspace_data/upload_blob.py +235 -0
- octostar/api/workspace_data/upsert_entities.py +284 -0
- octostar/api/workspace_permissions/__init__.py +0 -0
- octostar/api/workspace_permissions/get_permissions.py +325 -0
- octostar/api/workspace_tags/__init__.py +0 -0
- octostar/api/workspace_tags/delete_tag_from_entities.py +141 -0
- octostar/api/workspace_tags/tag_entities.py +180 -0
- octostar/client.py +492 -0
- octostar/errors.py +50 -0
- octostar/models/__init__.py +249 -0
- octostar/models/acknowledgement.py +74 -0
- octostar/models/acknowledgement_with_data.py +82 -0
- octostar/models/app_status.py +239 -0
- octostar/models/app_status_annotations.py +66 -0
- octostar/models/app_status_labels.py +69 -0
- octostar/models/app_with_url.py +82 -0
- octostar/models/child_processing_status.py +118 -0
- octostar/models/delete_entities_response_401.py +74 -0
- octostar/models/delete_entities_response_409.py +82 -0
- octostar/models/delete_entities_response_500.py +82 -0
- octostar/models/delete_stream_response_401.py +74 -0
- octostar/models/delete_tag_from_entities_response_401.py +74 -0
- octostar/models/deploy_app_json_body.py +90 -0
- octostar/models/deploy_app_json_body_secrets.py +65 -0
- octostar/models/deploy_app_response_200.py +98 -0
- octostar/models/deploy_app_response_200_data.py +60 -0
- octostar/models/deploy_app_response_400.py +82 -0
- octostar/models/deploy_app_response_403.py +82 -0
- octostar/models/deploy_app_response_404.py +82 -0
- octostar/models/deploy_app_response_409.py +82 -0
- octostar/models/deploy_app_response_500.py +82 -0
- octostar/models/entity.py +80 -0
- octostar/models/entity_response.py +99 -0
- octostar/models/entity_response_s3_urls.py +93 -0
- octostar/models/entity_response_s3_urls_additional_property.py +105 -0
- octostar/models/entity_response_s3_urls_additional_property_fields.py +114 -0
- octostar/models/execute_app_job_json_body.py +151 -0
- octostar/models/execute_app_job_json_body_annotation.py +65 -0
- octostar/models/execute_app_job_response_401.py +74 -0
- octostar/models/fetch_ontology_data_response_200.py +60 -0
- octostar/models/fetch_ontology_data_response_401.py +74 -0
- octostar/models/fetch_ontology_data_response_500.py +82 -0
- octostar/models/get_app_logs_response_401.py +74 -0
- octostar/models/get_app_logs_response_404.py +74 -0
- octostar/models/get_app_logs_response_500.py +82 -0
- octostar/models/get_apps_url_json_body.py +76 -0
- octostar/models/get_apps_url_response_401.py +74 -0
- octostar/models/get_apps_url_response_500.py +82 -0
- octostar/models/get_attachment_response_200.py +74 -0
- octostar/models/get_attachment_response_401.py +74 -0
- octostar/models/get_files_tree_response_200.py +106 -0
- octostar/models/get_files_tree_response_200_status.py +8 -0
- octostar/models/get_files_tree_response_400.py +111 -0
- octostar/models/get_files_tree_response_400_data.py +60 -0
- octostar/models/get_files_tree_response_400_status.py +8 -0
- octostar/models/get_files_tree_response_401.py +74 -0
- octostar/models/get_files_tree_response_500.py +111 -0
- octostar/models/get_files_tree_response_500_data.py +60 -0
- octostar/models/get_files_tree_response_500_status.py +8 -0
- octostar/models/get_job_logs_response_401.py +74 -0
- octostar/models/get_job_logs_response_404.py +74 -0
- octostar/models/get_job_logs_response_500.py +82 -0
- octostar/models/get_job_progress_response_401.py +74 -0
- octostar/models/get_object_response_401.py +74 -0
- octostar/models/get_ontologies_response_401.py +74 -0
- octostar/models/get_ontologies_response_500.py +81 -0
- octostar/models/get_permissions_response_200.py +98 -0
- octostar/models/get_permissions_response_400.py +82 -0
- octostar/models/get_permissions_response_401.py +74 -0
- octostar/models/get_permissions_response_500.py +82 -0
- octostar/models/get_processing_status_response_200.py +104 -0
- octostar/models/get_processing_status_response_200_data.py +87 -0
- octostar/models/get_processing_status_response_400.py +82 -0
- octostar/models/get_processing_status_response_500.py +82 -0
- octostar/models/get_subscriptions_response_200_item.py +74 -0
- octostar/models/get_version_response_200.py +74 -0
- octostar/models/get_version_response_404.py +74 -0
- octostar/models/get_whoami_response_200.py +129 -0
- octostar/models/get_whoami_response_401.py +74 -0
- octostar/models/insert_entity.py +114 -0
- octostar/models/insert_entity_base.py +266 -0
- octostar/models/insert_entity_relationships_item.py +107 -0
- octostar/models/insert_entity_request.py +94 -0
- octostar/models/internal_server_error.py +82 -0
- octostar/models/job_execution_result.py +146 -0
- octostar/models/job_status.py +196 -0
- octostar/models/job_status_labels.py +60 -0
- octostar/models/job_with_url.py +82 -0
- octostar/models/kill_job_response_401.py +74 -0
- octostar/models/list_app_jobs_response_401.py +74 -0
- octostar/models/list_app_jobs_response_500.py +82 -0
- octostar/models/list_apps_response_401.py +74 -0
- octostar/models/list_apps_response_500.py +82 -0
- octostar/models/multi_query_json_body.py +100 -0
- octostar/models/multi_query_json_body_queries_item.py +80 -0
- octostar/models/multi_query_response_400.py +82 -0
- octostar/models/multi_query_response_401.py +74 -0
- octostar/models/not_found_error.py +74 -0
- octostar/models/octostar_event.py +96 -0
- octostar/models/octostar_event_octostar_payload.py +100 -0
- octostar/models/octostar_event_octostar_payload_level.py +11 -0
- octostar/models/os_notification.py +122 -0
- octostar/models/processing_status.py +262 -0
- octostar/models/processing_status_code.py +14 -0
- octostar/models/progress_request.py +73 -0
- octostar/models/publish_notification_response_401.py +74 -0
- octostar/models/pull_events_from_stream_response_401.py +74 -0
- octostar/models/push_event_to_stream_response_401.py +74 -0
- octostar/models/query_json_body.py +101 -0
- octostar/models/query_json_body_params.py +60 -0
- octostar/models/query_response_400.py +82 -0
- octostar/models/query_response_401.py +74 -0
- octostar/models/set_job_progress_response_401.py +74 -0
- octostar/models/string_to_value_label_map.py +99 -0
- octostar/models/string_to_value_label_map_data.py +89 -0
- octostar/models/string_to_value_label_map_data_additional_property.py +80 -0
- octostar/models/successful_get_tags.py +103 -0
- octostar/models/successful_insertion.py +98 -0
- octostar/models/tag_entities_response_401.py +74 -0
- octostar/models/toast_level.py +11 -0
- octostar/models/toast_response_401.py +74 -0
- octostar/models/undeploy_app_response_401.py +74 -0
- octostar/models/update_processing_status_response_200.py +82 -0
- octostar/models/update_processing_status_response_400.py +82 -0
- octostar/models/update_processing_status_response_500.py +82 -0
- octostar/models/upsert_entities_response_401.py +74 -0
- octostar/models/upsert_entity.py +114 -0
- octostar/models/upsert_entity_base.py +266 -0
- octostar/models/upsert_entity_relationships_item.py +107 -0
- octostar/py.typed +1 -0
- octostar/types.py +54 -0
- octostar/utils/__init__.py +15 -0
- octostar/utils/chat/__init__.py +0 -0
- octostar/utils/chat/chat.py +513 -0
- octostar/utils/chat/detokenize.py +105 -0
- octostar/utils/chat/get_default_model.py +50 -0
- octostar/utils/chat/list_models.py +91 -0
- octostar/utils/chat/tokenize.py +105 -0
- octostar/utils/commons.py +226 -0
- octostar/utils/exceptions.py +134 -0
- octostar/utils/jobs/__init__.py +0 -0
- octostar/utils/jobs/apps/__init__.py +0 -0
- octostar/utils/jobs/apps/deploy_app.py +81 -0
- octostar/utils/jobs/apps/execute_app_job.py +114 -0
- octostar/utils/jobs/apps/get_app_logs.py +113 -0
- octostar/utils/jobs/apps/get_app_secret.py +102 -0
- octostar/utils/jobs/apps/get_apps_url.py +73 -0
- octostar/utils/jobs/apps/list_app_jobs.py +62 -0
- octostar/utils/jobs/apps/list_apps.py +126 -0
- octostar/utils/jobs/apps/undeploy_app.py +48 -0
- octostar/utils/jobs/get_job_logs.py +113 -0
- octostar/utils/jobs/get_job_progress.py +76 -0
- octostar/utils/jobs/kill_job.py +47 -0
- octostar/utils/jobs/set_job_progress.py +67 -0
- octostar/utils/meta/__init__.py +0 -0
- octostar/utils/meta/get_version.py +30 -0
- octostar/utils/meta/get_whoami.py +30 -0
- octostar/utils/notifications/__init__.py +0 -0
- octostar/utils/notifications/delete_stream.py +58 -0
- octostar/utils/notifications/get_my_subscriptions.py +49 -0
- octostar/utils/notifications/publish_notification.py +73 -0
- octostar/utils/notifications/pull_event_from_stream.py +63 -0
- octostar/utils/notifications/pull_events_from_stream.py +64 -0
- octostar/utils/notifications/push_event_to_stream.py +109 -0
- octostar/utils/notifications/push_events_to_stream.py +137 -0
- octostar/utils/notifications/toast.py +92 -0
- octostar/utils/ontology/__init__.py +10 -0
- octostar/utils/ontology/fetch_ontology_data.py +141 -0
- octostar/utils/ontology/get_ontologies.py +55 -0
- octostar/utils/ontology/multiquery_ontology.py +287 -0
- octostar/utils/ontology/query_ontology.py +186 -0
- octostar/utils/pipeline/__init__.py +1 -0
- octostar/utils/pipeline/get_processing_status.py +230 -0
- octostar/utils/pipeline/update_processing_status.py +286 -0
- octostar/utils/search/__init__.py +11 -0
- octostar/utils/search/bulk_update.py +138 -0
- octostar/utils/search/count.py +117 -0
- octostar/utils/search/get_entity_annotations.py +304 -0
- octostar/utils/search/get_index_definition.py +111 -0
- octostar/utils/search/multi_search.py +129 -0
- octostar/utils/workspace/__init__.py +0 -0
- octostar/utils/workspace/delete_entities.py +247 -0
- octostar/utils/workspace/delete_entity.py +81 -0
- octostar/utils/workspace/delete_relationship.py +78 -0
- octostar/utils/workspace/delete_relationships.py +85 -0
- octostar/utils/workspace/delete_temporary_blob.py +85 -0
- octostar/utils/workspace/extract_entities.py +140 -0
- octostar/utils/workspace/get_filepath_from_item.py +85 -0
- octostar/utils/workspace/get_filepaths_from_items.py +100 -0
- octostar/utils/workspace/get_files_tree.py +102 -0
- octostar/utils/workspace/get_item_from_filepath.py +102 -0
- octostar/utils/workspace/get_items_from_filepaths.py +108 -0
- octostar/utils/workspace/linkcharts/__init__.py +0 -0
- octostar/utils/workspace/linkcharts/create_linkchart.py +241 -0
- octostar/utils/workspace/permissions/PermissionLevel.py +8 -0
- octostar/utils/workspace/permissions/__init__.py +1 -0
- octostar/utils/workspace/permissions/get_permissions.py +81 -0
- octostar/utils/workspace/read_attachment.py +284 -0
- octostar/utils/workspace/read_file.py +113 -0
- octostar/utils/workspace/read_temporary_blob.py +428 -0
- octostar/utils/workspace/saved_searches/__init__.py +0 -0
- octostar/utils/workspace/saved_searches/create_saved_search.py +183 -0
- octostar/utils/workspace/tags/__init__.py +0 -0
- octostar/utils/workspace/tags/delete_tag_from_entities.py +96 -0
- octostar/utils/workspace/tags/tag_entities.py +175 -0
- octostar/utils/workspace/upsert_entities.py +268 -0
- octostar/utils/workspace/upsert_entity.py +110 -0
- octostar/utils/workspace/upsert_relationship.py +128 -0
- octostar/utils/workspace/upsert_relationships.py +194 -0
- octostar/utils/workspace/write_attachment.py +263 -0
- octostar/utils/workspace/write_file.py +335 -0
- octostar/utils/workspace/write_temporary_blob.py +218 -0
- octostar_python_client-0.1.759.dist-info/METADATA +159 -0
- octostar_python_client-0.1.759.dist-info/RECORD +257 -0
- octostar_python_client-0.1.759.dist-info/WHEEL +5 -0
- octostar_python_client-0.1.759.dist-info/licenses/LICENSE +21 -0
- octostar_python_client-0.1.759.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import logging
|
|
3
|
+
import yaml
|
|
4
|
+
from typing import Optional, Union
|
|
5
|
+
|
|
6
|
+
_logger = logging.getLogger(__name__)
|
|
7
|
+
|
|
8
|
+
from ....api.apps import execute_app_job
|
|
9
|
+
from ....models.execute_app_job_json_body import ExecuteAppJobJsonBody
|
|
10
|
+
from ....models.execute_app_job_json_body_annotation import (
|
|
11
|
+
ExecuteAppJobJsonBodyAnnotation,
|
|
12
|
+
)
|
|
13
|
+
from ....client import Client
|
|
14
|
+
from ...exceptions import ApiConnectionError
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def sync(
|
|
18
|
+
commands: str,
|
|
19
|
+
zip_archive_link: Optional[str] = os.getenv("OS_SELF_ARCHIVE"),
|
|
20
|
+
manifest: Optional[Union[dict, str]] = None,
|
|
21
|
+
annotations: Optional[dict[str, str]] = None,
|
|
22
|
+
client: Client = None,
|
|
23
|
+
):
|
|
24
|
+
"""
|
|
25
|
+
# Start a new job
|
|
26
|
+
|
|
27
|
+
## Arguments
|
|
28
|
+
|
|
29
|
+
- `commands`: The bash commands to execute in the new job.
|
|
30
|
+
- `zip_archive_link`: A URL to a zip archive containing a valid app. Note that the app will not execute through `main.sh` but via the provided commands.
|
|
31
|
+
- `manifest`: A manifest file, either as a dictionary parsable as YAML or as a raw YAML string.
|
|
32
|
+
Note that `app_name`, `alias` and `app_title` are always inherited from the parent and cannot be overridden by this manifest.
|
|
33
|
+
- `annotations`: A list of key-value strings to be appended to the kubernetes pod.
|
|
34
|
+
Keys must start with 'app.octostar.com/'. Example: {'app.octostar.com/author': 'John Doe'}
|
|
35
|
+
- `client`: The Client with which to connect to Octostar. If None, the default one is used.
|
|
36
|
+
|
|
37
|
+
## Returns
|
|
38
|
+
|
|
39
|
+
An acknowledgment.
|
|
40
|
+
|
|
41
|
+
## Raises
|
|
42
|
+
|
|
43
|
+
- `ApiConnectionError`: If the operation was unsuccessful on the server.
|
|
44
|
+
"""
|
|
45
|
+
if not annotations:
|
|
46
|
+
annotations = {}
|
|
47
|
+
if not manifest:
|
|
48
|
+
manifest = None
|
|
49
|
+
if manifest and isinstance(manifest, dict):
|
|
50
|
+
manifest = yaml.dump(manifest)
|
|
51
|
+
response = execute_app_job.sync_detailed(
|
|
52
|
+
json_body=ExecuteAppJobJsonBody(
|
|
53
|
+
ontology=client.ontology,
|
|
54
|
+
archive=zip_archive_link,
|
|
55
|
+
commands=commands,
|
|
56
|
+
manifest=manifest,
|
|
57
|
+
annotation=ExecuteAppJobJsonBodyAnnotation(**annotations),
|
|
58
|
+
ancestor=os.getenv("OS_ANCESTOR") or os.getenv("OS_APP_ID"),
|
|
59
|
+
),
|
|
60
|
+
client=client,
|
|
61
|
+
)
|
|
62
|
+
if response.status_code != 200:
|
|
63
|
+
raise ApiConnectionError("execute_app_job", response, client)
|
|
64
|
+
return response.parsed
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
async def asyncio(
|
|
68
|
+
commands: str,
|
|
69
|
+
zip_archive_link: Optional[str] = os.getenv("OS_SELF_ARCHIVE"),
|
|
70
|
+
manifest: Optional[Union[dict, str]] = None,
|
|
71
|
+
annotations: Optional[dict[str, str]] = None,
|
|
72
|
+
client: Client = None,
|
|
73
|
+
):
|
|
74
|
+
"""
|
|
75
|
+
# Start a new job asynchronously
|
|
76
|
+
|
|
77
|
+
## Arguments
|
|
78
|
+
|
|
79
|
+
- `commands`: The bash commands to execute in the new job.
|
|
80
|
+
- `zip_archive_link`: A URL to a zip archive containing a valid app. Note that the app will not execute through `main.sh` but via the provided commands.
|
|
81
|
+
- `manifest`: A manifest file, either as a dictionary parsable as YAML or as a raw YAML string.
|
|
82
|
+
Note that `app_name`, `alias` and `app_title` are always inherited from the parent and cannot be overridden by this manifest.
|
|
83
|
+
- `annotations`: A list of key-value strings to be appended to the kubernetes pod.
|
|
84
|
+
Keys must start with 'app.octostar.com/'. Example: {'app.octostar.com/author': 'John Doe'}
|
|
85
|
+
- `client`: The Client with which to connect to Octostar. If None, the default one is used.
|
|
86
|
+
|
|
87
|
+
## Returns
|
|
88
|
+
|
|
89
|
+
An acknowledgment.
|
|
90
|
+
|
|
91
|
+
## Raises
|
|
92
|
+
|
|
93
|
+
- `ApiConnectionError`: If the operation was unsuccessful on the server.
|
|
94
|
+
"""
|
|
95
|
+
if not annotations:
|
|
96
|
+
annotations = {}
|
|
97
|
+
if not manifest:
|
|
98
|
+
manifest = None
|
|
99
|
+
if manifest and isinstance(manifest, dict):
|
|
100
|
+
manifest = yaml.dump(manifest)
|
|
101
|
+
response = await execute_app_job.asyncio_detailed(
|
|
102
|
+
json_body=ExecuteAppJobJsonBody(
|
|
103
|
+
ontology=client.ontology,
|
|
104
|
+
archive=zip_archive_link,
|
|
105
|
+
commands=commands,
|
|
106
|
+
manifest=manifest,
|
|
107
|
+
annotation=ExecuteAppJobJsonBodyAnnotation(**annotations),
|
|
108
|
+
ancestor=os.getenv("OS_ANCESTOR") or os.getenv("OS_APP_ID"),
|
|
109
|
+
),
|
|
110
|
+
client=client,
|
|
111
|
+
)
|
|
112
|
+
if response.status_code != 200:
|
|
113
|
+
raise ApiConnectionError("execute_app_job", response, client)
|
|
114
|
+
return response.parsed
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import logging
|
|
3
|
+
import re
|
|
4
|
+
|
|
5
|
+
_logger = logging.getLogger(__name__)
|
|
6
|
+
|
|
7
|
+
from ....api.apps import get_app_logs
|
|
8
|
+
from ....client import Client
|
|
9
|
+
from ...exceptions import ApiConnectionError
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def sync(
|
|
13
|
+
app_id: str = os.getenv("OS_APP_ID"),
|
|
14
|
+
since_seconds: int = None,
|
|
15
|
+
tail_lines: int = None,
|
|
16
|
+
client: Client = None,
|
|
17
|
+
):
|
|
18
|
+
"""
|
|
19
|
+
# Get App Logs
|
|
20
|
+
|
|
21
|
+
Retrieves the logs of a running app given its ID.
|
|
22
|
+
|
|
23
|
+
## Arguments
|
|
24
|
+
- `app_id`: The running app ID.
|
|
25
|
+
- `since_seconds`: The maximum amount of seconds prior to now to get logs for.
|
|
26
|
+
- `tail_lines`: The maximum amount of log lines to retrieve.
|
|
27
|
+
|
|
28
|
+
- `client`: The Client with which to connect to Octostar. If None, the default one is used.
|
|
29
|
+
|
|
30
|
+
## Returns
|
|
31
|
+
An UTF-8 string with the app logs.
|
|
32
|
+
|
|
33
|
+
## Raises
|
|
34
|
+
- `ApiConnectionError`: If the request was unsuccessful on the server.
|
|
35
|
+
"""
|
|
36
|
+
response = get_app_logs.sync_detailed(
|
|
37
|
+
app_id=app_id,
|
|
38
|
+
since_seconds=since_seconds,
|
|
39
|
+
tail_lines=tail_lines,
|
|
40
|
+
client=client,
|
|
41
|
+
)
|
|
42
|
+
if response.status_code != 200:
|
|
43
|
+
raise ApiConnectionError("get_app_logs", response, client)
|
|
44
|
+
logs = response.content
|
|
45
|
+
try:
|
|
46
|
+
escaped_logs = logs.decode("utf-8", "replace")
|
|
47
|
+
escaped_logs = re.sub(
|
|
48
|
+
r"\\.",
|
|
49
|
+
lambda x: {
|
|
50
|
+
"\\n": "\n",
|
|
51
|
+
"\\t": "\t",
|
|
52
|
+
"\\r": "\r",
|
|
53
|
+
'\\"': '"',
|
|
54
|
+
"\\'": "'",
|
|
55
|
+
}.get(x[0], x[0]),
|
|
56
|
+
escaped_logs,
|
|
57
|
+
)
|
|
58
|
+
return escaped_logs
|
|
59
|
+
except Exception:
|
|
60
|
+
_logger.warning("Could not decode logs! Returning raw bytes")
|
|
61
|
+
return logs
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
async def asyncio(
|
|
65
|
+
app_id: str = os.getenv("OS_APP_ID"),
|
|
66
|
+
since_seconds: int = None,
|
|
67
|
+
tail_lines: int = None,
|
|
68
|
+
client: Client = None,
|
|
69
|
+
):
|
|
70
|
+
"""
|
|
71
|
+
# Get App Logs Asynchronously
|
|
72
|
+
|
|
73
|
+
Asynchronously retrieves the logs of a running app/job given its ID.
|
|
74
|
+
|
|
75
|
+
## Arguments
|
|
76
|
+
- `app_id`: The running app ID.
|
|
77
|
+
- `since_seconds`: The maximum amount of seconds prior to now to get logs for.
|
|
78
|
+
- `tail_lines`: The maximum amount of log lines to retrieve.
|
|
79
|
+
|
|
80
|
+
- `client`: The Client with which to connect to Octostar. If None, the default one is used.
|
|
81
|
+
|
|
82
|
+
## Returns
|
|
83
|
+
An UTF-8 string with the app logs.
|
|
84
|
+
|
|
85
|
+
## Raises
|
|
86
|
+
- `ApiConnectionError`: If the request was unsuccessful on the server.
|
|
87
|
+
"""
|
|
88
|
+
response = await get_app_logs.asyncio_detailed(
|
|
89
|
+
app_id=app_id,
|
|
90
|
+
since_seconds=since_seconds,
|
|
91
|
+
tail_lines=tail_lines,
|
|
92
|
+
client=client,
|
|
93
|
+
)
|
|
94
|
+
if response.status_code != 200:
|
|
95
|
+
raise ApiConnectionError("get_app_logs", response, client)
|
|
96
|
+
logs = response.content
|
|
97
|
+
try:
|
|
98
|
+
escaped_logs = logs.decode("utf-8", "replace")
|
|
99
|
+
escaped_logs = re.sub(
|
|
100
|
+
r"\\.",
|
|
101
|
+
lambda x: {
|
|
102
|
+
"\\n": "\n",
|
|
103
|
+
"\\t": "\t",
|
|
104
|
+
"\\r": "\r",
|
|
105
|
+
'\\"': '"',
|
|
106
|
+
"\\'": "'",
|
|
107
|
+
}.get(x[0], x[0]),
|
|
108
|
+
escaped_logs,
|
|
109
|
+
)
|
|
110
|
+
return escaped_logs
|
|
111
|
+
except Exception:
|
|
112
|
+
_logger.warning("Could not decode logs! Returning raw bytes")
|
|
113
|
+
return logs
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from warnings import warn
|
|
3
|
+
from dotenv import get_key, find_dotenv, load_dotenv
|
|
4
|
+
from ....client import Client
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def sync(key: str, client: Client = None) -> str:
|
|
8
|
+
"""
|
|
9
|
+
# Reads an application secret value
|
|
10
|
+
|
|
11
|
+
Retrieves the value of an application secret based on the provided key.
|
|
12
|
+
|
|
13
|
+
## Arguments
|
|
14
|
+
|
|
15
|
+
- `key`: The key for the application secret.
|
|
16
|
+
- `client`: The Client with which to connect to Octostar. If None, the default one is used.
|
|
17
|
+
|
|
18
|
+
## Returns
|
|
19
|
+
|
|
20
|
+
The corresponding secret value.
|
|
21
|
+
|
|
22
|
+
## Raises
|
|
23
|
+
|
|
24
|
+
- `ValueError`: If the key is not valid.
|
|
25
|
+
- `RuntimeError`: If the secrets file could not be read.
|
|
26
|
+
|
|
27
|
+
## Example
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
secret_value = sync("my_secret_key")
|
|
31
|
+
print(secret_value)
|
|
32
|
+
```
|
|
33
|
+
"""
|
|
34
|
+
if not key or not isinstance(key, str):
|
|
35
|
+
raise ValueError("key must be a non-empty string")
|
|
36
|
+
if not key.strip():
|
|
37
|
+
raise ValueError("key must be non-empty")
|
|
38
|
+
|
|
39
|
+
sanitized_key = (
|
|
40
|
+
key.replace("/", "_").replace(".", "_").replace("-", "_").replace(" ", "_")
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
if f"{os.getenv('OS_DEV_MODE')}".lower() == "true":
|
|
44
|
+
if not os.getenv(sanitized_key):
|
|
45
|
+
dotenv_value = get_key(find_dotenv(usecwd=True), sanitized_key)
|
|
46
|
+
if dotenv_value is not None:
|
|
47
|
+
os.environ[sanitized_key] = dotenv_value
|
|
48
|
+
warn(
|
|
49
|
+
"Loading secret from .env file. This is fine for development but not for production!",
|
|
50
|
+
stacklevel=2,
|
|
51
|
+
)
|
|
52
|
+
if os.getenv(sanitized_key) is not None:
|
|
53
|
+
warn(
|
|
54
|
+
f"App secret {sanitized_key} has been loaded in plaintext from environment variables. This is fine for development but it should not happen in production!",
|
|
55
|
+
Warning,
|
|
56
|
+
stacklevel=2,
|
|
57
|
+
)
|
|
58
|
+
return os.environ[sanitized_key]
|
|
59
|
+
|
|
60
|
+
path = "/etc/secrets/" + sanitized_key
|
|
61
|
+
|
|
62
|
+
if not os.path.isfile(path):
|
|
63
|
+
raise RuntimeError(f"Secret file not found at {path}")
|
|
64
|
+
|
|
65
|
+
try:
|
|
66
|
+
with open(path, "r") as file:
|
|
67
|
+
line = file.readline()
|
|
68
|
+
if not line:
|
|
69
|
+
raise ValueError(f"Secret file {path} is empty")
|
|
70
|
+
return line.strip()
|
|
71
|
+
except Exception as e:
|
|
72
|
+
raise RuntimeError(f"Error reading secret file {path}: {e}")
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
async def asyncio(key: str, client: Client = None) -> str:
|
|
76
|
+
"""
|
|
77
|
+
# Reads an application secret value asynchronously
|
|
78
|
+
|
|
79
|
+
Retrieves the value of an application secret based on the provided key asynchronously.
|
|
80
|
+
|
|
81
|
+
## Arguments
|
|
82
|
+
|
|
83
|
+
- `key`: The key for the application secret.
|
|
84
|
+
- `client`: The Client with which to connect to Octostar. If None, the default one is used.
|
|
85
|
+
|
|
86
|
+
## Returns
|
|
87
|
+
|
|
88
|
+
The corresponding secret value.
|
|
89
|
+
|
|
90
|
+
## Raises
|
|
91
|
+
|
|
92
|
+
- `ValueError`: If the key is not valid.
|
|
93
|
+
- `RuntimeError`: If the secrets file could not be read.
|
|
94
|
+
|
|
95
|
+
## Example
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
secret_value = await asyncio("my_secret_key")
|
|
99
|
+
print(secret_value)
|
|
100
|
+
```
|
|
101
|
+
"""
|
|
102
|
+
return sync(key, client)
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Union
|
|
3
|
+
|
|
4
|
+
_logger = logging.getLogger(__name__)
|
|
5
|
+
|
|
6
|
+
from ....api.apps import get_apps_url
|
|
7
|
+
from ....models.get_apps_url_json_body import GetAppsUrlJsonBody
|
|
8
|
+
from ....client import Client
|
|
9
|
+
from ...exceptions import ApiConnectionError
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def sync(app_id: Union[str, list[str]], client: Client = None):
|
|
13
|
+
"""
|
|
14
|
+
# Get App URL
|
|
15
|
+
|
|
16
|
+
Get the app URL for a app ID.
|
|
17
|
+
|
|
18
|
+
## Arguments
|
|
19
|
+
- `app_id`: The ID of the app. Can also be a list of such IDs.
|
|
20
|
+
- `client`: The Client with which to connect to Octostar. If None, the default one is used.
|
|
21
|
+
|
|
22
|
+
## Returns
|
|
23
|
+
One or a list of app urls.
|
|
24
|
+
|
|
25
|
+
## Raises
|
|
26
|
+
- `ApiConnectionError`: If the request was unsuccessful on the server.
|
|
27
|
+
"""
|
|
28
|
+
as_list = True
|
|
29
|
+
if not isinstance(app_id, list):
|
|
30
|
+
app_id = [app_id]
|
|
31
|
+
as_list = False
|
|
32
|
+
response = get_apps_url.sync_detailed(
|
|
33
|
+
json_body=GetAppsUrlJsonBody(app_id), client=client
|
|
34
|
+
)
|
|
35
|
+
if response.status_code != 200:
|
|
36
|
+
raise ApiConnectionError("get_apps_url", response, client)
|
|
37
|
+
content = response.parsed
|
|
38
|
+
content = [app.app_url for app in content]
|
|
39
|
+
if not as_list:
|
|
40
|
+
content = content[0]
|
|
41
|
+
return content
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
async def asyncio(app_id: Union[str, list[str]], client: Client = None):
|
|
45
|
+
"""
|
|
46
|
+
# Get App URL Asynchronously
|
|
47
|
+
|
|
48
|
+
Get asynchronously the app URL for a app ID.
|
|
49
|
+
|
|
50
|
+
## Arguments
|
|
51
|
+
- `app_id`: The ID of the app. Can also be a list of such IDs.
|
|
52
|
+
- `client`: The Client with which to connect to Octostar. If None, the default one is used.
|
|
53
|
+
|
|
54
|
+
## Returns
|
|
55
|
+
One or a list of app urls.
|
|
56
|
+
|
|
57
|
+
## Raises
|
|
58
|
+
- `ApiConnectionError`: If the request was unsuccessful on the server.
|
|
59
|
+
"""
|
|
60
|
+
as_list = True
|
|
61
|
+
if not isinstance(app_id, list):
|
|
62
|
+
app_id = [app_id]
|
|
63
|
+
as_list = False
|
|
64
|
+
response = await get_apps_url.asyncio_detailed(
|
|
65
|
+
json_body=GetAppsUrlJsonBody(app_id), client=client
|
|
66
|
+
)
|
|
67
|
+
if response.status_code != 200:
|
|
68
|
+
raise ApiConnectionError("get_apps_url", response, client)
|
|
69
|
+
content = response.parsed
|
|
70
|
+
content = [app.app_url for app in content]
|
|
71
|
+
if not as_list:
|
|
72
|
+
content = content[0]
|
|
73
|
+
return content
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import logging
|
|
3
|
+
|
|
4
|
+
_logger = logging.getLogger(__name__)
|
|
5
|
+
|
|
6
|
+
from ....api.apps import list_app_jobs
|
|
7
|
+
from ....client import Client
|
|
8
|
+
from ...exceptions import ApiConnectionError
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def sync(app_id: str = os.getenv("OS_APP_ID"), client: Client = None):
|
|
12
|
+
"""
|
|
13
|
+
# List App Children
|
|
14
|
+
|
|
15
|
+
List the jobs spawned by a app.
|
|
16
|
+
|
|
17
|
+
## Arguments
|
|
18
|
+
- `app_id`: The running app ID.
|
|
19
|
+
- `client`: The Client with which to connect to Octostar. If None, the default one is used.
|
|
20
|
+
|
|
21
|
+
## Returns
|
|
22
|
+
A list of jobs, each containing their full info. Note the full info does not contain the job URL,
|
|
23
|
+
use `get_job_url()` to retrieve it.
|
|
24
|
+
|
|
25
|
+
## Raises
|
|
26
|
+
- `ApiConnectionError`: If the request was unsuccessful on the server.
|
|
27
|
+
"""
|
|
28
|
+
response = list_app_jobs.sync_detailed(app_id=app_id, client=client)
|
|
29
|
+
if response.status_code != 200:
|
|
30
|
+
raise ApiConnectionError("list_app_jobs", response, client)
|
|
31
|
+
content = response.parsed
|
|
32
|
+
content = list(filter(lambda x: x.name != app_id, content))
|
|
33
|
+
for elem in content:
|
|
34
|
+
elem.labels = elem.labels.additional_properties
|
|
35
|
+
return content
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
async def asyncio(app_id: str = os.getenv("OS_APP_ID"), client: Client = None):
|
|
39
|
+
"""
|
|
40
|
+
# List App Children Asynchronously
|
|
41
|
+
|
|
42
|
+
List asynchronously the jobs spawned by a app.
|
|
43
|
+
|
|
44
|
+
## Arguments
|
|
45
|
+
- `app_id`: The running app ID.
|
|
46
|
+
- `client`: The Client with which to connect to Octostar. If None, the default one is used.
|
|
47
|
+
|
|
48
|
+
## Returns
|
|
49
|
+
A list of jobs, each containing their full info. Note the full info does not contain the job URL,
|
|
50
|
+
use `get_job_url()` to retrieve it.
|
|
51
|
+
|
|
52
|
+
## Raises
|
|
53
|
+
- `ApiConnectionError`: If the request was unsuccessful on the server.
|
|
54
|
+
"""
|
|
55
|
+
response = await list_app_jobs.asyncio_detailed(app_id=app_id, client=client)
|
|
56
|
+
if response.status_code != 200:
|
|
57
|
+
raise ApiConnectionError("list_app_jobs", response, client)
|
|
58
|
+
content = response.parsed
|
|
59
|
+
content = list(filter(lambda x: x.name != app_id, content))
|
|
60
|
+
for elem in content:
|
|
61
|
+
elem.labels = elem.labels.additional_properties
|
|
62
|
+
return content
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Optional
|
|
3
|
+
import httpx
|
|
4
|
+
from httpx import QueryParams
|
|
5
|
+
|
|
6
|
+
_logger = logging.getLogger(__name__)
|
|
7
|
+
|
|
8
|
+
from ....client import Client
|
|
9
|
+
from ...exceptions import ApiConnectionError
|
|
10
|
+
from ...commons import network_retry_strategy
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def sync(
|
|
14
|
+
workspaces: Optional[list[str]] = None,
|
|
15
|
+
include_all: bool = False,
|
|
16
|
+
main_namespace_only: bool = False,
|
|
17
|
+
client: Client = None,
|
|
18
|
+
):
|
|
19
|
+
"""
|
|
20
|
+
# List Apps
|
|
21
|
+
|
|
22
|
+
List all of the apps running in Octostar.
|
|
23
|
+
|
|
24
|
+
## Arguments
|
|
25
|
+
- `workspaces`: The list of workspace IDs by which to filter apps. If None, all workspaces are searched.
|
|
26
|
+
- `include_all`: If False, only running apps are returned. If True, undeployed apps are also returned.
|
|
27
|
+
- `main_namespace_only`: If True, running apps will only be searched in the main kubernetes namespace.
|
|
28
|
+
- `client`: The Client with which to connect to Octostar. If None, the default one is used.
|
|
29
|
+
|
|
30
|
+
## Returns
|
|
31
|
+
A list of apps, each containing their full info.
|
|
32
|
+
|
|
33
|
+
## Raises
|
|
34
|
+
- `ApiConnectionError`: If the request was unsuccessful on the server.
|
|
35
|
+
"""
|
|
36
|
+
endpoint_url = f"{client.get_base_url_v1()}/api/v1/apps/"
|
|
37
|
+
headers = {
|
|
38
|
+
"Authorization": f"Bearer {client.token}",
|
|
39
|
+
"x-ontology": client.ontology,
|
|
40
|
+
}
|
|
41
|
+
if not workspaces:
|
|
42
|
+
workspaces = []
|
|
43
|
+
query_params = QueryParams(
|
|
44
|
+
[
|
|
45
|
+
*[("workspaces", ws) for ws in workspaces],
|
|
46
|
+
("include_all", include_all),
|
|
47
|
+
("main_namespace_only", main_namespace_only),
|
|
48
|
+
]
|
|
49
|
+
)
|
|
50
|
+
response = None
|
|
51
|
+
try:
|
|
52
|
+
for attempt in network_retry_strategy():
|
|
53
|
+
with attempt:
|
|
54
|
+
with httpx.Client() as httpx_client:
|
|
55
|
+
response = httpx_client.get(
|
|
56
|
+
endpoint_url, headers=headers, params=query_params, timeout=30
|
|
57
|
+
)
|
|
58
|
+
response.raise_for_status()
|
|
59
|
+
try:
|
|
60
|
+
parsed = response.json()
|
|
61
|
+
except ValueError:
|
|
62
|
+
raise ConnectionError(
|
|
63
|
+
"Could not fetch data from API (failed to parse response), responded with\n"
|
|
64
|
+
+ str(response.content)
|
|
65
|
+
)
|
|
66
|
+
except Exception:
|
|
67
|
+
raise ApiConnectionError("list_apps", response, client)
|
|
68
|
+
return parsed["apps"]
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
async def asyncio(
|
|
72
|
+
workspaces: Optional[list[str]] = None,
|
|
73
|
+
include_all: bool = False,
|
|
74
|
+
main_namespace_only: bool = False,
|
|
75
|
+
client: Client = None,
|
|
76
|
+
):
|
|
77
|
+
"""
|
|
78
|
+
# List Apps
|
|
79
|
+
|
|
80
|
+
List asynchronously all of the apps running in Octostar.
|
|
81
|
+
|
|
82
|
+
## Arguments
|
|
83
|
+
- `workspaces`: The list of workspace IDs by which to filter apps. If None, all workspaces are searched.
|
|
84
|
+
- `include_all`: If False, only running apps are returned. If True, undeployed apps are also returned.
|
|
85
|
+
- `main_namespace_only`: If True, running apps will only be searched in the main kubernetes namespace.
|
|
86
|
+
- `client`: The Client with which to connect to Octostar. If None, the default one is used.
|
|
87
|
+
|
|
88
|
+
## Returns
|
|
89
|
+
A list of apps, each containing their full info.
|
|
90
|
+
|
|
91
|
+
## Raises
|
|
92
|
+
- `ApiConnectionError`: If the request was unsuccessful on the server.
|
|
93
|
+
"""
|
|
94
|
+
endpoint_url = f"{client.get_base_url_v1()}/api/v1/apps/"
|
|
95
|
+
headers = {
|
|
96
|
+
"Authorization": f"Bearer {client.token}",
|
|
97
|
+
"x-ontology": client.ontology,
|
|
98
|
+
}
|
|
99
|
+
if not workspaces:
|
|
100
|
+
workspaces = []
|
|
101
|
+
query_params = QueryParams(
|
|
102
|
+
[
|
|
103
|
+
*[("workspaces", ws) for ws in workspaces],
|
|
104
|
+
("include_all", include_all),
|
|
105
|
+
("main_namespace_only", main_namespace_only),
|
|
106
|
+
]
|
|
107
|
+
)
|
|
108
|
+
response = None
|
|
109
|
+
try:
|
|
110
|
+
for attempt in network_retry_strategy():
|
|
111
|
+
with attempt:
|
|
112
|
+
async with httpx.AsyncClient() as httpx_client:
|
|
113
|
+
response = await httpx_client.get(
|
|
114
|
+
endpoint_url, headers=headers, params=query_params, timeout=30
|
|
115
|
+
)
|
|
116
|
+
response.raise_for_status()
|
|
117
|
+
try:
|
|
118
|
+
parsed = response.json()
|
|
119
|
+
except ValueError:
|
|
120
|
+
raise ConnectionError(
|
|
121
|
+
"Could not fetch data from API (failed to parse response), responded with\n"
|
|
122
|
+
+ str(response.content)
|
|
123
|
+
)
|
|
124
|
+
except Exception:
|
|
125
|
+
raise ApiConnectionError("list_apps", response, client)
|
|
126
|
+
return parsed["apps"]
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import logging
|
|
3
|
+
|
|
4
|
+
_logger = logging.getLogger(__name__)
|
|
5
|
+
|
|
6
|
+
from ....api.apps import undeploy_app
|
|
7
|
+
from ....client import Client
|
|
8
|
+
from ...exceptions import ApiConnectionError
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def sync(
|
|
12
|
+
app_id: str = os.getenv("OS_APP_ID"),
|
|
13
|
+
client: Client = None,
|
|
14
|
+
):
|
|
15
|
+
"""
|
|
16
|
+
# Undeploys an App.
|
|
17
|
+
|
|
18
|
+
## Arguments
|
|
19
|
+
- `app_id`: The ID of the app to undeploy.
|
|
20
|
+
- `client`: The Client with which to connect to Octostar. If None, the default one is used.
|
|
21
|
+
|
|
22
|
+
## Raises
|
|
23
|
+
- `ApiConnectionError`: If the request was unsuccessful on the server.
|
|
24
|
+
"""
|
|
25
|
+
response = undeploy_app.sync_detailed(app_id=app_id, client=client)
|
|
26
|
+
if response.status_code != 200:
|
|
27
|
+
raise ApiConnectionError("undeploy_app", response, client)
|
|
28
|
+
return response.parsed
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
async def asyncio(
|
|
32
|
+
app_id: str = os.getenv("OS_APP_ID"),
|
|
33
|
+
client: Client = None,
|
|
34
|
+
):
|
|
35
|
+
"""
|
|
36
|
+
# Undeploys an App.
|
|
37
|
+
|
|
38
|
+
## Arguments
|
|
39
|
+
- `app_id`: The ID of the app to undeploy.
|
|
40
|
+
- `client`: The Client with which to connect to Octostar. If None, the default one is used.
|
|
41
|
+
|
|
42
|
+
## Raises
|
|
43
|
+
- `ApiConnectionError`: If the request was unsuccessful on the server.
|
|
44
|
+
"""
|
|
45
|
+
response = await undeploy_app.asyncio_detailed(app_id=app_id, client=client)
|
|
46
|
+
if response.status_code != 200:
|
|
47
|
+
raise ApiConnectionError("undeploy_app", response, client)
|
|
48
|
+
return response.parsed
|