From b432b293fc1d809c73c01dc416f4dbe37ff0f40d Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Thu, 5 Sep 2024 15:16:02 +0300 Subject: [PATCH 01/30] update sdks --- _pieces_lib/pieces_os_client/__init__.py | 13 +- .../pieces_os_client/api/activities_api.py | 134 +++ .../pieces_os_client/api/anchor_api.py | 292 ++++++ .../pieces_os_client/api/anchor_points_api.py | 134 +++ .../pieces_os_client/api/anchors_api.py | 134 +++ .../pieces_os_client/api/annotations_api.py | 134 +++ .../pieces_os_client/api/applications_api.py | 634 +----------- .../pieces_os_client/api/backup_api.py | 162 +++- .../pieces_os_client/api/backups_api.py | 284 ++++++ .../api/conversation_message_api.py | 918 +++++++++++++++++- .../api/conversation_messages_api.py | 134 +++ .../pieces_os_client/api/format_api.py | 149 --- .../pieces_os_client/api/formats_api.py | 134 +++ _pieces_lib/pieces_os_client/api/hints_api.py | 134 +++ .../pieces_os_client/api/models_api.py | 134 +++ .../pieces_os_client/api/person_api.py | 292 ++++++ .../pieces_os_client/api/persons_api.py | 134 +++ .../pieces_os_client/api/ranges_api.py | 134 +++ .../pieces_os_client/api/sensitives_api.py | 134 +++ _pieces_lib/pieces_os_client/api/tags_api.py | 134 +++ .../pieces_os_client/api/website_api.py | 292 ++++++ .../pieces_os_client/api/websites_api.py | 134 +++ .../pieces_os_client/api/well_known_api.py | 135 ++- _pieces_lib/pieces_os_client/api_client.py | 2 +- _pieces_lib/pieces_os_client/configuration.py | 2 +- .../pieces_os_client/models/__init__.py | 11 +- .../pieces_os_client/models/activity.py | 2 +- _pieces_lib/pieces_os_client/models/anchor.py | 10 +- .../models/backups_streamed_progress.py | 95 ++ .../models/checked_os_update.py | 108 +++ .../models/conversation_message.py | 22 +- .../models/flattened_anchor.py | 10 +- .../models/flattened_application.py | 99 ++ .../models/flattened_conversation.py | 2 +- .../models/flattened_conversation_message.py | 22 +- .../models/flattened_person.py | 10 +- .../models/flattened_website.py | 10 +- _pieces_lib/pieces_os_client/models/model.py | 12 +- .../models/model_capabilities.py | 90 ++ .../models/os_file_read_streamed_progress.py | 112 +++ _pieces_lib/pieces_os_client/models/person.py | 10 +- .../models/qgpt_relevance_input.py | 10 +- .../models/referenced_application.py | 84 ++ .../models/relevant_qgpt_seed.py | 8 +- .../pieces_os_client/models/seeded_model.py | 12 +- .../models/seeded_tracked_application.py | 2 +- .../models/streamed_identifier.py | 88 +- .../models/timestamp_range.py | 105 ++ .../models/tracked_application.py | 104 ++ .../models/tracked_application_install.py | 64 +- .../models/tracked_application_update.py | 66 +- .../pieces_os_client/models/tracked_format.py | 74 +- .../models/tracked_format_event.py | 68 +- .../models/tracked_interaction_event.py | 60 +- .../models/tracked_keyboard_event.py | 64 +- .../models/tracked_user_profile.py | 70 +- .../models/unchecked_os_update.py | 92 ++ .../pieces_os_client/models/website.py | 10 +- .../models/workstream_event_trigger.py | 2 +- .../workstream_event_trigger_metadata.py | 92 ++ .../pieces_os_client/wrapper/__init__.py | 3 + .../wrapper/basic_identifier/__init__.py | 6 + .../wrapper/basic_identifier/asset.py | 337 +++++++ .../wrapper/basic_identifier/basic.py | 80 ++ .../wrapper/basic_identifier/chat.py | 89 ++ .../wrapper/basic_identifier/message.py | 118 +++ .../wrapper/basic_identifier/user.py | 144 +++ .../pieces_os_client/wrapper/client.py | 181 ++++ .../pieces_os_client/wrapper/context.py | 85 ++ .../pieces_os_client/wrapper/copilot.py | 159 +++ .../wrapper/streamed_identifiers/__init__.py | 9 + .../_streamed_identifiers.py | 130 +++ .../streamed_identifiers/assets_snapshot.py | 20 + .../conversations_snapshot.py | 23 + .../wrapper/version_compatibility.py | 49 + .../wrapper/websockets/__init__.py | 15 + .../wrapper/websockets/ask_ws.py | 74 ++ .../websockets/assets_identifiers_ws.py | 71 ++ .../wrapper/websockets/auth_ws.py | 64 ++ .../wrapper/websockets/base_websocket.py | 176 ++++ .../wrapper/websockets/conversations_ws.py | 61 ++ .../wrapper/websockets/health_ws.py | 9 + _pieces_lib/semver/LICENSE.txt | 27 - _pieces_lib/semver/__about__.py | 37 - _pieces_lib/semver/__init__.py | 72 -- _pieces_lib/semver/__main__.py | 28 - _pieces_lib/semver/_deprecated.py | 410 -------- _pieces_lib/semver/_types.py | 12 - _pieces_lib/semver/cli.py | 174 ---- _pieces_lib/semver/py.typed | 0 _pieces_lib/semver/version.py | 742 -------------- 91 files changed, 7505 insertions(+), 2517 deletions(-) create mode 100644 _pieces_lib/pieces_os_client/models/backups_streamed_progress.py create mode 100644 _pieces_lib/pieces_os_client/models/checked_os_update.py create mode 100644 _pieces_lib/pieces_os_client/models/flattened_application.py create mode 100644 _pieces_lib/pieces_os_client/models/model_capabilities.py create mode 100644 _pieces_lib/pieces_os_client/models/os_file_read_streamed_progress.py create mode 100644 _pieces_lib/pieces_os_client/models/referenced_application.py create mode 100644 _pieces_lib/pieces_os_client/models/timestamp_range.py create mode 100644 _pieces_lib/pieces_os_client/models/tracked_application.py create mode 100644 _pieces_lib/pieces_os_client/models/unchecked_os_update.py create mode 100644 _pieces_lib/pieces_os_client/models/workstream_event_trigger_metadata.py create mode 100644 _pieces_lib/pieces_os_client/wrapper/__init__.py create mode 100644 _pieces_lib/pieces_os_client/wrapper/basic_identifier/__init__.py create mode 100644 _pieces_lib/pieces_os_client/wrapper/basic_identifier/asset.py create mode 100644 _pieces_lib/pieces_os_client/wrapper/basic_identifier/basic.py create mode 100644 _pieces_lib/pieces_os_client/wrapper/basic_identifier/chat.py create mode 100644 _pieces_lib/pieces_os_client/wrapper/basic_identifier/message.py create mode 100644 _pieces_lib/pieces_os_client/wrapper/basic_identifier/user.py create mode 100644 _pieces_lib/pieces_os_client/wrapper/client.py create mode 100644 _pieces_lib/pieces_os_client/wrapper/context.py create mode 100644 _pieces_lib/pieces_os_client/wrapper/copilot.py create mode 100644 _pieces_lib/pieces_os_client/wrapper/streamed_identifiers/__init__.py create mode 100644 _pieces_lib/pieces_os_client/wrapper/streamed_identifiers/_streamed_identifiers.py create mode 100644 _pieces_lib/pieces_os_client/wrapper/streamed_identifiers/assets_snapshot.py create mode 100644 _pieces_lib/pieces_os_client/wrapper/streamed_identifiers/conversations_snapshot.py create mode 100644 _pieces_lib/pieces_os_client/wrapper/version_compatibility.py create mode 100644 _pieces_lib/pieces_os_client/wrapper/websockets/__init__.py create mode 100644 _pieces_lib/pieces_os_client/wrapper/websockets/ask_ws.py create mode 100644 _pieces_lib/pieces_os_client/wrapper/websockets/assets_identifiers_ws.py create mode 100644 _pieces_lib/pieces_os_client/wrapper/websockets/auth_ws.py create mode 100644 _pieces_lib/pieces_os_client/wrapper/websockets/base_websocket.py create mode 100644 _pieces_lib/pieces_os_client/wrapper/websockets/conversations_ws.py create mode 100644 _pieces_lib/pieces_os_client/wrapper/websockets/health_ws.py delete mode 100644 _pieces_lib/semver/LICENSE.txt delete mode 100644 _pieces_lib/semver/__about__.py delete mode 100644 _pieces_lib/semver/__init__.py delete mode 100644 _pieces_lib/semver/__main__.py delete mode 100644 _pieces_lib/semver/_deprecated.py delete mode 100644 _pieces_lib/semver/_types.py delete mode 100644 _pieces_lib/semver/cli.py delete mode 100644 _pieces_lib/semver/py.typed delete mode 100644 _pieces_lib/semver/version.py diff --git a/_pieces_lib/pieces_os_client/__init__.py b/_pieces_lib/pieces_os_client/__init__.py index 0c75bf1..e09f294 100644 --- a/_pieces_lib/pieces_os_client/__init__.py +++ b/_pieces_lib/pieces_os_client/__init__.py @@ -15,7 +15,7 @@ """ # noqa: E501 -__version__ = "2.7.0" +__version__ = "3.1.0" # import apis into sdk package from Pieces._pieces_lib.pieces_os_client.api.activities_api import ActivitiesApi @@ -158,6 +158,7 @@ from Pieces._pieces_lib.pieces_os_client.models.backup_status_enum import BackupStatusEnum from Pieces._pieces_lib.pieces_os_client.models.backup_streamed_progress import BackupStreamedProgress from Pieces._pieces_lib.pieces_os_client.models.backups import Backups +from Pieces._pieces_lib.pieces_os_client.models.backups_streamed_progress import BackupsStreamedProgress from Pieces._pieces_lib.pieces_os_client.models.browser_selection import BrowserSelection from Pieces._pieces_lib.pieces_os_client.models.browser_tab import BrowserTab from Pieces._pieces_lib.pieces_os_client.models.browser_tab_value import BrowserTabValue @@ -232,6 +233,7 @@ from Pieces._pieces_lib.pieces_os_client.models.flattened_anchors import FlattenedAnchors from Pieces._pieces_lib.pieces_os_client.models.flattened_annotation import FlattenedAnnotation from Pieces._pieces_lib.pieces_os_client.models.flattened_annotations import FlattenedAnnotations +from Pieces._pieces_lib.pieces_os_client.models.flattened_application import FlattenedApplication from Pieces._pieces_lib.pieces_os_client.models.flattened_asset import FlattenedAsset from Pieces._pieces_lib.pieces_os_client.models.flattened_assets import FlattenedAssets from Pieces._pieces_lib.pieces_os_client.models.flattened_conversation import FlattenedConversation @@ -316,6 +318,7 @@ from Pieces._pieces_lib.pieces_os_client.models.mailgun_metadata import MailgunMetadata from Pieces._pieces_lib.pieces_os_client.models.mechanism_enum import MechanismEnum from Pieces._pieces_lib.pieces_os_client.models.model import Model +from Pieces._pieces_lib.pieces_os_client.models.model_capabilities import ModelCapabilities from Pieces._pieces_lib.pieces_os_client.models.model_delete_cache_input import ModelDeleteCacheInput from Pieces._pieces_lib.pieces_os_client.models.model_delete_cache_output import ModelDeleteCacheOutput from Pieces._pieces_lib.pieces_os_client.models.model_download_progress import ModelDownloadProgress @@ -413,6 +416,7 @@ from Pieces._pieces_lib.pieces_os_client.models.referenced_anchor import ReferencedAnchor from Pieces._pieces_lib.pieces_os_client.models.referenced_anchor_point import ReferencedAnchorPoint from Pieces._pieces_lib.pieces_os_client.models.referenced_annotation import ReferencedAnnotation +from Pieces._pieces_lib.pieces_os_client.models.referenced_application import ReferencedApplication from Pieces._pieces_lib.pieces_os_client.models.referenced_asset import ReferencedAsset from Pieces._pieces_lib.pieces_os_client.models.referenced_conversation import ReferencedConversation from Pieces._pieces_lib.pieces_os_client.models.referenced_conversation_message import ReferencedConversationMessage @@ -598,8 +602,6 @@ from Pieces._pieces_lib.pieces_os_client.models.textually_extracted_materials import TextuallyExtractedMaterials from Pieces._pieces_lib.pieces_os_client.models.theme import Theme from Pieces._pieces_lib.pieces_os_client.models.tokenized_pkce import TokenizedPKCE -from Pieces._pieces_lib.pieces_os_client.models.tracked_application_install import TrackedApplicationInstall -from Pieces._pieces_lib.pieces_os_client.models.tracked_application_update import TrackedApplicationUpdate from Pieces._pieces_lib.pieces_os_client.models.tracked_asset_event_creation_metadata import TrackedAssetEventCreationMetadata from Pieces._pieces_lib.pieces_os_client.models.tracked_asset_event_creation_metadata_clipboard import TrackedAssetEventCreationMetadataClipboard from Pieces._pieces_lib.pieces_os_client.models.tracked_asset_event_creation_metadata_file import TrackedAssetEventCreationMetadataFile @@ -613,15 +615,10 @@ from Pieces._pieces_lib.pieces_os_client.models.tracked_conversation_event_identifier_description_pairs import TrackedConversationEventIdentifierDescriptionPairs from Pieces._pieces_lib.pieces_os_client.models.tracked_conversation_event_metadata import TrackedConversationEventMetadata from Pieces._pieces_lib.pieces_os_client.models.tracked_conversation_event_rename_metadata import TrackedConversationEventRenameMetadata -from Pieces._pieces_lib.pieces_os_client.models.tracked_format import TrackedFormat -from Pieces._pieces_lib.pieces_os_client.models.tracked_format_event import TrackedFormatEvent from Pieces._pieces_lib.pieces_os_client.models.tracked_format_event_identifier_description_pairs import TrackedFormatEventIdentifierDescriptionPairs from Pieces._pieces_lib.pieces_os_client.models.tracked_format_event_metadata import TrackedFormatEventMetadata -from Pieces._pieces_lib.pieces_os_client.models.tracked_interaction_event import TrackedInteractionEvent -from Pieces._pieces_lib.pieces_os_client.models.tracked_keyboard_event import TrackedKeyboardEvent from Pieces._pieces_lib.pieces_os_client.models.tracked_session_event_identifier_description_pairs import TrackedSessionEventIdentifierDescriptionPairs from Pieces._pieces_lib.pieces_os_client.models.tracked_summary_totals import TrackedSummaryTotals -from Pieces._pieces_lib.pieces_os_client.models.tracked_user_profile import TrackedUserProfile from Pieces._pieces_lib.pieces_os_client.models.transferable_bytes import TransferableBytes from Pieces._pieces_lib.pieces_os_client.models.transferable_string import TransferableString from Pieces._pieces_lib.pieces_os_client.models.unchecked_os_server_update import UncheckedOSServerUpdate diff --git a/_pieces_lib/pieces_os_client/api/activities_api.py b/_pieces_lib/pieces_os_client/api/activities_api.py index 3fd070b..b2c0900 100644 --- a/_pieces_lib/pieces_os_client/api/activities_api.py +++ b/_pieces_lib/pieces_os_client/api/activities_api.py @@ -27,6 +27,7 @@ from Pieces._pieces_lib.pieces_os_client.models.activities import Activities from Pieces._pieces_lib.pieces_os_client.models.activity import Activity from Pieces._pieces_lib.pieces_os_client.models.seeded_activity import SeededActivity +from Pieces._pieces_lib.pieces_os_client.models.streamed_identifiers import StreamedIdentifiers from Pieces._pieces_lib.pieces_os_client.api_client import ApiClient from Pieces._pieces_lib.pieces_os_client.api_response import ApiResponse @@ -490,3 +491,136 @@ def activities_snapshot_with_http_info(self, transferables : Annotated[Optional[ _request_timeout=_params.get('_request_timeout'), collection_formats=_collection_formats, _request_auth=_params.get('_request_auth')) + + @validate_arguments + def activities_stream_identifiers(self, **kwargs) -> StreamedIdentifiers: # noqa: E501 + """/activities/stream/identifiers [WS] # noqa: E501 + + Provides a WebSocket connection that emits changes to your activity identifiers (UUIDs). # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.activities_stream_identifiers(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: StreamedIdentifiers + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the activities_stream_identifiers_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.activities_stream_identifiers_with_http_info(**kwargs) # noqa: E501 + + @validate_arguments + def activities_stream_identifiers_with_http_info(self, **kwargs) -> ApiResponse: # noqa: E501 + """/activities/stream/identifiers [WS] # noqa: E501 + + Provides a WebSocket connection that emits changes to your activity identifiers (UUIDs). # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.activities_stream_identifiers_with_http_info(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: tuple(StreamedIdentifiers, status_code(int), headers(HTTPHeaderDict)) + """ + + _params = locals() + + _all_params = [ + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method activities_stream_identifiers" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['application/json', 'text/plain']) # noqa: E501 + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = { + '200': "StreamedIdentifiers", + '500': "str", + } + + return self.api_client.call_api( + '/activities/stream/identifiers', 'GET', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) diff --git a/_pieces_lib/pieces_os_client/api/anchor_api.py b/_pieces_lib/pieces_os_client/api/anchor_api.py index 92e519f..bb27fb6 100644 --- a/_pieces_lib/pieces_os_client/api/anchor_api.py +++ b/_pieces_lib/pieces_os_client/api/anchor_api.py @@ -339,6 +339,152 @@ def anchor_associate_conversation_with_http_info(self, anchor : Annotated[Strict collection_formats=_collection_formats, _request_auth=_params.get('_request_auth')) + @validate_arguments + def anchor_associate_message(self, anchor : Annotated[StrictStr, Field(..., description="This is the specific uuid of an anchor.")], message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], **kwargs) -> None: # noqa: E501 + """/anchor/{anchor}/messages/associate/{message} [POST] # noqa: E501 + + This will associate a anchor with a message. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.anchor_associate_message(anchor, message, async_req=True) + >>> result = thread.get() + + :param anchor: This is the specific uuid of an anchor. (required) + :type anchor: str + :param message: This is the uuid of a message. (required) + :type message: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the anchor_associate_message_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.anchor_associate_message_with_http_info(anchor, message, **kwargs) # noqa: E501 + + @validate_arguments + def anchor_associate_message_with_http_info(self, anchor : Annotated[StrictStr, Field(..., description="This is the specific uuid of an anchor.")], message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], **kwargs) -> ApiResponse: # noqa: E501 + """/anchor/{anchor}/messages/associate/{message} [POST] # noqa: E501 + + This will associate a anchor with a message. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.anchor_associate_message_with_http_info(anchor, message, async_req=True) + >>> result = thread.get() + + :param anchor: This is the specific uuid of an anchor. (required) + :type anchor: str + :param message: This is the uuid of a message. (required) + :type message: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + + _params = locals() + + _all_params = [ + 'anchor', + 'message' + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method anchor_associate_message" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + if _params['anchor'] is not None: + _path_params['anchor'] = _params['anchor'] + + if _params['message'] is not None: + _path_params['message'] = _params['message'] + + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['text/plain']) # noqa: E501 + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = {} + + return self.api_client.call_api( + '/anchor/{anchor}/messages/associate/{message}', 'POST', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) + @validate_arguments def anchor_associate_person(self, anchor : Annotated[StrictStr, Field(..., description="This is the specific uuid of an anchor.")], person : Annotated[StrictStr, Field(..., description="This is a uuid that represents a person.")], **kwargs) -> None: # noqa: E501 """/anchor/{anchor}/persons/associate/{person} [POST] # noqa: E501 @@ -923,6 +1069,152 @@ def anchor_disassociate_conversation_with_http_info(self, anchor : Annotated[Str collection_formats=_collection_formats, _request_auth=_params.get('_request_auth')) + @validate_arguments + def anchor_disassociate_message(self, anchor : Annotated[StrictStr, Field(..., description="This is the specific uuid of an anchor.")], message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], **kwargs) -> None: # noqa: E501 + """/anchor/{anchor}/messages/disassociate/{message} [POST] # noqa: E501 + + This will enable us to disassociate a anchor from a message. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.anchor_disassociate_message(anchor, message, async_req=True) + >>> result = thread.get() + + :param anchor: This is the specific uuid of an anchor. (required) + :type anchor: str + :param message: This is the uuid of a message. (required) + :type message: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the anchor_disassociate_message_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.anchor_disassociate_message_with_http_info(anchor, message, **kwargs) # noqa: E501 + + @validate_arguments + def anchor_disassociate_message_with_http_info(self, anchor : Annotated[StrictStr, Field(..., description="This is the specific uuid of an anchor.")], message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], **kwargs) -> ApiResponse: # noqa: E501 + """/anchor/{anchor}/messages/disassociate/{message} [POST] # noqa: E501 + + This will enable us to disassociate a anchor from a message. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.anchor_disassociate_message_with_http_info(anchor, message, async_req=True) + >>> result = thread.get() + + :param anchor: This is the specific uuid of an anchor. (required) + :type anchor: str + :param message: This is the uuid of a message. (required) + :type message: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + + _params = locals() + + _all_params = [ + 'anchor', + 'message' + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method anchor_disassociate_message" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + if _params['anchor'] is not None: + _path_params['anchor'] = _params['anchor'] + + if _params['message'] is not None: + _path_params['message'] = _params['message'] + + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['text/plain']) # noqa: E501 + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = {} + + return self.api_client.call_api( + '/anchor/{anchor}/messages/disassociate/{message}', 'POST', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) + @validate_arguments def anchor_disassociate_person(self, anchor : Annotated[StrictStr, Field(..., description="This is the specific uuid of an anchor.")], person : Annotated[StrictStr, Field(..., description="This is a uuid that represents a person.")], **kwargs) -> None: # noqa: E501 """/anchor/{anchor}/persons/disassociate/{person} [POST] # noqa: E501 diff --git a/_pieces_lib/pieces_os_client/api/anchor_points_api.py b/_pieces_lib/pieces_os_client/api/anchor_points_api.py index 1b85b78..df4520d 100644 --- a/_pieces_lib/pieces_os_client/api/anchor_points_api.py +++ b/_pieces_lib/pieces_os_client/api/anchor_points_api.py @@ -27,6 +27,7 @@ from Pieces._pieces_lib.pieces_os_client.models.anchor_point import AnchorPoint from Pieces._pieces_lib.pieces_os_client.models.anchor_points import AnchorPoints from Pieces._pieces_lib.pieces_os_client.models.seeded_anchor_point import SeededAnchorPoint +from Pieces._pieces_lib.pieces_os_client.models.streamed_identifiers import StreamedIdentifiers from Pieces._pieces_lib.pieces_os_client.api_client import ApiClient from Pieces._pieces_lib.pieces_os_client.api_response import ApiResponse @@ -482,3 +483,136 @@ def anchor_points_snapshot_with_http_info(self, transferables : Annotated[Option _request_timeout=_params.get('_request_timeout'), collection_formats=_collection_formats, _request_auth=_params.get('_request_auth')) + + @validate_arguments + def anchor_points_stream_identifiers(self, **kwargs) -> StreamedIdentifiers: # noqa: E501 + """/anchor_points/stream/identifiers [WS] # noqa: E501 + + Provides a WebSocket connection that emits changes to your annotation identifiers (UUIDs). # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.anchor_points_stream_identifiers(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: StreamedIdentifiers + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the anchor_points_stream_identifiers_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.anchor_points_stream_identifiers_with_http_info(**kwargs) # noqa: E501 + + @validate_arguments + def anchor_points_stream_identifiers_with_http_info(self, **kwargs) -> ApiResponse: # noqa: E501 + """/anchor_points/stream/identifiers [WS] # noqa: E501 + + Provides a WebSocket connection that emits changes to your annotation identifiers (UUIDs). # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.anchor_points_stream_identifiers_with_http_info(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: tuple(StreamedIdentifiers, status_code(int), headers(HTTPHeaderDict)) + """ + + _params = locals() + + _all_params = [ + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method anchor_points_stream_identifiers" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['application/json', 'text/plain']) # noqa: E501 + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = { + '200': "StreamedIdentifiers", + '500': "str", + } + + return self.api_client.call_api( + '/anchor_points/stream/identifiers', 'GET', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) diff --git a/_pieces_lib/pieces_os_client/api/anchors_api.py b/_pieces_lib/pieces_os_client/api/anchors_api.py index 07ff561..f440b9e 100644 --- a/_pieces_lib/pieces_os_client/api/anchors_api.py +++ b/_pieces_lib/pieces_os_client/api/anchors_api.py @@ -29,6 +29,7 @@ from Pieces._pieces_lib.pieces_os_client.models.search_input import SearchInput from Pieces._pieces_lib.pieces_os_client.models.searched_anchors import SearchedAnchors from Pieces._pieces_lib.pieces_os_client.models.seeded_anchor import SeededAnchor +from Pieces._pieces_lib.pieces_os_client.models.streamed_identifiers import StreamedIdentifiers from Pieces._pieces_lib.pieces_os_client.api_client import ApiClient from Pieces._pieces_lib.pieces_os_client.api_response import ApiResponse @@ -485,6 +486,139 @@ def anchors_snapshot_with_http_info(self, transferables : Annotated[Optional[Str collection_formats=_collection_formats, _request_auth=_params.get('_request_auth')) + @validate_arguments + def anchors_stream_identifiers(self, **kwargs) -> StreamedIdentifiers: # noqa: E501 + """/anchors/stream/identifiers [WS] # noqa: E501 + + Provides a WebSocket connection that emits changes to your anchor identifiers (UUIDs). # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.anchors_stream_identifiers(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: StreamedIdentifiers + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the anchors_stream_identifiers_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.anchors_stream_identifiers_with_http_info(**kwargs) # noqa: E501 + + @validate_arguments + def anchors_stream_identifiers_with_http_info(self, **kwargs) -> ApiResponse: # noqa: E501 + """/anchors/stream/identifiers [WS] # noqa: E501 + + Provides a WebSocket connection that emits changes to your anchor identifiers (UUIDs). # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.anchors_stream_identifiers_with_http_info(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: tuple(StreamedIdentifiers, status_code(int), headers(HTTPHeaderDict)) + """ + + _params = locals() + + _all_params = [ + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method anchors_stream_identifiers" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['application/json', 'text/plain']) # noqa: E501 + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = { + '200': "StreamedIdentifiers", + '500': "str", + } + + return self.api_client.call_api( + '/anchors/stream/identifiers', 'GET', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) + @validate_arguments def search_anchors(self, transferables : Annotated[Optional[StrictBool], Field(description="This is a boolean that will decided if we are want to return the transferable data (default) or not(performance enhancement)")] = None, search_input : Optional[SearchInput] = None, **kwargs) -> SearchedAnchors: # noqa: E501 """/anchors/search [POST] # noqa: E501 diff --git a/_pieces_lib/pieces_os_client/api/annotations_api.py b/_pieces_lib/pieces_os_client/api/annotations_api.py index d429a73..c50b837 100644 --- a/_pieces_lib/pieces_os_client/api/annotations_api.py +++ b/_pieces_lib/pieces_os_client/api/annotations_api.py @@ -29,6 +29,7 @@ from Pieces._pieces_lib.pieces_os_client.models.search_input import SearchInput from Pieces._pieces_lib.pieces_os_client.models.searched_annotations import SearchedAnnotations from Pieces._pieces_lib.pieces_os_client.models.seeded_annotation import SeededAnnotation +from Pieces._pieces_lib.pieces_os_client.models.streamed_identifiers import StreamedIdentifiers from Pieces._pieces_lib.pieces_os_client.api_client import ApiClient from Pieces._pieces_lib.pieces_os_client.api_response import ApiResponse @@ -477,6 +478,139 @@ def annotations_snapshot_with_http_info(self, annotation_type_filter : Annotated collection_formats=_collection_formats, _request_auth=_params.get('_request_auth')) + @validate_arguments + def annotations_stream_identifiers(self, **kwargs) -> StreamedIdentifiers: # noqa: E501 + """/annotations/stream/identifiers [WS] # noqa: E501 + + Provides a WebSocket connection that emits changes to your annotation identifiers (UUIDs). # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.annotations_stream_identifiers(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: StreamedIdentifiers + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the annotations_stream_identifiers_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.annotations_stream_identifiers_with_http_info(**kwargs) # noqa: E501 + + @validate_arguments + def annotations_stream_identifiers_with_http_info(self, **kwargs) -> ApiResponse: # noqa: E501 + """/annotations/stream/identifiers [WS] # noqa: E501 + + Provides a WebSocket connection that emits changes to your annotation identifiers (UUIDs). # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.annotations_stream_identifiers_with_http_info(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: tuple(StreamedIdentifiers, status_code(int), headers(HTTPHeaderDict)) + """ + + _params = locals() + + _all_params = [ + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method annotations_stream_identifiers" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['application/json', 'text/plain']) # noqa: E501 + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = { + '200': "StreamedIdentifiers", + '500': "str", + } + + return self.api_client.call_api( + '/annotations/stream/identifiers', 'GET', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) + @validate_arguments def search_annotations(self, transferables : Annotated[Optional[StrictBool], Field(description="This is a boolean that will decided if we are want to return the transferable data (default) or not(performance enhancement)")] = None, search_input : Optional[SearchInput] = None, **kwargs) -> SearchedAnnotations: # noqa: E501 """/annotations/search [POST] # noqa: E501 diff --git a/_pieces_lib/pieces_os_client/api/applications_api.py b/_pieces_lib/pieces_os_client/api/applications_api.py index 8d83a3f..e45c916 100644 --- a/_pieces_lib/pieces_os_client/api/applications_api.py +++ b/_pieces_lib/pieces_os_client/api/applications_api.py @@ -27,13 +27,8 @@ from Pieces._pieces_lib.pieces_os_client.models.application import Application from Pieces._pieces_lib.pieces_os_client.models.applications import Applications from Pieces._pieces_lib.pieces_os_client.models.detected_external_applications import DetectedExternalApplications -from Pieces._pieces_lib.pieces_os_client.models.seeded_tracked_interaction_event import SeededTrackedInteractionEvent -from Pieces._pieces_lib.pieces_os_client.models.seeded_tracked_keyboard_event import SeededTrackedKeyboardEvent from Pieces._pieces_lib.pieces_os_client.models.session import Session -from Pieces._pieces_lib.pieces_os_client.models.tracked_application_install import TrackedApplicationInstall -from Pieces._pieces_lib.pieces_os_client.models.tracked_application_update import TrackedApplicationUpdate -from Pieces._pieces_lib.pieces_os_client.models.tracked_interaction_event import TrackedInteractionEvent -from Pieces._pieces_lib.pieces_os_client.models.tracked_keyboard_event import TrackedKeyboardEvent +from Pieces._pieces_lib.pieces_os_client.models.streamed_identifiers import StreamedIdentifiers from Pieces._pieces_lib.pieces_os_client.api_client import ApiClient from Pieces._pieces_lib.pieces_os_client.api_response import ApiResponse @@ -753,148 +748,6 @@ def applications_session_open_with_http_info(self, **kwargs) -> ApiResponse: # collection_formats=_collection_formats, _request_auth=_params.get('_request_auth')) - @validate_arguments - def applications_session_snapshot(self, session : Annotated[StrictStr, Field(..., description="This is a uuid that points to a session.")], **kwargs) -> Session: # noqa: E501 - """(Deprecated) /applications/sessions/{session} [GET] # noqa: E501 - - Fetches detailed information about a specific session, identified by a session UUID, including application usage and engagement data. # noqa: E501 - This method makes a synchronous HTTP request by default. To make an - asynchronous HTTP request, please pass async_req=True - - >>> thread = api.applications_session_snapshot(session, async_req=True) - >>> result = thread.get() - - :param session: This is a uuid that points to a session. (required) - :type session: str - :param async_req: Whether to execute the request asynchronously. - :type async_req: bool, optional - :param _request_timeout: timeout setting for this request. - If one number provided, it will be total request - timeout. It can also be a pair (tuple) of - (connection, read) timeouts. - :return: Returns the result object. - If the method is called asynchronously, - returns the request thread. - :rtype: Session - """ - kwargs['_return_http_data_only'] = True - if '_preload_content' in kwargs: - message = "Error! Please call the applications_session_snapshot_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 - raise ValueError(message) - return self.applications_session_snapshot_with_http_info(session, **kwargs) # noqa: E501 - - @validate_arguments - def applications_session_snapshot_with_http_info(self, session : Annotated[StrictStr, Field(..., description="This is a uuid that points to a session.")], **kwargs) -> ApiResponse: # noqa: E501 - """(Deprecated) /applications/sessions/{session} [GET] # noqa: E501 - - Fetches detailed information about a specific session, identified by a session UUID, including application usage and engagement data. # noqa: E501 - This method makes a synchronous HTTP request by default. To make an - asynchronous HTTP request, please pass async_req=True - - >>> thread = api.applications_session_snapshot_with_http_info(session, async_req=True) - >>> result = thread.get() - - :param session: This is a uuid that points to a session. (required) - :type session: str - :param async_req: Whether to execute the request asynchronously. - :type async_req: bool, optional - :param _preload_content: if False, the ApiResponse.data will - be set to none and raw_data will store the - HTTP response body without reading/decoding. - Default is True. - :type _preload_content: bool, optional - :param _return_http_data_only: response data instead of ApiResponse - object with status code, headers, etc - :type _return_http_data_only: bool, optional - :param _request_timeout: timeout setting for this request. If one - number provided, it will be total request - timeout. It can also be a pair (tuple) of - (connection, read) timeouts. - :param _request_auth: set to override the auth_settings for an a single - request; this effectively ignores the authentication - in the spec for a single request. - :type _request_auth: dict, optional - :type _content_type: string, optional: force content-type for the request - :return: Returns the result object. - If the method is called asynchronously, - returns the request thread. - :rtype: tuple(Session, status_code(int), headers(HTTPHeaderDict)) - """ - - warnings.warn("GET /applications/sessions/{session} is deprecated.", DeprecationWarning) - - _params = locals() - - _all_params = [ - 'session' - ] - _all_params.extend( - [ - 'async_req', - '_return_http_data_only', - '_preload_content', - '_request_timeout', - '_request_auth', - '_content_type', - '_headers' - ] - ) - - # validate the arguments - for _key, _val in _params['kwargs'].items(): - if _key not in _all_params: - raise ApiTypeError( - "Got an unexpected keyword argument '%s'" - " to method applications_session_snapshot" % _key - ) - _params[_key] = _val - del _params['kwargs'] - - _collection_formats = {} - - # process the path parameters - _path_params = {} - if _params['session'] is not None: - _path_params['session'] = _params['session'] - - - # process the query parameters - _query_params = [] - # process the header parameters - _header_params = dict(_params.get('_headers', {})) - # process the form parameters - _form_params = [] - _files = {} - # process the body parameter - _body_params = None - # set the HTTP header `Accept` - _header_params['Accept'] = self.api_client.select_header_accept( - ['application/json']) # noqa: E501 - - # authentication setting - _auth_settings = [] # noqa: E501 - - _response_types_map = { - '200': "Session", - } - - return self.api_client.call_api( - '/applications/sessions/{session}', 'GET', - _path_params, - _query_params, - _header_params, - body=_body_params, - post_params=_form_params, - files=_files, - response_types_map=_response_types_map, - auth_settings=_auth_settings, - async_req=_params.get('async_req'), - _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 - _preload_content=_params.get('_preload_content', True), - _request_timeout=_params.get('_request_timeout'), - collection_formats=_collection_formats, - _request_auth=_params.get('_request_auth')) - @validate_arguments def applications_snapshot(self, **kwargs) -> Applications: # noqa: E501 """/applications [GET] # noqa: E501 @@ -1168,167 +1021,16 @@ def applications_specific_application_snapshot_with_http_info(self, application _request_auth=_params.get('_request_auth')) @validate_arguments - def applications_usage_engagement_interaction(self, seeded_tracked_interaction_event : Optional[SeededTrackedInteractionEvent] = None, **kwargs) -> TrackedInteractionEvent: # noqa: E501 - """(Deprecated) /applications/usage/engagement/interaction [POST] Scoped to Apps # noqa: E501 - - Records user interaction events within applications, such as clicks or taps, to analyze engagement patterns and user behavior. # noqa: E501 - This method makes a synchronous HTTP request by default. To make an - asynchronous HTTP request, please pass async_req=True - - >>> thread = api.applications_usage_engagement_interaction(seeded_tracked_interaction_event, async_req=True) - >>> result = thread.get() - - :param seeded_tracked_interaction_event: - :type seeded_tracked_interaction_event: SeededTrackedInteractionEvent - :param async_req: Whether to execute the request asynchronously. - :type async_req: bool, optional - :param _request_timeout: timeout setting for this request. - If one number provided, it will be total request - timeout. It can also be a pair (tuple) of - (connection, read) timeouts. - :return: Returns the result object. - If the method is called asynchronously, - returns the request thread. - :rtype: TrackedInteractionEvent - """ - kwargs['_return_http_data_only'] = True - if '_preload_content' in kwargs: - message = "Error! Please call the applications_usage_engagement_interaction_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 - raise ValueError(message) - return self.applications_usage_engagement_interaction_with_http_info(seeded_tracked_interaction_event, **kwargs) # noqa: E501 - - @validate_arguments - def applications_usage_engagement_interaction_with_http_info(self, seeded_tracked_interaction_event : Optional[SeededTrackedInteractionEvent] = None, **kwargs) -> ApiResponse: # noqa: E501 - """(Deprecated) /applications/usage/engagement/interaction [POST] Scoped to Apps # noqa: E501 - - Records user interaction events within applications, such as clicks or taps, to analyze engagement patterns and user behavior. # noqa: E501 - This method makes a synchronous HTTP request by default. To make an - asynchronous HTTP request, please pass async_req=True - - >>> thread = api.applications_usage_engagement_interaction_with_http_info(seeded_tracked_interaction_event, async_req=True) - >>> result = thread.get() - - :param seeded_tracked_interaction_event: - :type seeded_tracked_interaction_event: SeededTrackedInteractionEvent - :param async_req: Whether to execute the request asynchronously. - :type async_req: bool, optional - :param _preload_content: if False, the ApiResponse.data will - be set to none and raw_data will store the - HTTP response body without reading/decoding. - Default is True. - :type _preload_content: bool, optional - :param _return_http_data_only: response data instead of ApiResponse - object with status code, headers, etc - :type _return_http_data_only: bool, optional - :param _request_timeout: timeout setting for this request. If one - number provided, it will be total request - timeout. It can also be a pair (tuple) of - (connection, read) timeouts. - :param _request_auth: set to override the auth_settings for an a single - request; this effectively ignores the authentication - in the spec for a single request. - :type _request_auth: dict, optional - :type _content_type: string, optional: force content-type for the request - :return: Returns the result object. - If the method is called asynchronously, - returns the request thread. - :rtype: tuple(TrackedInteractionEvent, status_code(int), headers(HTTPHeaderDict)) - """ - - warnings.warn("POST /applications/usage/engagement/interaction is deprecated.", DeprecationWarning) - - _params = locals() - - _all_params = [ - 'seeded_tracked_interaction_event' - ] - _all_params.extend( - [ - 'async_req', - '_return_http_data_only', - '_preload_content', - '_request_timeout', - '_request_auth', - '_content_type', - '_headers' - ] - ) - - # validate the arguments - for _key, _val in _params['kwargs'].items(): - if _key not in _all_params: - raise ApiTypeError( - "Got an unexpected keyword argument '%s'" - " to method applications_usage_engagement_interaction" % _key - ) - _params[_key] = _val - del _params['kwargs'] - - _collection_formats = {} - - # process the path parameters - _path_params = {} - - # process the query parameters - _query_params = [] - # process the header parameters - _header_params = dict(_params.get('_headers', {})) - # process the form parameters - _form_params = [] - _files = {} - # process the body parameter - _body_params = None - if _params['seeded_tracked_interaction_event'] is not None: - _body_params = _params['seeded_tracked_interaction_event'] - - # set the HTTP header `Accept` - _header_params['Accept'] = self.api_client.select_header_accept( - ['application/json']) # noqa: E501 - - # set the HTTP header `Content-Type` - _content_types_list = _params.get('_content_type', - self.api_client.select_header_content_type( - ['application/json'])) - if _content_types_list: - _header_params['Content-Type'] = _content_types_list - - # authentication setting - _auth_settings = [] # noqa: E501 - - _response_types_map = { - '200': "TrackedInteractionEvent", - } - - return self.api_client.call_api( - '/applications/usage/engagement/interaction', 'POST', - _path_params, - _query_params, - _header_params, - body=_body_params, - post_params=_form_params, - files=_files, - response_types_map=_response_types_map, - auth_settings=_auth_settings, - async_req=_params.get('async_req'), - _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 - _preload_content=_params.get('_preload_content', True), - _request_timeout=_params.get('_request_timeout'), - collection_formats=_collection_formats, - _request_auth=_params.get('_request_auth')) - - @validate_arguments - def applications_usage_engagement_keyboard(self, seeded_tracked_keyboard_event : Optional[SeededTrackedKeyboardEvent] = None, **kwargs) -> TrackedKeyboardEvent: # noqa: E501 - """(Deprecated) /applications/usage/engagement/keyboard [POST] Scoped to Apps # noqa: E501 + def applications_stream_identifiers(self, **kwargs) -> StreamedIdentifiers: # noqa: E501 + """/applications/stream/identifiers [WS] # noqa: E501 - Captures keyboard interaction events, including shortcuts, within applications to monitor user engagement and productivity enhancements. # noqa: E501 + Provides a WebSocket connection that emits changes to your application identifiers (UUIDs). # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True - >>> thread = api.applications_usage_engagement_keyboard(seeded_tracked_keyboard_event, async_req=True) + >>> thread = api.applications_stream_identifiers(async_req=True) >>> result = thread.get() - :param seeded_tracked_keyboard_event: - :type seeded_tracked_keyboard_event: SeededTrackedKeyboardEvent :param async_req: Whether to execute the request asynchronously. :type async_req: bool, optional :param _request_timeout: timeout setting for this request. @@ -1338,27 +1040,25 @@ def applications_usage_engagement_keyboard(self, seeded_tracked_keyboard_event : :return: Returns the result object. If the method is called asynchronously, returns the request thread. - :rtype: TrackedKeyboardEvent + :rtype: StreamedIdentifiers """ kwargs['_return_http_data_only'] = True if '_preload_content' in kwargs: - message = "Error! Please call the applications_usage_engagement_keyboard_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + message = "Error! Please call the applications_stream_identifiers_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 raise ValueError(message) - return self.applications_usage_engagement_keyboard_with_http_info(seeded_tracked_keyboard_event, **kwargs) # noqa: E501 + return self.applications_stream_identifiers_with_http_info(**kwargs) # noqa: E501 @validate_arguments - def applications_usage_engagement_keyboard_with_http_info(self, seeded_tracked_keyboard_event : Optional[SeededTrackedKeyboardEvent] = None, **kwargs) -> ApiResponse: # noqa: E501 - """(Deprecated) /applications/usage/engagement/keyboard [POST] Scoped to Apps # noqa: E501 + def applications_stream_identifiers_with_http_info(self, **kwargs) -> ApiResponse: # noqa: E501 + """/applications/stream/identifiers [WS] # noqa: E501 - Captures keyboard interaction events, including shortcuts, within applications to monitor user engagement and productivity enhancements. # noqa: E501 + Provides a WebSocket connection that emits changes to your application identifiers (UUIDs). # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True - >>> thread = api.applications_usage_engagement_keyboard_with_http_info(seeded_tracked_keyboard_event, async_req=True) + >>> thread = api.applications_stream_identifiers_with_http_info(async_req=True) >>> result = thread.get() - :param seeded_tracked_keyboard_event: - :type seeded_tracked_keyboard_event: SeededTrackedKeyboardEvent :param async_req: Whether to execute the request asynchronously. :type async_req: bool, optional :param _preload_content: if False, the ApiResponse.data will @@ -1381,15 +1081,12 @@ def applications_usage_engagement_keyboard_with_http_info(self, seeded_tracked_k :return: Returns the result object. If the method is called asynchronously, returns the request thread. - :rtype: tuple(TrackedKeyboardEvent, status_code(int), headers(HTTPHeaderDict)) + :rtype: tuple(StreamedIdentifiers, status_code(int), headers(HTTPHeaderDict)) """ - warnings.warn("POST /applications/usage/engagement/keyboard is deprecated.", DeprecationWarning) - _params = locals() _all_params = [ - 'seeded_tracked_keyboard_event' ] _all_params.extend( [ @@ -1408,7 +1105,7 @@ def applications_usage_engagement_keyboard_with_http_info(self, seeded_tracked_k if _key not in _all_params: raise ApiTypeError( "Got an unexpected keyword argument '%s'" - " to method applications_usage_engagement_keyboard" % _key + " to method applications_stream_identifiers" % _key ) _params[_key] = _val del _params['kwargs'] @@ -1427,315 +1124,20 @@ def applications_usage_engagement_keyboard_with_http_info(self, seeded_tracked_k _files = {} # process the body parameter _body_params = None - if _params['seeded_tracked_keyboard_event'] is not None: - _body_params = _params['seeded_tracked_keyboard_event'] - # set the HTTP header `Accept` _header_params['Accept'] = self.api_client.select_header_accept( - ['application/json']) # noqa: E501 - - # set the HTTP header `Content-Type` - _content_types_list = _params.get('_content_type', - self.api_client.select_header_content_type( - ['application/json'])) - if _content_types_list: - _header_params['Content-Type'] = _content_types_list + ['application/json', 'text/plain']) # noqa: E501 # authentication setting _auth_settings = [] # noqa: E501 _response_types_map = { - '200': "TrackedKeyboardEvent", + '200': "StreamedIdentifiers", + '500': "str", } return self.api_client.call_api( - '/applications/usage/engagement/keyboard', 'POST', - _path_params, - _query_params, - _header_params, - body=_body_params, - post_params=_form_params, - files=_files, - response_types_map=_response_types_map, - auth_settings=_auth_settings, - async_req=_params.get('async_req'), - _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 - _preload_content=_params.get('_preload_content', True), - _request_timeout=_params.get('_request_timeout'), - collection_formats=_collection_formats, - _request_auth=_params.get('_request_auth')) - - @validate_arguments - def applications_usage_installation(self, tracked_application_install : Optional[TrackedApplicationInstall] = None, **kwargs) -> None: # noqa: E501 - """(Deprecated) /applications/usage/installation [POST] # noqa: E501 - - Logs the installation events of the Pieces application. # noqa: E501 - This method makes a synchronous HTTP request by default. To make an - asynchronous HTTP request, please pass async_req=True - - >>> thread = api.applications_usage_installation(tracked_application_install, async_req=True) - >>> result = thread.get() - - :param tracked_application_install: - :type tracked_application_install: TrackedApplicationInstall - :param async_req: Whether to execute the request asynchronously. - :type async_req: bool, optional - :param _request_timeout: timeout setting for this request. - If one number provided, it will be total request - timeout. It can also be a pair (tuple) of - (connection, read) timeouts. - :return: Returns the result object. - If the method is called asynchronously, - returns the request thread. - :rtype: None - """ - kwargs['_return_http_data_only'] = True - if '_preload_content' in kwargs: - message = "Error! Please call the applications_usage_installation_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 - raise ValueError(message) - return self.applications_usage_installation_with_http_info(tracked_application_install, **kwargs) # noqa: E501 - - @validate_arguments - def applications_usage_installation_with_http_info(self, tracked_application_install : Optional[TrackedApplicationInstall] = None, **kwargs) -> ApiResponse: # noqa: E501 - """(Deprecated) /applications/usage/installation [POST] # noqa: E501 - - Logs the installation events of the Pieces application. # noqa: E501 - This method makes a synchronous HTTP request by default. To make an - asynchronous HTTP request, please pass async_req=True - - >>> thread = api.applications_usage_installation_with_http_info(tracked_application_install, async_req=True) - >>> result = thread.get() - - :param tracked_application_install: - :type tracked_application_install: TrackedApplicationInstall - :param async_req: Whether to execute the request asynchronously. - :type async_req: bool, optional - :param _preload_content: if False, the ApiResponse.data will - be set to none and raw_data will store the - HTTP response body without reading/decoding. - Default is True. - :type _preload_content: bool, optional - :param _return_http_data_only: response data instead of ApiResponse - object with status code, headers, etc - :type _return_http_data_only: bool, optional - :param _request_timeout: timeout setting for this request. If one - number provided, it will be total request - timeout. It can also be a pair (tuple) of - (connection, read) timeouts. - :param _request_auth: set to override the auth_settings for an a single - request; this effectively ignores the authentication - in the spec for a single request. - :type _request_auth: dict, optional - :type _content_type: string, optional: force content-type for the request - :return: Returns the result object. - If the method is called asynchronously, - returns the request thread. - :rtype: None - """ - - warnings.warn("POST /applications/usage/installation is deprecated.", DeprecationWarning) - - _params = locals() - - _all_params = [ - 'tracked_application_install' - ] - _all_params.extend( - [ - 'async_req', - '_return_http_data_only', - '_preload_content', - '_request_timeout', - '_request_auth', - '_content_type', - '_headers' - ] - ) - - # validate the arguments - for _key, _val in _params['kwargs'].items(): - if _key not in _all_params: - raise ApiTypeError( - "Got an unexpected keyword argument '%s'" - " to method applications_usage_installation" % _key - ) - _params[_key] = _val - del _params['kwargs'] - - _collection_formats = {} - - # process the path parameters - _path_params = {} - - # process the query parameters - _query_params = [] - # process the header parameters - _header_params = dict(_params.get('_headers', {})) - # process the form parameters - _form_params = [] - _files = {} - # process the body parameter - _body_params = None - if _params['tracked_application_install'] is not None: - _body_params = _params['tracked_application_install'] - - # set the HTTP header `Content-Type` - _content_types_list = _params.get('_content_type', - self.api_client.select_header_content_type( - ['application/json'])) - if _content_types_list: - _header_params['Content-Type'] = _content_types_list - - # authentication setting - _auth_settings = [] # noqa: E501 - - _response_types_map = {} - - return self.api_client.call_api( - '/applications/usage/installation', 'POST', - _path_params, - _query_params, - _header_params, - body=_body_params, - post_params=_form_params, - files=_files, - response_types_map=_response_types_map, - auth_settings=_auth_settings, - async_req=_params.get('async_req'), - _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 - _preload_content=_params.get('_preload_content', True), - _request_timeout=_params.get('_request_timeout'), - collection_formats=_collection_formats, - _request_auth=_params.get('_request_auth')) - - @validate_arguments - def post_applications_usage_updated(self, tracked_application_update : Annotated[Optional[TrackedApplicationUpdate], Field(description="Sending over the previous application version, the current version, and the user.")] = None, **kwargs) -> None: # noqa: E501 - """(Deprecated) /applications/usage/updated [POST] # noqa: E501 - - Tracks updates to the Pieces application, including version changes. # noqa: E501 - This method makes a synchronous HTTP request by default. To make an - asynchronous HTTP request, please pass async_req=True - - >>> thread = api.post_applications_usage_updated(tracked_application_update, async_req=True) - >>> result = thread.get() - - :param tracked_application_update: Sending over the previous application version, the current version, and the user. - :type tracked_application_update: TrackedApplicationUpdate - :param async_req: Whether to execute the request asynchronously. - :type async_req: bool, optional - :param _request_timeout: timeout setting for this request. - If one number provided, it will be total request - timeout. It can also be a pair (tuple) of - (connection, read) timeouts. - :return: Returns the result object. - If the method is called asynchronously, - returns the request thread. - :rtype: None - """ - kwargs['_return_http_data_only'] = True - if '_preload_content' in kwargs: - message = "Error! Please call the post_applications_usage_updated_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 - raise ValueError(message) - return self.post_applications_usage_updated_with_http_info(tracked_application_update, **kwargs) # noqa: E501 - - @validate_arguments - def post_applications_usage_updated_with_http_info(self, tracked_application_update : Annotated[Optional[TrackedApplicationUpdate], Field(description="Sending over the previous application version, the current version, and the user.")] = None, **kwargs) -> ApiResponse: # noqa: E501 - """(Deprecated) /applications/usage/updated [POST] # noqa: E501 - - Tracks updates to the Pieces application, including version changes. # noqa: E501 - This method makes a synchronous HTTP request by default. To make an - asynchronous HTTP request, please pass async_req=True - - >>> thread = api.post_applications_usage_updated_with_http_info(tracked_application_update, async_req=True) - >>> result = thread.get() - - :param tracked_application_update: Sending over the previous application version, the current version, and the user. - :type tracked_application_update: TrackedApplicationUpdate - :param async_req: Whether to execute the request asynchronously. - :type async_req: bool, optional - :param _preload_content: if False, the ApiResponse.data will - be set to none and raw_data will store the - HTTP response body without reading/decoding. - Default is True. - :type _preload_content: bool, optional - :param _return_http_data_only: response data instead of ApiResponse - object with status code, headers, etc - :type _return_http_data_only: bool, optional - :param _request_timeout: timeout setting for this request. If one - number provided, it will be total request - timeout. It can also be a pair (tuple) of - (connection, read) timeouts. - :param _request_auth: set to override the auth_settings for an a single - request; this effectively ignores the authentication - in the spec for a single request. - :type _request_auth: dict, optional - :type _content_type: string, optional: force content-type for the request - :return: Returns the result object. - If the method is called asynchronously, - returns the request thread. - :rtype: None - """ - - warnings.warn("POST /applications/usage/updated is deprecated.", DeprecationWarning) - - _params = locals() - - _all_params = [ - 'tracked_application_update' - ] - _all_params.extend( - [ - 'async_req', - '_return_http_data_only', - '_preload_content', - '_request_timeout', - '_request_auth', - '_content_type', - '_headers' - ] - ) - - # validate the arguments - for _key, _val in _params['kwargs'].items(): - if _key not in _all_params: - raise ApiTypeError( - "Got an unexpected keyword argument '%s'" - " to method post_applications_usage_updated" % _key - ) - _params[_key] = _val - del _params['kwargs'] - - _collection_formats = {} - - # process the path parameters - _path_params = {} - - # process the query parameters - _query_params = [] - # process the header parameters - _header_params = dict(_params.get('_headers', {})) - # process the form parameters - _form_params = [] - _files = {} - # process the body parameter - _body_params = None - if _params['tracked_application_update'] is not None: - _body_params = _params['tracked_application_update'] - - # set the HTTP header `Content-Type` - _content_types_list = _params.get('_content_type', - self.api_client.select_header_content_type( - ['application/json'])) - if _content_types_list: - _header_params['Content-Type'] = _content_types_list - - # authentication setting - _auth_settings = [] # noqa: E501 - - _response_types_map = {} - - return self.api_client.call_api( - '/applications/usage/updated', 'POST', + '/applications/stream/identifiers', 'GET', _path_params, _query_params, _header_params, diff --git a/_pieces_lib/pieces_os_client/api/backup_api.py b/_pieces_lib/pieces_os_client/api/backup_api.py index 6d4e73b..7654ca4 100644 --- a/_pieces_lib/pieces_os_client/api/backup_api.py +++ b/_pieces_lib/pieces_os_client/api/backup_api.py @@ -500,7 +500,7 @@ def backup_restore_specific_backup_with_http_info(self, backup : Annotated[Stric def backup_restore_specific_backup_streamed(self, backup : Annotated[StrictStr, Field(..., description="This is a identifier that is used to identify a specific backup.(version_timestamp)")], backup2 : Optional[Backup] = None, **kwargs) -> BackupStreamedProgress: # noqa: E501 """/backup/{backup}/restore/streamed [POST] # noqa: E501 - This take a local database and ensure that it is backed up to the cloud. NOTE: This is a streamed version of the /backups/create. and Since the Generator is unable to generate a streamed endpoint. this is a place holder, and will need to be implemented isolated from the code generator. # noqa: E501 + This take a local database and ensure that it is backed up to the cloud. NOTE: This is a streamed version of the /backups//restore. and Since the Generator is unable to generate a streamed endpoint. this is a place holder, and will need to be implemented isolated from the code generator. # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True @@ -532,7 +532,7 @@ def backup_restore_specific_backup_streamed(self, backup : Annotated[StrictStr, def backup_restore_specific_backup_streamed_with_http_info(self, backup : Annotated[StrictStr, Field(..., description="This is a identifier that is used to identify a specific backup.(version_timestamp)")], backup2 : Optional[Backup] = None, **kwargs) -> ApiResponse: # noqa: E501 """/backup/{backup}/restore/streamed [POST] # noqa: E501 - This take a local database and ensure that it is backed up to the cloud. NOTE: This is a streamed version of the /backups/create. and Since the Generator is unable to generate a streamed endpoint. this is a place holder, and will need to be implemented isolated from the code generator. # noqa: E501 + This take a local database and ensure that it is backed up to the cloud. NOTE: This is a streamed version of the /backups//restore. and Since the Generator is unable to generate a streamed endpoint. this is a place holder, and will need to be implemented isolated from the code generator. # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True @@ -654,6 +654,164 @@ def backup_restore_specific_backup_streamed_with_http_info(self, backup : Annota collection_formats=_collection_formats, _request_auth=_params.get('_request_auth')) + @validate_arguments + def backup_restore_specific_backup_streamed_websocket(self, backup : Annotated[StrictStr, Field(..., description="This is a identifier that is used to identify a specific backup.(version_timestamp)")], backup2 : Optional[Backup] = None, **kwargs) -> BackupStreamedProgress: # noqa: E501 + """/backup/{backup}/restore/streamed/websocket [WS] # noqa: E501 + + WEBOCKET IMPLEMENTATION: This take a local database and ensure that it is backed up to the cloud. NOTE: This is a streamed version of the /backups//restore. and Since the Generator is unable to generate a streamed endpoint. this is a place holder, and will need to be implemented isolated from the code generator. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.backup_restore_specific_backup_streamed_websocket(backup, backup2, async_req=True) + >>> result = thread.get() + + :param backup: This is a identifier that is used to identify a specific backup.(version_timestamp) (required) + :type backup: str + :param backup2: + :type backup2: Backup + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: BackupStreamedProgress + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the backup_restore_specific_backup_streamed_websocket_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.backup_restore_specific_backup_streamed_websocket_with_http_info(backup, backup2, **kwargs) # noqa: E501 + + @validate_arguments + def backup_restore_specific_backup_streamed_websocket_with_http_info(self, backup : Annotated[StrictStr, Field(..., description="This is a identifier that is used to identify a specific backup.(version_timestamp)")], backup2 : Optional[Backup] = None, **kwargs) -> ApiResponse: # noqa: E501 + """/backup/{backup}/restore/streamed/websocket [WS] # noqa: E501 + + WEBOCKET IMPLEMENTATION: This take a local database and ensure that it is backed up to the cloud. NOTE: This is a streamed version of the /backups//restore. and Since the Generator is unable to generate a streamed endpoint. this is a place holder, and will need to be implemented isolated from the code generator. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.backup_restore_specific_backup_streamed_websocket_with_http_info(backup, backup2, async_req=True) + >>> result = thread.get() + + :param backup: This is a identifier that is used to identify a specific backup.(version_timestamp) (required) + :type backup: str + :param backup2: + :type backup2: Backup + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: tuple(BackupStreamedProgress, status_code(int), headers(HTTPHeaderDict)) + """ + + _params = locals() + + _all_params = [ + 'backup', + 'backup2' + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method backup_restore_specific_backup_streamed_websocket" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + if _params['backup'] is not None: + _path_params['backup'] = _params['backup'] + + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + if _params['backup2'] is not None: + _body_params = _params['backup2'] + + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['application/json', 'text/plain']) # noqa: E501 + + # set the HTTP header `Content-Type` + _content_types_list = _params.get('_content_type', + self.api_client.select_header_content_type( + ['application/json'])) + if _content_types_list: + _header_params['Content-Type'] = _content_types_list + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = { + '200': "BackupStreamedProgress", + '500': "str", + '511': "str", + '505': "str", + } + + return self.api_client.call_api( + '/backup/{backup}/restore/streamed/websocket', 'GET', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) + @validate_arguments def backup_specific_backup_snapshot(self, backup : Annotated[StrictStr, Field(..., description="This is a identifier that is used to identify a specific backup.(version_timestamp)")], **kwargs) -> Backup: # noqa: E501 """/backup/{backup} [GET] # noqa: E501 diff --git a/_pieces_lib/pieces_os_client/api/backups_api.py b/_pieces_lib/pieces_os_client/api/backups_api.py index 4c9b0bf..8828bfe 100644 --- a/_pieces_lib/pieces_os_client/api/backups_api.py +++ b/_pieces_lib/pieces_os_client/api/backups_api.py @@ -27,6 +27,7 @@ from Pieces._pieces_lib.pieces_os_client.models.backup import Backup from Pieces._pieces_lib.pieces_os_client.models.backup_streamed_progress import BackupStreamedProgress from Pieces._pieces_lib.pieces_os_client.models.backups import Backups +from Pieces._pieces_lib.pieces_os_client.models.backups_streamed_progress import BackupsStreamedProgress from Pieces._pieces_lib.pieces_os_client.models.seeded_backup import SeededBackup from Pieces._pieces_lib.pieces_os_client.api_client import ApiClient @@ -349,6 +350,156 @@ def backups_create_new_backup_streamed_with_http_info(self, seeded_backup : Opti collection_formats=_collection_formats, _request_auth=_params.get('_request_auth')) + @validate_arguments + def backups_create_new_backup_streamed_websocket(self, seeded_backup : Optional[SeededBackup] = None, **kwargs) -> BackupStreamedProgress: # noqa: E501 + """/backups/create/streamed/websocket [WS] # noqa: E501 + + WEBSOCKET VERSION! This take a local database and ensure that it is backed up to the cloud. NOTE: This is a streamed version of the /backups/create. and Since the Generator is unable to generate a streamed endpoint. this is a place holder, and will need to be implemented isolated from the code generator. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.backups_create_new_backup_streamed_websocket(seeded_backup, async_req=True) + >>> result = thread.get() + + :param seeded_backup: + :type seeded_backup: SeededBackup + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: BackupStreamedProgress + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the backups_create_new_backup_streamed_websocket_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.backups_create_new_backup_streamed_websocket_with_http_info(seeded_backup, **kwargs) # noqa: E501 + + @validate_arguments + def backups_create_new_backup_streamed_websocket_with_http_info(self, seeded_backup : Optional[SeededBackup] = None, **kwargs) -> ApiResponse: # noqa: E501 + """/backups/create/streamed/websocket [WS] # noqa: E501 + + WEBSOCKET VERSION! This take a local database and ensure that it is backed up to the cloud. NOTE: This is a streamed version of the /backups/create. and Since the Generator is unable to generate a streamed endpoint. this is a place holder, and will need to be implemented isolated from the code generator. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.backups_create_new_backup_streamed_websocket_with_http_info(seeded_backup, async_req=True) + >>> result = thread.get() + + :param seeded_backup: + :type seeded_backup: SeededBackup + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: tuple(BackupStreamedProgress, status_code(int), headers(HTTPHeaderDict)) + """ + + _params = locals() + + _all_params = [ + 'seeded_backup' + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method backups_create_new_backup_streamed_websocket" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + if _params['seeded_backup'] is not None: + _body_params = _params['seeded_backup'] + + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['application/json', 'text/plain']) # noqa: E501 + + # set the HTTP header `Content-Type` + _content_types_list = _params.get('_content_type', + self.api_client.select_header_content_type( + ['application/json'])) + if _content_types_list: + _header_params['Content-Type'] = _content_types_list + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = { + '200': "BackupStreamedProgress", + '500': "str", + '511': "str", + '505': "str", + } + + return self.api_client.call_api( + '/backups/create/streamed/websocket', 'GET', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) + @validate_arguments def backups_delete_specific_backup(self, backup : Annotated[StrictStr, Field(..., description="This is a identifier that is used to identify a specific backup.(version_timestamp)")], backup2 : Optional[Backup] = None, **kwargs) -> None: # noqa: E501 """/backups/{backup}/delete [POST] # noqa: E501 @@ -636,3 +787,136 @@ def backups_snapshot_with_http_info(self, **kwargs) -> ApiResponse: # noqa: E50 _request_timeout=_params.get('_request_timeout'), collection_formats=_collection_formats, _request_auth=_params.get('_request_auth')) + + @validate_arguments + def backups_streamed_progress(self, **kwargs) -> BackupsStreamedProgress: # noqa: E501 + """/backups/streamed/progress [WS] # noqa: E501 + + This endpoint is a Websocket, that will list all the current websockets that are in progress, this will emit changes as there are changes with the backups or restores in progress. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.backups_streamed_progress(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: BackupsStreamedProgress + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the backups_streamed_progress_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.backups_streamed_progress_with_http_info(**kwargs) # noqa: E501 + + @validate_arguments + def backups_streamed_progress_with_http_info(self, **kwargs) -> ApiResponse: # noqa: E501 + """/backups/streamed/progress [WS] # noqa: E501 + + This endpoint is a Websocket, that will list all the current websockets that are in progress, this will emit changes as there are changes with the backups or restores in progress. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.backups_streamed_progress_with_http_info(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: tuple(BackupsStreamedProgress, status_code(int), headers(HTTPHeaderDict)) + """ + + _params = locals() + + _all_params = [ + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method backups_streamed_progress" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['application/json', 'text/plain']) # noqa: E501 + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = { + '200': "BackupsStreamedProgress", + '500': "str", + } + + return self.api_client.call_api( + '/backups/streamed/progress', 'GET', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) diff --git a/_pieces_lib/pieces_os_client/api/conversation_message_api.py b/_pieces_lib/pieces_os_client/api/conversation_message_api.py index 52e0cae..478ce35 100644 --- a/_pieces_lib/pieces_os_client/api/conversation_message_api.py +++ b/_pieces_lib/pieces_os_client/api/conversation_message_api.py @@ -47,6 +47,152 @@ def __init__(self, api_client=None) -> None: api_client = ApiClient.get_default() self.api_client = api_client + @validate_arguments + def message_associate_anchor(self, message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], anchor : Annotated[StrictStr, Field(..., description="This is the specific uuid of an anchor.")], **kwargs) -> None: # noqa: E501 + """/message/{message}/anchors/associate/{anchor} [POST] # noqa: E501 + + This will associate a message with an anchor. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.message_associate_anchor(message, anchor, async_req=True) + >>> result = thread.get() + + :param message: This is the uuid of a message. (required) + :type message: str + :param anchor: This is the specific uuid of an anchor. (required) + :type anchor: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the message_associate_anchor_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.message_associate_anchor_with_http_info(message, anchor, **kwargs) # noqa: E501 + + @validate_arguments + def message_associate_anchor_with_http_info(self, message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], anchor : Annotated[StrictStr, Field(..., description="This is the specific uuid of an anchor.")], **kwargs) -> ApiResponse: # noqa: E501 + """/message/{message}/anchors/associate/{anchor} [POST] # noqa: E501 + + This will associate a message with an anchor. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.message_associate_anchor_with_http_info(message, anchor, async_req=True) + >>> result = thread.get() + + :param message: This is the uuid of a message. (required) + :type message: str + :param anchor: This is the specific uuid of an anchor. (required) + :type anchor: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + + _params = locals() + + _all_params = [ + 'message', + 'anchor' + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method message_associate_anchor" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + if _params['message'] is not None: + _path_params['message'] = _params['message'] + + if _params['anchor'] is not None: + _path_params['anchor'] = _params['anchor'] + + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['text/plain']) # noqa: E501 + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = {} + + return self.api_client.call_api( + '/message/{message}/anchors/associate/{anchor}', 'POST', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) + @validate_arguments def message_associate_annotation(self, annotation : Annotated[StrictStr, Field(..., description="This is a specific annotation uuid.")], message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], **kwargs) -> None: # noqa: E501 """/message/{message}/annotations/associate/{annotation} [POST] # noqa: E501 @@ -194,20 +340,20 @@ def message_associate_annotation_with_http_info(self, annotation : Annotated[Str _request_auth=_params.get('_request_auth')) @validate_arguments - def message_disassociate_annotation(self, annotation : Annotated[StrictStr, Field(..., description="This is a specific annotation uuid.")], message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], **kwargs) -> None: # noqa: E501 - """/message/{message}/annotations/disassociate/{annotation} [POST] # noqa: E501 + def message_associate_person(self, message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], person : Annotated[StrictStr, Field(..., description="This is a uuid that represents a person.")], **kwargs) -> None: # noqa: E501 + """/message/{message}/persons/associate/{person} [POST] # noqa: E501 - This will enable us to dissassociate a message from an annotation. # noqa: E501 + This will associate a message with a person. # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True - >>> thread = api.message_disassociate_annotation(annotation, message, async_req=True) + >>> thread = api.message_associate_person(message, person, async_req=True) >>> result = thread.get() - :param annotation: This is a specific annotation uuid. (required) - :type annotation: str :param message: This is the uuid of a message. (required) :type message: str + :param person: This is a uuid that represents a person. (required) + :type person: str :param async_req: Whether to execute the request asynchronously. :type async_req: bool, optional :param _request_timeout: timeout setting for this request. @@ -221,25 +367,25 @@ def message_disassociate_annotation(self, annotation : Annotated[StrictStr, Fiel """ kwargs['_return_http_data_only'] = True if '_preload_content' in kwargs: - message = "Error! Please call the message_disassociate_annotation_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + message = "Error! Please call the message_associate_person_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 raise ValueError(message) - return self.message_disassociate_annotation_with_http_info(annotation, message, **kwargs) # noqa: E501 + return self.message_associate_person_with_http_info(message, person, **kwargs) # noqa: E501 @validate_arguments - def message_disassociate_annotation_with_http_info(self, annotation : Annotated[StrictStr, Field(..., description="This is a specific annotation uuid.")], message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], **kwargs) -> ApiResponse: # noqa: E501 - """/message/{message}/annotations/disassociate/{annotation} [POST] # noqa: E501 + def message_associate_person_with_http_info(self, message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], person : Annotated[StrictStr, Field(..., description="This is a uuid that represents a person.")], **kwargs) -> ApiResponse: # noqa: E501 + """/message/{message}/persons/associate/{person} [POST] # noqa: E501 - This will enable us to dissassociate a message from an annotation. # noqa: E501 + This will associate a message with a person. # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True - >>> thread = api.message_disassociate_annotation_with_http_info(annotation, message, async_req=True) + >>> thread = api.message_associate_person_with_http_info(message, person, async_req=True) >>> result = thread.get() - :param annotation: This is a specific annotation uuid. (required) - :type annotation: str :param message: This is the uuid of a message. (required) :type message: str + :param person: This is a uuid that represents a person. (required) + :type person: str :param async_req: Whether to execute the request asynchronously. :type async_req: bool, optional :param _preload_content: if False, the ApiResponse.data will @@ -268,8 +414,8 @@ def message_disassociate_annotation_with_http_info(self, annotation : Annotated[ _params = locals() _all_params = [ - 'annotation', - 'message' + 'message', + 'person' ] _all_params.extend( [ @@ -288,7 +434,7 @@ def message_disassociate_annotation_with_http_info(self, annotation : Annotated[ if _key not in _all_params: raise ApiTypeError( "Got an unexpected keyword argument '%s'" - " to method message_disassociate_annotation" % _key + " to method message_associate_person" % _key ) _params[_key] = _val del _params['kwargs'] @@ -297,12 +443,12 @@ def message_disassociate_annotation_with_http_info(self, annotation : Annotated[ # process the path parameters _path_params = {} - if _params['annotation'] is not None: - _path_params['annotation'] = _params['annotation'] - if _params['message'] is not None: _path_params['message'] = _params['message'] + if _params['person'] is not None: + _path_params['person'] = _params['person'] + # process the query parameters _query_params = [] @@ -323,7 +469,737 @@ def message_disassociate_annotation_with_http_info(self, annotation : Annotated[ _response_types_map = {} return self.api_client.call_api( - '/message/{message}/annotations/disassociate/{annotation}', 'POST', + '/message/{message}/persons/associate/{person}', 'POST', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) + + @validate_arguments + def message_associate_website(self, message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], website : Annotated[StrictStr, Field(..., description="website id")], **kwargs) -> None: # noqa: E501 + """Associate a message with a website # noqa: E501 + + This will associate a message with a website. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.message_associate_website(message, website, async_req=True) + >>> result = thread.get() + + :param message: This is the uuid of a message. (required) + :type message: str + :param website: website id (required) + :type website: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the message_associate_website_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.message_associate_website_with_http_info(message, website, **kwargs) # noqa: E501 + + @validate_arguments + def message_associate_website_with_http_info(self, message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], website : Annotated[StrictStr, Field(..., description="website id")], **kwargs) -> ApiResponse: # noqa: E501 + """Associate a message with a website # noqa: E501 + + This will associate a message with a website. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.message_associate_website_with_http_info(message, website, async_req=True) + >>> result = thread.get() + + :param message: This is the uuid of a message. (required) + :type message: str + :param website: website id (required) + :type website: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + + _params = locals() + + _all_params = [ + 'message', + 'website' + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method message_associate_website" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + if _params['message'] is not None: + _path_params['message'] = _params['message'] + + if _params['website'] is not None: + _path_params['website'] = _params['website'] + + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['text/plain']) # noqa: E501 + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = {} + + return self.api_client.call_api( + '/message/{message}/websites/associate/{website}', 'POST', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) + + @validate_arguments + def message_disassociate_anchor(self, message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], anchor : Annotated[StrictStr, Field(..., description="This is the specific uuid of an anchor.")], **kwargs) -> None: # noqa: E501 + """/message/{message}/anchors/disassociate/{anchor} [POST] # noqa: E501 + + This will enable us to disassociate a message from an anchor. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.message_disassociate_anchor(message, anchor, async_req=True) + >>> result = thread.get() + + :param message: This is the uuid of a message. (required) + :type message: str + :param anchor: This is the specific uuid of an anchor. (required) + :type anchor: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the message_disassociate_anchor_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.message_disassociate_anchor_with_http_info(message, anchor, **kwargs) # noqa: E501 + + @validate_arguments + def message_disassociate_anchor_with_http_info(self, message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], anchor : Annotated[StrictStr, Field(..., description="This is the specific uuid of an anchor.")], **kwargs) -> ApiResponse: # noqa: E501 + """/message/{message}/anchors/disassociate/{anchor} [POST] # noqa: E501 + + This will enable us to disassociate a message from an anchor. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.message_disassociate_anchor_with_http_info(message, anchor, async_req=True) + >>> result = thread.get() + + :param message: This is the uuid of a message. (required) + :type message: str + :param anchor: This is the specific uuid of an anchor. (required) + :type anchor: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + + _params = locals() + + _all_params = [ + 'message', + 'anchor' + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method message_disassociate_anchor" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + if _params['message'] is not None: + _path_params['message'] = _params['message'] + + if _params['anchor'] is not None: + _path_params['anchor'] = _params['anchor'] + + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['text/plain']) # noqa: E501 + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = {} + + return self.api_client.call_api( + '/message/{message}/anchors/disassociate/{anchor}', 'POST', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) + + @validate_arguments + def message_disassociate_annotation(self, annotation : Annotated[StrictStr, Field(..., description="This is a specific annotation uuid.")], message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], **kwargs) -> None: # noqa: E501 + """/message/{message}/annotations/disassociate/{annotation} [POST] # noqa: E501 + + This will enable us to dissassociate a message from an annotation. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.message_disassociate_annotation(annotation, message, async_req=True) + >>> result = thread.get() + + :param annotation: This is a specific annotation uuid. (required) + :type annotation: str + :param message: This is the uuid of a message. (required) + :type message: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the message_disassociate_annotation_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.message_disassociate_annotation_with_http_info(annotation, message, **kwargs) # noqa: E501 + + @validate_arguments + def message_disassociate_annotation_with_http_info(self, annotation : Annotated[StrictStr, Field(..., description="This is a specific annotation uuid.")], message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], **kwargs) -> ApiResponse: # noqa: E501 + """/message/{message}/annotations/disassociate/{annotation} [POST] # noqa: E501 + + This will enable us to dissassociate a message from an annotation. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.message_disassociate_annotation_with_http_info(annotation, message, async_req=True) + >>> result = thread.get() + + :param annotation: This is a specific annotation uuid. (required) + :type annotation: str + :param message: This is the uuid of a message. (required) + :type message: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + + _params = locals() + + _all_params = [ + 'annotation', + 'message' + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method message_disassociate_annotation" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + if _params['annotation'] is not None: + _path_params['annotation'] = _params['annotation'] + + if _params['message'] is not None: + _path_params['message'] = _params['message'] + + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['text/plain']) # noqa: E501 + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = {} + + return self.api_client.call_api( + '/message/{message}/annotations/disassociate/{annotation}', 'POST', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) + + @validate_arguments + def message_disassociate_person(self, message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], person : Annotated[StrictStr, Field(..., description="This is a uuid that represents a person.")], **kwargs) -> None: # noqa: E501 + """/message/{message}/persons/disassociate/{person} [POST] # noqa: E501 + + This will enable us to disassociate a message from a person. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.message_disassociate_person(message, person, async_req=True) + >>> result = thread.get() + + :param message: This is the uuid of a message. (required) + :type message: str + :param person: This is a uuid that represents a person. (required) + :type person: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the message_disassociate_person_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.message_disassociate_person_with_http_info(message, person, **kwargs) # noqa: E501 + + @validate_arguments + def message_disassociate_person_with_http_info(self, message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], person : Annotated[StrictStr, Field(..., description="This is a uuid that represents a person.")], **kwargs) -> ApiResponse: # noqa: E501 + """/message/{message}/persons/disassociate/{person} [POST] # noqa: E501 + + This will enable us to disassociate a message from a person. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.message_disassociate_person_with_http_info(message, person, async_req=True) + >>> result = thread.get() + + :param message: This is the uuid of a message. (required) + :type message: str + :param person: This is a uuid that represents a person. (required) + :type person: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + + _params = locals() + + _all_params = [ + 'message', + 'person' + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method message_disassociate_person" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + if _params['message'] is not None: + _path_params['message'] = _params['message'] + + if _params['person'] is not None: + _path_params['person'] = _params['person'] + + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['text/plain']) # noqa: E501 + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = {} + + return self.api_client.call_api( + '/message/{message}/persons/disassociate/{person}', 'POST', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) + + @validate_arguments + def message_disassociate_website(self, message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], website : Annotated[StrictStr, Field(..., description="website id")], **kwargs) -> None: # noqa: E501 + """/message/{message}/websites/disassociate/{website} [POST] # noqa: E501 + + This will enable us to disassociate a message from a website. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.message_disassociate_website(message, website, async_req=True) + >>> result = thread.get() + + :param message: This is the uuid of a message. (required) + :type message: str + :param website: website id (required) + :type website: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the message_disassociate_website_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.message_disassociate_website_with_http_info(message, website, **kwargs) # noqa: E501 + + @validate_arguments + def message_disassociate_website_with_http_info(self, message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], website : Annotated[StrictStr, Field(..., description="website id")], **kwargs) -> ApiResponse: # noqa: E501 + """/message/{message}/websites/disassociate/{website} [POST] # noqa: E501 + + This will enable us to disassociate a message from a website. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.message_disassociate_website_with_http_info(message, website, async_req=True) + >>> result = thread.get() + + :param message: This is the uuid of a message. (required) + :type message: str + :param website: website id (required) + :type website: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + + _params = locals() + + _all_params = [ + 'message', + 'website' + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method message_disassociate_website" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + if _params['message'] is not None: + _path_params['message'] = _params['message'] + + if _params['website'] is not None: + _path_params['website'] = _params['website'] + + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['text/plain']) # noqa: E501 + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = {} + + return self.api_client.call_api( + '/message/{message}/websites/disassociate/{website}', 'POST', _path_params, _query_params, _header_params, diff --git a/_pieces_lib/pieces_os_client/api/conversation_messages_api.py b/_pieces_lib/pieces_os_client/api/conversation_messages_api.py index aa1947a..3e6270e 100644 --- a/_pieces_lib/pieces_os_client/api/conversation_messages_api.py +++ b/_pieces_lib/pieces_os_client/api/conversation_messages_api.py @@ -29,6 +29,7 @@ from Pieces._pieces_lib.pieces_os_client.models.search_input import SearchInput from Pieces._pieces_lib.pieces_os_client.models.searched_conversation_messages import SearchedConversationMessages from Pieces._pieces_lib.pieces_os_client.models.seeded_conversation_message import SeededConversationMessage +from Pieces._pieces_lib.pieces_os_client.models.streamed_identifiers import StreamedIdentifiers from Pieces._pieces_lib.pieces_os_client.api_client import ApiClient from Pieces._pieces_lib.pieces_os_client.api_response import ApiResponse @@ -50,6 +51,139 @@ def __init__(self, api_client=None) -> None: api_client = ApiClient.get_default() self.api_client = api_client + @validate_arguments + def conversation_messages_stream_identifiers(self, **kwargs) -> StreamedIdentifiers: # noqa: E501 + """/messages/stream/identifiers [WS] # noqa: E501 + + Provides a WebSocket connection that emits changes to your conversation messages identifiers (UUIDs). # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.conversation_messages_stream_identifiers(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: StreamedIdentifiers + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the conversation_messages_stream_identifiers_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.conversation_messages_stream_identifiers_with_http_info(**kwargs) # noqa: E501 + + @validate_arguments + def conversation_messages_stream_identifiers_with_http_info(self, **kwargs) -> ApiResponse: # noqa: E501 + """/messages/stream/identifiers [WS] # noqa: E501 + + Provides a WebSocket connection that emits changes to your conversation messages identifiers (UUIDs). # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.conversation_messages_stream_identifiers_with_http_info(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: tuple(StreamedIdentifiers, status_code(int), headers(HTTPHeaderDict)) + """ + + _params = locals() + + _all_params = [ + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method conversation_messages_stream_identifiers" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['application/json', 'text/plain']) # noqa: E501 + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = { + '200': "StreamedIdentifiers", + '500': "str", + } + + return self.api_client.call_api( + '/messages/stream/identifiers', 'GET', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) + @validate_arguments def messages_create_specific_message(self, transferables : Annotated[Optional[StrictBool], Field(description="This is a boolean that will decided if we are want to return the transferable data (default) or not(performance enhancement)")] = None, seeded_conversation_message : Optional[SeededConversationMessage] = None, **kwargs) -> ConversationMessage: # noqa: E501 """/messages/create [POST] # noqa: E501 diff --git a/_pieces_lib/pieces_os_client/api/format_api.py b/_pieces_lib/pieces_os_client/api/format_api.py index f6a44c3..0de5f1a 100644 --- a/_pieces_lib/pieces_os_client/api/format_api.py +++ b/_pieces_lib/pieces_os_client/api/format_api.py @@ -27,8 +27,6 @@ from Pieces._pieces_lib.pieces_os_client.models.analysis import Analysis from Pieces._pieces_lib.pieces_os_client.models.format import Format from Pieces._pieces_lib.pieces_os_client.models.format_reclassification import FormatReclassification -from Pieces._pieces_lib.pieces_os_client.models.seeded_tracked_format_event import SeededTrackedFormatEvent -from Pieces._pieces_lib.pieces_os_client.models.tracked_format_event import TrackedFormatEvent from Pieces._pieces_lib.pieces_os_client.api_client import ApiClient from Pieces._pieces_lib.pieces_os_client.api_response import ApiResponse @@ -649,150 +647,3 @@ def format_update_value_with_http_info(self, transferable : Annotated[Optional[S _request_timeout=_params.get('_request_timeout'), collection_formats=_collection_formats, _request_auth=_params.get('_request_auth')) - - @validate_arguments - def format_usage_event(self, seeded_tracked_format_event : Annotated[Optional[SeededTrackedFormatEvent], Field(description="This is a SeededTrackedFormatEvent, per tracked event:)")] = None, **kwargs) -> TrackedFormatEvent: # noqa: E501 - """/format/usage/event [POST] Scoped to Format # noqa: E501 - - This is an analytics endpoint that will enable us to know when a user has copied/downloaded/beamed/viewed a format. # noqa: E501 - This method makes a synchronous HTTP request by default. To make an - asynchronous HTTP request, please pass async_req=True - - >>> thread = api.format_usage_event(seeded_tracked_format_event, async_req=True) - >>> result = thread.get() - - :param seeded_tracked_format_event: This is a SeededTrackedFormatEvent, per tracked event:) - :type seeded_tracked_format_event: SeededTrackedFormatEvent - :param async_req: Whether to execute the request asynchronously. - :type async_req: bool, optional - :param _request_timeout: timeout setting for this request. - If one number provided, it will be total request - timeout. It can also be a pair (tuple) of - (connection, read) timeouts. - :return: Returns the result object. - If the method is called asynchronously, - returns the request thread. - :rtype: TrackedFormatEvent - """ - kwargs['_return_http_data_only'] = True - if '_preload_content' in kwargs: - message = "Error! Please call the format_usage_event_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 - raise ValueError(message) - return self.format_usage_event_with_http_info(seeded_tracked_format_event, **kwargs) # noqa: E501 - - @validate_arguments - def format_usage_event_with_http_info(self, seeded_tracked_format_event : Annotated[Optional[SeededTrackedFormatEvent], Field(description="This is a SeededTrackedFormatEvent, per tracked event:)")] = None, **kwargs) -> ApiResponse: # noqa: E501 - """/format/usage/event [POST] Scoped to Format # noqa: E501 - - This is an analytics endpoint that will enable us to know when a user has copied/downloaded/beamed/viewed a format. # noqa: E501 - This method makes a synchronous HTTP request by default. To make an - asynchronous HTTP request, please pass async_req=True - - >>> thread = api.format_usage_event_with_http_info(seeded_tracked_format_event, async_req=True) - >>> result = thread.get() - - :param seeded_tracked_format_event: This is a SeededTrackedFormatEvent, per tracked event:) - :type seeded_tracked_format_event: SeededTrackedFormatEvent - :param async_req: Whether to execute the request asynchronously. - :type async_req: bool, optional - :param _preload_content: if False, the ApiResponse.data will - be set to none and raw_data will store the - HTTP response body without reading/decoding. - Default is True. - :type _preload_content: bool, optional - :param _return_http_data_only: response data instead of ApiResponse - object with status code, headers, etc - :type _return_http_data_only: bool, optional - :param _request_timeout: timeout setting for this request. If one - number provided, it will be total request - timeout. It can also be a pair (tuple) of - (connection, read) timeouts. - :param _request_auth: set to override the auth_settings for an a single - request; this effectively ignores the authentication - in the spec for a single request. - :type _request_auth: dict, optional - :type _content_type: string, optional: force content-type for the request - :return: Returns the result object. - If the method is called asynchronously, - returns the request thread. - :rtype: tuple(TrackedFormatEvent, status_code(int), headers(HTTPHeaderDict)) - """ - - _params = locals() - - _all_params = [ - 'seeded_tracked_format_event' - ] - _all_params.extend( - [ - 'async_req', - '_return_http_data_only', - '_preload_content', - '_request_timeout', - '_request_auth', - '_content_type', - '_headers' - ] - ) - - # validate the arguments - for _key, _val in _params['kwargs'].items(): - if _key not in _all_params: - raise ApiTypeError( - "Got an unexpected keyword argument '%s'" - " to method format_usage_event" % _key - ) - _params[_key] = _val - del _params['kwargs'] - - _collection_formats = {} - - # process the path parameters - _path_params = {} - - # process the query parameters - _query_params = [] - # process the header parameters - _header_params = dict(_params.get('_headers', {})) - # process the form parameters - _form_params = [] - _files = {} - # process the body parameter - _body_params = None - if _params['seeded_tracked_format_event'] is not None: - _body_params = _params['seeded_tracked_format_event'] - - # set the HTTP header `Accept` - _header_params['Accept'] = self.api_client.select_header_accept( - ['application/json']) # noqa: E501 - - # set the HTTP header `Content-Type` - _content_types_list = _params.get('_content_type', - self.api_client.select_header_content_type( - ['application/json'])) - if _content_types_list: - _header_params['Content-Type'] = _content_types_list - - # authentication setting - _auth_settings = [] # noqa: E501 - - _response_types_map = { - '200': "TrackedFormatEvent", - } - - return self.api_client.call_api( - '/format/usage/event', 'POST', - _path_params, - _query_params, - _header_params, - body=_body_params, - post_params=_form_params, - files=_files, - response_types_map=_response_types_map, - auth_settings=_auth_settings, - async_req=_params.get('async_req'), - _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 - _preload_content=_params.get('_preload_content', True), - _request_timeout=_params.get('_request_timeout'), - collection_formats=_collection_formats, - _request_auth=_params.get('_request_auth')) diff --git a/_pieces_lib/pieces_os_client/api/formats_api.py b/_pieces_lib/pieces_os_client/api/formats_api.py index a02cb0a..842179e 100644 --- a/_pieces_lib/pieces_os_client/api/formats_api.py +++ b/_pieces_lib/pieces_os_client/api/formats_api.py @@ -26,6 +26,7 @@ from Pieces._pieces_lib.pieces_os_client.models.format import Format from Pieces._pieces_lib.pieces_os_client.models.formats import Formats +from Pieces._pieces_lib.pieces_os_client.models.streamed_identifiers import StreamedIdentifiers from Pieces._pieces_lib.pieces_os_client.api_client import ApiClient from Pieces._pieces_lib.pieces_os_client.api_response import ApiResponse @@ -334,3 +335,136 @@ def formats_specific_format_snapshot_with_http_info(self, format : Annotated[Str _request_timeout=_params.get('_request_timeout'), collection_formats=_collection_formats, _request_auth=_params.get('_request_auth')) + + @validate_arguments + def formats_stream_identifiers(self, **kwargs) -> StreamedIdentifiers: # noqa: E501 + """/formats/stream/identifiers [WS] # noqa: E501 + + Provides a WebSocket connection that emits changes to your format identifiers (UUIDs). # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.formats_stream_identifiers(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: StreamedIdentifiers + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the formats_stream_identifiers_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.formats_stream_identifiers_with_http_info(**kwargs) # noqa: E501 + + @validate_arguments + def formats_stream_identifiers_with_http_info(self, **kwargs) -> ApiResponse: # noqa: E501 + """/formats/stream/identifiers [WS] # noqa: E501 + + Provides a WebSocket connection that emits changes to your format identifiers (UUIDs). # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.formats_stream_identifiers_with_http_info(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: tuple(StreamedIdentifiers, status_code(int), headers(HTTPHeaderDict)) + """ + + _params = locals() + + _all_params = [ + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method formats_stream_identifiers" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['application/json', 'text/plain']) # noqa: E501 + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = { + '200': "StreamedIdentifiers", + '500': "str", + } + + return self.api_client.call_api( + '/formats/stream/identifiers', 'GET', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) diff --git a/_pieces_lib/pieces_os_client/api/hints_api.py b/_pieces_lib/pieces_os_client/api/hints_api.py index 64ae581..ac35634 100644 --- a/_pieces_lib/pieces_os_client/api/hints_api.py +++ b/_pieces_lib/pieces_os_client/api/hints_api.py @@ -29,6 +29,7 @@ from Pieces._pieces_lib.pieces_os_client.models.search_input import SearchInput from Pieces._pieces_lib.pieces_os_client.models.searched_hints import SearchedHints from Pieces._pieces_lib.pieces_os_client.models.seeded_hint import SeededHint +from Pieces._pieces_lib.pieces_os_client.models.streamed_identifiers import StreamedIdentifiers from Pieces._pieces_lib.pieces_os_client.api_client import ApiClient from Pieces._pieces_lib.pieces_os_client.api_response import ApiResponse @@ -469,6 +470,139 @@ def hints_snapshot_with_http_info(self, **kwargs) -> ApiResponse: # noqa: E501 collection_formats=_collection_formats, _request_auth=_params.get('_request_auth')) + @validate_arguments + def hints_stream_identifiers(self, **kwargs) -> StreamedIdentifiers: # noqa: E501 + """/hints/stream/identifiers [WS] # noqa: E501 + + Provides a WebSocket connection that emits changes to your hint identifiers (UUIDs). # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.hints_stream_identifiers(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: StreamedIdentifiers + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the hints_stream_identifiers_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.hints_stream_identifiers_with_http_info(**kwargs) # noqa: E501 + + @validate_arguments + def hints_stream_identifiers_with_http_info(self, **kwargs) -> ApiResponse: # noqa: E501 + """/hints/stream/identifiers [WS] # noqa: E501 + + Provides a WebSocket connection that emits changes to your hint identifiers (UUIDs). # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.hints_stream_identifiers_with_http_info(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: tuple(StreamedIdentifiers, status_code(int), headers(HTTPHeaderDict)) + """ + + _params = locals() + + _all_params = [ + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method hints_stream_identifiers" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['application/json', 'text/plain']) # noqa: E501 + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = { + '200': "StreamedIdentifiers", + '500': "str", + } + + return self.api_client.call_api( + '/hints/stream/identifiers', 'GET', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) + @validate_arguments def search_hints(self, transferables : Annotated[Optional[StrictBool], Field(description="This is a boolean that will decided if we are want to return the transferable data (default) or not(performance enhancement)")] = None, search_input : Optional[SearchInput] = None, **kwargs) -> SearchedHints: # noqa: E501 """/hints/search [POST] # noqa: E501 diff --git a/_pieces_lib/pieces_os_client/api/models_api.py b/_pieces_lib/pieces_os_client/api/models_api.py index 1b6b725..79588f7 100644 --- a/_pieces_lib/pieces_os_client/api/models_api.py +++ b/_pieces_lib/pieces_os_client/api/models_api.py @@ -29,6 +29,7 @@ from Pieces._pieces_lib.pieces_os_client.models.model_delete_cache_output import ModelDeleteCacheOutput from Pieces._pieces_lib.pieces_os_client.models.models import Models from Pieces._pieces_lib.pieces_os_client.models.seeded_model import SeededModel +from Pieces._pieces_lib.pieces_os_client.models.streamed_identifiers import StreamedIdentifiers from Pieces._pieces_lib.pieces_os_client.api_client import ApiClient from Pieces._pieces_lib.pieces_os_client.api_response import ApiResponse @@ -625,6 +626,139 @@ def models_snapshot_with_http_info(self, **kwargs) -> ApiResponse: # noqa: E501 collection_formats=_collection_formats, _request_auth=_params.get('_request_auth')) + @validate_arguments + def models_stream_identifiers(self, **kwargs) -> StreamedIdentifiers: # noqa: E501 + """/models/stream/identifiers [WS] # noqa: E501 + + Provides a WebSocket connection that emits changes to your model identifiers (UUIDs). # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.models_stream_identifiers(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: StreamedIdentifiers + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the models_stream_identifiers_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.models_stream_identifiers_with_http_info(**kwargs) # noqa: E501 + + @validate_arguments + def models_stream_identifiers_with_http_info(self, **kwargs) -> ApiResponse: # noqa: E501 + """/models/stream/identifiers [WS] # noqa: E501 + + Provides a WebSocket connection that emits changes to your model identifiers (UUIDs). # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.models_stream_identifiers_with_http_info(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: tuple(StreamedIdentifiers, status_code(int), headers(HTTPHeaderDict)) + """ + + _params = locals() + + _all_params = [ + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method models_stream_identifiers" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['application/json', 'text/plain']) # noqa: E501 + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = { + '200': "StreamedIdentifiers", + '500': "str", + } + + return self.api_client.call_api( + '/models/stream/identifiers', 'GET', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) + @validate_arguments def unload_models(self, **kwargs) -> None: # noqa: E501 """/models/unload [POST] # noqa: E501 diff --git a/_pieces_lib/pieces_os_client/api/person_api.py b/_pieces_lib/pieces_os_client/api/person_api.py index 2e17500..dc54de0 100644 --- a/_pieces_lib/pieces_os_client/api/person_api.py +++ b/_pieces_lib/pieces_os_client/api/person_api.py @@ -339,6 +339,152 @@ def person_associate_asset_with_http_info(self, person : Annotated[StrictStr, Fi collection_formats=_collection_formats, _request_auth=_params.get('_request_auth')) + @validate_arguments + def person_associate_message(self, person : Annotated[StrictStr, Field(..., description="This is a uuid that represents a person.")], message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], **kwargs) -> None: # noqa: E501 + """/person/{person}/messages/associate/{message} [POST] # noqa: E501 + + This will associate a person with a message. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.person_associate_message(person, message, async_req=True) + >>> result = thread.get() + + :param person: This is a uuid that represents a person. (required) + :type person: str + :param message: This is the uuid of a message. (required) + :type message: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the person_associate_message_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.person_associate_message_with_http_info(person, message, **kwargs) # noqa: E501 + + @validate_arguments + def person_associate_message_with_http_info(self, person : Annotated[StrictStr, Field(..., description="This is a uuid that represents a person.")], message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], **kwargs) -> ApiResponse: # noqa: E501 + """/person/{person}/messages/associate/{message} [POST] # noqa: E501 + + This will associate a person with a message. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.person_associate_message_with_http_info(person, message, async_req=True) + >>> result = thread.get() + + :param person: This is a uuid that represents a person. (required) + :type person: str + :param message: This is the uuid of a message. (required) + :type message: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + + _params = locals() + + _all_params = [ + 'person', + 'message' + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method person_associate_message" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + if _params['person'] is not None: + _path_params['person'] = _params['person'] + + if _params['message'] is not None: + _path_params['message'] = _params['message'] + + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['text/plain']) # noqa: E501 + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = {} + + return self.api_client.call_api( + '/person/{person}/messages/associate/{message}', 'POST', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) + @validate_arguments def person_associate_tag(self, person : Annotated[StrictStr, Field(..., description="This is a uuid that represents a person.")], tag : Annotated[StrictStr, Field(..., description="tag id")], **kwargs) -> None: # noqa: E501 """/person/{person}/tags/associate/{tag} [POST] # noqa: E501 @@ -1069,6 +1215,152 @@ def person_disassociate_asset_with_http_info(self, person : Annotated[StrictStr, collection_formats=_collection_formats, _request_auth=_params.get('_request_auth')) + @validate_arguments + def person_disassociate_message(self, person : Annotated[StrictStr, Field(..., description="This is a uuid that represents a person.")], message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], **kwargs) -> None: # noqa: E501 + """/person/{person}/messages/disassociate/{message} [POST] # noqa: E501 + + This will enable us to disassociate a person from a message. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.person_disassociate_message(person, message, async_req=True) + >>> result = thread.get() + + :param person: This is a uuid that represents a person. (required) + :type person: str + :param message: This is the uuid of a message. (required) + :type message: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the person_disassociate_message_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.person_disassociate_message_with_http_info(person, message, **kwargs) # noqa: E501 + + @validate_arguments + def person_disassociate_message_with_http_info(self, person : Annotated[StrictStr, Field(..., description="This is a uuid that represents a person.")], message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], **kwargs) -> ApiResponse: # noqa: E501 + """/person/{person}/messages/disassociate/{message} [POST] # noqa: E501 + + This will enable us to disassociate a person from a message. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.person_disassociate_message_with_http_info(person, message, async_req=True) + >>> result = thread.get() + + :param person: This is a uuid that represents a person. (required) + :type person: str + :param message: This is the uuid of a message. (required) + :type message: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + + _params = locals() + + _all_params = [ + 'person', + 'message' + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method person_disassociate_message" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + if _params['person'] is not None: + _path_params['person'] = _params['person'] + + if _params['message'] is not None: + _path_params['message'] = _params['message'] + + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['text/plain']) # noqa: E501 + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = {} + + return self.api_client.call_api( + '/person/{person}/messages/disassociate/{message}', 'POST', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) + @validate_arguments def person_disassociate_tag(self, person : Annotated[StrictStr, Field(..., description="This is a uuid that represents a person.")], tag : Annotated[StrictStr, Field(..., description="tag id")], **kwargs) -> None: # noqa: E501 """/person/{person}/tags/disassociate/{tag} [POST] # noqa: E501 diff --git a/_pieces_lib/pieces_os_client/api/persons_api.py b/_pieces_lib/pieces_os_client/api/persons_api.py index f4347b8..9b79b9b 100644 --- a/_pieces_lib/pieces_os_client/api/persons_api.py +++ b/_pieces_lib/pieces_os_client/api/persons_api.py @@ -29,6 +29,7 @@ from Pieces._pieces_lib.pieces_os_client.models.search_input import SearchInput from Pieces._pieces_lib.pieces_os_client.models.searched_persons import SearchedPersons from Pieces._pieces_lib.pieces_os_client.models.seeded_person import SeededPerson +from Pieces._pieces_lib.pieces_os_client.models.streamed_identifiers import StreamedIdentifiers from Pieces._pieces_lib.pieces_os_client.api_client import ApiClient from Pieces._pieces_lib.pieces_os_client.api_response import ApiResponse @@ -485,6 +486,139 @@ def persons_snapshot_with_http_info(self, transferables : Annotated[Optional[Str collection_formats=_collection_formats, _request_auth=_params.get('_request_auth')) + @validate_arguments + def persons_stream_identifiers(self, **kwargs) -> StreamedIdentifiers: # noqa: E501 + """/persons/stream/identifiers [WS] # noqa: E501 + + Provides a WebSocket connection that emits changes to your person identifiers (UUIDs). # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.persons_stream_identifiers(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: StreamedIdentifiers + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the persons_stream_identifiers_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.persons_stream_identifiers_with_http_info(**kwargs) # noqa: E501 + + @validate_arguments + def persons_stream_identifiers_with_http_info(self, **kwargs) -> ApiResponse: # noqa: E501 + """/persons/stream/identifiers [WS] # noqa: E501 + + Provides a WebSocket connection that emits changes to your person identifiers (UUIDs). # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.persons_stream_identifiers_with_http_info(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: tuple(StreamedIdentifiers, status_code(int), headers(HTTPHeaderDict)) + """ + + _params = locals() + + _all_params = [ + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method persons_stream_identifiers" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['application/json', 'text/plain']) # noqa: E501 + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = { + '200': "StreamedIdentifiers", + '500': "str", + } + + return self.api_client.call_api( + '/persons/stream/identifiers', 'GET', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) + @validate_arguments def search_persons(self, transferables : Annotated[Optional[StrictBool], Field(description="This is a boolean that will decided if we are want to return the transferable data (default) or not(performance enhancement)")] = None, search_input : Optional[SearchInput] = None, **kwargs) -> SearchedPersons: # noqa: E501 """/persons/search [POST] # noqa: E501 diff --git a/_pieces_lib/pieces_os_client/api/ranges_api.py b/_pieces_lib/pieces_os_client/api/ranges_api.py index 5445966..6dd99a5 100644 --- a/_pieces_lib/pieces_os_client/api/ranges_api.py +++ b/_pieces_lib/pieces_os_client/api/ranges_api.py @@ -27,6 +27,7 @@ from Pieces._pieces_lib.pieces_os_client.models.range import Range from Pieces._pieces_lib.pieces_os_client.models.ranges import Ranges from Pieces._pieces_lib.pieces_os_client.models.seeded_range import SeededRange +from Pieces._pieces_lib.pieces_os_client.models.streamed_identifiers import StreamedIdentifiers from Pieces._pieces_lib.pieces_os_client.api_client import ApiClient from Pieces._pieces_lib.pieces_os_client.api_response import ApiResponse @@ -466,3 +467,136 @@ def ranges_snapshot_with_http_info(self, **kwargs) -> ApiResponse: # noqa: E501 _request_timeout=_params.get('_request_timeout'), collection_formats=_collection_formats, _request_auth=_params.get('_request_auth')) + + @validate_arguments + def ranges_stream_identifiers(self, **kwargs) -> StreamedIdentifiers: # noqa: E501 + """/ranges/stream/identifiers [WS] # noqa: E501 + + Provides a WebSocket connection that emits changes to your range identifiers (UUIDs). # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.ranges_stream_identifiers(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: StreamedIdentifiers + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the ranges_stream_identifiers_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.ranges_stream_identifiers_with_http_info(**kwargs) # noqa: E501 + + @validate_arguments + def ranges_stream_identifiers_with_http_info(self, **kwargs) -> ApiResponse: # noqa: E501 + """/ranges/stream/identifiers [WS] # noqa: E501 + + Provides a WebSocket connection that emits changes to your range identifiers (UUIDs). # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.ranges_stream_identifiers_with_http_info(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: tuple(StreamedIdentifiers, status_code(int), headers(HTTPHeaderDict)) + """ + + _params = locals() + + _all_params = [ + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method ranges_stream_identifiers" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['application/json', 'text/plain']) # noqa: E501 + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = { + '200': "StreamedIdentifiers", + '500': "str", + } + + return self.api_client.call_api( + '/ranges/stream/identifiers', 'GET', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) diff --git a/_pieces_lib/pieces_os_client/api/sensitives_api.py b/_pieces_lib/pieces_os_client/api/sensitives_api.py index 24a3a12..3d2a7a7 100644 --- a/_pieces_lib/pieces_os_client/api/sensitives_api.py +++ b/_pieces_lib/pieces_os_client/api/sensitives_api.py @@ -29,6 +29,7 @@ from Pieces._pieces_lib.pieces_os_client.models.seeded_sensitive import SeededSensitive from Pieces._pieces_lib.pieces_os_client.models.sensitive import Sensitive from Pieces._pieces_lib.pieces_os_client.models.sensitives import Sensitives +from Pieces._pieces_lib.pieces_os_client.models.streamed_identifiers import StreamedIdentifiers from Pieces._pieces_lib.pieces_os_client.api_client import ApiClient from Pieces._pieces_lib.pieces_os_client.api_response import ApiResponse @@ -624,3 +625,136 @@ def sensitives_snapshot_with_http_info(self, **kwargs) -> ApiResponse: # noqa: _request_timeout=_params.get('_request_timeout'), collection_formats=_collection_formats, _request_auth=_params.get('_request_auth')) + + @validate_arguments + def sensitives_stream_identifiers(self, **kwargs) -> StreamedIdentifiers: # noqa: E501 + """/sensitives/stream/identifiers [WS] # noqa: E501 + + Provides a WebSocket connection that emits changes to your sensitive identifiers (UUIDs). # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.sensitives_stream_identifiers(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: StreamedIdentifiers + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the sensitives_stream_identifiers_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.sensitives_stream_identifiers_with_http_info(**kwargs) # noqa: E501 + + @validate_arguments + def sensitives_stream_identifiers_with_http_info(self, **kwargs) -> ApiResponse: # noqa: E501 + """/sensitives/stream/identifiers [WS] # noqa: E501 + + Provides a WebSocket connection that emits changes to your sensitive identifiers (UUIDs). # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.sensitives_stream_identifiers_with_http_info(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: tuple(StreamedIdentifiers, status_code(int), headers(HTTPHeaderDict)) + """ + + _params = locals() + + _all_params = [ + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method sensitives_stream_identifiers" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['application/json', 'text/plain']) # noqa: E501 + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = { + '200': "StreamedIdentifiers", + '500': "str", + } + + return self.api_client.call_api( + '/sensitives/stream/identifiers', 'GET', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) diff --git a/_pieces_lib/pieces_os_client/api/tags_api.py b/_pieces_lib/pieces_os_client/api/tags_api.py index 7edfdcc..e71e58a 100644 --- a/_pieces_lib/pieces_os_client/api/tags_api.py +++ b/_pieces_lib/pieces_os_client/api/tags_api.py @@ -29,6 +29,7 @@ from Pieces._pieces_lib.pieces_os_client.models.search_input import SearchInput from Pieces._pieces_lib.pieces_os_client.models.searched_tags import SearchedTags from Pieces._pieces_lib.pieces_os_client.models.seeded_tag import SeededTag +from Pieces._pieces_lib.pieces_os_client.models.streamed_identifiers import StreamedIdentifiers from Pieces._pieces_lib.pieces_os_client.models.tag import Tag from Pieces._pieces_lib.pieces_os_client.models.tags import Tags @@ -790,3 +791,136 @@ def tags_snapshot_with_http_info(self, transferables : Annotated[Optional[Strict _request_timeout=_params.get('_request_timeout'), collection_formats=_collection_formats, _request_auth=_params.get('_request_auth')) + + @validate_arguments + def tags_stream_identifiers(self, **kwargs) -> StreamedIdentifiers: # noqa: E501 + """/tags/stream/identifiers [WS] # noqa: E501 + + Provides a WebSocket connection that emits changes to your tag identifiers (UUIDs). # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.tags_stream_identifiers(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: StreamedIdentifiers + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the tags_stream_identifiers_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.tags_stream_identifiers_with_http_info(**kwargs) # noqa: E501 + + @validate_arguments + def tags_stream_identifiers_with_http_info(self, **kwargs) -> ApiResponse: # noqa: E501 + """/tags/stream/identifiers [WS] # noqa: E501 + + Provides a WebSocket connection that emits changes to your tag identifiers (UUIDs). # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.tags_stream_identifiers_with_http_info(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: tuple(StreamedIdentifiers, status_code(int), headers(HTTPHeaderDict)) + """ + + _params = locals() + + _all_params = [ + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method tags_stream_identifiers" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['application/json', 'text/plain']) # noqa: E501 + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = { + '200': "StreamedIdentifiers", + '500': "str", + } + + return self.api_client.call_api( + '/tags/stream/identifiers', 'GET', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) diff --git a/_pieces_lib/pieces_os_client/api/website_api.py b/_pieces_lib/pieces_os_client/api/website_api.py index 7846de4..7f1afcb 100644 --- a/_pieces_lib/pieces_os_client/api/website_api.py +++ b/_pieces_lib/pieces_os_client/api/website_api.py @@ -339,6 +339,152 @@ def website_associate_conversation_with_http_info(self, website : Annotated[Stri collection_formats=_collection_formats, _request_auth=_params.get('_request_auth')) + @validate_arguments + def website_associate_message(self, website : Annotated[StrictStr, Field(..., description="website id")], message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], **kwargs) -> None: # noqa: E501 + """/website/{website}/messages/associate/{message} [POST] # noqa: E501 + + This will associate a website with a message. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.website_associate_message(website, message, async_req=True) + >>> result = thread.get() + + :param website: website id (required) + :type website: str + :param message: This is the uuid of a message. (required) + :type message: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the website_associate_message_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.website_associate_message_with_http_info(website, message, **kwargs) # noqa: E501 + + @validate_arguments + def website_associate_message_with_http_info(self, website : Annotated[StrictStr, Field(..., description="website id")], message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], **kwargs) -> ApiResponse: # noqa: E501 + """/website/{website}/messages/associate/{message} [POST] # noqa: E501 + + This will associate a website with a message. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.website_associate_message_with_http_info(website, message, async_req=True) + >>> result = thread.get() + + :param website: website id (required) + :type website: str + :param message: This is the uuid of a message. (required) + :type message: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + + _params = locals() + + _all_params = [ + 'website', + 'message' + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method website_associate_message" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + if _params['website'] is not None: + _path_params['website'] = _params['website'] + + if _params['message'] is not None: + _path_params['message'] = _params['message'] + + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['text/plain']) # noqa: E501 + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = {} + + return self.api_client.call_api( + '/website/{website}/messages/associate/{message}', 'POST', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) + @validate_arguments def website_associate_person(self, website : Annotated[StrictStr, Field(..., description="website id")], person : Annotated[StrictStr, Field(..., description="This is a uuid that represents a person.")], **kwargs) -> None: # noqa: E501 """/website/{website}/persons/associate/{person} [POST] # noqa: E501 @@ -923,6 +1069,152 @@ def website_disassociate_conversation_with_http_info(self, website : Annotated[S collection_formats=_collection_formats, _request_auth=_params.get('_request_auth')) + @validate_arguments + def website_disassociate_message(self, website : Annotated[StrictStr, Field(..., description="website id")], message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], **kwargs) -> None: # noqa: E501 + """/website/{website}/messages/disassociate/{message} [POST] # noqa: E501 + + This will enable us to disassociate a website from a message. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.website_disassociate_message(website, message, async_req=True) + >>> result = thread.get() + + :param website: website id (required) + :type website: str + :param message: This is the uuid of a message. (required) + :type message: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the website_disassociate_message_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.website_disassociate_message_with_http_info(website, message, **kwargs) # noqa: E501 + + @validate_arguments + def website_disassociate_message_with_http_info(self, website : Annotated[StrictStr, Field(..., description="website id")], message : Annotated[StrictStr, Field(..., description="This is the uuid of a message.")], **kwargs) -> ApiResponse: # noqa: E501 + """/website/{website}/messages/disassociate/{message} [POST] # noqa: E501 + + This will enable us to disassociate a website from a message. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.website_disassociate_message_with_http_info(website, message, async_req=True) + >>> result = thread.get() + + :param website: website id (required) + :type website: str + :param message: This is the uuid of a message. (required) + :type message: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: None + """ + + _params = locals() + + _all_params = [ + 'website', + 'message' + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method website_disassociate_message" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + if _params['website'] is not None: + _path_params['website'] = _params['website'] + + if _params['message'] is not None: + _path_params['message'] = _params['message'] + + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['text/plain']) # noqa: E501 + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = {} + + return self.api_client.call_api( + '/website/{website}/messages/disassociate/{message}', 'POST', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) + @validate_arguments def website_disassociate_person(self, website : Annotated[StrictStr, Field(..., description="website id")], person : Annotated[StrictStr, Field(..., description="This is a uuid that represents a person.")], **kwargs) -> None: # noqa: E501 """/website/{website}/persons/disassociate/{person} [POST] # noqa: E501 diff --git a/_pieces_lib/pieces_os_client/api/websites_api.py b/_pieces_lib/pieces_os_client/api/websites_api.py index 9ac115f..2912285 100644 --- a/_pieces_lib/pieces_os_client/api/websites_api.py +++ b/_pieces_lib/pieces_os_client/api/websites_api.py @@ -29,6 +29,7 @@ from Pieces._pieces_lib.pieces_os_client.models.search_input import SearchInput from Pieces._pieces_lib.pieces_os_client.models.searched_websites import SearchedWebsites from Pieces._pieces_lib.pieces_os_client.models.seeded_website import SeededWebsite +from Pieces._pieces_lib.pieces_os_client.models.streamed_identifiers import StreamedIdentifiers from Pieces._pieces_lib.pieces_os_client.models.website import Website from Pieces._pieces_lib.pieces_os_client.models.websites import Websites @@ -790,3 +791,136 @@ def websites_snapshot_with_http_info(self, transferables : Annotated[Optional[St _request_timeout=_params.get('_request_timeout'), collection_formats=_collection_formats, _request_auth=_params.get('_request_auth')) + + @validate_arguments + def websites_stream_identifiers(self, **kwargs) -> StreamedIdentifiers: # noqa: E501 + """/websites/stream/identifiers [WS] # noqa: E501 + + Provides a WebSocket connection that emits changes to your website identifiers (UUIDs). # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.websites_stream_identifiers(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: StreamedIdentifiers + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the websites_stream_identifiers_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.websites_stream_identifiers_with_http_info(**kwargs) # noqa: E501 + + @validate_arguments + def websites_stream_identifiers_with_http_info(self, **kwargs) -> ApiResponse: # noqa: E501 + """/websites/stream/identifiers [WS] # noqa: E501 + + Provides a WebSocket connection that emits changes to your website identifiers (UUIDs). # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.websites_stream_identifiers_with_http_info(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: tuple(StreamedIdentifiers, status_code(int), headers(HTTPHeaderDict)) + """ + + _params = locals() + + _all_params = [ + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method websites_stream_identifiers" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['application/json', 'text/plain']) # noqa: E501 + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = { + '200': "StreamedIdentifiers", + '500': "str", + } + + return self.api_client.call_api( + '/websites/stream/identifiers', 'GET', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) diff --git a/_pieces_lib/pieces_os_client/api/well_known_api.py b/_pieces_lib/pieces_os_client/api/well_known_api.py index 8bb62e7..ade951b 100644 --- a/_pieces_lib/pieces_os_client/api/well_known_api.py +++ b/_pieces_lib/pieces_os_client/api/well_known_api.py @@ -172,11 +172,143 @@ def get_well_known_health_with_http_info(self, **kwargs) -> ApiResponse: # noqa collection_formats=_collection_formats, _request_auth=_params.get('_request_auth')) + @validate_arguments + def get_well_known_stream_health(self, **kwargs) -> str: # noqa: E501 + """/.well-known/stream/health [WS] # noqa: E501 + + This is a Streamed endpoint please use a WS connection to call this Endpoint. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.get_well_known_stream_health(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: str + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the get_well_known_stream_health_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.get_well_known_stream_health_with_http_info(**kwargs) # noqa: E501 + + @validate_arguments + def get_well_known_stream_health_with_http_info(self, **kwargs) -> ApiResponse: # noqa: E501 + """/.well-known/stream/health [WS] # noqa: E501 + + This is a Streamed endpoint please use a WS connection to call this Endpoint. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.get_well_known_stream_health_with_http_info(async_req=True) + >>> result = thread.get() + + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: tuple(str, status_code(int), headers(HTTPHeaderDict)) + """ + + _params = locals() + + _all_params = [ + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method get_well_known_stream_health" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + + # process the query parameters + _query_params = [] + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['text/plain']) # noqa: E501 + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = { + '200': "str", + '500': "str", + } + + return self.api_client.call_api( + '/.well-known/stream/health', 'GET', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) + @validate_arguments def get_well_known_version(self, **kwargs) -> str: # noqa: E501 """/.well-known/version [Get] # noqa: E501 - Retrieves the version of the server. It returns a string representing the current version. # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True @@ -204,7 +336,6 @@ def get_well_known_version(self, **kwargs) -> str: # noqa: E501 def get_well_known_version_with_http_info(self, **kwargs) -> ApiResponse: # noqa: E501 """/.well-known/version [Get] # noqa: E501 - Retrieves the version of the server. It returns a string representing the current version. # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True diff --git a/_pieces_lib/pieces_os_client/api_client.py b/_pieces_lib/pieces_os_client/api_client.py index 9dde6ed..845756f 100644 --- a/_pieces_lib/pieces_os_client/api_client.py +++ b/_pieces_lib/pieces_os_client/api_client.py @@ -77,7 +77,7 @@ def __init__(self, configuration=None, header_name=None, header_value=None, self.default_headers[header_name] = header_value self.cookie = cookie # Set default User-Agent. - self.user_agent = 'OpenAPI-Generator/2.7.0/python' + self.user_agent = 'OpenAPI-Generator/3.1.0/python' self.client_side_validation = configuration.client_side_validation def __enter__(self): diff --git a/_pieces_lib/pieces_os_client/configuration.py b/_pieces_lib/pieces_os_client/configuration.py index ca67bc9..1cae92b 100644 --- a/_pieces_lib/pieces_os_client/configuration.py +++ b/_pieces_lib/pieces_os_client/configuration.py @@ -412,7 +412,7 @@ def to_debug_report(self): "OS: {env}\n"\ "Python Version: {pyversion}\n"\ "Version of the API: 1.0\n"\ - "SDK Package Version: 2.7.0".\ + "SDK Package Version: 3.1.0".\ format(env=sys.platform, pyversion=sys.version) def get_host_settings(self): diff --git a/_pieces_lib/pieces_os_client/models/__init__.py b/_pieces_lib/pieces_os_client/models/__init__.py index 75c7570..dcb8e46 100644 --- a/_pieces_lib/pieces_os_client/models/__init__.py +++ b/_pieces_lib/pieces_os_client/models/__init__.py @@ -68,6 +68,7 @@ from Pieces._pieces_lib.pieces_os_client.models.backup_status_enum import BackupStatusEnum from Pieces._pieces_lib.pieces_os_client.models.backup_streamed_progress import BackupStreamedProgress from Pieces._pieces_lib.pieces_os_client.models.backups import Backups +from Pieces._pieces_lib.pieces_os_client.models.backups_streamed_progress import BackupsStreamedProgress from Pieces._pieces_lib.pieces_os_client.models.browser_selection import BrowserSelection from Pieces._pieces_lib.pieces_os_client.models.browser_tab import BrowserTab from Pieces._pieces_lib.pieces_os_client.models.browser_tab_value import BrowserTabValue @@ -142,6 +143,7 @@ from Pieces._pieces_lib.pieces_os_client.models.flattened_anchors import FlattenedAnchors from Pieces._pieces_lib.pieces_os_client.models.flattened_annotation import FlattenedAnnotation from Pieces._pieces_lib.pieces_os_client.models.flattened_annotations import FlattenedAnnotations +from Pieces._pieces_lib.pieces_os_client.models.flattened_application import FlattenedApplication from Pieces._pieces_lib.pieces_os_client.models.flattened_asset import FlattenedAsset from Pieces._pieces_lib.pieces_os_client.models.flattened_assets import FlattenedAssets from Pieces._pieces_lib.pieces_os_client.models.flattened_conversation import FlattenedConversation @@ -226,6 +228,7 @@ from Pieces._pieces_lib.pieces_os_client.models.mailgun_metadata import MailgunMetadata from Pieces._pieces_lib.pieces_os_client.models.mechanism_enum import MechanismEnum from Pieces._pieces_lib.pieces_os_client.models.model import Model +from Pieces._pieces_lib.pieces_os_client.models.model_capabilities import ModelCapabilities from Pieces._pieces_lib.pieces_os_client.models.model_delete_cache_input import ModelDeleteCacheInput from Pieces._pieces_lib.pieces_os_client.models.model_delete_cache_output import ModelDeleteCacheOutput from Pieces._pieces_lib.pieces_os_client.models.model_download_progress import ModelDownloadProgress @@ -323,6 +326,7 @@ from Pieces._pieces_lib.pieces_os_client.models.referenced_anchor import ReferencedAnchor from Pieces._pieces_lib.pieces_os_client.models.referenced_anchor_point import ReferencedAnchorPoint from Pieces._pieces_lib.pieces_os_client.models.referenced_annotation import ReferencedAnnotation +from Pieces._pieces_lib.pieces_os_client.models.referenced_application import ReferencedApplication from Pieces._pieces_lib.pieces_os_client.models.referenced_asset import ReferencedAsset from Pieces._pieces_lib.pieces_os_client.models.referenced_conversation import ReferencedConversation from Pieces._pieces_lib.pieces_os_client.models.referenced_conversation_message import ReferencedConversationMessage @@ -508,8 +512,6 @@ from Pieces._pieces_lib.pieces_os_client.models.textually_extracted_materials import TextuallyExtractedMaterials from Pieces._pieces_lib.pieces_os_client.models.theme import Theme from Pieces._pieces_lib.pieces_os_client.models.tokenized_pkce import TokenizedPKCE -from Pieces._pieces_lib.pieces_os_client.models.tracked_application_install import TrackedApplicationInstall -from Pieces._pieces_lib.pieces_os_client.models.tracked_application_update import TrackedApplicationUpdate from Pieces._pieces_lib.pieces_os_client.models.tracked_asset_event_creation_metadata import TrackedAssetEventCreationMetadata from Pieces._pieces_lib.pieces_os_client.models.tracked_asset_event_creation_metadata_clipboard import TrackedAssetEventCreationMetadataClipboard from Pieces._pieces_lib.pieces_os_client.models.tracked_asset_event_creation_metadata_file import TrackedAssetEventCreationMetadataFile @@ -523,15 +525,10 @@ from Pieces._pieces_lib.pieces_os_client.models.tracked_conversation_event_identifier_description_pairs import TrackedConversationEventIdentifierDescriptionPairs from Pieces._pieces_lib.pieces_os_client.models.tracked_conversation_event_metadata import TrackedConversationEventMetadata from Pieces._pieces_lib.pieces_os_client.models.tracked_conversation_event_rename_metadata import TrackedConversationEventRenameMetadata -from Pieces._pieces_lib.pieces_os_client.models.tracked_format import TrackedFormat -from Pieces._pieces_lib.pieces_os_client.models.tracked_format_event import TrackedFormatEvent from Pieces._pieces_lib.pieces_os_client.models.tracked_format_event_identifier_description_pairs import TrackedFormatEventIdentifierDescriptionPairs from Pieces._pieces_lib.pieces_os_client.models.tracked_format_event_metadata import TrackedFormatEventMetadata -from Pieces._pieces_lib.pieces_os_client.models.tracked_interaction_event import TrackedInteractionEvent -from Pieces._pieces_lib.pieces_os_client.models.tracked_keyboard_event import TrackedKeyboardEvent from Pieces._pieces_lib.pieces_os_client.models.tracked_session_event_identifier_description_pairs import TrackedSessionEventIdentifierDescriptionPairs from Pieces._pieces_lib.pieces_os_client.models.tracked_summary_totals import TrackedSummaryTotals -from Pieces._pieces_lib.pieces_os_client.models.tracked_user_profile import TrackedUserProfile from Pieces._pieces_lib.pieces_os_client.models.transferable_bytes import TransferableBytes from Pieces._pieces_lib.pieces_os_client.models.transferable_string import TransferableString from Pieces._pieces_lib.pieces_os_client.models.unchecked_os_server_update import UncheckedOSServerUpdate diff --git a/_pieces_lib/pieces_os_client/models/activity.py b/_pieces_lib/pieces_os_client/models/activity.py index 21ecf24..ac418ff 100644 --- a/_pieces_lib/pieces_os_client/models/activity.py +++ b/_pieces_lib/pieces_os_client/models/activity.py @@ -32,7 +32,7 @@ class Activity(BaseModel): """ - # noqa: E501 + consider a rename to Event? That being said if we go with event we need to think about a word to pre/post fix event because it is likely to be a reserved word. additional documentation: https://www.notion.so/getpieces/Activity-4da8de193733441f85f87b510235fb74 Notes: - user/asset/format are all optional, NOT required that one of these are present. - if mechanism == internal we will not display to the user. Thoughts around additional properties. - hmm dismissed array here, that is an array of strings, where the string is the userId that dismissed this notification? or we could potentially do it based on the os_ID. - # noqa: E501 """ var_schema: Optional[EmbeddedModelSchema] = Field(default=None, alias="schema") id: StrictStr = Field(...) diff --git a/_pieces_lib/pieces_os_client/models/anchor.py b/_pieces_lib/pieces_os_client/models/anchor.py index 3f09e6b..9528a59 100644 --- a/_pieces_lib/pieces_os_client/models/anchor.py +++ b/_pieces_lib/pieces_os_client/models/anchor.py @@ -26,6 +26,7 @@ from Pieces._pieces_lib.pieces_os_client.models.flattened_anchor_points import FlattenedAnchorPoints from Pieces._pieces_lib.pieces_os_client.models.flattened_annotations import FlattenedAnnotations from Pieces._pieces_lib.pieces_os_client.models.flattened_assets import FlattenedAssets +from Pieces._pieces_lib.pieces_os_client.models.flattened_conversation_messages import FlattenedConversationMessages from Pieces._pieces_lib.pieces_os_client.models.flattened_conversations import FlattenedConversations from Pieces._pieces_lib.pieces_os_client.models.flattened_persons import FlattenedPersons from Pieces._pieces_lib.pieces_os_client.models.flattened_workstream_summaries import FlattenedWorkstreamSummaries @@ -51,7 +52,8 @@ class Anchor(BaseModel): score: Optional[Score] = None summaries: Optional[FlattenedWorkstreamSummaries] = None persons: Optional[FlattenedPersons] = None - __properties = ["schema", "id", "name", "type", "watch", "points", "created", "updated", "deleted", "assets", "annotations", "conversations", "score", "summaries", "persons"] + messages: Optional[FlattenedConversationMessages] = None + __properties = ["schema", "id", "name", "type", "watch", "points", "created", "updated", "deleted", "assets", "annotations", "conversations", "score", "summaries", "persons", "messages"] class Config: """Pydantic configuration""" @@ -110,6 +112,9 @@ def to_dict(self): # override the default output from pydantic by calling `to_dict()` of persons if self.persons: _dict['persons'] = self.persons.to_dict() + # override the default output from pydantic by calling `to_dict()` of messages + if self.messages: + _dict['messages'] = self.messages.to_dict() return _dict @classmethod @@ -136,7 +141,8 @@ def from_dict(cls, obj: dict) -> Anchor: "conversations": FlattenedConversations.from_dict(obj.get("conversations")) if obj.get("conversations") is not None else None, "score": Score.from_dict(obj.get("score")) if obj.get("score") is not None else None, "summaries": FlattenedWorkstreamSummaries.from_dict(obj.get("summaries")) if obj.get("summaries") is not None else None, - "persons": FlattenedPersons.from_dict(obj.get("persons")) if obj.get("persons") is not None else None + "persons": FlattenedPersons.from_dict(obj.get("persons")) if obj.get("persons") is not None else None, + "messages": FlattenedConversationMessages.from_dict(obj.get("messages")) if obj.get("messages") is not None else None }) return _obj diff --git a/_pieces_lib/pieces_os_client/models/backups_streamed_progress.py b/_pieces_lib/pieces_os_client/models/backups_streamed_progress.py new file mode 100644 index 0000000..219d2b2 --- /dev/null +++ b/_pieces_lib/pieces_os_client/models/backups_streamed_progress.py @@ -0,0 +1,95 @@ +# coding: utf-8 + +""" + Pieces Isomorphic OpenAPI + + Endpoints for Assets, Formats, Users, Asset, Format, User. + + The version of the OpenAPI document: 1.0 + Contact: tsavo@pieces.app + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + + +from typing import List, Optional +from Pieces._pieces_lib.pydantic import BaseModel, Field, conlist +from Pieces._pieces_lib.pieces_os_client.models.backup_streamed_progress import BackupStreamedProgress +from Pieces._pieces_lib.pieces_os_client.models.embedded_model_schema import EmbeddedModelSchema + +class BackupsStreamedProgress(BaseModel): + """ + This is used in the backups plural stream to stream the changes to all the restorations and backups in progress. # noqa: E501 + """ + var_schema: Optional[EmbeddedModelSchema] = Field(default=None, alias="schema") + backups: Optional[conlist(BackupStreamedProgress)] = None + restorations: Optional[conlist(BackupStreamedProgress)] = None + __properties = ["schema", "backups", "restorations"] + + class Config: + """Pydantic configuration""" + allow_population_by_field_name = True + validate_assignment = True + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.dict(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> BackupsStreamedProgress: + """Create an instance of BackupsStreamedProgress from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self): + """Returns the dictionary representation of the model using alias""" + _dict = self.dict(by_alias=True, + exclude={ + }, + exclude_none=True) + # override the default output from pydantic by calling `to_dict()` of var_schema + if self.var_schema: + _dict['schema'] = self.var_schema.to_dict() + # override the default output from pydantic by calling `to_dict()` of each item in backups (list) + _items = [] + if self.backups: + for _item in self.backups: + if _item: + _items.append(_item.to_dict()) + _dict['backups'] = _items + # override the default output from pydantic by calling `to_dict()` of each item in restorations (list) + _items = [] + if self.restorations: + for _item in self.restorations: + if _item: + _items.append(_item.to_dict()) + _dict['restorations'] = _items + return _dict + + @classmethod + def from_dict(cls, obj: dict) -> BackupsStreamedProgress: + """Create an instance of BackupsStreamedProgress from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return BackupsStreamedProgress.parse_obj(obj) + + _obj = BackupsStreamedProgress.parse_obj({ + "var_schema": EmbeddedModelSchema.from_dict(obj.get("schema")) if obj.get("schema") is not None else None, + "backups": [BackupStreamedProgress.from_dict(_item) for _item in obj.get("backups")] if obj.get("backups") is not None else None, + "restorations": [BackupStreamedProgress.from_dict(_item) for _item in obj.get("restorations")] if obj.get("restorations") is not None else None + }) + return _obj + + diff --git a/_pieces_lib/pieces_os_client/models/checked_os_update.py b/_pieces_lib/pieces_os_client/models/checked_os_update.py new file mode 100644 index 0000000..fadef78 --- /dev/null +++ b/_pieces_lib/pieces_os_client/models/checked_os_update.py @@ -0,0 +1,108 @@ +# coding: utf-8 + +""" + Pieces Isomorphic OpenAPI + + Endpoints for Assets, Formats, Users, Asset, Format, User. + + The version of the OpenAPI document: 1.0 + Contact: tsavo@pieces.app + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from Pieces._pieces_lib.pydantic import BaseModel, Field, StrictFloat, StrictInt +from typing import Any, ClassVar, Dict, List, Optional, Union +from Pieces._pieces_lib.pieces_os_client.models.embedded_model_schema import EmbeddedModelSchema +from Pieces._pieces_lib.pieces_os_client.models.grouped_timestamp import GroupedTimestamp +from Pieces._pieces_lib.pieces_os_client.models.updating_status_enum import UpdatingStatusEnum +from typing import Optional, Set +from Pieces._pieces_lib.typing_extensions import Self + +class CheckedOSUpdate(BaseModel): + """ + This is the model for the progress of the current update of Pieces os. /os/update/check/stream && /os/update/check/ we will emit on a progress update updated: is an optional property that will let us know when the update was checked last. NOTE: it is reccommended to use the stream instead of pulling. NOTE: lets think about if we want to have a closing(as well as how we want to handle restarts) + """ # noqa: E501 + var_schema: Optional[EmbeddedModelSchema] = Field(default=None, alias="schema") + status: UpdatingStatusEnum + updated: Optional[GroupedTimestamp] = None + percentage: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="Optionally if the update is in progress you will recieve a download percent(from 0-100).") + __properties: ClassVar[List[str]] = ["schema", "status", "updated", "percentage"] + + model_config = { + "populate_by_name": True, + "validate_assignment": True, + "protected_namespaces": (), + } + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CheckedOSUpdate from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of var_schema + if self.var_schema: + _dict['schema'] = self.var_schema.to_dict() + # override the default output from pydantic by calling `to_dict()` of updated + if self.updated: + _dict['updated'] = self.updated.to_dict() + # set to None if percentage (nullable) is None + # and model_fields_set contains the field + if self.percentage is None and "percentage" in self.model_fields_set: + _dict['percentage'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CheckedOSUpdate from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "schema": EmbeddedModelSchema.from_dict(obj["schema"]) if obj.get("schema") is not None else None, + "status": obj.get("status"), + "updated": GroupedTimestamp.from_dict(obj["updated"]) if obj.get("updated") is not None else None, + "percentage": obj.get("percentage") + }) + return _obj + + diff --git a/_pieces_lib/pieces_os_client/models/conversation_message.py b/_pieces_lib/pieces_os_client/models/conversation_message.py index 26c5f00..d0e0b84 100644 --- a/_pieces_lib/pieces_os_client/models/conversation_message.py +++ b/_pieces_lib/pieces_os_client/models/conversation_message.py @@ -23,7 +23,10 @@ from Pieces._pieces_lib.pydantic import BaseModel, Field, StrictStr from Pieces._pieces_lib.pieces_os_client.models.conversation_message_sentiment_enum import ConversationMessageSentimentEnum from Pieces._pieces_lib.pieces_os_client.models.embedded_model_schema import EmbeddedModelSchema +from Pieces._pieces_lib.pieces_os_client.models.flattened_anchors import FlattenedAnchors from Pieces._pieces_lib.pieces_os_client.models.flattened_annotations import FlattenedAnnotations +from Pieces._pieces_lib.pieces_os_client.models.flattened_persons import FlattenedPersons +from Pieces._pieces_lib.pieces_os_client.models.flattened_websites import FlattenedWebsites from Pieces._pieces_lib.pieces_os_client.models.fragment_format import FragmentFormat from Pieces._pieces_lib.pieces_os_client.models.grouped_timestamp import GroupedTimestamp from Pieces._pieces_lib.pieces_os_client.models.model import Model @@ -47,7 +50,10 @@ class ConversationMessage(BaseModel): role: QGPTConversationMessageRoleEnum = Field(...) score: Optional[Score] = None annotations: Optional[FlattenedAnnotations] = None - __properties = ["schema", "id", "created", "updated", "deleted", "model", "fragment", "conversation", "sentiment", "role", "score", "annotations"] + websites: Optional[FlattenedWebsites] = None + persons: Optional[FlattenedPersons] = None + anchors: Optional[FlattenedAnchors] = None + __properties = ["schema", "id", "created", "updated", "deleted", "model", "fragment", "conversation", "sentiment", "role", "score", "annotations", "websites", "persons", "anchors"] class Config: """Pydantic configuration""" @@ -100,6 +106,15 @@ def to_dict(self): # override the default output from pydantic by calling `to_dict()` of annotations if self.annotations: _dict['annotations'] = self.annotations.to_dict() + # override the default output from pydantic by calling `to_dict()` of websites + if self.websites: + _dict['websites'] = self.websites.to_dict() + # override the default output from pydantic by calling `to_dict()` of persons + if self.persons: + _dict['persons'] = self.persons.to_dict() + # override the default output from pydantic by calling `to_dict()` of anchors + if self.anchors: + _dict['anchors'] = self.anchors.to_dict() return _dict @classmethod @@ -123,7 +138,10 @@ def from_dict(cls, obj: dict) -> ConversationMessage: "sentiment": obj.get("sentiment"), "role": obj.get("role"), "score": Score.from_dict(obj.get("score")) if obj.get("score") is not None else None, - "annotations": FlattenedAnnotations.from_dict(obj.get("annotations")) if obj.get("annotations") is not None else None + "annotations": FlattenedAnnotations.from_dict(obj.get("annotations")) if obj.get("annotations") is not None else None, + "websites": FlattenedWebsites.from_dict(obj.get("websites")) if obj.get("websites") is not None else None, + "persons": FlattenedPersons.from_dict(obj.get("persons")) if obj.get("persons") is not None else None, + "anchors": FlattenedAnchors.from_dict(obj.get("anchors")) if obj.get("anchors") is not None else None }) return _obj diff --git a/_pieces_lib/pieces_os_client/models/flattened_anchor.py b/_pieces_lib/pieces_os_client/models/flattened_anchor.py index 54ca6d4..d37f561 100644 --- a/_pieces_lib/pieces_os_client/models/flattened_anchor.py +++ b/_pieces_lib/pieces_os_client/models/flattened_anchor.py @@ -45,7 +45,8 @@ class FlattenedAnchor(BaseModel): score: Optional[Score] = None summaries: Optional[FlattenedWorkstreamSummaries] = None persons: Optional[FlattenedPersons] = None - __properties = ["schema", "id", "type", "watch", "points", "created", "updated", "deleted", "assets", "name", "annotations", "conversations", "score", "summaries", "persons"] + messages: Optional[FlattenedConversationMessages] = None + __properties = ["schema", "id", "type", "watch", "points", "created", "updated", "deleted", "assets", "name", "annotations", "conversations", "score", "summaries", "persons", "messages"] class Config: """Pydantic configuration""" @@ -104,6 +105,9 @@ def to_dict(self): # override the default output from pydantic by calling `to_dict()` of persons if self.persons: _dict['persons'] = self.persons.to_dict() + # override the default output from pydantic by calling `to_dict()` of messages + if self.messages: + _dict['messages'] = self.messages.to_dict() return _dict @classmethod @@ -130,13 +134,15 @@ def from_dict(cls, obj: dict) -> FlattenedAnchor: "conversations": FlattenedConversations.from_dict(obj.get("conversations")) if obj.get("conversations") is not None else None, "score": Score.from_dict(obj.get("score")) if obj.get("score") is not None else None, "summaries": FlattenedWorkstreamSummaries.from_dict(obj.get("summaries")) if obj.get("summaries") is not None else None, - "persons": FlattenedPersons.from_dict(obj.get("persons")) if obj.get("persons") is not None else None + "persons": FlattenedPersons.from_dict(obj.get("persons")) if obj.get("persons") is not None else None, + "messages": FlattenedConversationMessages.from_dict(obj.get("messages")) if obj.get("messages") is not None else None }) return _obj from Pieces._pieces_lib.pieces_os_client.models.flattened_anchor_points import FlattenedAnchorPoints from Pieces._pieces_lib.pieces_os_client.models.flattened_annotations import FlattenedAnnotations from Pieces._pieces_lib.pieces_os_client.models.flattened_assets import FlattenedAssets +from Pieces._pieces_lib.pieces_os_client.models.flattened_conversation_messages import FlattenedConversationMessages from Pieces._pieces_lib.pieces_os_client.models.flattened_conversations import FlattenedConversations from Pieces._pieces_lib.pieces_os_client.models.flattened_persons import FlattenedPersons from Pieces._pieces_lib.pieces_os_client.models.flattened_workstream_summaries import FlattenedWorkstreamSummaries diff --git a/_pieces_lib/pieces_os_client/models/flattened_application.py b/_pieces_lib/pieces_os_client/models/flattened_application.py new file mode 100644 index 0000000..710c287 --- /dev/null +++ b/_pieces_lib/pieces_os_client/models/flattened_application.py @@ -0,0 +1,99 @@ +# coding: utf-8 + +""" + Pieces Isomorphic OpenAPI + + Endpoints for Assets, Formats, Users, Asset, Format, User. + + The version of the OpenAPI document: 1.0 + Contact: tsavo@pieces.app + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + + +from typing import Optional +from Pieces._pieces_lib.pydantic import BaseModel, Field, StrictBool, StrictStr +from Pieces._pieces_lib.pieces_os_client.models.application_name_enum import ApplicationNameEnum +from Pieces._pieces_lib.pieces_os_client.models.capabilities_enum import CapabilitiesEnum +from Pieces._pieces_lib.pieces_os_client.models.embedded_model_schema import EmbeddedModelSchema +from Pieces._pieces_lib.pieces_os_client.models.mechanism_enum import MechanismEnum +from Pieces._pieces_lib.pieces_os_client.models.platform_enum import PlatformEnum +from Pieces._pieces_lib.pieces_os_client.models.privacy_enum import PrivacyEnum + +class FlattenedApplication(BaseModel): + """ + Flattened version of the Application(for now just the same properties) # noqa: E501 + """ + var_schema: Optional[EmbeddedModelSchema] = Field(default=None, alias="schema") + id: StrictStr = Field(default=..., description="The ID of the application at the device level") + name: ApplicationNameEnum = Field(...) + version: StrictStr = Field(default=..., description="This is the specific version number 0.0.0") + platform: PlatformEnum = Field(...) + onboarded: StrictBool = Field(...) + privacy: PrivacyEnum = Field(...) + capabilities: Optional[CapabilitiesEnum] = None + mechanism: Optional[MechanismEnum] = None + automatic_unload: Optional[StrictBool] = Field(default=None, alias="automaticUnload", description="This is a proper that will let us know if we will proactivity unload all of your machine learning models.by default this is false.") + __properties = ["schema", "id", "name", "version", "platform", "onboarded", "privacy", "capabilities", "mechanism", "automaticUnload"] + + class Config: + """Pydantic configuration""" + allow_population_by_field_name = True + validate_assignment = True + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.dict(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> FlattenedApplication: + """Create an instance of FlattenedApplication from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self): + """Returns the dictionary representation of the model using alias""" + _dict = self.dict(by_alias=True, + exclude={ + }, + exclude_none=True) + # override the default output from pydantic by calling `to_dict()` of var_schema + if self.var_schema: + _dict['schema'] = self.var_schema.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: dict) -> FlattenedApplication: + """Create an instance of FlattenedApplication from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return FlattenedApplication.parse_obj(obj) + + _obj = FlattenedApplication.parse_obj({ + "var_schema": EmbeddedModelSchema.from_dict(obj.get("schema")) if obj.get("schema") is not None else None, + "id": obj.get("id"), + "name": obj.get("name"), + "version": obj.get("version"), + "platform": obj.get("platform"), + "onboarded": obj.get("onboarded"), + "privacy": obj.get("privacy"), + "capabilities": obj.get("capabilities"), + "mechanism": obj.get("mechanism"), + "automatic_unload": obj.get("automaticUnload") + }) + return _obj + + diff --git a/_pieces_lib/pieces_os_client/models/flattened_conversation.py b/_pieces_lib/pieces_os_client/models/flattened_conversation.py index 1ecc0fd..8df63c5 100644 --- a/_pieces_lib/pieces_os_client/models/flattened_conversation.py +++ b/_pieces_lib/pieces_os_client/models/flattened_conversation.py @@ -31,7 +31,7 @@ class FlattenedConversation(BaseModel): """ - This is a flattend version of the Convsersation for DAG-Safety. This will hold together a conversation. Ie allthe message within a conversation. All the additional properties on here used on here like(anchors/assets) are used for context that will seed the conversation. model is a calculated property, and will be the model of the last message sent if applicable. summaries: on the top level here will simply be used to associate a conversation and a summary(this is not used for grounding), grounding.summaries will be used for this.(TODO) # noqa: E501 + This is a flattened version of the Convsersation for DAG-Safety. This will hold together a conversation. Ie all the message within a conversation. All the additional properties on here used on here like(anchors/assets) are used for context that will seed the conversation. model is a calculated property, and will be the model of the last message sent if applicable. summaries: on the top level here will simply be used to associate a conversation and a summary(this is not used for grounding), grounding.summaries will be used for this.(TODO) # noqa: E501 """ var_schema: Optional[EmbeddedModelSchema] = Field(default=None, alias="schema") id: StrictStr = Field(...) diff --git a/_pieces_lib/pieces_os_client/models/flattened_conversation_message.py b/_pieces_lib/pieces_os_client/models/flattened_conversation_message.py index d671722..57e2266 100644 --- a/_pieces_lib/pieces_os_client/models/flattened_conversation_message.py +++ b/_pieces_lib/pieces_os_client/models/flattened_conversation_message.py @@ -45,7 +45,10 @@ class FlattenedConversationMessage(BaseModel): role: QGPTConversationMessageRoleEnum = Field(...) score: Optional[Score] = None annotations: Optional[FlattenedAnnotations] = None - __properties = ["schema", "id", "created", "updated", "deleted", "model", "fragment", "conversation", "sentiment", "role", "score", "annotations"] + anchors: Optional[FlattenedAnchors] = None + persons: Optional[FlattenedPersons] = None + websites: Optional[FlattenedWebsites] = None + __properties = ["schema", "id", "created", "updated", "deleted", "model", "fragment", "conversation", "sentiment", "role", "score", "annotations", "anchors", "persons", "websites"] class Config: """Pydantic configuration""" @@ -98,6 +101,15 @@ def to_dict(self): # override the default output from pydantic by calling `to_dict()` of annotations if self.annotations: _dict['annotations'] = self.annotations.to_dict() + # override the default output from pydantic by calling `to_dict()` of anchors + if self.anchors: + _dict['anchors'] = self.anchors.to_dict() + # override the default output from pydantic by calling `to_dict()` of persons + if self.persons: + _dict['persons'] = self.persons.to_dict() + # override the default output from pydantic by calling `to_dict()` of websites + if self.websites: + _dict['websites'] = self.websites.to_dict() return _dict @classmethod @@ -121,11 +133,17 @@ def from_dict(cls, obj: dict) -> FlattenedConversationMessage: "sentiment": obj.get("sentiment"), "role": obj.get("role"), "score": Score.from_dict(obj.get("score")) if obj.get("score") is not None else None, - "annotations": FlattenedAnnotations.from_dict(obj.get("annotations")) if obj.get("annotations") is not None else None + "annotations": FlattenedAnnotations.from_dict(obj.get("annotations")) if obj.get("annotations") is not None else None, + "anchors": FlattenedAnchors.from_dict(obj.get("anchors")) if obj.get("anchors") is not None else None, + "persons": FlattenedPersons.from_dict(obj.get("persons")) if obj.get("persons") is not None else None, + "websites": FlattenedWebsites.from_dict(obj.get("websites")) if obj.get("websites") is not None else None }) return _obj +from Pieces._pieces_lib.pieces_os_client.models.flattened_anchors import FlattenedAnchors from Pieces._pieces_lib.pieces_os_client.models.flattened_annotations import FlattenedAnnotations +from Pieces._pieces_lib.pieces_os_client.models.flattened_persons import FlattenedPersons +from Pieces._pieces_lib.pieces_os_client.models.flattened_websites import FlattenedWebsites from Pieces._pieces_lib.pieces_os_client.models.referenced_conversation import ReferencedConversation FlattenedConversationMessage.update_forward_refs() diff --git a/_pieces_lib/pieces_os_client/models/flattened_person.py b/_pieces_lib/pieces_os_client/models/flattened_person.py index 29ba12a..c7faf70 100644 --- a/_pieces_lib/pieces_os_client/models/flattened_person.py +++ b/_pieces_lib/pieces_os_client/models/flattened_person.py @@ -49,7 +49,8 @@ class FlattenedPerson(BaseModel): score: Optional[Score] = None summaries: Optional[FlattenedWorkstreamSummaries] = None anchors: Optional[FlattenedAnchors] = None - __properties = ["schema", "id", "created", "updated", "deleted", "type", "assets", "mechanisms", "interactions", "access", "tags", "websites", "models", "annotations", "score", "summaries", "anchors"] + messages: Optional[FlattenedConversationMessages] = None + __properties = ["schema", "id", "created", "updated", "deleted", "type", "assets", "mechanisms", "interactions", "access", "tags", "websites", "models", "annotations", "score", "summaries", "anchors", "messages"] class Config: """Pydantic configuration""" @@ -125,6 +126,9 @@ def to_dict(self): # override the default output from pydantic by calling `to_dict()` of anchors if self.anchors: _dict['anchors'] = self.anchors.to_dict() + # override the default output from pydantic by calling `to_dict()` of messages + if self.messages: + _dict['messages'] = self.messages.to_dict() return _dict @classmethod @@ -163,13 +167,15 @@ def from_dict(cls, obj: dict) -> FlattenedPerson: "annotations": FlattenedAnnotations.from_dict(obj.get("annotations")) if obj.get("annotations") is not None else None, "score": Score.from_dict(obj.get("score")) if obj.get("score") is not None else None, "summaries": FlattenedWorkstreamSummaries.from_dict(obj.get("summaries")) if obj.get("summaries") is not None else None, - "anchors": FlattenedAnchors.from_dict(obj.get("anchors")) if obj.get("anchors") is not None else None + "anchors": FlattenedAnchors.from_dict(obj.get("anchors")) if obj.get("anchors") is not None else None, + "messages": FlattenedConversationMessages.from_dict(obj.get("messages")) if obj.get("messages") is not None else None }) return _obj from Pieces._pieces_lib.pieces_os_client.models.flattened_anchors import FlattenedAnchors from Pieces._pieces_lib.pieces_os_client.models.flattened_annotations import FlattenedAnnotations from Pieces._pieces_lib.pieces_os_client.models.flattened_assets import FlattenedAssets +from Pieces._pieces_lib.pieces_os_client.models.flattened_conversation_messages import FlattenedConversationMessages from Pieces._pieces_lib.pieces_os_client.models.flattened_tags import FlattenedTags from Pieces._pieces_lib.pieces_os_client.models.flattened_websites import FlattenedWebsites from Pieces._pieces_lib.pieces_os_client.models.flattened_workstream_summaries import FlattenedWorkstreamSummaries diff --git a/_pieces_lib/pieces_os_client/models/flattened_website.py b/_pieces_lib/pieces_os_client/models/flattened_website.py index 776d690..1fb9123 100644 --- a/_pieces_lib/pieces_os_client/models/flattened_website.py +++ b/_pieces_lib/pieces_os_client/models/flattened_website.py @@ -44,7 +44,8 @@ class FlattenedWebsite(BaseModel): conversations: Optional[FlattenedConversations] = None score: Optional[Score] = None summaries: Optional[FlattenedWorkstreamSummaries] = None - __properties = ["schema", "id", "assets", "name", "url", "created", "updated", "deleted", "mechanisms", "interactions", "persons", "conversations", "score", "summaries"] + messages: Optional[FlattenedConversationMessages] = None + __properties = ["schema", "id", "assets", "name", "url", "created", "updated", "deleted", "mechanisms", "interactions", "persons", "conversations", "score", "summaries", "messages"] class Config: """Pydantic configuration""" @@ -97,6 +98,9 @@ def to_dict(self): # override the default output from pydantic by calling `to_dict()` of summaries if self.summaries: _dict['summaries'] = self.summaries.to_dict() + # override the default output from pydantic by calling `to_dict()` of messages + if self.messages: + _dict['messages'] = self.messages.to_dict() return _dict @classmethod @@ -122,11 +126,13 @@ def from_dict(cls, obj: dict) -> FlattenedWebsite: "persons": FlattenedPersons.from_dict(obj.get("persons")) if obj.get("persons") is not None else None, "conversations": FlattenedConversations.from_dict(obj.get("conversations")) if obj.get("conversations") is not None else None, "score": Score.from_dict(obj.get("score")) if obj.get("score") is not None else None, - "summaries": FlattenedWorkstreamSummaries.from_dict(obj.get("summaries")) if obj.get("summaries") is not None else None + "summaries": FlattenedWorkstreamSummaries.from_dict(obj.get("summaries")) if obj.get("summaries") is not None else None, + "messages": FlattenedConversationMessages.from_dict(obj.get("messages")) if obj.get("messages") is not None else None }) return _obj from Pieces._pieces_lib.pieces_os_client.models.flattened_assets import FlattenedAssets +from Pieces._pieces_lib.pieces_os_client.models.flattened_conversation_messages import FlattenedConversationMessages from Pieces._pieces_lib.pieces_os_client.models.flattened_conversations import FlattenedConversations from Pieces._pieces_lib.pieces_os_client.models.flattened_persons import FlattenedPersons from Pieces._pieces_lib.pieces_os_client.models.flattened_workstream_summaries import FlattenedWorkstreamSummaries diff --git a/_pieces_lib/pieces_os_client/models/model.py b/_pieces_lib/pieces_os_client/models/model.py index 3c95745..35b414e 100644 --- a/_pieces_lib/pieces_os_client/models/model.py +++ b/_pieces_lib/pieces_os_client/models/model.py @@ -25,6 +25,7 @@ from Pieces._pieces_lib.pieces_os_client.models.embedded_model_schema import EmbeddedModelSchema from Pieces._pieces_lib.pieces_os_client.models.external_ml_provider_enum import ExternalMLProviderEnum from Pieces._pieces_lib.pieces_os_client.models.grouped_timestamp import GroupedTimestamp +from Pieces._pieces_lib.pieces_os_client.models.model_capabilities import ModelCapabilities from Pieces._pieces_lib.pieces_os_client.models.model_foundation_enum import ModelFoundationEnum from Pieces._pieces_lib.pieces_os_client.models.model_max_tokens import ModelMaxTokens from Pieces._pieces_lib.pieces_os_client.models.model_type_enum import ModelTypeEnum @@ -55,8 +56,9 @@ class Model(BaseModel): cpu: Optional[StrictBool] = Field(default=None, description="This is an optional bool that is optimized for CPU usage.") downloading: Optional[StrictBool] = Field(default=None, description="This is a calculated property, that will say if this is currently downloading.") max_tokens: Optional[ModelMaxTokens] = Field(default=None, alias="maxTokens") - custom: Optional[StrictBool] = None - __properties = ["schema", "id", "version", "created", "name", "description", "cloud", "type", "usage", "bytes", "ram", "quantization", "foundation", "downloaded", "loaded", "unique", "parameters", "provider", "cpu", "downloading", "maxTokens", "custom"] + custom: Optional[StrictBool] = Field(default=None, description="This will let us know if this is a custom, or fine tuned model imported by the user.") + capabilities: Optional[ModelCapabilities] = None + __properties = ["schema", "id", "version", "created", "name", "description", "cloud", "type", "usage", "bytes", "ram", "quantization", "foundation", "downloaded", "loaded", "unique", "parameters", "provider", "cpu", "downloading", "maxTokens", "custom", "capabilities"] class Config: """Pydantic configuration""" @@ -97,6 +99,9 @@ def to_dict(self): # override the default output from pydantic by calling `to_dict()` of max_tokens if self.max_tokens: _dict['maxTokens'] = self.max_tokens.to_dict() + # override the default output from pydantic by calling `to_dict()` of capabilities + if self.capabilities: + _dict['capabilities'] = self.capabilities.to_dict() # set to None if parameters (nullable) is None # and __fields_set__ contains the field if self.parameters is None and "parameters" in self.__fields_set__: @@ -135,7 +140,8 @@ def from_dict(cls, obj: dict) -> Model: "cpu": obj.get("cpu"), "downloading": obj.get("downloading"), "max_tokens": ModelMaxTokens.from_dict(obj.get("maxTokens")) if obj.get("maxTokens") is not None else None, - "custom": obj.get("custom") + "custom": obj.get("custom"), + "capabilities": ModelCapabilities.from_dict(obj.get("capabilities")) if obj.get("capabilities") is not None else None }) return _obj diff --git a/_pieces_lib/pieces_os_client/models/model_capabilities.py b/_pieces_lib/pieces_os_client/models/model_capabilities.py new file mode 100644 index 0000000..8105a01 --- /dev/null +++ b/_pieces_lib/pieces_os_client/models/model_capabilities.py @@ -0,0 +1,90 @@ +# coding: utf-8 + +""" + Pieces Isomorphic OpenAPI + + Endpoints for Assets, Formats, Users, Asset, Format, User. + + The version of the OpenAPI document: 1.0 + Contact: tsavo@pieces.app + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + + +from typing import Optional +from Pieces._pieces_lib.pydantic import BaseModel, Field, StrictBool +from Pieces._pieces_lib.pieces_os_client.models.embedded_model_schema import EmbeddedModelSchema + +class ModelCapabilities(BaseModel): + """ + This will let us know what capabilities the model is aloud to be used for. # noqa: E501 + """ + var_schema: Optional[EmbeddedModelSchema] = Field(default=None, alias="schema") + temporal: Optional[StrictBool] = Field(default=None, description="True if model is able to support live context and any other temporally powered RAG Capabilities i.e. \"What did I do yesterday?\"") + images: Optional[StrictBool] = Field(default=None, description="True if the model can leverage images and graphical material files in it's context window") + videos: Optional[StrictBool] = Field(default=None, description="True if the model can leverage videos files in it's context window") + documents: Optional[StrictBool] = Field(default=None, description="True if the model can leverage code/text/other files in it's context window") + codebases: Optional[StrictBool] = Field(default=None, description="True if the model can leverage entire code bases/snippetized code bases in its context window") + assets: Optional[StrictBool] = Field(default=None, description="True if the model can leverage saved assets & their metadata in its context window.") + websites: Optional[StrictBool] = Field(default=None, description="True if the model can leverage websites in its context window.") + __properties = ["schema", "temporal", "images", "videos", "documents", "codebases", "assets", "websites"] + + class Config: + """Pydantic configuration""" + allow_population_by_field_name = True + validate_assignment = True + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.dict(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> ModelCapabilities: + """Create an instance of ModelCapabilities from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self): + """Returns the dictionary representation of the model using alias""" + _dict = self.dict(by_alias=True, + exclude={ + }, + exclude_none=True) + # override the default output from pydantic by calling `to_dict()` of var_schema + if self.var_schema: + _dict['schema'] = self.var_schema.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: dict) -> ModelCapabilities: + """Create an instance of ModelCapabilities from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return ModelCapabilities.parse_obj(obj) + + _obj = ModelCapabilities.parse_obj({ + "var_schema": EmbeddedModelSchema.from_dict(obj.get("schema")) if obj.get("schema") is not None else None, + "temporal": obj.get("temporal"), + "images": obj.get("images"), + "videos": obj.get("videos"), + "documents": obj.get("documents"), + "codebases": obj.get("codebases"), + "assets": obj.get("assets"), + "websites": obj.get("websites") + }) + return _obj + + diff --git a/_pieces_lib/pieces_os_client/models/os_file_read_streamed_progress.py b/_pieces_lib/pieces_os_client/models/os_file_read_streamed_progress.py new file mode 100644 index 0000000..e56d33e --- /dev/null +++ b/_pieces_lib/pieces_os_client/models/os_file_read_streamed_progress.py @@ -0,0 +1,112 @@ +# coding: utf-8 + +""" + Pieces Isomorphic OpenAPI + + Endpoints for Assets, Formats, Users, Asset, Format, User. + + The version of the OpenAPI document: 1.0 + Contact: tsavo@pieces.app + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from Pieces._pieces_lib.pydantic import BaseModel, Field, StrictFloat, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional, Union +from Pieces._pieces_lib.pieces_os_client.models.embedded_model_schema import EmbeddedModelSchema +from Pieces._pieces_lib.pieces_os_client.models.model_download_progress_status_enum import ModelDownloadProgressStatusEnum +from Pieces._pieces_lib.pieces_os_client.models.transferable_bytes import TransferableBytes +from typing import Optional, Set +from Pieces._pieces_lib.typing_extensions import Self + +class OSFileReadStreamedProgress(BaseModel): + """ + This is a model to return stream progress for a file read. + """ # noqa: E501 + var_schema: Optional[EmbeddedModelSchema] = Field(default=None, alias="schema") + status: ModelDownloadProgressStatusEnum + percentage: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="Optionally if the download is in progress you will receive a download percent(from 0-100).") + path: StrictStr + id: StrictStr = Field(description="This is a generated UUID that represents this current stream in progress(can be used to cancel this in the future)") + bytes: Optional[TransferableBytes] = None + __properties: ClassVar[List[str]] = ["schema", "status", "percentage", "path", "id", "bytes"] + + model_config = { + "populate_by_name": True, + "validate_assignment": True, + "protected_namespaces": (), + } + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of OSFileReadStreamedProgress from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of var_schema + if self.var_schema: + _dict['schema'] = self.var_schema.to_dict() + # override the default output from pydantic by calling `to_dict()` of bytes + if self.bytes: + _dict['bytes'] = self.bytes.to_dict() + # set to None if percentage (nullable) is None + # and model_fields_set contains the field + if self.percentage is None and "percentage" in self.model_fields_set: + _dict['percentage'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of OSFileReadStreamedProgress from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "schema": EmbeddedModelSchema.from_dict(obj["schema"]) if obj.get("schema") is not None else None, + "status": obj.get("status"), + "percentage": obj.get("percentage"), + "path": obj.get("path"), + "id": obj.get("id"), + "bytes": TransferableBytes.from_dict(obj["bytes"]) if obj.get("bytes") is not None else None + }) + return _obj + + diff --git a/_pieces_lib/pieces_os_client/models/person.py b/_pieces_lib/pieces_os_client/models/person.py index 3254be5..6f437e4 100644 --- a/_pieces_lib/pieces_os_client/models/person.py +++ b/_pieces_lib/pieces_os_client/models/person.py @@ -25,6 +25,7 @@ from Pieces._pieces_lib.pieces_os_client.models.flattened_anchors import FlattenedAnchors from Pieces._pieces_lib.pieces_os_client.models.flattened_annotations import FlattenedAnnotations from Pieces._pieces_lib.pieces_os_client.models.flattened_assets import FlattenedAssets +from Pieces._pieces_lib.pieces_os_client.models.flattened_conversation_messages import FlattenedConversationMessages from Pieces._pieces_lib.pieces_os_client.models.flattened_tags import FlattenedTags from Pieces._pieces_lib.pieces_os_client.models.flattened_websites import FlattenedWebsites from Pieces._pieces_lib.pieces_os_client.models.flattened_workstream_summaries import FlattenedWorkstreamSummaries @@ -56,7 +57,8 @@ class Person(BaseModel): score: Optional[Score] = None summaries: Optional[FlattenedWorkstreamSummaries] = None anchors: Optional[FlattenedAnchors] = None - __properties = ["schema", "id", "created", "updated", "deleted", "type", "assets", "mechanisms", "interactions", "access", "tags", "websites", "models", "annotations", "score", "summaries", "anchors"] + messages: Optional[FlattenedConversationMessages] = None + __properties = ["schema", "id", "created", "updated", "deleted", "type", "assets", "mechanisms", "interactions", "access", "tags", "websites", "models", "annotations", "score", "summaries", "anchors", "messages"] class Config: """Pydantic configuration""" @@ -132,6 +134,9 @@ def to_dict(self): # override the default output from pydantic by calling `to_dict()` of anchors if self.anchors: _dict['anchors'] = self.anchors.to_dict() + # override the default output from pydantic by calling `to_dict()` of messages + if self.messages: + _dict['messages'] = self.messages.to_dict() return _dict @classmethod @@ -170,7 +175,8 @@ def from_dict(cls, obj: dict) -> Person: "annotations": FlattenedAnnotations.from_dict(obj.get("annotations")) if obj.get("annotations") is not None else None, "score": Score.from_dict(obj.get("score")) if obj.get("score") is not None else None, "summaries": FlattenedWorkstreamSummaries.from_dict(obj.get("summaries")) if obj.get("summaries") is not None else None, - "anchors": FlattenedAnchors.from_dict(obj.get("anchors")) if obj.get("anchors") is not None else None + "anchors": FlattenedAnchors.from_dict(obj.get("anchors")) if obj.get("anchors") is not None else None, + "messages": FlattenedConversationMessages.from_dict(obj.get("messages")) if obj.get("messages") is not None else None }) return _obj diff --git a/_pieces_lib/pieces_os_client/models/qgpt_relevance_input.py b/_pieces_lib/pieces_os_client/models/qgpt_relevance_input.py index 8fc65e6..9cbf4e9 100644 --- a/_pieces_lib/pieces_os_client/models/qgpt_relevance_input.py +++ b/_pieces_lib/pieces_os_client/models/qgpt_relevance_input.py @@ -22,6 +22,7 @@ from typing import List, Optional from Pieces._pieces_lib.pydantic import BaseModel, Field, StrictStr, conlist from Pieces._pieces_lib.pieces_os_client.models.embedded_model_schema import EmbeddedModelSchema +from Pieces._pieces_lib.pieces_os_client.models.flattened_anchors import FlattenedAnchors from Pieces._pieces_lib.pieces_os_client.models.flattened_assets import FlattenedAssets from Pieces._pieces_lib.pieces_os_client.models.flattened_conversation_messages import FlattenedConversationMessages from Pieces._pieces_lib.pieces_os_client.models.qgpt_relevance_input_options import QGPTRelevanceInputOptions @@ -42,7 +43,8 @@ class QGPTRelevanceInput(BaseModel): application: Optional[StrictStr] = Field(default=None, description="optional application id") model: Optional[StrictStr] = Field(default=None, description="optional model id") temporal: Optional[TemporalRangeGrounding] = None - __properties = ["schema", "query", "paths", "seeds", "assets", "messages", "options", "application", "model", "temporal"] + anchors: Optional[FlattenedAnchors] = None + __properties = ["schema", "query", "paths", "seeds", "assets", "messages", "options", "application", "model", "temporal", "anchors"] class Config: """Pydantic configuration""" @@ -86,6 +88,9 @@ def to_dict(self): # override the default output from pydantic by calling `to_dict()` of temporal if self.temporal: _dict['temporal'] = self.temporal.to_dict() + # override the default output from pydantic by calling `to_dict()` of anchors + if self.anchors: + _dict['anchors'] = self.anchors.to_dict() return _dict @classmethod @@ -107,7 +112,8 @@ def from_dict(cls, obj: dict) -> QGPTRelevanceInput: "options": QGPTRelevanceInputOptions.from_dict(obj.get("options")) if obj.get("options") is not None else None, "application": obj.get("application"), "model": obj.get("model"), - "temporal": TemporalRangeGrounding.from_dict(obj.get("temporal")) if obj.get("temporal") is not None else None + "temporal": TemporalRangeGrounding.from_dict(obj.get("temporal")) if obj.get("temporal") is not None else None, + "anchors": FlattenedAnchors.from_dict(obj.get("anchors")) if obj.get("anchors") is not None else None }) return _obj diff --git a/_pieces_lib/pieces_os_client/models/referenced_application.py b/_pieces_lib/pieces_os_client/models/referenced_application.py new file mode 100644 index 0000000..2a77832 --- /dev/null +++ b/_pieces_lib/pieces_os_client/models/referenced_application.py @@ -0,0 +1,84 @@ +# coding: utf-8 + +""" + Pieces Isomorphic OpenAPI + + Endpoints for Assets, Formats, Users, Asset, Format, User. + + The version of the OpenAPI document: 1.0 + Contact: tsavo@pieces.app + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + + +from typing import Optional +from Pieces._pieces_lib.pydantic import BaseModel, Field, StrictStr +from Pieces._pieces_lib.pieces_os_client.models.embedded_model_schema import EmbeddedModelSchema +from Pieces._pieces_lib.pieces_os_client.models.flattened_application import FlattenedApplication + +class ReferencedApplication(BaseModel): + """ + ReferencedApplication + """ + var_schema: Optional[EmbeddedModelSchema] = Field(default=None, alias="schema") + id: StrictStr = Field(...) + reference: Optional[FlattenedApplication] = None + __properties = ["schema", "id", "reference"] + + class Config: + """Pydantic configuration""" + allow_population_by_field_name = True + validate_assignment = True + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.dict(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> ReferencedApplication: + """Create an instance of ReferencedApplication from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self): + """Returns the dictionary representation of the model using alias""" + _dict = self.dict(by_alias=True, + exclude={ + }, + exclude_none=True) + # override the default output from pydantic by calling `to_dict()` of var_schema + if self.var_schema: + _dict['schema'] = self.var_schema.to_dict() + # override the default output from pydantic by calling `to_dict()` of reference + if self.reference: + _dict['reference'] = self.reference.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: dict) -> ReferencedApplication: + """Create an instance of ReferencedApplication from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return ReferencedApplication.parse_obj(obj) + + _obj = ReferencedApplication.parse_obj({ + "var_schema": EmbeddedModelSchema.from_dict(obj.get("schema")) if obj.get("schema") is not None else None, + "id": obj.get("id"), + "reference": FlattenedApplication.from_dict(obj.get("reference")) if obj.get("reference") is not None else None + }) + return _obj + + diff --git a/_pieces_lib/pieces_os_client/models/relevant_qgpt_seed.py b/_pieces_lib/pieces_os_client/models/relevant_qgpt_seed.py index fe55ba3..32bd6d3 100644 --- a/_pieces_lib/pieces_os_client/models/relevant_qgpt_seed.py +++ b/_pieces_lib/pieces_os_client/models/relevant_qgpt_seed.py @@ -22,6 +22,7 @@ from typing import Optional from Pieces._pieces_lib.pydantic import BaseModel, Field, StrictStr from Pieces._pieces_lib.pieces_os_client.models.embedded_model_schema import EmbeddedModelSchema +from Pieces._pieces_lib.pieces_os_client.models.referenced_anchor import ReferencedAnchor from Pieces._pieces_lib.pieces_os_client.models.referenced_asset import ReferencedAsset from Pieces._pieces_lib.pieces_os_client.models.seed import Seed @@ -33,8 +34,9 @@ class RelevantQGPTSeed(BaseModel): id: Optional[StrictStr] = None seed: Optional[Seed] = None path: Optional[StrictStr] = Field(default=None, description="This is an optional file path") + anchor: Optional[ReferencedAnchor] = None asset: Optional[ReferencedAsset] = None - __properties = ["schema", "id", "seed", "path", "asset"] + __properties = ["schema", "id", "seed", "path", "anchor", "asset"] class Config: """Pydantic configuration""" @@ -66,6 +68,9 @@ def to_dict(self): # override the default output from pydantic by calling `to_dict()` of seed if self.seed: _dict['seed'] = self.seed.to_dict() + # override the default output from pydantic by calling `to_dict()` of anchor + if self.anchor: + _dict['anchor'] = self.anchor.to_dict() # override the default output from pydantic by calling `to_dict()` of asset if self.asset: _dict['asset'] = self.asset.to_dict() @@ -85,6 +90,7 @@ def from_dict(cls, obj: dict) -> RelevantQGPTSeed: "id": obj.get("id"), "seed": Seed.from_dict(obj.get("seed")) if obj.get("seed") is not None else None, "path": obj.get("path"), + "anchor": ReferencedAnchor.from_dict(obj.get("anchor")) if obj.get("anchor") is not None else None, "asset": ReferencedAsset.from_dict(obj.get("asset")) if obj.get("asset") is not None else None }) return _obj diff --git a/_pieces_lib/pieces_os_client/models/seeded_model.py b/_pieces_lib/pieces_os_client/models/seeded_model.py index 42d09cb..09b2878 100644 --- a/_pieces_lib/pieces_os_client/models/seeded_model.py +++ b/_pieces_lib/pieces_os_client/models/seeded_model.py @@ -25,6 +25,7 @@ from Pieces._pieces_lib.pieces_os_client.models.embedded_model_schema import EmbeddedModelSchema from Pieces._pieces_lib.pieces_os_client.models.external_ml_provider_enum import ExternalMLProviderEnum from Pieces._pieces_lib.pieces_os_client.models.grouped_timestamp import GroupedTimestamp +from Pieces._pieces_lib.pieces_os_client.models.model_capabilities import ModelCapabilities from Pieces._pieces_lib.pieces_os_client.models.model_foundation_enum import ModelFoundationEnum from Pieces._pieces_lib.pieces_os_client.models.model_max_tokens import ModelMaxTokens from Pieces._pieces_lib.pieces_os_client.models.model_type_enum import ModelTypeEnum @@ -52,8 +53,9 @@ class SeededModel(BaseModel): provider: Optional[ExternalMLProviderEnum] = None cpu: Optional[StrictBool] = Field(default=None, description="This is an optional bool that is optimized for CPU usage.") max_tokens: Optional[ModelMaxTokens] = Field(default=None, alias="maxTokens") - custom: Optional[StrictBool] = Field(default=None, description="This is reserved to custommly registed models.") - __properties = ["schema", "version", "created", "name", "description", "cloud", "type", "usage", "bytes", "ram", "quantization", "foundation", "downloaded", "unique", "parameters", "provider", "cpu", "maxTokens", "custom"] + custom: Optional[StrictBool] = Field(default=None, description="This is reserved to customly register models.") + capabilities: Optional[ModelCapabilities] = None + __properties = ["schema", "version", "created", "name", "description", "cloud", "type", "usage", "bytes", "ram", "quantization", "foundation", "downloaded", "unique", "parameters", "provider", "cpu", "maxTokens", "custom", "capabilities"] class Config: """Pydantic configuration""" @@ -94,6 +96,9 @@ def to_dict(self): # override the default output from pydantic by calling `to_dict()` of max_tokens if self.max_tokens: _dict['maxTokens'] = self.max_tokens.to_dict() + # override the default output from pydantic by calling `to_dict()` of capabilities + if self.capabilities: + _dict['capabilities'] = self.capabilities.to_dict() # set to None if parameters (nullable) is None # and __fields_set__ contains the field if self.parameters is None and "parameters" in self.__fields_set__: @@ -129,7 +134,8 @@ def from_dict(cls, obj: dict) -> SeededModel: "provider": obj.get("provider"), "cpu": obj.get("cpu"), "max_tokens": ModelMaxTokens.from_dict(obj.get("maxTokens")) if obj.get("maxTokens") is not None else None, - "custom": obj.get("custom") + "custom": obj.get("custom"), + "capabilities": ModelCapabilities.from_dict(obj.get("capabilities")) if obj.get("capabilities") is not None else None }) return _obj diff --git a/_pieces_lib/pieces_os_client/models/seeded_tracked_application.py b/_pieces_lib/pieces_os_client/models/seeded_tracked_application.py index b9a72fb..049a44e 100644 --- a/_pieces_lib/pieces_os_client/models/seeded_tracked_application.py +++ b/_pieces_lib/pieces_os_client/models/seeded_tracked_application.py @@ -29,7 +29,7 @@ class SeededTrackedApplication(BaseModel): """ - A Model to describe what application a format/analytics event originated - Specifically NOT requiring an ID # noqa: E501 + # noqa: E501 """ var_schema: Optional[EmbeddedModelSchema] = Field(default=None, alias="schema") name: ApplicationNameEnum = Field(...) diff --git a/_pieces_lib/pieces_os_client/models/streamed_identifier.py b/_pieces_lib/pieces_os_client/models/streamed_identifier.py index 2d7c616..56d3dc1 100644 --- a/_pieces_lib/pieces_os_client/models/streamed_identifier.py +++ b/_pieces_lib/pieces_os_client/models/streamed_identifier.py @@ -21,17 +21,45 @@ from typing import Optional from Pieces._pieces_lib.pydantic import BaseModel, Field, StrictBool +from Pieces._pieces_lib.pieces_os_client.models.referenced_activity import ReferencedActivity +from Pieces._pieces_lib.pieces_os_client.models.referenced_anchor import ReferencedAnchor +from Pieces._pieces_lib.pieces_os_client.models.referenced_anchor_point import ReferencedAnchorPoint +from Pieces._pieces_lib.pieces_os_client.models.referenced_annotation import ReferencedAnnotation +from Pieces._pieces_lib.pieces_os_client.models.referenced_application import ReferencedApplication from Pieces._pieces_lib.pieces_os_client.models.referenced_asset import ReferencedAsset from Pieces._pieces_lib.pieces_os_client.models.referenced_conversation import ReferencedConversation +from Pieces._pieces_lib.pieces_os_client.models.referenced_conversation_message import ReferencedConversationMessage +from Pieces._pieces_lib.pieces_os_client.models.referenced_format import ReferencedFormat +from Pieces._pieces_lib.pieces_os_client.models.referenced_hint import ReferencedHint +from Pieces._pieces_lib.pieces_os_client.models.referenced_model import ReferencedModel +from Pieces._pieces_lib.pieces_os_client.models.referenced_person import ReferencedPerson +from Pieces._pieces_lib.pieces_os_client.models.referenced_range import ReferencedRange +from Pieces._pieces_lib.pieces_os_client.models.referenced_sensitive import ReferencedSensitive +from Pieces._pieces_lib.pieces_os_client.models.referenced_tag import ReferencedTag +from Pieces._pieces_lib.pieces_os_client.models.referenced_website import ReferencedWebsite class StreamedIdentifier(BaseModel): """ - This is currently only used within /assets/steam/identifiers && /conversations/steam/identifiers but can be used with other as well, if we want to expand this class. # noqa: E501 + This is currently only used within /assets/steam/identifiers && /conversations/steam/identifiers && annotations but can be used with other as well, if we want to expand this class. # noqa: E501 """ asset: Optional[ReferencedAsset] = None conversation: Optional[ReferencedConversation] = None + annotation: Optional[ReferencedAnnotation] = None + activity: Optional[ReferencedActivity] = None + anchor: Optional[ReferencedAnchor] = None + anchor_point: Optional[ReferencedAnchorPoint] = Field(default=None, alias="anchorPoint") + hint: Optional[ReferencedHint] = None + conversation_message: Optional[ReferencedConversationMessage] = Field(default=None, alias="conversationMessage") + format: Optional[ReferencedFormat] = None + person: Optional[ReferencedPerson] = None + range: Optional[ReferencedRange] = None + sensitive: Optional[ReferencedSensitive] = None + tag: Optional[ReferencedTag] = None + website: Optional[ReferencedWebsite] = None + application: Optional[ReferencedApplication] = None + model: Optional[ReferencedModel] = None deleted: Optional[StrictBool] = Field(default=None, description="This is a specific bool that will let us know if we deleted an Identifierfrom the db.") - __properties = ["asset", "conversation", "deleted"] + __properties = ["asset", "conversation", "annotation", "activity", "anchor", "anchorPoint", "hint", "conversationMessage", "format", "person", "range", "sensitive", "tag", "website", "application", "model", "deleted"] class Config: """Pydantic configuration""" @@ -63,6 +91,48 @@ def to_dict(self): # override the default output from pydantic by calling `to_dict()` of conversation if self.conversation: _dict['conversation'] = self.conversation.to_dict() + # override the default output from pydantic by calling `to_dict()` of annotation + if self.annotation: + _dict['annotation'] = self.annotation.to_dict() + # override the default output from pydantic by calling `to_dict()` of activity + if self.activity: + _dict['activity'] = self.activity.to_dict() + # override the default output from pydantic by calling `to_dict()` of anchor + if self.anchor: + _dict['anchor'] = self.anchor.to_dict() + # override the default output from pydantic by calling `to_dict()` of anchor_point + if self.anchor_point: + _dict['anchorPoint'] = self.anchor_point.to_dict() + # override the default output from pydantic by calling `to_dict()` of hint + if self.hint: + _dict['hint'] = self.hint.to_dict() + # override the default output from pydantic by calling `to_dict()` of conversation_message + if self.conversation_message: + _dict['conversationMessage'] = self.conversation_message.to_dict() + # override the default output from pydantic by calling `to_dict()` of format + if self.format: + _dict['format'] = self.format.to_dict() + # override the default output from pydantic by calling `to_dict()` of person + if self.person: + _dict['person'] = self.person.to_dict() + # override the default output from pydantic by calling `to_dict()` of range + if self.range: + _dict['range'] = self.range.to_dict() + # override the default output from pydantic by calling `to_dict()` of sensitive + if self.sensitive: + _dict['sensitive'] = self.sensitive.to_dict() + # override the default output from pydantic by calling `to_dict()` of tag + if self.tag: + _dict['tag'] = self.tag.to_dict() + # override the default output from pydantic by calling `to_dict()` of website + if self.website: + _dict['website'] = self.website.to_dict() + # override the default output from pydantic by calling `to_dict()` of application + if self.application: + _dict['application'] = self.application.to_dict() + # override the default output from pydantic by calling `to_dict()` of model + if self.model: + _dict['model'] = self.model.to_dict() return _dict @classmethod @@ -77,6 +147,20 @@ def from_dict(cls, obj: dict) -> StreamedIdentifier: _obj = StreamedIdentifier.parse_obj({ "asset": ReferencedAsset.from_dict(obj.get("asset")) if obj.get("asset") is not None else None, "conversation": ReferencedConversation.from_dict(obj.get("conversation")) if obj.get("conversation") is not None else None, + "annotation": ReferencedAnnotation.from_dict(obj.get("annotation")) if obj.get("annotation") is not None else None, + "activity": ReferencedActivity.from_dict(obj.get("activity")) if obj.get("activity") is not None else None, + "anchor": ReferencedAnchor.from_dict(obj.get("anchor")) if obj.get("anchor") is not None else None, + "anchor_point": ReferencedAnchorPoint.from_dict(obj.get("anchorPoint")) if obj.get("anchorPoint") is not None else None, + "hint": ReferencedHint.from_dict(obj.get("hint")) if obj.get("hint") is not None else None, + "conversation_message": ReferencedConversationMessage.from_dict(obj.get("conversationMessage")) if obj.get("conversationMessage") is not None else None, + "format": ReferencedFormat.from_dict(obj.get("format")) if obj.get("format") is not None else None, + "person": ReferencedPerson.from_dict(obj.get("person")) if obj.get("person") is not None else None, + "range": ReferencedRange.from_dict(obj.get("range")) if obj.get("range") is not None else None, + "sensitive": ReferencedSensitive.from_dict(obj.get("sensitive")) if obj.get("sensitive") is not None else None, + "tag": ReferencedTag.from_dict(obj.get("tag")) if obj.get("tag") is not None else None, + "website": ReferencedWebsite.from_dict(obj.get("website")) if obj.get("website") is not None else None, + "application": ReferencedApplication.from_dict(obj.get("application")) if obj.get("application") is not None else None, + "model": ReferencedModel.from_dict(obj.get("model")) if obj.get("model") is not None else None, "deleted": obj.get("deleted") }) return _obj diff --git a/_pieces_lib/pieces_os_client/models/timestamp_range.py b/_pieces_lib/pieces_os_client/models/timestamp_range.py new file mode 100644 index 0000000..f7c4570 --- /dev/null +++ b/_pieces_lib/pieces_os_client/models/timestamp_range.py @@ -0,0 +1,105 @@ +# coding: utf-8 + +""" + Pieces Isomorphic OpenAPI + + Endpoints for Assets, Formats, Users, Asset, Format, User. + + The version of the OpenAPI document: 1.0 + Contact: tsavo@pieces.app + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from Pieces._pieces_lib.pydantic import BaseModel, Field, StrictBool +from typing import Any, ClassVar, Dict, List, Optional +from Pieces._pieces_lib.pieces_os_client.models.embedded_model_schema import EmbeddedModelSchema +from Pieces._pieces_lib.pieces_os_client.models.grouped_timestamp import GroupedTimestamp +from typing import Optional, Set +from Pieces._pieces_lib.typing_extensions import Self + +class TimestampRange(BaseModel): + """ + if you want a range between you can use from && to. if you want anything before, use to and NO from. if you want anything after, use from and NO to. + """ # noqa: E501 + var_schema: Optional[EmbeddedModelSchema] = Field(default=None, alias="schema") + var_from: Optional[GroupedTimestamp] = Field(default=None, alias="from") + to: Optional[GroupedTimestamp] = None + between: Optional[StrictBool] = None + __properties: ClassVar[List[str]] = ["schema", "from", "to", "between"] + + model_config = { + "populate_by_name": True, + "validate_assignment": True, + "protected_namespaces": (), + } + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of TimestampRange from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of var_schema + if self.var_schema: + _dict['schema'] = self.var_schema.to_dict() + # override the default output from pydantic by calling `to_dict()` of var_from + if self.var_from: + _dict['from'] = self.var_from.to_dict() + # override the default output from pydantic by calling `to_dict()` of to + if self.to: + _dict['to'] = self.to.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of TimestampRange from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "schema": EmbeddedModelSchema.from_dict(obj["schema"]) if obj.get("schema") is not None else None, + "from": GroupedTimestamp.from_dict(obj["from"]) if obj.get("from") is not None else None, + "to": GroupedTimestamp.from_dict(obj["to"]) if obj.get("to") is not None else None, + "between": obj.get("between") + }) + return _obj + + diff --git a/_pieces_lib/pieces_os_client/models/tracked_application.py b/_pieces_lib/pieces_os_client/models/tracked_application.py new file mode 100644 index 0000000..5a9ca92 --- /dev/null +++ b/_pieces_lib/pieces_os_client/models/tracked_application.py @@ -0,0 +1,104 @@ +# coding: utf-8 + +""" + Pieces Isomorphic OpenAPI + + Endpoints for Assets, Formats, Users, Asset, Format, User. + + The version of the OpenAPI document: 1.0 + Contact: tsavo@pieces.app + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from Pieces._pieces_lib.pydantic import BaseModel, Field, StrictBool, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from Pieces._pieces_lib.pieces_os_client.models.application_name_enum import ApplicationNameEnum +from Pieces._pieces_lib.pieces_os_client.models.embedded_model_schema import EmbeddedModelSchema +from Pieces._pieces_lib.pieces_os_client.models.platform_enum import PlatformEnum +from typing import Optional, Set +from Pieces._pieces_lib.typing_extensions import Self + +class TrackedApplication(BaseModel): + """ + A Model to describe what application a format/analytics event originated. + """ # noqa: E501 + var_schema: Optional[EmbeddedModelSchema] = Field(default=None, alias="schema") + id: StrictStr = Field(description="The ID of the tracked application.") + name: ApplicationNameEnum + version: StrictStr = Field(description="This is the specific version number 0.0.0") + platform: PlatformEnum + automatic_unload: Optional[StrictBool] = Field(default=None, description="This is a proper that will let us know if we will proactivity unload all of your machine learning models.by default this is false.", alias="automaticUnload") + __properties: ClassVar[List[str]] = ["schema", "id", "name", "version", "platform", "automaticUnload"] + + model_config = { + "populate_by_name": True, + "validate_assignment": True, + "protected_namespaces": (), + } + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of TrackedApplication from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of var_schema + if self.var_schema: + _dict['schema'] = self.var_schema.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of TrackedApplication from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "schema": EmbeddedModelSchema.from_dict(obj["schema"]) if obj.get("schema") is not None else None, + "id": obj.get("id"), + "name": obj.get("name"), + "version": obj.get("version"), + "platform": obj.get("platform"), + "automaticUnload": obj.get("automaticUnload") + }) + return _obj + + diff --git a/_pieces_lib/pieces_os_client/models/tracked_application_install.py b/_pieces_lib/pieces_os_client/models/tracked_application_install.py index decb769..dfe0c33 100644 --- a/_pieces_lib/pieces_os_client/models/tracked_application_install.py +++ b/_pieces_lib/pieces_os_client/models/tracked_application_install.py @@ -18,46 +18,62 @@ import re # noqa: F401 import json - -from typing import Optional from Pieces._pieces_lib.pydantic import BaseModel, Field +from typing import Any, ClassVar, Dict, List, Optional from Pieces._pieces_lib.pieces_os_client.models.application import Application from Pieces._pieces_lib.pieces_os_client.models.embedded_model_schema import EmbeddedModelSchema from Pieces._pieces_lib.pieces_os_client.models.tracked_user_profile import TrackedUserProfile +from typing import Optional, Set +from Pieces._pieces_lib.typing_extensions import Self class TrackedApplicationInstall(BaseModel): """ - A model that allows for us to specifically track Application Installs & Related Data # noqa: E501 - """ + A model that allows for us to specifically track Application Installs & Related Data + """ # noqa: E501 var_schema: Optional[EmbeddedModelSchema] = Field(default=None, alias="schema") - application: Application = Field(...) + application: Application user: Optional[TrackedUserProfile] = None - __properties = ["schema", "application", "user"] + __properties: ClassVar[List[str]] = ["schema", "application", "user"] + + model_config = { + "populate_by_name": True, + "validate_assignment": True, + "protected_namespaces": (), + } - class Config: - """Pydantic configuration""" - allow_population_by_field_name = True - validate_assignment = True def to_str(self) -> str: """Returns the string representation of the model using alias""" - return pprint.pformat(self.dict(by_alias=True)) + return pprint.pformat(self.model_dump(by_alias=True)) def to_json(self) -> str: """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead return json.dumps(self.to_dict()) @classmethod - def from_json(cls, json_str: str) -> TrackedApplicationInstall: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TrackedApplicationInstall from a JSON string""" return cls.from_dict(json.loads(json_str)) - def to_dict(self): - """Returns the dictionary representation of the model using alias""" - _dict = self.dict(by_alias=True, - exclude={ - }, - exclude_none=True) + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) # override the default output from pydantic by calling `to_dict()` of var_schema if self.var_schema: _dict['schema'] = self.var_schema.to_dict() @@ -70,18 +86,18 @@ def to_dict(self): return _dict @classmethod - def from_dict(cls, obj: dict) -> TrackedApplicationInstall: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TrackedApplicationInstall from a dict""" if obj is None: return None if not isinstance(obj, dict): - return TrackedApplicationInstall.parse_obj(obj) + return cls.model_validate(obj) - _obj = TrackedApplicationInstall.parse_obj({ - "var_schema": EmbeddedModelSchema.from_dict(obj.get("schema")) if obj.get("schema") is not None else None, - "application": Application.from_dict(obj.get("application")) if obj.get("application") is not None else None, - "user": TrackedUserProfile.from_dict(obj.get("user")) if obj.get("user") is not None else None + _obj = cls.model_validate({ + "schema": EmbeddedModelSchema.from_dict(obj["schema"]) if obj.get("schema") is not None else None, + "application": Application.from_dict(obj["application"]) if obj.get("application") is not None else None, + "user": TrackedUserProfile.from_dict(obj["user"]) if obj.get("user") is not None else None }) return _obj diff --git a/_pieces_lib/pieces_os_client/models/tracked_application_update.py b/_pieces_lib/pieces_os_client/models/tracked_application_update.py index bc9c203..3b3bcee 100644 --- a/_pieces_lib/pieces_os_client/models/tracked_application_update.py +++ b/_pieces_lib/pieces_os_client/models/tracked_application_update.py @@ -18,47 +18,63 @@ import re # noqa: F401 import json - -from typing import Optional from Pieces._pieces_lib.pydantic import BaseModel, Field +from typing import Any, ClassVar, Dict, List, Optional from Pieces._pieces_lib.pieces_os_client.models.application import Application from Pieces._pieces_lib.pieces_os_client.models.embedded_model_schema import EmbeddedModelSchema from Pieces._pieces_lib.pieces_os_client.models.tracked_user_profile import TrackedUserProfile +from typing import Optional, Set +from Pieces._pieces_lib.typing_extensions import Self class TrackedApplicationUpdate(BaseModel): """ - This is a model used to track when an Application is Updated # noqa: E501 - """ + This is a model used to track when an Application is Updated + """ # noqa: E501 var_schema: Optional[EmbeddedModelSchema] = Field(default=None, alias="schema") - current: Application = Field(...) + current: Application previous: Optional[Application] = None user: Optional[TrackedUserProfile] = None - __properties = ["schema", "current", "previous", "user"] + __properties: ClassVar[List[str]] = ["schema", "current", "previous", "user"] + + model_config = { + "populate_by_name": True, + "validate_assignment": True, + "protected_namespaces": (), + } - class Config: - """Pydantic configuration""" - allow_population_by_field_name = True - validate_assignment = True def to_str(self) -> str: """Returns the string representation of the model using alias""" - return pprint.pformat(self.dict(by_alias=True)) + return pprint.pformat(self.model_dump(by_alias=True)) def to_json(self) -> str: """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead return json.dumps(self.to_dict()) @classmethod - def from_json(cls, json_str: str) -> TrackedApplicationUpdate: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TrackedApplicationUpdate from a JSON string""" return cls.from_dict(json.loads(json_str)) - def to_dict(self): - """Returns the dictionary representation of the model using alias""" - _dict = self.dict(by_alias=True, - exclude={ - }, - exclude_none=True) + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) # override the default output from pydantic by calling `to_dict()` of var_schema if self.var_schema: _dict['schema'] = self.var_schema.to_dict() @@ -74,19 +90,19 @@ def to_dict(self): return _dict @classmethod - def from_dict(cls, obj: dict) -> TrackedApplicationUpdate: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TrackedApplicationUpdate from a dict""" if obj is None: return None if not isinstance(obj, dict): - return TrackedApplicationUpdate.parse_obj(obj) + return cls.model_validate(obj) - _obj = TrackedApplicationUpdate.parse_obj({ - "var_schema": EmbeddedModelSchema.from_dict(obj.get("schema")) if obj.get("schema") is not None else None, - "current": Application.from_dict(obj.get("current")) if obj.get("current") is not None else None, - "previous": Application.from_dict(obj.get("previous")) if obj.get("previous") is not None else None, - "user": TrackedUserProfile.from_dict(obj.get("user")) if obj.get("user") is not None else None + _obj = cls.model_validate({ + "schema": EmbeddedModelSchema.from_dict(obj["schema"]) if obj.get("schema") is not None else None, + "current": Application.from_dict(obj["current"]) if obj.get("current") is not None else None, + "previous": Application.from_dict(obj["previous"]) if obj.get("previous") is not None else None, + "user": TrackedUserProfile.from_dict(obj["user"]) if obj.get("user") is not None else None }) return _obj diff --git a/_pieces_lib/pieces_os_client/models/tracked_format.py b/_pieces_lib/pieces_os_client/models/tracked_format.py index f20262c..0382201 100644 --- a/_pieces_lib/pieces_os_client/models/tracked_format.py +++ b/_pieces_lib/pieces_os_client/models/tracked_format.py @@ -18,50 +18,66 @@ import re # noqa: F401 import json - -from typing import Optional from Pieces._pieces_lib.pydantic import BaseModel, Field, StrictBool, StrictStr +from typing import Any, ClassVar, Dict, List, Optional from Pieces._pieces_lib.pieces_os_client.models.classification import Classification from Pieces._pieces_lib.pieces_os_client.models.embedded_model_schema import EmbeddedModelSchema from Pieces._pieces_lib.pieces_os_client.models.role import Role +from typing import Optional, Set +from Pieces._pieces_lib.typing_extensions import Self class TrackedFormat(BaseModel): """ - A minimal format to send to Mixpanel # noqa: E501 - """ + A minimal format to send to Mixpanel + """ # noqa: E501 var_schema: Optional[EmbeddedModelSchema] = Field(default=None, alias="schema") - id: StrictStr = Field(default=..., description="The UUID of the format") - classification: Classification = Field(...) - role: Role = Field(...) - asset: StrictStr = Field(default=..., description="The UUID of the asset associated") - fragment: StrictBool = Field(...) - file: StrictBool = Field(...) - __properties = ["schema", "id", "classification", "role", "asset", "fragment", "file"] - - class Config: - """Pydantic configuration""" - allow_population_by_field_name = True - validate_assignment = True + id: StrictStr = Field(description="The UUID of the format") + classification: Classification + role: Role + asset: StrictStr = Field(description="The UUID of the asset associated") + fragment: StrictBool + file: StrictBool + __properties: ClassVar[List[str]] = ["schema", "id", "classification", "role", "asset", "fragment", "file"] + + model_config = { + "populate_by_name": True, + "validate_assignment": True, + "protected_namespaces": (), + } + def to_str(self) -> str: """Returns the string representation of the model using alias""" - return pprint.pformat(self.dict(by_alias=True)) + return pprint.pformat(self.model_dump(by_alias=True)) def to_json(self) -> str: """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead return json.dumps(self.to_dict()) @classmethod - def from_json(cls, json_str: str) -> TrackedFormat: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TrackedFormat from a JSON string""" return cls.from_dict(json.loads(json_str)) - def to_dict(self): - """Returns the dictionary representation of the model using alias""" - _dict = self.dict(by_alias=True, - exclude={ - }, - exclude_none=True) + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) # override the default output from pydantic by calling `to_dict()` of var_schema if self.var_schema: _dict['schema'] = self.var_schema.to_dict() @@ -71,18 +87,18 @@ def to_dict(self): return _dict @classmethod - def from_dict(cls, obj: dict) -> TrackedFormat: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TrackedFormat from a dict""" if obj is None: return None if not isinstance(obj, dict): - return TrackedFormat.parse_obj(obj) + return cls.model_validate(obj) - _obj = TrackedFormat.parse_obj({ - "var_schema": EmbeddedModelSchema.from_dict(obj.get("schema")) if obj.get("schema") is not None else None, + _obj = cls.model_validate({ + "schema": EmbeddedModelSchema.from_dict(obj["schema"]) if obj.get("schema") is not None else None, "id": obj.get("id"), - "classification": Classification.from_dict(obj.get("classification")) if obj.get("classification") is not None else None, + "classification": Classification.from_dict(obj["classification"]) if obj.get("classification") is not None else None, "role": obj.get("role"), "asset": obj.get("asset"), "fragment": obj.get("fragment"), diff --git a/_pieces_lib/pieces_os_client/models/tracked_format_event.py b/_pieces_lib/pieces_os_client/models/tracked_format_event.py index 43fb090..24814ee 100644 --- a/_pieces_lib/pieces_os_client/models/tracked_format_event.py +++ b/_pieces_lib/pieces_os_client/models/tracked_format_event.py @@ -18,48 +18,64 @@ import re # noqa: F401 import json - -from typing import Optional from Pieces._pieces_lib.pydantic import BaseModel, Field +from typing import Any, ClassVar, Dict, List, Optional from Pieces._pieces_lib.pieces_os_client.models.embedded_model_schema import EmbeddedModelSchema from Pieces._pieces_lib.pieces_os_client.models.tracked_format import TrackedFormat from Pieces._pieces_lib.pieces_os_client.models.tracked_format_event_identifier_description_pairs import TrackedFormatEventIdentifierDescriptionPairs from Pieces._pieces_lib.pieces_os_client.models.tracked_format_event_metadata import TrackedFormatEventMetadata +from typing import Optional, Set +from Pieces._pieces_lib.typing_extensions import Self class TrackedFormatEvent(BaseModel): """ - This is a model that represents a generic event that we may want to track in relation to a format, for example beamed, copied, downloaded, and view. ** Note: This is the model that will get returned by our api, and is. Representative of a full TrackedFormat event. ** # noqa: E501 - """ + This is a model that represents a generic event that we may want to track in relation to a format, for example beamed, copied, downloaded, and view. ** Note: This is the model that will get returned by our api, and is. Representative of a full TrackedFormat event. ** + """ # noqa: E501 var_schema: Optional[EmbeddedModelSchema] = Field(default=None, alias="schema") - format: TrackedFormat = Field(default=..., alias=" format") - identifier_description_pair: TrackedFormatEventIdentifierDescriptionPairs = Field(...) + format: TrackedFormat = Field(alias=" format") + identifier_description_pair: TrackedFormatEventIdentifierDescriptionPairs metadata: Optional[TrackedFormatEventMetadata] = None - __properties = ["schema", " format", "identifier_description_pair", "metadata"] + __properties: ClassVar[List[str]] = ["schema", " format", "identifier_description_pair", "metadata"] + + model_config = { + "populate_by_name": True, + "validate_assignment": True, + "protected_namespaces": (), + } - class Config: - """Pydantic configuration""" - allow_population_by_field_name = True - validate_assignment = True def to_str(self) -> str: """Returns the string representation of the model using alias""" - return pprint.pformat(self.dict(by_alias=True)) + return pprint.pformat(self.model_dump(by_alias=True)) def to_json(self) -> str: """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead return json.dumps(self.to_dict()) @classmethod - def from_json(cls, json_str: str) -> TrackedFormatEvent: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TrackedFormatEvent from a JSON string""" return cls.from_dict(json.loads(json_str)) - def to_dict(self): - """Returns the dictionary representation of the model using alias""" - _dict = self.dict(by_alias=True, - exclude={ - }, - exclude_none=True) + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) # override the default output from pydantic by calling `to_dict()` of var_schema if self.var_schema: _dict['schema'] = self.var_schema.to_dict() @@ -75,19 +91,19 @@ def to_dict(self): return _dict @classmethod - def from_dict(cls, obj: dict) -> TrackedFormatEvent: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TrackedFormatEvent from a dict""" if obj is None: return None if not isinstance(obj, dict): - return TrackedFormatEvent.parse_obj(obj) + return cls.model_validate(obj) - _obj = TrackedFormatEvent.parse_obj({ - "var_schema": EmbeddedModelSchema.from_dict(obj.get("schema")) if obj.get("schema") is not None else None, - "format": TrackedFormat.from_dict(obj.get(" format")) if obj.get(" format") is not None else None, - "identifier_description_pair": TrackedFormatEventIdentifierDescriptionPairs.from_dict(obj.get("identifier_description_pair")) if obj.get("identifier_description_pair") is not None else None, - "metadata": TrackedFormatEventMetadata.from_dict(obj.get("metadata")) if obj.get("metadata") is not None else None + _obj = cls.model_validate({ + "schema": EmbeddedModelSchema.from_dict(obj["schema"]) if obj.get("schema") is not None else None, + " format": TrackedFormat.from_dict(obj[" format"]) if obj.get(" format") is not None else None, + "identifier_description_pair": TrackedFormatEventIdentifierDescriptionPairs.from_dict(obj["identifier_description_pair"]) if obj.get("identifier_description_pair") is not None else None, + "metadata": TrackedFormatEventMetadata.from_dict(obj["metadata"]) if obj.get("metadata") is not None else None }) return _obj diff --git a/_pieces_lib/pieces_os_client/models/tracked_interaction_event.py b/_pieces_lib/pieces_os_client/models/tracked_interaction_event.py index 91a1355..71eb230 100644 --- a/_pieces_lib/pieces_os_client/models/tracked_interaction_event.py +++ b/_pieces_lib/pieces_os_client/models/tracked_interaction_event.py @@ -18,60 +18,76 @@ import re # noqa: F401 import json - -from typing import Optional from Pieces._pieces_lib.pydantic import BaseModel, Field, StrictStr +from typing import Any, ClassVar, Dict, List, Optional from Pieces._pieces_lib.pieces_os_client.models.embedded_model_schema import EmbeddedModelSchema +from typing import Optional, Set +from Pieces._pieces_lib.typing_extensions import Self class TrackedInteractionEvent(BaseModel): """ - This is a model that will hold relavent information in relation to an interaction(ONLY CLICK/TAP) analytics event(usage). If you want to register an event that relates to an interaction with the key then register a Keyboard Event. # noqa: E501 - """ + This is a model that will hold relavent information in relation to an interaction(ONLY CLICK/TAP) analytics event(usage). If you want to register an event that relates to an interaction with the key then register a Keyboard Event. + """ # noqa: E501 var_schema: Optional[EmbeddedModelSchema] = Field(default=None, alias="schema") - description: StrictStr = Field(default=..., description="(optional) a description of this button that was clicked. or maybe what it did.") + description: StrictStr = Field(description="(optional) a description of this button that was clicked. or maybe what it did.") element: Optional[StrictStr] = Field(default=None, description="This is an identifer that will allow the developer to know what unique button/field was interacted with.") - __properties = ["schema", "description", "element"] + __properties: ClassVar[List[str]] = ["schema", "description", "element"] + + model_config = { + "populate_by_name": True, + "validate_assignment": True, + "protected_namespaces": (), + } - class Config: - """Pydantic configuration""" - allow_population_by_field_name = True - validate_assignment = True def to_str(self) -> str: """Returns the string representation of the model using alias""" - return pprint.pformat(self.dict(by_alias=True)) + return pprint.pformat(self.model_dump(by_alias=True)) def to_json(self) -> str: """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead return json.dumps(self.to_dict()) @classmethod - def from_json(cls, json_str: str) -> TrackedInteractionEvent: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TrackedInteractionEvent from a JSON string""" return cls.from_dict(json.loads(json_str)) - def to_dict(self): - """Returns the dictionary representation of the model using alias""" - _dict = self.dict(by_alias=True, - exclude={ - }, - exclude_none=True) + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) # override the default output from pydantic by calling `to_dict()` of var_schema if self.var_schema: _dict['schema'] = self.var_schema.to_dict() return _dict @classmethod - def from_dict(cls, obj: dict) -> TrackedInteractionEvent: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TrackedInteractionEvent from a dict""" if obj is None: return None if not isinstance(obj, dict): - return TrackedInteractionEvent.parse_obj(obj) + return cls.model_validate(obj) - _obj = TrackedInteractionEvent.parse_obj({ - "var_schema": EmbeddedModelSchema.from_dict(obj.get("schema")) if obj.get("schema") is not None else None, + _obj = cls.model_validate({ + "schema": EmbeddedModelSchema.from_dict(obj["schema"]) if obj.get("schema") is not None else None, "description": obj.get("description"), "element": obj.get("element") }) diff --git a/_pieces_lib/pieces_os_client/models/tracked_keyboard_event.py b/_pieces_lib/pieces_os_client/models/tracked_keyboard_event.py index 226a94b..98c948d 100644 --- a/_pieces_lib/pieces_os_client/models/tracked_keyboard_event.py +++ b/_pieces_lib/pieces_os_client/models/tracked_keyboard_event.py @@ -18,60 +18,76 @@ import re # noqa: F401 import json - -from typing import List, Optional -from Pieces._pieces_lib.pydantic import BaseModel, Field, StrictInt, StrictStr, conlist +from Pieces._pieces_lib.pydantic import BaseModel, Field, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional from Pieces._pieces_lib.pieces_os_client.models.embedded_model_schema import EmbeddedModelSchema +from typing import Optional, Set +from Pieces._pieces_lib.typing_extensions import Self class TrackedKeyboardEvent(BaseModel): """ - This is a model that will hold relavent information in relation to a keyboard(including shortcuts) analytics event (usage). # noqa: E501 - """ + This is a model that will hold relavent information in relation to a keyboard(including shortcuts) analytics event (usage). + """ # noqa: E501 var_schema: Optional[EmbeddedModelSchema] = Field(default=None, alias="schema") - description: StrictStr = Field(default=..., description="this is a description of the event, optional.") - shortcut: conlist(StrictInt) = Field(default=..., description="this is an array of of ascii values that represent numerics on your keyboard.") - __properties = ["schema", "description", "shortcut"] + description: StrictStr = Field(description="this is a description of the event, optional.") + shortcut: List[StrictInt] = Field(description="this is an array of of ascii values that represent numerics on your keyboard.") + __properties: ClassVar[List[str]] = ["schema", "description", "shortcut"] + + model_config = { + "populate_by_name": True, + "validate_assignment": True, + "protected_namespaces": (), + } - class Config: - """Pydantic configuration""" - allow_population_by_field_name = True - validate_assignment = True def to_str(self) -> str: """Returns the string representation of the model using alias""" - return pprint.pformat(self.dict(by_alias=True)) + return pprint.pformat(self.model_dump(by_alias=True)) def to_json(self) -> str: """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead return json.dumps(self.to_dict()) @classmethod - def from_json(cls, json_str: str) -> TrackedKeyboardEvent: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TrackedKeyboardEvent from a JSON string""" return cls.from_dict(json.loads(json_str)) - def to_dict(self): - """Returns the dictionary representation of the model using alias""" - _dict = self.dict(by_alias=True, - exclude={ - }, - exclude_none=True) + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) # override the default output from pydantic by calling `to_dict()` of var_schema if self.var_schema: _dict['schema'] = self.var_schema.to_dict() return _dict @classmethod - def from_dict(cls, obj: dict) -> TrackedKeyboardEvent: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TrackedKeyboardEvent from a dict""" if obj is None: return None if not isinstance(obj, dict): - return TrackedKeyboardEvent.parse_obj(obj) + return cls.model_validate(obj) - _obj = TrackedKeyboardEvent.parse_obj({ - "var_schema": EmbeddedModelSchema.from_dict(obj.get("schema")) if obj.get("schema") is not None else None, + _obj = cls.model_validate({ + "schema": EmbeddedModelSchema.from_dict(obj["schema"]) if obj.get("schema") is not None else None, "description": obj.get("description"), "shortcut": obj.get("shortcut") }) diff --git a/_pieces_lib/pieces_os_client/models/tracked_user_profile.py b/_pieces_lib/pieces_os_client/models/tracked_user_profile.py index b9af9a3..11a8bb6 100644 --- a/_pieces_lib/pieces_os_client/models/tracked_user_profile.py +++ b/_pieces_lib/pieces_os_client/models/tracked_user_profile.py @@ -18,69 +18,85 @@ import re # noqa: F401 import json - -from typing import Optional -from Pieces._pieces_lib.pydantic import BaseModel, Field, StrictStr, validator +from Pieces._pieces_lib.pydantic import BaseModel, Field, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional from Pieces._pieces_lib.pieces_os_client.models.embedded_model_schema import EmbeddedModelSchema +from typing import Optional, Set +from Pieces._pieces_lib.typing_extensions import Self class TrackedUserProfile(BaseModel): """ - A user that will be passed along with each analytics event # noqa: E501 - """ + A user that will be passed along with each analytics event + """ # noqa: E501 var_schema: Optional[EmbeddedModelSchema] = Field(default=None, alias="schema") - id: StrictStr = Field(default=..., description="The ID of the user that you are tracking.") - username: StrictStr = Field(default=..., description="This is a username that is attempted to be assigned but is \"Anonymous User\" by default") + id: StrictStr = Field(description="The ID of the user that you are tracking.") + username: StrictStr = Field(description="This is a username that is attempted to be assigned but is \"Anonymous User\" by default") email: Optional[StrictStr] = Field(default=None, description="The user's email if we have it.") - granularity: StrictStr = Field(default=..., description="At what level is this user being tracked.") - __properties = ["schema", "id", "username", "email", "granularity"] + granularity: StrictStr = Field(description="At what level is this user being tracked.") + __properties: ClassVar[List[str]] = ["schema", "id", "username", "email", "granularity"] - @validator('granularity') + @field_validator('granularity') def granularity_validate_enum(cls, value): """Validates the enum""" - if value not in ('DEVICE', 'ACCOUNT', 'ANONYMOUS'): + if value not in set(['DEVICE', 'ACCOUNT', 'ANONYMOUS']): raise ValueError("must be one of enum values ('DEVICE', 'ACCOUNT', 'ANONYMOUS')") return value - class Config: - """Pydantic configuration""" - allow_population_by_field_name = True - validate_assignment = True + model_config = { + "populate_by_name": True, + "validate_assignment": True, + "protected_namespaces": (), + } + def to_str(self) -> str: """Returns the string representation of the model using alias""" - return pprint.pformat(self.dict(by_alias=True)) + return pprint.pformat(self.model_dump(by_alias=True)) def to_json(self) -> str: """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead return json.dumps(self.to_dict()) @classmethod - def from_json(cls, json_str: str) -> TrackedUserProfile: + def from_json(cls, json_str: str) -> Optional[Self]: """Create an instance of TrackedUserProfile from a JSON string""" return cls.from_dict(json.loads(json_str)) - def to_dict(self): - """Returns the dictionary representation of the model using alias""" - _dict = self.dict(by_alias=True, - exclude={ - }, - exclude_none=True) + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) # override the default output from pydantic by calling `to_dict()` of var_schema if self.var_schema: _dict['schema'] = self.var_schema.to_dict() return _dict @classmethod - def from_dict(cls, obj: dict) -> TrackedUserProfile: + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: """Create an instance of TrackedUserProfile from a dict""" if obj is None: return None if not isinstance(obj, dict): - return TrackedUserProfile.parse_obj(obj) + return cls.model_validate(obj) - _obj = TrackedUserProfile.parse_obj({ - "var_schema": EmbeddedModelSchema.from_dict(obj.get("schema")) if obj.get("schema") is not None else None, + _obj = cls.model_validate({ + "schema": EmbeddedModelSchema.from_dict(obj["schema"]) if obj.get("schema") is not None else None, "id": obj.get("id"), "username": obj.get("username") if obj.get("username") is not None else 'unknown', "email": obj.get("email"), diff --git a/_pieces_lib/pieces_os_client/models/unchecked_os_update.py b/_pieces_lib/pieces_os_client/models/unchecked_os_update.py new file mode 100644 index 0000000..5316a47 --- /dev/null +++ b/_pieces_lib/pieces_os_client/models/unchecked_os_update.py @@ -0,0 +1,92 @@ +# coding: utf-8 + +""" + Pieces Isomorphic OpenAPI + + Endpoints for Assets, Formats, Users, Asset, Format, User. + + The version of the OpenAPI document: 1.0 + Contact: tsavo@pieces.app + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from Pieces._pieces_lib.pydantic import BaseModel, Field +from typing import Any, ClassVar, Dict, List, Optional +from Pieces._pieces_lib.pieces_os_client.models.embedded_model_schema import EmbeddedModelSchema +from typing import Optional, Set +from Pieces._pieces_lib.typing_extensions import Self + +class UncheckedOSUpdate(BaseModel): + """ + This is the input body for /os/update/check, just a placeholder for now. + """ # noqa: E501 + var_schema: Optional[EmbeddedModelSchema] = Field(default=None, alias="schema") + __properties: ClassVar[List[str]] = ["schema"] + + model_config = { + "populate_by_name": True, + "validate_assignment": True, + "protected_namespaces": (), + } + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of UncheckedOSUpdate from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of var_schema + if self.var_schema: + _dict['schema'] = self.var_schema.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of UncheckedOSUpdate from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "schema": EmbeddedModelSchema.from_dict(obj["schema"]) if obj.get("schema") is not None else None + }) + return _obj + + diff --git a/_pieces_lib/pieces_os_client/models/website.py b/_pieces_lib/pieces_os_client/models/website.py index 414860b..d4f2f57 100644 --- a/_pieces_lib/pieces_os_client/models/website.py +++ b/_pieces_lib/pieces_os_client/models/website.py @@ -23,6 +23,7 @@ from Pieces._pieces_lib.pydantic import BaseModel, Field, StrictInt, StrictStr from Pieces._pieces_lib.pieces_os_client.models.embedded_model_schema import EmbeddedModelSchema from Pieces._pieces_lib.pieces_os_client.models.flattened_assets import FlattenedAssets +from Pieces._pieces_lib.pieces_os_client.models.flattened_conversation_messages import FlattenedConversationMessages from Pieces._pieces_lib.pieces_os_client.models.flattened_conversations import FlattenedConversations from Pieces._pieces_lib.pieces_os_client.models.flattened_persons import FlattenedPersons from Pieces._pieces_lib.pieces_os_client.models.flattened_workstream_summaries import FlattenedWorkstreamSummaries @@ -48,7 +49,8 @@ class Website(BaseModel): conversations: Optional[FlattenedConversations] = None score: Optional[Score] = None summaries: Optional[FlattenedWorkstreamSummaries] = None - __properties = ["schema", "id", "assets", "url", "name", "created", "updated", "deleted", "mechanisms", "interactions", "persons", "conversations", "score", "summaries"] + messages: Optional[FlattenedConversationMessages] = None + __properties = ["schema", "id", "assets", "url", "name", "created", "updated", "deleted", "mechanisms", "interactions", "persons", "conversations", "score", "summaries", "messages"] class Config: """Pydantic configuration""" @@ -101,6 +103,9 @@ def to_dict(self): # override the default output from pydantic by calling `to_dict()` of summaries if self.summaries: _dict['summaries'] = self.summaries.to_dict() + # override the default output from pydantic by calling `to_dict()` of messages + if self.messages: + _dict['messages'] = self.messages.to_dict() return _dict @classmethod @@ -126,7 +131,8 @@ def from_dict(cls, obj: dict) -> Website: "persons": FlattenedPersons.from_dict(obj.get("persons")) if obj.get("persons") is not None else None, "conversations": FlattenedConversations.from_dict(obj.get("conversations")) if obj.get("conversations") is not None else None, "score": Score.from_dict(obj.get("score")) if obj.get("score") is not None else None, - "summaries": FlattenedWorkstreamSummaries.from_dict(obj.get("summaries")) if obj.get("summaries") is not None else None + "summaries": FlattenedWorkstreamSummaries.from_dict(obj.get("summaries")) if obj.get("summaries") is not None else None, + "messages": FlattenedConversationMessages.from_dict(obj.get("messages")) if obj.get("messages") is not None else None }) return _obj diff --git a/_pieces_lib/pieces_os_client/models/workstream_event_trigger.py b/_pieces_lib/pieces_os_client/models/workstream_event_trigger.py index 8405044..1f289fa 100644 --- a/_pieces_lib/pieces_os_client/models/workstream_event_trigger.py +++ b/_pieces_lib/pieces_os_client/models/workstream_event_trigger.py @@ -28,7 +28,7 @@ class WorkstreamEventTrigger(BaseModel): This is the specific event that represent the Shadow Activity ie the copy/paste ...xyz # noqa: E501 """ var_schema: Optional[EmbeddedModelSchema] = Field(default=None, alias="schema") - check_in: Optional[StrictBool] = Field(default=None, description="this is a sort of check-in event(ie when ever your application is in the foreground on there is an interaction)") + check_in: Optional[StrictBool] = Field(default=None, description="this is a sort of check-in event(ie when ever your application is in the forground on there is an interaction)") copy_field: Optional[StrictBool] = Field(default=None, alias="copy") paste: Optional[StrictBool] = None file_open: Optional[StrictBool] = None diff --git a/_pieces_lib/pieces_os_client/models/workstream_event_trigger_metadata.py b/_pieces_lib/pieces_os_client/models/workstream_event_trigger_metadata.py new file mode 100644 index 0000000..022e2aa --- /dev/null +++ b/_pieces_lib/pieces_os_client/models/workstream_event_trigger_metadata.py @@ -0,0 +1,92 @@ +# coding: utf-8 + +""" + Pieces Isomorphic OpenAPI + + Endpoints for Assets, Formats, Users, Asset, Format, User. + + The version of the OpenAPI document: 1.0 + Contact: tsavo@pieces.app + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from Pieces._pieces_lib.pydantic import BaseModel, Field +from typing import Any, ClassVar, Dict, List, Optional +from Pieces._pieces_lib.pieces_os_client.models.embedded_model_schema import EmbeddedModelSchema +from typing import Optional, Set +from Pieces._pieces_lib.typing_extensions import Self + +class WorkstreamEventTriggerMetadata(BaseModel): + """ + This is a free form data object that will enable additional data to be passed into SeededWorkstreamEvent, that corresponds to the event on the WorkstreamEvent. This is a WIP object. Need to think if we want to do something like raw:string (that is just a jsonObject) that is stringified, or if we add specific bits of data that we want. and specific fields for each event. + """ # noqa: E501 + var_schema: Optional[EmbeddedModelSchema] = Field(default=None, alias="schema") + __properties: ClassVar[List[str]] = ["schema"] + + model_config = { + "populate_by_name": True, + "validate_assignment": True, + "protected_namespaces": (), + } + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of WorkstreamEventTriggerMetadata from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of var_schema + if self.var_schema: + _dict['schema'] = self.var_schema.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of WorkstreamEventTriggerMetadata from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "schema": EmbeddedModelSchema.from_dict(obj["schema"]) if obj.get("schema") is not None else None + }) + return _obj + + diff --git a/_pieces_lib/pieces_os_client/wrapper/__init__.py b/_pieces_lib/pieces_os_client/wrapper/__init__.py new file mode 100644 index 0000000..419112e --- /dev/null +++ b/_pieces_lib/pieces_os_client/wrapper/__init__.py @@ -0,0 +1,3 @@ +from .client import PiecesClient + +__all__ = ["PiecesClient"] diff --git a/_pieces_lib/pieces_os_client/wrapper/basic_identifier/__init__.py b/_pieces_lib/pieces_os_client/wrapper/basic_identifier/__init__.py new file mode 100644 index 0000000..f1ebe12 --- /dev/null +++ b/_pieces_lib/pieces_os_client/wrapper/basic_identifier/__init__.py @@ -0,0 +1,6 @@ +from .asset import BasicAsset +from .chat import BasicChat +from .message import BasicMessage +from .user import BasicUser + +__all__ = ["BasicAsset","BasicChat","BasicMessage","BasicUser"] diff --git a/_pieces_lib/pieces_os_client/wrapper/basic_identifier/asset.py b/_pieces_lib/pieces_os_client/wrapper/basic_identifier/asset.py new file mode 100644 index 0000000..ac7cebf --- /dev/null +++ b/_pieces_lib/pieces_os_client/wrapper/basic_identifier/asset.py @@ -0,0 +1,337 @@ +from ..streamed_identifiers.assets_snapshot import AssetSnapshot +from Pieces._pieces_lib.pieces_os_client import ( + Asset, + AssetsApi, + AssetApi, + ClassificationSpecificEnum, + FormatApi, + ClassificationGenericEnum, + Annotation, + Format, + Classification, + Annotations, + SeededAsset, + Seed, + SeededFormat, + SeededFragment, + TransferableString, + FragmentMetadata, + AssetReclassification, + Linkify, + Shares +) + +from typing import Optional +from .basic import Basic +from .user import BasicUser + +# Friendly wrapper (to avoid interacting with the pieces_os_client sdks models) + +class BasicAsset(Basic): + """ + A wrapper class for managing assets. + """ + + @property + def asset(self) -> Asset: + asset = AssetSnapshot.identifiers_snapshot.get(self._id) + if not asset: + raise ValueError("Asset not found") + return asset + + @property + def id(self) -> str: + """ + :returns: The asset id + """ + return self.asset.id + + @property + def raw_content(self) -> Optional[str]: + """ + Get the raw content of the asset. + + Returns: + Optional[str]: The raw content if available, otherwise None. + + Raises: + ValueError: If unable to get OCR content for an image. + """ + if self.is_image: + content = self._get_ocr_content() + if content is None: + raise ValueError('Unable to get OCR content') + return content + else: + return ( + self.asset.original.reference.fragment.string.raw or + self.asset.preview.base.reference.fragment.string.raw or + '' + ) + + @raw_content.setter + def raw_content(self, content: str): + """ + Edit the original format of the asset. + + Args: + content: The new content to be set. + + Raises: + NotImplemented: If the asset is an image. + """ + format_api = AssetSnapshot.pieces_client.format_api + original = format_api.format_snapshot(self.asset.original.id, transferable=True) + if original.classification.generic == ClassificationGenericEnum.IMAGE: + raise NotImplemented("Can't edit an image yet") + + if original.fragment and original.fragment.string and original.fragment.string.raw: + original.fragment.string.raw = content + elif original.file and original.file.string and original.file.string.raw: + original.file.string.raw = content + format_api.format_update_value(transferable=False, format=original) + + @property + def is_image(self) -> bool: + """ + Check if the asset is an image. + + Returns: + bool: True if the asset is an image, otherwise False. + """ + return ( + self.asset.original.reference.classification.generic == + ClassificationGenericEnum.IMAGE + ) + + + @property + def classification(self) -> Optional[ClassificationSpecificEnum]: + """ + Get the specific classification of the asset (eg: py). + + :return: The classification value of the asset, or None if not available. + """ + if self.is_image: + ocr_format = self._get_ocr_format(self.asset) + if ocr_format: + return ocr_format.classification.specific + return self.asset.original.reference.classification.specific + + @classification.setter + def classification(self, classification): + """ + Reclassify the classification attribute. + + Args: + classification (str or ClassificationSpecificEnum): The new classification value. + + Raises: + ValueError: If the classification is not a string or ClassificationSpecificEnum. + NotImplementedError: If the asset is an image, reclassification is not supported. + """ + if isinstance(classification, str): + if classification not in ClassificationSpecificEnum: + raise ValueError(f"Classification must be one from {list(ClassificationSpecificEnum)}") + classification = ClassificationSpecificEnum(classification) + + if not isinstance(classification, ClassificationSpecificEnum): + raise ValueError("Invalid classification") + + if self.is_image: + raise NotImplementedError("Error in reclassify asset: Image reclassification is not supported") + + AssetSnapshot.pieces_client.asset_api.asset_reclassify( + asset_reclassification=AssetReclassification( + ext=classification, asset=self.asset), + transferables=False + ) + + + + @property + def name(self) -> str: + """ + Get the name of the asset. + + Returns: + Optional[str]: The name of the asset if available, otherwise "Unnamed snippet". + """ + return self.asset.name if self.asset.name else "Unnamed snippet" + + @name.setter + def name(self, name: str): + """ + Edit the name of the asset. + + :param name: The new name to be set for the asset. + """ + self.asset.name = name + self._edit_asset(self.asset) + + @property + def description(self): + """ + Retrieve the description of the asset. + + :return: The description text of the asset, or None if not available. + """ + annotations = self.annotations + if not annotations: + return + annotations = sorted(annotations, key=lambda x: x.updated.value, reverse=True) + d = None + for annotation in annotations: + if annotation.type == "DESCRIPTION": + d = annotation + + return d.text if d else None + + + @property + def annotations(self) -> Optional[Annotations]: + """ + Get all annotations of the asset. + + Returns: + Optional[Annotations]: The annotations if available, otherwise None. + """ + return getattr(self.asset.annotations,"iterable",None) + + + def delete(self): + """ + Delete the asset. + """ + AssetSnapshot.pieces_client.assets_api.assets_delete_asset(self.id) + + @classmethod + def create(cls,raw_content: str, metadata: Optional[FragmentMetadata] = None) -> str: + """ + Create a new asset. + + Args: + raw_content (str): The raw content of the asset. + metadata (Optional[FragmentMetadata]): The metadata of the asset. + + Returns: + str: The ID of the created asset. + """ + seed = cls._get_seed(raw_content,metadata) + + created_asset_id = AssetSnapshot.pieces_client.assets_api.assets_create_new_asset(transferables=False, seed=seed).id + return created_asset_id + + def share(self) -> Shares: + """ + Generates a shareable link for the given asset. + + Raises: + PermissionError: If the user is not logged in or is not connected to the cloud. + """ + return self._share(self.asset) + + + @classmethod + def share_raw_content(cls,raw_content:str) -> Shares: + """ + Generates a shareable link for the given user raw content. + Note: this will create an asset + + Args: + raw_content (str): The raw content of the asset that will be shared. + + Raises: + PermissionError: If the user is not logged in or is not connected to the cloud. + """ + return cls._share(seed = cls._get_seed(raw_content)) + + @staticmethod + def _get_seed(raw: str, metadata: Optional[FragmentMetadata] = None) -> Seed: + return Seed( + asset=SeededAsset( + application=AssetSnapshot.pieces_client.tracked_application, + format=SeededFormat( + fragment=SeededFragment( + string=TransferableString(raw=raw), + metadata=metadata + ) + ), + metadata=None + ), + type="SEEDED_ASSET" + ) + + def _get_ocr_content(self) -> Optional[str]: + """ + Get the OCR content of the asset. + + Returns: + Optional[str]: The OCR content if available, otherwise None. + """ + if not self.asset: + return + format = self._get_ocr_format(self.asset) + if format is None: + return + return self._ocr_from_format(format) + + @staticmethod + def _get_ocr_format(src: Asset) -> Optional[Format]: + """ + Get the OCR format of the asset. + + Args: + src (Asset): The asset object. + + Returns: + Optional[Format]: The OCR format if available, otherwise None. + """ + image_id = src.original.reference.analysis.image.ocr.raw.id if src.original and src.original.reference and src.original.reference.analysis and src.original.reference.analysis.image and src.original.reference.analysis.image.ocr and src.original.reference.analysis.image.ocr.raw and src.original.reference.analysis.image.ocr.raw.id else None + if image_id is None: + return None + return next((element for element in src.formats.iterable if element.id == image_id), None) + + @staticmethod + def _ocr_from_format(src: Optional[Format]) -> Optional[str]: + """ + Extract OCR content from the format. + + Args: + src (Optional[Format]): The format object. + + Returns: + Optional[str]: The OCR content if available, otherwise None. + """ + if src is None: + return None + return bytes(src.file.bytes.raw).decode('utf-8') + + @staticmethod + def _edit_asset(asset): + AssetSnapshot.pieces_client.asset_api.asset_update(False,asset) + + @staticmethod + def _share(asset=None,seed=None): + """ + You need to either give the seed or the asset_id + """ + if asset: + kwargs = {"asset" : asset} + else: + kwargs = {"seed" : seed} + + user = BasicUser.user_profile + + if not user: + raise PermissionError("You need to be logged in to generate a shareable link") + + if not user.allocation: + raise PermissionError("You need to connect to the cloud to generate a shareable link") + + return AssetSnapshot.pieces_client.linkfy_api.linkify( + linkify=Linkify( + access="PUBLIC", + **kwargs + ) + ) diff --git a/_pieces_lib/pieces_os_client/wrapper/basic_identifier/basic.py b/_pieces_lib/pieces_os_client/wrapper/basic_identifier/basic.py new file mode 100644 index 0000000..e034289 --- /dev/null +++ b/_pieces_lib/pieces_os_client/wrapper/basic_identifier/basic.py @@ -0,0 +1,80 @@ +from abc import ABC,abstractmethod +from typing import Optional +from Pieces._pieces_lib.pieces_os_client import Annotations, AnnotationTypeEnum + + +class Basic(ABC): + def __init__(self, id) -> None: + """ + Initialize the class with a given ID. + + :param id: The ID of the Object. + """ + self._id = id + + @property + def description(self) -> Optional[str]: + """ + Retrieve the description. + + :return: The description text or None if not available. + """ + annotations = self.annotations + if not annotations: + return + d = None + for annotation in annotations.iterable: + if annotation.type == AnnotationTypeEnum.DESCRIPTION: + d = annotation + + return d.text if d else None + + @property + @abstractmethod + def annotations(self) -> Optional[Annotations]: + """ + Get all the annotations. + + Returns: + Optional[Annotations]: The annotations if available, otherwise None. + """ + pass + + @property + @abstractmethod + def id(self) -> str: + pass + + @abstractmethod + def delete(self) -> None: + pass + + def __repr__(self): + """ + Returns a detailed string representation of the object. + """ + return f"<{self.__class__.__name__}(id={self.id})>" + + def __eq__(self, other): + """ + Checks equality between two instances. + """ + if isinstance(other, self.__class__): + return self.id == other.id + return False + + def __str__(self): + """ + Returns a user-friendly string representation of the object. + """ + if hasattr(self,"name"): + return f"ID: {self.id}, Name: {self.name}" + return f"ID: {self.id}" + + + def __hash__(self): + """ + Returns a hash of the instance. + """ + return hash(self.id) + diff --git a/_pieces_lib/pieces_os_client/wrapper/basic_identifier/chat.py b/_pieces_lib/pieces_os_client/wrapper/basic_identifier/chat.py new file mode 100644 index 0000000..5fb6d11 --- /dev/null +++ b/_pieces_lib/pieces_os_client/wrapper/basic_identifier/chat.py @@ -0,0 +1,89 @@ +from Pieces._pieces_lib.pieces_os_client.models.conversation import Conversation +from ..streamed_identifiers import ConversationsSnapshot +from typing import Optional, List +from .basic import Basic +from .message import BasicMessage + +class BasicChat(Basic): + """ + A class to represent a basic chat, initialized with a conversation ID. + """ + @property + def conversation(self) -> Conversation: + conversation = ConversationsSnapshot.identifiers_snapshot.get(self._id) + if not conversation: + raise ValueError("Conversation not found") + return conversation + + @property + def id(self): + """ + Gets the ID of the conversation. + + Returns: + The ID of the conversation. + """ + return self.conversation.id + + @property + def name(self) -> str: + """ + Gets the name of the conversation. + + Returns: + The name of the conversation, or "New Conversation" if the name is not set. + """ + return self.conversation.name if self.conversation.name else "New Conversation" + + @name.setter + def name(self, name): + """ + Sets the name of the conversation. + + Args: + name: The new name of the conversation. + """ + self.conversation.name = name + self._edit_conversation(self.conversation) + + def messages(self) -> List[BasicMessage]: + """ + Retrieves the messages in the conversation. + + Returns: + A list of BasicMessage instances representing the messages in the conversation. + """ + out = [] + for message_id, index in (self.conversation.messages.indices or {}).items(): + if index == -1: # Deleted message + continue + out.append(BasicMessage(ConversationsSnapshot.pieces_client,message_id)) + return out + + + @property + def annotations(self): + """ + Gets the annotations of the conversation. + + Returns: + The annotations of the conversation, or None if not available. + """ + return getattr(self.conversation.annotations, "iterable", None) + + def delete(self): + """ + Deletes the conversation. + """ + ConversationsSnapshot.pieces_client.conversations_api.conversations_delete_specific_conversation(self.id) + + @staticmethod + def _edit_conversation(conversation): + """ + Edits the conversation. + + Args: + conversation: The conversation to edit. + """ + ConversationsSnapshot.pieces_client.conversation_api.conversation_update(False, conversation) + diff --git a/_pieces_lib/pieces_os_client/wrapper/basic_identifier/message.py b/_pieces_lib/pieces_os_client/wrapper/basic_identifier/message.py new file mode 100644 index 0000000..f867668 --- /dev/null +++ b/_pieces_lib/pieces_os_client/wrapper/basic_identifier/message.py @@ -0,0 +1,118 @@ +from typing import Literal, Optional,TYPE_CHECKING +from Pieces._pieces_lib.pieces_os_client import ConversationMessage,Annotations +from .basic import Basic +if TYPE_CHECKING: + from ..client import PiecesClient + +class BasicMessage(Basic): + """ + A class to represent a basic message in the Pieces client. + + Attributes: + ---------- + pieces_client : PiecesClient + An instance of the PiecesClient to interact with the API. + message_id : str + The ID of the message to be retrieved. + + Methods: + ------- + raw_content: + Gets or sets the raw content of the message. + role: + Gets the role of the message. + id: + Gets the ID of the message. + delete(): + Deletes the message. + """ + + def __init__(self, pieces_client:"PiecesClient", id: str) -> None: + """ + Constructs all the necessary attributes for the BasicMessage object. + + Parameters: + ---------- + pieces_client : PiecesClient + An instance of the PiecesClient to interact with the API. + id: str + The ID of the message to be retrieved. + """ + try: + self.message:ConversationMessage = pieces_client.conversation_message_api.message_specific_message_snapshot( + message=id, transferables=True + ) + except: + raise ValueError("Error in retrieving the message") + self.pieces_client = pieces_client + + @property + def raw_content(self) -> Optional[str]: + """ + Gets the raw content of the message. + + Returns: + ------- + Optional[str] + The raw content of the message if available, otherwise None. + """ + try: + return self.message.fragment.string.raw + except: + pass + + @raw_content.setter + def raw_content(self, value: str) -> None: + """ + Sets the raw content of the message and updates it in the API. + + Parameters: + ---------- + value : str + The new raw content of the message. + """ + self.message.fragment.string.raw = value + self.pieces_client.conversation_message_api.message_update_value( + False, self.message + ) + + @property + def role(self) -> Literal["USER", "SYSTEM", "ASSISTANT"]: + """ + Gets the role of the message. + + Returns: + ------- + Literal["USER", "SYSTEM", "ASSISTANT"] + The role of the message. + """ + return self.message.role.value + + @property + def id(self) -> str: + """ + Gets the ID of the message. + + Returns: + ------- + str + The ID of the message. + """ + return self.message.id + + def delete(self) -> None: + """ + Deletes the message from the API. + """ + self.pieces_client.conversation_messages_api.messages_delete_specific_message( + self.message.id + ) + + @property + def annotations(self) -> Optional[Annotations]: + out = [] + if self.message.annotations: + for referenced_annotation in self.message.annotations.iterable: + out.append(self.pieces_client.annotation_api.annotation_specific_annotation_snapshot(referenced_annotation.id)) + return Annotations(iterable=out) + diff --git a/_pieces_lib/pieces_os_client/wrapper/basic_identifier/user.py b/_pieces_lib/pieces_os_client/wrapper/basic_identifier/user.py new file mode 100644 index 0000000..080c6a3 --- /dev/null +++ b/_pieces_lib/pieces_os_client/wrapper/basic_identifier/user.py @@ -0,0 +1,144 @@ +import threading +from Pieces._pieces_lib.pieces_os_client import UserProfile,AllocationStatusEnum +from typing import Optional + +## TODO: Modify the Basic class to be able to fit in the BasicUser +class BasicUser: + """ + A class to represent a basic user and manage their connection to the cloud. + + Attributes: + user_profile: The profile of the user. + pieces_client: The client used to interact with the pieces OS API. + """ + + user_profile: Optional[UserProfile] = None + + def __init__(self, pieces_client) -> None: + """ + Initializes the BasicUser with a pieces client. + + Args: + pieces_client: The client used to interact with the pieces OS API. + """ + self.pieces_client = pieces_client + + def on_user_callback(self, user: Optional[UserProfile], connecting=False): + """ + Callback function to set the user profile. + + Args: + user: The profile of the user. + connecting: A flag indicating if the user is connecting to the cloud (default is False). + """ + self.user_profile = user + + def _on_login_connect(self, thread, timeout): + """ + Waits for the user to login and then connects to the cloud. + + Args: + thread: The thread handling the login process. + timeout: The maximum time to wait for the login process. + """ + thread.get(timeout) # Wait for the user to login + self.connect() + + def login(self, connect_after_login=True, timeout=120): + """ + Logs the user into the OS and optionally connects to the cloud. + + Args: + connect_after_login: A flag indicating if the user should connect to the cloud after login (default is True). + timeout: The maximum time to wait for the login process (default is 120 seconds). + """ + thread = self.pieces_client.os_api.sign_into_os(async_req=True) + if connect_after_login: + threading.Thread(target=lambda: self._on_login_connect(thread, timeout)) + + def logout(self): + """ + Logs the user out of the OS. + """ + self.pieces_client.api_client.os_api.sign_out_of_os() + + def connect(self): + """ + Connects the user to the cloud. + + Raises: + PermissionError: If the user is not logged in. + """ + if not self.user_profile: + raise PermissionError("You must be logged in to use this feature") + self.on_user_callback(self.user_profile, True) # Set the connecting to cloud bool to true + self.pieces_client.allocations_api.allocations_connect_new_cloud(self.user_profile) + + def disconnect(self): + """ + Disconnects the user from the cloud. + + Raises: + PermissionError: If the user is not logged in. + """ + if not self.user_profile: + raise PermissionError("You must be logged in to use this feature") + if self.user_profile.allocation: # Check if there is an allocation iterable + self.pieces_client.api_client.allocations_api.allocations_disconnect_cloud(self.user_profile.allocation) + + @property + def picture(self) -> Optional[str]: + """ + Returns the user's profile picture URL. + + Returns: + The URL of the user's profile picture, or None if not available. + """ + if self.user_profile: + return self.user_profile.picture + + + @property + def name(self) -> Optional[str]: + """ + Returns the name of the user. + + Returns: + Optional[str]: The name of the user if the user logged in, otherwise None. + """ + if self.user_profile: + return self.user_profile.name + + @property + def email(self) -> Optional[str]: + """ + Returns the email of the user. + + Returns: + Optional[str]: The email of the user if the user logged in, otherwise None. + """ + if self.user_profile: + return self.user_profile.email + + @property + def vanity_name(self) -> Optional[str]: # TODO: implements the setter object + """ + Returns the vanity name of the user which is the base name of the cloud url. + For example, if the cloud URL is 'bishoyatpieces.pieces.cloud', this method returns 'bishoyatpieces'. + + Returns: + Optional[str]: The vanity name of the user if the user user logged in and connected to the cloud, otherwise None. + """ + if self.user_profile: + return self.user_profile.vanityname + + @property + def cloud_status(self) -> Optional[AllocationStatusEnum]: + """ + Returns the cloud status of the user's cloud. + + Returns: + Optional[AllocationStatusEnum]: The cloud status of the user's cloud. + """ + if self.user_profile and self.user_profile.allocation: + return self.user_profile.allocation.status.cloud diff --git a/_pieces_lib/pieces_os_client/wrapper/client.py b/_pieces_lib/pieces_os_client/wrapper/client.py new file mode 100644 index 0000000..257a939 --- /dev/null +++ b/_pieces_lib/pieces_os_client/wrapper/client.py @@ -0,0 +1,181 @@ +from Pieces._pieces_lib.pieces_os_client import ( + ApiClient, + Configuration, + ConversationApi, + ConversationMessageApi, + ConversationMessagesApi, + ConversationsApi, + QGPTApi, + UserApi, + FormatApi, + ConnectorApi, + SeededConnectorConnection, + SeededTrackedApplication, + AssetApi, + AssetsApi, + FragmentMetadata, + ModelsApi, + AnnotationApi, + LinkifyApi, + WellKnownApi, + OSApi, + AllocationsApi, + __version__ +) +from typing import Optional,Dict +import platform +import atexit +import subprocess + + +from .copilot import Copilot +from .basic_identifier import BasicAsset,BasicUser +from .streamed_identifiers import AssetSnapshot +from .websockets import * + +class PiecesClient: + def __init__(self, host:str="", seeded_connector: Optional[SeededConnectorConnection] = None,**kwargs): + if host: + self.host = host + else: + self.host = "http://localhost:5323" if 'Linux' in platform.platform() else "http://localhost:1000" + + + self.api_client = ApiClient(Configuration(self.host)) + + self.conversation_message_api = ConversationMessageApi(self.api_client) + self.conversation_messages_api = ConversationMessagesApi(self.api_client) + self.conversations_api = ConversationsApi(self.api_client) + self.conversation_api = ConversationApi(self.api_client) + self.qgpt_api = QGPTApi(self.api_client) + self.user_api = UserApi(self.api_client) + self.assets_api = AssetsApi(self.api_client) + self.asset_api = AssetApi(self.api_client) + self.format_api = FormatApi(self.api_client) + self.connector_api = ConnectorApi(self.api_client) + self.models_api = ModelsApi(self.api_client) + self.annotation_api = AnnotationApi(self.api_client) + self.well_known_api = WellKnownApi(self.api_client) + self.os_api = OSApi(self.api_client) + self.allocations_api = AllocationsApi(self.api_client) + self.linkfy_api = LinkifyApi(self.api_client) + + # Websocket urls + if not self.host.startswith("http"): + raise ValueError("Invalid host url\n Host should start with http or https") + ws_base_url:str = self.host.replace('http','ws') + + self.ASSETS_IDENTIFIERS_WS_URL = ws_base_url + "/assets/stream/identifiers" + self.AUTH_WS_URL = ws_base_url + "/user/stream" + self.ASK_STREAM_WS_URL = ws_base_url + "/qgpt/stream" + self.CONVERSATION_WS_URL = ws_base_url + "/conversations/stream/identifiers" + self.HEALTH_WS_URL = ws_base_url + "/.well-known/stream/health" + + self.local_os = platform.system().upper() if platform.system().upper() in ["WINDOWS","LINUX","DARWIN"] else "WEB" + self.local_os = "MACOS" if self.local_os == "DARWIN" else self.local_os + seeded_connector = seeded_connector or SeededConnectorConnection( + application=SeededTrackedApplication( + name = "OPEN_SOURCE", + platform = self.local_os, + version = __version__)) + + self.tracked_application = self.connector_api.connect(seeded_connector_connection=seeded_connector).application + + self.user = BasicUser(self) + + if kwargs.get("connect_wesockets",True): + self.conversation_ws = ConversationWS(self) + self.assets_ws = AssetsIdentifiersWS(self) + self.user_websocket = AuthWS(self,self.user.on_user_callback) + # Start all initilized websockets + BaseWebsocket.start_all() + + self.models = None + self.model_name = "GPT-3.5-turbo Chat Model" + self.copilot = Copilot(self) + + + def assets(self): + self.ensure_initialization() + return [BasicAsset(id) for id in AssetSnapshot.identifiers_snapshot.keys()] + + def asset(self,asset_id): + self.ensure_initialization() + return BasicAsset(asset_id) + + @staticmethod + def create_asset(content:str,metadata:Optional[FragmentMetadata]=None): + return BasicAsset.create(content,metadata) + + + def get_models(self) -> Dict[str, str]: + if self.models: + return self.models + api_response = self.models_api.models_snapshot() + models = {model.name: model.id for model in api_response.iterable if model.cloud or model.downloaded} # getting the models that are available in the cloud or is downloaded + self.models = models + return models + + @property + def model_name(self): + return self._model_name + + @model_name.setter + def model_name(self,model): + models = self.get_models() + if model not in models: + raise ValueError(f"Not a vaild model name, the available models are {', '.join(models.keys())}") + self._model_name = model + self.model_id = models[model] + + @property + def available_models_names(self) -> list: + return list(self.get_models().keys()) + + def ensure_initialization(self): + """ + Waits for all the assets/conversations and all the started websockets to open + """ + BaseWebsocket.wait_all() + + def close(self): + """ + Use this when you exit the app + """ + BaseWebsocket.close_all() + + @property + def version(self) -> str: + """ + Returns Pieces OS Version + """ + return self.well_known_api.get_well_known_version() + + @property + def health(self) -> bool: + """ + Returns True Pieces OS health is ok else False + """ + try: + return self.well_known_api.get_well_known_health_with_http_info().status_code == 200 + except: + pass + return False + + def open_pieces_os(self) -> bool: + """ + Open Pieces OS + + Returns (bool): true if Pieces OS runned successfully else false + """ + if self.local_os == "WINDOWS": + subprocess.run(["start", "pieces://launch"], shell=True) + elif self.local_os == "MACOS": + subprocess.run(["open","pieces://launch"]) + elif self.local_os == "LINUX": + subprocess.run(["xdg-open","pieces://launch"]) + return self.health + +# Register the function to be called on exit +atexit.register(BaseWebsocket.close_all) + diff --git a/_pieces_lib/pieces_os_client/wrapper/context.py b/_pieces_lib/pieces_os_client/wrapper/context.py new file mode 100644 index 0000000..930b12a --- /dev/null +++ b/_pieces_lib/pieces_os_client/wrapper/context.py @@ -0,0 +1,85 @@ +from typing import TYPE_CHECKING + +from .basic_identifier import BasicAsset,BasicMessage +import os +from Pieces._pieces_lib.pieces_os_client import QGPTRelevanceInput,Seeds,FlattenedAssets,FlattenedConversationMessages + +if TYPE_CHECKING: + from . import PiecesClient + +class Context: + def __init__(self, + pieces_client:"PiecesClient", + paths:list[str] = [], + raw_assets:list[str] = [], + assets:list[BasicAsset] = [], + messages:list[BasicMessage] = []): + self.pieces_client = pieces_client + self.raw_assets = raw_assets + self.paths = paths + self.assets = assets + self.messages = messages + + def clear(self): + self.raw_assets = [] + self.paths = [] + self.assets = [] + self.messages = [] + + def _get_relevant_dict(self): + self._check_paths(self.paths) + assets = self._check_assets(self.assets) + raw_snippet = self._check_raw_assets(self.raw_assets) + messages = self._check_messages(self.messages) + + return { + "paths":self.paths, + "seed":raw_snippet, + "assets":assets, + "messages":messages + } + + def _check_relevant_existance(self) -> bool: + return bool(self.paths or self.assets or self.raw_assets) + + @staticmethod + def _check_messages(messages): + message_list = FlattenedConversationMessages(iterable=[]) + for message in messages: + if not isinstance(message,BasicMessage): + raise ValueError("Invalid message type") + message_list.iterable.append(message.message) + return message_list + + @staticmethod + def _check_assets(assets): + assets_list = FlattenedAssets(iterable=[]) + for snippet in assets: + if not isinstance(snippet,BasicAsset): + raise ValueError("Invalid asset type") + assets_list.iterable.append(snippet.asset) + return assets_list + + @staticmethod + def _check_paths(paths): + for path in paths: + if not os.path.exists(path): + raise ValueError("Invalid path in the context") + + @staticmethod + def _check_raw_assets(assets:list[str]): + seed_list = Seeds(iterable=[]) + for raw in assets: + if not isinstance(raw,str): + raise ValueError("Raw snippet content should be string type") + seed_list.iterable.append(BasicAsset._get_seed(raw)) + return seed_list + + def _relevance_api(self,query): + return self.pieces_client.qgpt_api.relevance( + QGPTRelevanceInput( + query=query, + application=self.pieces_client.tracked_application.id, + model=self.pieces_client.model_id, + **self._get_relevant_dict() + )).relevant \ No newline at end of file diff --git a/_pieces_lib/pieces_os_client/wrapper/copilot.py b/_pieces_lib/pieces_os_client/wrapper/copilot.py new file mode 100644 index 0000000..570fbfa --- /dev/null +++ b/_pieces_lib/pieces_os_client/wrapper/copilot.py @@ -0,0 +1,159 @@ +from typing import TYPE_CHECKING, Optional, Generator +from Pieces._pieces_lib.pieces_os_client import (SeededConversation, + QGPTStreamInput, + RelevantQGPTSeeds, + QGPTQuestionInput, + QGPTStreamOutput, + QGPTStreamEnum, + QGPTQuestionOutput) +from Pieces._pieces_lib.pieces_os_client.models.qgpt_prompt_pipeline import QGPTPromptPipeline + +from .context import Context +from .basic_identifier.chat import BasicChat +from .streamed_identifiers.conversations_snapshot import ConversationsSnapshot +from .websockets import AskStreamWS +import queue + + +if TYPE_CHECKING: + from .client import PiecesClient + + +class Copilot: + """ + A class to interact with the Pieces Copilot SDK for managing conversations and streaming QGPT responses. + """ + + def __init__(self, pieces_client: "PiecesClient"): + """ + Initializes the Copilot instance. + + Args: + pieces_client: The client instance to interact with the Pieces API. + """ + self.pieces_client = pieces_client + self._on_message_queue = queue.Queue() + self.ask_stream_ws = AskStreamWS(self.pieces_client, self._on_message_queue.put) + self.context = Context(pieces_client) + self._chat = None + + def stream_question(self, + query: str, + pipeline: Optional[QGPTPromptPipeline] = None + ) -> Generator[QGPTStreamOutput, None, None]: + """ + Asks a question to the QGPT model and streams the responses. + by default it will create a new conversation and always use it in the ask. + You can always change the conversation in copilot.chat = BasicChat(chat_id="YOU ID GOES HERE") + + Args: + query (str): The question to ask. + pipeline (Optional[QGPTPromptPipeline]): the pipeline to use. + + Yields: + QGPTStreamOutput: The streamed output from the QGPT model. + """ + id = self._chat.id if self._chat else None + relevant = self.context._relevance_api(query) if self.context._check_relevant_existance else RelevantQGPTSeeds(iterable=[]) + self.ask_stream_ws.send_message( + QGPTStreamInput( + question=QGPTQuestionInput( + relevant=relevant, + query=query, + application=self.pieces_client.tracked_application.id, + model=self.pieces_client.model_id, + pipeline=pipeline + ), + conversation=id, + ) + ) + + while True: + message: QGPTStreamOutput = self._on_message_queue.get() + if message.status != QGPTStreamEnum.IN_MINUS_PROGRESS: # Loop only while in progress + yield message + self.chat = BasicChat(message.conversation) # Save the conversation + break + yield message + + + def question(self, + query:str, + relevant_qgpt_seeds: RelevantQGPTSeeds = RelevantQGPTSeeds(iterable=[]), + pipeline:Optional[QGPTPromptPipeline]=None + ) -> QGPTQuestionOutput: + """ + Asks a question to the QGPT model and return the responses, + Note: the question is not a part of any conversation. + + Args: + query (str): The question to ask. + relevant_qgpt_seeds (RelevantQGPTSeeds): Context to the model . + pipeline (Optional[QGPTPromptPipeline]): the pipeline to use. + + returns: + QGPTQuestionOutput: The streamed output from the QGPT model. + """ + gpt_input = QGPTQuestionInput( + query = query, + model = self.pieces_client.model_id, + application = self.pieces_client.tracked_application.id, + pipeline=pipeline, + relevant = relevant_qgpt_seeds + ) + + return self.pieces_client.qgpt_api.question(gpt_input) + + def chats(self) -> list[BasicChat]: + """ + Retrieves a list of all chat identifiers. + + Returns: + list[BasicChat]: A list of BasicChat instances representing the chat identifiers. + """ + self.pieces_client.ensure_initialization() + return [BasicChat(id) for id in ConversationsSnapshot.identifiers_snapshot] + + @property + def chat(self) -> Optional[BasicChat]: + """ + Gets the current conversation being used in the copilot. + + Returns: + Optional[BasicChat]: The current chat instance or None if no chat is set. + """ + self.context.clear() # clear the context on changing the conversation + return self._chat + + @chat.setter + def chat(self, chat: Optional[BasicChat]): + """ + Sets the current conversation to be used in the copilot. + + Args: + chat (Optional[BasicChat]): The chat instance to set. + + Raises: + ValueError: If the provided chat is not a valid BasicChat instance. + """ + if not (chat is None or isinstance(chat, BasicChat)): + raise ValueError("Not a valid chat") + self._chat = chat + + + def create_chat(self, name:Optional[str]=None): + """ + Creates a New Chat and change the current Copilot chat state to the new generated one + """ + new_conversation = self.pieces_client.conversations_api.conversations_create_specific_conversation( + seeded_conversation={ + 'name': name, + 'type': 'COPILOT', + } + ) + + ConversationsSnapshot.identifiers_snapshot[new_conversation.id] = new_conversation # Make sure to update the cache + self.chat = BasicChat(new_conversation.id) + + return self.chat + diff --git a/_pieces_lib/pieces_os_client/wrapper/streamed_identifiers/__init__.py b/_pieces_lib/pieces_os_client/wrapper/streamed_identifiers/__init__.py new file mode 100644 index 0000000..c1cbfd4 --- /dev/null +++ b/_pieces_lib/pieces_os_client/wrapper/streamed_identifiers/__init__.py @@ -0,0 +1,9 @@ +from .assets_snapshot import AssetSnapshot +from .conversations_snapshot import ConversationsSnapshot + + +__all__ = [ + "AssetSnapshot", + "ConversationsSnapshot" +] + diff --git a/_pieces_lib/pieces_os_client/wrapper/streamed_identifiers/_streamed_identifiers.py b/_pieces_lib/pieces_os_client/wrapper/streamed_identifiers/_streamed_identifiers.py new file mode 100644 index 0000000..80c44c4 --- /dev/null +++ b/_pieces_lib/pieces_os_client/wrapper/streamed_identifiers/_streamed_identifiers.py @@ -0,0 +1,130 @@ +""" +A class for caching Streamed Identifiers. This class is designed to be inherited. + +Attributes: + identifiers_snapshot (Dict[str, Union[Asset, Conversation]]): A dictionary mapping IDs to their corresponding API call results. + identifiers_queue (queue.Queue): A queue for IDs to be processed. + identifiers_set (set): A set for IDs currently in the queue. + _api_call (Callable[[str], Union[Asset, Conversation]]): A callable that takes an ID and returns either an Asset or a Conversation. + block (bool): A flag to indicate whether to wait for the queue to receive the first ID. + first_shot (bool): A flag to indicate if it's the first time to open the websocket. + lock (threading.Lock): A lock for thread safety. + worker_thread (threading.Thread): A thread for processing the queue. + +Methods: + worker(): Continuously processes IDs from the queue and updates the identifiers_snapshot. + update_identifier(id: str): Updates the identifier snapshot with the result of the API call. + streamed_identifiers_callback(ids: StreamedIdentifiers): Callback method to handle streamed identifiers. + +Example: + class AssetSnapshot(StreamedIdentifiersCache,_api_call=AssetApi(PiecesSettings.api_client).asset_snapshot): + pass +""" +import queue +from typing import Dict, List, Union, Callable, TYPE_CHECKING +from Pieces._pieces_lib.pieces_os_client import Conversation, StreamedIdentifiers, Asset +from abc import ABC, abstractmethod +import threading + +if TYPE_CHECKING: + from ..client import PiecesClient + +class StreamedIdentifiersCache(ABC): + """ + This class is made for caching Streamed Identifiers. + Please use this class only as a parent class. + """ + pieces_client: "PiecesClient" + + def __init_subclass__(cls, **kwargs): + super().__init_subclass__(**kwargs) + cls.on_update_list: List[Callable] = [] + cls.on_remove_list: List[Callable] = [] + cls.identifiers_snapshot: Dict[str, Union[Asset, Conversation, None]] = {} # Map id:return from the _api_call + cls.identifiers_queue = queue.Queue() # Queue for ids to be processed + cls.identifiers_set = set() # Set for ids in the queue + cls.block = True # to wait for the queue to receive the first id + cls.first_shot = True # First time to open the websocket or not + cls._lock = threading.Lock() # Lock for thread safety + cls._worker_thread = threading.Thread(target=cls.worker) + cls._worker_thread.daemon = True # Ensure the thread exits when the main program does + + @classmethod + def on_update(cls, obj): + for update in cls.on_update_list: + update(obj) + + @classmethod + def on_remove(cls, obj): + for remove in cls.on_remove_list: + remove(obj) + + @abstractmethod + def _api_call(cls, id: str) -> Union[Asset, Conversation]: + pass + + @abstractmethod + def _sort_first_shot(cls): + """ + Sorting algorithm in the first shot + """ + pass + + @classmethod + def worker(cls): + while True: + try: + id = cls.identifiers_queue.get(block=cls.block, timeout=5) + with cls._lock: + cls.identifiers_set.remove(id) # Remove the id from the set + cls.update_identifier(id) + cls.identifiers_queue.task_done() + except queue.Empty: # queue is empty and the block is false + if cls.block: + continue # if there are more ids to load + + if cls.first_shot: + cls.first_shot = False + cls._initialized.set() + cls._sort_first_shot() + + return # End the worker + except Exception as e: + print(f"Error in worker: {e}") + + @classmethod + def update_identifier(cls, identifier: str): + try: + id_value = cls._api_call(identifier) + with cls._lock: + cls.identifiers_snapshot[identifier] = id_value + cls.on_update(id_value) + return id_value + except Exception as e: + print(f"Error updating identifier {identifier}: {e}") + return None + + @classmethod + def streamed_identifiers_callback(cls, ids: StreamedIdentifiers): + # Start the worker thread if it's not running + cls.block = True + if not cls._worker_thread.is_alive(): + cls._worker_thread = threading.Thread(target=cls.worker) + cls._worker_thread.daemon = True + cls._worker_thread.start() + + for item in ids.iterable: + reference_id = item.asset.id if item.asset else item.conversation.id # Get either the conversation or the asset + + with cls._lock: + if reference_id not in cls.identifiers_set: + if item.deleted: + # Asset deleted + cls.on_remove(cls.identifiers_snapshot.pop(reference_id, None)) + else: + if reference_id not in cls.identifiers_snapshot and not cls.first_shot: + cls.identifiers_snapshot = {reference_id: None, **cls.identifiers_snapshot} + cls.identifiers_queue.put(reference_id) # Add id to the queue + cls.identifiers_set.add(reference_id) # Add id to the set + + cls.block = False # Remove the block to end the thread \ No newline at end of file diff --git a/_pieces_lib/pieces_os_client/wrapper/streamed_identifiers/assets_snapshot.py b/_pieces_lib/pieces_os_client/wrapper/streamed_identifiers/assets_snapshot.py new file mode 100644 index 0000000..547b180 --- /dev/null +++ b/_pieces_lib/pieces_os_client/wrapper/streamed_identifiers/assets_snapshot.py @@ -0,0 +1,20 @@ +import threading +from ._streamed_identifiers import StreamedIdentifiersCache + +class AssetSnapshot(StreamedIdentifiersCache): + """ + A class to represent a snapshot of all the cached Assets. + """ + _initialized:threading.Event + + @classmethod + def _api_call(cls, id): + asset = cls.pieces_client.asset_api.asset_snapshot(id) + # cls.on_update(asset) + return asset + + + @staticmethod + def _sort_first_shot(): + pass + diff --git a/_pieces_lib/pieces_os_client/wrapper/streamed_identifiers/conversations_snapshot.py b/_pieces_lib/pieces_os_client/wrapper/streamed_identifiers/conversations_snapshot.py new file mode 100644 index 0000000..16fd991 --- /dev/null +++ b/_pieces_lib/pieces_os_client/wrapper/streamed_identifiers/conversations_snapshot.py @@ -0,0 +1,23 @@ +import threading +from ._streamed_identifiers import StreamedIdentifiersCache + +class ConversationsSnapshot(StreamedIdentifiersCache): + """ + A class to represent a snapshot of all the cached Conversations. + + Class attributes: + identifiers_snapshot (dict): A dictionary where the keys are UUIDs (unique identifiers) and the values are Conversation objects. + """ + _initialized:threading.Event + + @classmethod + def _sort_first_shot(cls): + # Sort the dictionary by the "updated" timestamp + sorted_conversations = sorted(cls.identifiers_snapshot.values(), key=lambda x: x.updated.value, reverse=True) + cls.identifiers_snapshot = {conversation.id:conversation for conversation in sorted_conversations} + + @classmethod + def _api_call(cls,id): + con = cls.pieces_client.conversation_api.conversation_get_specific_conversation(id) + # cls.on_update(con) + return con diff --git a/_pieces_lib/pieces_os_client/wrapper/version_compatibility.py b/_pieces_lib/pieces_os_client/wrapper/version_compatibility.py new file mode 100644 index 0000000..f5f3257 --- /dev/null +++ b/_pieces_lib/pieces_os_client/wrapper/version_compatibility.py @@ -0,0 +1,49 @@ +from enum import Enum +import re +from typing import Optional + +class VersionChecker: + def __init__(self, min_version: str, max_version: str, pieces_os_version:str): + self.min_version = min_version + self.max_version = max_version + self.pieces_os_version = pieces_os_version + + @staticmethod + def _parse_version(version_str): + """Parse a version string into a tuple of integers and pre-release labels.""" + match = re.match(r'^(\d+)\.(\d+)\.(\d+)(?:[-.](\S+))?$', version_str) + if not match: + raise ValueError(f"Invalid version format: {version_str}") + + major, minor, patch, pre_release = match.groups() + version_tuple = (int(major), int(minor), int(patch)) + pre_release_tuple = tuple(pre_release.split('.')) if pre_release else () + return version_tuple, pre_release_tuple + + def version_check(self): + """Check if the Pieces OS version is within the supported range.""" + # Parse version numbers + os_version_parsed, os_pre_release = self._parse_version(self.pieces_os_version) + min_version_parsed, min_pre_release = self._parse_version(self.min_version) + max_version_parsed, max_pre_release = self._parse_version(self.max_version) + + # Determine compatibility + if (os_version_parsed < min_version_parsed or + (os_version_parsed == min_version_parsed and os_pre_release < min_pre_release)): + return VersionCheckResult(False, UpdateEnum.PiecesOS) + elif (os_version_parsed > max_version_parsed or + (os_version_parsed == max_version_parsed and os_pre_release >= max_pre_release)): + return VersionCheckResult(False, UpdateEnum.Plugin) + + return VersionCheckResult(True) + + +class UpdateEnum(Enum): + PiecesOS = 1 + Plugin = 2 + +class VersionCheckResult: + """Result of the version check.""" + def __init__(self, compatible, update:Optional[UpdateEnum]=None): + self.compatible = compatible + self.update = update diff --git a/_pieces_lib/pieces_os_client/wrapper/websockets/__init__.py b/_pieces_lib/pieces_os_client/wrapper/websockets/__init__.py new file mode 100644 index 0000000..defb3f9 --- /dev/null +++ b/_pieces_lib/pieces_os_client/wrapper/websockets/__init__.py @@ -0,0 +1,15 @@ +from .ask_ws import AskStreamWS +from .assets_identifiers_ws import AssetsIdentifiersWS +from .auth_ws import AuthWS +from .health_ws import HealthWS +from .conversations_ws import ConversationWS +from .base_websocket import BaseWebsocket + +__all__ = [ + "AskStreamWS", + "AssetsIdentifiersWS", + "AuthWS", + "HealthWS", + "ConversationWS", + "BaseWebsocket" +] \ No newline at end of file diff --git a/_pieces_lib/pieces_os_client/wrapper/websockets/ask_ws.py b/_pieces_lib/pieces_os_client/wrapper/websockets/ask_ws.py new file mode 100644 index 0000000..0c9894a --- /dev/null +++ b/_pieces_lib/pieces_os_client/wrapper/websockets/ask_ws.py @@ -0,0 +1,74 @@ +from Pieces._pieces_lib.pieces_os_client import QGPTStreamOutput, QGPTStreamInput +from Pieces._pieces_lib.websocket import WebSocketConnectionClosedException, WebSocketApp +from typing import Callable, Optional,TYPE_CHECKING + +from .base_websocket import BaseWebsocket + +if TYPE_CHECKING: + from ..client import PiecesClient + +class AskStreamWS(BaseWebsocket): + """ + A WebSocket client for handling streaming requests and responses using the PiecesClient. + + Attributes: + pieces_client (PiecesClient): The client used to interact with the Pieces API. + on_message_callback (Callable[[QGPTStreamOutput], None]): Callback function to handle incoming messages. + on_open_callback (Optional[Callable[[WebSocketApp], None]]): Optional callback function to handle WebSocket opening. + on_error (Optional[Callable[[WebSocketApp, Exception], None]]): Optional callback function to handle errors. + on_close (Optional[Callable[[WebSocketApp], None]]): Optional callback function to handle WebSocket closing. + """ + def __init__(self, pieces_client: "PiecesClient", + on_message_callback: Callable[[QGPTStreamOutput], None], + on_open_callback: Optional[Callable[[WebSocketApp], None]] = None, + on_error: Optional[Callable[[WebSocketApp, Exception], None]] = None, + on_close: Optional[Callable[[WebSocketApp], None]] = None): + """ + Initializes the AskStreamWS instance. + + Args: + pieces_client (PiecesClient): The client used to interact with the Pieces API. + on_message_callback (Callable[[QGPTStreamOutput], None]): Callback function to handle incoming messages. + on_open_callback (Optional[Callable[[WebSocketApp], None]]): Optional callback function to handle WebSocket opening. + on_error (Optional[Callable[[WebSocketApp, Exception], None]]): Optional callback function to handle errors. + on_close (Optional[Callable[[WebSocketApp], None]]): Optional callback function to handle WebSocket closing. + """ + super().__init__(pieces_client, on_message_callback, on_open_callback, on_error, on_close) + + @property + def url(self): + """ + Returns the WebSocket URL for the ASK stream. + + Returns: + str: The WebSocket URL. + """ + return self.pieces_client.ASK_STREAM_WS_URL + + def on_message(self, ws, message): + """ + Handles incoming messages from the WebSocket. + + Args: + ws (WebSocketApp): The WebSocket application instance. + message (str): The incoming message in JSON format. + """ + self.on_message_callback(QGPTStreamOutput.from_json(message)) + + def send_message(self, message: QGPTStreamInput): + """ + Sends a message through the WebSocket. + + Args: + message (QGPTStreamInput): The message to be sent. + + Raises: + WebSocketConnectionClosedException: If the WebSocket connection is closed. + """ + try: + if not self.ws: + raise WebSocketConnectionClosedException() + self.ws.send(message.to_json()) + except WebSocketConnectionClosedException: + self.on_open = lambda ws: ws.send(message.to_json()) # Send the message on opening + self.start() # Start a new WebSocket since we are not connected to any diff --git a/_pieces_lib/pieces_os_client/wrapper/websockets/assets_identifiers_ws.py b/_pieces_lib/pieces_os_client/wrapper/websockets/assets_identifiers_ws.py new file mode 100644 index 0000000..99ca531 --- /dev/null +++ b/_pieces_lib/pieces_os_client/wrapper/websockets/assets_identifiers_ws.py @@ -0,0 +1,71 @@ +from typing import Callable,Optional,TYPE_CHECKING +from Pieces._pieces_lib.pieces_os_client import StreamedIdentifiers,Asset +from ..streamed_identifiers.assets_snapshot import AssetSnapshot +from .base_websocket import BaseWebsocket +from Pieces._pieces_lib.websocket import WebSocketApp + +if TYPE_CHECKING: + from ..client import PiecesClient +class AssetsIdentifiersWS(BaseWebsocket): + """ + WebSocket client for handling asset identifiers updates and removals. + + Attributes: + pieces_client (PiecesClient): The client used to interact with the Pieces API. + on_asset_update (Optional[Callable[[Asset], None]]): Callback function to handle asset updates. + on_asset_remove (Optional[Callable[[Asset], None]]): Callback function to handle asset removals. + on_open_callback (Optional[Callable[[WebSocketApp], None]]): Callback function to handle WebSocket opening. + on_error (Optional[Callable[[WebSocketApp, Exception], None]]): Callback function to handle WebSocket errors. + on_close (Optional[Callable[[WebSocketApp], None]]): Callback function to handle WebSocket closing. + """ + + def __init__(self, pieces_client: "PiecesClient", + on_asset_update: Optional[Callable[[Asset], None]] = None, + on_asset_remove: Optional[Callable[[Asset], None]] = None, + on_open_callback: Optional[Callable[[WebSocketApp], None]] = None, + on_error: Optional[Callable[[WebSocketApp, Exception], None]] = None, + on_close: Optional[Callable[[WebSocketApp], None]] = None): + """ + Initializes the AssetsIdentifiersWS instance. + + Args: + pieces_client (PiecesClient): The client used to interact with the Pieces API. + on_asset_update (Optional[Callable[[Asset], None]]): Callback function to handle asset updates. + on_asset_remove (Optional[Callable[[Asset], None]]): Callback function to handle asset removals. + on_open_callback (Optional[Callable[[WebSocketApp], None]]): Callback function to handle WebSocket opening. + on_error (Optional[Callable[[WebSocketApp, Exception], None]]): Callback function to handle WebSocket errors. + on_close (Optional[Callable[[WebSocketApp], None]]): Callback function to handle WebSocket closing. + """ + AssetSnapshot.pieces_client = pieces_client + if on_asset_update: + AssetSnapshot.on_update_list.append(on_asset_update) + if on_asset_remove: + AssetSnapshot.on_remove_list.append(on_asset_remove) + + super().__init__(pieces_client, AssetSnapshot.streamed_identifiers_callback, on_open_callback, on_error, on_close) + AssetSnapshot._initialized = self._initialized + + @property + def url(self): + """ + Returns the WebSocket URL for asset identifiers. + + Returns: + str: The WebSocket URL. + """ + return self.pieces_client.ASSETS_IDENTIFIERS_WS_URL + + def on_message(self, ws, message): + """ + Handles incoming WebSocket messages. + + Args: + ws (WebSocketApp): The WebSocket application instance. + message (str): The incoming message in JSON format. + """ + self.on_message_callback(StreamedIdentifiers.from_json(message)) + + @property + def _is_initialized_on_open(self): + return False + diff --git a/_pieces_lib/pieces_os_client/wrapper/websockets/auth_ws.py b/_pieces_lib/pieces_os_client/wrapper/websockets/auth_ws.py new file mode 100644 index 0000000..f91316f --- /dev/null +++ b/_pieces_lib/pieces_os_client/wrapper/websockets/auth_ws.py @@ -0,0 +1,64 @@ +from .base_websocket import BaseWebsocket +from Pieces._pieces_lib.pieces_os_client import UserProfile +import json +from typing import Callable, Optional,TYPE_CHECKING +from Pieces._pieces_lib.websocket import WebSocketApp + +if TYPE_CHECKING: + from ..client import PiecesClient + +class AuthWS(BaseWebsocket): + """ + AuthWS is a WebSocket client for handling authentication-related messages. + + Attributes: + pieces_client (PiecesClient): The client used to interact with the Pieces service. + on_message_callback (Callable[[Optional[UserProfile]], None]): Callback function to handle incoming messages. + on_open_callback (Optional[Callable[[WebSocketApp], None]]): Optional callback function to handle WebSocket opening. + on_error (Optional[Callable[[WebSocketApp, Exception], None]]): Optional callback function to handle errors. + on_close (Optional[Callable[[WebSocketApp], None]]): Optional callback function to handle WebSocket closing. + """ + + def __init__(self, + pieces_client: "PiecesClient", + on_message_callback: Callable[[Optional[UserProfile]], None], + on_open_callback: Optional[Callable[[WebSocketApp], None]] = None, + on_error: Optional[Callable[[WebSocketApp, Exception], None]] = None, + on_close: Optional[Callable[[WebSocketApp], None]] = None): + """ + Initializes the AuthWS instance. + + Args: + pieces_client (PiecesClient): The client used to interact with the Pieces service. + on_message_callback (Callable[[Optional[UserProfile]], None]): Callback function to handle incoming messages. + on_open_callback (Optional[Callable[[WebSocketApp], None]]): Optional callback function to handle WebSocket opening. + on_error (Optional[Callable[[WebSocketApp, Exception], None]]): Optional callback function to handle errors. + on_close (Optional[Callable[[WebSocketApp], None]]): Optional callback function to handle WebSocket closing. + """ + super().__init__(pieces_client, on_message_callback, on_open_callback, on_error, on_close) + + @property + def url(self): + """ + Returns the WebSocket URL for authentication. + + Returns: + str: The WebSocket URL for authentication. + """ + return self.pieces_client.AUTH_WS_URL + + def on_message(self, ws, message): + """ + Handles incoming WebSocket messages. + + Args: + ws (WebSocketApp): The WebSocket application instance. + message (str): The incoming message as a JSON string. + + Raises: + json.decoder.JSONDecodeError: If the message cannot be decoded as JSON. + """ + try: + self.on_message_callback(UserProfile.from_json(message)) + except json.decoder.JSONDecodeError: + self.on_message_callback(None) # User logged out! diff --git a/_pieces_lib/pieces_os_client/wrapper/websockets/base_websocket.py b/_pieces_lib/pieces_os_client/wrapper/websockets/base_websocket.py new file mode 100644 index 0000000..a6bc564 --- /dev/null +++ b/_pieces_lib/pieces_os_client/wrapper/websockets/base_websocket.py @@ -0,0 +1,176 @@ +from typing import Callable, Optional,TYPE_CHECKING +from Pieces._pieces_lib.typing_extensions import Self +from Pieces._pieces_lib import websocket +import threading +from abc import ABC, abstractmethod + +if TYPE_CHECKING: + from ..client import PiecesClient + +class BaseWebsocket(ABC): + instances = [] + _initialized_events:list[threading.Event] = [] + + def __new__(cls, *args, **kwargs): + """ + Ensure that only one instance of the url class is created (Singleton pattern). + """ + if not hasattr(cls, 'instance'): + cls.instance = super(BaseWebsocket, cls).__new__(cls) + return cls.instance + + def __init__(self, + pieces_client: "PiecesClient", + on_message_callback: Callable[[str], None], + on_open_callback: Optional[Callable[[websocket.WebSocketApp], None]] = None, + on_error: Optional[Callable[[websocket.WebSocketApp, Exception], None]] = None, + on_close: Optional[Callable[[websocket.WebSocketApp], None]] = None): + """ + Initialize the BaseWebsocket instance. + + :param pieces_client: An instance of PiecesClient. + :param on_message_callback: Callback function to handle incoming messages. + :param on_open_callback: Optional callback function to handle the websocket opening. + :param on_error: Optional callback function to handle errors. + :param on_close: Optional callback function to handle the websocket closing. + """ + self.ws = None + self.thread = None + self.running = False + self.on_message_callback = on_message_callback + self.on_open_callback = on_open_callback if on_open_callback else lambda x: None + self.on_error = on_error if on_error else lambda ws, error: print(error) + self.on_close = on_close if on_close else lambda ws, close_status_code, close_msg: None + self.pieces_client = pieces_client + self._initialized = threading.Event() + self._initialized.set() # Set it as true at the beginning + + + if self not in BaseWebsocket.instances: + BaseWebsocket.instances.append(self) + BaseWebsocket._initialized_events.append(self._initialized) + + @property + def _is_initialized_on_open(self): + return True + + @abstractmethod + def url(self) -> str: + """ + The URL to connect to. Should be overridden by subclasses. + """ + pass + + @abstractmethod + def on_message(self, ws, message): + """ + Handle incoming messages. Should be overridden by subclasses. + """ + pass + + def on_open(self, ws): + """ + Handle the websocket opening event. + """ + self.running = True + self.on_open_callback(ws) + if self._is_initialized_on_open: + self._initialized.set() + + def run(self): + """ + Run the websocket connection. + """ + self.ws = websocket.WebSocketApp( + self.url, + on_message=self.on_message, + on_error=self.on_error, + on_close=self.on_close, + on_open=self.on_open + ) + self.ws.run_forever() + + def start(self): + """ + Start the websocket connection in a new thread. + """ + if not self.running: + self._initialized.clear() + self.thread = threading.Thread(target=self.run) + self.thread.start() + + def close(self): + """ + Close the websocket connection and stop the thread. + """ + if self.running: + self.ws.close() + self.thread.join() + self.running = False + + @classmethod + def close_all(cls): + """ + Close all websocket instances. + """ + for instance in cls.instances: + instance.close() + + @classmethod + def reconnect_all(cls): + """ + Reconnect all websocket instances. + """ + for instance in cls.instances: + instance.reconnect() + + def reconnect(self): + """ + Reconnect the websocket connection. + """ + self.close() + self.start() + + def __str__(self): + """ + Return a string representation of the instance. + """ + return getattr(self, "url", "BaseWebsocket(ABC)") + + @classmethod + def is_running(cls) -> bool: + """ + Check if the websocket instance is running. + + :return: True if running, False otherwise. + """ + instance = cls.get_instance() + if instance: + return cls.instance.running + return False + + @classmethod + def get_instance(cls) -> Optional[type]: + """ + Get the singleton instance of the class. + + :return: The singleton instance or None if not created. + """ + return getattr(cls, 'instance', None) + + @classmethod + def start_all(cls): + """ + Start all the websockets that are already initialized. + """ + for ws in cls.instances: + ws.start() + + @classmethod + def wait_all(cls): + """ + Wait for all websockets to set the internal flag on + """ + for event in cls._initialized_events: + event.wait() + diff --git a/_pieces_lib/pieces_os_client/wrapper/websockets/conversations_ws.py b/_pieces_lib/pieces_os_client/wrapper/websockets/conversations_ws.py new file mode 100644 index 0000000..55e1419 --- /dev/null +++ b/_pieces_lib/pieces_os_client/wrapper/websockets/conversations_ws.py @@ -0,0 +1,61 @@ +from Pieces._pieces_lib.pieces_os_client import StreamedIdentifiers, Conversation +from .base_websocket import BaseWebsocket +from ..streamed_identifiers import ConversationsSnapshot +from Pieces._pieces_lib.websocket import WebSocketApp +from typing import Optional, Callable,TYPE_CHECKING + +if TYPE_CHECKING: + from ..client import PiecesClient + +class ConversationWS(BaseWebsocket): + def __init__(self, pieces_client: "PiecesClient", + on_conversation_update: Optional[Callable[[Conversation], None]] = None, + on_conversation_remove: Optional[Callable[[Conversation], None]] = None, + on_open_callback: Optional[Callable[[WebSocketApp], None]] = None, + on_error: Optional[Callable[[WebSocketApp, Exception], None]] = None, + on_close: Optional[Callable[[WebSocketApp], None]] = None): + """ + Initialize the ConversationWS class. + + :param pieces_client: An instance of PiecesClient. + :param on_conversation_update: Optional callback for when a conversation is updated. + :param on_conversation_remove: Optional callback for when a conversation is removed. + :param on_open_callback: Optional callback for when the WebSocket connection is opened. + :param on_error: Optional callback for when an error occurs. + :param on_close: Optional callback for when the WebSocket connection is closed. + """ + # Set the pieces_client for ConversationsSnapshot + ConversationsSnapshot.pieces_client = pieces_client + + # Set the update and remove callbacks, defaulting to no-op lambdas if not provided + if on_conversation_update: + ConversationsSnapshot.on_update_list.append(on_conversation_update) + if on_conversation_remove: + ConversationsSnapshot.on_remove_list.append(on_conversation_remove) + + super().__init__(pieces_client, ConversationsSnapshot.streamed_identifiers_callback, on_open_callback, on_error, on_close) + ConversationsSnapshot._initialized = self._initialized + # Initialize the base WebSocket with the provided callbacks + + @property + def url(self): + """ + Property to get the WebSocket URL for conversations. + + :return: The WebSocket URL for conversations. + """ + return self.pieces_client.CONVERSATION_WS_URL + + def on_message(self, ws, message): + """ + Handle incoming WebSocket messages. + + :param ws: The WebSocketApp instance. + :param message: The incoming message as a JSON string. + """ + # Parse the incoming message and pass it to the callback + self.on_message_callback(StreamedIdentifiers.from_json(message)) + + @property + def _is_initialized_on_open(self): + return False \ No newline at end of file diff --git a/_pieces_lib/pieces_os_client/wrapper/websockets/health_ws.py b/_pieces_lib/pieces_os_client/wrapper/websockets/health_ws.py new file mode 100644 index 0000000..75785ee --- /dev/null +++ b/_pieces_lib/pieces_os_client/wrapper/websockets/health_ws.py @@ -0,0 +1,9 @@ +from .base_websocket import BaseWebsocket + +class HealthWS(BaseWebsocket): + @property + def url(self): + return self.pieces_client.HEALTH_WS_URL + + def on_message(self, ws, message): + self.on_message_callback(message) \ No newline at end of file diff --git a/_pieces_lib/semver/LICENSE.txt b/_pieces_lib/semver/LICENSE.txt deleted file mode 100644 index f98e22b..0000000 --- a/_pieces_lib/semver/LICENSE.txt +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2013, Konstantine Rybnikov -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of the {organization} nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/_pieces_lib/semver/__about__.py b/_pieces_lib/semver/__about__.py deleted file mode 100644 index a0d9cf9..0000000 --- a/_pieces_lib/semver/__about__.py +++ /dev/null @@ -1,37 +0,0 @@ -""" -Metadata about semver. - -Contains information about semver's version, the implemented version -of the semver specifictation, author, maintainers, and description. - -.. autodata:: __author__ - -.. autodata:: __description__ - -.. autodata:: __maintainer__ - -.. autodata:: __version__ - -.. autodata:: SEMVER_SPEC_VERSION -""" - -#: Semver version -__version__ = "3.0.2" - -#: Original semver author -__author__ = "Kostiantyn Rybnikov" - -#: Author's email address -__author_email__ = "k-bx@k-bx.com" - -#: Current maintainer -__maintainer__ = ["Sebastien Celles", "Tom Schraitle"] - -#: Maintainer's email address -__maintainer_email__ = "s.celles@gmail.com" - -#: Short description about semver -__description__ = "Python helper for Semantic Versioning (https://semver.org)" - -#: Supported semver specification -SEMVER_SPEC_VERSION = "2.0.0" diff --git a/_pieces_lib/semver/__init__.py b/_pieces_lib/semver/__init__.py deleted file mode 100644 index 19c88f7..0000000 --- a/_pieces_lib/semver/__init__.py +++ /dev/null @@ -1,72 +0,0 @@ -""" -Semver package major release 3. - -A Python module for semantic versioning. Simplifies comparing versions. -""" - -from ._deprecated import ( - bump_build, - bump_major, - bump_minor, - bump_patch, - compare, - bump_prerelease, - finalize_version, - format_version, - match, - max_ver, - min_ver, - parse, - parse_version_info, - replace, - cmd_bump, - cmd_compare, - cmd_nextver, - cmd_check, - createparser, - process, - main, -) -from .version import Version, VersionInfo -from .__about__ import ( - __version__, - __author__, - __maintainer__, - __author_email__, - __description__, - __maintainer_email__, - SEMVER_SPEC_VERSION, -) - -__all__ = [ - "bump_build", - "bump_major", - "bump_minor", - "bump_patch", - "compare", - "bump_prerelease", - "finalize_version", - "format_version", - "match", - "max_ver", - "min_ver", - "parse", - "parse_version_info", - "replace", - "cmd_bump", - "cmd_compare", - "cmd_nextver", - "cmd_check", - "createparser", - "process", - "main", - "Version", - "VersionInfo", - "__version__", - "__author__", - "__maintainer__", - "__author_email__", - "__description__", - "__maintainer_email__", - "SEMVER_SPEC_VERSION", -] diff --git a/_pieces_lib/semver/__main__.py b/_pieces_lib/semver/__main__.py deleted file mode 100644 index f055b6d..0000000 --- a/_pieces_lib/semver/__main__.py +++ /dev/null @@ -1,28 +0,0 @@ -""" -Module to support call with :file:`__main__.py`. Used to support the following -call:: - - $ python3 -m semver ... - -This makes it also possible to "run" a wheel like in this command:: - - $ python3 semver-3*-py3-none-any.whl/semver -h - -""" -import os.path -import sys -from typing import List, Optional - -from Pieces._pieces_lib.semver import cli - - -def main(cliargs: Optional[List[str]] = None) -> int: - if __package__ == "": - path = os.path.dirname(os.path.dirname(__file__)) - sys.path[0:0] = [path] - - return cli.main(cliargs) - - -if __name__ == "__main__": - sys.exit(main(sys.argv[1:])) diff --git a/_pieces_lib/semver/_deprecated.py b/_pieces_lib/semver/_deprecated.py deleted file mode 100644 index efbdf43..0000000 --- a/_pieces_lib/semver/_deprecated.py +++ /dev/null @@ -1,410 +0,0 @@ -""" -Contains all deprecated functions. - -.. autofunction: deprecated -""" -import inspect -import warnings -from functools import partial, wraps -from types import FrameType -from typing import Type, Callable, Optional, cast - -from . import cli -from .version import Version -from ._types import Decorator, F - - -def deprecated( - func: Optional[F] = None, - *, - replace: Optional[str] = None, - version: Optional[str] = None, - remove: Optional[str] = None, - category: Type[Warning] = DeprecationWarning, -) -> Decorator: - """ - Decorates a function to output a deprecation warning. - - :param func: the function to decorate - :param replace: the function to replace (use the full qualified - name like ``semver.version.Version.bump_major``. - :param version: the first version when this function was deprecated. - :param category: allow you to specify the deprecation warning class - of your choice. By default, it's :class:`DeprecationWarning`, but - you can choose :class:`PendingDeprecationWarning` or a custom class. - :return: decorated function which is marked as deprecated - """ - - if func is None: - return partial( - deprecated, - replace=replace, - version=version, - remove=remove, - category=category, - ) - - @wraps(func) - def wrapper(*args, **kwargs) -> Callable[..., F]: - msg_list = ["Function 'semver.{f}' is deprecated."] - - if version: - msg_list.append("Deprecated since version {v}. ") - - if not remove: - msg_list.append("This function will be removed in semver 3.") - else: - msg_list.append(str(remove)) - - if replace: - msg_list.append("Use {r!r} instead.") - else: - msg_list.append("Use the respective 'semver.Version.{r}' instead.") - - f = cast(F, func).__qualname__ - r = replace or f - - frame = cast(FrameType, cast(FrameType, inspect.currentframe()).f_back) - - msg = " ".join(msg_list) - warnings.warn_explicit( - msg.format(f=f, r=r, v=version), - category=category, - filename=inspect.getfile(frame.f_code), - lineno=frame.f_lineno, - ) - # As recommended in the Python documentation - # https://docs.python.org/3/library/inspect.html#the-interpreter-stack - # better remove the interpreter stack: - del frame - return func(*args, **kwargs) # type: ignore - - return wrapper - - -@deprecated( - version="3.0.0", - remove="Still under investigation, see #258.", - category=PendingDeprecationWarning, -) -def compare(ver1: str, ver2: str) -> int: - """ - Compare two versions strings. - - .. deprecated:: 3.0.0 - The situation of this function is unclear and it might - disappear in the future. - If possible, use :meth:`semver.version.Version.compare`. - See :gh:`258` for details. - - :param ver1: first version string - :param ver2: second version string - :return: The return value is negative if ver1 < ver2, - zero if ver1 == ver2 and strictly positive if ver1 > ver2 - - >>> semver.compare("1.0.0", "2.0.0") - -1 - >>> semver.compare("2.0.0", "1.0.0") - 1 - >>> semver.compare("2.0.0", "2.0.0") - 0 - """ - return Version.parse(ver1).compare(ver2) - - -@deprecated(version="2.10.0") -def parse(version): - """ - Parse version to major, minor, patch, pre-release, build parts. - - .. deprecated:: 2.10.0 - Use :meth:`~semver.version.Version.parse` instead. - - :param version: version string - :return: dictionary with the keys 'build', 'major', 'minor', 'patch', - and 'prerelease'. The prerelease or build keys can be None - if not provided - :rtype: dict - - >>> ver = semver.parse('3.4.5-pre.2+build.4') - >>> ver['major'] - 3 - >>> ver['minor'] - 4 - >>> ver['patch'] - 5 - >>> ver['prerelease'] - 'pre.2' - >>> ver['build'] - 'build.4' - """ - return Version.parse(version).to_dict() - - -@deprecated(replace="semver.version.Version.parse", version="2.10.0") -def parse_version_info(version): - """ - Parse version string to a Version instance. - - .. deprecated:: 2.10.0 - Use :meth:`~semver.version.Version.parse` instead. - .. versionadded:: 2.7.2 - Added :func:`semver.parse_version_info` - - :param version: version string - :return: a :class:`VersionInfo` instance - - >>> version_info = semver.Version.parse("3.4.5-pre.2+build.4") - >>> version_info.major - 3 - >>> version_info.minor - 4 - >>> version_info.patch - 5 - >>> version_info.prerelease - 'pre.2' - >>> version_info.build - 'build.4' - """ - return Version.parse(version) - - -@deprecated(version="2.10.0") -def match(version, match_expr): - """ - Compare two versions strings through a comparison. - - .. deprecated:: 2.10.0 - Use :meth:`~semver.version.Version.match` instead. - - :param str version: a version string - :param str match_expr: operator and version; valid operators are - < smaller than - > greater than - >= greator or equal than - <= smaller or equal than - == equal - != not equal - :return: True if the expression matches the version, otherwise False - :rtype: bool - - >>> semver.match("2.0.0", ">=1.0.0") - True - >>> semver.match("1.0.0", ">1.0.0") - False - """ - ver = Version.parse(version) - return ver.match(match_expr) - - -@deprecated(replace="max", version="2.10.2") -def max_ver(ver1, ver2): - """ - Returns the greater version of two versions strings. - - .. deprecated:: 2.10.2 - Use :func:`max` instead. - - :param ver1: version string 1 - :param ver2: version string 2 - :return: the greater version of the two - :rtype: :class:`Version` - - >>> semver.max_ver("1.0.0", "2.0.0") - '2.0.0' - """ - return str(max(ver1, ver2, key=Version.parse)) - - -@deprecated(replace="min", version="2.10.2") -def min_ver(ver1, ver2): - """ - Returns the smaller version of two versions strings. - - .. deprecated:: 2.10.2 - Use Use :func:`min` instead. - - :param ver1: version string 1 - :param ver2: version string 2 - :return: the smaller version of the two - :rtype: :class:`Version` - - >>> semver.min_ver("1.0.0", "2.0.0") - '1.0.0' - """ - return str(min(ver1, ver2, key=Version.parse)) - - -@deprecated(replace="str(versionobject)", version="2.10.0") -def format_version(major, minor, patch, prerelease=None, build=None): - """ - Format a version string according to the Semantic Versioning specification. - - .. deprecated:: 2.10.0 - Use ``str(Version(VERSION)`` instead. - - :param int major: the required major part of a version - :param int minor: the required minor part of a version - :param int patch: the required patch part of a version - :param str prerelease: the optional prerelease part of a version - :param str build: the optional build part of a version - :return: the formatted string - :rtype: str - - >>> semver.format_version(3, 4, 5, 'pre.2', 'build.4') - '3.4.5-pre.2+build.4' - """ - return str(Version(major, minor, patch, prerelease, build)) - - -@deprecated(version="2.10.0") -def bump_major(version): - """ - Raise the major part of the version string. - - .. deprecated:: 2.10.0 - Use :meth:`~semver.version.Version.bump_major` instead. - - :param: version string - :return: the raised version string - :rtype: str - - >>> semver.bump_major("3.4.5") - '4.0.0' - """ - return str(Version.parse(version).bump_major()) - - -@deprecated(version="2.10.0") -def bump_minor(version): - """ - Raise the minor part of the version string. - - .. deprecated:: 2.10.0 - Use :meth:`~semver.version.Version.bump_minor` instead. - - :param: version string - :return: the raised version string - :rtype: str - - >>> semver.bump_minor("3.4.5") - '3.5.0' - """ - return str(Version.parse(version).bump_minor()) - - -@deprecated(version="2.10.0") -def bump_patch(version): - """ - Raise the patch part of the version string. - - .. deprecated:: 2.10.0 - Use :meth:`~semver.version.Version.bump_patch` instead. - - :param: version string - :return: the raised version string - :rtype: str - - >>> semver.bump_patch("3.4.5") - '3.4.6' - """ - return str(Version.parse(version).bump_patch()) - - -@deprecated(version="2.10.0") -def bump_prerelease(version, token="rc"): - """ - Raise the prerelease part of the version string. - - .. deprecated:: 2.10.0 - Use :meth:`~semver.version.Version.bump_prerelease` instead. - - :param version: version string - :param token: defaults to 'rc' - :return: the raised version string - :rtype: str - - >>> semver.bump_prerelease('3.4.5', 'dev') - '3.4.5-dev.1' - """ - return str(Version.parse(version).bump_prerelease(token)) - - -@deprecated(version="2.10.0") -def bump_build(version, token="build"): - """ - Raise the build part of the version string. - - .. deprecated:: 2.10.0 - Use :meth:`~semver.version.Version.bump_build` instead. - - :param version: version string - :param token: defaults to 'build' - :return: the raised version string - :rtype: str - - >>> semver.bump_build('3.4.5-rc.1+build.9') - '3.4.5-rc.1+build.10' - """ - return str(Version.parse(version).bump_build(token)) - - -@deprecated(version="2.10.0") -def finalize_version(version): - """ - Remove any prerelease and build metadata from the version string. - - .. deprecated:: 2.10.0 - Use :meth:`~semver.version.Version.finalize_version` instead. - - .. versionadded:: 2.7.9 - Added :func:`finalize_version` - - :param version: version string - :return: the finalized version string - :rtype: str - - >>> semver.finalize_version('1.2.3-rc.5') - '1.2.3' - """ - verinfo = Version.parse(version) - return str(verinfo.finalize_version()) - - -@deprecated(version="2.10.0") -def replace(version, **parts): - """ - Replace one or more parts of a version and return the new string. - - .. deprecated:: 2.10.0 - Use :meth:`~semver.version.Version.replace` instead. - .. versionadded:: 2.9.0 - Added :func:`replace` - - :param version: the version string to replace - :param parts: the parts to be updated. Valid keys are: - ``major``, ``minor``, ``patch``, ``prerelease``, or ``build`` - :return: the replaced version string - :raises TypeError: if ``parts`` contains invalid keys - - >>> import semver - >>> semver.replace("1.2.3", major=2, patch=10) - '2.2.10' - """ - return str(Version.parse(version).replace(**parts)) - - -# CLI -cmd_bump = deprecated(cli.cmd_bump, replace="semver.cli.cmd_bump", version="3.0.0") -cmd_check = deprecated(cli.cmd_check, replace="semver.cli.cmd_check", version="3.0.0") -cmd_compare = deprecated( - cli.cmd_compare, replace="semver.cli.cmd_compare", version="3.0.0" -) -cmd_nextver = deprecated( - cli.cmd_nextver, replace="semver.cli.cmd_nextver", version="3.0.0" -) -createparser = deprecated( - cli.createparser, replace="semver.cli.createparser", version="3.0.0" -) -process = deprecated(cli.process, replace="semver.cli.process", version="3.0.0") -main = deprecated(cli.main, replace="semver.cli.main", version="3.0.0") diff --git a/_pieces_lib/semver/_types.py b/_pieces_lib/semver/_types.py deleted file mode 100644 index 7afb6ff..0000000 --- a/_pieces_lib/semver/_types.py +++ /dev/null @@ -1,12 +0,0 @@ -"""Typing for semver.""" - -from functools import partial -from typing import Union, Optional, Tuple, Dict, Iterable, Callable, TypeVar - -VersionPart = Union[int, Optional[str]] -VersionTuple = Tuple[int, int, int, Optional[str], Optional[str]] -VersionDict = Dict[str, VersionPart] -VersionIterator = Iterable[VersionPart] -String = Union[str, bytes] -F = TypeVar("F", bound=Callable) -Decorator = Union[Callable[..., F], partial] diff --git a/_pieces_lib/semver/cli.py b/_pieces_lib/semver/cli.py deleted file mode 100644 index 43e101e..0000000 --- a/_pieces_lib/semver/cli.py +++ /dev/null @@ -1,174 +0,0 @@ -""" -CLI parsing for :command:`pysemver` command. - -Each command in :command:`pysemver` is mapped to a ``cmd_`` function. -The :func:`main ` function calls -:func:`createparser ` and -:func:`process ` to parse and process -all the commandline options. - -The result of each command is printed on stdout. -""" - -import argparse -import sys -from typing import cast, List, Optional - -from .version import Version -from .__about__ import __version__ - - -def cmd_bump(args: argparse.Namespace) -> str: - """ - Subcommand: Bumps a version. - - Synopsis: bump - can be major, minor, patch, prerelease, or build - - :param args: The parsed arguments - :return: the new, bumped version - """ - maptable = { - "major": "bump_major", - "minor": "bump_minor", - "patch": "bump_patch", - "prerelease": "bump_prerelease", - "build": "bump_build", - } - if args.bump is None: - # When bump is called without arguments, - # print the help and exit - args.parser.parse_args(["bump", "-h"]) - - ver = Version.parse(args.version) - # get the respective method and call it - func = getattr(ver, maptable[cast(str, args.bump)]) - return str(func()) - - -def cmd_check(args: argparse.Namespace) -> None: - """ - Subcommand: Checks if a string is a valid semver version. - - Synopsis: check - - :param args: The parsed arguments - """ - if Version.is_valid(args.version): - return None - raise ValueError("Invalid version %r" % args.version) - - -def cmd_compare(args: argparse.Namespace) -> str: - """ - Subcommand: Compare two versions. - - Synopsis: compare - - :param args: The parsed arguments - """ - ver1 = Version.parse(args.version1) - return str(ver1.compare(args.version2)) - - -def cmd_nextver(args: argparse.Namespace) -> str: - """ - Subcommand: Determines the next version, taking prereleases into account. - - Synopsis: nextver - - :param args: The parsed arguments - """ - version = Version.parse(args.version) - return str(version.next_version(args.part)) - - -def createparser() -> argparse.ArgumentParser: - """ - Create an :class:`argparse.ArgumentParser` instance. - - :return: parser instance - """ - parser = argparse.ArgumentParser(prog=__package__, description=__doc__) - - parser.add_argument( - "--version", action="version", version="%(prog)s " + __version__ - ) - - s = parser.add_subparsers() - # create compare subcommand - parser_compare = s.add_parser("compare", help="Compare two versions") - parser_compare.set_defaults(func=cmd_compare) - parser_compare.add_argument("version1", help="First version") - parser_compare.add_argument("version2", help="Second version") - - # create bump subcommand - parser_bump = s.add_parser("bump", help="Bumps a version") - parser_bump.set_defaults(func=cmd_bump) - sb = parser_bump.add_subparsers(title="Bump commands", dest="bump") - - # Create subparsers for the bump subparser: - for p in ( - sb.add_parser("major", help="Bump the major part of the version"), - sb.add_parser("minor", help="Bump the minor part of the version"), - sb.add_parser("patch", help="Bump the patch part of the version"), - sb.add_parser("prerelease", help="Bump the prerelease part of the version"), - sb.add_parser("build", help="Bump the build part of the version"), - ): - p.add_argument("version", help="Version to raise") - - # Create the check subcommand - parser_check = s.add_parser( - "check", help="Checks if a string is a valid semver version" - ) - parser_check.set_defaults(func=cmd_check) - parser_check.add_argument("version", help="Version to check") - - # Create the nextver subcommand - parser_nextver = s.add_parser( - "nextver", help="Determines the next version, taking prereleases into account." - ) - parser_nextver.set_defaults(func=cmd_nextver) - parser_nextver.add_argument("version", help="Version to raise") - parser_nextver.add_argument( - "part", help="One of 'major', 'minor', 'patch', or 'prerelease'" - ) - return parser - - -def process(args: argparse.Namespace) -> str: - """ - Process the input from the CLI. - - :param args: The parsed arguments - :param parser: the parser instance - :return: result of the selected action - """ - if not hasattr(args, "func"): - args.parser.print_help() - raise SystemExit() - - # Call the respective function object: - return args.func(args) - - -def main(cliargs: Optional[List[str]] = None) -> int: - """ - Entry point for the application script. - - :param list cliargs: Arguments to parse or None (=use :class:`sys.argv`) - :return: error code - """ - try: - parser = createparser() - args = parser.parse_args(args=cliargs) - # Save parser instance: - args.parser = parser - result = process(args) - if result is not None: - print(result) - return 0 - - except (ValueError, TypeError) as err: - print("ERROR", err, file=sys.stderr) - return 2 diff --git a/_pieces_lib/semver/py.typed b/_pieces_lib/semver/py.typed deleted file mode 100644 index e69de29..0000000 diff --git a/_pieces_lib/semver/version.py b/_pieces_lib/semver/version.py deleted file mode 100644 index 29309ab..0000000 --- a/_pieces_lib/semver/version.py +++ /dev/null @@ -1,742 +0,0 @@ -"""Version handling by a semver compatible version class.""" - -import re -from functools import wraps -from typing import ( - Any, - ClassVar, - Dict, - Iterable, - Optional, - Pattern, - SupportsInt, - Tuple, - Union, - cast, - Callable, - Collection, - Type, - TypeVar, -) - -from ._types import ( - VersionTuple, - VersionDict, - VersionIterator, - String, - VersionPart, -) - -# These types are required here because of circular imports -Comparable = Union["Version", Dict[str, VersionPart], Collection[VersionPart], str] -Comparator = Callable[["Version", Comparable], bool] - -T = TypeVar("T", bound="Version") - - -def _comparator(operator: Comparator) -> Comparator: - """Wrap a Version binary op method in a type-check.""" - - @wraps(operator) - def wrapper(self: "Version", other: Comparable) -> bool: - comparable_types = ( - Version, - dict, - tuple, - list, - *String.__args__, # type: ignore - ) - if not isinstance(other, comparable_types): - return NotImplemented - return operator(self, other) - - return wrapper - - -def _cmp(a, b): # TODO: type hints - """Return negative if ab.""" - return (a > b) - (a < b) - - -class Version: - """ - A semver compatible version class. - - See specification at https://semver.org. - - :param major: version when you make incompatible API changes. - :param minor: version when you add functionality in a backwards-compatible manner. - :param patch: version when you make backwards-compatible bug fixes. - :param prerelease: an optional prerelease string - :param build: an optional build string - """ - - __slots__ = ("_major", "_minor", "_patch", "_prerelease", "_build") - - #: The names of the different parts of a version - NAMES: ClassVar[Tuple[str, ...]] = tuple([item[1:] for item in __slots__]) - - #: Regex for number in a prerelease - _LAST_NUMBER: ClassVar[Pattern[str]] = re.compile(r"(?:[^\d]*(\d+)[^\d]*)+") - #: Regex template for a semver version - _REGEX_TEMPLATE: ClassVar[ - str - ] = r""" - ^ - (?P0|[1-9]\d*) - (?: - \. - (?P0|[1-9]\d*) - (?: - \. - (?P0|[1-9]\d*) - ){opt_patch} - ){opt_minor} - (?:-(?P - (?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*) - (?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))* - ))? - (?:\+(?P - [0-9a-zA-Z-]+ - (?:\.[0-9a-zA-Z-]+)* - ))? - $ - """ - #: Regex for a semver version - _REGEX: ClassVar[Pattern[str]] = re.compile( - _REGEX_TEMPLATE.format(opt_patch="", opt_minor=""), - re.VERBOSE, - ) - #: Regex for a semver version that might be shorter - _REGEX_OPTIONAL_MINOR_AND_PATCH: ClassVar[Pattern[str]] = re.compile( - _REGEX_TEMPLATE.format(opt_patch="?", opt_minor="?"), - re.VERBOSE, - ) - - def __init__( - self, - major: SupportsInt, - minor: SupportsInt = 0, - patch: SupportsInt = 0, - prerelease: Optional[Union[String, int]] = None, - build: Optional[Union[String, int]] = None, - ): - # Build a dictionary of the arguments except prerelease and build - version_parts = {"major": int(major), "minor": int(minor), "patch": int(patch)} - - for name, value in version_parts.items(): - if value < 0: - raise ValueError( - "{!r} is negative. A version can only be positive.".format(name) - ) - - self._major = version_parts["major"] - self._minor = version_parts["minor"] - self._patch = version_parts["patch"] - self._prerelease = None if prerelease is None else str(prerelease) - self._build = None if build is None else str(build) - - @classmethod - def _nat_cmp(cls, a, b): # TODO: type hints - def cmp_prerelease_tag(a, b): - if isinstance(a, int) and isinstance(b, int): - return _cmp(a, b) - elif isinstance(a, int): - return -1 - elif isinstance(b, int): - return 1 - else: - return _cmp(a, b) - - a, b = a or "", b or "" - a_parts, b_parts = a.split("."), b.split(".") - a_parts = [int(x) if re.match(r"^\d+$", x) else x for x in a_parts] - b_parts = [int(x) if re.match(r"^\d+$", x) else x for x in b_parts] - for sub_a, sub_b in zip(a_parts, b_parts): - cmp_result = cmp_prerelease_tag(sub_a, sub_b) - if cmp_result != 0: - return cmp_result - else: - return _cmp(len(a), len(b)) - - @property - def major(self) -> int: - """The major part of a version (read-only).""" - return self._major - - @major.setter - def major(self, value): - raise AttributeError("attribute 'major' is readonly") - - @property - def minor(self) -> int: - """The minor part of a version (read-only).""" - return self._minor - - @minor.setter - def minor(self, value): - raise AttributeError("attribute 'minor' is readonly") - - @property - def patch(self) -> int: - """The patch part of a version (read-only).""" - return self._patch - - @patch.setter - def patch(self, value): - raise AttributeError("attribute 'patch' is readonly") - - @property - def prerelease(self) -> Optional[str]: - """The prerelease part of a version (read-only).""" - return self._prerelease - - @prerelease.setter - def prerelease(self, value): - raise AttributeError("attribute 'prerelease' is readonly") - - @property - def build(self) -> Optional[str]: - """The build part of a version (read-only).""" - return self._build - - @build.setter - def build(self, value): - raise AttributeError("attribute 'build' is readonly") - - def to_tuple(self) -> VersionTuple: - """ - Convert the Version object to a tuple. - - .. versionadded:: 2.10.0 - Renamed :meth:`Version._astuple` to :meth:`Version.to_tuple` to - make this function available in the public API. - - :return: a tuple with all the parts - - >>> semver.Version(5, 3, 1).to_tuple() - (5, 3, 1, None, None) - """ - return (self.major, self.minor, self.patch, self.prerelease, self.build) - - def to_dict(self) -> VersionDict: - """ - Convert the Version object to an dict. - - .. versionadded:: 2.10.0 - Renamed :meth:`Version._asdict` to :meth:`Version.to_dict` to - make this function available in the public API. - - :return: an dict with the keys in the order ``major``, ``minor``, - ``patch``, ``prerelease``, and ``build``. - - >>> semver.Version(3, 2, 1).to_dict() - {'major': 3, 'minor': 2, 'patch': 1, 'prerelease': None, 'build': None} - """ - return dict( - major=self.major, - minor=self.minor, - patch=self.patch, - prerelease=self.prerelease, - build=self.build, - ) - - def __iter__(self) -> VersionIterator: - """Return iter(self).""" - yield from self.to_tuple() - - @staticmethod - def _increment_string(string: str) -> str: - """ - Look for the last sequence of number(s) in a string and increment. - - :param string: the string to search for. - :return: the incremented string - - Source: - http://code.activestate.com/recipes/442460-increment-numbers-in-a-string/#c1 - """ - match = Version._LAST_NUMBER.search(string) - if match: - next_ = str(int(match.group(1)) + 1) - start, end = match.span(1) - string = string[: max(end - len(next_), start)] + next_ + string[end:] - return string - - def bump_major(self) -> "Version": - """ - Raise the major part of the version, return a new object but leave self - untouched. - - :return: new object with the raised major part - - >>> ver = semver.parse("3.4.5") - >>> ver.bump_major() - Version(major=4, minor=0, patch=0, prerelease=None, build=None) - """ - cls = type(self) - return cls(self._major + 1) - - def bump_minor(self) -> "Version": - """ - Raise the minor part of the version, return a new object but leave self - untouched. - - :return: new object with the raised minor part - - >>> ver = semver.parse("3.4.5") - >>> ver.bump_minor() - Version(major=3, minor=5, patch=0, prerelease=None, build=None) - """ - cls = type(self) - return cls(self._major, self._minor + 1) - - def bump_patch(self) -> "Version": - """ - Raise the patch part of the version, return a new object but leave self - untouched. - - :return: new object with the raised patch part - - >>> ver = semver.parse("3.4.5") - >>> ver.bump_patch() - Version(major=3, minor=4, patch=6, prerelease=None, build=None) - """ - cls = type(self) - return cls(self._major, self._minor, self._patch + 1) - - def bump_prerelease(self, token: Optional[str] = "rc") -> "Version": - """ - Raise the prerelease part of the version, return a new object but leave - self untouched. - - :param token: defaults to ``'rc'`` - :return: new :class:`Version` object with the raised prerelease part. - The original object is not modified. - - >>> ver = semver.parse("3.4.5") - >>> ver.bump_prerelease().prerelease - 'rc.2' - >>> ver.bump_prerelease('').prerelease - '1' - >>> ver.bump_prerelease(None).prerelease - 'rc.1' - """ - cls = type(self) - if self._prerelease is not None: - prerelease = self._prerelease - elif token == "": - prerelease = "0" - elif token is None: - prerelease = "rc.0" - else: - prerelease = str(token) + ".0" - - prerelease = cls._increment_string(prerelease) - return cls(self._major, self._minor, self._patch, prerelease) - - def bump_build(self, token: Optional[str] = "build") -> "Version": - """ - Raise the build part of the version, return a new object but leave self - untouched. - - :param token: defaults to ``'build'`` - :return: new :class:`Version` object with the raised build part. - The original object is not modified. - - >>> ver = semver.parse("3.4.5-rc.1+build.9") - >>> ver.bump_build() - Version(major=3, minor=4, patch=5, prerelease='rc.1', \ -build='build.10') - """ - cls = type(self) - if self._build is not None: - build = self._build - elif token == "": - build = "0" - elif token is None: - build = "build.0" - else: - build = str(token) + ".0" - - # self._build or (token or "build") + ".0" - build = cls._increment_string(build) - if self._build is not None: - build = self._build - elif token == "": - build = "0" - elif token is None: - build = "build.0" - else: - build = str(token) + ".0" - - # self._build or (token or "build") + ".0" - build = cls._increment_string(build) - return cls(self._major, self._minor, self._patch, self._prerelease, build) - - def compare(self, other: Comparable) -> int: - """ - Compare self with other. - - :param other: the second version - :return: The return value is negative if ver1 < ver2, - zero if ver1 == ver2 and strictly positive if ver1 > ver2 - - >>> semver.compare("2.0.0") - -1 - >>> semver.compare("1.0.0") - 1 - >>> semver.compare("2.0.0") - 0 - >>> semver.compare(dict(major=2, minor=0, patch=0)) - 0 - """ - cls = type(self) - if isinstance(other, String.__args__): # type: ignore - other = cls.parse(other) - elif isinstance(other, dict): - other = cls(**other) - elif isinstance(other, (tuple, list)): - other = cls(*other) - elif not isinstance(other, cls): - raise TypeError( - f"Expected str, bytes, dict, tuple, list, or {cls.__name__} instance, " - f"but got {type(other)}" - ) - - v1 = self.to_tuple()[:3] - v2 = other.to_tuple()[:3] - x = _cmp(v1, v2) - if x: - return x - - rc1, rc2 = self.prerelease, other.prerelease - rccmp = self._nat_cmp(rc1, rc2) - - if not rccmp: - return 0 - if not rc1: - return 1 - elif not rc2: - return -1 - - return rccmp - - def next_version(self, part: str, prerelease_token: str = "rc") -> "Version": - """ - Determines next version, preserving natural order. - - .. versionadded:: 2.10.0 - - This function is taking prereleases into account. - The "major", "minor", and "patch" raises the respective parts like - the ``bump_*`` functions. The real difference is using the - "prerelease" part. It gives you the next patch version of the - prerelease, for example: - - >>> str(semver.parse("0.1.4").next_version("prerelease")) - '0.1.5-rc.1' - - :param part: One of "major", "minor", "patch", or "prerelease" - :param prerelease_token: prefix string of prerelease, defaults to 'rc' - :return: new object with the appropriate part raised - """ - cls = type(self) - # "build" is currently not used, that's why we use [:-1] - validparts = cls.NAMES[:-1] - if part not in validparts: - raise ValueError( - f"Invalid part. Expected one of {validparts}, but got {part!r}" - ) - version = self - if (version.prerelease or version.build) and ( - part == "patch" - or (part == "minor" and version.patch == 0) - or (part == "major" and version.minor == version.patch == 0) - ): - return version.replace(prerelease=None, build=None) - - # Only check the main parts: - if part in cls.NAMES[:3]: - return getattr(version, "bump_" + part)() - - if not version.prerelease: - version = version.bump_patch() - return version.bump_prerelease(prerelease_token) - - @_comparator - def __eq__(self, other: Comparable) -> bool: # type: ignore - return self.compare(other) == 0 - - @_comparator - def __ne__(self, other: Comparable) -> bool: # type: ignore - return self.compare(other) != 0 - - @_comparator - def __lt__(self, other: Comparable) -> bool: - return self.compare(other) < 0 - - @_comparator - def __le__(self, other: Comparable) -> bool: - return self.compare(other) <= 0 - - @_comparator - def __gt__(self, other: Comparable) -> bool: - return self.compare(other) > 0 - - @_comparator - def __ge__(self, other: Comparable) -> bool: - return self.compare(other) >= 0 - - def __getitem__( - self, index: Union[int, slice] - ) -> Union[int, Optional[str], Tuple[Union[int, str], ...]]: - """ - self.__getitem__(index) <==> self[index] Implement getitem. - - If the part requested is undefined, or a part of the range requested - is undefined, it will throw an index error. - Negative indices are not supported. - - :param index: a positive integer indicating the - offset or a :func:`slice` object - :raises IndexError: if index is beyond the range or a part is None - :return: the requested part of the version at position index - - >>> ver = semver.Version.parse("3.4.5") - >>> ver[0], ver[1], ver[2] - (3, 4, 5) - """ - if isinstance(index, int): - index = slice(index, index + 1) - index = cast(slice, index) - - if ( - isinstance(index, slice) - and (index.start is not None and index.start < 0) - or (index.stop is not None and index.stop < 0) - ): - raise IndexError("Version index cannot be negative") - - part = tuple( - filter(lambda p: p is not None, cast(Iterable, self.to_tuple()[index])) - ) - - if len(part) == 1: - return part[0] - elif not part: - raise IndexError("Version part undefined") - return part - - def __repr__(self) -> str: - s = ", ".join("%s=%r" % (key, val) for key, val in self.to_dict().items()) - return "%s(%s)" % (type(self).__name__, s) - - def __str__(self) -> str: - version = "%d.%d.%d" % (self.major, self.minor, self.patch) - if self.prerelease: - version += "-%s" % self.prerelease - if self.build: - version += "+%s" % self.build - return version - - def __hash__(self) -> int: - return hash(self.to_tuple()[:4]) - - def finalize_version(self) -> "Version": - """ - Remove any prerelease and build metadata from the version. - - :return: a new instance with the finalized version string - - >>> str(semver.Version.parse('1.2.3-rc.5').finalize_version()) - '1.2.3' - """ - cls = type(self) - return cls(self.major, self.minor, self.patch) - - def match(self, match_expr: str) -> bool: - """ - Compare self to match a match expression. - - :param match_expr: optional operator and version; valid operators are - ``<`` smaller than - ``>`` greater than - ``>=`` greator or equal than - ``<=`` smaller or equal than - ``==`` equal - ``!=`` not equal - :return: True if the expression matches the version, otherwise False - - >>> semver.Version.parse("2.0.0").match(">=1.0.0") - True - >>> semver.Version.parse("1.0.0").match(">1.0.0") - False - >>> semver.Version.parse("4.0.4").match("4.0.4") - True - """ - prefix = match_expr[:2] - if prefix in (">=", "<=", "==", "!="): - match_version = match_expr[2:] - elif prefix and prefix[0] in (">", "<"): - prefix = prefix[0] - match_version = match_expr[1:] - elif match_expr and match_expr[0] in "0123456789": - prefix = "==" - match_version = match_expr - else: - raise ValueError( - "match_expr parameter should be in format , " - "where is one of " - "['<', '>', '==', '<=', '>=', '!=']. " - "You provided: %r" % match_expr - ) - - possibilities_dict = { - ">": (1,), - "<": (-1,), - "==": (0,), - "!=": (-1, 1), - ">=": (0, 1), - "<=": (-1, 0), - } - - possibilities = possibilities_dict[prefix] - cmp_res = self.compare(match_version) - - return cmp_res in possibilities - - @classmethod - def parse( - cls: Type[T], version: String, optional_minor_and_patch: bool = False - ) -> T: - """ - Parse version string to a Version instance. - - .. versionchanged:: 2.11.0 - Changed method from static to classmethod to - allow subclasses. - .. versionchanged:: 3.0.0 - Added optional parameter ``optional_minor_and_patch`` to allow - optional minor and patch parts. - - :param version: version string - :param optional_minor_and_patch: if set to true, the version string to parse \ - can contain optional minor and patch parts. Optional parts are set to zero. - By default (False), the version string to parse has to follow the semver - specification. - :return: a new :class:`Version` instance - :raises ValueError: if version is invalid - :raises TypeError: if version contains the wrong type - - >>> semver.Version.parse('3.4.5-pre.2+build.4') - Version(major=3, minor=4, patch=5, \ -prerelease='pre.2', build='build.4') - """ - if isinstance(version, bytes): - version = version.decode("UTF-8") - elif not isinstance(version, String.__args__): # type: ignore - raise TypeError("not expecting type '%s'" % type(version)) - - if optional_minor_and_patch: - match = cls._REGEX_OPTIONAL_MINOR_AND_PATCH.match(version) - else: - match = cls._REGEX.match(version) - if match is None: - raise ValueError(f"{version} is not valid SemVer string") - - matched_version_parts: Dict[str, Any] = match.groupdict() - if not matched_version_parts["minor"]: - matched_version_parts["minor"] = 0 - if not matched_version_parts["patch"]: - matched_version_parts["patch"] = 0 - - return cls(**matched_version_parts) - - def replace(self, **parts: Union[int, Optional[str]]) -> "Version": - """ - Replace one or more parts of a version and return a new :class:`Version` - object, but leave self untouched. - - .. versionadded:: 2.9.0 - Added :func:`Version.replace` - - :param parts: the parts to be updated. Valid keys are: - ``major``, ``minor``, ``patch``, ``prerelease``, or ``build`` - :return: the new :class:`~semver.version.Version` object with - the changed parts - :raises TypeError: if ``parts`` contain invalid keys - """ - version = self.to_dict() - version.update(parts) - try: - return type(self)(**version) # type: ignore - except TypeError: - unknownkeys = set(parts) - set(self.to_dict()) - error = "replace() got %d unexpected keyword argument(s): %s" % ( - len(unknownkeys), - ", ".join(unknownkeys), - ) - raise TypeError(error) - - @classmethod - def is_valid(cls, version: str) -> bool: - """ - Check if the string is a valid semver version. - - .. versionadded:: 2.9.1 - - .. versionchanged:: 3.0.0 - Renamed from :meth:`~semver.version.Version.isvalid` - - :param version: the version string to check - :return: True if the version string is a valid semver version, False - otherwise. - """ - try: - cls.parse(version) - return True - except ValueError: - return False - - def is_compatible(self, other: "Version") -> bool: - """ - Check if current version is compatible with other version. - - The result is True, if either of the following is true: - - * both versions are equal, or - * both majors are equal and higher than 0. Same for both minors. - Both pre-releases are equal, or - * both majors are equal and higher than 0. The minor of b's - minor version is higher then a's. Both pre-releases are equal. - - The algorithm does *not* check patches. - - .. versionadded:: 3.0.0 - - :param other: the version to check for compatibility - :return: True, if ``other`` is compatible with the old version, - otherwise False - - >>> Version(1, 1, 0).is_compatible(Version(1, 0, 0)) - False - >>> Version(1, 0, 0).is_compatible(Version(1, 1, 0)) - True - """ - if not isinstance(other, Version): - raise TypeError(f"Expected a Version type but got {type(other)}") - - # All major-0 versions should be incompatible with anything but itself - if (0 == self.major == other.major) and (self[:4] != other[:4]): - return False - - return ( - (self.major == other.major) - and (other.minor >= self.minor) - and (self.prerelease == other.prerelease) - ) - - -#: Keep the VersionInfo name for compatibility -VersionInfo = Version From 0bf843fc2bf029e59e153770f90206f0343c5e24 Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Thu, 5 Sep 2024 16:40:23 +0300 Subject: [PATCH 02/30] remove extra code that is in the wrapper --- api.py | 78 ------------------------ assets/assets_identifiers_ws.py | 29 --------- assets/assets_snapshot.py | 58 ------------------ auth/auth_websocket.py | 23 ------- base_websocket.py | 94 ----------------------------- copilot/ask_websocket.py | 23 ------- copilot/conversation_websocket.py | 12 ---- copilot/conversations.py | 12 ---- streamed_identifiers.py | 99 ------------------------------- 9 files changed, 428 deletions(-) delete mode 100644 api.py delete mode 100644 assets/assets_identifiers_ws.py delete mode 100644 assets/assets_snapshot.py delete mode 100644 auth/auth_websocket.py delete mode 100644 base_websocket.py delete mode 100644 copilot/ask_websocket.py delete mode 100644 copilot/conversation_websocket.py delete mode 100644 copilot/conversations.py delete mode 100644 streamed_identifiers.py diff --git a/api.py b/api.py deleted file mode 100644 index 3c0acd9..0000000 --- a/api.py +++ /dev/null @@ -1,78 +0,0 @@ -from typing import Optional -import sublime -from ._pieces_lib import pieces_os_client as pos_client -from .settings import PiecesSettings -import time -import subprocess -from . import __version__ -from ._pieces_lib import semver - -PIECES_OS_MIN_VERSION = "10.0.3" # Minimum version (10.0.3) -PIECES_OS_MAX_VERSION = "11.0.0" # Maximum version (11.0.0) - -def get_version() -> Optional[str]: - """Get pieces os version return None if there is a problem""" - try: - version = pos_client.WellKnownApi(PiecesSettings.api_client).get_well_known_version() - return version - except: # There is a problem in the startup - return None - - - - -def open_pieces_os() -> Optional[str]: - """Open pieces os and return its version""" - version = get_version() - if version: - return version - # sublime.platform() -> Literal['osx', 'linux', 'windows'] - pl = sublime.platform().lower() - if pl == "windows": - subprocess.run(["start", "pieces://launch"], shell=True) - elif pl == "osx": - subprocess.run(["open","pieces://launch"]) - elif pl == "linux": - subprocess.run(["xdg-open","pieces://launch"]) - - for _ in range(2): - version = get_version() - if version: - return version - time.sleep(2) # wait for the server to open - return get_version() # pieces os version - - -def get_user(): - api_instance = pos_client.UserApi(PiecesSettings.api_client) - user = api_instance.user_snapshot().user - return user - -def version_check(): - """Check the version of the pieces os in the within range""" - pieces_os_version = get_version() - - # Parse version numbers - os_version_parsed = semver.VersionInfo.parse(pieces_os_version) - min_version_parsed = semver.VersionInfo.parse(PIECES_OS_MIN_VERSION) - max_version_parsed = semver.VersionInfo.parse(PIECES_OS_MAX_VERSION) - - # Check compatibility - if os_version_parsed >= max_version_parsed: - message = "Please make sure your Pieces Sublime Package is up-to-date. It is not compatible with the current Pieces OS version" - print() - print() - print_version_details(pieces_os_version, __version__) - sublime.message_dialog(message) - return False,"the Pieces Sublime Package" - elif os_version_parsed < min_version_parsed: - message = "Please make sure your Pieces OS is up-to-date. It is not compatible with the current Pieces package" - print(message) - print() - print_version_details(pieces_os_version, __version__) - sublime.message_dialog(message) - return False,"Pieces OS" - return True,None - -def print_version_details(pieces_os_version, __version__): - print(f"Pieces OS version: {pieces_os_version}\nPlugin version: {__version__}") diff --git a/assets/assets_identifiers_ws.py b/assets/assets_identifiers_ws.py deleted file mode 100644 index 6ef120c..0000000 --- a/assets/assets_identifiers_ws.py +++ /dev/null @@ -1,29 +0,0 @@ -from .._pieces_lib.pieces_os_client import StreamedIdentifiers,StreamedIdentifier,ReferencedAsset,AssetsApi -import threading -import sublime - -from ..settings import PiecesSettings -from ..base_websocket import BaseWebsocket - -class AssetsIdentifiersWS(BaseWebsocket): - @property - def url(self): - return PiecesSettings.ASSETS_IDENTIFIERS_WS_URL - - def on_message(self,ws, message): - self.on_message_callback(StreamedIdentifiers.from_json(message)) - - def on_error(self,ws,error): # Some issues with the dns so we need to warn the user the websocket is not running - if type(error) == OSError: - iterable = AssetsApi(PiecesSettings.api_client).assets_identifiers_snapshot().iterable - streamed_idetifiers = StreamedIdentifiers( - iterable = [ - StreamedIdentifier(asset = ReferencedAsset(id = asset.id)) for asset in iterable - ] - ) - self.on_message_callback(streamed_idetifiers) - sublime.message_dialog( - "Warning: The Pieces package is unable to connect to the websocket.\n" - "As a result, assets and certain functionalities will not be updated in real-time." - ) - print(error) \ No newline at end of file diff --git a/assets/assets_snapshot.py b/assets/assets_snapshot.py deleted file mode 100644 index 61053ec..0000000 --- a/assets/assets_snapshot.py +++ /dev/null @@ -1,58 +0,0 @@ -from typing import Optional -import sublime - - -from ..streamed_identifiers import StreamedIdentifiersCache -from .._pieces_lib.pieces_os_client import (Asset, - AssetApi, - ClassificationSpecificEnum, - FormatApi, - ClassificationGenericEnum) -from ..settings import PiecesSettings - -class AssetSnapshot(StreamedIdentifiersCache, - api_call=AssetApi(PiecesSettings.api_client).asset_snapshot): - def __init__(self,asset_id) -> None: - self._asset_id = asset_id - self.asset = self.get_asset(asset_id) - super().__init__() - - @classmethod - def get_asset(cls,asset_id) -> Optional[Asset]: - return cls.identifiers_snapshot.get(asset_id) - - def original_classification_specific(self) -> Optional[ClassificationSpecificEnum]: - if self.asset: - return self.asset.original.reference.classification.specific - - def edit_asset_original_format(self,data) -> None: - if not self.asset: - raise AttributeError("Asset not found") - format_api = FormatApi(PiecesSettings.api_client) - original = format_api.format_snapshot(self.asset.original.id, transferable=True) - if original.classification.generic == ClassificationGenericEnum.IMAGE: - # TODO: Ability to edit images - sublime.error_message("Could not edit an image") - return - - if original.fragment.string.raw: - original.fragment.string.raw = data - elif original.file.string.raw: - original.file.string.raw = data - format_api.format_update_value(transferable=False, format=original) - - def get_asset_raw(self) -> Optional[str]: - if not self.asset: - return - asset_reference = self.asset.original.reference - if asset_reference.fragment: - return asset_reference.fragment.string.raw - elif asset_reference.file.string: - return asset_reference.file.string.raw - @property - def name(self) -> Optional[str]: - return self.asset.name if self.asset else None - - @staticmethod - def sort_first_shot(): - pass \ No newline at end of file diff --git a/auth/auth_websocket.py b/auth/auth_websocket.py deleted file mode 100644 index e1af15c..0000000 --- a/auth/auth_websocket.py +++ /dev/null @@ -1,23 +0,0 @@ -from ..base_websocket import BaseWebsocket -from ..settings import PiecesSettings -from .._pieces_lib.pieces_os_client import UserProfile,UserApi -import threading -import json - - -class AuthWebsocket(BaseWebsocket): - @property - def url(self): - return PiecesSettings.AUTH_WS_URL - - def on_message(self,ws, message): - try: - self.on_message_callback(UserProfile.from_json(message)) - except json.decoder.JSONDecodeError: - self.on_message_callback(None) # User logged out! - - def on_error(self,ws,error): - if type(error) == OSError: # Some issues with the dns so we need to warn the user the websocket is not running - returned_user = UserApi(PiecesSettings.api_client).user_snapshot() - self.on_message_callback(getattr(returned_user,"user",None)) - print(error) \ No newline at end of file diff --git a/base_websocket.py b/base_websocket.py deleted file mode 100644 index e184b26..0000000 --- a/base_websocket.py +++ /dev/null @@ -1,94 +0,0 @@ -from typing import Optional -from ._pieces_lib.typing_extensions import Self -from ._pieces_lib import websocket -import threading -from abc import ABC, abstractmethod - -class BaseWebsocket(ABC): - instances = [] - def __new__(cls,*args,**kwargs): - if not hasattr(cls, 'instance'): - cls.instance = super(BaseWebsocket, cls).__new__(cls) - return cls.instance - - def __init__(self, on_message_callback,on_open_callbacks=[]): - self.ws = None - self.thread = None - self.running = False - self.on_message_callback = on_message_callback - self.on_open_callbacks = on_open_callbacks - - if self not in BaseWebsocket.instances: - BaseWebsocket.instances.append(self) - - @abstractmethod - def url(self) -> str: - """The URL to connect to. Should be overridden.""" - pass - - - @abstractmethod - def on_message(self, ws, message): - pass - - def on_error(self, ws, error): - print(f"Error: {error}") - - def on_close(self, ws, close_status_code, close_msg): - pass - - def on_open(self, ws): - self.running = True - for callback in self.on_open_callbacks: - callback() - - def run(self): - self.ws = websocket.WebSocketApp( - self.url, - on_message=self.on_message, - on_error=self.on_error, - on_close=self.on_close, - on_open=self.on_open - ) - self.ws.run_forever() - - def start(self): - if not self.running: - self.thread = threading.Thread(target=self.run) - self.thread.start() - - def close(self): - if self.running: - self.ws.close() - self.thread.join() - self.running = False - - @classmethod - def close_all(cls): - for instance in cls.instances: - instance.close() - - @classmethod - def reconnect_all(cls): - """Reconnect all websocket instances.""" - for instance in cls.instances: - instance.reconnect() - - def reconnect(self): - """Reconnect the websocket connection.""" - self.close() - self.start() - - def __str__(self): - return getattr(self, "url", self.instances) - - @classmethod - def is_running(cls) -> bool: - instance = cls.get_instance() - if instance: - return cls.instance.running - return False - - @classmethod - def get_instance(cls) -> Optional[Self]: - return getattr(cls,'instance',None) \ No newline at end of file diff --git a/copilot/ask_websocket.py b/copilot/ask_websocket.py deleted file mode 100644 index fd75f4c..0000000 --- a/copilot/ask_websocket.py +++ /dev/null @@ -1,23 +0,0 @@ -from .._pieces_lib.pieces_os_client import QGPTStreamOutput,QGPTStreamInput -from .._pieces_lib.websocket import WebSocketConnectionClosedException - -from ..settings import PiecesSettings -from ..base_websocket import BaseWebsocket - -class AskStreamWS(BaseWebsocket): - @property - def url(self): - return PiecesSettings.ASK_STREAM_WS_URL - - def on_message(self,ws, message): - self.on_message_callback(QGPTStreamOutput.from_json(message)) - - - def send_message(self,message:QGPTStreamInput): - try: - if not self.ws: - raise WebSocketConnectionClosedException() - self.ws.send(message.to_json()) - except WebSocketConnectionClosedException: - self.on_open = lambda ws: ws.send(message.to_json()) # Send the message on opening - self.start() # Start a new websocket since we are not connected to any \ No newline at end of file diff --git a/copilot/conversation_websocket.py b/copilot/conversation_websocket.py deleted file mode 100644 index 338100d..0000000 --- a/copilot/conversation_websocket.py +++ /dev/null @@ -1,12 +0,0 @@ -from .._pieces_lib.pieces_os_client import StreamedIdentifiers - -from ..settings import PiecesSettings -from ..base_websocket import BaseWebsocket - -class ConversationWS(BaseWebsocket): - @property - def url(self): - return PiecesSettings.CONVERSATION_WS_URL - - def on_message(self,ws, message): - self.on_message_callback(StreamedIdentifiers.from_json(message)) diff --git a/copilot/conversations.py b/copilot/conversations.py deleted file mode 100644 index 42dfd89..0000000 --- a/copilot/conversations.py +++ /dev/null @@ -1,12 +0,0 @@ -from ..streamed_identifiers import StreamedIdentifiersCache -from ..settings import PiecesSettings -from .._pieces_lib.pieces_os_client import ConversationApi - -class ConversationsSnapshot(StreamedIdentifiersCache, - api_call=ConversationApi(PiecesSettings.api_client).conversation_get_specific_conversation): - - @classmethod - def sort_first_shot(cls): - # Sort the dictionary by the "updated" timestamp - sorted_conversations = sorted(cls.identifiers_snapshot.values(), key=lambda x: x.updated.value, reverse=True) - cls.identifiers_snapshot = {conversation.id:conversation for conversation in sorted_conversations} \ No newline at end of file diff --git a/streamed_identifiers.py b/streamed_identifiers.py deleted file mode 100644 index 8261fa4..0000000 --- a/streamed_identifiers.py +++ /dev/null @@ -1,99 +0,0 @@ -""" -A class for caching Streamed Identifiers. This class is designed to be inherited. - -Attributes: - identifiers_snapshot (Dict[str, Union[Asset, Conversation]]): A dictionary mapping IDs to their corresponding API call results. - identifiers_queue (queue.Queue): A queue for IDs to be processed. - identifiers_set (set): A set for IDs currently in the queue. - api_call (Callable[[str], Union[Asset, Conversation]]): A callable that takes an ID and returns either an Asset or a Conversation. - block (bool): A flag to indicate whether to wait for the queue to receive the first ID. - first_shot (bool): A flag to indicate if it's the first time to open the websocket. - lock (threading.Lock): A lock for thread safety. - worker_thread (threading.Thread): A thread for processing the queue. - -Methods: - worker(): Continuously processes IDs from the queue and updates the identifiers_snapshot. - update_identifier(id: str): Updates the identifier snapshot with the result of the API call. - streamed_identifiers_callback(ids: StreamedIdentifiers): Callback method to handle streamed identifiers. - -Example: - class AssetSnapshot(StreamedIdentifiersCache,api_call=AssetApi(PiecesSettings.api_client).asset_snapshot): - pass -""" - -import queue -from typing import Dict, Union, Callable -from ._pieces_lib.pieces_os_client import Conversation, StreamedIdentifiers, Asset -import sublime -from abc import ABC,abstractmethod - - -class StreamedIdentifiersCache(ABC): - """ - This class is made for caching Streamed Identifiers. - Please use this class only as a parent class. - """ - - def __init_subclass__(cls, api_call: Callable[[str], Union[Asset, Conversation]], **kwargs): - super().__init_subclass__(**kwargs) - cls.identifiers_snapshot: Dict[str, Union[Asset, Conversation,None]] = {} # Map id:return from the api_call - cls.identifiers_queue = queue.Queue() # Queue for ids to be processed - cls.identifiers_set = set() # Set for ids in the queue - cls.api_call = api_call - cls.block = True # to wait for the queue to receive the first id - cls.first_shot = True # First time to open the websocket or not - - - @abstractmethod - def sort_first_shot(): - """ - Sorting algrothim in the first shot - """ - pass - - @classmethod - def worker(cls): - while True: - try: - id = cls.identifiers_queue.get(block=cls.block, timeout=5) - cls.identifiers_set.remove(id) # Remove the id from the set - cls.update_identifier(id) - cls.identifiers_queue.task_done() - except queue.Empty: # queue is empty and the block is false - if cls.block: - continue # if there are more ids to load - - if cls.first_shot: - cls.first_shot = False - cls.sort_first_shot() - - return # End the worker - - @classmethod - def update_identifier(cls, identifier: str): - try: - id_value = cls.api_call(identifier) - cls.identifiers_snapshot[identifier] = id_value - return id_value - except: - return None - - @classmethod - def streamed_identifiers_callback(cls, ids: StreamedIdentifiers): - # Start the worker thread if it's not running - cls.block = True - sublime.set_timeout_async(cls.worker) - for item in ids.iterable: - reference_id = item.asset.id if item.asset else item.conversation.id # Get either the conversation or the asset - - if reference_id not in cls.identifiers_set: - if item.deleted: - # Asset deleted - cls.identifiers_snapshot.pop(reference_id, None) - else: - if reference_id not in cls.identifiers_snapshot and not cls.first_shot: - cls.identifiers_snapshot = {reference_id: None, **cls.identifiers_snapshot} - cls.identifiers_queue.put(reference_id) # Add id to the queue - cls.identifiers_set.add(reference_id) # Add id to the set - - cls.block = False # Remove the block to end the thread \ No newline at end of file From dd41001798a7f8025f028bf1dfe6b3e498161a30 Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Thu, 5 Sep 2024 16:41:03 +0300 Subject: [PATCH 03/30] add the init_host method to the client --- .../pieces_os_client/wrapper/client.py | 51 ++++++++++--------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/_pieces_lib/pieces_os_client/wrapper/client.py b/_pieces_lib/pieces_os_client/wrapper/client.py index 257a939..92e81e5 100644 --- a/_pieces_lib/pieces_os_client/wrapper/client.py +++ b/_pieces_lib/pieces_os_client/wrapper/client.py @@ -20,6 +20,7 @@ WellKnownApi, OSApi, AllocationsApi, + SearchApi, __version__ ) from typing import Optional,Dict @@ -40,9 +41,32 @@ def __init__(self, host:str="", seeded_connector: Optional[SeededConnectorConnec else: self.host = "http://localhost:5323" if 'Linux' in platform.platform() else "http://localhost:1000" + self.init_host(self.host) + self.local_os = platform.system().upper() if platform.system().upper() in ["WINDOWS","LINUX","DARWIN"] else "WEB" + self.local_os = "MACOS" if self.local_os == "DARWIN" else self.local_os + seeded_connector = seeded_connector or SeededConnectorConnection( + application=SeededTrackedApplication( + name = "OPEN_SOURCE", + platform = self.local_os, + version = __version__)) + + self.tracked_application = self.connector_api.connect(seeded_connector_connection=seeded_connector).application - self.api_client = ApiClient(Configuration(self.host)) + self.user = BasicUser(self) + if kwargs.get("connect_wesockets",True): + self.conversation_ws = ConversationWS(self) + self.assets_ws = AssetsIdentifiersWS(self) + self.user_websocket = AuthWS(self,self.user.on_user_callback) + # Start all initilized websockets + BaseWebsocket.start_all() + + self.models = None + self.model_name = "GPT-3.5-turbo Chat Model" + self.copilot = Copilot(self) + + def init_host(self,host): + self.api_client = ApiClient(Configuration(host)) self.conversation_message_api = ConversationMessageApi(self.api_client) self.conversation_messages_api = ConversationMessagesApi(self.api_client) self.conversations_api = ConversationsApi(self.api_client) @@ -59,6 +83,7 @@ def __init__(self, host:str="", seeded_connector: Optional[SeededConnectorConnec self.os_api = OSApi(self.api_client) self.allocations_api = AllocationsApi(self.api_client) self.linkfy_api = LinkifyApi(self.api_client) + self.search_api = SearchApi(self.api_client) # Websocket urls if not self.host.startswith("http"): @@ -71,30 +96,6 @@ def __init__(self, host:str="", seeded_connector: Optional[SeededConnectorConnec self.CONVERSATION_WS_URL = ws_base_url + "/conversations/stream/identifiers" self.HEALTH_WS_URL = ws_base_url + "/.well-known/stream/health" - self.local_os = platform.system().upper() if platform.system().upper() in ["WINDOWS","LINUX","DARWIN"] else "WEB" - self.local_os = "MACOS" if self.local_os == "DARWIN" else self.local_os - seeded_connector = seeded_connector or SeededConnectorConnection( - application=SeededTrackedApplication( - name = "OPEN_SOURCE", - platform = self.local_os, - version = __version__)) - - self.tracked_application = self.connector_api.connect(seeded_connector_connection=seeded_connector).application - - self.user = BasicUser(self) - - if kwargs.get("connect_wesockets",True): - self.conversation_ws = ConversationWS(self) - self.assets_ws = AssetsIdentifiersWS(self) - self.user_websocket = AuthWS(self,self.user.on_user_callback) - # Start all initilized websockets - BaseWebsocket.start_all() - - self.models = None - self.model_name = "GPT-3.5-turbo Chat Model" - self.copilot = Copilot(self) - - def assets(self): self.ensure_initialization() return [BasicAsset(id) for id in AssetSnapshot.identifiers_snapshot.keys()] From 74bc95d906334ad1ae02b947c98dd0fd395116ad Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Thu, 5 Sep 2024 16:41:06 +0300 Subject: [PATCH 04/30] Delete health_ws.py --- health_ws.py | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 health_ws.py diff --git a/health_ws.py b/health_ws.py deleted file mode 100644 index 38f3563..0000000 --- a/health_ws.py +++ /dev/null @@ -1,19 +0,0 @@ -from .settings import PiecesSettings -from .base_websocket import BaseWebsocket - -class HealthWS(BaseWebsocket): - def __init__(self): - super().__init__(lambda:None, []) - - @property - def url(self): - return PiecesSettings.HEALTH_WS_URL - - def on_message(self,ws, message): - if message == "OK": - PiecesSettings.is_loaded = True - else: - PiecesSettings.is_loaded = False - - def on_close(self, ws, close_status_code, close_msg): - PiecesSettings.is_loaded = False # the websocket is closed From 03b6c69de3646c1297fa38a76c85e68e2d8258a7 Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Thu, 5 Sep 2024 16:41:17 +0300 Subject: [PATCH 05/30] refactor main.py --- main.py | 85 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 43 insertions(+), 42 deletions(-) diff --git a/main.py b/main.py index 5f6c6e3..2f61431 100644 --- a/main.py +++ b/main.py @@ -1,9 +1,9 @@ from . import __version__ -from .api import open_pieces_os,print_version_details,version_check from .settings import PiecesSettings from .copilot.ask_command import copilot -from .health_ws import HealthWS import sublime +from ._pieces_lib.pieces_os_client.wrapper.version_compatibility import VersionChecker,UpdateEnum +from ._pieces_lib.pieces_os_client.wrapper.websockets import BaseWebsocket,AuthWS,HealthWS # load the commands from .assets import * @@ -12,63 +12,64 @@ from .search import * from .misc import * from .copilot import * -from .base_websocket import BaseWebsocket - - -def startup(settings_model): - pieces_version = None - if PiecesSettings.get_settings().get("auto_start_pieces_os"): - pieces_version = open_pieces_os() - - - if not pieces_version: - print("Couldn't start pieces OS\nPlease run Pieces OS and restart the editor to ensure everything is running properly") +PIECES_OS_MIN_VERSION = "10.1.5" # Minimum version (10.0.3) +PIECES_OS_MAX_VERSION = "11.0.0" # Maximum version (11.0.0) + + +def startup(): + pieces_os_version = PiecesSettings.api_client.version + version_result = VersionChecker(PIECES_OS_MIN_VERSION,PIECES_OS_MAX_VERSION,pieces_os_version).version_check() + if version_result.compatible: + print(f"Pieces OS version: {pieces_os_version}\nPlugin version: {__version__}") + PiecesSettings.models_init(PiecesSettings.get_settings().get('model')) # Intilize the models + else: + if version_result.update == UpdateEnum.PiecesOS: + update = "Pieces OS" + else: + update = "Pieces Sublime Plugin" + sublime.message_dialog(f"{update} is outdated. Can you please update {update}") + PiecesSettings.is_loaded = False + BaseWebsocket.close_all() return - else: - if version_check()[0]: - PiecesSettings.is_loaded = True - PiecesSettings.compatible = True - PiecesSettings.get_application() - print_version_details(pieces_version, __version__) - PiecesSettings.models_init(settings_model) # Intilize the models - else: return - - - # WEBSOCKETS: - # Assets Identifiers Websocket - AssetsIdentifiersWS(AssetSnapshot.streamed_identifiers_callback).start() # Load the assets ws at the startup # User Weboscket PiecesSettings.create_auth_output_panel() - - AuthWebsocket(AuthUser.on_user_callback).start() # Load the stream user websocket - - # Conversation Websocket - ConversationWS(ConversationsSnapshot.streamed_identifiers_callback).start() - - # Health websocket - HealthWS().start() + auth_ws = AuthWS.get_instance() + auth_ws.on_message_callback = AuthUser.on_user_callback # Lunch Onboarding if it is the first time if not PiecesOnboardingCommand.get_onboarding_settings().get("lunch_onboarding",False): sublime.active_window().run_command("pieces_onboarding") PiecesOnboardingCommand.add_onboarding_settings(lunch_onboarding=True) -def plugin_loaded(): - global settings # Set it to global to use +def on_message(message): + if message == "OK": + PiecesSettings.is_loaded = True + else: + PiecesSettings.is_loaded = False + print("Please make sure Pieces OS is running\n") + +def on_close(ws): + PiecesSettings.is_loaded = False - settings = sublime.load_settings('Pieces.sublime-settings') +def plugin_loaded(): + settings = PiecesSettings.get_settings() host = settings.get("host") - model = settings.get('model') - settings.add_on_change("PIECES_SETTINGS",PiecesSettings.on_settings_change) - PiecesSettings.host_init(host) # Intilize the hosts url + PiecesSettings.host_init(host) # Intilize the hosts url # callbacks needed onchange settings PiecesSettings.on_model_change_callbacks.append(copilot.update_status_bar) + health = PiecesSettings.api_client.health + if PiecesSettings.get_settings().get("auto_start_pieces_os") and not health: + health = PiecesSettings.api_client.open_pieces_os() + + if health: + HealthWS(PiecesSettings.api_client, on_message, startup, on_close).start() + else: + print("Couldn't start pieces OS\nPlease run Pieces OS and restart the editor to ensure everything is running properly") + BaseWebsocket.close_all() - sublime.set_timeout_async(lambda : startup(model) ,0) - def plugin_unloaded(): BaseWebsocket.close_all() From 30901301f84c67939ba1691873a0017a87300f7c Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Thu, 5 Sep 2024 16:41:27 +0300 Subject: [PATCH 06/30] refactor settings.py --- settings.py | 98 +++++++++-------------------------------------------- 1 file changed, 16 insertions(+), 82 deletions(-) diff --git a/settings.py b/settings.py index 21b104c..1e43960 100644 --- a/settings.py +++ b/settings.py @@ -1,6 +1,7 @@ -from ._pieces_lib import pieces_os_client as pos_client +from ._pieces_lib.pieces_os_client import SeededConnectorConnection,SeededTrackedApplication +from ._pieces_lib.pieces_os_client.wrapper.websockets.base_websocket import BaseWebsocket +from ._pieces_lib.pieces_os_client.wrapper import PiecesClient import sublime -from typing import Dict import os from . import __version__ @@ -9,21 +10,18 @@ class PiecesSettings: # Initialize class variables - application = None - models = None - host = "" - model_name = "" - api_client = None + api_client = PiecesClient(seeded_connector= SeededConnectorConnection( + application=SeededTrackedApplication( + name = "SUBLIME", + platform = sublime.platform().upper() if sublime.platform() != 'osx' else "MACOS", + version = __version__))) is_loaded = False # is the plugin loaded - compatible = False # compatible? ONBOARDING_SYNTAX = "Packages/Pieces/syntax/Onboarding.sublime-syntax" - - on_model_change_callbacks = [] # If the model change a function should be runned + on_model_change_callbacks = [] # If the model change a function should be runned PIECES_USER_DIRECTORY = os.path.join(sublime.packages_path(),"User","Pieces") - autocomplete_snippet:bool = True # Create the pieces directory to store the data if it does not exists @@ -31,21 +29,6 @@ class PiecesSettings: os.makedirs(PIECES_USER_DIRECTORY) - @classmethod - def get_health(cls): - """ - Retrieves the health status from the WellKnownApi and returns True if the health is 'ok', otherwise returns False. - - Returns: - bool: True if the health status is 'ok', False otherwise. - """ - try: - health = pos_client.WellKnownApi(cls.api_client).get_well_known_health() - return health == "ok" - except: - return False - - @classmethod def host_init(cls,host): """ @@ -54,26 +37,9 @@ def host_init(cls,host): This method sets the host URL based on the configuration settings. If the host URL is not provided in the settings, it defaults to a specific URL based on the platform. It then creates the WebSocket base URL and defines the WebSocket URLs for different API endpoints. """ - cls.host = host - if not host: - if 'linux' == sublime.platform(): - cls.host = "http://127.0.0.1:5323" - else: - cls.host = "http://127.0.0.1:1000" - - # Websocket urls - ws_base_url = cls.host.replace('http','ws') - cls.ASSETS_IDENTIFIERS_WS_URL = ws_base_url + "/assets/stream/identifiers" - cls.AUTH_WS_URL = ws_base_url + "/user/stream" - cls.ASK_STREAM_WS_URL = ws_base_url + "/qgpt/stream" - cls.CONVERSATION_WS_URL = ws_base_url + "/conversations/stream/identifiers" - cls.HEALTH_WS_URL = ws_base_url + "/.well-known/stream/health" - - configuration = pos_client.Configuration(host=cls.host) - - cls.api_client = pos_client.ApiClient(configuration) - - + if host != cls.api_client.host: + cls.api_client.init_host(host) + BaseWebsocket.reconnect_all() @classmethod @@ -85,7 +51,7 @@ def models_init(cls,model): and defaults to a specific model ("GPT-3.5-turbo Chat Model") if the specified model is not found. """ - models = cls.get_models_ids() + models = cls.api_client.get_models() cls.model_name = model cls.model_id = models.get(str(cls.model_name)) @@ -100,10 +66,10 @@ def on_settings_change(cls,all = False): all parameter means to update everything not the changes """ settings = cls.get_settings() - cls.autocomplete_snippet = settings.get("snippet.autocomplete",True) + cls.autocomplete_snippet = bool(settings.get("snippet.autocomplete",True)) host = settings.get('host') model = settings.get("model") - if cls.host != host or all: + if cls.api_client.host != host or all: cls.host_init(host = host) cls.models_init(model = model) @@ -114,37 +80,6 @@ def on_settings_change(cls,all = False): def get_settings(): return sublime.load_settings("Pieces.sublime-settings") # Reload the settings - - @classmethod - def get_application(cls)-> pos_client.Application: - if cls.application: - return cls.application - - # Decide if it's Windows, Mac, Linux or Web - api_instance = pos_client.ConnectorApi(cls.api_client) - seeded_connector_connection = pos_client.SeededConnectorConnection( - application=pos_client.SeededTrackedApplication( - name = "SUBLIME", - platform = sublime.platform().upper() if sublime.platform() != 'osx' else "MACOS", - version = __version__)) - api_response = api_instance.connect(seeded_connector_connection=seeded_connector_connection) - cls.application = api_response.application - return cls.application - - @classmethod - def get_models_ids(cls) -> Dict[str, str]: - if cls.models: - return cls.models - - api_instance = pos_client.ModelsApi(cls.api_client) - - api_response = api_instance.models_snapshot() - cls.models = {model.name: model.id for model in api_response.iterable if model.cloud or model.downloaded} # getting the models that are available in the cloud or is downloaded - - - return cls.models - - @classmethod def create_auth_output_panel(cls): window = sublime.active_window() @@ -153,8 +88,7 @@ def create_auth_output_panel(cls): cls.output_panel.settings().set("gutter", False) cls.output_panel.set_read_only(True) - - # Load the settings from 'Pieces.sublime-settings' file using Sublime Text API pieces_settings = sublime.load_settings('Pieces.sublime-settings') pieces_settings.add_on_change("PIECES_SETTINGS",on_settings_change) + From db15208bac770d09a890ff3deae30c207c58893e Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Thu, 5 Sep 2024 16:41:40 +0300 Subject: [PATCH 07/30] refactor snippets details autocomplete --- snippet_details_autocomplete.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/snippet_details_autocomplete.py b/snippet_details_autocomplete.py index f0d5c27..86fa427 100644 --- a/snippet_details_autocomplete.py +++ b/snippet_details_autocomplete.py @@ -1,13 +1,13 @@ +from ._pieces_lib.pieces_os_client.wrapper.basic_identifier.asset import BasicAsset import sublime_plugin import mdpopups -from .assets.assets_snapshot import AssetSnapshot -from .assets.list_assets import PiecesAssetIdInputHandler + class PiecesShowCompletionDetailsCommand(sublime_plugin.TextCommand): def run(self,edit,asset_id): - asset_wrapper = AssetSnapshot(asset_id) - lang = asset_wrapper.original_classification_specific().value - content = asset_wrapper.get_asset_raw() - details = PiecesAssetIdInputHandler.get_annotation(asset_wrapper.asset) + asset_wrapper = BasicAsset(asset_id) + lang = asset_wrapper.classification.value if asset_wrapper.classification else "txt" + content = asset_wrapper.raw_content + details = asset_wrapper.description mdpopups.show_popup( self.view, f"{details.text if details else ''}\n```{lang}\n{content}\n```",max_width=900, From 62cbbc3fe276e592f7091e8eca60498dc6e09dc3 Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Thu, 5 Sep 2024 16:41:47 +0300 Subject: [PATCH 08/30] refactor searching --- search/search_command.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/search/search_command.py b/search/search_command.py index 0edf1bf..9b1c758 100644 --- a/search/search_command.py +++ b/search/search_command.py @@ -1,12 +1,11 @@ import sublime_plugin import sublime +from typing import List, Optional from ..settings import PiecesSettings -from ..assets.assets_snapshot import AssetSnapshot from ..assets.list_assets import PiecesAssetIdInputHandler -from .._pieces_lib.pieces_os_client import SearchApi,AssetsApi - +from .._pieces_lib.pieces_os_client.wrapper.basic_identifier import BasicAsset @@ -25,18 +24,24 @@ def preview(self,text): return result = PiecesSearchCommand.search(SearchTypeInputHandler.search_type,query = text) if result: - names_html = [f"
  • {asset.name}
  • " for id,asset in result.items()] + names_html = [] + for asset in result: + try: + names_html.append(f"
  • {asset.name}
  • ") + except ValueError: # Asset id is not valid + pass return sublime.Html(f"""

    Asset Matches:

      {"".join(names_html)}
    """) def next_input(self,args): result = PiecesSearchCommand.search(**args) if not result: # No results just set the status - sublime.active_window().active_view().set_status('Pieces Search', 'No matches found.') - return + view = sublime.active_window().active_view() + if view: + view.set_status('Pieces Search', 'No matches found.') + return return PiecesAssetIdExtendInputHandler(result) # get a choose menu of the assets found - @@ -44,8 +49,7 @@ class SearchTypeInputHandler(sublime_plugin.ListInputHandler): def list_items(self): return [ ("Neural Code Search","ncs"), - ("Full Text Search", "fts"), - ("Fuzzy Search", "assets") + ("Full Text Search", "fts") ] def next_input(self,args): SearchTypeInputHandler.search_type = args["search_type"] # used in the preview @@ -59,17 +63,14 @@ def run(self,search_type,query,pieces_asset_id=None): return self.window.run_command("pieces_list_assets",args={"pieces_asset_id":pieces_asset_id}) @staticmethod - def search(search_type,query)-> list: - if search_type == 'assets': - api_instance = AssetsApi(PiecesSettings.api_client) - results = api_instance.assets_search_assets(query=query, transferables=False) - elif search_type == 'ncs': - api_instance = SearchApi(PiecesSettings.api_client) + def search(search_type,query)-> Optional[List[BasicAsset]]: + api_instance = PiecesSettings.api_client.search_api + if search_type == 'ncs': results = api_instance.neural_code_search(query=query) elif search_type == 'fts': - api_instance = SearchApi(PiecesSettings.api_client) results = api_instance.full_text_search(query=query) # Check and extract asset IDs from the results + if results: # Extract the iterable which contains the search results iterable_list = results.iterable if hasattr(results, 'iterable') else [] @@ -85,8 +86,7 @@ def search(search_type,query)-> list: # Print the combined asset details if combined_ids: - identifiers_snapshot = AssetSnapshot.identifiers_snapshot - return {id:identifiers_snapshot.get(id) for id in combined_ids if identifiers_snapshot.get(id)} + return [BasicAsset(id) for id in combined_ids] def is_enabled(self): return PiecesSettings.is_loaded From 7a994bddc860e8bec7e6bb07c8947fd79a1537df Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Thu, 5 Sep 2024 16:42:01 +0300 Subject: [PATCH 09/30] refactor event_listener --- auth/auth_user.py | 4 +++- event_listener.py | 33 ++++++++++++--------------------- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/auth/auth_user.py b/auth/auth_user.py index 57492de..953302b 100644 --- a/auth/auth_user.py +++ b/auth/auth_user.py @@ -1,6 +1,7 @@ from .._pieces_lib.pieces_os_client import UserProfile from ..settings import PiecesSettings import sublime +from typing import Optional CONNECTING_HTML = "

    Cloud Status: • Connecting

    " @@ -18,7 +19,8 @@ def create_new_phantom(cls,html): sublime.Region(0, 0), html, sublime.LAYOUT_INLINE) @classmethod - def on_user_callback(cls,user:UserProfile=None): + def on_user_callback(cls,user:Optional[UserProfile]=None): + PiecesSettings.api_client.user.on_user_callback(user) sublime.active_window().focus_view(PiecesSettings.output_panel) cls.user_profile = user if not user: diff --git a/event_listener.py b/event_listener.py index 6bc520e..8299df1 100644 --- a/event_listener.py +++ b/event_listener.py @@ -1,14 +1,12 @@ import sublime import sublime_plugin +from ._pieces_lib.pieces_os_client.wrapper.basic_identifier.asset import BasicAsset from .assets.list_assets import PiecesListAssetsCommand from .assets.ext_map import file_map -from .assets.assets_snapshot import AssetSnapshot from .settings import PiecesSettings from .misc import PiecesOnboardingCommand from .copilot.ask_command import copilot -from .copilot.ask_view import CopilotViewManager -from .copilot.conversation_websocket import ConversationWS file_map_reverse = {v:k for k,v in file_map.items()} @@ -48,8 +46,8 @@ def on_pre_close(self,view): sheet_id = view.settings().get("pieces_sheet_id","") if sheet_id in PiecesListAssetsCommand.sheets_md: asset_id = PiecesListAssetsCommand.sheets_md[sheet_id] - asset_wrapper = AssetSnapshot(asset_id) - code = asset_wrapper.get_asset_raw() + asset_wrapper = BasicAsset(asset_id) + code = asset_wrapper.raw_content data = view.substr(sublime.Region(0, view.size())) if data != code: @@ -98,15 +96,9 @@ def on_init(self,views): if view.settings().get("PIECES_GPT_VIEW"): # Update the conversation to be real-time # Close the old view and rerender the conversation - conversation = view.settings().get("conversation_id") - if conversation: - on_open = lambda: view.close(lambda x:copilot.render_conversation(conversation)) # Wait some sec until the conversations is loaded - if ConversationWS.is_running(): - on_open() # Run the command if it is running already - else: - instance = ConversationWS.get_instance() - if instance: - instance.on_open_callbacks.append(on_open) + view.close() + + @staticmethod def on_deactivated(view): copilot.secondary_view = view @@ -117,16 +109,15 @@ def on_query_completions(self, view:sublime.View, prefix, locations): return classification_enum = file_map_reverse.get(syntax.path) out = [] - for asset_id in AssetSnapshot.identifiers_snapshot: - asset_wrapper = AssetSnapshot(asset_id) - if asset_wrapper.original_classification_specific() == classification_enum: - content = asset_wrapper.get_asset_raw() + for asset in PiecesSettings.api_client.assets(): + if asset.classification == classification_enum: + content = asset.raw_content - if prefix.lower() in asset_wrapper.name.lower().replace(" ","") and prefix != "": - href = sublime.command_url("pieces_show_completion_details",{"asset_id":asset_wrapper._asset_id}) + if prefix.lower() in asset.name.lower().replace(" ","") and prefix != "" and content: + href = sublime.command_url("pieces_show_completion_details",{"asset_id":asset.id}) out.append( sublime.CompletionItem( - asset_wrapper.name, + asset.name, annotation="Pieces", completion=content, kind=sublime.KIND_SNIPPET, From 68f46b783f745bf729cedf724c3be5af855247af Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Thu, 5 Sep 2024 16:50:47 +0300 Subject: [PATCH 10/30] refactor misc commands --- main.py | 1 + misc/about_command.py | 4 ++-- misc/onboarding_command.py | 32 ++------------------------------ misc/open_pieces_command.py | 11 +++++++---- misc/reload_command.py | 4 ++-- settings.py | 3 +-- 6 files changed, 15 insertions(+), 40 deletions(-) diff --git a/main.py b/main.py index 2f61431..8cfb816 100644 --- a/main.py +++ b/main.py @@ -45,6 +45,7 @@ def startup(): def on_message(message): if message == "OK": + PiecesSettings.health = message PiecesSettings.is_loaded = True else: PiecesSettings.is_loaded = False diff --git a/misc/about_command.py b/misc/about_command.py index 6edb7c0..f09fe4d 100644 --- a/misc/about_command.py +++ b/misc/about_command.py @@ -1,8 +1,8 @@ +from settings import PiecesSettings import sublime import sublime_plugin import mdpopups from .. import __version__ -from ..api import get_version md_text = f""" @@ -27,7 +27,7 @@ ## Version - Plugin Version: {__version__} -- Pieces Version: {get_version() if get_version() else "Unknown"} +- Pieces Version: {PiecesSettings.api_client.version if PiecesSettings.api_client.version else "Unknown"} """ class PiecesAboutCommand(sublime_plugin.WindowCommand): def run(self): diff --git a/misc/onboarding_command.py b/misc/onboarding_command.py index c03405f..ea16837 100644 --- a/misc/onboarding_command.py +++ b/misc/onboarding_command.py @@ -6,7 +6,6 @@ import json from ..settings import PiecesSettings -from ..api import version_check CSS = """ html.dark { @@ -169,36 +168,9 @@ def reload(self,sheet): sheet.set_contents(html_template.format(**kwargs)) - def _lazy_load(func): - def wrapper(self,*args, **kwargs): - """ - Wrapper will be used on the function that takes time to load - it will return a placeholder with loading utill it is loaded - """ - if self.clearing_time < time.time(): - self.clearing_time = time.time() + 20 - self.calls = {} - - def load_function(): - self.calls[func.__name__] = func(*args, **kwargs) - self.reload(sublime.HtmlSheet(self.sheet_id)) - - if self.calls.get(func.__name__): - return self.calls[func.__name__] - else: - sublime.set_timeout_async(load_function,0) - return self.lazy_load_status.get(func.__name__,"[Loading]") - return wrapper - - - @_lazy_load - def pieces_os_status(): - if PiecesSettings().get_health(): - check_version,update = version_check() - if not check_version: - return red(f'You need to update {update}') + def pieces_os_status(self): + if PiecesSettings.health == "OK": return green('Installed Pieces OS is installed successfully') - return red("Oops! Pieces OS is not running.") + """
    Don't worry, you can easily open Pieces OS and get started right away!
    diff --git a/misc/open_pieces_command.py b/misc/open_pieces_command.py index 35c8360..aea0e9a 100644 --- a/misc/open_pieces_command.py +++ b/misc/open_pieces_command.py @@ -1,6 +1,6 @@ import sublime_plugin import sublime -from ..api import open_pieces_os +from ..settings import PiecesSettings class PiecesOpenPiecesCommand(sublime_plugin.ApplicationCommand): def run(self): @@ -10,6 +10,9 @@ def run(self): def run_async(): view = sublime.active_window().active_view() view.set_status("OPEN_STATUS","Opening Pieces OS") if view else None - open_pieces_os() - view.erase_status("OPEN_STATUS") if view else None - sublime.status_message("Pieces OS lunched successfully") \ No newline at end of file + if PiecesSettings.api_client.open_pieces_os(): + view.erase_status("OPEN_STATUS") if view else None + sublime.status_message("Pieces OS lunched successfully") + else: + view.erase_status("OPEN_STATUS") if view else None + sublime.status_message("Unable to lunch Pieces OS") \ No newline at end of file diff --git a/misc/reload_command.py b/misc/reload_command.py index dd011e9..598e357 100644 --- a/misc/reload_command.py +++ b/misc/reload_command.py @@ -1,5 +1,5 @@ from ..settings import PiecesSettings -from ..base_websocket import BaseWebsocket +from .._pieces_lib.pieces_os_client.wrapper.websockets import BaseWebsocket import sublime import sublime_plugin @@ -11,7 +11,7 @@ def run(self): def reload_async(self): - if PiecesSettings.get_health(): + if PiecesSettings.api_client.health: try: sublime.set_timeout_async(self.run_reload_async) except Exception as e: diff --git a/settings.py b/settings.py index 1e43960..8f390a1 100644 --- a/settings.py +++ b/settings.py @@ -16,9 +16,8 @@ class PiecesSettings: platform = sublime.platform().upper() if sublime.platform() != 'osx' else "MACOS", version = __version__))) is_loaded = False # is the plugin loaded - + health = "failed" ONBOARDING_SYNTAX = "Packages/Pieces/syntax/Onboarding.sublime-syntax" - on_model_change_callbacks = [] # If the model change a function should be runned PIECES_USER_DIRECTORY = os.path.join(sublime.packages_path(),"User","Pieces") From fd5ba9f55e7772e689cf349936422fa9692a67bd Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Thu, 5 Sep 2024 17:05:50 +0300 Subject: [PATCH 11/30] refactor auth --- auth/__init__.py | 1 - auth/auth_command.py | 32 ++++++-------------------------- auth/auth_user.py | 32 ++++++++++++++++---------------- main.py | 4 ++-- 4 files changed, 24 insertions(+), 45 deletions(-) diff --git a/auth/__init__.py b/auth/__init__.py index a6a5442..f035a88 100644 --- a/auth/__init__.py +++ b/auth/__init__.py @@ -2,5 +2,4 @@ PiecesLogoutCommand, PiecesAllocationConnectCommand, PiecesAllocationDisconnectCommand) -from .auth_websocket import AuthWebsocket from .auth_user import AuthUser \ No newline at end of file diff --git a/auth/auth_command.py b/auth/auth_command.py index 7f0b6eb..8749be2 100644 --- a/auth/auth_command.py +++ b/auth/auth_command.py @@ -9,15 +9,7 @@ class PiecesLoginCommand(sublime_plugin.WindowCommand): def run(self): - self.login_thread = OSApi(PiecesSettings.api_client).sign_into_os(async_req=True) - sublime.set_timeout_async(self.run_allocation_async) - - def run_allocation_async(self): - try: - user = self.login_thread.get(120) # 120 sec timeout - self.window.run_command("pieces_allocation_connect") - except: - pass + sublime.set_timeout_async(lambda:PiecesSettings.api_client.user.login(False)) def is_enabled(self): return PiecesSettings.is_loaded @@ -25,34 +17,22 @@ def is_enabled(self): class PiecesLogoutCommand(sublime_plugin.WindowCommand): def run(self): - OSApi(PiecesSettings.api_client).sign_out_of_os(async_req=True) + sublime.set_timeout_async(lambda:PiecesSettings.api_client.user.logout()) def is_enabled(self): return PiecesSettings.is_loaded class PiecesAllocationConnectCommand(sublime_plugin.WindowCommand): def run(self): - user = AuthUser.user_profile - if user: # User logged in - AllocationsApi(PiecesSettings.api_client).allocations_connect_new_cloud(user,async_req=True) - AuthUser.logout_page(user.email,user.name,None,True) + sublime.set_timeout_async(lambda:PiecesSettings.api_client.user.connect()) def is_enabled(self): - return PiecesSettings.is_loaded - - def is_visible(self): # will appear if the user logged in but no allocation - return bool(AuthUser.user_profile) and not bool(AuthUser.user_profile.allocation) + return PiecesSettings.is_loaded and bool(AuthUser.user_profile) and not bool(AuthUser.user_profile.allocation) class PiecesAllocationDisconnectCommand(sublime_plugin.WindowCommand): def run(self): - if AuthUser.user_profile: - if AuthUser.user_profile.allocation: # Check if there is an allocation iterable - AllocationsApi(PiecesSettings.api_client).allocations_disconnect_cloud(AuthUser.user_profile.allocation,async_req=True) - - def is_visible(self): # will appear if the user logged in but no allocation - return bool(AuthUser.user_profile) and bool(AuthUser.user_profile.allocation) - + sublime.set_timeout_async(lambda:PiecesSettings.api_client.user.disconnect()) def is_enabled(self): - return PiecesSettings.is_loaded + return PiecesSettings.is_loaded and bool(AuthUser.user_profile) and bool(AuthUser.user_profile.allocation) diff --git a/auth/auth_user.py b/auth/auth_user.py index 953302b..208d6a6 100644 --- a/auth/auth_user.py +++ b/auth/auth_user.py @@ -1,4 +1,4 @@ -from .._pieces_lib.pieces_os_client import UserProfile +from .._pieces_lib.pieces_os_client import UserProfile,AllocationStatusEnum from ..settings import PiecesSettings import sublime from typing import Optional @@ -19,14 +19,14 @@ def create_new_phantom(cls,html): sublime.Region(0, 0), html, sublime.LAYOUT_INLINE) @classmethod - def on_user_callback(cls,user:Optional[UserProfile]=None): - PiecesSettings.api_client.user.on_user_callback(user) + def on_user_callback(cls,user:Optional[UserProfile]=None,connecting=False): + PiecesSettings.api_client.user.user_profile = user sublime.active_window().focus_view(PiecesSettings.output_panel) cls.user_profile = user if not user: cls.login_page() else: - cls.logout_page(user.email,user.name,user.allocation) + cls.logout_page(connecting) @classmethod def login_page(cls): @@ -35,26 +35,26 @@ def login_page(cls): @classmethod - def logout_page(cls,email,username,allocation=None,connecting=False): + def logout_page(cls,connecting=False): allocation_html = "" - if allocation: - status = allocation.status.cloud - if status == "PENDING": + user = PiecesSettings.api_client.user + status = user.cloud_status + if status: + + if status == AllocationStatusEnum.PENDING: allocation_html = CONNECTING_HTML - elif status == "RUNNING" and "SUCCEEDED": + elif status == AllocationStatusEnum.SUCCEEDED \ + or status == AllocationStatusEnum.RUNNING: allocation_html = CONNECTED_HTML - elif status == "FAILED": + elif status == AllocationStatusEnum.FAILED: allocation_html = DISCONNECTED_HTML - try: - if allocation.urls.vanity.url: - allocation_html += f"

    Personal Domain: {allocation.urls.vanity.url}

    " - except AttributeError: - pass + if user.vanity_name: + allocation_html += f"

    Personal Domain: {user.vanity_name}.pieces.cloud

    " else: if connecting: allocation_html = CONNECTING_HTML else: allocation_html = DISCONNECTED_HTML - phantom_content = f"

    Username: {username}

    Email: {email}

    {allocation_html}Logout" + phantom_content = f"

    Username: {user.name}

    Email: {user.email}

    {allocation_html}Logout" cls.create_new_phantom(phantom_content) diff --git a/main.py b/main.py index 8cfb816..dec08cc 100644 --- a/main.py +++ b/main.py @@ -35,8 +35,8 @@ def startup(): # User Weboscket PiecesSettings.create_auth_output_panel() - auth_ws = AuthWS.get_instance() - auth_ws.on_message_callback = AuthUser.on_user_callback + + PiecesSettings.api_client.user.on_user_callback = AuthUser.on_user_callback # Lunch Onboarding if it is the first time if not PiecesOnboardingCommand.get_onboarding_settings().get("lunch_onboarding",False): From 123a877f20d74a558f6de338c968a34521e67be5 Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Fri, 6 Sep 2024 01:00:16 +0300 Subject: [PATCH 12/30] refactor assets --- .../wrapper/basic_identifier/asset.py | 2 +- assets/create_asset.py | 58 +++---------------- assets/delete_asset.py | 12 ++-- assets/export_command.py | 17 +++--- assets/list_assets.py | 32 ++++------ assets/markdown_handler.py | 13 ++--- assets/save_asset.py | 3 +- assets/share_asset.py | 25 +++----- settings.py | 11 ++++ 9 files changed, 60 insertions(+), 113 deletions(-) diff --git a/_pieces_lib/pieces_os_client/wrapper/basic_identifier/asset.py b/_pieces_lib/pieces_os_client/wrapper/basic_identifier/asset.py index ac7cebf..a97c5fb 100644 --- a/_pieces_lib/pieces_os_client/wrapper/basic_identifier/asset.py +++ b/_pieces_lib/pieces_os_client/wrapper/basic_identifier/asset.py @@ -170,7 +170,7 @@ def name(self, name: str): self._edit_asset(self.asset) @property - def description(self): + def description(self) -> str: """ Retrieve the description of the asset. diff --git a/assets/create_asset.py b/assets/create_asset.py index e74cc5d..0406e34 100644 --- a/assets/create_asset.py +++ b/assets/create_asset.py @@ -1,72 +1,28 @@ from ..settings import PiecesSettings -from .._pieces_lib import pieces_os_client as pos_client +from .._pieces_lib.pieces_os_client import ClassificationSpecificEnum,FragmentMetadata import sublime_plugin import sublime class PiecesCreateAssetCommand(sublime_plugin.TextCommand): - - def get_seeds(self,data=None): - + def run(self,edit,data=None,metadata=None): if not data: # Get the all the selected text data = "\n".join([self.view.substr(selection) for selection in self.view.sel()]) if not data: return sublime.error_message("Please select a text") - - - # Getting the metadata - if not data: - try: - ext = self.view.file_name().split(".")[-1] - - if ext in pos_client.ClassificationSpecificEnum: - metadata = pos_client.FragmentMetadata(ext=ext) - else: - raise IndexError - except: - metadata = None - else: - metadata = None - - - - # Construct a Seed - seed = pos_client.Seed( - asset=pos_client.SeededAsset( - application=PiecesSettings.get_application(), - format=pos_client.SeededFormat( - fragment=pos_client.SeededFragment( - string=pos_client.TransferableString(raw=data), - metadata=metadata - ) - ), - metadata=None - ), - type="SEEDED_ASSET" - ) - return seed - def run(self,edit,data=None): - seed = self.get_seeds(data) + ext = self.view.name().split(".")[-1] + metadata = FragmentMetadata(ext = ClassificationSpecificEnum(ext)) if ext in ClassificationSpecificEnum else None # Creating the new asset using the assets API - sublime.set_timeout_async(lambda : self.run_create_async(seed) ,0) - - + sublime.set_timeout_async(lambda :self.run_create_async(data,metadata) ,0) - def run_create_async(self,seed): + def run_create_async(self,data,metadata): self.view.set_status('Pieces Creating', 'Creating an asset') - created_asset_id = self.create_asset(seed) + created_asset_id = PiecesSettings.api_client.create_asset(data,metadata) self.view.window().run_command("pieces_list_assets",{"pieces_asset_id":created_asset_id}) self.view.erase_status('Pieces Creating') - - @staticmethod - def create_asset(seed): - assets_api = pos_client.AssetsApi(PiecesSettings.api_client) - created_asset_id = assets_api.assets_create_new_asset(transferables=False, seed=seed).id - return created_asset_id - def is_enabled(self): return PiecesSettings.is_loaded diff --git a/assets/delete_asset.py b/assets/delete_asset.py index 339475b..06f91fe 100644 --- a/assets/delete_asset.py +++ b/assets/delete_asset.py @@ -1,30 +1,30 @@ +from .._pieces_lib.pieces_os_client.wrapper.basic_identifier import BasicAsset from .._pieces_lib.pieces_os_client import AssetsApi from ..settings import PiecesSettings from .list_assets import PiecesListAssetsCommand -from .assets_snapshot import AssetSnapshot import sublime import sublime_plugin class PiecesDeleteAssetCommand(sublime_plugin.WindowCommand): def run(self,asset_id=None): - if not asset_id: sheet = self.window.active_sheet() asset_id = PiecesListAssetsCommand.sheets_md.get(sheet.id()) if not asset_id: return - asset_wrapper = AssetSnapshot(asset_id) + asset_wrapper = BasicAsset(asset_id) name = asset_wrapper.name msg = f"Are you sure you want to delete '{name}'" else: sheet = None - msg = "Are you sure you want to delete this asset" + asset_wrapper = BasicAsset(asset_id) + msg = f"Are you sure you want to delete '{asset_wrapper.name}'" if sublime.ok_cancel_dialog(msg,ok_title='Yes, I am sure',title="Warning"): - delete_instance = AssetsApi(PiecesSettings.api_client) - delete_instance.assets_delete_asset(asset_id) + asset_wrapper.delete() if sheet: sheet.close() + def is_enabled(self): return PiecesSettings.is_loaded \ No newline at end of file diff --git a/assets/export_command.py b/assets/export_command.py index c0f4277..eb1f6a0 100644 --- a/assets/export_command.py +++ b/assets/export_command.py @@ -2,9 +2,9 @@ import mdpopups import os import re -from .._pieces_lib.typing_extensions import Self +from typing import Self +from .._pieces_lib.pieces_os_client.wrapper.basic_identifier.asset import BasicAsset from .list_assets import PiecesAssetIdInputHandler,A_TAG_STYLE -from .assets_snapshot import AssetSnapshot from .ext_map import file_map from ..settings import PiecesSettings @@ -56,15 +56,16 @@ def input(self, args: dict): return PiecesAssetIdInputHandler() def run(self,pieces_asset_id): - asset_wrapper = AssetSnapshot(pieces_asset_id) + asset_wrapper = BasicAsset(pieces_asset_id) self.trigger = asset_wrapper.name - self.description = getattr(PiecesAssetIdInputHandler.get_annotation(asset_wrapper.asset),"text","No Description Found") + self.asset_description = asset_wrapper.description if asset_wrapper.description else "No description found" - self.content = asset_wrapper.get_asset_raw() + self.content = asset_wrapper.raw_content self.dummy_view = self.window.create_output_panel("pieces_dummy_view",unlisted=True) - self.lang = asset_wrapper.original_classification_specific() + self.lang = asset_wrapper.classification self.asset_id = pieces_asset_id + try: syntax = file_map[self.lang] except: syntax=None @@ -86,9 +87,9 @@ def update_sheet(self): trigger = self.trigger, asset_id = self.asset_id, content = self.content, - description = self.description, + description = self.asset_description, scope = self.scope, - lang = self.lang.value, + lang = self.lang.value if self.lang else "txt", A_TAG_STYLE = A_TAG_STYLE, sheet_id =self.sheet.id() ), diff --git a/assets/list_assets.py b/assets/list_assets.py index a8589f4..ecb8725 100644 --- a/assets/list_assets.py +++ b/assets/list_assets.py @@ -1,11 +1,10 @@ -from typing import Optional +from _pieces_lib.pieces_os_client.wrapper.basic_identifier.asset import BasicAsset import sublime_plugin import sublime import mdpopups import re -from .assets_snapshot import AssetSnapshot -from .assets_identifiers_ws import AssetsIdentifiersWS +from .._pieces_lib.pieces_os_client.wrapper.websockets import AssetsIdentifiersWS from .._pieces_lib.pieces_os_client import * from ..settings import PiecesSettings @@ -34,7 +33,6 @@ def update_sheet(cls,sheet,asset_id,buttons_kwargs={}): try: api_response = api_instance.asset_specific_asset_export(asset_id, "MD") except: - AssetSnapshot.identifiers_snapshot.pop(asset_id) return sublime.error_message("Asset Not Found") markdown_text = api_response.raw.string.raw @@ -76,31 +74,21 @@ def is_enabled(self): return PiecesSettings.is_loaded and AssetsIdentifiersWS.is_running() - - - class PiecesAssetIdInputHandler(sublime_plugin.ListInputHandler): def list_items(self): - return self.get_assets_list(AssetSnapshot.identifiers_snapshot) + return self.get_assets_list(PiecesSettings.api_client.assets()) - def get_assets_list(self,assets_snapshot): + def get_assets_list(self,assets_snapshot:list[BasicAsset]): assets_list = [] - for asset_id in assets_snapshot.keys(): - asset = assets_snapshot[asset_id] - name = asset.name if asset.name else "New asset" - annotation = self.get_annotation(asset) + for basic_asset in assets_snapshot: + name = basic_asset.name + annotation = basic_asset.description if annotation: - assets_list.append(sublime.ListInputItem(text=name, value=asset_id,details=annotation.text)) + assets_list.append(sublime.ListInputItem(text=name, value=basic_asset.id,details=annotation)) else: - assets_list.append(sublime.ListInputItem(text=name, value=asset_id)) + assets_list.append(sublime.ListInputItem(text=name, value=basic_asset.id)) return assets_list - @staticmethod - def get_annotation(asset) -> Optional[Annotation]: - annotations = asset.annotations.iterable - annotations = sorted(annotations, key=lambda x: x.updated.value, reverse=True) - for annotation in annotations: - if annotation.type == "DESCRIPTION": - return annotation + def placeholder(self): return "Choose an asset" diff --git a/assets/markdown_handler.py b/assets/markdown_handler.py index 8f44397..49c3791 100644 --- a/assets/markdown_handler.py +++ b/assets/markdown_handler.py @@ -1,8 +1,7 @@ import sublime_plugin import sublime -from .assets_snapshot import AssetSnapshot from .._pieces_lib.pieces_os_client import * - +from .._pieces_lib.pieces_os_client.wrapper.basic_identifier import BasicAsset from .list_assets import PiecesListAssetsCommand from .ext_map import file_map @@ -42,10 +41,10 @@ def run(self,mode,sheet_id=None,data=None,close=True): if not asset_id: return - asset_wrapper = AssetSnapshot(asset_id) - self.code = asset_wrapper.get_asset_raw() - self.language = asset_wrapper.original_classification_specific() - self.name = asset_wrapper.name + asset_wrapper = BasicAsset(asset_id) + self.code = asset_wrapper.raw_content + self.language = asset_wrapper.classification + self.asset_name = asset_wrapper.name self.asset_id = asset_id if mode == "copy": @@ -80,7 +79,7 @@ def handle_edit(self): # Insert the text view.run_command('append', {'characters': self.code}) # Set the name - view.set_name(self.name) + view.set_name(self.asset_name) # Set it to scratch to avoid the default saving menu view.set_scratch(True) # Set the view to handle the save operation diff --git a/assets/save_asset.py b/assets/save_asset.py index 04ca4aa..133a899 100644 --- a/assets/save_asset.py +++ b/assets/save_asset.py @@ -1,6 +1,7 @@ import sublime import sublime_plugin from .._pieces_lib.pieces_os_client import ClassificationGenericEnum,FormatApi +from .._pieces_lib.pieces_os_client.wrapper.basic_identifier.asset import BasicAsset from ..settings import PiecesSettings from .assets_snapshot import AssetSnapshot @@ -8,5 +9,5 @@ class PiecesSaveAssetCommand(sublime_plugin.WindowCommand): def run(self,asset_id,data): - AssetSnapshot(asset_id).edit_asset_original_format(data) + BasicAsset(asset_id).raw_content = data diff --git a/assets/share_asset.py b/assets/share_asset.py index 05145ce..b92b40e 100644 --- a/assets/share_asset.py +++ b/assets/share_asset.py @@ -1,10 +1,8 @@ import sublime_plugin import sublime -from .._pieces_lib.pieces_os_client import LinkifyApi,Linkify +from .._pieces_lib.pieces_os_client.wrapper.basic_identifier.asset import BasicAsset -from .assets_snapshot import AssetSnapshot from .list_assets import PiecesListAssetsCommand -from .create_asset import PiecesCreateAssetCommand from ..settings import PiecesSettings from ..auth.auth_user import AuthUser @@ -17,14 +15,11 @@ def run(self,asset_id,update_sheet=False): PiecesListAssetsCommand.update_sheet(self.sheet,asset_id,{"share":{"title":"Sharing","url":"noop"}}) sublime.set_timeout_async(lambda:self.run_async(asset_id)) - def run_async(self,asset_id=None,seed=None): + def run_async(self,asset_id=None,raw_content=None): """ You need to either give the seed or the asset_id """ - if asset_id: - kwargs = {"asset" : AssetSnapshot.get_asset(asset_id)} - else: - kwargs = {"seed" : seed} + user = AuthUser.user_profile if not user: if sublime.ok_cancel_dialog("You need to be logged in to generate a shareable link",ok_title="Login",title="Pieces"): @@ -35,12 +30,10 @@ def run_async(self,asset_id=None,seed=None): self.window.run_command("pieces_allocation_connect") return - self.thread = LinkifyApi(PiecesSettings.api_client).linkify(async_req=True, - linkify=Linkify( - access="PUBLIC", - **kwargs - ) - ) + if asset_id: + self.thread = PiecesSettings.pool().apply_async(BasicAsset(asset_id).share) + if raw_content: + self.thread = PiecesSettings.pool().apply_async(BasicAsset.share_raw_content,raw_content) share = None try: @@ -70,12 +63,10 @@ def run(self,edit,data=None): def run_async(self): self.view.set_status("pieces_share","Creating asset") - create_asset = PiecesCreateAssetCommand(self.view) - seed = create_asset.get_seeds(self.data) self.view.set_status("pieces_share","Generating shareable link") - shares = PiecesShareAssetCommand(sublime.active_window()).run_async(seed=seed) + shares = PiecesShareAssetCommand(sublime.active_window()).run_async(raw_content=self.data) link = shares.iterable[0].link self.view.set_status("pieces_share",f"Link Generated {link}") diff --git a/settings.py b/settings.py index 8f390a1..88c02ed 100644 --- a/settings.py +++ b/settings.py @@ -1,6 +1,7 @@ from ._pieces_lib.pieces_os_client import SeededConnectorConnection,SeededTrackedApplication from ._pieces_lib.pieces_os_client.wrapper.websockets.base_websocket import BaseWebsocket from ._pieces_lib.pieces_os_client.wrapper import PiecesClient +from multiprocessing.pool import ThreadPool import sublime import os @@ -15,6 +16,7 @@ class PiecesSettings: name = "SUBLIME", platform = sublime.platform().upper() if sublime.platform() != 'osx' else "MACOS", version = __version__))) + _pool = None is_loaded = False # is the plugin loaded health = "failed" ONBOARDING_SYNTAX = "Packages/Pieces/syntax/Onboarding.sublime-syntax" @@ -87,6 +89,15 @@ def create_auth_output_panel(cls): cls.output_panel.settings().set("gutter", False) cls.output_panel.set_read_only(True) + @classmethod + def pool(cls): + """Create thread pool on first request + avoids instantiating unused threadpool for blocking clients. + """ + if cls._pool is None: + cls._pool = ThreadPool(1) + return cls._pool + # Load the settings from 'Pieces.sublime-settings' file using Sublime Text API pieces_settings = sublime.load_settings('Pieces.sublime-settings') pieces_settings.add_on_change("PIECES_SETTINGS",on_settings_change) From 59fbf6875818db95d225be2136df0cda45536180 Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Fri, 6 Sep 2024 01:02:52 +0300 Subject: [PATCH 13/30] refactor ask --- ask/commands.py | 6 ++---- assets/__init__.py | 3 +-- copilot/__init__.py | 2 -- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/ask/commands.py b/ask/commands.py index 0323b37..ecf1f46 100644 --- a/ask/commands.py +++ b/ask/commands.py @@ -40,8 +40,6 @@ def run(self,edit, task): sublime.set_timeout_async(self.run_async,0) - - def run_async(self): # Get the current selection self.selection = self.view.sel()[0] @@ -93,7 +91,7 @@ def on_done_async(self): gpt_input = QGPTQuestionInput( query = " ", model = PiecesSettings.model_id, - application = PiecesSettings.application.id, + application = PiecesSettings.api_client.tracked_application.id, pipeline = QGPTPromptPipeline( task = pipeline ), @@ -103,7 +101,7 @@ def on_done_async(self): seed = Seed( type="SEEDED_ASSET", asset=SeededAsset( - application=PiecesSettings.application, + application=PiecesSettings.api_client.tracked_application, format=SeededFormat( fragment = SeededFragment( string = TransferableString(raw = self.selected_text) diff --git a/assets/__init__.py b/assets/__init__.py index 902d1fa..08be868 100644 --- a/assets/__init__.py +++ b/assets/__init__.py @@ -1,6 +1,5 @@ -from .list_assets import PiecesListAssetsCommand, AssetSnapshot +from .list_assets import PiecesListAssetsCommand from .markdown_handler import PiecesHandleMarkdownCommand -from .assets_identifiers_ws import AssetsIdentifiersWS from .create_asset import PiecesCreateAssetCommand from .delete_asset import PiecesDeleteAssetCommand from .save_asset import PiecesSaveAssetCommand diff --git a/copilot/__init__.py b/copilot/__init__.py index 03ace94..5187839 100644 --- a/copilot/__init__.py +++ b/copilot/__init__.py @@ -1,6 +1,4 @@ from .ask_command import PiecesAskStreamCommand,PiecesEnterResponseCommand,PiecesInsertTextCommand -from .conversation_websocket import ConversationWS -from .conversations import ConversationsSnapshot from .explain import PiecesExplainCommand from .context_manager import PiecesContextManagerCommand from .ask_about_command import PiecesAskStreamAboutCommand From c44efd43e5b1eeb4be9d532253bf222897aec59d Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Fri, 6 Sep 2024 19:10:59 +0300 Subject: [PATCH 14/30] compatibility with Python 3.8 --- _pieces_lib/pieces_os_client/wrapper/context.py | 13 ++++++------- _pieces_lib/pieces_os_client/wrapper/copilot.py | 4 ++-- .../wrapper/websockets/base_websocket.py | 4 ++-- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/_pieces_lib/pieces_os_client/wrapper/context.py b/_pieces_lib/pieces_os_client/wrapper/context.py index 930b12a..7500664 100644 --- a/_pieces_lib/pieces_os_client/wrapper/context.py +++ b/_pieces_lib/pieces_os_client/wrapper/context.py @@ -1,5 +1,4 @@ -from typing import TYPE_CHECKING - +from typing import TYPE_CHECKING, List from .basic_identifier import BasicAsset,BasicMessage import os from Pieces._pieces_lib.pieces_os_client import QGPTRelevanceInput,Seeds,FlattenedAssets,FlattenedConversationMessages @@ -10,10 +9,10 @@ class Context: def __init__(self, pieces_client:"PiecesClient", - paths:list[str] = [], - raw_assets:list[str] = [], - assets:list[BasicAsset] = [], - messages:list[BasicMessage] = []): + paths:List[str] = [], + raw_assets:List[str] = [], + assets:List[BasicAsset] = [], + messages:List[BasicMessage] = []): self.pieces_client = pieces_client self.raw_assets = raw_assets self.paths = paths @@ -67,7 +66,7 @@ def _check_paths(paths): raise ValueError("Invalid path in the context") @staticmethod - def _check_raw_assets(assets:list[str]): + def _check_raw_assets(assets:List[str]): seed_list = Seeds(iterable=[]) for raw in assets: if not isinstance(raw,str): diff --git a/_pieces_lib/pieces_os_client/wrapper/copilot.py b/_pieces_lib/pieces_os_client/wrapper/copilot.py index 570fbfa..a157d96 100644 --- a/_pieces_lib/pieces_os_client/wrapper/copilot.py +++ b/_pieces_lib/pieces_os_client/wrapper/copilot.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Optional, Generator +from typing import TYPE_CHECKING, Optional, Generator,List from Pieces._pieces_lib.pieces_os_client import (SeededConversation, QGPTStreamInput, RelevantQGPTSeeds, @@ -104,7 +104,7 @@ def question(self, return self.pieces_client.qgpt_api.question(gpt_input) - def chats(self) -> list[BasicChat]: + def chats(self) -> List[BasicChat]: """ Retrieves a list of all chat identifiers. diff --git a/_pieces_lib/pieces_os_client/wrapper/websockets/base_websocket.py b/_pieces_lib/pieces_os_client/wrapper/websockets/base_websocket.py index a6bc564..26b0f2f 100644 --- a/_pieces_lib/pieces_os_client/wrapper/websockets/base_websocket.py +++ b/_pieces_lib/pieces_os_client/wrapper/websockets/base_websocket.py @@ -1,4 +1,4 @@ -from typing import Callable, Optional,TYPE_CHECKING +from typing import Callable, Optional,TYPE_CHECKING,List from Pieces._pieces_lib.typing_extensions import Self from Pieces._pieces_lib import websocket import threading @@ -9,7 +9,7 @@ class BaseWebsocket(ABC): instances = [] - _initialized_events:list[threading.Event] = [] + _initialized_events:List[threading.Event] = [] def __new__(cls, *args, **kwargs): """ From adcb7dd36c28d04176ce669f86a9d45d7c8d08bf Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Sat, 7 Sep 2024 22:28:18 +0300 Subject: [PATCH 15/30] refactor the ask command --- ask/commands.py | 43 +++++++++++++++++-------------------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/ask/commands.py b/ask/commands.py index ecf1f46..92114d6 100644 --- a/ask/commands.py +++ b/ask/commands.py @@ -87,35 +87,26 @@ def on_done_async(self): self.view.set_status('Pieces Refactoring', 'Copilot is thinking...') - - gpt_input = QGPTQuestionInput( - query = " ", - model = PiecesSettings.model_id, - application = PiecesSettings.api_client.tracked_application.id, - pipeline = QGPTPromptPipeline( - task = pipeline - ), - relevant = RelevantQGPTSeeds( - iterable = [ - RelevantQGPTSeed( - seed = Seed( - type="SEEDED_ASSET", - asset=SeededAsset( - application=PiecesSettings.api_client.tracked_application, - format=SeededFormat( - fragment = SeededFragment( - string = TransferableString(raw = self.selected_text) - ), - classification = self.classification + relevant = RelevantQGPTSeeds( + iterable = [ + RelevantQGPTSeed( + seed = Seed( + type="SEEDED_ASSET", + asset=SeededAsset( + application=PiecesSettings.api_client.tracked_application, + format=SeededFormat( + fragment = SeededFragment( + string = TransferableString(raw = self.selected_text) ), - ), - ), - ) - ] - ) + classification = self.classification + ), + ), + ), + ) + ] ) try: - res = QGPTApi(PiecesSettings.api_client).question(gpt_input) + res = PiecesSettings.api_client.copilot.question(" ",relevant,pipeline) except: self.view.set_status('Pieces Refactoring', 'Copilot error in getting the responses') sublime.set_timeout(lambda:self.view.erase_status("Pieces Refactoring"),5000) From 1085cfc0d341ba82883845ae15466e494dcf6fa2 Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Sat, 7 Sep 2024 22:28:40 +0300 Subject: [PATCH 16/30] refactor copilot --- assets/list_assets.py | 2 +- copilot/ask_command.py | 25 +++----- copilot/ask_view.py | 118 +++++++++---------------------------- copilot/context_manager.py | 45 ++++++++------ copilot/explain.py | 13 ++-- 5 files changed, 70 insertions(+), 133 deletions(-) diff --git a/assets/list_assets.py b/assets/list_assets.py index ecb8725..6913202 100644 --- a/assets/list_assets.py +++ b/assets/list_assets.py @@ -1,10 +1,10 @@ -from _pieces_lib.pieces_os_client.wrapper.basic_identifier.asset import BasicAsset import sublime_plugin import sublime import mdpopups import re from .._pieces_lib.pieces_os_client.wrapper.websockets import AssetsIdentifiersWS +from .._pieces_lib.pieces_os_client.wrapper.basic_identifier import BasicAsset from .._pieces_lib.pieces_os_client import * from ..settings import PiecesSettings diff --git a/copilot/ask_command.py b/copilot/ask_command.py index 567eb02..397d0cc 100644 --- a/copilot/ask_command.py +++ b/copilot/ask_command.py @@ -1,8 +1,7 @@ import sublime_plugin import sublime from .ask_view import CopilotViewManager -from .conversations import ConversationsSnapshot -from .conversation_websocket import ConversationWS +from .._pieces_lib.pieces_os_client.wrapper.websockets import ConversationWS from .._pieces_lib.pieces_os_client import AnnotationApi,Seeds,FlattenedAssets from ..settings import PiecesSettings from typing import Optional @@ -57,22 +56,12 @@ def is_enabled(self): class PiecesConversationIdInputHandler(sublime_plugin.ListInputHandler): def list_items(self): - conversation_list = [] - api = AnnotationApi(PiecesSettings.api_client) - for conversation in ConversationsSnapshot.identifiers_snapshot.values(): - name = getattr(conversation,"name","New Conversation") - if not name: name = "New Conversation" - - try: - id = list(conversation.annotations.indices.keys())[0] - details = str(api.annotation_specific_annotation_snapshot(id).text).replace("\n"," ") - except AttributeError: - details = "" - - - conversation_list.append(sublime.ListInputItem(text=name, value=conversation.id,details=details)) - - return conversation_list + return [ + sublime.ListInputItem( + text=chat.name, + value=chat.id, + details=chat.description.replace("\n","") if chat.description else "") + for chat in PiecesSettings.api_client.copilot.chats()] def placeholder(self): return "Choose a conversation or start new one" diff --git a/copilot/ask_view.py b/copilot/ask_view.py index 2d00739..9caad31 100644 --- a/copilot/ask_view.py +++ b/copilot/ask_view.py @@ -1,19 +1,9 @@ +import copilot import sublime from sublime import Region from .images.context_image import ContextImage -from .ask_websocket import AskStreamWS -from .conversations import ConversationsSnapshot -from .._pieces_lib.pieces_os_client import (ConversationMessageApi, - QGPTQuestionInput, - QGPTStreamInput, - RelevantQGPTSeeds, - QGPTStreamOutput, - QGPTRelevanceInput, - QGPTApi, - Asset, - Seed, - Seeds, - FlattenedAssets) +from .._pieces_lib.pieces_os_client import QGPTStreamOutput +from .._pieces_lib.pieces_os_client.wrapper.basic_identifier.chat import BasicChat from ..settings import PiecesSettings import re from typing import Optional @@ -82,7 +72,8 @@ def gpt_view(self) -> sublime.View: # Focus on the new group sublime.active_window().focus_group(1) - # Relevant + # Update the Copilot message callback + PiecesSettings.api_client.copilot.ask_stream_ws.on_message_callback = self.on_message_callback return CopilotViewManager._gpt_view @@ -107,15 +98,16 @@ def gpt_view(self,view): def update_status_bar(self): if getattr(self,"_gpt_view",None): - self._gpt_view.set_status("MODEL",f"LLM Model: {PiecesSettings.model_name.replace('Chat Model','')}") + self._gpt_view.set_status("MODEL",f"LLM Model: {PiecesSettings.api_client.model_name.replace('Chat Model','')}") @property def show_cursor(self): - self.gpt_view.set_status("MODEL",PiecesSettings.model_name) + self.update_status_bar() self.gpt_view.run_command("append",{"characters":">>> "}) self.end_response += 4 # ">>> " 4 characters region = sublime.Region(self.gpt_view.size(), self.gpt_view.size()) point_phantom = self.gpt_view.line(region.a).begin() + self.add_context_phantom(sublime.Region(point_phantom,point_phantom)) ui = sublime.ui_info()["theme"]["style"] @@ -130,10 +122,9 @@ def show_cursor(self): icon=f"Packages/Pieces/copilot/images/copilot-icon-{ui}.png", flags=sublime.HIDDEN ) + self.add_role("User: ") self.select_end - - @property def end_response(self) -> int: return self.gpt_view.settings().get("end_response") @@ -194,6 +185,7 @@ def conversation_id(self): @conversation_id.setter def conversation_id(self,id): + PiecesSettings.api_client.copilot.chat = BasicChat(id) self.gpt_view.settings().set("conversation_id",id) @property @@ -205,30 +197,6 @@ def new_line(self,lines = 2) -> None: for _ in range(lines): self.gpt_view.run_command("append",{"characters":"\n"}) - - def add_context(self, paths: Optional[list] = None, seed: Optional[Seed] = None, asset: Optional[Asset] = None): - if paths: - self._relevant["paths"] = self._relevant.get("paths", []) + paths - if seed: - seeds = self._relevant.get("seeds") - if seeds is None: - self._relevant["seeds"] = Seeds(iterable=[]) - self._relevant["seeds"].iterable.append(seed) - if asset: - assets = self._relevant.get("assets",None) - if assets is None: - self._relevant["assets"] = FlattenedAssets(iterable=[]) - self._relevant["assets"].iterable.append(asset) - - - - @property - def relevant(self): - return self._relevant - @relevant.setter - def relevant(self,relevant): - self._relevant = relevant - def ask(self,pipeline=None): query = self.gpt_view.substr(Region(self.end_response,self.gpt_view.size())) if not query: @@ -237,39 +205,12 @@ def ask(self,pipeline=None): self.select_end # got to the end of the text to enter the new lines self.new_line() self.remove_context_phantom() - sublime.set_timeout_async(lambda: self.run_ask_async(query,pipeline)) - - def run_ask_async(self,query,pipeline): - if self._relevant: - relevance_input = QGPTApi(PiecesSettings.api_client).relevance(QGPTRelevanceInput( - query=query, - application=PiecesSettings.get_application().id, - model=PiecesSettings.model_id, - **self._relevant - )).relevant - else: - relevance_input = RelevantQGPTSeeds(iterable=[]) - - - self.ask_websocket.send_message( - QGPTStreamInput( - question=QGPTQuestionInput( - query=query, - relevant = relevance_input, - application=PiecesSettings.get_application().id, - model = PiecesSettings.model_id, - pipeline=pipeline - ), - conversation = self.conversation_id, - )) - - @property - def ask_websocket(self): - if not hasattr(self,"_ask_websocket"): - CopilotViewManager._ask_websocket = AskStreamWS(self.on_message_callback) - return self._ask_websocket - + self.add_role("Copilot") + sublime.set_timeout_async(lambda: PiecesSettings.api_client.copilot.stream_question(query,pipeline)) + def add_role(self,role): + self.gpt_view.run_command("append",{"characters":f"{role}: "}) + self.end_response += len(role) + 2 def add_code_phantoms(self): view = self.gpt_view @@ -334,17 +275,14 @@ def update_phantom_set(self,region,id,save="Save",copy="Copy",share="Share",inse def render_conversation(self,conversation_id): - - self.conversation_id = conversation_id # Set the conversation - # Clear everything! - self._gpt_view = None # clear the old _gpt_view - self.phantom_set.update([]) # Clear old phantoms - + self.clear() if conversation_id: - conversation = ConversationsSnapshot.identifiers_snapshot.get(conversation_id) - if not conversation: + try: + conversation = BasicChat(conversation_id) + conversation.conversation + except ValueError: return sublime.error_message("Conversation not found") # Error conversation not found else: self.gpt_view # Nothing need to be rendered @@ -354,18 +292,16 @@ def render_conversation(self,conversation_id): self.view_name = conversation.name self.gpt_view.run_command("select_all") self.gpt_view.run_command("right_delete") # Clear the cursor created by default ">>>" - message_api = ConversationMessageApi(PiecesSettings.api_client) - for key,val in conversation.messages.indices.items(): - self.select_end - if val == -1: # message is deleted - continue - message = message_api.message_specific_message_snapshot(message=key,transferables=True) + + for message in conversation.messages(): if message.role == "USER": self.show_cursor + else: + self.add_role("Copilot") - if message.fragment.string: - self.gpt_view.run_command("append",{"characters":message.fragment.string.raw}) + if message.raw_content: + self.gpt_view.run_command("append",{"characters":message.raw_content}) self.new_line() @@ -376,6 +312,7 @@ def render_conversation(self,conversation_id): @property def secondary_view(self): return getattr(self,"_secondary_view",None) # Will be updated via event listeners + @secondary_view.setter def secondary_view(self,view): if not view.settings().get("PIECES_GPT_VIEW") and view in sublime.active_window().views(): @@ -387,6 +324,7 @@ def clear(self): self.can_type = True view = self._gpt_view self._gpt_view = None + self.phantom_set.update([]) if not view: return view.run_command("select_all") diff --git a/copilot/context_manager.py b/copilot/context_manager.py index cc52924..956a1de 100644 --- a/copilot/context_manager.py +++ b/copilot/context_manager.py @@ -1,28 +1,27 @@ import sublime_plugin import sublime -from .ask_command import copilot +from .._pieces_lib.pieces_os_client.wrapper.basic_identifier.asset import BasicAsset +from ..settings import PiecesSettings from ..assets.list_assets import PiecesAssetIdInputHandler -from ..assets.assets_snapshot import AssetSnapshot -RELEVANCE_FILE_TYPES = [ - ("",) -] # TODO: add the types of the files - class PiecesContextManagerCommand(sublime_plugin.TextCommand): def run(self, edit: sublime.Edit,context=None,pieces_asset_id=None,context_remove=None): if context_remove: key,idx = context_remove.split("_") idx = int(idx) if key == "paths": - copilot.relevant[key].pop(idx) - else: - copilot.relevant[key].iterable.pop(idx) + PiecesSettings.api_client.copilot.context.paths.pop(idx) + elif key == "seeds": + PiecesSettings.api_client.copilot.context.raw_assets.pop(idx) + elif key == "assets": + PiecesSettings.api_client.copilot.context.assets.pop(idx) + if pieces_asset_id: - copilot.add_context(asset = AssetSnapshot.get_asset(pieces_asset_id)) + PiecesSettings.api_client.copilot.context.assets.append(BasicAsset(pieces_asset_id)) def is_enabled(self): - return self.view.settings().get("PIECES_GPT_VIEW",False) + return self.view.settings().get("PIECES_GPT_VIEW",False) and PiecesSettings.is_loaded def input(self,args): return PiecesContextInputHandler() @@ -31,38 +30,50 @@ class PiecesContextInputHandler(sublime_plugin.ListInputHandler): def name(self): return "context" def list_items(self): + relevance_exists = PiecesSettings.api_client.copilot.context._check_relevant_existance() return [ ("Add Folder","folder"), ("Add File","file"), ("Add a Snippet","asset"), - *([("Show context", "show")] if copilot.relevant else []), # Show context if there is - *([("Reset Context","reset")] if copilot.relevant else []) + *([("Show context", "show")] if relevance_exists else []), # Show context if there is + *([("Reset Context","reset")] if relevance_exists else []) ] def next_input(self,args): context = args["context"] if context == "file": sublime.open_dialog( - lambda x:copilot.add_context(paths=list(x)) if x else None, + self.append_path, multi_select=True, ) elif context == "folder": sublime.select_folder_dialog( - lambda x: copilot.add_context(paths=list(x)) if x else None, + self.append_path, multi_select=True ) elif context == "asset": return PiecesAssetIdInputHandler() # Choose your asset elif context == "reset": - copilot.relevant = {} + PiecesSettings.api_client.copilot.context.clear() elif context == "show": return PiecesShowInputHandler() + + @staticmethod + def append_path(paths): + if isinstance(paths,list): + for path in paths: + PiecesSettings.api_client.copilot.context.paths.append(path) + elif isinstance(paths,str): + PiecesSettings.api_client.copilot.context.paths.append(paths) class PiecesShowInputHandler(sublime_plugin.ListInputHandler): def name(self): return "context_remove" + def list_items(self): res = [] - for key,value in copilot.relevant.items(): + context = PiecesSettings.api_client.copilot.context + + for key,value in {"paths":context.paths, "seeds":context.raw_assets, "assets":context.assets}.items(): if key == "paths": for idx,path in enumerate(value): res.append((path,f"paths_{idx}")) diff --git a/copilot/explain.py b/copilot/explain.py index 9a6f1c7..7b73eb9 100644 --- a/copilot/explain.py +++ b/copilot/explain.py @@ -2,19 +2,18 @@ from .._pieces_lib.pieces_os_client import (QGPTTaskPipeline, QGPTTaskPipelineForCodeExplanation) from .ask_command import copilot -from ..assets.create_asset import PiecesCreateAssetCommand from ..settings import PiecesSettings class PiecesExplainCommand(sublime_plugin.TextCommand): def run(self,edit): + # Get the all the selected text + data = "\n".join([self.view.substr(selection) for selection in self.view.sel()]) + if not data: + return sublime.error_message("Please select a text") copilot.clear() - if self.view.file_name(): - ext = self.view.file_name().split(".")[-1] - else: ext = 'txt' - seed = PiecesCreateAssetCommand(self.view).get_seeds() - query = f"Can you explain this \n```{ext}\n{seed.asset.format.fragment.string.raw}\n```" + ext = self.view.file_name().split(".")[-1] if self.view.file_name() else 'txt' + query = f"Can you explain this \n```{ext}\n{data}\n```" copilot.add_query(query) - # copilot.add_context(seed=seed) copilot.ask( pipeline=QGPTTaskPipeline( code_explanation=QGPTTaskPipelineForCodeExplanation() From 24bdabd7cb606d8a9b0160e7a546a93eefdd0099 Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Sat, 7 Sep 2024 22:29:51 +0300 Subject: [PATCH 17/30] fix extra import --- copilot/ask_view.py | 1 - 1 file changed, 1 deletion(-) diff --git a/copilot/ask_view.py b/copilot/ask_view.py index 9caad31..b646654 100644 --- a/copilot/ask_view.py +++ b/copilot/ask_view.py @@ -1,4 +1,3 @@ -import copilot import sublime from sublime import Region from .images.context_image import ContextImage From e9de683eb9f0725283d5ded31ff419d0440130b5 Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Sat, 7 Sep 2024 22:30:01 +0300 Subject: [PATCH 18/30] fix typos --- event_listener.py | 2 +- main.py | 2 +- settings.py | 13 +++++-------- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/event_listener.py b/event_listener.py index 8299df1..a0fc330 100644 --- a/event_listener.py +++ b/event_listener.py @@ -52,7 +52,7 @@ def on_pre_close(self,view): if data != code: sublime.active_window().focus_view(view) - if sublime.ok_cancel_dialog("Do you want to this snippet to pieces?", ok_title='Save', title='Save snippet'): + if sublime.ok_cancel_dialog("Do you want to save this snippet to Pieces?", ok_title='Save', title='Save snippet'): view.window().run_command("pieces_handle_markdown",{"mode": "save","sheet_id":sheet_id,"data":data,"close":False}) del view.settings()["pieces_sheet_id"] return diff --git a/main.py b/main.py index dec08cc..76305bf 100644 --- a/main.py +++ b/main.py @@ -13,7 +13,7 @@ from .misc import * from .copilot import * -PIECES_OS_MIN_VERSION = "10.1.5" # Minimum version (10.0.3) +PIECES_OS_MIN_VERSION = "10.1.5" # Minimum version (10.1.5) PIECES_OS_MAX_VERSION = "11.0.0" # Maximum version (11.0.0) diff --git a/settings.py b/settings.py index 88c02ed..6b0e668 100644 --- a/settings.py +++ b/settings.py @@ -51,13 +51,10 @@ def models_init(cls,model): This method retrieves the available models, sets the model ID based on the settings provided, and defaults to a specific model ("GPT-3.5-turbo Chat Model") if the specified model is not found. """ - - models = cls.api_client.get_models() - cls.model_name = model - cls.model_id = models.get(str(cls.model_name)) - - if not cls.model_id: - cls.model_id = models["GPT-3.5-turbo Chat Model"] + try: + cls.api_client.model_name = model + except ValueError: + sublime.error_message(f"Invalid model\n Choose one from {' ,'.join(cls.api_client.available_models_names)}") for func in cls.on_model_change_callbacks: func() @@ -74,7 +71,7 @@ def on_settings_change(cls,all = False): cls.host_init(host = host) cls.models_init(model = model) - if cls.model_name != model or all: + if cls.api_client.model_name != model or all: cls.models_init(model = model) @staticmethod From 729bd7d418f3264ce24250e565b81b0e2b29b993 Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Sat, 7 Sep 2024 23:03:07 +0300 Subject: [PATCH 19/30] add is_pieces_running --- .../pieces_os_client/wrapper/client.py | 87 +++++++++++++------ .../wrapper/websockets/base_websocket.py | 2 +- 2 files changed, 62 insertions(+), 27 deletions(-) diff --git a/_pieces_lib/pieces_os_client/wrapper/client.py b/_pieces_lib/pieces_os_client/wrapper/client.py index 92e81e5..774f69b 100644 --- a/_pieces_lib/pieces_os_client/wrapper/client.py +++ b/_pieces_lib/pieces_os_client/wrapper/client.py @@ -27,6 +27,8 @@ import platform import atexit import subprocess +import urllib.request +import urllib.error from .copilot import Copilot @@ -34,27 +36,35 @@ from .streamed_identifiers import AssetSnapshot from .websockets import * + class PiecesClient: def __init__(self, host:str="", seeded_connector: Optional[SeededConnectorConnection] = None,**kwargs): - if host: - self.host = host - else: - self.host = "http://localhost:5323" if 'Linux' in platform.platform() else "http://localhost:1000" + if not host: + host = "http://localhost:5323" if 'Linux' in platform.platform() else "http://localhost:1000" - self.init_host(self.host) + self.host = host + self._is_started_runned = False self.local_os = platform.system().upper() if platform.system().upper() in ["WINDOWS","LINUX","DARWIN"] else "WEB" self.local_os = "MACOS" if self.local_os == "DARWIN" else self.local_os - seeded_connector = seeded_connector or SeededConnectorConnection( + self._seeded_connector = seeded_connector or SeededConnectorConnection( application=SeededTrackedApplication( name = "OPEN_SOURCE", platform = self.local_os, version = __version__)) + self._connect_websockets = kwargs.get("connect_wesockets",True) + self.user = BasicUser(self) + self.copilot = Copilot(self) + self._startup() + - self.tracked_application = self.connector_api.connect(seeded_connector_connection=seeded_connector).application + def _startup(self) -> bool: + if self._is_started_runned: return True + if not self.is_pieces_running(): return False - self.user = BasicUser(self) + self._is_started_runned = True + self.tracked_application = self.connector_api.connect(seeded_connector_connection=self._seeded_connector).application - if kwargs.get("connect_wesockets",True): + if self._connect_websockets: self.conversation_ws = ConversationWS(self) self.assets_ws = AssetsIdentifiersWS(self) self.user_websocket = AuthWS(self,self.user.on_user_callback) @@ -63,9 +73,19 @@ def __init__(self, host:str="", seeded_connector: Optional[SeededConnectorConnec self.models = None self.model_name = "GPT-3.5-turbo Chat Model" - self.copilot = Copilot(self) + return True + - def init_host(self,host): + @property + def host(self) -> str: + return self._host + + @host.setter + def host(self,host:str): + if not host.startswith("http"): + raise TypeError("Invalid host url\n Host should start with http or https") + + self._host = host self.api_client = ApiClient(Configuration(host)) self.conversation_message_api = ConversationMessageApi(self.api_client) self.conversation_messages_api = ConversationMessagesApi(self.api_client) @@ -86,10 +106,7 @@ def init_host(self,host): self.search_api = SearchApi(self.api_client) # Websocket urls - if not self.host.startswith("http"): - raise ValueError("Invalid host url\n Host should start with http or https") - ws_base_url:str = self.host.replace('http','ws') - + ws_base_url:str = host.replace('http','ws') self.ASSETS_IDENTIFIERS_WS_URL = ws_base_url + "/assets/stream/identifiers" self.AUTH_WS_URL = ws_base_url + "/user/stream" self.ASK_STREAM_WS_URL = ws_base_url + "/qgpt/stream" @@ -137,6 +154,7 @@ def ensure_initialization(self): """ Waits for all the assets/conversations and all the started websockets to open """ + self._check_startup() BaseWebsocket.wait_all() def close(self): @@ -151,17 +169,15 @@ def version(self) -> str: Returns Pieces OS Version """ return self.well_known_api.get_well_known_version() - + @property - def health(self) -> bool: + def health(self) -> str: """ - Returns True Pieces OS health is ok else False + Calls the well known health api + /.well-known/health [GET] """ - try: - return self.well_known_api.get_well_known_health_with_http_info().status_code == 200 - except: - pass - return False + return self.well_known_api.get_well_known_health() + def open_pieces_os(self) -> bool: """ @@ -169,14 +185,33 @@ def open_pieces_os(self) -> bool: Returns (bool): true if Pieces OS runned successfully else false """ + if self.is_pieces_running(): return True if self.local_os == "WINDOWS": subprocess.run(["start", "pieces://launch"], shell=True) elif self.local_os == "MACOS": subprocess.run(["open","pieces://launch"]) elif self.local_os == "LINUX": subprocess.run(["xdg-open","pieces://launch"]) - return self.health + return self.is_pieces_running(maxium_retries=3) -# Register the function to be called on exit -atexit.register(BaseWebsocket.close_all) + def is_pieces_running(self,maxium_retries=1) -> bool: + """ + Checks if Pieces OS is running or not + + Returns (bool): true if Pieces OS is running + """ + for _ in range(maxium_retries): + try: + with urllib.request.urlopen(f"{self.host}/.well-known/health", timeout=1) as response: + return response.status == 200 + except: + pass + return False + + def _check_startup(self): + if not self._startup(): + raise ValueError("PiecesClient is not started successfully\nPerhaps Pieces OS is not running") + +# Register the function to be called on exit +atexit.register(BaseWebsocket.close_all) \ No newline at end of file diff --git a/_pieces_lib/pieces_os_client/wrapper/websockets/base_websocket.py b/_pieces_lib/pieces_os_client/wrapper/websockets/base_websocket.py index 26b0f2f..e7df13e 100644 --- a/_pieces_lib/pieces_os_client/wrapper/websockets/base_websocket.py +++ b/_pieces_lib/pieces_os_client/wrapper/websockets/base_websocket.py @@ -103,7 +103,7 @@ def close(self): """ Close the websocket connection and stop the thread. """ - if self.running: + if self.running and self.ws: self.ws.close() self.thread.join() self.running = False From 6ea97e2adeca4c32957aeb93b857bcc5b75e103d Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Sat, 7 Sep 2024 23:05:07 +0300 Subject: [PATCH 20/30] fix imports --- assets/export_command.py | 2 +- assets/list_assets.py | 3 ++- assets/save_asset.py | 1 - event_listener.py | 1 - main.py | 16 ++++++++++++---- misc/about_command.py | 2 +- misc/onboarding_command.py | 2 +- misc/reload_command.py | 2 +- settings.py | 10 +++++----- 9 files changed, 23 insertions(+), 16 deletions(-) diff --git a/assets/export_command.py b/assets/export_command.py index eb1f6a0..ad46629 100644 --- a/assets/export_command.py +++ b/assets/export_command.py @@ -2,7 +2,7 @@ import mdpopups import os import re -from typing import Self +from .._pieces_lib.typing_extensions import Self from .._pieces_lib.pieces_os_client.wrapper.basic_identifier.asset import BasicAsset from .list_assets import PiecesAssetIdInputHandler,A_TAG_STYLE from .ext_map import file_map diff --git a/assets/list_assets.py b/assets/list_assets.py index 6913202..16a94d2 100644 --- a/assets/list_assets.py +++ b/assets/list_assets.py @@ -2,6 +2,7 @@ import sublime import mdpopups import re +from typing import List from .._pieces_lib.pieces_os_client.wrapper.websockets import AssetsIdentifiersWS from .._pieces_lib.pieces_os_client.wrapper.basic_identifier import BasicAsset @@ -78,7 +79,7 @@ class PiecesAssetIdInputHandler(sublime_plugin.ListInputHandler): def list_items(self): return self.get_assets_list(PiecesSettings.api_client.assets()) - def get_assets_list(self,assets_snapshot:list[BasicAsset]): + def get_assets_list(self,assets_snapshot:List[BasicAsset]): assets_list = [] for basic_asset in assets_snapshot: name = basic_asset.name diff --git a/assets/save_asset.py b/assets/save_asset.py index 133a899..0bad9ca 100644 --- a/assets/save_asset.py +++ b/assets/save_asset.py @@ -3,7 +3,6 @@ from .._pieces_lib.pieces_os_client import ClassificationGenericEnum,FormatApi from .._pieces_lib.pieces_os_client.wrapper.basic_identifier.asset import BasicAsset from ..settings import PiecesSettings -from .assets_snapshot import AssetSnapshot diff --git a/event_listener.py b/event_listener.py index a0fc330..89f1409 100644 --- a/event_listener.py +++ b/event_listener.py @@ -14,7 +14,6 @@ class PiecesEventListener(sublime_plugin.EventListener): secondary_view = None # Used in the ask to know the secondary view at insert - commands_to_exclude = ["pieces_onboarding","pieces_reload","pieces_support"] onboarding_commands_dict = { "pieces_create_asset":"create", diff --git a/main.py b/main.py index 76305bf..421bfbe 100644 --- a/main.py +++ b/main.py @@ -3,7 +3,11 @@ from .copilot.ask_command import copilot import sublime from ._pieces_lib.pieces_os_client.wrapper.version_compatibility import VersionChecker,UpdateEnum -from ._pieces_lib.pieces_os_client.wrapper.websockets import BaseWebsocket,AuthWS,HealthWS +from ._pieces_lib.pieces_os_client.wrapper.websockets import ( + BaseWebsocket, + AuthWS,HealthWS, + ConversationWS, + AssetsIdentifiersWS) # load the commands from .assets import * @@ -18,6 +22,11 @@ def startup(): + ConversationWS(PiecesSettings.api_client) + AssetsIdentifiersWS(PiecesSettings.api_client) + AuthWS(PiecesSettings.api_client,PiecesSettings.api_client.user.on_user_callback) + BaseWebsocket.start_all() + pieces_os_version = PiecesSettings.api_client.version version_result = VersionChecker(PIECES_OS_MIN_VERSION,PIECES_OS_MAX_VERSION,pieces_os_version).version_check() if version_result.compatible: @@ -45,11 +54,10 @@ def startup(): def on_message(message): if message == "OK": - PiecesSettings.health = message PiecesSettings.is_loaded = True else: PiecesSettings.is_loaded = False - print("Please make sure Pieces OS is running\n") + print("Please make sure Pieces OS is running") def on_close(ws): PiecesSettings.is_loaded = False @@ -61,7 +69,7 @@ def plugin_loaded(): PiecesSettings.host_init(host) # Intilize the hosts url # callbacks needed onchange settings PiecesSettings.on_model_change_callbacks.append(copilot.update_status_bar) - health = PiecesSettings.api_client.health + health = PiecesSettings.api_client.is_pieces_running() if PiecesSettings.get_settings().get("auto_start_pieces_os") and not health: health = PiecesSettings.api_client.open_pieces_os() diff --git a/misc/about_command.py b/misc/about_command.py index f09fe4d..0cc9e2b 100644 --- a/misc/about_command.py +++ b/misc/about_command.py @@ -1,4 +1,4 @@ -from settings import PiecesSettings +from ..settings import PiecesSettings import sublime import sublime_plugin import mdpopups diff --git a/misc/onboarding_command.py b/misc/onboarding_command.py index ea16837..090c506 100644 --- a/misc/onboarding_command.py +++ b/misc/onboarding_command.py @@ -169,7 +169,7 @@ def reload(self,sheet): def pieces_os_status(self): - if PiecesSettings.health == "OK": + if PiecesSettings.api_client.is_pieces_running: return green('Installed Pieces OS is installed successfully') return red("Oops! Pieces OS is not running.") + """
    diff --git a/misc/reload_command.py b/misc/reload_command.py index 598e357..0fa02a9 100644 --- a/misc/reload_command.py +++ b/misc/reload_command.py @@ -11,7 +11,7 @@ def run(self): def reload_async(self): - if PiecesSettings.api_client.health: + if PiecesSettings.api_client.is_pieces_running(): try: sublime.set_timeout_async(self.run_reload_async) except Exception as e: diff --git a/settings.py b/settings.py index 6b0e668..3cc2aa5 100644 --- a/settings.py +++ b/settings.py @@ -15,10 +15,9 @@ class PiecesSettings: application=SeededTrackedApplication( name = "SUBLIME", platform = sublime.platform().upper() if sublime.platform() != 'osx' else "MACOS", - version = __version__))) + version = __version__)),connect_wesockets=False) _pool = None is_loaded = False # is the plugin loaded - health = "failed" ONBOARDING_SYNTAX = "Packages/Pieces/syntax/Onboarding.sublime-syntax" on_model_change_callbacks = [] # If the model change a function should be runned @@ -38,9 +37,10 @@ def host_init(cls,host): This method sets the host URL based on the configuration settings. If the host URL is not provided in the settings, it defaults to a specific URL based on the platform. It then creates the WebSocket base URL and defines the WebSocket URLs for different API endpoints. """ - if host != cls.api_client.host: - cls.api_client.init_host(host) - BaseWebsocket.reconnect_all() + if host != cls.api_client.host and host: + cls.api_client.host = host + if BaseWebsocket.instances: + sublime.set_timeout_async(BaseWebsocket.reconnect_all) @classmethod From 79973ed6162315fafa4c9909a04a27f451b085ee Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Sun, 8 Sep 2024 19:11:08 +0300 Subject: [PATCH 21/30] bug fixes --- .../wrapper/basic_identifier/asset.py | 15 ++++++++++----- .../wrapper/websockets/base_websocket.py | 2 +- assets/list_assets.py | 4 +--- copilot/ask_command.py | 14 ++++++++++++-- copilot/ask_view.py | 11 ++++++----- event_listener.py | 2 ++ main.py | 6 +++--- 7 files changed, 35 insertions(+), 19 deletions(-) diff --git a/_pieces_lib/pieces_os_client/wrapper/basic_identifier/asset.py b/_pieces_lib/pieces_os_client/wrapper/basic_identifier/asset.py index a97c5fb..1d7b899 100644 --- a/_pieces_lib/pieces_os_client/wrapper/basic_identifier/asset.py +++ b/_pieces_lib/pieces_os_client/wrapper/basic_identifier/asset.py @@ -63,11 +63,16 @@ def raw_content(self) -> Optional[str]: raise ValueError('Unable to get OCR content') return content else: - return ( - self.asset.original.reference.fragment.string.raw or - self.asset.preview.base.reference.fragment.string.raw or - '' - ) + try: + fragment_raw = self.asset.original.reference.fragment.string.raw + except AttributeError: + fragment_raw = "" + try: + preview_raw = self.asset.preview.base.reference.fragment.string.raw + except AttributeError: + preview_raw = "" + + return preview_raw or fragment_raw or '' @raw_content.setter def raw_content(self, content: str): diff --git a/_pieces_lib/pieces_os_client/wrapper/websockets/base_websocket.py b/_pieces_lib/pieces_os_client/wrapper/websockets/base_websocket.py index e7df13e..d4fb2b1 100644 --- a/_pieces_lib/pieces_os_client/wrapper/websockets/base_websocket.py +++ b/_pieces_lib/pieces_os_client/wrapper/websockets/base_websocket.py @@ -24,7 +24,7 @@ def __init__(self, on_message_callback: Callable[[str], None], on_open_callback: Optional[Callable[[websocket.WebSocketApp], None]] = None, on_error: Optional[Callable[[websocket.WebSocketApp, Exception], None]] = None, - on_close: Optional[Callable[[websocket.WebSocketApp], None]] = None): + on_close: Optional[Callable[[websocket.WebSocketApp,str,str], None]] = None): """ Initialize the BaseWebsocket instance. diff --git a/assets/list_assets.py b/assets/list_assets.py index 16a94d2..3393f13 100644 --- a/assets/list_assets.py +++ b/assets/list_assets.py @@ -25,14 +25,12 @@ def run_async(self): self.sheet = self.window.new_html_sheet("Loading","") self.sheet_id = self.sheet.id() self.update_sheet(self.sheet,self.pieces_asset_id) - @classmethod def update_sheet(cls,sheet,asset_id,buttons_kwargs={}): - api_instance = AssetApi(PiecesSettings.api_client) try: - api_response = api_instance.asset_specific_asset_export(asset_id, "MD") + api_response = PiecesSettings.api_client.asset_api.asset_specific_asset_export(asset_id, "MD") except: return sublime.error_message("Asset Not Found") diff --git a/copilot/ask_command.py b/copilot/ask_command.py index 397d0cc..c3c9061 100644 --- a/copilot/ask_command.py +++ b/copilot/ask_command.py @@ -60,8 +60,18 @@ def list_items(self): sublime.ListInputItem( text=chat.name, value=chat.id, - details=chat.description.replace("\n","") if chat.description else "") - for chat in PiecesSettings.api_client.copilot.chats()] + details=self.get_annotation(chat)) + for chat in PiecesSettings.api_client.copilot.chats()] + + def get_annotation(self,chat): + try: + annotation = " " + annotations = chat.conversation.annotations + if annotations and annotations.indices: + annotation = PiecesSettings.api_client.annotation_api.annotation_specific_annotation_snapshot(list(annotations.indices.keys())[0]).text.replace("\n"," ") + return annotation + except: + return "" def placeholder(self): return "Choose a conversation or start new one" diff --git a/copilot/ask_view.py b/copilot/ask_view.py index b646654..0c75c88 100644 --- a/copilot/ask_view.py +++ b/copilot/ask_view.py @@ -102,8 +102,6 @@ def update_status_bar(self): @property def show_cursor(self): self.update_status_bar() - self.gpt_view.run_command("append",{"characters":">>> "}) - self.end_response += 4 # ">>> " 4 characters region = sublime.Region(self.gpt_view.size(), self.gpt_view.size()) point_phantom = self.gpt_view.line(region.a).begin() @@ -121,7 +119,7 @@ def show_cursor(self): icon=f"Packages/Pieces/copilot/images/copilot-icon-{ui}.png", flags=sublime.HIDDEN ) - self.add_role("User: ") + self.add_role("User") self.select_end @property @@ -208,8 +206,11 @@ def ask(self,pipeline=None): sublime.set_timeout_async(lambda: PiecesSettings.api_client.copilot.stream_question(query,pipeline)) def add_role(self,role): - self.gpt_view.run_command("append",{"characters":f"{role}: "}) - self.end_response += len(role) + 2 + text = f'>>> **{role}**: ' + text_size = len(text) + self.gpt_view.run_command("append",{"characters":text}) + self.end_response += text_size + def add_code_phantoms(self): view = self.gpt_view diff --git a/event_listener.py b/event_listener.py index 89f1409..3d61b15 100644 --- a/event_listener.py +++ b/event_listener.py @@ -103,6 +103,8 @@ def on_deactivated(view): copilot.secondary_view = view def on_query_completions(self, view:sublime.View, prefix, locations): + if not PiecesSettings.autocomplete_snippet or not PiecesSettings.is_loaded: + return syntax = view.syntax() if not syntax: return diff --git a/main.py b/main.py index 421bfbe..8981f42 100644 --- a/main.py +++ b/main.py @@ -59,7 +59,7 @@ def on_message(message): PiecesSettings.is_loaded = False print("Please make sure Pieces OS is running") -def on_close(ws): +def on_close(): PiecesSettings.is_loaded = False def plugin_loaded(): @@ -70,11 +70,11 @@ def plugin_loaded(): # callbacks needed onchange settings PiecesSettings.on_model_change_callbacks.append(copilot.update_status_bar) health = PiecesSettings.api_client.is_pieces_running() - if PiecesSettings.get_settings().get("auto_start_pieces_os") and not health: + if PiecesSettings.get_settings().get("auto_start_pieces_os"): health = PiecesSettings.api_client.open_pieces_os() if health: - HealthWS(PiecesSettings.api_client, on_message, startup, on_close).start() + HealthWS(PiecesSettings.api_client, on_message, lambda x:startup(), on_close=lambda x,y,z:on_close).start() else: print("Couldn't start pieces OS\nPlease run Pieces OS and restart the editor to ensure everything is running properly") BaseWebsocket.close_all() From b8e2879787e587405ae9e5874e1e348109e2a776 Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Mon, 9 Sep 2024 03:39:02 +0300 Subject: [PATCH 22/30] fix copilot is not streaming --- .../pieces_os_client/wrapper/copilot.py | 20 +++-------- copilot/ask_about_command.py | 36 +++++++++---------- copilot/ask_command.py | 2 ++ copilot/ask_view.py | 15 ++++---- copilot/context_manager.py | 6 ++-- 5 files changed, 33 insertions(+), 46 deletions(-) diff --git a/_pieces_lib/pieces_os_client/wrapper/copilot.py b/_pieces_lib/pieces_os_client/wrapper/copilot.py index a157d96..2be1cc2 100644 --- a/_pieces_lib/pieces_os_client/wrapper/copilot.py +++ b/_pieces_lib/pieces_os_client/wrapper/copilot.py @@ -36,6 +36,7 @@ def __init__(self, pieces_client: "PiecesClient"): self.ask_stream_ws = AskStreamWS(self.pieces_client, self._on_message_queue.put) self.context = Context(pieces_client) self._chat = None + self._chat_id = None def stream_question(self, query: str, @@ -53,7 +54,6 @@ def stream_question(self, Yields: QGPTStreamOutput: The streamed output from the QGPT model. """ - id = self._chat.id if self._chat else None relevant = self.context._relevance_api(query) if self.context._check_relevant_existance else RelevantQGPTSeeds(iterable=[]) self.ask_stream_ws.send_message( QGPTStreamInput( @@ -64,17 +64,10 @@ def stream_question(self, model=self.pieces_client.model_id, pipeline=pipeline ), - conversation=id, + conversation=self._chat_id, ) ) - while True: - message: QGPTStreamOutput = self._on_message_queue.get() - if message.status != QGPTStreamEnum.IN_MINUS_PROGRESS: # Loop only while in progress - yield message - self.chat = BasicChat(message.conversation) # Save the conversation - break - yield message def question(self, @@ -122,7 +115,6 @@ def chat(self) -> Optional[BasicChat]: Returns: Optional[BasicChat]: The current chat instance or None if no chat is set. """ - self.context.clear() # clear the context on changing the conversation return self._chat @chat.setter @@ -132,13 +124,11 @@ def chat(self, chat: Optional[BasicChat]): Args: chat (Optional[BasicChat]): The chat instance to set. - - Raises: - ValueError: If the provided chat is not a valid BasicChat instance. + use chat = None if you want to create a new conversation on asking """ - if not (chat is None or isinstance(chat, BasicChat)): - raise ValueError("Not a valid chat") self._chat = chat + self.context.clear() # clear the context on changing the conversation + self._chat_id = chat.id if chat else None def create_chat(self, name:Optional[str]=None): diff --git a/copilot/ask_about_command.py b/copilot/ask_about_command.py index 670aa73..0371529 100644 --- a/copilot/ask_about_command.py +++ b/copilot/ask_about_command.py @@ -1,44 +1,40 @@ import sublime_plugin import sublime -from .ask_command import copilot -from ..assets.create_asset import PiecesCreateAssetCommand +from .ask_command import copilot,PiecesQueryInputHandler from ..settings import PiecesSettings + class PiecesAskStreamAboutCommand(sublime_plugin.TextCommand): - def run(self,edit,type): + def run(self,edit,type,pieces_query): + self.context = PiecesSettings.api_client.copilot.context self.before_query = "" if type == "file": path = self.view.file_name() if not path: return - - placeholder = "Ask about that file" - self.context = {"paths":[path]} + self.context.paths.append(path) elif type == "folder": window = self.view.window() if not window: return paths = window.folders() if not paths: return - - self.context = {"paths":paths} - placeholder = "Ask a question about your current project" + [self.context.paths.append(path) for path in paths] elif type == "section": - seed = PiecesCreateAssetCommand(self.view).get_seeds() - if not seed: return - self.before_query = str(seed.asset.format.fragment.string.raw) - self.context = {"seed":seed} - placeholder = "Ask about the current section" + # Get the all the selected text + data = "\n".join([self.view.substr(selection) for selection in self.view.sel()]) + if not data: + return sublime.error_message("Please select a text") + self.context.raw_assets.append(data) - self.view.window().show_input_panel(placeholder, "",self.on_done, None, None) - - def on_done(self,query): copilot.render_conversation(None) # Create conversation if not already - copilot.add_context(**self.context) - if self.before_query: query = self.before_query + query - copilot.add_query(query) # Add the query + if self.before_query: + pieces_query = self.before_query + pieces_query + copilot.add_query(pieces_query) # Add the query copilot.gpt_view.run_command("pieces_enter_response") def is_enabled(self): return PiecesSettings.is_loaded + def input(self, args): + return PiecesQueryInputHandler() diff --git a/copilot/ask_command.py b/copilot/ask_command.py index c3c9061..caf8709 100644 --- a/copilot/ask_command.py +++ b/copilot/ask_command.py @@ -44,6 +44,8 @@ def next_input(self, args): class PiecesQueryInputHandler(sublime_plugin.TextInputHandler): def placeholder(self) -> str: return "Enter a query to ask the copilot about" + def validate(self, text: str) -> bool: + return bool(text.strip()) class PiecesEnterResponseCommand(sublime_plugin.TextCommand): diff --git a/copilot/ask_view.py b/copilot/ask_view.py index 0c75c88..f259701 100644 --- a/copilot/ask_view.py +++ b/copilot/ask_view.py @@ -163,11 +163,12 @@ def show_failed(self): def add_context_phantom(self,region): self.context_phantom_region = region - href = sublime.html_format_command("show_overlay", args={"overlay": "command_palette","text":"Pieces: Manage Conversation Context"}) ui = sublime.ui_info()["theme"]["style"] + if ui not in ["light","dark"]: + ui = "light" image = getattr(ContextImage,ui) self.context_phantom.update( - [sublime.Phantom(region,f"{image.format(style='width:20px;height:20px')}",sublime.LAYOUT_INLINE)] + [sublime.Phantom(region,f"{image.format(style='width:20px;height:20px')}",sublime.LAYOUT_INLINE)] ) def remove_context_phantom(self): self.context_phantom.update([]) @@ -207,9 +208,8 @@ def ask(self,pipeline=None): def add_role(self,role): text = f'>>> **{role}**: ' - text_size = len(text) self.gpt_view.run_command("append",{"characters":text}) - self.end_response += text_size + self.end_response = self.gpt_view.size() def add_code_phantoms(self): @@ -226,7 +226,6 @@ def add_code_phantoms(self): id = str(len(self.phantom_details_dict)) # Create a phantom at the end of each code block - end_point = match.end() region = sublime.Region(end_point+self.last_edit_phantom, end_point+self.last_edit_phantom) self.phantom_details_dict[id] = {"code":match.group(1),"region":region} @@ -280,16 +279,16 @@ def render_conversation(self,conversation_id): if conversation_id: try: - conversation = BasicChat(conversation_id) - conversation.conversation + PiecesSettings.api_client.copilot.chat = BasicChat(conversation_id) except ValueError: return sublime.error_message("Conversation not found") # Error conversation not found else: + PiecesSettings.api_client.copilot.chat = None self.gpt_view # Nothing need to be rendered if hasattr(self,"_view_name"): delattr(self,"_view_name") return - self.view_name = conversation.name + self.view_name = PiecesSettings.api_client.copilot.chat.name self.gpt_view.run_command("select_all") self.gpt_view.run_command("right_delete") # Clear the cursor created by default ">>>" diff --git a/copilot/context_manager.py b/copilot/context_manager.py index 956a1de..4bf6add 100644 --- a/copilot/context_manager.py +++ b/copilot/context_manager.py @@ -5,8 +5,8 @@ from ..assets.list_assets import PiecesAssetIdInputHandler -class PiecesContextManagerCommand(sublime_plugin.TextCommand): - def run(self, edit: sublime.Edit,context=None,pieces_asset_id=None,context_remove=None): +class PiecesContextManagerCommand(sublime_plugin.WindowCommand): + def run(self,context,pieces_asset_id=None,context_remove=None): if context_remove: key,idx = context_remove.split("_") idx = int(idx) @@ -21,7 +21,7 @@ def run(self, edit: sublime.Edit,context=None,pieces_asset_id=None,context_remov PiecesSettings.api_client.copilot.context.assets.append(BasicAsset(pieces_asset_id)) def is_enabled(self): - return self.view.settings().get("PIECES_GPT_VIEW",False) and PiecesSettings.is_loaded + return sublime.active_window().active_view().settings().get("PIECES_GPT_VIEW",False) and PiecesSettings.is_loaded def input(self,args): return PiecesContextInputHandler() From 28420871485c200a0ed74882308e61581ae64b14 Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Mon, 9 Sep 2024 03:39:14 +0300 Subject: [PATCH 23/30] add close command --- misc/__init__.py | 1 + misc/close_command.py | 13 +++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 misc/close_command.py diff --git a/misc/__init__.py b/misc/__init__.py index 91cac2b..1484dd2 100644 --- a/misc/__init__.py +++ b/misc/__init__.py @@ -3,3 +3,4 @@ from .open_pieces_command import PiecesOpenPiecesCommand from .about_command import PiecesOpenNotesCommand,PiecesAboutCommand from .onboarding_command import PiecesOnboardingCommand,PiecesOnboardingCommandsCommand,PiecesResetOnboardingCommand +from .close_command import PiecesCloseOsCommand \ No newline at end of file diff --git a/misc/close_command.py b/misc/close_command.py new file mode 100644 index 0000000..5a1f948 --- /dev/null +++ b/misc/close_command.py @@ -0,0 +1,13 @@ +import sublime +import sublime_plugin +from ..settings import PiecesSettings + + + +class PiecesCloseOsCommand(sublime_plugin.ApplicationCommand): + def run(self): + PiecesSettings.api_client.os_api.os_terminate() + sublime.status_message(f"Pieces OS closed successfully") + + def is_enabled(self): + return PiecesSettings.is_loaded From 0924f2c6381f2fa7672bc81a1c83d7f9c40d27f1 Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Mon, 9 Sep 2024 03:39:44 +0300 Subject: [PATCH 24/30] fix auto open pieces --- misc/about_command.py | 2 +- misc/onboarding_command.py | 2 +- misc/open_pieces_command.py | 1 + misc/reload_command.py | 11 ++--------- 4 files changed, 5 insertions(+), 11 deletions(-) diff --git a/misc/about_command.py b/misc/about_command.py index 0cc9e2b..5a147ff 100644 --- a/misc/about_command.py +++ b/misc/about_command.py @@ -27,7 +27,7 @@ ## Version - Plugin Version: {__version__} -- Pieces Version: {PiecesSettings.api_client.version if PiecesSettings.api_client.version else "Unknown"} +- Pieces Version: {PiecesSettings.api_client.version if PiecesSettings.api_client.is_pieces_running() else "Unknown"} """ class PiecesAboutCommand(sublime_plugin.WindowCommand): def run(self): diff --git a/misc/onboarding_command.py b/misc/onboarding_command.py index 090c506..e248d08 100644 --- a/misc/onboarding_command.py +++ b/misc/onboarding_command.py @@ -248,7 +248,7 @@ def add_onboarding_settings(cls, **kwargs): str2 = "?" def str_size(s): - return len(s.encode('utf-8')) + return len(s.encode('utf-8')) str_size(str1) str_size(str2) diff --git a/misc/open_pieces_command.py b/misc/open_pieces_command.py index aea0e9a..8410371 100644 --- a/misc/open_pieces_command.py +++ b/misc/open_pieces_command.py @@ -12,6 +12,7 @@ def run_async(): view.set_status("OPEN_STATUS","Opening Pieces OS") if view else None if PiecesSettings.api_client.open_pieces_os(): view.erase_status("OPEN_STATUS") if view else None + sublime.run_command("pieces_reload") sublime.status_message("Pieces OS lunched successfully") else: view.erase_status("OPEN_STATUS") if view else None diff --git a/misc/reload_command.py b/misc/reload_command.py index 0fa02a9..5914b57 100644 --- a/misc/reload_command.py +++ b/misc/reload_command.py @@ -13,17 +13,10 @@ def run(self): def reload_async(self): if PiecesSettings.api_client.is_pieces_running(): try: - sublime.set_timeout_async(self.run_reload_async) + PiecesSettings.on_settings_change(all = True) + sublime.status_message(f"Reloading [completed]") except Exception as e: sublime.error_message(f"Error during reload: {e}") else: sublime.status_message(f"Pieces OS is offline") - @staticmethod - def run_reload_async(): - PiecesSettings.on_settings_change(all = True) - BaseWebsocket.reconnect_all() - sublime.status_message(f"Reloading [completed]") - - def is_enabled(self) -> bool: - return PiecesSettings.is_loaded \ No newline at end of file From 775ba60e50a597ea0b7879419851e12ce3db6c83 Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Mon, 9 Sep 2024 03:39:57 +0300 Subject: [PATCH 25/30] add the close to the sublime-commands --- Pieces.sublime-commands | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Pieces.sublime-commands b/Pieces.sublime-commands index cf6f93b..e88f8ce 100644 --- a/Pieces.sublime-commands +++ b/Pieces.sublime-commands @@ -83,5 +83,9 @@ { "caption": "Pieces: Export Pieces Material", "command":"pieces_export_asset_to_sublime" + }, + { + "caption": "Pieces: Close Pieces OS", + "command":"pieces_close_os" } ] \ No newline at end of file From 04ee8c3f4dcbfcea5db14190e9f3c670c03ff28b Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Mon, 9 Sep 2024 03:40:17 +0300 Subject: [PATCH 26/30] fix startup when Pieces OS is not running --- event_listener.py | 1 - main.py | 12 ++++++++---- settings.py | 7 ++++--- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/event_listener.py b/event_listener.py index 3d61b15..8dc8024 100644 --- a/event_listener.py +++ b/event_listener.py @@ -69,7 +69,6 @@ def on_query_context(self,view,key, operator, operand, match_all): elif key == "pieces_copilot_add" or key == "pieces_copilot_remove": ## TRUE -> Means no operation will be done ## False -> Means operation can be done - if view.settings().get("PIECES_GPT_VIEW"): if not copilot.can_type: return True # If we can't type then don't accpet operations diff --git a/main.py b/main.py index 8981f42..c35f579 100644 --- a/main.py +++ b/main.py @@ -22,6 +22,9 @@ def startup(): + # Use the auth callback instead of the default one in the client + PiecesSettings.api_client.user.on_user_callback = AuthUser.on_user_callback + ConversationWS(PiecesSettings.api_client) AssetsIdentifiersWS(PiecesSettings.api_client) AuthWS(PiecesSettings.api_client,PiecesSettings.api_client.user.on_user_callback) @@ -45,7 +48,6 @@ def startup(): # User Weboscket PiecesSettings.create_auth_output_panel() - PiecesSettings.api_client.user.on_user_callback = AuthUser.on_user_callback # Lunch Onboarding if it is the first time if not PiecesOnboardingCommand.get_onboarding_settings().get("lunch_onboarding",False): @@ -61,6 +63,7 @@ def on_message(message): def on_close(): PiecesSettings.is_loaded = False + print("Please make sure Pieces OS is running") def plugin_loaded(): settings = PiecesSettings.get_settings() @@ -70,13 +73,14 @@ def plugin_loaded(): # callbacks needed onchange settings PiecesSettings.on_model_change_callbacks.append(copilot.update_status_bar) health = PiecesSettings.api_client.is_pieces_running() + health_ws = HealthWS(PiecesSettings.api_client, on_message, lambda x:startup(), on_close=lambda x,y,z:on_close()) if PiecesSettings.get_settings().get("auto_start_pieces_os"): - health = PiecesSettings.api_client.open_pieces_os() + health = PiecesSettings.api_client.open_pieces_os() if health: - HealthWS(PiecesSettings.api_client, on_message, lambda x:startup(), on_close=lambda x,y,z:on_close).start() + health_ws.start() else: - print("Couldn't start pieces OS\nPlease run Pieces OS and restart the editor to ensure everything is running properly") + print("Please run Pieces OS and restart the editor to ensure everything is running properly") BaseWebsocket.close_all() diff --git a/settings.py b/settings.py index 3cc2aa5..f7c6c1d 100644 --- a/settings.py +++ b/settings.py @@ -39,8 +39,9 @@ def host_init(cls,host): """ if host != cls.api_client.host and host: cls.api_client.host = host - if BaseWebsocket.instances: - sublime.set_timeout_async(BaseWebsocket.reconnect_all) + + if BaseWebsocket.instances: + BaseWebsocket.reconnect_all() @classmethod @@ -71,7 +72,7 @@ def on_settings_change(cls,all = False): cls.host_init(host = host) cls.models_init(model = model) - if cls.api_client.model_name != model or all: + elif cls.api_client.model_name != model: cls.models_init(model = model) @staticmethod From d5c23d67816b65792581365054d990b50a46558a Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Mon, 9 Sep 2024 03:40:48 +0300 Subject: [PATCH 27/30] fix Pieces OS client has no attribute called model --- _pieces_lib/pieces_os_client/wrapper/client.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/_pieces_lib/pieces_os_client/wrapper/client.py b/_pieces_lib/pieces_os_client/wrapper/client.py index 774f69b..67a32bf 100644 --- a/_pieces_lib/pieces_os_client/wrapper/client.py +++ b/_pieces_lib/pieces_os_client/wrapper/client.py @@ -42,6 +42,7 @@ def __init__(self, host:str="", seeded_connector: Optional[SeededConnectorConnec if not host: host = "http://localhost:5323" if 'Linux' in platform.platform() else "http://localhost:1000" + self.models = None self.host = host self._is_started_runned = False self.local_os = platform.system().upper() if platform.system().upper() in ["WINDOWS","LINUX","DARWIN"] else "WEB" @@ -56,7 +57,6 @@ def __init__(self, host:str="", seeded_connector: Optional[SeededConnectorConnec self.copilot = Copilot(self) self._startup() - def _startup(self) -> bool: if self._is_started_runned: return True if not self.is_pieces_running(): return False @@ -71,7 +71,6 @@ def _startup(self) -> bool: # Start all initilized websockets BaseWebsocket.start_all() - self.models = None self.model_name = "GPT-3.5-turbo Chat Model" return True From deb827f14658e4b348d76171242b7d173db62ca8 Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Mon, 9 Sep 2024 03:42:02 +0300 Subject: [PATCH 28/30] add new version for the changelog --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b515dd9..4bdb5b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,14 @@ # CHANGELOG +# 1.3.0 + +## Sept 10, 2024 + +- Major speed stability +- Fix some typos +- Better Copilot UI +- Major bug fixes including many assets and Copilot commands +- New Pieces Close command + # [1.2.0](https://github.com/pieces-app/plugin_sublime/milestone/3) ## Jul 15, 2024 From 3bf9092b0d035f10b62ac0299c27187d467be398 Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Mon, 9 Sep 2024 03:42:10 +0300 Subject: [PATCH 29/30] bump version --- _version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_version.py b/_version.py index 10aa336..67bc602 100644 --- a/_version.py +++ b/_version.py @@ -1 +1 @@ -__version__ = "1.2.3" +__version__ = "1.3.0" From feda016d24986024b329fff51adb9b10b5171b18 Mon Sep 17 00:00:00 2001 From: Bishoy-at-pieces Date: Mon, 9 Sep 2024 03:46:42 +0300 Subject: [PATCH 30/30] add the new message.txt --- messages/1.3.0.txt | 22 ++++++++++++++++++++++ messages/install.txt | 4 ++-- 2 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 messages/1.3.0.txt diff --git a/messages/1.3.0.txt b/messages/1.3.0.txt new file mode 100644 index 0000000..7ed7b2b --- /dev/null +++ b/messages/1.3.0.txt @@ -0,0 +1,22 @@ +Pieces for Sublime + +Version 1.3.0 +------------- + +Bug fixes +- Major speed stability (much faster startup) +- Fix some typos +- Major bug fixes including many assets and Copilot commands + +New Features +- New Pieces Close command +- Better Copilot UI + + +Useful links: +------------- +Website: https://pieces.app +GitHub: https://github.com/pieces-app/plugin_sublime +Discord: https://discord.gg/getpieces +YouTube: https://youtube.com/@getpieces + diff --git a/messages/install.txt b/messages/install.txt index f96d669..2b69528 100644 --- a/messages/install.txt +++ b/messages/install.txt @@ -1,5 +1,5 @@ -Welcome to Pieces Sublime Plugin --------------------------------- +Pieces for Sublime +------------------- To get started, please make sure you have Pieces OS installed, running, and up-to-date.