diff --git a/.github/workflows/shared-tests.yml b/.github/workflows/shared-tests.yml index 2c54d2b7..0ab797d8 100644 --- a/.github/workflows/shared-tests.yml +++ b/.github/workflows/shared-tests.yml @@ -27,7 +27,7 @@ jobs: - name: 'Run Tests' run: | pip install -r requirements.txt - python -m coverage run --source=skyflow --omit=skyflow/generated/*,skyflow/utils/validations/*,skyflow/vault/data/*,skyflow/vault/tokens/*,skyflow/vault/connection/*,skyflow/error/*,skyflow/utils/enums/*,skyflow/vault/controller/_audit.py,skyflow/vault/controller/_bin_look_up.py -m unittest discover + python -m coverage run --source=skyflow --omit=skyflow/generated/*,skyflow/utils/validations/*,skyflow/vault/data/*,skyflow/vault/detect/*,skyflow/vault/tokens/*,skyflow/vault/connection/*,skyflow/error/*,skyflow/utils/enums/*,skyflow/vault/controller/_audit.py,skyflow/vault/controller/_bin_look_up.py -m unittest discover - name: coverage run: coverage xml -o test-coverage.xml diff --git a/skyflow/generated/rest/__init__.py b/skyflow/generated/rest/__init__.py index 1c97d8e2..9ff683cb 100644 --- a/skyflow/generated/rest/__init__.py +++ b/skyflow/generated/rest/__init__.py @@ -21,6 +21,7 @@ DeidentifyStatusResponse, DeidentifyStatusResponseOutputType, DeidentifyStatusResponseStatus, + DeidentifyStatusResponseWordCharacterCount, DeidentifyStringResponse, DetectDataAccuracy, DetectDataEntities, @@ -180,6 +181,7 @@ "DeidentifyStatusResponse", "DeidentifyStatusResponseOutputType", "DeidentifyStatusResponseStatus", + "DeidentifyStatusResponseWordCharacterCount", "DeidentifyStringResponse", "DeidentifyStructuredTextRequestFile", "DeidentifyStructuredTextRequestFileDataFormat", diff --git a/skyflow/generated/rest/audit/client.py b/skyflow/generated/rest/audit/client.py index 7e22b077..34d589d1 100644 --- a/skyflow/generated/rest/audit/client.py +++ b/skyflow/generated/rest/audit/client.py @@ -200,8 +200,13 @@ def audit_service_list_audit_events( Examples -------- from skyflow import Skyflow - client = Skyflow(token="YOUR_TOKEN", ) - client.audit.audit_service_list_audit_events(filter_ops_account_id='filterOps.accountID', ) + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.audit.audit_service_list_audit_events( + filter_ops_account_id="filterOps.accountID", + ) """ _response = self._raw_client.audit_service_list_audit_events( filter_ops_account_id=filter_ops_account_id, @@ -415,11 +420,21 @@ async def audit_service_list_audit_events( Examples -------- - from skyflow import AsyncSkyflow import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + from skyflow import AsyncSkyflow + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.audit.audit_service_list_audit_events(filter_ops_account_id='filterOps.accountID', ) + await client.audit.audit_service_list_audit_events( + filter_ops_account_id="filterOps.accountID", + ) + + asyncio.run(main()) """ _response = await self._raw_client.audit_service_list_audit_events( diff --git a/skyflow/generated/rest/authentication/client.py b/skyflow/generated/rest/authentication/client.py index 81408a26..2f1e804e 100644 --- a/skyflow/generated/rest/authentication/client.py +++ b/skyflow/generated/rest/authentication/client.py @@ -71,8 +71,14 @@ def authentication_service_get_auth_token( Examples -------- from skyflow import Skyflow - client = Skyflow(token="YOUR_TOKEN", ) - client.authentication.authentication_service_get_auth_token(grant_type='urn:ietf:params:oauth:grant-type:jwt-bearer', assertion='eyLhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaXNzIjoiY29tcGFueSIsImV4cCI6MTYxNTE5MzgwNywiaWF0IjoxNjE1MTY1MDQwLCJhdWQiOiKzb21lYXVkaWVuY2UifQ.4pcPyMDQ9o1PSyXnrXCjTwXyr4BSezdI1AVTmud2fU3', ) + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.authentication.authentication_service_get_auth_token( + grant_type="urn:ietf:params:oauth:grant-type:jwt-bearer", + assertion="eyLhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaXNzIjoiY29tcGFueSIsImV4cCI6MTYxNTE5MzgwNywiaWF0IjoxNjE1MTY1MDQwLCJhdWQiOiKzb21lYXVkaWVuY2UifQ.4pcPyMDQ9o1PSyXnrXCjTwXyr4BSezdI1AVTmud2fU3", + ) """ _response = self._raw_client.authentication_service_get_auth_token( grant_type=grant_type, @@ -145,11 +151,22 @@ async def authentication_service_get_auth_token( Examples -------- - from skyflow import AsyncSkyflow import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + from skyflow import AsyncSkyflow + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.authentication.authentication_service_get_auth_token(grant_type='urn:ietf:params:oauth:grant-type:jwt-bearer', assertion='eyLhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaXNzIjoiY29tcGFueSIsImV4cCI6MTYxNTE5MzgwNywiaWF0IjoxNjE1MTY1MDQwLCJhdWQiOiKzb21lYXVkaWVuY2UifQ.4pcPyMDQ9o1PSyXnrXCjTwXyr4BSezdI1AVTmud2fU3', ) + await client.authentication.authentication_service_get_auth_token( + grant_type="urn:ietf:params:oauth:grant-type:jwt-bearer", + assertion="eyLhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaXNzIjoiY29tcGFueSIsImV4cCI6MTYxNTE5MzgwNywiaWF0IjoxNjE1MTY1MDQwLCJhdWQiOiKzb21lYXVkaWVuY2UifQ.4pcPyMDQ9o1PSyXnrXCjTwXyr4BSezdI1AVTmud2fU3", + ) + + asyncio.run(main()) """ _response = await self._raw_client.authentication_service_get_auth_token( diff --git a/skyflow/generated/rest/bin_lookup/client.py b/skyflow/generated/rest/bin_lookup/client.py index a217ae60..fe8c892a 100644 --- a/skyflow/generated/rest/bin_lookup/client.py +++ b/skyflow/generated/rest/bin_lookup/client.py @@ -63,8 +63,13 @@ def bin_list_service_list_cards_of_bin( Examples -------- from skyflow import Skyflow - client = Skyflow(token="YOUR_TOKEN", ) - client.bin_lookup.bin_list_service_list_cards_of_bin(bin='012345', ) + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.bin_lookup.bin_list_service_list_cards_of_bin( + bin="012345", + ) """ _response = self._raw_client.bin_list_service_list_cards_of_bin( fields=fields, @@ -126,11 +131,21 @@ async def bin_list_service_list_cards_of_bin( Examples -------- - from skyflow import AsyncSkyflow import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + from skyflow import AsyncSkyflow + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.bin_lookup.bin_list_service_list_cards_of_bin(bin='012345', ) + await client.bin_lookup.bin_list_service_list_cards_of_bin( + bin="012345", + ) + + asyncio.run(main()) """ _response = await self._raw_client.bin_list_service_list_cards_of_bin( diff --git a/skyflow/generated/rest/client.py b/skyflow/generated/rest/client.py index 60dd336f..315d1f86 100644 --- a/skyflow/generated/rest/client.py +++ b/skyflow/generated/rest/client.py @@ -28,6 +28,8 @@ class Skyflow: environment : SkyflowEnvironment The environment to use for requests from the client. from .environment import SkyflowEnvironment + + Defaults to SkyflowEnvironment.PRODUCTION @@ -45,7 +47,10 @@ class Skyflow: Examples -------- from skyflow import Skyflow - client = Skyflow(token="YOUR_TOKEN", ) + + client = Skyflow( + token="YOUR_TOKEN", + ) """ def __init__( @@ -94,6 +99,8 @@ class AsyncSkyflow: environment : SkyflowEnvironment The environment to use for requests from the client. from .environment import SkyflowEnvironment + + Defaults to SkyflowEnvironment.PRODUCTION @@ -111,7 +118,10 @@ class AsyncSkyflow: Examples -------- from skyflow import AsyncSkyflow - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) """ def __init__( diff --git a/skyflow/generated/rest/core/client_wrapper.py b/skyflow/generated/rest/core/client_wrapper.py index 6a448618..67c11850 100644 --- a/skyflow/generated/rest/core/client_wrapper.py +++ b/skyflow/generated/rest/core/client_wrapper.py @@ -22,7 +22,7 @@ def get_headers(self) -> typing.Dict[str, str]: headers: typing.Dict[str, str] = { "X-Fern-Language": "Python", "X-Fern-SDK-Name": "skyflow.generated.rest", - "X-Fern-SDK-Version": "0.0.173", + "X-Fern-SDK-Version": "0.0.200", } headers["Authorization"] = f"Bearer {self._get_token()}" return headers diff --git a/skyflow/generated/rest/core/force_multipart.py b/skyflow/generated/rest/core/force_multipart.py new file mode 100644 index 00000000..ae24ccff --- /dev/null +++ b/skyflow/generated/rest/core/force_multipart.py @@ -0,0 +1,16 @@ +# This file was auto-generated by Fern from our API Definition. + + +class ForceMultipartDict(dict): + """ + A dictionary subclass that always evaluates to True in boolean contexts. + + This is used to force multipart/form-data encoding in HTTP requests even when + the dictionary is empty, which would normally evaluate to False. + """ + + def __bool__(self): + return True + + +FORCE_MULTIPART = ForceMultipartDict() diff --git a/skyflow/generated/rest/core/http_client.py b/skyflow/generated/rest/core/http_client.py index e7bd4f79..e4173f99 100644 --- a/skyflow/generated/rest/core/http_client.py +++ b/skyflow/generated/rest/core/http_client.py @@ -11,10 +11,12 @@ import httpx from .file import File, convert_file_dict_to_httpx_tuples +from .force_multipart import FORCE_MULTIPART from .jsonable_encoder import jsonable_encoder from .query_encoder import encode_query from .remove_none_from_dict import remove_none_from_dict from .request_options import RequestOptions +from httpx._types import RequestFiles INITIAL_RETRY_DELAY_SECONDS = 0.5 MAX_RETRY_DELAY_SECONDS = 10 @@ -178,11 +180,17 @@ def request( json: typing.Optional[typing.Any] = None, data: typing.Optional[typing.Any] = None, content: typing.Optional[typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]]] = None, - files: typing.Optional[typing.Dict[str, typing.Optional[typing.Union[File, typing.List[File]]]]] = None, + files: typing.Optional[ + typing.Union[ + typing.Dict[str, typing.Optional[typing.Union[File, typing.List[File]]]], + typing.List[typing.Tuple[str, File]], + ] + ] = None, headers: typing.Optional[typing.Dict[str, typing.Any]] = None, request_options: typing.Optional[RequestOptions] = None, retries: int = 2, omit: typing.Optional[typing.Any] = None, + force_multipart: typing.Optional[bool] = None, ) -> httpx.Response: base_url = self.get_base_url(base_url) timeout = ( @@ -193,6 +201,15 @@ def request( json_body, data_body = get_request_body(json=json, data=data, request_options=request_options, omit=omit) + request_files: typing.Optional[RequestFiles] = ( + convert_file_dict_to_httpx_tuples(remove_omit_from_dict(remove_none_from_dict(files), omit)) + if (files is not None and files is not omit and isinstance(files, dict)) + else None + ) + + if (request_files is None or len(request_files) == 0) and force_multipart: + request_files = FORCE_MULTIPART + response = self.httpx_client.request( method=method, url=urllib.parse.urljoin(f"{base_url}/", path), @@ -225,11 +242,7 @@ def request( json=json_body, data=data_body, content=content, - files=( - convert_file_dict_to_httpx_tuples(remove_omit_from_dict(remove_none_from_dict(files), omit)) - if (files is not None and files is not omit) - else None - ), + files=request_files, timeout=timeout, ) @@ -264,11 +277,17 @@ def stream( json: typing.Optional[typing.Any] = None, data: typing.Optional[typing.Any] = None, content: typing.Optional[typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]]] = None, - files: typing.Optional[typing.Dict[str, typing.Optional[typing.Union[File, typing.List[File]]]]] = None, + files: typing.Optional[ + typing.Union[ + typing.Dict[str, typing.Optional[typing.Union[File, typing.List[File]]]], + typing.List[typing.Tuple[str, File]], + ] + ] = None, headers: typing.Optional[typing.Dict[str, typing.Any]] = None, request_options: typing.Optional[RequestOptions] = None, retries: int = 2, omit: typing.Optional[typing.Any] = None, + force_multipart: typing.Optional[bool] = None, ) -> typing.Iterator[httpx.Response]: base_url = self.get_base_url(base_url) timeout = ( @@ -277,6 +296,15 @@ def stream( else self.base_timeout() ) + request_files: typing.Optional[RequestFiles] = ( + convert_file_dict_to_httpx_tuples(remove_omit_from_dict(remove_none_from_dict(files), omit)) + if (files is not None and files is not omit and isinstance(files, dict)) + else None + ) + + if (request_files is None or len(request_files) == 0) and force_multipart: + request_files = FORCE_MULTIPART + json_body, data_body = get_request_body(json=json, data=data, request_options=request_options, omit=omit) with self.httpx_client.stream( @@ -311,11 +339,7 @@ def stream( json=json_body, data=data_body, content=content, - files=( - convert_file_dict_to_httpx_tuples(remove_omit_from_dict(remove_none_from_dict(files), omit)) - if (files is not None and files is not omit) - else None - ), + files=request_files, timeout=timeout, ) as stream: yield stream @@ -354,11 +378,17 @@ async def request( json: typing.Optional[typing.Any] = None, data: typing.Optional[typing.Any] = None, content: typing.Optional[typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]]] = None, - files: typing.Optional[typing.Dict[str, typing.Optional[typing.Union[File, typing.List[File]]]]] = None, + files: typing.Optional[ + typing.Union[ + typing.Dict[str, typing.Optional[typing.Union[File, typing.List[File]]]], + typing.List[typing.Tuple[str, File]], + ] + ] = None, headers: typing.Optional[typing.Dict[str, typing.Any]] = None, request_options: typing.Optional[RequestOptions] = None, retries: int = 2, omit: typing.Optional[typing.Any] = None, + force_multipart: typing.Optional[bool] = None, ) -> httpx.Response: base_url = self.get_base_url(base_url) timeout = ( @@ -367,6 +397,15 @@ async def request( else self.base_timeout() ) + request_files: typing.Optional[RequestFiles] = ( + convert_file_dict_to_httpx_tuples(remove_omit_from_dict(remove_none_from_dict(files), omit)) + if (files is not None and files is not omit and isinstance(files, dict)) + else None + ) + + if (request_files is None or len(request_files) == 0) and force_multipart: + request_files = FORCE_MULTIPART + json_body, data_body = get_request_body(json=json, data=data, request_options=request_options, omit=omit) # Add the input to each of these and do None-safety checks @@ -402,11 +441,7 @@ async def request( json=json_body, data=data_body, content=content, - files=( - convert_file_dict_to_httpx_tuples(remove_omit_from_dict(remove_none_from_dict(files), omit)) - if files is not None - else None - ), + files=request_files, timeout=timeout, ) @@ -440,11 +475,17 @@ async def stream( json: typing.Optional[typing.Any] = None, data: typing.Optional[typing.Any] = None, content: typing.Optional[typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]]] = None, - files: typing.Optional[typing.Dict[str, typing.Optional[typing.Union[File, typing.List[File]]]]] = None, + files: typing.Optional[ + typing.Union[ + typing.Dict[str, typing.Optional[typing.Union[File, typing.List[File]]]], + typing.List[typing.Tuple[str, File]], + ] + ] = None, headers: typing.Optional[typing.Dict[str, typing.Any]] = None, request_options: typing.Optional[RequestOptions] = None, retries: int = 2, omit: typing.Optional[typing.Any] = None, + force_multipart: typing.Optional[bool] = None, ) -> typing.AsyncIterator[httpx.Response]: base_url = self.get_base_url(base_url) timeout = ( @@ -453,6 +494,15 @@ async def stream( else self.base_timeout() ) + request_files: typing.Optional[RequestFiles] = ( + convert_file_dict_to_httpx_tuples(remove_omit_from_dict(remove_none_from_dict(files), omit)) + if (files is not None and files is not omit and isinstance(files, dict)) + else None + ) + + if (request_files is None or len(request_files) == 0) and force_multipart: + request_files = FORCE_MULTIPART + json_body, data_body = get_request_body(json=json, data=data, request_options=request_options, omit=omit) async with self.httpx_client.stream( @@ -487,11 +537,7 @@ async def stream( json=json_body, data=data_body, content=content, - files=( - convert_file_dict_to_httpx_tuples(remove_omit_from_dict(remove_none_from_dict(files), omit)) - if files is not None - else None - ), + files=request_files, timeout=timeout, ) as stream: yield stream diff --git a/skyflow/generated/rest/core/pydantic_utilities.py b/skyflow/generated/rest/core/pydantic_utilities.py index 60a2c713..0360ef49 100644 --- a/skyflow/generated/rest/core/pydantic_utilities.py +++ b/skyflow/generated/rest/core/pydantic_utilities.py @@ -181,7 +181,7 @@ def deep_union_pydantic_dicts(source: Dict[str, Any], destination: Dict[str, Any if IS_PYDANTIC_V2: - class V2RootModel(UniversalBaseModel, pydantic.RootModel): # type: ignore[name-defined, type-arg] + class V2RootModel(UniversalBaseModel, pydantic.RootModel): # type: ignore[misc, name-defined, type-arg] pass UniversalRootModel: TypeAlias = V2RootModel # type: ignore[misc] diff --git a/skyflow/generated/rest/deprecated/client.py b/skyflow/generated/rest/deprecated/client.py index fadfa1cc..bd1cc88c 100644 --- a/skyflow/generated/rest/deprecated/client.py +++ b/skyflow/generated/rest/deprecated/client.py @@ -109,10 +109,48 @@ def detect_service_detect_file_input( Examples -------- - from skyflow import Skyflow - from skyflow import V1AudioConfig - client = Skyflow(token="YOUR_TOKEN", ) - client.deprecated.detect_service_detect_file_input(file='fkdjfhdlnnggtsjj...', data_format="mp3", input_type="BASE64", vault_id='a372f752689c9bfc8ca3d4dba', restrict_entity_types=["name", "age", "location", "ssn", "bank_account", "credit_card", "credit_card_expiration", "cvv", "date", "date_interval", "dob", "driver_license", "email_address", "healthcare_number", "numerical_pii", "phone_number", "medical_code", "account_number", "gender_sexuality", "name_medical_professional", "occupation", "organization", "organization_medical_facility"], return_entities=True, accuracy="high_multilingual", audio=V1AudioConfig(output_transcription="none", output_processed_audio=False, ), ) + from skyflow import Skyflow, V1AudioConfig + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.deprecated.detect_service_detect_file_input( + file="fkdjfhdlnnggtsjj...", + data_format="mp3", + input_type="BASE64", + vault_id="a372f752689c9bfc8ca3d4dba", + restrict_entity_types=[ + "name", + "age", + "location", + "ssn", + "bank_account", + "credit_card", + "credit_card_expiration", + "cvv", + "date", + "date_interval", + "dob", + "driver_license", + "email_address", + "healthcare_number", + "numerical_pii", + "phone_number", + "medical_code", + "account_number", + "gender_sexuality", + "name_medical_professional", + "occupation", + "organization", + "organization_medical_facility", + ], + return_entities=True, + accuracy="high_multilingual", + audio=V1AudioConfig( + output_transcription="none", + output_processed_audio=False, + ), + ) """ _response = self._raw_client.detect_service_detect_file_input( file=file, @@ -159,8 +197,13 @@ def detect_service_detect_status( Examples -------- from skyflow import Skyflow - client = Skyflow(token="YOUR_TOKEN", ) - client.deprecated.detect_service_detect_status(id='ID', ) + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.deprecated.detect_service_detect_status( + id="ID", + ) """ _response = self._raw_client.detect_service_detect_status( id, vault_id=vault_id, request_options=request_options @@ -229,8 +272,14 @@ def detect_service_detect_text( Examples -------- from skyflow import Skyflow - client = Skyflow(token="YOUR_TOKEN", ) - client.deprecated.detect_service_detect_text(text='text', vault_id='c848741aefb74bf38780da5399a76507', ) + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.deprecated.detect_service_detect_text( + text="text", + vault_id="c848741aefb74bf38780da5399a76507", + ) """ _response = self._raw_client.detect_service_detect_text( text=text, @@ -336,12 +385,55 @@ async def detect_service_detect_file_input( Examples -------- - from skyflow import AsyncSkyflow - from skyflow import V1AudioConfig import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + from skyflow import AsyncSkyflow, V1AudioConfig + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.deprecated.detect_service_detect_file_input(file='fkdjfhdlnnggtsjj...', data_format="mp3", input_type="BASE64", vault_id='a372f752689c9bfc8ca3d4dba', restrict_entity_types=["name", "age", "location", "ssn", "bank_account", "credit_card", "credit_card_expiration", "cvv", "date", "date_interval", "dob", "driver_license", "email_address", "healthcare_number", "numerical_pii", "phone_number", "medical_code", "account_number", "gender_sexuality", "name_medical_professional", "occupation", "organization", "organization_medical_facility"], return_entities=True, accuracy="high_multilingual", audio=V1AudioConfig(output_transcription="none", output_processed_audio=False, ), ) + await client.deprecated.detect_service_detect_file_input( + file="fkdjfhdlnnggtsjj...", + data_format="mp3", + input_type="BASE64", + vault_id="a372f752689c9bfc8ca3d4dba", + restrict_entity_types=[ + "name", + "age", + "location", + "ssn", + "bank_account", + "credit_card", + "credit_card_expiration", + "cvv", + "date", + "date_interval", + "dob", + "driver_license", + "email_address", + "healthcare_number", + "numerical_pii", + "phone_number", + "medical_code", + "account_number", + "gender_sexuality", + "name_medical_professional", + "occupation", + "organization", + "organization_medical_facility", + ], + return_entities=True, + accuracy="high_multilingual", + audio=V1AudioConfig( + output_transcription="none", + output_processed_audio=False, + ), + ) + + asyncio.run(main()) """ _response = await self._raw_client.detect_service_detect_file_input( @@ -388,11 +480,21 @@ async def detect_service_detect_status( Examples -------- - from skyflow import AsyncSkyflow import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + from skyflow import AsyncSkyflow + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.deprecated.detect_service_detect_status(id='ID', ) + await client.deprecated.detect_service_detect_status( + id="ID", + ) + + asyncio.run(main()) """ _response = await self._raw_client.detect_service_detect_status( @@ -461,11 +563,22 @@ async def detect_service_detect_text( Examples -------- - from skyflow import AsyncSkyflow import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + from skyflow import AsyncSkyflow + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.deprecated.detect_service_detect_text(text='text', vault_id='c848741aefb74bf38780da5399a76507', ) + await client.deprecated.detect_service_detect_text( + text="text", + vault_id="c848741aefb74bf38780da5399a76507", + ) + + asyncio.run(main()) """ _response = await self._raw_client.detect_service_detect_text( diff --git a/skyflow/generated/rest/files/client.py b/skyflow/generated/rest/files/client.py index 12f79022..913ccd59 100644 --- a/skyflow/generated/rest/files/client.py +++ b/skyflow/generated/rest/files/client.py @@ -90,8 +90,17 @@ def deidentify_file( -------- from skyflow import Skyflow from skyflow.files import DeidentifyFileRequestFile - client = Skyflow(token="YOUR_TOKEN", ) - client.files.deidentify_file(vault_id='f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b', file=DeidentifyFileRequestFile(base_64='Zm9vYmFy', data_format="txt", ), ) + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.files.deidentify_file( + vault_id="f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b", + file=DeidentifyFileRequestFile( + base_64="Zm9vYmFy", + data_format="txt", + ), + ) """ _response = self._raw_client.deidentify_file( vault_id=vault_id, @@ -149,8 +158,17 @@ def deidentify_document( -------- from skyflow import Skyflow from skyflow.files import DeidentifyDocumentRequestFile - client = Skyflow(token="YOUR_TOKEN", ) - client.files.deidentify_document(vault_id='f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b', file=DeidentifyDocumentRequestFile(base_64='SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==', data_format="docx", ), ) + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.files.deidentify_document( + vault_id="f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b", + file=DeidentifyDocumentRequestFile( + base_64="SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==", + data_format="docx", + ), + ) """ _response = self._raw_client.deidentify_document( vault_id=vault_id, @@ -216,8 +234,16 @@ def deidentify_pdf( -------- from skyflow import Skyflow from skyflow.files import DeidentifyPdfRequestFile - client = Skyflow(token="YOUR_TOKEN", ) - client.files.deidentify_pdf(vault_id='f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b', file=DeidentifyPdfRequestFile(base_64='SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==', ), ) + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.files.deidentify_pdf( + vault_id="f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b", + file=DeidentifyPdfRequestFile( + base_64="SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==", + ), + ) """ _response = self._raw_client.deidentify_pdf( vault_id=vault_id, @@ -289,8 +315,17 @@ def deidentify_image( -------- from skyflow import Skyflow from skyflow.files import DeidentifyImageRequestFile - client = Skyflow(token="YOUR_TOKEN", ) - client.files.deidentify_image(vault_id='f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b', file=DeidentifyImageRequestFile(base_64='SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==', data_format="jpg", ), ) + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.files.deidentify_image( + vault_id="f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b", + file=DeidentifyImageRequestFile( + base_64="SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==", + data_format="jpg", + ), + ) """ _response = self._raw_client.deidentify_image( vault_id=vault_id, @@ -351,8 +386,16 @@ def deidentify_text( -------- from skyflow import Skyflow from skyflow.files import DeidentifyTextRequestFile - client = Skyflow(token="YOUR_TOKEN", ) - client.files.deidentify_text(vault_id='f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b', file=DeidentifyTextRequestFile(base_64='Zm9vYmFy', ), ) + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.files.deidentify_text( + vault_id="f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b", + file=DeidentifyTextRequestFile( + base_64="Zm9vYmFy", + ), + ) """ _response = self._raw_client.deidentify_text( vault_id=vault_id, @@ -410,8 +453,17 @@ def deidentify_structured_text( -------- from skyflow import Skyflow from skyflow.files import DeidentifyStructuredTextRequestFile - client = Skyflow(token="YOUR_TOKEN", ) - client.files.deidentify_structured_text(vault_id='f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b', file=DeidentifyStructuredTextRequestFile(base_64='SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==', data_format="json", ), ) + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.files.deidentify_structured_text( + vault_id="f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b", + file=DeidentifyStructuredTextRequestFile( + base_64="SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==", + data_format="json", + ), + ) """ _response = self._raw_client.deidentify_structured_text( vault_id=vault_id, @@ -469,8 +521,17 @@ def deidentify_spreadsheet( -------- from skyflow import Skyflow from skyflow.files import DeidentifySpreadsheetRequestFile - client = Skyflow(token="YOUR_TOKEN", ) - client.files.deidentify_spreadsheet(vault_id='f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b', file=DeidentifySpreadsheetRequestFile(base_64='SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==', data_format="csv", ), ) + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.files.deidentify_spreadsheet( + vault_id="f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b", + file=DeidentifySpreadsheetRequestFile( + base_64="SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==", + data_format="csv", + ), + ) """ _response = self._raw_client.deidentify_spreadsheet( vault_id=vault_id, @@ -528,8 +589,17 @@ def deidentify_presentation( -------- from skyflow import Skyflow from skyflow.files import DeidentifyPresentationRequestFile - client = Skyflow(token="YOUR_TOKEN", ) - client.files.deidentify_presentation(vault_id='f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b', file=DeidentifyPresentationRequestFile(base_64='SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==', data_format="pptx", ), ) + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.files.deidentify_presentation( + vault_id="f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b", + file=DeidentifyPresentationRequestFile( + base_64="SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==", + data_format="pptx", + ), + ) """ _response = self._raw_client.deidentify_presentation( vault_id=vault_id, @@ -611,8 +681,17 @@ def deidentify_audio( -------- from skyflow import Skyflow from skyflow.files import DeidentifyAudioRequestFile - client = Skyflow(token="YOUR_TOKEN", ) - client.files.deidentify_audio(vault_id='f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b', file=DeidentifyAudioRequestFile(base_64='SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==', data_format="mp3", ), ) + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.files.deidentify_audio( + vault_id="f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b", + file=DeidentifyAudioRequestFile( + base_64="SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==", + data_format="mp3", + ), + ) """ _response = self._raw_client.deidentify_audio( vault_id=vault_id, @@ -657,8 +736,14 @@ def get_run( Examples -------- from skyflow import Skyflow - client = Skyflow(token="YOUR_TOKEN", ) - client.files.get_run(run_id='run_id', vault_id='vault_id', ) + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.files.get_run( + run_id="run_id", + vault_id="vault_id", + ) """ _response = self._raw_client.get_run(run_id, vault_id=vault_id, request_options=request_options) return _response.data @@ -721,12 +806,26 @@ async def deidentify_file( Examples -------- + import asyncio + from skyflow import AsyncSkyflow from skyflow.files import DeidentifyFileRequestFile - import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.files.deidentify_file(vault_id='f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b', file=DeidentifyFileRequestFile(base_64='Zm9vYmFy', data_format="txt", ), ) + await client.files.deidentify_file( + vault_id="f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b", + file=DeidentifyFileRequestFile( + base_64="Zm9vYmFy", + data_format="txt", + ), + ) + + asyncio.run(main()) """ _response = await self._raw_client.deidentify_file( @@ -783,12 +882,26 @@ async def deidentify_document( Examples -------- + import asyncio + from skyflow import AsyncSkyflow from skyflow.files import DeidentifyDocumentRequestFile - import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.files.deidentify_document(vault_id='f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b', file=DeidentifyDocumentRequestFile(base_64='SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==', data_format="docx", ), ) + await client.files.deidentify_document( + vault_id="f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b", + file=DeidentifyDocumentRequestFile( + base_64="SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==", + data_format="docx", + ), + ) + + asyncio.run(main()) """ _response = await self._raw_client.deidentify_document( @@ -853,12 +966,25 @@ async def deidentify_pdf( Examples -------- + import asyncio + from skyflow import AsyncSkyflow from skyflow.files import DeidentifyPdfRequestFile - import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.files.deidentify_pdf(vault_id='f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b', file=DeidentifyPdfRequestFile(base_64='SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==', ), ) + await client.files.deidentify_pdf( + vault_id="f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b", + file=DeidentifyPdfRequestFile( + base_64="SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==", + ), + ) + + asyncio.run(main()) """ _response = await self._raw_client.deidentify_pdf( @@ -929,12 +1055,26 @@ async def deidentify_image( Examples -------- + import asyncio + from skyflow import AsyncSkyflow from skyflow.files import DeidentifyImageRequestFile - import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.files.deidentify_image(vault_id='f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b', file=DeidentifyImageRequestFile(base_64='SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==', data_format="jpg", ), ) + await client.files.deidentify_image( + vault_id="f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b", + file=DeidentifyImageRequestFile( + base_64="SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==", + data_format="jpg", + ), + ) + + asyncio.run(main()) """ _response = await self._raw_client.deidentify_image( @@ -994,12 +1134,25 @@ async def deidentify_text( Examples -------- + import asyncio + from skyflow import AsyncSkyflow from skyflow.files import DeidentifyTextRequestFile - import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.files.deidentify_text(vault_id='f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b', file=DeidentifyTextRequestFile(base_64='Zm9vYmFy', ), ) + await client.files.deidentify_text( + vault_id="f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b", + file=DeidentifyTextRequestFile( + base_64="Zm9vYmFy", + ), + ) + + asyncio.run(main()) """ _response = await self._raw_client.deidentify_text( @@ -1056,12 +1209,26 @@ async def deidentify_structured_text( Examples -------- + import asyncio + from skyflow import AsyncSkyflow from skyflow.files import DeidentifyStructuredTextRequestFile - import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.files.deidentify_structured_text(vault_id='f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b', file=DeidentifyStructuredTextRequestFile(base_64='SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==', data_format="json", ), ) + await client.files.deidentify_structured_text( + vault_id="f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b", + file=DeidentifyStructuredTextRequestFile( + base_64="SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==", + data_format="json", + ), + ) + + asyncio.run(main()) """ _response = await self._raw_client.deidentify_structured_text( @@ -1118,12 +1285,26 @@ async def deidentify_spreadsheet( Examples -------- + import asyncio + from skyflow import AsyncSkyflow from skyflow.files import DeidentifySpreadsheetRequestFile - import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.files.deidentify_spreadsheet(vault_id='f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b', file=DeidentifySpreadsheetRequestFile(base_64='SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==', data_format="csv", ), ) + await client.files.deidentify_spreadsheet( + vault_id="f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b", + file=DeidentifySpreadsheetRequestFile( + base_64="SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==", + data_format="csv", + ), + ) + + asyncio.run(main()) """ _response = await self._raw_client.deidentify_spreadsheet( @@ -1180,12 +1361,26 @@ async def deidentify_presentation( Examples -------- + import asyncio + from skyflow import AsyncSkyflow from skyflow.files import DeidentifyPresentationRequestFile - import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.files.deidentify_presentation(vault_id='f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b', file=DeidentifyPresentationRequestFile(base_64='SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==', data_format="pptx", ), ) + await client.files.deidentify_presentation( + vault_id="f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b", + file=DeidentifyPresentationRequestFile( + base_64="SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==", + data_format="pptx", + ), + ) + + asyncio.run(main()) """ _response = await self._raw_client.deidentify_presentation( @@ -1266,12 +1461,26 @@ async def deidentify_audio( Examples -------- + import asyncio + from skyflow import AsyncSkyflow from skyflow.files import DeidentifyAudioRequestFile - import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.files.deidentify_audio(vault_id='f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b', file=DeidentifyAudioRequestFile(base_64='SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==', data_format="mp3", ), ) + await client.files.deidentify_audio( + vault_id="f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b", + file=DeidentifyAudioRequestFile( + base_64="SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==", + data_format="mp3", + ), + ) + + asyncio.run(main()) """ _response = await self._raw_client.deidentify_audio( @@ -1316,11 +1525,22 @@ async def get_run( Examples -------- - from skyflow import AsyncSkyflow import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + from skyflow import AsyncSkyflow + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.files.get_run(run_id='run_id', vault_id='vault_id', ) + await client.files.get_run( + run_id="run_id", + vault_id="vault_id", + ) + + asyncio.run(main()) """ _response = await self._raw_client.get_run(run_id, vault_id=vault_id, request_options=request_options) diff --git a/skyflow/generated/rest/query/client.py b/skyflow/generated/rest/query/client.py index 1f5edd75..28fd454e 100644 --- a/skyflow/generated/rest/query/client.py +++ b/skyflow/generated/rest/query/client.py @@ -55,8 +55,14 @@ def query_service_execute_query( Examples -------- from skyflow import Skyflow - client = Skyflow(token="YOUR_TOKEN", ) - client.query.query_service_execute_query(vault_id='vaultID', query='select * from opportunities where id="01010000ade21cded569d43944544ec6"', ) + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.query.query_service_execute_query( + vault_id="vaultID", + query='select * from opportunities where id="01010000ade21cded569d43944544ec6"', + ) """ _response = self._raw_client.query_service_execute_query(vault_id, query=query, request_options=request_options) return _response.data @@ -105,11 +111,22 @@ async def query_service_execute_query( Examples -------- - from skyflow import AsyncSkyflow import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + from skyflow import AsyncSkyflow + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.query.query_service_execute_query(vault_id='vaultID', query='select * from opportunities where id="01010000ade21cded569d43944544ec6"', ) + await client.query.query_service_execute_query( + vault_id="vaultID", + query='select * from opportunities where id="01010000ade21cded569d43944544ec6"', + ) + + asyncio.run(main()) """ _response = await self._raw_client.query_service_execute_query( diff --git a/skyflow/generated/rest/records/client.py b/skyflow/generated/rest/records/client.py index 643e2826..1f727bfc 100644 --- a/skyflow/generated/rest/records/client.py +++ b/skyflow/generated/rest/records/client.py @@ -75,14 +75,40 @@ def record_service_batch_operation( Examples -------- - from skyflow import Skyflow - from skyflow import V1BatchRecord - client = Skyflow(token="YOUR_TOKEN", ) - client.records.record_service_batch_operation(vault_id='vaultID', records=[V1BatchRecord(fields={'drivers_license_number': '89867453' - , 'name': 'Connor' - , 'phone_number': '8794523160' - , 'ssn': '143-89-2306' - }, table_name='persons', method="POST", batch_id='persons-12345', redaction="PLAIN_TEXT", tokenization=False, download_url=False, upsert='drivers_license_number', ), V1BatchRecord(table_name='persons', method="GET", batch_id='persons-12345', redaction="PLAIN_TEXT", tokenization=False, id='f1dbc55c-7c9b-495d-9a36-72bb2b619202', download_url=True, )], ) + from skyflow import Skyflow, V1BatchRecord + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.records.record_service_batch_operation( + vault_id="vaultID", + records=[ + V1BatchRecord( + fields={ + "drivers_license_number": "89867453", + "name": "Connor", + "phone_number": "8794523160", + "ssn": "143-89-2306", + }, + table_name="persons", + method="POST", + batch_id="persons-12345", + redaction="PLAIN_TEXT", + tokenization=False, + download_url=False, + upsert="drivers_license_number", + ), + V1BatchRecord( + table_name="persons", + method="GET", + batch_id="persons-12345", + redaction="PLAIN_TEXT", + tokenization=False, + id="f1dbc55c-7c9b-495d-9a36-72bb2b619202", + download_url=True, + ), + ], + ) """ _response = self._raw_client.record_service_batch_operation( vault_id, records=records, continue_on_error=continue_on_error, byot=byot, request_options=request_options @@ -158,8 +184,14 @@ def record_service_bulk_get_record( Examples -------- from skyflow import Skyflow - client = Skyflow(token="YOUR_TOKEN", ) - client.records.record_service_bulk_get_record(vault_id='vaultID', object_name='objectName', ) + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.records.record_service_bulk_get_record( + vault_id="vaultID", + object_name="objectName", + ) """ _response = self._raw_client.record_service_bulk_get_record( vault_id, @@ -225,18 +257,36 @@ def record_service_insert_record( Examples -------- - from skyflow import Skyflow - from skyflow import V1FieldRecords - client = Skyflow(token="YOUR_TOKEN", ) - client.records.record_service_insert_record(vault_id='vaultID', object_name='objectName', records=[V1FieldRecords(fields={'drivers_license_number': '13456789' - , 'name': 'John' - , 'phone_number': '1236784563' - , 'ssn': '123-45-6789' - }, ), V1FieldRecords(fields={'drivers_license_number': '98765432' - , 'name': 'James' - , 'phone_number': '9876543215' - , 'ssn': '345-45-9876' - }, )], tokenization=True, upsert='drivers_license_number', homogeneous=False, ) + from skyflow import Skyflow, V1FieldRecords + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.records.record_service_insert_record( + vault_id="vaultID", + object_name="objectName", + records=[ + V1FieldRecords( + fields={ + "drivers_license_number": "13456789", + "name": "John", + "phone_number": "1236784563", + "ssn": "123-45-6789", + }, + ), + V1FieldRecords( + fields={ + "drivers_license_number": "98765432", + "name": "James", + "phone_number": "9876543215", + "ssn": "345-45-9876", + }, + ), + ], + tokenization=True, + upsert="drivers_license_number", + homogeneous=False, + ) """ _response = self._raw_client.record_service_insert_record( vault_id, @@ -283,8 +333,18 @@ def record_service_bulk_delete_record( Examples -------- from skyflow import Skyflow - client = Skyflow(token="YOUR_TOKEN", ) - client.records.record_service_bulk_delete_record(vault_id='vaultID', object_name='objectName', skyflow_ids=['51782ea4-91a5-4430-a06d-f4b76efd3d2f', '110ce08f-6059-4874-b1ae-7c6651d286ff'], ) + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.records.record_service_bulk_delete_record( + vault_id="vaultID", + object_name="objectName", + skyflow_ids=[ + "51782ea4-91a5-4430-a06d-f4b76efd3d2f", + "110ce08f-6059-4874-b1ae-7c6651d286ff", + ], + ) """ _response = self._raw_client.record_service_bulk_delete_record( vault_id, object_name, skyflow_ids=skyflow_ids, request_options=request_options @@ -340,8 +400,15 @@ def record_service_get_record( Examples -------- from skyflow import Skyflow - client = Skyflow(token="YOUR_TOKEN", ) - client.records.record_service_get_record(vault_id='vaultID', object_name='objectName', id='ID', ) + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.records.record_service_get_record( + vault_id="vaultID", + object_name="objectName", + id="ID", + ) """ _response = self._raw_client.record_service_get_record( vault_id, @@ -397,14 +464,25 @@ def record_service_update_record( Examples -------- - from skyflow import Skyflow - from skyflow import V1FieldRecords - client = Skyflow(token="YOUR_TOKEN", ) - client.records.record_service_update_record(vault_id='vaultID', object_name='objectName', id='ID', record=V1FieldRecords(fields={'drivers_license_number': '89867453' - , 'name': 'Steve Smith' - , 'phone_number': '8794523160' - , 'ssn': '143-89-2306' - }, ), tokenization=True, ) + from skyflow import Skyflow, V1FieldRecords + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.records.record_service_update_record( + vault_id="vaultID", + object_name="objectName", + id="ID", + record=V1FieldRecords( + fields={ + "drivers_license_number": "89867453", + "name": "Steve Smith", + "phone_number": "8794523160", + "ssn": "143-89-2306", + }, + ), + tokenization=True, + ) """ _response = self._raw_client.record_service_update_record( vault_id, @@ -445,8 +523,15 @@ def record_service_delete_record( Examples -------- from skyflow import Skyflow - client = Skyflow(token="YOUR_TOKEN", ) - client.records.record_service_delete_record(vault_id='vaultID', object_name='objectName', id='ID', ) + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.records.record_service_delete_record( + vault_id="vaultID", + object_name="objectName", + id="ID", + ) """ _response = self._raw_client.record_service_delete_record( vault_id, object_name, id, request_options=request_options @@ -459,7 +544,8 @@ def file_service_upload_file( object_name: str, id: str, *, - file_column_name: typing.Optional[core.File] = OMIT, + file: typing.Optional[core.File] = OMIT, + column_name: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> V1UpdateRecordResponse: """ @@ -476,9 +562,12 @@ def file_service_upload_file( id : str `skyflow_id` of the record. - file_column_name : typing.Optional[core.File] + file : typing.Optional[core.File] See core.File for more documentation + column_name : typing.Optional[str] + Name of the column to store the file in. The column must have a file data type. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -490,11 +579,18 @@ def file_service_upload_file( Examples -------- from skyflow import Skyflow - client = Skyflow(token="YOUR_TOKEN", ) - client.records.file_service_upload_file(vault_id='vaultID', object_name='objectName', id='ID', ) + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.records.file_service_upload_file( + vault_id="vaultID", + object_name="objectName", + id="ID", + ) """ _response = self._raw_client.file_service_upload_file( - vault_id, object_name, id, file_column_name=file_column_name, request_options=request_options + vault_id, object_name, id, file=file, column_name=column_name, request_options=request_options ) return _response.data @@ -535,8 +631,16 @@ def file_service_delete_file( Examples -------- from skyflow import Skyflow - client = Skyflow(token="YOUR_TOKEN", ) - client.records.file_service_delete_file(vault_id='vaultID', table_name='tableName', id='ID', column_name='columnName', ) + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.records.file_service_delete_file( + vault_id="vaultID", + table_name="tableName", + id="ID", + column_name="columnName", + ) """ _response = self._raw_client.file_service_delete_file( vault_id, table_name, id, column_name, request_options=request_options @@ -580,8 +684,16 @@ def file_service_get_file_scan_status( Examples -------- from skyflow import Skyflow - client = Skyflow(token="YOUR_TOKEN", ) - client.records.file_service_get_file_scan_status(vault_id='vaultID', table_name='tableName', id='ID', column_name='columnName', ) + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.records.file_service_get_file_scan_status( + vault_id="vaultID", + table_name="tableName", + id="ID", + column_name="columnName", + ) """ _response = self._raw_client.file_service_get_file_scan_status( vault_id, table_name, id, column_name, request_options=request_options @@ -639,16 +751,47 @@ async def record_service_batch_operation( Examples -------- - from skyflow import AsyncSkyflow - from skyflow import V1BatchRecord import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + from skyflow import AsyncSkyflow, V1BatchRecord + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.records.record_service_batch_operation(vault_id='vaultID', records=[V1BatchRecord(fields={'drivers_license_number': '89867453' - , 'name': 'Connor' - , 'phone_number': '8794523160' - , 'ssn': '143-89-2306' - }, table_name='persons', method="POST", batch_id='persons-12345', redaction="PLAIN_TEXT", tokenization=False, download_url=False, upsert='drivers_license_number', ), V1BatchRecord(table_name='persons', method="GET", batch_id='persons-12345', redaction="PLAIN_TEXT", tokenization=False, id='f1dbc55c-7c9b-495d-9a36-72bb2b619202', download_url=True, )], ) + await client.records.record_service_batch_operation( + vault_id="vaultID", + records=[ + V1BatchRecord( + fields={ + "drivers_license_number": "89867453", + "name": "Connor", + "phone_number": "8794523160", + "ssn": "143-89-2306", + }, + table_name="persons", + method="POST", + batch_id="persons-12345", + redaction="PLAIN_TEXT", + tokenization=False, + download_url=False, + upsert="drivers_license_number", + ), + V1BatchRecord( + table_name="persons", + method="GET", + batch_id="persons-12345", + redaction="PLAIN_TEXT", + tokenization=False, + id="f1dbc55c-7c9b-495d-9a36-72bb2b619202", + download_url=True, + ), + ], + ) + + asyncio.run(main()) """ _response = await self._raw_client.record_service_batch_operation( @@ -724,11 +867,22 @@ async def record_service_bulk_get_record( Examples -------- - from skyflow import AsyncSkyflow import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + from skyflow import AsyncSkyflow + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.records.record_service_bulk_get_record(vault_id='vaultID', object_name='objectName', ) + await client.records.record_service_bulk_get_record( + vault_id="vaultID", + object_name="objectName", + ) + + asyncio.run(main()) """ _response = await self._raw_client.record_service_bulk_get_record( @@ -795,20 +949,43 @@ async def record_service_insert_record( Examples -------- - from skyflow import AsyncSkyflow - from skyflow import V1FieldRecords import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + from skyflow import AsyncSkyflow, V1FieldRecords + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.records.record_service_insert_record(vault_id='vaultID', object_name='objectName', records=[V1FieldRecords(fields={'drivers_license_number': '13456789' - , 'name': 'John' - , 'phone_number': '1236784563' - , 'ssn': '123-45-6789' - }, ), V1FieldRecords(fields={'drivers_license_number': '98765432' - , 'name': 'James' - , 'phone_number': '9876543215' - , 'ssn': '345-45-9876' - }, )], tokenization=True, upsert='drivers_license_number', homogeneous=False, ) + await client.records.record_service_insert_record( + vault_id="vaultID", + object_name="objectName", + records=[ + V1FieldRecords( + fields={ + "drivers_license_number": "13456789", + "name": "John", + "phone_number": "1236784563", + "ssn": "123-45-6789", + }, + ), + V1FieldRecords( + fields={ + "drivers_license_number": "98765432", + "name": "James", + "phone_number": "9876543215", + "ssn": "345-45-9876", + }, + ), + ], + tokenization=True, + upsert="drivers_license_number", + homogeneous=False, + ) + + asyncio.run(main()) """ _response = await self._raw_client.record_service_insert_record( @@ -855,11 +1032,26 @@ async def record_service_bulk_delete_record( Examples -------- - from skyflow import AsyncSkyflow import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + from skyflow import AsyncSkyflow + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.records.record_service_bulk_delete_record(vault_id='vaultID', object_name='objectName', skyflow_ids=['51782ea4-91a5-4430-a06d-f4b76efd3d2f', '110ce08f-6059-4874-b1ae-7c6651d286ff'], ) + await client.records.record_service_bulk_delete_record( + vault_id="vaultID", + object_name="objectName", + skyflow_ids=[ + "51782ea4-91a5-4430-a06d-f4b76efd3d2f", + "110ce08f-6059-4874-b1ae-7c6651d286ff", + ], + ) + + asyncio.run(main()) """ _response = await self._raw_client.record_service_bulk_delete_record( @@ -915,11 +1107,23 @@ async def record_service_get_record( Examples -------- - from skyflow import AsyncSkyflow import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + from skyflow import AsyncSkyflow + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.records.record_service_get_record(vault_id='vaultID', object_name='objectName', id='ID', ) + await client.records.record_service_get_record( + vault_id="vaultID", + object_name="objectName", + id="ID", + ) + + asyncio.run(main()) """ _response = await self._raw_client.record_service_get_record( @@ -976,16 +1180,32 @@ async def record_service_update_record( Examples -------- - from skyflow import AsyncSkyflow - from skyflow import V1FieldRecords import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + from skyflow import AsyncSkyflow, V1FieldRecords + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.records.record_service_update_record(vault_id='vaultID', object_name='objectName', id='ID', record=V1FieldRecords(fields={'drivers_license_number': '89867453' - , 'name': 'Steve Smith' - , 'phone_number': '8794523160' - , 'ssn': '143-89-2306' - }, ), tokenization=True, ) + await client.records.record_service_update_record( + vault_id="vaultID", + object_name="objectName", + id="ID", + record=V1FieldRecords( + fields={ + "drivers_license_number": "89867453", + "name": "Steve Smith", + "phone_number": "8794523160", + "ssn": "143-89-2306", + }, + ), + tokenization=True, + ) + + asyncio.run(main()) """ _response = await self._raw_client.record_service_update_record( @@ -1026,11 +1246,23 @@ async def record_service_delete_record( Examples -------- - from skyflow import AsyncSkyflow import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + from skyflow import AsyncSkyflow + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.records.record_service_delete_record(vault_id='vaultID', object_name='objectName', id='ID', ) + await client.records.record_service_delete_record( + vault_id="vaultID", + object_name="objectName", + id="ID", + ) + + asyncio.run(main()) """ _response = await self._raw_client.record_service_delete_record( @@ -1044,7 +1276,8 @@ async def file_service_upload_file( object_name: str, id: str, *, - file_column_name: typing.Optional[core.File] = OMIT, + file: typing.Optional[core.File] = OMIT, + column_name: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> V1UpdateRecordResponse: """ @@ -1061,9 +1294,12 @@ async def file_service_upload_file( id : str `skyflow_id` of the record. - file_column_name : typing.Optional[core.File] + file : typing.Optional[core.File] See core.File for more documentation + column_name : typing.Optional[str] + Name of the column to store the file in. The column must have a file data type. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1074,15 +1310,27 @@ async def file_service_upload_file( Examples -------- - from skyflow import AsyncSkyflow import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + from skyflow import AsyncSkyflow + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.records.file_service_upload_file(vault_id='vaultID', object_name='objectName', id='ID', ) + await client.records.file_service_upload_file( + vault_id="vaultID", + object_name="objectName", + id="ID", + ) + + asyncio.run(main()) """ _response = await self._raw_client.file_service_upload_file( - vault_id, object_name, id, file_column_name=file_column_name, request_options=request_options + vault_id, object_name, id, file=file, column_name=column_name, request_options=request_options ) return _response.data @@ -1122,11 +1370,24 @@ async def file_service_delete_file( Examples -------- - from skyflow import AsyncSkyflow import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + from skyflow import AsyncSkyflow + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.records.file_service_delete_file(vault_id='vaultID', table_name='tableName', id='ID', column_name='columnName', ) + await client.records.file_service_delete_file( + vault_id="vaultID", + table_name="tableName", + id="ID", + column_name="columnName", + ) + + asyncio.run(main()) """ _response = await self._raw_client.file_service_delete_file( @@ -1170,11 +1431,24 @@ async def file_service_get_file_scan_status( Examples -------- - from skyflow import AsyncSkyflow import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + from skyflow import AsyncSkyflow + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.records.file_service_get_file_scan_status(vault_id='vaultID', table_name='tableName', id='ID', column_name='columnName', ) + await client.records.file_service_get_file_scan_status( + vault_id="vaultID", + table_name="tableName", + id="ID", + column_name="columnName", + ) + + asyncio.run(main()) """ _response = await self._raw_client.file_service_get_file_scan_status( diff --git a/skyflow/generated/rest/records/raw_client.py b/skyflow/generated/rest/records/raw_client.py index 2be53677..e2bfdc92 100644 --- a/skyflow/generated/rest/records/raw_client.py +++ b/skyflow/generated/rest/records/raw_client.py @@ -603,7 +603,8 @@ def file_service_upload_file( object_name: str, id: str, *, - file_column_name: typing.Optional[core.File] = OMIT, + file: typing.Optional[core.File] = OMIT, + column_name: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[V1UpdateRecordResponse]: """ @@ -620,9 +621,12 @@ def file_service_upload_file( id : str `skyflow_id` of the record. - file_column_name : typing.Optional[core.File] + file : typing.Optional[core.File] See core.File for more documentation + column_name : typing.Optional[str] + Name of the column to store the file in. The column must have a file data type. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -634,12 +638,15 @@ def file_service_upload_file( _response = self._client_wrapper.httpx_client.request( f"v1/vaults/{jsonable_encoder(vault_id)}/{jsonable_encoder(object_name)}/{jsonable_encoder(id)}/files", method="POST", - data={}, + data={ + "columnName": column_name, + }, files={ - **({"fileColumnName": file_column_name} if fileColumnName is not None else {}), + **({"file": file} if file is not None else {}), }, request_options=request_options, omit=OMIT, + force_multipart=True, ) try: if 200 <= _response.status_code < 300: @@ -1370,7 +1377,8 @@ async def file_service_upload_file( object_name: str, id: str, *, - file_column_name: typing.Optional[core.File] = OMIT, + file: typing.Optional[core.File] = OMIT, + column_name: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[V1UpdateRecordResponse]: """ @@ -1387,9 +1395,12 @@ async def file_service_upload_file( id : str `skyflow_id` of the record. - file_column_name : typing.Optional[core.File] + file : typing.Optional[core.File] See core.File for more documentation + column_name : typing.Optional[str] + Name of the column to store the file in. The column must have a file data type. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1401,12 +1412,15 @@ async def file_service_upload_file( _response = await self._client_wrapper.httpx_client.request( f"v1/vaults/{jsonable_encoder(vault_id)}/{jsonable_encoder(object_name)}/{jsonable_encoder(id)}/files", method="POST", - data={}, + data={ + "columnName": column_name, + }, files={ - **({"fileColumnName": file_column_name} if fileColumnName is not None else {}), + **({"file": file} if file is not None else {}), }, request_options=request_options, omit=OMIT, + force_multipart=True, ) try: if 200 <= _response.status_code < 300: diff --git a/skyflow/generated/rest/strings/client.py b/skyflow/generated/rest/strings/client.py index 3d8388a3..5c71662d 100644 --- a/skyflow/generated/rest/strings/client.py +++ b/skyflow/generated/rest/strings/client.py @@ -77,8 +77,14 @@ def deidentify_string( Examples -------- from skyflow import Skyflow - client = Skyflow(token="YOUR_TOKEN", ) - client.strings.deidentify_string(vault_id='f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b', text='My name is John Doe, and my email is johndoe@acme.com.', ) + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.strings.deidentify_string( + vault_id="f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b", + text="My name is John Doe, and my email is johndoe@acme.com.", + ) """ _response = self._raw_client.deidentify_string( vault_id=vault_id, @@ -125,8 +131,14 @@ def reidentify_string( Examples -------- from skyflow import Skyflow - client = Skyflow(token="YOUR_TOKEN", ) - client.strings.reidentify_string(text='My name is [NAME_1], and my email is [EMAIL_1].', vault_id='1ad6db07-8405-46cf-9a1e-db148ff9f4c5', ) + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.strings.reidentify_string( + text="My name is [NAME_1], and my email is [EMAIL_1].", + vault_id="1ad6db07-8405-46cf-9a1e-db148ff9f4c5", + ) """ _response = self._raw_client.reidentify_string( text=text, vault_id=vault_id, format=format, request_options=request_options @@ -191,11 +203,22 @@ async def deidentify_string( Examples -------- - from skyflow import AsyncSkyflow import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + from skyflow import AsyncSkyflow + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.strings.deidentify_string(vault_id='f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b', text='My name is John Doe, and my email is johndoe@acme.com.', ) + await client.strings.deidentify_string( + vault_id="f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b", + text="My name is John Doe, and my email is johndoe@acme.com.", + ) + + asyncio.run(main()) """ _response = await self._raw_client.deidentify_string( @@ -242,11 +265,22 @@ async def reidentify_string( Examples -------- - from skyflow import AsyncSkyflow import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + from skyflow import AsyncSkyflow + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.strings.reidentify_string(text='My name is [NAME_1], and my email is [EMAIL_1].', vault_id='1ad6db07-8405-46cf-9a1e-db148ff9f4c5', ) + await client.strings.reidentify_string( + text="My name is [NAME_1], and my email is [EMAIL_1].", + vault_id="1ad6db07-8405-46cf-9a1e-db148ff9f4c5", + ) + + asyncio.run(main()) """ _response = await self._raw_client.reidentify_string( diff --git a/skyflow/generated/rest/tokens/client.py b/skyflow/generated/rest/tokens/client.py index d7861277..5518932c 100644 --- a/skyflow/generated/rest/tokens/client.py +++ b/skyflow/generated/rest/tokens/client.py @@ -65,10 +65,25 @@ def record_service_detokenize( Examples -------- - from skyflow import Skyflow - from skyflow import V1DetokenizeRecordRequest - client = Skyflow(token="YOUR_TOKEN", ) - client.tokens.record_service_detokenize(vault_id='vaultID', detokenization_parameters=[V1DetokenizeRecordRequest(token='afbd1074-51c1-4a16-9eee-e2c0ecb52125', redaction="PLAIN_TEXT", ), V1DetokenizeRecordRequest(token='05383487-fcae-42e5-a48e-5bd62a51af12', redaction="DEFAULT", )], download_url=False, ) + from skyflow import Skyflow, V1DetokenizeRecordRequest + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.tokens.record_service_detokenize( + vault_id="vaultID", + detokenization_parameters=[ + V1DetokenizeRecordRequest( + token="afbd1074-51c1-4a16-9eee-e2c0ecb52125", + redaction="PLAIN_TEXT", + ), + V1DetokenizeRecordRequest( + token="05383487-fcae-42e5-a48e-5bd62a51af12", + redaction="DEFAULT", + ), + ], + download_url=False, + ) """ _response = self._raw_client.record_service_detokenize( vault_id, @@ -108,8 +123,13 @@ def record_service_tokenize( Examples -------- from skyflow import Skyflow - client = Skyflow(token="YOUR_TOKEN", ) - client.tokens.record_service_tokenize(vault_id='vaultID', ) + + client = Skyflow( + token="YOUR_TOKEN", + ) + client.tokens.record_service_tokenize( + vault_id="vaultID", + ) """ _response = self._raw_client.record_service_tokenize( vault_id, tokenization_parameters=tokenization_parameters, request_options=request_options @@ -168,12 +188,32 @@ async def record_service_detokenize( Examples -------- - from skyflow import AsyncSkyflow - from skyflow import V1DetokenizeRecordRequest import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + from skyflow import AsyncSkyflow, V1DetokenizeRecordRequest + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.tokens.record_service_detokenize(vault_id='vaultID', detokenization_parameters=[V1DetokenizeRecordRequest(token='afbd1074-51c1-4a16-9eee-e2c0ecb52125', redaction="PLAIN_TEXT", ), V1DetokenizeRecordRequest(token='05383487-fcae-42e5-a48e-5bd62a51af12', redaction="DEFAULT", )], download_url=False, ) + await client.tokens.record_service_detokenize( + vault_id="vaultID", + detokenization_parameters=[ + V1DetokenizeRecordRequest( + token="afbd1074-51c1-4a16-9eee-e2c0ecb52125", + redaction="PLAIN_TEXT", + ), + V1DetokenizeRecordRequest( + token="05383487-fcae-42e5-a48e-5bd62a51af12", + redaction="DEFAULT", + ), + ], + download_url=False, + ) + + asyncio.run(main()) """ _response = await self._raw_client.record_service_detokenize( @@ -213,11 +253,21 @@ async def record_service_tokenize( Examples -------- - from skyflow import AsyncSkyflow import asyncio - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + from skyflow import AsyncSkyflow + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + async def main() -> None: - await client.tokens.record_service_tokenize(vault_id='vaultID', ) + await client.tokens.record_service_tokenize( + vault_id="vaultID", + ) + + asyncio.run(main()) """ _response = await self._raw_client.record_service_tokenize( diff --git a/skyflow/generated/rest/types/__init__.py b/skyflow/generated/rest/types/__init__.py index a30d1b32..74b8a5d1 100644 --- a/skyflow/generated/rest/types/__init__.py +++ b/skyflow/generated/rest/types/__init__.py @@ -20,6 +20,7 @@ from .deidentify_status_response import DeidentifyStatusResponse from .deidentify_status_response_output_type import DeidentifyStatusResponseOutputType from .deidentify_status_response_status import DeidentifyStatusResponseStatus +from .deidentify_status_response_word_character_count import DeidentifyStatusResponseWordCharacterCount from .deidentify_string_response import DeidentifyStringResponse from .detect_data_accuracy import DetectDataAccuracy from .detect_data_entities import DetectDataEntities @@ -116,6 +117,7 @@ "DeidentifyStatusResponse", "DeidentifyStatusResponseOutputType", "DeidentifyStatusResponseStatus", + "DeidentifyStatusResponseWordCharacterCount", "DeidentifyStringResponse", "DetectDataAccuracy", "DetectDataEntities", diff --git a/skyflow/generated/rest/types/deidentify_file_output.py b/skyflow/generated/rest/types/deidentify_file_output.py index 7e17e168..a4c2da4d 100644 --- a/skyflow/generated/rest/types/deidentify_file_output.py +++ b/skyflow/generated/rest/types/deidentify_file_output.py @@ -3,7 +3,9 @@ import typing import pydantic +import typing_extensions from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata from .deidentify_file_output_processed_file_type import DeidentifyFileOutputProcessedFileType @@ -12,17 +14,23 @@ class DeidentifyFileOutput(UniversalBaseModel): Details and contents of the processed file. """ - processed_file: typing.Optional[str] = pydantic.Field(default=None) + processed_file: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="processedFile")] = ( + pydantic.Field(default=None) + ) """ URL or base64-encoded data of the output. """ - processed_file_type: typing.Optional[DeidentifyFileOutputProcessedFileType] = pydantic.Field(default=None) + processed_file_type: typing_extensions.Annotated[ + typing.Optional[DeidentifyFileOutputProcessedFileType], FieldMetadata(alias="processedFileType") + ] = pydantic.Field(default=None) """ Type of the processed file. """ - processed_file_extension: typing.Optional[str] = pydantic.Field(default=None) + processed_file_extension: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="processedFileExtension") + ] = pydantic.Field(default=None) """ Extension of the processed file. """ diff --git a/skyflow/generated/rest/types/deidentify_status_response.py b/skyflow/generated/rest/types/deidentify_status_response.py index a0333564..0ad91e62 100644 --- a/skyflow/generated/rest/types/deidentify_status_response.py +++ b/skyflow/generated/rest/types/deidentify_status_response.py @@ -3,10 +3,13 @@ import typing import pydantic +import typing_extensions from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata from .deidentify_file_output import DeidentifyFileOutput from .deidentify_status_response_output_type import DeidentifyStatusResponseOutputType from .deidentify_status_response_status import DeidentifyStatusResponseStatus +from .deidentify_status_response_word_character_count import DeidentifyStatusResponseWordCharacterCount class DeidentifyStatusResponse(UniversalBaseModel): @@ -24,7 +27,9 @@ class DeidentifyStatusResponse(UniversalBaseModel): How the input file was specified. """ - output_type: DeidentifyStatusResponseOutputType = pydantic.Field() + output_type: typing_extensions.Annotated[ + typing.Optional[DeidentifyStatusResponseOutputType], FieldMetadata(alias="outputType") + ] = pydantic.Field(default=None) """ How the output file is specified. """ @@ -34,22 +39,19 @@ class DeidentifyStatusResponse(UniversalBaseModel): Status details about the detect run. """ - word_count: typing.Optional[int] = pydantic.Field(default=None) + word_character_count: typing_extensions.Annotated[ + typing.Optional[DeidentifyStatusResponseWordCharacterCount], FieldMetadata(alias="wordCharacterCount") + ] = pydantic.Field(default=None) """ - Number of words in the processed text. + Word and character count in the processed text. """ - character_count: typing.Optional[int] = pydantic.Field(default=None) - """ - Number of characters in the processed text. - """ - - size: typing.Optional[int] = pydantic.Field(default=None) + size: typing.Optional[float] = pydantic.Field(default=None) """ Size of the processed text in kilobytes (KB). """ - duration: typing.Optional[int] = pydantic.Field(default=None) + duration: typing.Optional[float] = pydantic.Field(default=None) """ Duration of the processed audio in seconds. """ diff --git a/skyflow/generated/rest/types/deidentify_status_response_word_character_count.py b/skyflow/generated/rest/types/deidentify_status_response_word_character_count.py new file mode 100644 index 00000000..6584ca92 --- /dev/null +++ b/skyflow/generated/rest/types/deidentify_status_response_word_character_count.py @@ -0,0 +1,26 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata + + +class DeidentifyStatusResponseWordCharacterCount(UniversalBaseModel): + """ + Word and character count in the processed text. + """ + + word_count: typing_extensions.Annotated[typing.Optional[int], FieldMetadata(alias="wordCount")] = None + character_count: typing_extensions.Annotated[typing.Optional[int], FieldMetadata(alias="characterCount")] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/skyflow/generated/rest/version.py b/skyflow/generated/rest/version.py index 5a6bc65e..8c0d5d5b 100644 --- a/skyflow/generated/rest/version.py +++ b/skyflow/generated/rest/version.py @@ -1 +1 @@ -__version__ = "2.0.0" \ No newline at end of file +__version__ = "2.0.0" diff --git a/skyflow/utils/_skyflow_messages.py b/skyflow/utils/_skyflow_messages.py index e941b7dd..32f1c6b6 100644 --- a/skyflow/utils/_skyflow_messages.py +++ b/skyflow/utils/_skyflow_messages.py @@ -71,6 +71,14 @@ class Error(Enum): RESPONSE_NOT_JSON = f"{error_prefix} Response {{}} is not valid JSON." API_ERROR = f"{error_prefix} Server returned status code {{}}" + INVALID_FILE_INPUT = f"{error_prefix} Validation error. Invalid file input. Specify a valid file input." + INVALID_DETECT_ENTITIES_TYPE = f"{error_prefix} Validation error. Invalid type of detect entities. Specify detect entities as list of DetectEntities enum." + INVALID_TYPE_FOR_DEFAULT_TOKEN_TYPE = f"{error_prefix} Validation error. Invalid type of default token type. Specify default token type as TokenType enum." + INVALID_TOKEN_TYPE_VALUE = f"{error_prefix} Validation error. Invalid value for token type {{}}. Specify as list of DetectEntities enum." + INVALID_MAXIMUM_RESOLUTION = f"{error_prefix} Validation error. Invalid type of maximum resolution. Specify maximum resolution as a number." + INVALID_OUTPUT_DIRECTORY_VALUE = f"{error_prefix} Validation error. Invalid type of output directory. Specify output directory as a string." + WAIT_TIME_GREATER_THEN_64 = f"{error_prefix} Validation error. Invalid wait time. Wait time should be less than or equal to 64 seconds." + MISSING_TABLE_NAME_IN_INSERT = f"{error_prefix} Validation error. Table name cannot be empty in insert request. Specify a table name." INVALID_TABLE_NAME_IN_INSERT = f"{error_prefix} Validation error. Invalid table name in insert request. Specify a valid table name." INVALID_TYPE_OF_DATA_IN_INSERT = f"{error_prefix} Validation error. Invalid type of data in insert request. Specify data as a object array." @@ -147,50 +155,56 @@ class Error(Enum): FILE_INVALID_JSON = f"{error_prefix} Initialization failed. File at {{}} is not in valid JSON format. Verify the file contents." INVALID_JSON_FORMAT_IN_CREDENTIALS_ENV = f"{error_prefix} Validation error. Invalid JSON format in SKYFLOW_CREDENTIALS environment variable." - INVALID_TEXT_IN_DEIDENTIFY = f"{error_prefix} Validation error. The text field is required and must be a non-empty string. Specify a valid text." - INVALID_ENTITIES_IN_DEIDENTIFY = f"{error_prefix} Validation error. The entities field must be an array of DetectEntities enums. Specify a valid entities." - INVALID_ALLOW_REGEX_LIST = f"{error_prefix} Validation error. The allowRegexList field must be an array of strings. Specify a valid allowRegexList." - INVALID_RESTRICT_REGEX_LIST = f"{error_prefix} Validation error. The restrictRegexList field must be an array of strings. Specify a valid restrictRegexList." - INVALID_TOKEN_FORMAT = f"{error_prefix} Validation error. The tokenFormat key must be an instance of TokenFormat. Specify a valid token format." - INVALID_TRANSFORMATIONS = f"{error_prefix} Validation error. The transformations key must be an instance of Transformations. Specify a valid transformations." - - INVALID_TEXT_IN_REIDENTIFY = f"{error_prefix} Validation error. The text field is required and must be a non-empty string. Specify a valid text." - INVALID_REDACTED_ENTITIES_IN_REIDENTIFY = f"{error_prefix} Validation error. The redactedEntities field must be an array of DetectEntities enums. Specify a valid redactedEntities." - INVALID_MASKED_ENTITIES_IN_REIDENTIFY = f"{error_prefix} Validation error. The maskedEntities field must be an array of DetectEntities enums. Specify a valid maskedEntities." - INVALID_PLAIN_TEXT_ENTITIES_IN_REIDENTIFY = f"{error_prefix} Validation error. The plainTextEntities field must be an array of DetectEntities enums. Specify a valid plainTextEntities." - - INVALID_DEIDENTIFY_FILE_REQUEST = f"{error_prefix} Validation error. Invalid deidentify file request. Specify a valid deidentify file request." - EMPTY_FILE_OBJECT = f"{error_prefix} Validation error. File object cannot be empty. Specify a valid file object." - INVALID_FILE_FORMAT = f"{error_prefix} Validation error. Invalid file format. Specify a valid file format." - MISSING_FILE_SOURCE = f"{error_prefix} Validation error. Provide exactly one of filePath, base64, or fileObject." - INVALID_FILE_OBJECT = f"{error_prefix} Validation error. Invalid file object. Specify a valid file object." - INVALID_BASE64_STRING = f"{error_prefix} Validation error. Invalid base64 string. Specify a valid base64 string." - INVALID_DEIDENTIFY_FILE_OPTIONS = f"{error_prefix} Validation error. Invalid deidentify file options. Specify a valid deidentify file options." - INVALID_ENTITIES = f"{error_prefix} Validation error. Invalid entities. Specify valid entities as string array." - EMPTY_ENTITIES = f"{error_prefix} Validation error. Entities cannot be empty. Specify valid entities." - EMPTY_ALLOW_REGEX_LIST = f"{error_prefix} Validation error. Allow regex list cannot be empty. Specify valid allow regex list." - INVALID_ALLOW_REGEX = f"{error_prefix} Validation error. Invalid allow regex. Specify valid allow regex at index {{}}." - EMPTY_RESTRICT_REGEX_LIST = f"{error_prefix} Validation error. Restrict regex list cannot be empty. Specify valid restrict regex list." - INVALID_RESTRICT_REGEX = f"{error_prefix} Validation error. Invalid restrict regex. Specify valid restrict regex at index {{}}." - INVALID_OUTPUT_PROCESSED_IMAGE = f"{error_prefix} Validation error. Invalid output processed image. Specify valid output processed image as string." - INVALID_OUTPUT_OCR_TEXT = f"{error_prefix} Validation error. Invalid output ocr text. Specify valid output ocr text as string." - INVALID_MASKING_METHOD = f"{error_prefix} Validation error. Invalid masking method. Specify valid masking method as string." - INVALID_PIXEL_DENSITY = f"{error_prefix} Validation error. Invalid pixel density. Specify valid pixel density as string." - INVALID_OUTPUT_TRANSCRIPTION = f"{error_prefix} Validation error. Invalid output transcription. Specify valid output transcription as string." - INVALID_OUTPUT_PROCESSED_AUDIO = f"{error_prefix} Validation error. Invalid output processed audio. Specify valid output processed audio as string." - INVALID_MAX_RESOLUTION = f"{error_prefix} Validation error. Invalid max resolution. Specify valid max resolution as string." - INVALID_BLEEP = f"{error_prefix} Validation error. Invalid bleep. Specify valid bleep as object." - INVALID_FILE_OR_ENCODED_FILE = f"{error_prefix} . Error while decoding base64 and saving file" - INVALID_FILE_TYPE = f"{error_prefix} Validation error. Invalid file type. Specify a valid file type." - INVALID_FILE_NAME = f"{error_prefix} Validation error. Invalid file name. Specify a valid file name." - FILE_READ_ERROR = f"{error_prefix} Validation error. Unable to read file. Verify the file path." - INVALID_BASE64_HEADER = f"{error_prefix} Validation error. Invalid base64 header. Specify a valid base64 header." - INVALID_WAIT_TIME = f"{error_prefix} Validation error. Invalid wait time. Specify a valid wait time as number and should not be greater than 20 secs." - INVALID_OUTPUT_DIRECTORY = f"{error_prefix} Validation error. Invalid output directory. Specify a valid output directory as string." - INVALID_OUTPUT_DIRECTORY_PATH = f"{error_prefix} Validation error. Invalid output directory path. Specify a valid output directory path as string." - EMPTY_RUN_ID = f"{error_prefix} Validation error. Run id cannot be empty. Specify a valid run id." - INVALID_RUN_ID = f"{error_prefix} Validation error. Invalid run id. Specify a valid run id as string." - INTERNAL_SERVER_ERROR = f"{error_prefix}. Internal server error. {{}}." + INVALID_TEXT_IN_DEIDENTIFY= f"{error_prefix} Validation error. The text field is required and must be a non-empty string. Specify a valid text." + INVALID_ENTITIES_IN_DEIDENTIFY= f"{error_prefix} Validation error. The entities field must be an array of DetectEntities enums. Specify a valid entities." + INVALID_ALLOW_REGEX_LIST= f"{error_prefix} Validation error. The allowRegexList field must be an array of strings. Specify a valid allowRegexList." + INVALID_RESTRICT_REGEX_LIST= f"{error_prefix} Validation error. The restrictRegexList field must be an array of strings. Specify a valid restrictRegexList." + INVALID_TOKEN_FORMAT= f"{error_prefix} Validation error. The tokenFormat key must be an instance of TokenFormat. Specify a valid token format." + INVALID_TRANSFORMATIONS= f"{error_prefix} Validation error. The transformations key must be an instance of Transformations. Specify a valid transformations." + + INVALID_TEXT_IN_REIDENTIFY= f"{error_prefix} Validation error. The text field is required and must be a non-empty string. Specify a valid text." + INVALID_REDACTED_ENTITIES_IN_REIDENTIFY= f"{error_prefix} Validation error. The redactedEntities field must be an array of DetectEntities enums. Specify a valid redactedEntities." + INVALID_MASKED_ENTITIES_IN_REIDENTIFY= f"{error_prefix} Validation error. The maskedEntities field must be an array of DetectEntities enums. Specify a valid maskedEntities." + INVALID_PLAIN_TEXT_ENTITIES_IN_REIDENTIFY= f"{error_prefix} Validation error. The plainTextEntities field must be an array of DetectEntities enums. Specify a valid plainTextEntities." + + INVALID_DEIDENTIFY_FILE_REQUEST= f"{error_prefix} Validation error. Invalid deidentify file request. Specify a valid deidentify file request." + EMPTY_FILE_OBJECT= f"{error_prefix} Validation error. File object cannot be empty. Specify a valid file object." + INVALID_FILE_FORMAT= f"{error_prefix} Validation error. Invalid file format. Specify a valid file format." + MISSING_FILE_SOURCE= f"{error_prefix} Validation error. Provide exactly one of filePath, base64, or fileObject." + INVALID_FILE_OBJECT= f"{error_prefix} Validation error. Invalid file object. Specify a valid file object." + INVALID_BASE64_STRING= f"{error_prefix} Validation error. Invalid base64 string. Specify a valid base64 string." + INVALID_DEIDENTIFY_FILE_OPTIONS= f"{error_prefix} Validation error. Invalid deidentify file options. Specify a valid deidentify file options." + INVALID_ENTITIES= f"{error_prefix} Validation error. Invalid entities. Specify valid entities as string array." + EMPTY_ENTITIES= f"{error_prefix} Validation error. Entities cannot be empty. Specify valid entities." + EMPTY_ALLOW_REGEX_LIST= f"{error_prefix} Validation error. Allow regex list cannot be empty. Specify valid allow regex list." + INVALID_ALLOW_REGEX= f"{error_prefix} Validation error. Invalid allow regex. Specify valid allow regex at index {{}}." + EMPTY_RESTRICT_REGEX_LIST= f"{error_prefix} Validation error. Restrict regex list cannot be empty. Specify valid restrict regex list." + INVALID_RESTRICT_REGEX= f"{error_prefix} Validation error. Invalid restrict regex. Specify valid restrict regex at index {{}}." + INVALID_OUTPUT_PROCESSED_IMAGE= f"{error_prefix} Validation error. Invalid output processed image. Specify valid output processed image as string." + INVALID_OUTPUT_OCR_TEXT= f"{error_prefix} Validation error. Invalid output ocr text. Specify valid output ocr text as string." + INVALID_MASKING_METHOD= f"{error_prefix} Validation error. Invalid masking method. Specify valid masking method as MaskingMethod enum." + INVALID_PIXEL_DENSITY= f"{error_prefix} Validation error. Invalid pixel density. Specify valid pixel density as string." + INVALID_OUTPUT_TRANSCRIPTION= f"{error_prefix} Validation error. Invalid output transcription. Specify valid output transcription as string." + INVALID_BLEEP_TYPE= f"{error_prefix} Validation error. Invalid type of bleep. Specify bleep as Bleep object." + INVALID_BLEEP_GAIN= f"{error_prefix} Validation error. Invalid bleep gain. Specify valid bleep gain as a number." + INVALID_BLEEP_FREQUENCY= f"{error_prefix} Validation error. Invalid bleep frequency. Specify valid bleep frequency as a number." + INVALID_BLEEP_START_PADDING= f"{error_prefix} Validation error. Invalid bleep start padding. Specify valid bleep start padding as a number." + INVALID_BLEEP_STOP_PADDING= f"{error_prefix} Validation error. Invalid bleep stop padding. Specify valid bleep stop padding as a number." + INVALID_OUTPUT_PROCESSED_AUDIO= f"{error_prefix} Validation error. Invalid output processed audio. Specify valid output processed audio as string." + INVALID_MAX_RESOLUTION= f"{error_prefix} Validation error. Invalid max resolution. Specify valid max resolution as string." + INVALID_BLEEP= f"{error_prefix} Validation error. Invalid bleep. Specify valid bleep as object." + INVALID_FILE_OR_ENCODED_FILE= f"{error_prefix} . Error while decoding base64 and saving file" + INVALID_FILE_TYPE = f"{error_prefix} Validation error. Invalid file type. Specify a valid file type." + INVALID_FILE_NAME= f"{error_prefix} Validation error. Invalid file name. Specify a valid file name." + FILE_READ_ERROR= f"{error_prefix} Validation error. Unable to read file. Verify the file path." + INVALID_BASE64_HEADER= f"{error_prefix} Validation error. Invalid base64 header. Specify a valid base64 header." + INVALID_WAIT_TIME= f"{error_prefix} Validation error. Invalid wait time. Specify a valid wait time as number and should not be greater than 20 secs." + INVALID_OUTPUT_DIRECTORY= f"{error_prefix} Validation error. Invalid output directory. Specify a valid output directory as string." + INVALID_OUTPUT_DIRECTORY_PATH= f"{error_prefix} Validation error. Invalid output directory path. Specify a valid output directory path as string." + EMPTY_RUN_ID= f"{error_prefix} Validation error. Run id cannot be empty. Specify a valid run id." + INVALID_RUN_ID= f"{error_prefix} Validation error. Invalid run id. Specify a valid run id as string." + INTERNAL_SERVER_ERROR= f"{error_prefix}. Internal server error. {{}}." + GET_DETECT_RUN_FAILED = f"{error_prefix} Get detect run operation failed." class Info(Enum): CLIENT_INITIALIZED = f"{INFO}: [{error_prefix}] Initialized skyflow client." @@ -215,6 +229,11 @@ class Info(Enum): GENERATE_BEARER_TOKEN_FROM_CREDENTIALS_STRING_TRIGGERED = f"{INFO}: [{error_prefix}] generate bearer_token_from_credential_string method triggered." REUSE_BEARER_TOKEN = f"{INFO}: [{error_prefix}] Reusing bearer token." + VALIDATE_DEIDENTIFY_FILE_REQUEST = f"{INFO}: [{error_prefix}] Validating deidentify file request." + DETECT_FILE_TRIGGERED = f"{INFO}: [{error_prefix}] Detect file method triggered." + DETECT_FILE_REQUEST_RESOLVED = f"{INFO}: [{error_prefix}] Deidentify file request resolved." + DETECT_FILE_SUCCESS = f"{INFO}: [{error_prefix}] File deidentified." + VALIDATE_INSERT_REQUEST = f"{INFO}: [{error_prefix}] Validating insert request." INSERT_TRIGGERED = f"{INFO}: [{error_prefix}] Insert method triggered." INSERT_SUCCESS = f"{INFO}: [{error_prefix}] Data inserted." @@ -354,6 +373,7 @@ class ErrorLogs(Enum): DETECT_RUN_REQUEST_REJECTED = f"{ERROR}: [{error_prefix}] Detect get run resulted in failure." DEIDENTIFY_TEXT_REQUEST_REJECTED = f"{ERROR}: [{error_prefix}] Deidentify text resulted in failure." REIDENTIFY_TEXT_REQUEST_REJECTED = f"{ERROR}: [{error_prefix}] Reidentify text resulted in failure." + DETECT_FILE_REQUEST_REJECTED = f"{ERROR}: [{error_prefix}] Deidentify file resulted in failure." class Interface(Enum): INSERT = "INSERT" diff --git a/skyflow/utils/_utils.py b/skyflow/utils/_utils.py index 58e008a7..6b013a85 100644 --- a/skyflow/utils/_utils.py +++ b/skyflow/utils/_utils.py @@ -14,7 +14,7 @@ from skyflow.error import SkyflowError from skyflow.generated.rest import V1UpdateRecordResponse, V1BulkDeleteRecordResponse, \ V1DetokenizeResponse, V1TokenizeResponse, V1GetQueryResponse, V1BulkGetRecordResponse, \ - DeidentifyStringResponse, ReidentifyStringResponse + DeidentifyStringResponse, ReidentifyStringResponse, ErrorResponse from skyflow.generated.rest.core.http_response import HttpResponse from skyflow.utils.logger import log_error_log from skyflow.vault.detect import DeidentifyTextResponse, ReidentifyTextResponse @@ -421,6 +421,8 @@ def handle_json_error(err, data, request_id, logger): try: if isinstance(data, dict): # If data is already a dict description = data + elif isinstance(data, ErrorResponse): + description = data.dict() else: description = json.loads(data) status_code = description.get('error', {}).get('http_code', 500) # Default to 500 if not found diff --git a/skyflow/utils/enums/__init__.py b/skyflow/utils/enums/__init__.py index 928ba6ac..af293ce2 100644 --- a/skyflow/utils/enums/__init__.py +++ b/skyflow/utils/enums/__init__.py @@ -5,4 +5,8 @@ from .token_mode import TokenMode from .token_type import TokenType from .request_method import RequestMethod -from .redaction_type import RedactionType \ No newline at end of file +from .redaction_type import RedactionType +from .detect_entities import DetectEntities +from .detect_output_transcriptions import DetectOutputTranscriptions +from .masking_method import MaskingMethod +from .token_type import TokenType \ No newline at end of file diff --git a/skyflow/utils/enums/detect_output_transcriptions.py b/skyflow/utils/enums/detect_output_transcriptions.py new file mode 100644 index 00000000..69f94d79 --- /dev/null +++ b/skyflow/utils/enums/detect_output_transcriptions.py @@ -0,0 +1,8 @@ +from enum import Enum + +class DetectOutputTranscriptions(Enum): + DIARIZED_TRANSCRIPTION = "diarized_transcription" + MEDICAL_DIARIZED_TRANSCRIPTION = "medical_diarized_transcription" + MEDICAL_TRANSCRIPTION = "medical_transcription" + PLAINTEXT_TRANSCRIPTION = "plaintext_transcription" + TRANSCRIPTION = "transcription" \ No newline at end of file diff --git a/skyflow/utils/enums/masking_method.py b/skyflow/utils/enums/masking_method.py new file mode 100644 index 00000000..b7dad141 --- /dev/null +++ b/skyflow/utils/enums/masking_method.py @@ -0,0 +1,5 @@ +from enum import Enum + +class MaskingMethod(Enum): + BLACKOUT= "blackout" + BLUR= "blur" \ No newline at end of file diff --git a/skyflow/utils/validations/__init__.py b/skyflow/utils/validations/__init__.py index bf4a93e5..b8ce13c8 100644 --- a/skyflow/utils/validations/__init__.py +++ b/skyflow/utils/validations/__init__.py @@ -14,5 +14,7 @@ validate_tokenize_request, validate_invoke_connection_params, validate_deidentify_text_request, - validate_reidentify_text_request + validate_reidentify_text_request, + validate_deidentify_file_request, + validate_get_detect_run_request, ) \ No newline at end of file diff --git a/skyflow/utils/validations/_validations.py b/skyflow/utils/validations/_validations.py index f43bf31e..afcc7e5e 100644 --- a/skyflow/utils/validations/_validations.py +++ b/skyflow/utils/validations/_validations.py @@ -1,10 +1,14 @@ import json +import os +from skyflow.generated.rest import TokenType from skyflow.service_account import is_expired -from skyflow.utils.enums import LogLevel, Env, RedactionType, TokenMode +from skyflow.utils.enums import LogLevel, Env, RedactionType, TokenMode, DetectEntities, DetectOutputTranscriptions, \ + MaskingMethod from skyflow.error import SkyflowError from skyflow.utils import SkyflowMessages from skyflow.utils.logger import log_info, log_error_log -from skyflow.vault.detect import DeidentifyTextRequest, ReidentifyTextRequest, TokenFormat, Transformations +from skyflow.vault.detect import DeidentifyTextRequest, ReidentifyTextRequest, TokenFormat, Transformations, \ + GetDetectRunRequest, Bleep, DeidentifyFileRequest valid_vault_config_keys = ["vault_id", "cluster_id", "credentials", "env"] valid_connection_config_keys = ["connection_id", "connection_url", "credentials"] @@ -253,6 +257,106 @@ def validate_update_connection_config(logger, config): return True +def validate_deidentify_file_request(logger, request: DeidentifyFileRequest): + if not hasattr(request, 'file') or request.file is None: + raise SkyflowError(SkyflowMessages.Error.INVALID_FILE_INPUT.value, invalid_input_error_code) + + # Optional: entities + if hasattr(request, 'entities') and request.entities is not None: + if not isinstance(request.entities, list): + raise SkyflowError(SkyflowMessages.Error.INVALID_DETECT_ENTITIES_TYPE.value, invalid_input_error_code) + + if not all(isinstance(entity, DetectEntities) for entity in request.entities): + raise SkyflowError(SkyflowMessages.Error.INVALID_DETECT_ENTITIES_TYPE.value, invalid_input_error_code) + + # Optional: allow_regex_list + if hasattr(request, 'allow_regex_list') and request.allow_regex_list is not None: + if not isinstance(request.allow_regex_list, list) or not all(isinstance(x, str) for x in request.allow_regex_list): + raise SkyflowError(SkyflowMessages.Error.INVALID_ALLOW_REGEX_LIST.value, invalid_input_error_code) + + # Optional: restrict_regex_list + if hasattr(request, 'restrict_regex_list') and request.restrict_regex_list is not None: + if not isinstance(request.restrict_regex_list, list) or not all(isinstance(x, str) for x in request.restrict_regex_list): + raise SkyflowError(SkyflowMessages.Error.INVALID_RESTRICT_REGEX_LIST.value, invalid_input_error_code) + + # Optional: token_format + if request.token_format is not None and not isinstance(request.token_format, TokenFormat): + raise SkyflowError(SkyflowMessages.Error.INVALID_TOKEN_FORMAT.value, invalid_input_error_code) + + # Optional: transformations + if request.transformations is not None and not isinstance(request.transformations, Transformations): + raise SkyflowError(SkyflowMessages.Error.INVALID_TRANSFORMATIONS.value, invalid_input_error_code) + + # Optional: output_processed_image + if hasattr(request, 'output_processed_image') and request.output_processed_image is not None: + if not isinstance(request.output_processed_image, bool): + raise SkyflowError(SkyflowMessages.Error.INVALID_OUTPUT_PROCESSED_IMAGE.value, invalid_input_error_code) + + # Optional: output_ocr_text + if hasattr(request, 'output_ocr_text') and request.output_ocr_text is not None: + if not isinstance(request.output_ocr_text, bool): + raise SkyflowError(SkyflowMessages.Error.INVALID_OUTPUT_OCR_TEXT.value, invalid_input_error_code) + + # Optional: masking_method + # Optional: masking_method + if hasattr(request, 'masking_method') and request.masking_method is not None: + if not isinstance(request.masking_method, MaskingMethod): + raise SkyflowError(SkyflowMessages.Error.INVALID_MASKING_METHOD.value, invalid_input_error_code) + + # Optional: pixel_density + if hasattr(request, 'pixel_density') and request.pixel_density is not None: + if not isinstance(request.pixel_density, (int, float)): + raise SkyflowError(SkyflowMessages.Error.INVALID_PIXEL_DENSITY.value, invalid_input_error_code) + + # Optional: max_resolution + if hasattr(request, 'max_resolution') and request.max_resolution is not None: + if not isinstance(request.max_resolution, (int, float)): + raise SkyflowError(SkyflowMessages.Error.INVALID_MAXIMUM_RESOLUTION.value, invalid_input_error_code) + + # Optional: output_processed_audio + if hasattr(request, 'output_processed_audio') and request.output_processed_audio is not None: + if not isinstance(request.output_processed_audio, bool): + raise SkyflowError(SkyflowMessages.Error.INVALID_OUTPUT_PROCESSED_AUDIO.value, invalid_input_error_code) + + # Optional: output_transcription + if hasattr(request, 'output_transcription') and request.output_transcription is not None: + if not isinstance(request.output_transcription, DetectOutputTranscriptions): + raise SkyflowError(SkyflowMessages.Error.INVALID_OUTPUT_TRANSCRIPTION.value, invalid_input_error_code) + + # Optional: bleep + if hasattr(request, 'bleep') and request.bleep is not None: + if not isinstance(request.bleep, Bleep): + raise SkyflowError(SkyflowMessages.Error.INVALID_BLEEP_TYPE.value, invalid_input_error_code) + + # Validate gain + if request.bleep.gain is not None and not isinstance(request.bleep.gain, (int, float)): + raise SkyflowError(SkyflowMessages.Error.INVALID_BLEEP_GAIN.value, invalid_input_error_code) + + # Validate frequency + if request.bleep.frequency is not None and not isinstance(request.bleep.frequency, (int, float)): + raise SkyflowError(SkyflowMessages.Error.INVALID_BLEEP_FREQUENCY.value, invalid_input_error_code) + + # Validate start_padding + if request.bleep.start_padding is not None and not isinstance(request.bleep.start_padding, (int, float)): + raise SkyflowError(SkyflowMessages.Error.INVALID_BLEEP_START_PADDING.value, invalid_input_error_code) + + # Validate stop_padding + if request.bleep.stop_padding is not None and not isinstance(request.bleep.stop_padding, (int, float)): + raise SkyflowError(SkyflowMessages.Error.INVALID_BLEEP_STOP_PADDING.value, invalid_input_error_code) + + # Optional: output_directory + if hasattr(request, 'output_directory') and request.output_directory is not None: + if not isinstance(request.output_directory, str): + raise SkyflowError(SkyflowMessages.Error.INVALID_OUTPUT_DIRECTORY_VALUE.value, invalid_input_error_code) + if not os.path.isdir(request.output_directory): + raise SkyflowError(SkyflowMessages.Error.INVALID_OUTPUT_DIRECTORY_VALUE.value, invalid_input_error_code) + + # Optional: wait_time + if hasattr(request, 'wait_time') and request.wait_time is not None: + if not isinstance(request.wait_time, (int, float)): + raise SkyflowError(SkyflowMessages.Error.INVALID_WAIT_TIME.value, invalid_input_error_code) + if request.wait_time > 64: + raise SkyflowError(SkyflowMessages.Error.WAIT_TIME_GREATER_THEN_64.value, invalid_input_error_code) def validate_insert_request(logger, request): if not isinstance(request.table_name, str): @@ -613,3 +717,8 @@ def validate_reidentify_text_request(self, request: ReidentifyTextRequest): # Validate plain_text_entities if present if request.plain_text_entities is not None and not isinstance(request.plain_text_entities, list): raise SkyflowError(SkyflowMessages.Error.INVALID_PLAIN_TEXT_ENTITIES_IN_REIDENTIFY.value, invalid_input_error_code) + +def validate_get_detect_run_request(self, request: GetDetectRunRequest): + if not request.run_id or not isinstance(request.run_id, str) or not request.run_id.strip(): + raise SkyflowError(SkyflowMessages.Error.INVALID_RUN_ID.value, invalid_input_error_code) + diff --git a/skyflow/vault/controller/_detect.py b/skyflow/vault/controller/_detect.py index 928e0e6d..f0a9da7c 100644 --- a/skyflow/vault/controller/_detect.py +++ b/skyflow/vault/controller/_detect.py @@ -1,15 +1,24 @@ import json +import os +from skyflow.error import SkyflowError from skyflow.generated.rest.types.token_type import TokenType from skyflow.generated.rest.types.transformations import Transformations from skyflow.generated.rest.types.transformations_shift_dates import TransformationsShiftDates +import base64 +import time +from skyflow.generated.rest import DeidentifyTextRequestFile, DeidentifyAudioRequestFile, DeidentifyPdfRequestFile, \ + DeidentifyImageRequestFile, DeidentifyPresentationRequestFile, DeidentifySpreadsheetRequestFile, \ + DeidentifyDocumentRequestFile, DeidentifyFileRequestFile from skyflow.utils._skyflow_messages import SkyflowMessages from skyflow.utils._utils import get_metrics, handle_exception, parse_deidentify_text_response, parse_reidentify_text_response from skyflow.utils.constants import SKY_META_DATA_HEADER from skyflow.utils.logger import log_info, log_error_log +from skyflow.utils.validations import validate_deidentify_file_request, validate_get_detect_run_request from skyflow.utils.validations._validations import validate_deidentify_text_request, validate_reidentify_text_request from typing import Dict, Any from skyflow.generated.rest.strings.types.reidentify_string_request_format import ReidentifyStringRequestFormat -from skyflow.vault.detect import DeidentifyTextRequest, DeidentifyTextResponse, ReidentifyTextRequest, ReidentifyTextResponse +from skyflow.vault.detect import DeidentifyTextRequest, DeidentifyTextResponse, ReidentifyTextRequest, \ + ReidentifyTextResponse, DeidentifyFileRequest, DeidentifyFileResponse, GetDetectRunRequest class Detect: def __init__(self, vault_client): @@ -27,31 +36,13 @@ def __get_headers(self): def ___build_deidentify_text_body(self, request: DeidentifyTextRequest) -> Dict[str, Any]: deidentify_text_body = {} parsed_entity_types = request.entities - - parsed_token_type = None - if request.token_format is not None: - parsed_token_type = TokenType( - default = request.token_format.default, - vault_token = request.token_format.vault_token, - entity_unq_counter = request.token_format.entity_unique_counter, - entity_only = request.token_format.entity_only - ) - parsed_transformations = None - if request.transformations is not None: - parsed_transformations = Transformations( - shift_dates = TransformationsShiftDates( - max_days = request.transformations.shift_dates.max, - min_days = request.transformations.shift_dates.min, - entity_types = request.transformations.shift_dates.entities - ) - ) deidentify_text_body['text'] = request.text deidentify_text_body['entity_types'] = parsed_entity_types - deidentify_text_body['token_type'] = parsed_token_type + deidentify_text_body['token_type'] = self.__get_token_format(request) deidentify_text_body['allow_regex'] = request.allow_regex_list deidentify_text_body['restrict_regex'] = request.restrict_regex_list - deidentify_text_body['transformations'] = parsed_transformations + deidentify_text_body['transformations'] = self.__get_transformations(request) return deidentify_text_body @@ -66,6 +57,116 @@ def ___build_reidentify_text_body(self, request: ReidentifyTextRequest) -> Dict[ reidentify_text_body['format'] = parsed_format return reidentify_text_body + def _get_file_extension(self, filename: str): + return filename.split('.')[-1].lower() if '.' in filename else '' + + def __poll_for_processed_file(self, run_id, max_wait_time=64): + files_api = self.__vault_client.get_detect_file_api() + current_wait_time = 1 # Start with 1 second + try: + while True: + response = files_api.get_run(run_id, vault_id=self.__vault_client.get_vault_id(), request_options=self.__get_headers()) + status = response.status + if status == 'IN_PROGRESS': + if current_wait_time >= max_wait_time: + return DeidentifyFileResponse(run_id=run_id, status='IN_PROGRESS') + else: + next_wait_time = current_wait_time * 2 + if next_wait_time >= max_wait_time: + wait_time = max_wait_time - current_wait_time + current_wait_time = max_wait_time + else: + wait_time = next_wait_time + current_wait_time = next_wait_time + time.sleep(wait_time) + elif status == 'SUCCESS': + return response + elif status == 'FAILED': + raise SkyflowError(SkyflowMessages.Error.INTERNAL_SERVER_ERROR.value.format(response.message), 500) + else: + raise SkyflowError(SkyflowMessages.Error.GET_DETECT_RUN_FAILED.value, 500) + except Exception as e: + raise e + + def __parse_deidentify_file_response(self, data, run_id=None, status=None): + + output = getattr(data, "output", []) + output_type = getattr(data, "output_type", None) + word_character_count = getattr(data, "word_character_count", None) + size = getattr(data, "size", None) + duration = getattr(data, "duration", None) + pages = getattr(data, "pages", None) + slides = getattr(data, "slides", None) + message = getattr(data, "message", None) + status_val = getattr(data, "status", None) or status + run_id_val = getattr(data, "run_id", None) or run_id + + # Convert output to list of dicts if it's a list of objects + def output_to_dict_list(output): + result = [] + for o in output: + if isinstance(o, dict): + result.append({ + "file": o.get("processedFile") or o.get("processed_file"), + "type": o.get("processedFileType") or o.get("processed_file_type"), + "extension": o.get("processedFileExtension") or o.get("processed_file_extension") + }) + else: + result.append({ + "file": getattr(o, "processed_file", None), + "type": getattr(o, "processed_file_type", None), + "extension": getattr(o, "processed_file_extension", None) + }) + return result + + output_list = output_to_dict_list(output) + first_output = output_list[0] if output_list else {} + + entities = [o for o in output_list if o.get("type") == "entities"] + + word_count = getattr(word_character_count, "word_count", None) + char_count = getattr(word_character_count, "character_count", None) + + return DeidentifyFileResponse( + file=first_output.get("file", None), + type=first_output.get("type", None), + extension=first_output.get("extension", None), + word_count=word_count, + char_count=char_count, + size_in_kb=size, + duration_in_seconds=duration, + page_count=pages, + slide_count=slides, + entities=entities, + run_id=run_id_val, + status=status_val, + errors=[] + ) + + def __get_token_format(self, request): + if not hasattr(request, "token_format") or request.token_format is None: + return None + return { + 'default': getattr(request.token_format, "default", None), + 'entity_unq_counter': getattr(request.token_format, "entity_unique_counter", None), + 'entity_only': getattr(request.token_format, "entity_only", None), + 'vault_token': getattr(request.token_format, "vault_token", None) + } + + def __get_transformations(self, request): + if not hasattr(request, "transformations") or request.transformations is None: + return None + shift_dates = getattr(request.transformations, "shift_dates", None) + if shift_dates is None: + return None + return { + 'shift_dates': { + 'max_days': getattr(shift_dates, "max", None), + 'min_days': getattr(shift_dates, "min", None), + 'entity_types': getattr(shift_dates, "entities", None) + } + } + def deidentify_text(self, request: DeidentifyTextRequest) -> DeidentifyTextResponse: log_info(SkyflowMessages.Info.VALIDATING_DEIDENTIFY_TEXT_INPUT.value, self.__vault_client.get_logger()) validate_deidentify_text_request(self.__vault_client.get_logger(), request) @@ -117,3 +218,196 @@ def reidentify_text(self, request: ReidentifyTextRequest) -> ReidentifyTextRespo except Exception as e: log_error_log(SkyflowMessages.ErrorLogs.REIDENTIFY_TEXT_REQUEST_REJECTED.value, self.__vault_client.get_logger()) handle_exception(e, self.__vault_client.get_logger()) + + def deidentify_file(self, request: DeidentifyFileRequest): + log_info(SkyflowMessages.Info.DETECT_FILE_TRIGGERED.value, self.__vault_client.get_logger()) + validate_deidentify_file_request(self.__vault_client.get_logger(), request) + self.__initialize() + files_api = self.__vault_client.get_detect_file_api().with_raw_response + file_obj = request.file + file_name = getattr(file_obj, 'name', None) + file_extension = self._get_file_extension(file_name) if file_name else None + file_content = file_obj.read() + + base64_string = base64.b64encode(file_content).decode('utf-8') + + try: + if file_extension == 'txt': + req_file = DeidentifyTextRequestFile(base_64=base64_string, data_format="txt") + api_call = files_api.deidentify_text + api_kwargs = { + 'vault_id': self.__vault_client.get_vault_id(), + 'file': req_file, + 'entity_types': request.entities, + 'token_type': self.__get_token_format(request), + 'allow_regex': request.allow_regex_list, + 'restrict_regex': request.restrict_regex_list, + 'transformations': self.__get_transformations(request), + 'request_options': self.__get_headers() + } + + elif file_extension in ['mp3', 'wav']: + req_file = DeidentifyAudioRequestFile(base_64=base64_string, data_format=file_extension) + api_call = files_api.deidentify_audio + api_kwargs = { + 'vault_id': self.__vault_client.get_vault_id(), + 'file': req_file, + 'entity_types': request.entities, + 'token_type': self.__get_token_format(request), + 'allow_regex': request.allow_regex_list, + 'restrict_regex': request.restrict_regex_list, + 'transformations': self.__get_transformations(request), + 'output_transcription': getattr(request, 'output_transcription', None), + 'output_processed_audio': getattr(request, 'output_processed_audio', None), + 'bleep_gain': getattr(request, 'bleep', None).gain if getattr(request, 'bleep', None) is not None else None, + 'bleep_frequency': getattr(request, 'bleep', None).frequency if getattr(request, 'bleep', None) is not None else None, + 'bleep_start_padding': getattr(request, 'bleep', None).start_padding if getattr(request, 'bleep', None) is not None else None, + 'bleep_stop_padding': getattr(request, 'bleep', None).stop_padding if getattr(request, 'bleep', None) is not None else None, + 'request_options': self.__get_headers() + } + + elif file_extension == 'pdf': + req_file = DeidentifyPdfRequestFile(base_64=base64_string) + api_call = files_api.deidentify_pdf + api_kwargs = { + 'vault_id': self.__vault_client.get_vault_id(), + 'file': req_file, + 'entity_types': request.entities, + 'token_type': self.__get_token_format(request), + 'allow_regex': request.allow_regex_list, + 'restrict_regex': request.restrict_regex_list, + 'max_resolution': getattr(request, 'max_resolution', None), + 'density': getattr(request, 'pixel_density', None), + 'request_options': self.__get_headers() + } + + elif file_extension in ['jpeg', 'jpg', 'png', 'bmp', 'tif', 'tiff']: + req_file = DeidentifyImageRequestFile(base_64=base64_string, data_format=file_extension) + api_call = files_api.deidentify_image + api_kwargs = { + 'vault_id': self.__vault_client.get_vault_id(), + 'file': req_file, + 'entity_types': request.entities, + 'token_type': self.__get_token_format(request), + 'allow_regex': request.allow_regex_list, + 'restrict_regex': request.restrict_regex_list, + 'masking_method': getattr(request, 'masking_method', None), + 'output_ocr_text': getattr(request, 'output_ocr_text', None), + 'output_processed_image': getattr(request, 'output_processed_image', None), + 'request_options': self.__get_headers() + } + + elif file_extension in ['ppt', 'pptx']: + req_file = DeidentifyPresentationRequestFile(base_64=base64_string, data_format=file_extension) + api_call = files_api.deidentify_presentation + api_kwargs = { + 'vault_id': self.__vault_client.get_vault_id(), + 'file': req_file, + 'entity_types': request.entities, + 'token_type': self.__get_token_format(request), + 'allow_regex': request.allow_regex_list, + 'restrict_regex': request.restrict_regex_list, + 'request_options': self.__get_headers() + } + + elif file_extension in ['csv', 'xls', 'xlsx']: + req_file = DeidentifySpreadsheetRequestFile(base_64=base64_string, data_format=file_extension) + api_call = files_api.deidentify_spreadsheet + api_kwargs = { + 'vault_id': self.__vault_client.get_vault_id(), + 'file': req_file, + 'entity_types': request.entities, + 'token_type': self.__get_token_format(request), + 'allow_regex': request.allow_regex_list, + 'restrict_regex': request.restrict_regex_list, + 'transformations': self.__get_transformations(request), + 'request_options': self.__get_headers() + } + + elif file_extension in ['doc', 'docx']: + req_file = DeidentifyDocumentRequestFile(base_64=base64_string, data_format=file_extension) + api_call = files_api.deidentify_document + api_kwargs = { + 'vault_id': self.__vault_client.get_vault_id(), + 'file': req_file, + 'entity_types': request.entities, + 'token_type': self.__get_token_format(request), + 'allow_regex': request.allow_regex_list, + 'restrict_regex': request.restrict_regex_list, + 'request_options': self.__get_headers() + } + + elif file_extension in ['json', 'xml']: + from skyflow.generated.rest.files.types.deidentify_structured_text_request_file import \ + DeidentifyStructuredTextRequestFile + req_file = DeidentifyStructuredTextRequestFile(base_64=base64_string, data_format=file_extension) + api_call = files_api.deidentify_structured_text + api_kwargs = { + 'vault_id': self.__vault_client.get_vault_id(), + 'file': req_file, + 'entity_types': request.entities, + 'token_type': self.__get_token_format(request), + 'allow_regex': request.allow_regex_list, + 'restrict_regex': request.restrict_regex_list, + 'transformations': self.__get_transformations(request), + 'request_options': self.__get_headers() + } + + else: + req_file = DeidentifyFileRequestFile(base_64=base64_string, data_format=file_extension) + api_call = files_api.deidentify_file + api_kwargs = { + 'vault_id': self.__vault_client.get_vault_id(), + 'file': req_file, + 'entity_types': request.entities, + 'token_type': self.__get_token_format(request), + 'allow_regex': request.allow_regex_list, + 'restrict_regex': request.restrict_regex_list, + 'transformations': self.__get_transformations(request), + 'request_options': self.__get_headers() + } + + log_info(SkyflowMessages.Info.DETECT_FILE_REQUEST_RESOLVED.value, self.__vault_client.get_logger()) + api_response = api_call(**api_kwargs) + + run_id = getattr(api_response.data, 'run_id', None) + + processed_response = self.__poll_for_processed_file(run_id, request.wait_time) + parsed_response = self.__parse_deidentify_file_response(processed_response, run_id) + if request.output_directory and processed_response.status == 'SUCCESS': + file_name_only = 'processed-'+os.path.basename(file_name) + output_file_path = f"{request.output_directory}/{file_name_only}" + with open(output_file_path, 'wb') as output_file: + output_file.write(base64.b64decode(parsed_response.file)) + log_info(SkyflowMessages.Info.DETECT_FILE_SUCCESS.value, self.__vault_client.get_logger()) + return parsed_response + + except Exception as e: + log_error_log(SkyflowMessages.ErrorLogs.DETECT_FILE_REQUEST_REJECTED.value, + self.__vault_client.get_logger()) + handle_exception(e, self.__vault_client.get_logger()) + + def get_detect_run(self, request: GetDetectRunRequest): + log_info(SkyflowMessages.Info.VALIDATING_GET_DETECT_RUN_INPUT.value, self.__vault_client.get_logger()) + validate_get_detect_run_request(self.__vault_client.get_logger(), request) + log_info(SkyflowMessages.Info.DEIDENTIFY_TEXT_REQUEST_RESOLVED.value, self.__vault_client.get_logger()) + self.__initialize() + + files_api = self.__vault_client.get_detect_file_api().with_raw_response + run_id = request.run_id + try: + response = files_api.get_run( + run_id, + vault_id=self.__vault_client.get_vault_id(), + request_options=self.__get_headers() + ) + if response.data.status == 'IN_PROGRESS': + parsed_response = self.__parse_deidentify_file_response(DeidentifyFileResponse(run_id=run_id, status='IN_PROGRESS')) + else: + parsed_response = self.__parse_deidentify_file_response(response.data, run_id, response.data.status) + return parsed_response + except Exception as e: + log_error_log(SkyflowMessages.ErrorLogs.DETECT_FILE_REQUEST_REJECTED.value, + self.__vault_client.get_logger()) + handle_exception(e, self.__vault_client.get_logger()) + diff --git a/skyflow/vault/detect/__init__.py b/skyflow/vault/detect/__init__.py index c9a12b7c..e385a1f2 100644 --- a/skyflow/vault/detect/__init__.py +++ b/skyflow/vault/detect/__init__.py @@ -6,4 +6,8 @@ from ._reidentify_text_response import ReidentifyTextResponse from ._text_index import TextIndex from ._token_format import TokenFormat -from ._transformations import Transformations \ No newline at end of file +from ._transformations import Transformations +from ._deidentify_file_request import DeidentifyFileRequest +from ._audio_bleep import Bleep +from ._deidentify_file_response import DeidentifyFileResponse +from ._get_detect_run_request import GetDetectRunRequest \ No newline at end of file diff --git a/skyflow/vault/detect/_audio_bleep.py b/skyflow/vault/detect/_audio_bleep.py new file mode 100644 index 00000000..745b7d46 --- /dev/null +++ b/skyflow/vault/detect/_audio_bleep.py @@ -0,0 +1,14 @@ +from typing import Optional + +class Bleep: + def __init__( + self, + gain: Optional[float] = None, + frequency: Optional[float] = None, + start_padding: Optional[float] = None, + stop_padding: Optional[float] = None + ): + self.gain = gain + self.frequency = frequency + self.start_padding = start_padding + self.stop_padding = stop_padding \ No newline at end of file diff --git a/skyflow/vault/detect/_deidentify_file_request.py b/skyflow/vault/detect/_deidentify_file_request.py new file mode 100644 index 00000000..a429f5d5 --- /dev/null +++ b/skyflow/vault/detect/_deidentify_file_request.py @@ -0,0 +1,42 @@ +from typing import List, Optional, Union +from skyflow.utils.enums import DetectEntities +from skyflow.vault.detect import TokenFormat, Transformations +from skyflow.vault.detect._audio_bleep import Bleep +from skyflow.utils.enums import MaskingMethod, DetectOutputTranscriptions + +class DeidentifyFileRequest: + def __init__( + self, + file = None, + entities: Optional[List[DetectEntities]] = None, + allow_regex_list: Optional[List[str]] = None, + restrict_regex_list: Optional[List[str]] = None, + token_format: Optional[TokenFormat] = None, + transformations: Optional[Transformations] = None, + output_processed_image: Optional[bool] = None, + output_ocr_text: Optional[bool] = None, + masking_method: Optional[MaskingMethod] = None, + pixel_density: Optional[Union[int, float]] = None, + max_resolution: Optional[Union[int, float]] = None, + output_processed_audio: Optional[bool] = None, + output_transcription: Optional[DetectOutputTranscriptions] = None, + bleep: Optional[Bleep] = None, + output_directory: Optional[str] = None, + wait_time: Optional[Union[int, float]] = None + ): + self.file: object = file + self.entities: Optional[List[DetectEntities]] = entities + self.allow_regex_list: Optional[List[str]] = allow_regex_list + self.restrict_regex_list: Optional[List[str]] = restrict_regex_list + self.token_format: Optional[TokenFormat] = token_format + self.transformations: Optional[Transformations] = transformations + self.output_processed_image: Optional[bool] = output_processed_image + self.output_ocr_text: Optional[bool] = output_ocr_text + self.masking_method: Optional[MaskingMethod] = masking_method + self.pixel_density: Optional[Union[int, float]] = pixel_density + self.max_resolution: Optional[Union[int, float]] = max_resolution + self.output_processed_audio: Optional[bool] = output_processed_audio + self.output_transcription: Optional[DetectOutputTranscriptions] = output_transcription + self.bleep: Optional[Bleep] = bleep + self.output_directory: Optional[str] = output_directory + self.wait_time: Optional[Union[int, float]] = wait_time \ No newline at end of file diff --git a/skyflow/vault/detect/_deidentify_file_response.py b/skyflow/vault/detect/_deidentify_file_response.py new file mode 100644 index 00000000..f386080d --- /dev/null +++ b/skyflow/vault/detect/_deidentify_file_response.py @@ -0,0 +1,44 @@ +class DeidentifyFileResponse: + def __init__( + self, + file: str = None, + type: str = None, + extension: str = None, + word_count: int = None, + char_count: int = None, + size_in_kb: float = None, + duration_in_seconds: float = None, + page_count: int = None, + slide_count: int = None, + entities: list = None, # list of dicts with keys 'file' and 'extension' + run_id: str = None, + status: str = None, + errors: list = [], + ): + self.file = file + self.type = type + self.extension = extension + self.word_count = word_count + self.char_count = char_count + self.size_in_kb = size_in_kb + self.duration_in_seconds = duration_in_seconds + self.page_count = page_count + self.slide_count = slide_count + self.entities = entities if entities is not None else [] + self.run_id = run_id + self.status = status + self.errors = errors + + def __repr__(self): + return ( + f"DeidentifyFileResponse(" + f"file={self.file!r}, type={self.type!r}, extension={self.extension!r}, " + f"word_count={self.word_count!r}, char_count={self.char_count!r}, " + f"size_in_kb={self.size_in_kb!r}, duration_in_seconds={self.duration_in_seconds!r}, " + f"page_count={self.page_count!r}, slide_count={self.slide_count!r}, " + f"entities={self.entities!r}, run_id={self.run_id!r}, status={self.status!r})," + f"errors={self.errors!r})" + ) + + def __str__(self): + return self.__repr__() \ No newline at end of file diff --git a/skyflow/vault/detect/_get_detect_run_request.py b/skyflow/vault/detect/_get_detect_run_request.py new file mode 100644 index 00000000..14426458 --- /dev/null +++ b/skyflow/vault/detect/_get_detect_run_request.py @@ -0,0 +1,6 @@ +class GetDetectRunRequest: + def __init__( + self, + run_id: str, + ): + self.run_id: str = run_id \ No newline at end of file diff --git a/tests/utils/test__utils.py b/tests/utils/test__utils.py index 09f70bdb..6324d9a7 100644 --- a/tests/utils/test__utils.py +++ b/tests/utils/test__utils.py @@ -7,12 +7,13 @@ from requests import PreparedRequest from requests.models import HTTPError from skyflow.error import SkyflowError +from skyflow.generated.rest import ErrorResponse from skyflow.utils import get_credentials, SkyflowMessages, get_vault_url, construct_invoke_connection_request, \ parse_insert_response, parse_update_record_response, parse_delete_response, parse_get_response, \ parse_detokenize_response, parse_tokenize_response, parse_query_response, parse_invoke_connection_response, \ handle_exception, validate_api_key, encode_column_values, parse_deidentify_text_response, \ parse_reidentify_text_response, convert_detected_entity_to_entity_info -from skyflow.utils._utils import parse_path_params, to_lowercase_keys, get_metrics +from skyflow.utils._utils import parse_path_params, to_lowercase_keys, get_metrics, handle_json_error from skyflow.utils.enums import EnvUrls, Env, ContentType from skyflow.vault.connection import InvokeConnectionResponse from skyflow.vault.data import InsertResponse, DeleteResponse, GetResponse, QueryResponse @@ -67,6 +68,65 @@ def test_get_vault_url_with_invalid_env(self): url = get_vault_url(valid_cluster_id, valid_env, valid_vault_id) self.assertEqual(context.exception.message, SkyflowMessages.Error.INVALID_ENV.value.format(valid_vault_id)) + @patch("skyflow.utils._utils.log_and_reject_error") + def test_handle_json_error_with_dict_data(self, mock_log_and_reject_error): + """Test handling JSON error when data is already a dict.""" + error_dict = { + "error": { + "message": "Dict error message", + "http_code": 400, + "http_status": "Bad Request", + "grpc_code": 3, + "details": ["detail1"] + } + } + + mock_error = Mock() + mock_logger = Mock() + request_id = "test-request-id" + + handle_json_error(mock_error, error_dict, request_id, mock_logger) + + mock_log_and_reject_error.assert_called_once_with( + "Dict error message", + 400, + request_id, + "Bad Request", + 3, + ["detail1"], + logger=mock_logger + ) + + @patch("skyflow.utils._utils.log_and_reject_error") + def test_handle_json_error_with_error_response_object(self, mock_log_and_reject_error): + """Test handling JSON error when data is an ErrorResponse object.""" + mock_error_response = Mock(spec=ErrorResponse) + mock_error_response.dict.return_value = { + "error": { + "message": "ErrorResponse message", + "http_code": 403, + "http_status": "Forbidden", + "grpc_code": 7, + "details": ["detail2"] + } + } + + mock_error = Mock() + mock_logger = Mock() + request_id = "test-request-id-2" + + handle_json_error(mock_error, mock_error_response, request_id, mock_logger) + + mock_log_and_reject_error.assert_called_once_with( + "ErrorResponse message", + 403, + request_id, + "Forbidden", + 7, + ["detail2"], + logger=mock_logger + ) + def test_parse_path_params(self): url = "https://example.com/{param1}/{param2}" path_params = {"param1": "value1", "param2": "value2"} diff --git a/tests/vault/controller/test__detect.py b/tests/vault/controller/test__detect.py index 84953835..17f138ad 100644 --- a/tests/vault/controller/test__detect.py +++ b/tests/vault/controller/test__detect.py @@ -1,9 +1,12 @@ import unittest -from unittest.mock import Mock, patch +from unittest.mock import Mock, patch, MagicMock +import base64 +import os from skyflow.error import SkyflowError +from skyflow.utils import SkyflowMessages from skyflow.vault.controller import Detect from skyflow.vault.detect import DeidentifyTextRequest, ReidentifyTextRequest, \ - TokenFormat, DateTransformation, Transformations + TokenFormat, DateTransformation, Transformations, DeidentifyFileRequest, GetDetectRunRequest, DeidentifyFileResponse from skyflow.utils.enums import DetectEntities, TokenType VAULT_ID = "test_vault_id" @@ -113,6 +116,345 @@ def test_reidentify_text_handles_generic_error(self, mock_validate): detect_api.reidentify_string.assert_called_once() + @patch("skyflow.vault.controller._detect.validate_deidentify_file_request") + @patch("skyflow.vault.controller._detect.base64") + @patch("skyflow.vault.controller._detect.os.path.basename") + @patch("skyflow.vault.controller._detect.open", create=True) + def test_deidentify_file_txt_success(self, mock_open, mock_basename, mock_base64, mock_validate): + file_content = b"test content" + file_obj = Mock() + file_obj.read.return_value = file_content + file_obj.name = "/tmp/test.txt" + mock_basename.return_value = "test.txt" + mock_base64.b64encode.return_value = b"dGVzdCBjb250ZW50" + req = DeidentifyFileRequest(file=file_obj) + req.entities = [] + req.token_format = Mock(default="default", entity_unique_counter=[], entity_only=[]) + req.allow_regex_list = [] + req.restrict_regex_list = [] + req.transformations = None + req.output_directory = "/tmp" + files_api = Mock() + files_api.with_raw_response = files_api + files_api.deidentify_text = Mock() + self.vault_client.get_detect_file_api.return_value = files_api + api_response = Mock() + api_response.data = Mock(run_id="runid123") + files_api.deidentify_text.return_value = api_response -# if __name__ == '__main__': -# unittest.main() + processed_response = Mock() + processed_response.status = "SUCCESS" + processed_response.output = [] + processed_response.word_character_count = Mock(word_count=1, character_count=1) + with patch.object(self.detect, "_Detect__poll_for_processed_file", + return_value=processed_response) as mock_poll, \ + patch.object(self.detect, "_Detect__parse_deidentify_file_response", + return_value=DeidentifyFileResponse(file="dGVzdCBjb250ZW50", type="txt", extension="txt", + word_count=1, char_count=1, size_in_kb=1, + duration_in_seconds=None, page_count=None, + slide_count=None, entities=[], run_id="runid123", + status="SUCCESS", errors=[])) as mock_parse: + result = self.detect.deidentify_file(req) + mock_validate.assert_called_once() + files_api.deidentify_text.assert_called_once() + mock_poll.assert_called_once() + mock_parse.assert_called_once() + self.assertIsInstance(result, DeidentifyFileResponse) + self.assertEqual(result.status, "SUCCESS") + + @patch("skyflow.vault.controller._detect.validate_deidentify_file_request") + @patch("skyflow.vault.controller._detect.base64") + def test_deidentify_file_audio_success(self, mock_base64, mock_validate): + file_content = b"audio bytes" + file_obj = Mock() + file_obj.read.return_value = file_content + file_obj.name = "audio.mp3" + mock_base64.b64encode.return_value = b"YXVkaW8gYnl0ZXM=" + req = DeidentifyFileRequest(file=file_obj) + req.entities = [] + req.token_format = Mock(default="default", entity_unique_counter=[], entity_only=[]) + req.allow_regex_list = [] + req.restrict_regex_list = [] + req.transformations = None + req.output_directory = None + files_api = Mock() + files_api.with_raw_response = files_api + files_api.deidentify_audio = Mock() + self.vault_client.get_detect_file_api.return_value = files_api + api_response = Mock() + api_response.data = Mock(run_id="runid456") + files_api.deidentify_audio.return_value = api_response + + processed_response = Mock() + processed_response.status = "SUCCESS" + processed_response.output = [] + processed_response.word_character_count = Mock(word_count=1, character_count=1) + with patch.object(self.detect, "_Detect__poll_for_processed_file", + return_value=processed_response) as mock_poll, \ + patch.object(self.detect, "_Detect__parse_deidentify_file_response", + return_value=DeidentifyFileResponse(file="YXVkaW8gYnl0ZXM=", type="mp3", extension="mp3", + word_count=1, char_count=1, size_in_kb=1, + duration_in_seconds=1, page_count=None, + slide_count=None, entities=[], run_id="runid456", + status="SUCCESS", errors=[])) as mock_parse: + result = self.detect.deidentify_file(req) + mock_validate.assert_called_once() + files_api.deidentify_audio.assert_called_once() + mock_poll.assert_called_once() + mock_parse.assert_called_once() + self.assertIsInstance(result, DeidentifyFileResponse) + self.assertEqual(result.status, "SUCCESS") + + @patch("skyflow.vault.controller._detect.validate_deidentify_file_request") + def test_deidentify_file_exception(self, mock_validate): + req = DeidentifyFileRequest(file=Mock()) + req.entities = [] + req.token_format = Mock(default="default", entity_unique_counter=[], entity_only=[]) + req.allow_regex_list = [] + req.restrict_regex_list = [] + req.transformations = None + req.output_directory = None + files_api = Mock() + files_api.with_raw_response = files_api + files_api.deidentify_text.side_effect = Exception("API Error") + self.vault_client.get_detect_file_api.return_value = files_api + with self.assertRaises(Exception): + self.detect.deidentify_file(req) + + @patch("skyflow.vault.controller._detect.validate_get_detect_run_request") + def test_get_detect_run_success(self, mock_validate): + req = GetDetectRunRequest(run_id="runid789") + files_api = Mock() + files_api.with_raw_response = files_api + files_api.get_run = Mock() + self.vault_client.get_detect_file_api.return_value = files_api + response = Mock() + response.status = "SUCCESS" + response.output = [] + response.word_character_count = Mock(word_count=1, character_count=1) + files_api.get_run.return_value = response + with patch.object(self.detect, "_Detect__parse_deidentify_file_response", + return_value=DeidentifyFileResponse(file="file", type="txt", extension="txt", word_count=1, + char_count=1, size_in_kb=1, duration_in_seconds=None, + page_count=None, slide_count=None, entities=[], + run_id="runid789", status="SUCCESS", + errors=[])) as mock_parse: + result = self.detect.get_detect_run(req) + mock_validate.assert_called_once() + files_api.get_run.assert_called_once() + mock_parse.assert_called_once() + self.assertIsInstance(result, DeidentifyFileResponse) + self.assertEqual(result.status, "SUCCESS") + + @patch("skyflow.vault.controller._detect.validate_get_detect_run_request") + def test_get_detect_run_exception(self, mock_validate): + req = GetDetectRunRequest(run_id="runid789") + files_api = Mock() + files_api.with_raw_response = files_api + files_api.get_run.side_effect = Exception("API Error") + self.vault_client.get_detect_file_api.return_value = files_api + with self.assertRaises(Exception): + self.detect.get_detect_run(req) + + @patch("skyflow.vault.controller._detect.validate_deidentify_file_request") + @patch("skyflow.vault.controller._detect.base64") + @patch("skyflow.vault.controller._detect.os.path.basename") + @patch("skyflow.vault.controller._detect.open", create=True) + @patch("skyflow.vault.controller._detect.time.sleep", return_value=None) + def test_deidentify_file_all_branches(self, mock_sleep, mock_open, mock_basename, mock_base64, mock_validate): + # Helper to run a branch + def run_branch(file_name, file_extension, api_call_attr, req_file_class): + file_content = b"test content" + file_obj = Mock() + file_obj.read.return_value = file_content + file_obj.name = file_name + mock_basename.return_value = os.path.basename(file_name) + mock_base64.b64encode.return_value = b"dGVzdCBjb250ZW50" + req = DeidentifyFileRequest(file=file_obj) + req.entities = [] + req.token_format = Mock(default="default", entity_unique_counter=[], entity_only=[]) + req.allow_regex_list = [] + req.restrict_regex_list = [] + req.transformations = None + req.output_directory = "/tmp" + files_api = Mock() + files_api.with_raw_response = files_api + setattr(files_api, api_call_attr, Mock()) + self.vault_client.get_detect_file_api.return_value = files_api + api_response = Mock() + api_response.data = Mock(run_id="runid123") + getattr(files_api, api_call_attr).return_value = api_response + + # Patch get_run for polling + poll_response = Mock() + poll_response.status = "SUCCESS" + poll_response.output = [ + {"processedFile": "dGVzdCBjb250ZW50", "processedFileType": file_extension, + "processedFileExtension": file_extension} + ] + poll_response.word_character_count = Mock(word_count=1, character_count=1) + poll_response.size = 1 + poll_response.duration = 1 + poll_response.pages = 1 + poll_response.slides = 1 + poll_response.message = "" + poll_response.run_id = "runid123" + files_api.get_run.return_value = poll_response + + # Actually run the method (no patching of __poll_for_processed_file or __parse_deidentify_file_response) + result = self.detect.deidentify_file(req) + self.assertIsInstance(result, DeidentifyFileResponse) + self.assertEqual(result.status, "SUCCESS") + self.assertEqual(result.file, "dGVzdCBjb250ZW50") + self.assertEqual(result.type, file_extension) + self.assertEqual(result.extension, file_extension) + + # Test all branches + run_branch("test.pdf", "pdf", "deidentify_pdf", "DeidentifyPdfRequestFile") + run_branch("test.jpg", "jpg", "deidentify_image", "DeidentifyImageRequestFile") + run_branch("test.pptx", "pptx", "deidentify_presentation", "DeidentifyPresentationRequestFile") + run_branch("test.csv", "csv", "deidentify_spreadsheet", "DeidentifySpreadsheetRequestFile") + run_branch("test.docx", "docx", "deidentify_document", "DeidentifyDocumentRequestFile") + run_branch("test.json", "json", "deidentify_structured_text", "DeidentifyStructuredTextRequestFile") + run_branch("test.xml", "xml", "deidentify_structured_text", "DeidentifyStructuredTextRequestFile") + # Test else branch (unknown extension) + run_branch("test.unknown", "unknown", "deidentify_file", "DeidentifyFileRequestFile") + + @patch("skyflow.vault.controller._detect.validate_deidentify_file_request") + @patch("skyflow.vault.controller._detect.base64") + def test_deidentify_file_exception(self, mock_base64, mock_validate): + file_obj = Mock() + file_obj.read.side_effect = Exception("Read error") + file_obj.name = "test.txt" + req = DeidentifyFileRequest(file=file_obj) + req.entities = [] + req.token_format = Mock(default="default", entity_unique_counter=[], entity_only=[]) + req.allow_regex_list = [] + req.restrict_regex_list = [] + req.transformations = None + req.output_directory = None + with self.assertRaises(Exception): + self.detect.deidentify_file(req) + + @patch("skyflow.vault.controller._detect.time.sleep", return_value=None) + def test_poll_for_processed_file_success(self, mock_sleep): + files_api = Mock() + self.vault_client.get_detect_file_api.return_value = files_api + # First call returns IN_PROGRESS, second call returns SUCCESS + in_progress = Mock() + in_progress.status = "IN_PROGRESS" + in_progress.message = "" + success = Mock() + success.status = "SUCCESS" + files_api.get_run.side_effect = [in_progress, success] + result = self.detect._Detect__poll_for_processed_file("runid123", max_wait_time=2) + self.assertEqual(result.status, "SUCCESS") + + @patch("skyflow.vault.controller._detect.time.sleep", return_value=None) + def test_poll_for_processed_file_failed(self, mock_sleep): + files_api = Mock() + self.vault_client.get_detect_file_api.return_value = files_api + failed = Mock() + failed.status = "FAILED" + failed.message = "fail" + files_api.get_run.return_value = failed + with self.assertRaises(SkyflowError): + self.detect._Detect__poll_for_processed_file("runid123", max_wait_time=1) + + @patch("skyflow.vault.controller._detect.time.sleep", return_value=None) + def test_poll_for_processed_file_unknown(self, mock_sleep): + files_api = Mock() + self.vault_client.get_detect_file_api.return_value = files_api + unknown = Mock() + unknown.status = "UNKNOWN" + unknown.message = "fail" + files_api.get_run.return_value = unknown + with self.assertRaises(SkyflowError): + self.detect._Detect__poll_for_processed_file("runid123", max_wait_time=1) + + def test_parse_deidentify_file_response_dict_and_obj(self): + # Dict input + data = { + "output": [ + {"processedFile": "abc", "processedFileType": "pdf", "processedFileExtension": "pdf"}, + {"processedFile": "def", "processedFileType": "entities", "processedFileExtension": "json"} + ], + "word_character_count": {"word_count": 5, "character_count": 10}, + "size": 1, + "duration": 2, + "pages": 3, + "slides": 4, + "run_id": "runid", + "status": "SUCCESS" + } + result = self.detect._Detect__parse_deidentify_file_response(data, "runid", "SUCCESS") + self.assertIsInstance(result, DeidentifyFileResponse) + + # Object input + class DummyWordChar: + word_count = 7 + character_count = 14 + + class DummyData: + output = [ + type("O", (), + {"processed_file": "abc", "processed_file_type": "pdf", "processed_file_extension": "pdf"})(), + type("O", (), + {"processed_file": "def", "processed_file_type": "entities", "processed_file_extension": "json"})() + ] + word_character_count = DummyWordChar() + size = 1 + duration = 2 + pages = 3 + slides = 4 + run_id = "runid" + status = "SUCCESS" + + obj_data = DummyData() + result = self.detect._Detect__parse_deidentify_file_response(obj_data, "runid", "SUCCESS") + self.assertIsInstance(result, DeidentifyFileResponse) + def test_get_token_format_missing_attribute(self): + """Test __get_token_format when token_format attribute is missing""" + class DummyRequest: + pass + request = DummyRequest() + result = self.detect._Detect__get_token_format(request) + self.assertIsNone(result) + + def test_get_transformations_missing_shift_dates(self): + """Test __get_transformations when shift_dates is None""" + class DummyTransformations: + shift_dates = None + class DummyRequest: + transformations = DummyTransformations() + request = DummyRequest() + result = self.detect._Detect__get_transformations(request) + self.assertIsNone(result) + + @patch("skyflow.vault.controller._detect.validate_get_detect_run_request") + def test_get_detect_run_in_progress_status(self, mock_validate): + """Test get_detect_run when status is IN_PROGRESS""" + # Setup + run_id = "test_run_id" + req = GetDetectRunRequest(run_id=run_id) + + # Mock API response + files_api = Mock() + files_api.with_raw_response = files_api + mock_response = Mock() + mock_response.data = Mock() + mock_response.data.status = 'IN_PROGRESS' + files_api.get_run.return_value = mock_response + + self.vault_client.get_detect_file_api.return_value = files_api + + # Execute + with patch.object(self.detect, "_Detect__parse_deidentify_file_response") as mock_parse: + result = self.detect.get_detect_run(req) + + # Verify IN_PROGRESS handling + mock_parse.assert_called_once() + args = mock_parse.call_args[0][0] + self.assertIsInstance(args, DeidentifyFileResponse) + self.assertEqual(args.status, 'IN_PROGRESS') + self.assertEqual(args.run_id, run_id)