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/README.md b/README.md index af1e79f4..738d0cc4 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ The Skyflow Python SDK is designed to help with integrating Skyflow into a Pytho - [Authenticate](#authenticate) - [Initialize the client](#initialize-the-client) - [Insert data into the vault](#insert-data-into-the-vault) -- [Vault](#vault-apis) +- [Vault](#vault) - [Insert data into the vault](#insert-data-into-the-vault) - [Detokenize](#detokenize) - [Tokenize](#tokenize) @@ -30,8 +30,12 @@ The Skyflow Python SDK is designed to help with integrating Skyflow into a Pytho - [Redaction types](#redaction-types) - [Update](#update) - [Delete](#delete) - - [Invoke Connection](#invoke-connection) - [Query](#query) +- [Detect](#detect) + - [Deidentify Text](#deidentify-text) + - [Reidentify Text](#reidentify-text) + - [Deidentify File](#deidentify-file) + - [Get Detect Run](#get-detect-run) - [Connections](#connections) - [Invoke a connection](#invoke-a-connection) - [Authenticate with bearer tokens](#authenticate-with-bearer-tokens) @@ -39,6 +43,7 @@ The Skyflow Python SDK is designed to help with integrating Skyflow into a Pytho - [Generate bearer tokens with context](#generate-bearer-tokens-with-context) - [Generate scoped bearer tokens](#generate-scoped-bearer-tokens) - [Generate signed data tokens](#generate-signed-data-tokens) + - [Bearer token expiry edge case](#bearer-token-expiry-edge-case) - [Logging](#logging) - [Reporting a Vulnerability](#reporting-a-vulnerability) @@ -1668,6 +1673,479 @@ QueryResponse( ) ``` +## Detect +Skyflow Detect enables you to deidentify and reidentify sensitive data in text and files, supporting advanced privacy-preserving workflows. The Detect API supports the following operations: + +### Deidentify Text +To deidentify text, use the `deidentify_text` method. The `DeidentifyTextRequest` class creates a deidentify text request, which includes the text to be deidentified and options for controlling the deidentification process. + +#### Construct a Deidentify Text request + +```python +from skyflow.error import SkyflowError +from skyflow.utils.enums import DetectEntities, TokenType +from skyflow.vault.detect import DeidentifyTextRequest, TokenFormat, Transformations +""" +This example demonstrates how to deidentify text, along with corresponding DeidentifyTextRequest schema. +""" +try: + # Initialize Skyflow client + # Step 1: Create request with text to deidentify + request = DeidentifyTextRequest( + text="", + entities=[DetectEntities.SSN, DetectEntities.CREDIT_CARD], # Entities to detect + token_format = TokenFormat( # Specify the token format for deidentified entities + default=TokenType.VAULT_TOKEN, + ), + transformations=Transformations( # Specify custom transformations for entities + shift_dates={ + "max_days": 30, + "min_days": 10, + "entities": [DetectEntities.DOB] + } + ), + allow_regex_list=[""], # Optional regex patterns to allow + restrict_regex_list=[""] # Optional regex patterns to restrict + ) + + # Step 2: Call deidentify_text + deidentify_text_response = skyflow_client.detect('').deidentify_text(request) + # Replace with your actual Skyflow vault ID + + # Step 3: Print the deidentified text response + print('Response: ', deidentify_text_response) + + +except SkyflowError as error: + # Step 4: Handle any exceptions that may occur during the insert operation + print('Skyflow Specific Error: ', { + 'code': error.http_code, + 'message': error.message, + 'details': error.details + }) +except Exception as error: + print('Unexpected Error:', error) # Print the stack trace for debugging purposes +``` + +#### An example of Deidentify Text call + +```python +from skyflow.error import SkyflowError +from skyflow.utils.enums import DetectEntities, TokenType +from skyflow.vault.detect import DeidentifyTextRequest, TokenFormat, Transformations +""" + * Skyflow Text De-identification Example + * + * This example demonstrates how to: + * 1. Configure Skyflow client credentials + * 2. Set up vault configuration + * 3. Create a deidentify text request with all available options + * 4. Handle response and errors +""" +try: + # Initialize Skyflow Client + # Step 1: Create request with sample text containing sensitive data + request = DeidentifyTextRequest( + text="My SSN is 123-45-6789 and my card is 4111 1111 1111 1111.", + entities=[ + DetectEntities.SSN, + DetectEntities.CREDIT_CARD + ], + token_format = TokenFormat( # Specify the token format for deidentified entities + default=TokenType.VAULT_TOKEN, + ), + transformations=Transformations( # Specify custom transformations for entities + shift_dates={ + "max_days": 30, + "min_days": 30, + "entities": [DetectEntities.DOB] + } + ) + ) + + # Step 2: Call deidentify_text + deidentify_text_response = skyflow_client.detect('').deidentify_text(request) + # Replace with your actual Skyflow vault ID + + # Step 3: Print the deidentified text response + print('Response: ', deidentify_text_response) + +except SkyflowError as error: + # Step 4: Handle any exceptions that may occur during the insert operation + print('Skyflow Specific Error: ', { + 'code': error.http_code, + 'message': error.message, + 'details': error.details + }) +except Exception as error: + print('Unexpected Error:', error) # Print the stack trace for debugging purposes +``` + +Sample Response: +```python +DeidentifyTextResponse( + processed_text='My SSN is [SSN_VqLazzA] and my card is [CREDIT_CARD_54lAgtk].', + entities=[ + EntityInfo( + token='SSN_VqLazzA', + value='123-45-6789', + text_index=TextIndex(start=10, end=21), + processed_index=TextIndex(start=10, end=23), + entity='SSN', + scores={'SSN': 0.9383999705314636} + ), + EntityInfo( + token='CREDIT_CARD_54lAgtk', + value='4111 1111 1111 1111', + text_index=TextIndex(start=37, end=56), + processed_index=TextIndex(start=39, end=60), + entity='CREDIT_CARD', + scores={'CREDIT_CARD': 0.9050999879837036} + ) + ], + word_count=9, + char_count=57 +) +``` + +### Reidentify Text + +To reidentify text, use the `reidentify_text` method. The `ReidentifyTextRequest` class creates a reidentify text request, which includes the redacted or deidentified text to be reidentified. + +#### Construct a Reidentify Text request + +```python +from skyflow.error import SkyflowError +from skyflow.vault.detect import ReidentifyTextRequest, ReidentifyFormat +""" +This example demonstrates how to reidentify text, along with corresponding ReidentifyTextRequest schema. +""" +try: + # Initialize Skyflow client + # Step 1: Create request to reidentify + request = ReidentifyTextRequest( + text="", # Text containing tokens to reidentify + redacted_entities=[""], # Entities to show redacted + masked_entities=[""], # Entities to show masked + plain_text_entities=[""] # Entities to show as plain text + ) + + # Step 2: Call reidentify_text + reidentify_text_response = skyflow_client.detect('').reidentify_text(request) + # Replace with your actual Skyflow vault ID + + # Step 3: Print the reidentified text response + print('Response: ', reidentify_text_response) + +except SkyflowError as error: + # Step 4: Handle any exceptions that may occur during the insert operation + print('Skyflow Specific Error: ', { + 'code': error.http_code, + 'message': error.message, + 'details': error.details + }) +except Exception as error: + print('Unexpected Error:', error) # Print the stack trace for debugging purposes +``` + +#### An example for Reidentify Text call + +```python +from skyflow.error import SkyflowError +from skyflow.vault.detect import ReidentifyTextRequest, ReidentifyFormat +from skyflow.utils.enums import DetectEntities +""" + * Skyflow Text Re-identification Example + * + * This example demonstrates how to: + * 1. Configure credentials + * 2. Set up vault configuration + * 3. Create a reidentify text request + * 4. Use all available options for reidentification + * 5. Handle response and errors +""" +try: + # Initialize Skyflow Client + # Step 1: Create request with deidentified text + request = ReidentifyTextRequest( + text="My SSN is [SSN_VqLazzA] and my card is [CREDIT_CARD_54lAgtk].", + ) + + # Step 2: Call reidentify_text + reidentify_text_response = skyflow_client.detect('').reidentify_text(request) + # Replace with your actual Skyflow vault ID + + # Step 3: Print the reidentified text response + print('Response: ', reidentify_text_response) + +except SkyflowError as error: + # Step 4: Handle any exceptions that may occur during the insert operation + print('Skyflow Specific Error: ', { + 'code': error.http_code, + 'message': error.message, + 'details': error.details + }) +except Exception as error: + print('Unexpected Error:', error) # Print the stack trace for debugging purposes +``` + +Sample Response: +```python +ReidentifyTextResponse( + processed_text='My SSN is 123-45-6789 and my card is 4111 1111 1111 1111.' +) +``` + +### Deidentify File +To deidentify files, use the `deidentify_file` method. The `DeidentifyFileRequest` class creates a deidentify file request, which includes the file to be deidentified and various configuration options. + +#### Construct a Deidentify File request +```python +from skyflow.error import SkyflowError +from skyflow.utils.enums import DetectEntities, MaskingMethod, DetectOutputTranscriptions +from skyflow.vault.detect import DeidentifyFileRequest, TokenFormat, Transformations, Bleep +""" +This example demonstrates how to deidentify file, along with corresponding DeidentifyFileRequest schema. +""" +try: + # Initialize Skyflow client + # Step 1: Open file for deidentification + file = open('', 'rb') # Open the file in read-binary mode + # Step 2: Create deidentify file request + request = DeidentifyFileRequest( + file=file, # File object to deidentify + entities=[DetectEntities.SSN, DetectEntities.CREDIT_CARD], # Entities to detect + + # Token format configuration + token_format=TokenFormat( + default=True, + vault_token=[DetectEntities.SSN] + ), + + # Output configuration + output_directory='', # Output directory for saving the deidentified file + wait_time=15, # Max wait time in seconds (max 64) + + # Image-specific options + # output_processed_image=True, # Include processed image + # output_ocr_text=True, # Include OCR text + # masking_method=MaskingMethod.BLACKOUT, # Masking method + + # PDF-specific options + # pixel_density=1.5, # PDF processing density + # max_resolution=2000, # Max PDF resolution + + # Audio-specific options + # output_processed_audio=True, # Include processed audio + # output_transcription=DetectOutputTranscriptions.PLAINTEXT, # Transcription type + + # Audio bleep configuration + # bleep=Bleep( + # gain=5, # Loudness in dB + # frequency=1000, # Pitch in Hz + # start_padding=0.1, # Start padding in seconds + # stop_padding=0.2 # End padding in seconds + # ) + ) + + # Step 3: Call deidentify_file + deidentify_file_response = skyflow_client.detect('').deidentify_file(request) + # Replace with your actual Skyflow vault ID + + # Step 3: Print the reidentified text response + print('Response: ', deidentify_file_response) + +except SkyflowError as error: + # Step 4: Handle any exceptions that may occur during the insert operation + print('Skyflow Specific Error: ', { + 'code': error.http_code, + 'message': error.message, + 'details': error.details + }) +except Exception as error: + print('Unexpected Error:', error) # Print the stack trace for debugging purposes +``` + +#### An example for Deidentify File call + +```python +from skyflow.error import SkyflowError +from skyflow.utils.enums import DetectEntities, MaskingMethod, DetectOutputTranscriptions +from skyflow.vault.detect import DeidentifyFileRequest, TokenFormat, Bleep +""" + * Skyflow Deidentify File Example + * + * This sample demonstrates how to use all available options for deidentifying files. + * Supported file types: images (jpg, png, etc.), pdf, audio (mp3, wav), documents, + * spreadsheets, presentations, structured text. +""" +try: + # Initialize Skyflow client + # Step 1: Open file for deidentification + file = open('sensitive_document.txt', 'rb') # Open the file in read-binary mode + # Step 2: Create deidentify file request + request = DeidentifyFileRequest( + file=file, # File object to deidentify + entities=[ + DetectEntities.SSN, + DetectEntities.CREDIT_CARD + ], + # Token format configuration + token_format=TokenFormat( + default=True, + vault_token=[DetectEntities.SSN] + ), + output_directory="/tmp/processed", # Output directory for saving the deidentified file + wait_time=30, # Max wait time in seconds (max 64) + ) + + # Step 3: Call deidentify_file + deidentify_file_response = skyflow_client.detect('').deidentify_file(request) + # Replace with your actual Skyflow vault ID + + # Step 3: Print the reidentified text response + print('Response: ', deidentify_file_response) + +except SkyflowError as error: + # Step 4: Handle any exceptions that may occur during the insert operation + print('Skyflow Specific Error: ', { + 'code': error.http_code, + 'message': error.message, + 'details': error.details + }) +except Exception as error: + print('Unexpected Error:', error) # Print the stack trace for debugging purposes +``` + +Sample Response +```python +DeidentifyFileResponse( + file='TXkgY2FyZCBudW1iZXIgaXMgW0NSRURJVF9DQVJEXQpteSBzZWNvbmQ…', # Base64 encoded file content + type='redacted_file', + extension='txt', + word_count=19, + char_count=111, + size_in_kb=0.11, + duration_in_seconds=None, + page_count=None, + slide_count=None, + entities=[ + { + 'file': 'W3sicHJvY2Vzc2VleHQiOiJDUkVESVRfQ0FSRCIsInRleHQiOiIxMjM0NTY0Nzg5MDEyMzQ1NiIsImxvY2F0aW9uIjp7InN0dF9pZHgiOjE4LCJlbmRfaWR4IjozNSwic3R0X2lkeF9wcm9jZXNzZWR…', # Base64 encoded JSON string of entities + 'type': 'entities', + 'extension': 'json' + } + ], + run_id='83abcdef-2b61-4a83-a4e0-cbc71ffabffd', + status='SUCCESS', + errors=[] +) +``` + +### Get Detect Run +To retrieve the results of a previously started file deidentification operation, use the `get_detect_run` method. The `GetDetectRunRequest` class is initialized with the run_id returned from a prior `deidentify_file` call. + +#### Construct a Get Detect Run request + +```python +from skyflow.error import SkyflowError +from skyflow.vault.detect import GetDetectRunRequest + +""" +Example program to demonstrate get detect run using run id, along with corresponding GetDetectRunRequest schema. +""" + +try: + # Initialize Skyflow client + # Step 1: Create GetDetectRunRequest + request = GetDetectRunRequest( + run_id='' # Replace with runId from deidentify_file + ) + + # Step 2: Call get_detect_run + get_detect_run_response = skyflow_client.detect('').get_detect_run(request) + # Replace with your actual vault ID + + # Print the response from the get detect run operation + print('Response: ', get_detect_run_response) + +except SkyflowError as error: + # Step 3: Handle any exceptions that may occur during the insert operation + print('Skyflow Specific Error: ', { + 'code': error.http_code, + 'message': error.message, + 'details': error.details + }) +except Exception as error: + print('Unexpected Error:', error) # Print the stack trace for debugging purposes + +``` + +#### An example for Get Detect Run Call + +```python +from skyflow.error import SkyflowError +from skyflow.vault.detect import GetDetectRunRequest +""" + * Skyflow Get Detect Run Example + * + * This example demonstrates how to: + * 1. Configure credentials + * 2. Set up vault configuration + * 3. Create a get detect run request + * 4. Call getDetectRun to poll for file processing results + * 5. Handle response and errors +""" +try: + # Initialize Skyflow client + # Step 1: Create GetDetectRunRequest + request = GetDetectRunRequest( + run_id="48ec05ba-96ec-4641-a8e2-35e066afef95" + ) + + # Step 2: Call get_detect_run + get_detect_run_response = skyflow_client.detect('').get_detect_run(request) + # Replace with your actual vault ID + + # Print the response from the get detect run operation + print('Response: ', get_detect_run_response) + +except SkyflowError as error: + # Step 3: Handle any exceptions that may occur during the insert operation + print('Skyflow Specific Error: ', { + 'code': error.http_code, + 'message': error.message, + 'details': error.details + }) +except Exception as error: + print('Unexpected Error:', error) # Print the stack trace for debugging purposes +``` + +Sample Response +```python +DeidentifyFileResponse( + file='TXkgY2FyZCBudW1iZXIgaXMgW0NSRURJVF9DQVJEXQpteSBzZWNvbmQ…', # Base64 encoded file content + type='redacted_file', + extension='txt', + word_count=19, + char_count=111, + size_in_kb=0.11, + duration_in_seconds=None, + page_count=None, + slide_count=None, + entities=[ + { + 'file': 'W3sicHJvY2Vzc2VleHQiOiJDUkVESVRfQ0FSRCIsInRleHQiOiIxMjM0NTY0Nzg5MDEyMzQ1NiIsImxvY2F0aW9uIjp7InN0dF9pZHgiOjE4LCJlbmRfaWR4IjozNSwic3R0X2lkeF9wcm9jZXNzZWR…', # Base64 encoded JSON string of entities + 'type': 'entities', + 'extension': 'json' + } + ], + run_id='48ec05ba-96ec-4641-a8e2-35e066afef95', + status='SUCCESS', + errors=[] +) +``` + ### Connections Skyflow Connections is a gateway service that uses tokenization to securely send and receive data between your systems and first- or third-party services. The [connections](https://github.com/skyflowapi/skyflow-python/tree/v2/skyflow/vault/connection) module invokes both inbound and/or outbound connections. @@ -2142,6 +2620,130 @@ Notes: - The `time_to_live` (TTL) value should be specified in seconds. - By default, the TTL value is set to 60 seconds. +#### Bearer token expiry edge case +When you use bearer tokens for authentication and API requests in SDKs, there's the potential for a token to expire after the token is verified as valid but before the actual API call is made, causing the request to fail unexpectedly due to the token's expiration. An error from this edge case would look something like this: + +```txt +message: Authentication failed. Bearer token is expired. Use a valid bearer token. See https://docs.skyflow.com/api-authentication/ +``` + +If you encounter this kind of error, retry the request. During the retry, the SDK detects that the previous bearer token has expired and generates a new one for the current and subsequent requests. + +#### [Example](https://github.com/skyflowapi/skyflow-python/blob/v2/samples/service_account/bearer_token_expiry_example.py): +```python +import json +from skyflow.error import SkyflowError +from skyflow import Env +from skyflow import Skyflow, LogLevel +from skyflow.utils.enums import RedactionType +from skyflow.vault.tokens import DetokenizeRequest + +""" + * This example demonstrates how to configure and use the Skyflow SDK + * to detokenize sensitive data stored in a Skyflow vault. + * It includes setting up credentials, configuring the vault, and + * making a detokenization request. The code also implements a retry + * mechanism to handle unauthorized access errors (HTTP 401). +""" + + +def detokenize_data(skyflow_client, vault_id): + try: + # Creating a list of tokens to be detokenized + detokenize_data = [ + { + 'token': '', + 'redaction': RedactionType.REDACTED + }, + { + 'token': '', + 'redaction': RedactionType.MASKED + } + ] + + # Building a detokenization request + detokenize_request = DetokenizeRequest( + data=detokenize_data, + continue_on_error=False + ) + + # Sending the detokenization request and receiving the response + response = skyflow_client.vault(vault_id).detokenize(detokenize_request) + + # Printing the detokenized response + print('Detokenization successful:', response) + + except SkyflowError as error: + print("Skyflow error occurred:", error) + raise + + except Exception as error: + print("Unexpected error occurred:", error) + raise + + +def perform_detokenization(): + try: + # Setting up credentials for accessing the Skyflow vault + cred = { + 'clientID': '', + 'clientName': '', + 'tokenURI': '', + 'keyID': '', + 'privateKey': '', + } + + skyflow_credentials = { + 'credentials_string': json.dumps(cred) # Credentials string for authentication + } + + credentials = { + 'token': '' + } + + # Configuring the Skyflow vault with necessary details + primary_vault_config = { + 'vault_id': '', # Vault ID + 'cluster_id': '', # Cluster ID + 'env': Env.PROD, # Environment set to PROD + 'credentials': credentials # Setting credentials + } + + # Creating a Skyflow client instance with the configured vault + skyflow_client = ( + Skyflow.builder() + .add_vault_config(primary_vault_config) + .add_skyflow_credentials(skyflow_credentials) + .set_log_level(LogLevel.ERROR) # Setting log level to ERROR + .build() + ) + + # Attempting to detokenize data using the Skyflow client + try: + detokenize_data(skyflow_client, primary_vault_config.get('vault_id')) + except SkyflowError as err: + # Retry detokenization if the error is due to unauthorized access (HTTP 401) + if err.http_code == 401: + print("Unauthorized access detected. Retrying...") + detokenize_data(skyflow_client, primary_vault_config.get('vault_id')) + else: + # Rethrow the exception for other error codes + raise err + + except SkyflowError as error: + print('Skyflow Specific Error:', { + 'code': error.http_code, + 'message': error.message, + 'details': error.details + }) + except Exception as error: + print('Unexpected Error:', error) + + +# Invoke the function +perform_detokenization() +``` + ## Logging The SDK provides logging using python's inbuilt `logging` library. By default the logging level of the SDK is set to `LogLevel.ERROR`. This can be changed by using `set_log_level(log_level)` as shown below: diff --git a/samples/detect_api/deidentify_file.py b/samples/detect_api/deidentify_file.py new file mode 100644 index 00000000..ed13bfda --- /dev/null +++ b/samples/detect_api/deidentify_file.py @@ -0,0 +1,105 @@ +from skyflow.error import SkyflowError +from skyflow import Env, Skyflow, LogLevel +from skyflow.utils.enums import DetectEntities, MaskingMethod, DetectOutputTranscriptions +from skyflow.vault.detect import DeidentifyFileRequest, TokenFormat, Transformations, DateTransformation, Bleep + +""" + * Skyflow Deidentify File Example + * + * This sample demonstrates how to use all available options for deidentifying files. + * Supported file types: images (jpg, png, etc.), pdf, audio (mp3, wav), documents, + * spreadsheets, presentations, structured text. +""" + +def perform_file_deidentification(): + try: + # Step 1: Configure Credentials + credentials = { + 'path': '/path/to/credentials.json' # Path to credentials file + } + + # Step 2: Configure Vault + vault_config = { + 'vault_id': '', # Replace with your vault ID + 'cluster_id': '', # Replace with your cluster ID + 'env': Env.PROD, # Deployment environment + 'credentials': credentials + } + + # Step 3: Configure & Initialize Skyflow Client + skyflow_client = ( + Skyflow.builder() + .add_vault_config(vault_config) + .set_log_level(LogLevel.INFO) # Use LogLevel.ERROR in production + .build() + ) + + # Step 4: Create File Object + file_path = '' # Replace with your file path + file = open(file_path, 'rb') + # Step 5: Configure Deidentify File Request with all options + deidentify_request = DeidentifyFileRequest( + file=file, # File object to deidentify + entities=[DetectEntities.SSN, DetectEntities.CREDIT_CARD], # Entities to detect + allow_regex_list=[''], # Optional: Patterns to allow + restrict_regex_list=[''], # Optional: Patterns to restrict + + # Token format configuration + token_format=TokenFormat( + vault_token=[DetectEntities.SSN], # Use vault tokens for these entities + ), + + # Optional: Custom transformations + # transformations=Transformations( + # shift_dates=DateTransformation( + # max_days=30, + # min_days=10, + # entities=[DetectEntities.DOB] + # ) + # ), + + # Output configuration + output_directory='', # Where to save processed file + wait_time=15, # Max wait time in seconds (max 64) + + # Image-specific options + output_processed_image=True, # Include processed image in output + output_ocr_text=True, # Include OCR text in response + masking_method=MaskingMethod.BLACKOUT, # Masking method for images + + # PDF-specific options + pixel_density=15, # Pixel density for PDF processing + max_resolution=2000, # Max resolution for PDF + + # Audio-specific options + output_processed_audio=True, # Include processed audio + output_transcription=DetectOutputTranscriptions.PLAINTEXT_TRANSCRIPTION, # Transcription type + + # Audio bleep configuration + + # bleep=Bleep( + # gain=5, # Loudness in dB + # frequency=1000, # Pitch in Hz + # start_padding=0.1, # Padding at start (seconds) + # stop_padding=0.2 # Padding at end (seconds) + # ) + ) + + # Step 6: Call deidentifyFile API + response = skyflow_client.detect().deidentify_file(deidentify_request) + + # Handle Successful Response + print("\nDeidentify File Response:", response) + + except SkyflowError as error: + # Handle Skyflow-specific errors + print('\nSkyflow Error:', { + 'http_code': error.http_code, + 'grpc_code': error.grpc_code, + 'http_status': error.http_status, + 'message': error.message, + 'details': error.details + }) + except Exception as error: + # Handle unexpected errors + print('Unexpected Error:', error) diff --git a/samples/detect_api/deidentify_text.py b/samples/detect_api/deidentify_text.py new file mode 100644 index 00000000..c543b6f8 --- /dev/null +++ b/samples/detect_api/deidentify_text.py @@ -0,0 +1,82 @@ +from skyflow.error import SkyflowError +from skyflow import Env, Skyflow, LogLevel +from skyflow.utils.enums import DetectEntities +from skyflow.vault.detect import DeidentifyTextRequest, TokenFormat, Transformations, DateTransformation + +""" + * Skyflow Text De-identification Example + * + * This example demonstrates how to: + * 1. Configure Skyflow client credentials + * 2. Set up vault configuration + * 3. Create a deidentify text request with all available options + * 4. Handle response and errors +""" + +def perform_text_deidentification(): + try: + # Step 1: Configure Credentials + credentials = { + 'path': '/path/to/credentials.json' # Path to credentials file + } + + # Step 2: Configure Vault + vault_config = { + 'vault_id': '', # Replace with your vault ID + 'cluster_id': '', # Replace with your cluster ID + 'env': Env.PROD, # Deployment environment + 'credentials': credentials + } + + # Step 3: Configure & Initialize Skyflow Client + skyflow_client = ( + Skyflow.builder() + .add_vault_config(vault_config) + .set_log_level(LogLevel.ERROR) + .build() + ) + + # Step 4: Prepare Sample Text + sample_text = "My SSN is 123-45-6789 and my card is 4111 1111 1111 1111." + + # Step 5: Configure Token Format + token_format = TokenFormat( + vault_token=[DetectEntities.CREDIT_CARD, DetectEntities.SSN], # Use vault tokens for these entities + ) + + # Step 6: Configure Transformations + transformations = Transformations( + shift_dates=DateTransformation( + max_days=30, # Maximum days to shift + min_days=30, # Minimum days to shift + entities=[DetectEntities.DOB] # Apply shift to DOB entities + ) + ) + + # Step 7: Create Deidentify Request + deidentify_request = DeidentifyTextRequest( + text=sample_text, + entities=[DetectEntities.CREDIT_CARD, DetectEntities.SSN], # Entities to detect and deidentify + token_format=token_format, + transformations=transformations, + allow_regex_list=[''], # Optional: regex patterns to allow + restrict_regex_list=[''] # Optional: regex patterns to restrict + ) + + # Step 8: Perform Text Deidentification + response = skyflow_client.detect().deidentify_text(deidentify_request) + + # Handle Successful Response + print("\nDeidentify Text Response:", response) + + except SkyflowError as error: + # Handle Skyflow-specific errors + print('\nSkyflow Error:', { + 'http_code': error.http_code, + 'grpc_code': error.grpc_code, + 'http_status': error.http_status, + 'message': error.message, + 'details': error.details + }) + except Exception as error: + print('Unexpected Error:', error) diff --git a/samples/detect_api/get_detect_run.py b/samples/detect_api/get_detect_run.py new file mode 100644 index 00000000..c2380c27 --- /dev/null +++ b/samples/detect_api/get_detect_run.py @@ -0,0 +1,61 @@ +from skyflow.error import SkyflowError +from skyflow import Env, Skyflow, LogLevel +from skyflow.vault.detect import GetDetectRunRequest + +""" + * Skyflow Get Detect Run Example + * + * This example demonstrates how to: + * 1. Configure credentials + * 2. Set up vault configuration + * 3. Create a get detect run request + * 4. Call getDetectRun to poll for file processing results + * 5. Handle response and errors +""" + +def perform_get_detect_run(): + try: + # Step 1: Configure Credentials + credentials = { + 'path': '/path/to/credentials.json' # Path to credentials file + } + + # Step 2: Configure Vault + vault_config = { + 'vault_id': '', # Replace with your vault ID + 'cluster_id': '', # Replace with your cluster ID + 'env': Env.PROD, # Deployment environment + 'credentials': credentials + } + + # Step 3: Configure & Initialize Skyflow Client + skyflow_client = ( + Skyflow.builder() + .add_vault_config(vault_config) + .set_log_level(LogLevel.INFO) # Use LogLevel.ERROR in production + .build() + ) + + # Step 4: Create GetDetectRunRequest + get_detect_run_request = GetDetectRunRequest( + run_id='' # Replace with the runId from deidentifyFile call + ) + + # Step 5: Call getDetectRun API + response = skyflow_client.detect().get_detect_run(get_detect_run_request) + + # Handle Successful Response + print("\nGet Detect Run Response:", response) + + except SkyflowError as error: + # Handle Skyflow-specific errors + print('\nSkyflow Error:', { + 'http_code': error.http_code, + 'grpc_code': error.grpc_code, + 'http_status': error.http_status, + 'message': error.message, + 'details': error.details + }) + except Exception as error: + # Handle unexpected errors + print('Unexpected Error:', error) diff --git a/samples/detect_api/reidentify_text.py b/samples/detect_api/reidentify_text.py new file mode 100644 index 00000000..d158733f --- /dev/null +++ b/samples/detect_api/reidentify_text.py @@ -0,0 +1,66 @@ +from skyflow.error import SkyflowError +from skyflow import Env, Skyflow, LogLevel +from skyflow.utils.enums import DetectEntities +from skyflow.vault.detect import ReidentifyTextRequest + +""" + * Skyflow Text Re-identification Example + * + * This example demonstrates how to: + * 1. Configure credentials + * 2. Set up vault configuration + * 3. Create a reidentify text request + * 4. Use all available options for reidentification + * 5. Handle response and errors +""" + +def perform_text_reidentification(): + try: + # Step 1: Configure Credentials + credentials = { + 'path': '/path/to/credentials.json' # Path to credentials file + } + + # Step 2: Configure Vault + vault_config = { + 'vault_id': '', # Replace with your vault ID + 'cluster_id': '', # Replace with your cluster ID + 'env': Env.PROD, # Deployment environment + 'credentials': credentials + } + + # Step 3: Configure & Initialize Skyflow Client + skyflow_client = ( + Skyflow.builder() + .add_vault_config(vault_config) + .set_log_level(LogLevel.ERROR) + .build() + ) + + # Step 4: Prepare Sample Redacted Text + redacted_text = "" # Replace with your redacted text + + # Step 5: Create Reidentify Request + reidentify_request = ReidentifyTextRequest( + text=redacted_text, + plain_text_entities=[DetectEntities.PHONE_NUMBER] + ) + + # Step 6: Perform Text Reidentification + response = skyflow_client.detect().reidentify_text(reidentify_request) + + # Step 7: Handle Successful Response + print("\nReidentify Text Response:", response) + + except SkyflowError as error: + # Handle Skyflow-specific errors + print('\nSkyflow Error:', { + 'http_code': error.http_code, + 'grpc_code': error.grpc_code, + 'http_status': error.http_status, + 'message': error.message, + 'details': error.details + }) + except Exception as error: + # Handle unexpected errors + print('Unexpected Error:', error) diff --git a/samples/service_account/bearer_token_expiry_example.py b/samples/service_account/bearer_token_expiry_example.py new file mode 100644 index 00000000..169bf500 --- /dev/null +++ b/samples/service_account/bearer_token_expiry_example.py @@ -0,0 +1,111 @@ +import json +from skyflow.error import SkyflowError +from skyflow import Env +from skyflow import Skyflow, LogLevel +from skyflow.utils.enums import RedactionType +from skyflow.vault.tokens import DetokenizeRequest + +""" + * This example demonstrates how to configure and use the Skyflow SDK + * to detokenize sensitive data stored in a Skyflow vault. + * It includes setting up credentials, configuring the vault, and + * making a detokenization request. The code also implements a retry + * mechanism to handle unauthorized access errors (HTTP 401). +""" + + +def detokenize_data(skyflow_client, vault_id): + try: + # Creating a list of tokens to be detokenized + detokenize_data = [ + { + 'token': '', + 'redaction': RedactionType.REDACTED + }, + { + 'token': '', + 'redaction': RedactionType.MASKED + } + ] + + # Building a detokenization request + detokenize_request = DetokenizeRequest( + data=detokenize_data, + continue_on_error=False + ) + + # Sending the detokenization request and receiving the response + response = skyflow_client.vault(vault_id).detokenize(detokenize_request) + + # Printing the detokenized response + print('Detokenization successful:', response) + + except SkyflowError as error: + print("Skyflow error occurred:", error) + raise + + except Exception as error: + print("Unexpected error occurred:", error) + raise + + +def perform_detokenization(): + try: + # Setting up credentials for accessing the Skyflow vault + cred = { + 'clientID': '', + 'clientName': '', + 'tokenURI': '', + 'keyID': '', + 'privateKey': '', + } + + skyflow_credentials = { + 'credentials_string': json.dumps(cred) # Credentials string for authentication + } + + credentials = { + 'token': '' + } + + # Configuring the Skyflow vault with necessary details + primary_vault_config = { + 'vault_id': '', # Vault ID + 'cluster_id': '', # Cluster ID + 'env': Env.PROD, # Environment set to PROD + 'credentials': credentials # Setting credentials + } + + # Creating a Skyflow client instance with the configured vault + skyflow_client = ( + Skyflow.builder() + .add_vault_config(primary_vault_config) + .add_skyflow_credentials(skyflow_credentials) + .set_log_level(LogLevel.ERROR) # Setting log level to ERROR + .build() + ) + + # Attempting to detokenize data using the Skyflow client + try: + detokenize_data(skyflow_client, primary_vault_config.get('vault_id')) + except SkyflowError as err: + # Retry detokenization if the error is due to unauthorized access (HTTP 401) + if err.http_code == 401: + print("Unauthorized access detected. Retrying...") + detokenize_data(skyflow_client, primary_vault_config.get('vault_id')) + else: + # Rethrow the exception for other error codes + raise err + + except SkyflowError as error: + print('Skyflow Specific Error:', { + 'code': error.http_code, + 'message': error.message, + 'details': error.details + }) + except Exception as error: + print('Unexpected Error:', error) + + +# Invoke the function +perform_detokenization() diff --git a/setup.py b/setup.py index 09cea753..ad8aa72a 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ if sys.version_info < (3, 8): raise RuntimeError("skyflow requires Python 3.8+") -current_version = '2.0.0b3' +current_version = '2.0.0b3.dev0+afd7def' setup( name='skyflow', diff --git a/skyflow/client/skyflow.py b/skyflow/client/skyflow.py index 1c87bcaa..9f0d9dbf 100644 --- a/skyflow/client/skyflow.py +++ b/skyflow/client/skyflow.py @@ -8,6 +8,7 @@ from skyflow.vault.client.client import VaultClient from skyflow.vault.controller import Vault from skyflow.vault.controller import Connection +from skyflow.vault.controller import Detect class Skyflow: def __init__(self, builder): @@ -65,11 +66,15 @@ def update_log_level(self, log_level): def vault(self, vault_id = None) -> Vault: vault_config = self.__builder.get_vault_config(vault_id) - return vault_config.get("controller") + return vault_config.get("vault_controller") def connection(self, connection_id = None) -> Connection: connection_config = self.__builder.get_connection_config(connection_id) return connection_config.get("controller") + + def detect(self, vault_id = None) -> Detect: + vault_config = self.__builder.get_vault_config(vault_id) + return vault_config.get("detect_controller") class Builder: def __init__(self): @@ -182,9 +187,11 @@ def __add_vault_config(self, config): vault_client = VaultClient(config) self.__vault_configs[vault_id] = { "vault_client": vault_client, - "controller": Vault(vault_client) + "vault_controller": Vault(vault_client), + "detect_controller": Detect(vault_client) } log_info(SkyflowMessages.Info.VAULT_CONTROLLER_INITIALIZED.value.format(config.get("vault_id")), self.__logger) + log_info(SkyflowMessages.Info.DETECT_CONTROLLER_INITIALIZED.value.format(config.get("vault_id")), self.__logger) def __add_connection_config(self, config): validate_connection_config(self.__logger, config) diff --git a/skyflow/generated/rest/__init__.py b/skyflow/generated/rest/__init__.py index af42a8fa..9ff683cb 100644 --- a/skyflow/generated/rest/__init__.py +++ b/skyflow/generated/rest/__init__.py @@ -3,6 +3,11 @@ # isort: skip_file from .types import ( + AdvancedOptionsColumnMapping, + AdvancedOptionsEntityColumnMap, + AdvancedOptionsVaultSchema, + AllowRegex, + AudioConfigTranscriptionType, AuditEventAuditResourceType, AuditEventContext, AuditEventData, @@ -10,11 +15,45 @@ BatchRecordMethod, ContextAccessType, ContextAuthMode, + DeidentifyFileOutput, + DeidentifyFileOutputProcessedFileType, + DeidentifyFileResponse, + DeidentifyStatusResponse, + DeidentifyStatusResponseOutputType, + DeidentifyStatusResponseStatus, + DeidentifyStatusResponseWordCharacterCount, + DeidentifyStringResponse, + DetectDataAccuracy, + DetectDataEntities, + DetectFileRequestDataType, + DetectRequestDeidentifyOption, + DetectedEntity, DetokenizeRecordResponseValueType, + EntityLocation, + EntityType, + EntityTypes, + ErrorResponse, + ErrorResponseError, + ErrorString, GooglerpcStatus, + ProcessedFileOutputProcessedFileType, ProtobufAny, RedactionEnumRedaction, + ReidentifyStringResponse, RequestActionType, + ResourceId, + RestrictRegex, + TokenType, + TokenTypeDefault, + TokenTypeWithoutVault, + TokenTypeWithoutVaultDefault, + Transformations, + TransformationsShiftDates, + TransformationsShiftDatesEntityTypesItem, + Uuid, + V1AdvancedOptions, + V1AudioConfig, + V1AudioOptions, V1AuditAfterOptions, V1AuditEventResponse, V1AuditResponse, @@ -29,26 +68,39 @@ V1Card, V1DeleteFileResponse, V1DeleteRecordResponse, + V1DetectFileResponse, + V1DetectStatusResponse, + V1DetectStatusResponseStatus, + V1DetectTextRequest, + V1DetectTextResponse, V1DetokenizeRecordRequest, V1DetokenizeRecordResponse, V1DetokenizeResponse, V1FieldRecords, V1FileAvScanStatus, + V1FileDataFormat, V1GetAuthTokenResponse, V1GetFileScanStatusResponse, V1GetQueryResponse, + V1ImageOptions, V1InsertRecordResponse, + V1Locations, V1MemberType, + V1PdfConfig, + V1PdfOptions, + V1ProcessedFileOutput, V1RecordMetaProperties, + V1ResponseEntities, V1TokenizeRecordRequest, V1TokenizeRecordResponse, V1TokenizeResponse, V1UpdateRecordResponse, V1VaultFieldMapping, V1VaultSchemaConfig, + VaultId, ) -from .errors import BadRequestError, NotFoundError, UnauthorizedError -from . import audit, authentication, bin_lookup, query, records, tokens +from .errors import BadRequestError, InternalServerError, NotFoundError, UnauthorizedError +from . import audit, authentication, bin_lookup, deprecated, files, query, records, strings, tokens from .audit import ( AuditServiceListAuditEventsRequestFilterOpsActionType, AuditServiceListAuditEventsRequestFilterOpsContextAccessType, @@ -59,15 +111,41 @@ ) from .client import AsyncSkyflow, Skyflow from .environment import SkyflowEnvironment +from .files import ( + DeidentifyAudioRequestFile, + DeidentifyAudioRequestFileDataFormat, + DeidentifyAudioRequestOutputTranscription, + DeidentifyDocumentRequestFile, + DeidentifyDocumentRequestFileDataFormat, + DeidentifyFileRequestFile, + DeidentifyFileRequestFileDataFormat, + DeidentifyImageRequestFile, + DeidentifyImageRequestFileDataFormat, + DeidentifyImageRequestMaskingMethod, + DeidentifyPdfRequestFile, + DeidentifyPresentationRequestFile, + DeidentifyPresentationRequestFileDataFormat, + DeidentifySpreadsheetRequestFile, + DeidentifySpreadsheetRequestFileDataFormat, + DeidentifyStructuredTextRequestFile, + DeidentifyStructuredTextRequestFileDataFormat, + DeidentifyTextRequestFile, +) from .records import ( RecordServiceBulkGetRecordRequestOrderBy, RecordServiceBulkGetRecordRequestRedaction, RecordServiceGetRecordRequestRedaction, ) +from .strings import ReidentifyStringRequestFormat from .version import __version__ __all__ = [ + "AdvancedOptionsColumnMapping", + "AdvancedOptionsEntityColumnMap", + "AdvancedOptionsVaultSchema", + "AllowRegex", "AsyncSkyflow", + "AudioConfigTranscriptionType", "AuditEventAuditResourceType", "AuditEventContext", "AuditEventData", @@ -82,18 +160,72 @@ "BatchRecordMethod", "ContextAccessType", "ContextAuthMode", + "DeidentifyAudioRequestFile", + "DeidentifyAudioRequestFileDataFormat", + "DeidentifyAudioRequestOutputTranscription", + "DeidentifyDocumentRequestFile", + "DeidentifyDocumentRequestFileDataFormat", + "DeidentifyFileOutput", + "DeidentifyFileOutputProcessedFileType", + "DeidentifyFileRequestFile", + "DeidentifyFileRequestFileDataFormat", + "DeidentifyFileResponse", + "DeidentifyImageRequestFile", + "DeidentifyImageRequestFileDataFormat", + "DeidentifyImageRequestMaskingMethod", + "DeidentifyPdfRequestFile", + "DeidentifyPresentationRequestFile", + "DeidentifyPresentationRequestFileDataFormat", + "DeidentifySpreadsheetRequestFile", + "DeidentifySpreadsheetRequestFileDataFormat", + "DeidentifyStatusResponse", + "DeidentifyStatusResponseOutputType", + "DeidentifyStatusResponseStatus", + "DeidentifyStatusResponseWordCharacterCount", + "DeidentifyStringResponse", + "DeidentifyStructuredTextRequestFile", + "DeidentifyStructuredTextRequestFileDataFormat", + "DeidentifyTextRequestFile", + "DetectDataAccuracy", + "DetectDataEntities", + "DetectFileRequestDataType", + "DetectRequestDeidentifyOption", + "DetectedEntity", "DetokenizeRecordResponseValueType", + "EntityLocation", + "EntityType", + "EntityTypes", + "ErrorResponse", + "ErrorResponseError", + "ErrorString", "GooglerpcStatus", + "InternalServerError", "NotFoundError", + "ProcessedFileOutputProcessedFileType", "ProtobufAny", "RecordServiceBulkGetRecordRequestOrderBy", "RecordServiceBulkGetRecordRequestRedaction", "RecordServiceGetRecordRequestRedaction", "RedactionEnumRedaction", + "ReidentifyStringRequestFormat", + "ReidentifyStringResponse", "RequestActionType", + "ResourceId", + "RestrictRegex", "Skyflow", "SkyflowEnvironment", + "TokenType", + "TokenTypeDefault", + "TokenTypeWithoutVault", + "TokenTypeWithoutVaultDefault", + "Transformations", + "TransformationsShiftDates", + "TransformationsShiftDatesEntityTypesItem", "UnauthorizedError", + "Uuid", + "V1AdvancedOptions", + "V1AudioConfig", + "V1AudioOptions", "V1AuditAfterOptions", "V1AuditEventResponse", "V1AuditResponse", @@ -108,28 +240,44 @@ "V1Card", "V1DeleteFileResponse", "V1DeleteRecordResponse", + "V1DetectFileResponse", + "V1DetectStatusResponse", + "V1DetectStatusResponseStatus", + "V1DetectTextRequest", + "V1DetectTextResponse", "V1DetokenizeRecordRequest", "V1DetokenizeRecordResponse", "V1DetokenizeResponse", "V1FieldRecords", "V1FileAvScanStatus", + "V1FileDataFormat", "V1GetAuthTokenResponse", "V1GetFileScanStatusResponse", "V1GetQueryResponse", + "V1ImageOptions", "V1InsertRecordResponse", + "V1Locations", "V1MemberType", + "V1PdfConfig", + "V1PdfOptions", + "V1ProcessedFileOutput", "V1RecordMetaProperties", + "V1ResponseEntities", "V1TokenizeRecordRequest", "V1TokenizeRecordResponse", "V1TokenizeResponse", "V1UpdateRecordResponse", "V1VaultFieldMapping", "V1VaultSchemaConfig", + "VaultId", "__version__", "audit", "authentication", "bin_lookup", + "deprecated", + "files", "query", "records", + "strings", "tokens", ] 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/audit/raw_client.py b/skyflow/generated/rest/audit/raw_client.py index b67b025e..3d1277bf 100644 --- a/skyflow/generated/rest/audit/raw_client.py +++ b/skyflow/generated/rest/audit/raw_client.py @@ -244,9 +244,9 @@ def audit_service_list_audit_events( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -471,9 +471,9 @@ async def audit_service_list_audit_events( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), 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/authentication/raw_client.py b/skyflow/generated/rest/authentication/raw_client.py index bb1c2ed7..ad2caef6 100644 --- a/skyflow/generated/rest/authentication/raw_client.py +++ b/skyflow/generated/rest/authentication/raw_client.py @@ -94,9 +94,9 @@ def authentication_service_get_auth_token( raise BadRequestError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -105,9 +105,9 @@ def authentication_service_get_auth_token( raise UnauthorizedError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -116,9 +116,9 @@ def authentication_service_get_auth_token( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -206,9 +206,9 @@ async def authentication_service_get_auth_token( raise BadRequestError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -217,9 +217,9 @@ async def authentication_service_get_auth_token( raise UnauthorizedError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -228,9 +228,9 @@ async def authentication_service_get_auth_token( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), 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/bin_lookup/raw_client.py b/skyflow/generated/rest/bin_lookup/raw_client.py index 90202931..b82f4c84 100644 --- a/skyflow/generated/rest/bin_lookup/raw_client.py +++ b/skyflow/generated/rest/bin_lookup/raw_client.py @@ -85,9 +85,9 @@ def bin_list_service_list_cards_of_bin( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -166,9 +166,9 @@ async def bin_list_service_list_cards_of_bin( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), diff --git a/skyflow/generated/rest/client.py b/skyflow/generated/rest/client.py index 3dab76fb..315d1f86 100644 --- a/skyflow/generated/rest/client.py +++ b/skyflow/generated/rest/client.py @@ -7,9 +7,12 @@ from .authentication.client import AsyncAuthenticationClient, AuthenticationClient from .bin_lookup.client import AsyncBinLookupClient, BinLookupClient from .core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from .deprecated.client import AsyncDeprecatedClient, DeprecatedClient from .environment import SkyflowEnvironment +from .files.client import AsyncFilesClient, FilesClient from .query.client import AsyncQueryClient, QueryClient from .records.client import AsyncRecordsClient, RecordsClient +from .strings.client import AsyncStringsClient, StringsClient from .tokens.client import AsyncTokensClient, TokensClient @@ -25,6 +28,8 @@ class Skyflow: environment : SkyflowEnvironment The environment to use for requests from the client. from .environment import SkyflowEnvironment + + Defaults to SkyflowEnvironment.PRODUCTION @@ -42,7 +47,10 @@ class Skyflow: Examples -------- from skyflow import Skyflow - client = Skyflow(token="YOUR_TOKEN", ) + + client = Skyflow( + token="YOUR_TOKEN", + ) """ def __init__( @@ -74,6 +82,9 @@ def __init__( self.tokens = TokensClient(client_wrapper=self._client_wrapper) self.query = QueryClient(client_wrapper=self._client_wrapper) self.authentication = AuthenticationClient(client_wrapper=self._client_wrapper) + self.deprecated = DeprecatedClient(client_wrapper=self._client_wrapper) + self.strings = StringsClient(client_wrapper=self._client_wrapper) + self.files = FilesClient(client_wrapper=self._client_wrapper) class AsyncSkyflow: @@ -88,6 +99,8 @@ class AsyncSkyflow: environment : SkyflowEnvironment The environment to use for requests from the client. from .environment import SkyflowEnvironment + + Defaults to SkyflowEnvironment.PRODUCTION @@ -105,7 +118,10 @@ class AsyncSkyflow: Examples -------- from skyflow import AsyncSkyflow - client = AsyncSkyflow(token="YOUR_TOKEN", ) + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) """ def __init__( @@ -137,6 +153,9 @@ def __init__( self.tokens = AsyncTokensClient(client_wrapper=self._client_wrapper) self.query = AsyncQueryClient(client_wrapper=self._client_wrapper) self.authentication = AsyncAuthenticationClient(client_wrapper=self._client_wrapper) + self.deprecated = AsyncDeprecatedClient(client_wrapper=self._client_wrapper) + self.strings = AsyncStringsClient(client_wrapper=self._client_wrapper) + self.files = AsyncFilesClient(client_wrapper=self._client_wrapper) def _get_base_url(*, base_url: typing.Optional[str] = None, environment: SkyflowEnvironment) -> str: diff --git a/skyflow/generated/rest/core/client_wrapper.py b/skyflow/generated/rest/core/client_wrapper.py index b1396aef..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.166", + "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/__init__.py b/skyflow/generated/rest/deprecated/__init__.py new file mode 100644 index 00000000..5cde0202 --- /dev/null +++ b/skyflow/generated/rest/deprecated/__init__.py @@ -0,0 +1,4 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + diff --git a/skyflow/generated/rest/deprecated/client.py b/skyflow/generated/rest/deprecated/client.py new file mode 100644 index 00000000..bd1cc88c --- /dev/null +++ b/skyflow/generated/rest/deprecated/client.py @@ -0,0 +1,598 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.request_options import RequestOptions +from ..types.detect_data_accuracy import DetectDataAccuracy +from ..types.detect_data_entities import DetectDataEntities +from ..types.detect_file_request_data_type import DetectFileRequestDataType +from ..types.detect_request_deidentify_option import DetectRequestDeidentifyOption +from ..types.v_1_advanced_options import V1AdvancedOptions +from ..types.v_1_audio_config import V1AudioConfig +from ..types.v_1_detect_file_response import V1DetectFileResponse +from ..types.v_1_detect_status_response import V1DetectStatusResponse +from ..types.v_1_detect_text_response import V1DetectTextResponse +from ..types.v_1_file_data_format import V1FileDataFormat +from ..types.v_1_image_options import V1ImageOptions +from ..types.v_1_pdf_config import V1PdfConfig +from .raw_client import AsyncRawDeprecatedClient, RawDeprecatedClient + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class DeprecatedClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawDeprecatedClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawDeprecatedClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawDeprecatedClient + """ + return self._raw_client + + def detect_service_detect_file_input( + self, + *, + file: str, + data_format: V1FileDataFormat, + input_type: DetectFileRequestDataType, + vault_id: str, + session_id: typing.Optional[str] = OMIT, + restrict_entity_types: typing.Optional[typing.Sequence[DetectDataEntities]] = OMIT, + allow_regex: typing.Optional[typing.Sequence[str]] = OMIT, + restrict_regex: typing.Optional[typing.Sequence[str]] = OMIT, + return_entities: typing.Optional[bool] = OMIT, + accuracy: typing.Optional[DetectDataAccuracy] = OMIT, + audio: typing.Optional[V1AudioConfig] = OMIT, + image: typing.Optional[V1ImageOptions] = OMIT, + pdf: typing.Optional[V1PdfConfig] = OMIT, + advanced_options: typing.Optional[V1AdvancedOptions] = OMIT, + deidentify_token_format: typing.Optional[DetectRequestDeidentifyOption] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> V1DetectFileResponse: + """ + Note: This operation is deprecated. Use one of the De-identify File operations.

Detects and deidentifies sensitive data from image, audio, and video files. + + Parameters + ---------- + file : str + Path of the file or base64-encoded data that has to be processed. + + data_format : V1FileDataFormat + + input_type : DetectFileRequestDataType + + vault_id : str + ID of the vault. + + session_id : typing.Optional[str] + Will give a handle to delete the tokens generated during a specific interaction. + + restrict_entity_types : typing.Optional[typing.Sequence[DetectDataEntities]] + Entities to detect and deidentify. + + allow_regex : typing.Optional[typing.Sequence[str]] + Regular expressions to ignore when detecting entities. + + restrict_regex : typing.Optional[typing.Sequence[str]] + Regular expressions to always restrict. Strings matching these regular expressions are replaced with 'RESTRICTED'. + + return_entities : typing.Optional[bool] + If `true`, returns the details for the detected entities. + + accuracy : typing.Optional[DetectDataAccuracy] + + audio : typing.Optional[V1AudioConfig] + + image : typing.Optional[V1ImageOptions] + + pdf : typing.Optional[V1PdfConfig] + + advanced_options : typing.Optional[V1AdvancedOptions] + + deidentify_token_format : typing.Optional[DetectRequestDeidentifyOption] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + V1DetectFileResponse + A successful response. + + Examples + -------- + 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, + data_format=data_format, + input_type=input_type, + vault_id=vault_id, + session_id=session_id, + restrict_entity_types=restrict_entity_types, + allow_regex=allow_regex, + restrict_regex=restrict_regex, + return_entities=return_entities, + accuracy=accuracy, + audio=audio, + image=image, + pdf=pdf, + advanced_options=advanced_options, + deidentify_token_format=deidentify_token_format, + request_options=request_options, + ) + return _response.data + + def detect_service_detect_status( + self, id: str, *, vault_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None + ) -> V1DetectStatusResponse: + """ + Note: This operation is deprecated. Use Get Detect Run.

Returns the status of a file deidentification request. + + Parameters + ---------- + id : str + ID of the deidentification request. + + vault_id : typing.Optional[str] + ID of the vault. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + V1DetectStatusResponse + A successful response. + + Examples + -------- + from skyflow import Skyflow + + 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 + ) + return _response.data + + def detect_service_detect_text( + self, + *, + text: str, + vault_id: str, + session_id: typing.Optional[str] = OMIT, + restrict_entity_types: typing.Optional[typing.Sequence[DetectDataEntities]] = OMIT, + deidentify_token_format: typing.Optional[DetectRequestDeidentifyOption] = OMIT, + allow_regex: typing.Optional[typing.Sequence[str]] = OMIT, + restrict_regex: typing.Optional[typing.Sequence[str]] = OMIT, + return_entities: typing.Optional[bool] = OMIT, + accuracy: typing.Optional[DetectDataAccuracy] = OMIT, + advanced_options: typing.Optional[V1AdvancedOptions] = OMIT, + store_entities: typing.Optional[bool] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> V1DetectTextResponse: + """ + Note: This operation is deprecated. Use De-identify String.

Detects and deidentifies sensitive data from text. + + Parameters + ---------- + text : str + Data to deidentify. + + vault_id : str + ID of the vault. + + session_id : typing.Optional[str] + Will give a handle to delete the tokens generated during a specific interaction. + + restrict_entity_types : typing.Optional[typing.Sequence[DetectDataEntities]] + Entities to detect and deidentify. + + deidentify_token_format : typing.Optional[DetectRequestDeidentifyOption] + + allow_regex : typing.Optional[typing.Sequence[str]] + Regular expressions to ignore when detecting entities. + + restrict_regex : typing.Optional[typing.Sequence[str]] + Regular expressions to always restrict. Strings matching these regular expressions are replaced with 'RESTRICTED'. + + return_entities : typing.Optional[bool] + If `true`, returns the details for the detected entities. + + accuracy : typing.Optional[DetectDataAccuracy] + + advanced_options : typing.Optional[V1AdvancedOptions] + + store_entities : typing.Optional[bool] + Indicates whether entities should be stored in the vault. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + V1DetectTextResponse + A successful response. + + Examples + -------- + from skyflow import Skyflow + + 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, + vault_id=vault_id, + session_id=session_id, + restrict_entity_types=restrict_entity_types, + deidentify_token_format=deidentify_token_format, + allow_regex=allow_regex, + restrict_regex=restrict_regex, + return_entities=return_entities, + accuracy=accuracy, + advanced_options=advanced_options, + store_entities=store_entities, + request_options=request_options, + ) + return _response.data + + +class AsyncDeprecatedClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawDeprecatedClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawDeprecatedClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawDeprecatedClient + """ + return self._raw_client + + async def detect_service_detect_file_input( + self, + *, + file: str, + data_format: V1FileDataFormat, + input_type: DetectFileRequestDataType, + vault_id: str, + session_id: typing.Optional[str] = OMIT, + restrict_entity_types: typing.Optional[typing.Sequence[DetectDataEntities]] = OMIT, + allow_regex: typing.Optional[typing.Sequence[str]] = OMIT, + restrict_regex: typing.Optional[typing.Sequence[str]] = OMIT, + return_entities: typing.Optional[bool] = OMIT, + accuracy: typing.Optional[DetectDataAccuracy] = OMIT, + audio: typing.Optional[V1AudioConfig] = OMIT, + image: typing.Optional[V1ImageOptions] = OMIT, + pdf: typing.Optional[V1PdfConfig] = OMIT, + advanced_options: typing.Optional[V1AdvancedOptions] = OMIT, + deidentify_token_format: typing.Optional[DetectRequestDeidentifyOption] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> V1DetectFileResponse: + """ + Note: This operation is deprecated. Use one of the De-identify File operations.

Detects and deidentifies sensitive data from image, audio, and video files. + + Parameters + ---------- + file : str + Path of the file or base64-encoded data that has to be processed. + + data_format : V1FileDataFormat + + input_type : DetectFileRequestDataType + + vault_id : str + ID of the vault. + + session_id : typing.Optional[str] + Will give a handle to delete the tokens generated during a specific interaction. + + restrict_entity_types : typing.Optional[typing.Sequence[DetectDataEntities]] + Entities to detect and deidentify. + + allow_regex : typing.Optional[typing.Sequence[str]] + Regular expressions to ignore when detecting entities. + + restrict_regex : typing.Optional[typing.Sequence[str]] + Regular expressions to always restrict. Strings matching these regular expressions are replaced with 'RESTRICTED'. + + return_entities : typing.Optional[bool] + If `true`, returns the details for the detected entities. + + accuracy : typing.Optional[DetectDataAccuracy] + + audio : typing.Optional[V1AudioConfig] + + image : typing.Optional[V1ImageOptions] + + pdf : typing.Optional[V1PdfConfig] + + advanced_options : typing.Optional[V1AdvancedOptions] + + deidentify_token_format : typing.Optional[DetectRequestDeidentifyOption] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + V1DetectFileResponse + A successful response. + + Examples + -------- + import asyncio + + 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, + ), + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.detect_service_detect_file_input( + file=file, + data_format=data_format, + input_type=input_type, + vault_id=vault_id, + session_id=session_id, + restrict_entity_types=restrict_entity_types, + allow_regex=allow_regex, + restrict_regex=restrict_regex, + return_entities=return_entities, + accuracy=accuracy, + audio=audio, + image=image, + pdf=pdf, + advanced_options=advanced_options, + deidentify_token_format=deidentify_token_format, + request_options=request_options, + ) + return _response.data + + async def detect_service_detect_status( + self, id: str, *, vault_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None + ) -> V1DetectStatusResponse: + """ + Note: This operation is deprecated. Use Get Detect Run.

Returns the status of a file deidentification request. + + Parameters + ---------- + id : str + ID of the deidentification request. + + vault_id : typing.Optional[str] + ID of the vault. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + V1DetectStatusResponse + A successful response. + + Examples + -------- + import asyncio + + from skyflow import AsyncSkyflow + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.deprecated.detect_service_detect_status( + id="ID", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.detect_service_detect_status( + id, vault_id=vault_id, request_options=request_options + ) + return _response.data + + async def detect_service_detect_text( + self, + *, + text: str, + vault_id: str, + session_id: typing.Optional[str] = OMIT, + restrict_entity_types: typing.Optional[typing.Sequence[DetectDataEntities]] = OMIT, + deidentify_token_format: typing.Optional[DetectRequestDeidentifyOption] = OMIT, + allow_regex: typing.Optional[typing.Sequence[str]] = OMIT, + restrict_regex: typing.Optional[typing.Sequence[str]] = OMIT, + return_entities: typing.Optional[bool] = OMIT, + accuracy: typing.Optional[DetectDataAccuracy] = OMIT, + advanced_options: typing.Optional[V1AdvancedOptions] = OMIT, + store_entities: typing.Optional[bool] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> V1DetectTextResponse: + """ + Note: This operation is deprecated. Use De-identify String.

Detects and deidentifies sensitive data from text. + + Parameters + ---------- + text : str + Data to deidentify. + + vault_id : str + ID of the vault. + + session_id : typing.Optional[str] + Will give a handle to delete the tokens generated during a specific interaction. + + restrict_entity_types : typing.Optional[typing.Sequence[DetectDataEntities]] + Entities to detect and deidentify. + + deidentify_token_format : typing.Optional[DetectRequestDeidentifyOption] + + allow_regex : typing.Optional[typing.Sequence[str]] + Regular expressions to ignore when detecting entities. + + restrict_regex : typing.Optional[typing.Sequence[str]] + Regular expressions to always restrict. Strings matching these regular expressions are replaced with 'RESTRICTED'. + + return_entities : typing.Optional[bool] + If `true`, returns the details for the detected entities. + + accuracy : typing.Optional[DetectDataAccuracy] + + advanced_options : typing.Optional[V1AdvancedOptions] + + store_entities : typing.Optional[bool] + Indicates whether entities should be stored in the vault. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + V1DetectTextResponse + A successful response. + + Examples + -------- + import asyncio + + 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", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.detect_service_detect_text( + text=text, + vault_id=vault_id, + session_id=session_id, + restrict_entity_types=restrict_entity_types, + deidentify_token_format=deidentify_token_format, + allow_regex=allow_regex, + restrict_regex=restrict_regex, + return_entities=return_entities, + accuracy=accuracy, + advanced_options=advanced_options, + store_entities=store_entities, + request_options=request_options, + ) + return _response.data diff --git a/skyflow/generated/rest/deprecated/raw_client.py b/skyflow/generated/rest/deprecated/raw_client.py new file mode 100644 index 00000000..11dd7ef1 --- /dev/null +++ b/skyflow/generated/rest/deprecated/raw_client.py @@ -0,0 +1,624 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ..core.api_error import ApiError +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.http_response import AsyncHttpResponse, HttpResponse +from ..core.jsonable_encoder import jsonable_encoder +from ..core.pydantic_utilities import parse_obj_as +from ..core.request_options import RequestOptions +from ..core.serialization import convert_and_respect_annotation_metadata +from ..errors.not_found_error import NotFoundError +from ..types.detect_data_accuracy import DetectDataAccuracy +from ..types.detect_data_entities import DetectDataEntities +from ..types.detect_file_request_data_type import DetectFileRequestDataType +from ..types.detect_request_deidentify_option import DetectRequestDeidentifyOption +from ..types.v_1_advanced_options import V1AdvancedOptions +from ..types.v_1_audio_config import V1AudioConfig +from ..types.v_1_detect_file_response import V1DetectFileResponse +from ..types.v_1_detect_status_response import V1DetectStatusResponse +from ..types.v_1_detect_text_response import V1DetectTextResponse +from ..types.v_1_file_data_format import V1FileDataFormat +from ..types.v_1_image_options import V1ImageOptions +from ..types.v_1_pdf_config import V1PdfConfig + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawDeprecatedClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def detect_service_detect_file_input( + self, + *, + file: str, + data_format: V1FileDataFormat, + input_type: DetectFileRequestDataType, + vault_id: str, + session_id: typing.Optional[str] = OMIT, + restrict_entity_types: typing.Optional[typing.Sequence[DetectDataEntities]] = OMIT, + allow_regex: typing.Optional[typing.Sequence[str]] = OMIT, + restrict_regex: typing.Optional[typing.Sequence[str]] = OMIT, + return_entities: typing.Optional[bool] = OMIT, + accuracy: typing.Optional[DetectDataAccuracy] = OMIT, + audio: typing.Optional[V1AudioConfig] = OMIT, + image: typing.Optional[V1ImageOptions] = OMIT, + pdf: typing.Optional[V1PdfConfig] = OMIT, + advanced_options: typing.Optional[V1AdvancedOptions] = OMIT, + deidentify_token_format: typing.Optional[DetectRequestDeidentifyOption] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[V1DetectFileResponse]: + """ + Note: This operation is deprecated. Use one of the De-identify File operations.

Detects and deidentifies sensitive data from image, audio, and video files. + + Parameters + ---------- + file : str + Path of the file or base64-encoded data that has to be processed. + + data_format : V1FileDataFormat + + input_type : DetectFileRequestDataType + + vault_id : str + ID of the vault. + + session_id : typing.Optional[str] + Will give a handle to delete the tokens generated during a specific interaction. + + restrict_entity_types : typing.Optional[typing.Sequence[DetectDataEntities]] + Entities to detect and deidentify. + + allow_regex : typing.Optional[typing.Sequence[str]] + Regular expressions to ignore when detecting entities. + + restrict_regex : typing.Optional[typing.Sequence[str]] + Regular expressions to always restrict. Strings matching these regular expressions are replaced with 'RESTRICTED'. + + return_entities : typing.Optional[bool] + If `true`, returns the details for the detected entities. + + accuracy : typing.Optional[DetectDataAccuracy] + + audio : typing.Optional[V1AudioConfig] + + image : typing.Optional[V1ImageOptions] + + pdf : typing.Optional[V1PdfConfig] + + advanced_options : typing.Optional[V1AdvancedOptions] + + deidentify_token_format : typing.Optional[DetectRequestDeidentifyOption] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[V1DetectFileResponse] + A successful response. + """ + _response = self._client_wrapper.httpx_client.request( + "v1/detect/file", + method="POST", + json={ + "file": file, + "data_format": data_format, + "input_type": input_type, + "vault_id": vault_id, + "session_id": session_id, + "restrict_entity_types": restrict_entity_types, + "allow_regex": allow_regex, + "restrict_regex": restrict_regex, + "return_entities": return_entities, + "accuracy": accuracy, + "audio": convert_and_respect_annotation_metadata( + object_=audio, annotation=V1AudioConfig, direction="write" + ), + "image": convert_and_respect_annotation_metadata( + object_=image, annotation=V1ImageOptions, direction="write" + ), + "pdf": convert_and_respect_annotation_metadata(object_=pdf, annotation=V1PdfConfig, direction="write"), + "advanced_options": convert_and_respect_annotation_metadata( + object_=advanced_options, annotation=V1AdvancedOptions, direction="write" + ), + "deidentify_token_format": deidentify_token_format, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + V1DetectFileResponse, + parse_obj_as( + type_=V1DetectFileResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def detect_service_detect_status( + self, id: str, *, vault_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[V1DetectStatusResponse]: + """ + Note: This operation is deprecated. Use Get Detect Run.

Returns the status of a file deidentification request. + + Parameters + ---------- + id : str + ID of the deidentification request. + + vault_id : typing.Optional[str] + ID of the vault. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[V1DetectStatusResponse] + A successful response. + """ + _response = self._client_wrapper.httpx_client.request( + f"v1/detect/status/{jsonable_encoder(id)}", + method="GET", + params={ + "vault_id": vault_id, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + V1DetectStatusResponse, + parse_obj_as( + type_=V1DetectStatusResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def detect_service_detect_text( + self, + *, + text: str, + vault_id: str, + session_id: typing.Optional[str] = OMIT, + restrict_entity_types: typing.Optional[typing.Sequence[DetectDataEntities]] = OMIT, + deidentify_token_format: typing.Optional[DetectRequestDeidentifyOption] = OMIT, + allow_regex: typing.Optional[typing.Sequence[str]] = OMIT, + restrict_regex: typing.Optional[typing.Sequence[str]] = OMIT, + return_entities: typing.Optional[bool] = OMIT, + accuracy: typing.Optional[DetectDataAccuracy] = OMIT, + advanced_options: typing.Optional[V1AdvancedOptions] = OMIT, + store_entities: typing.Optional[bool] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[V1DetectTextResponse]: + """ + Note: This operation is deprecated. Use De-identify String.

Detects and deidentifies sensitive data from text. + + Parameters + ---------- + text : str + Data to deidentify. + + vault_id : str + ID of the vault. + + session_id : typing.Optional[str] + Will give a handle to delete the tokens generated during a specific interaction. + + restrict_entity_types : typing.Optional[typing.Sequence[DetectDataEntities]] + Entities to detect and deidentify. + + deidentify_token_format : typing.Optional[DetectRequestDeidentifyOption] + + allow_regex : typing.Optional[typing.Sequence[str]] + Regular expressions to ignore when detecting entities. + + restrict_regex : typing.Optional[typing.Sequence[str]] + Regular expressions to always restrict. Strings matching these regular expressions are replaced with 'RESTRICTED'. + + return_entities : typing.Optional[bool] + If `true`, returns the details for the detected entities. + + accuracy : typing.Optional[DetectDataAccuracy] + + advanced_options : typing.Optional[V1AdvancedOptions] + + store_entities : typing.Optional[bool] + Indicates whether entities should be stored in the vault. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[V1DetectTextResponse] + A successful response. + """ + _response = self._client_wrapper.httpx_client.request( + "v1/detect/text", + method="POST", + json={ + "text": text, + "vault_id": vault_id, + "session_id": session_id, + "restrict_entity_types": restrict_entity_types, + "deidentify_token_format": deidentify_token_format, + "allow_regex": allow_regex, + "restrict_regex": restrict_regex, + "return_entities": return_entities, + "accuracy": accuracy, + "advanced_options": convert_and_respect_annotation_metadata( + object_=advanced_options, annotation=V1AdvancedOptions, direction="write" + ), + "store_entities": store_entities, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + V1DetectTextResponse, + parse_obj_as( + type_=V1DetectTextResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + +class AsyncRawDeprecatedClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def detect_service_detect_file_input( + self, + *, + file: str, + data_format: V1FileDataFormat, + input_type: DetectFileRequestDataType, + vault_id: str, + session_id: typing.Optional[str] = OMIT, + restrict_entity_types: typing.Optional[typing.Sequence[DetectDataEntities]] = OMIT, + allow_regex: typing.Optional[typing.Sequence[str]] = OMIT, + restrict_regex: typing.Optional[typing.Sequence[str]] = OMIT, + return_entities: typing.Optional[bool] = OMIT, + accuracy: typing.Optional[DetectDataAccuracy] = OMIT, + audio: typing.Optional[V1AudioConfig] = OMIT, + image: typing.Optional[V1ImageOptions] = OMIT, + pdf: typing.Optional[V1PdfConfig] = OMIT, + advanced_options: typing.Optional[V1AdvancedOptions] = OMIT, + deidentify_token_format: typing.Optional[DetectRequestDeidentifyOption] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[V1DetectFileResponse]: + """ + Note: This operation is deprecated. Use one of the De-identify File operations.

Detects and deidentifies sensitive data from image, audio, and video files. + + Parameters + ---------- + file : str + Path of the file or base64-encoded data that has to be processed. + + data_format : V1FileDataFormat + + input_type : DetectFileRequestDataType + + vault_id : str + ID of the vault. + + session_id : typing.Optional[str] + Will give a handle to delete the tokens generated during a specific interaction. + + restrict_entity_types : typing.Optional[typing.Sequence[DetectDataEntities]] + Entities to detect and deidentify. + + allow_regex : typing.Optional[typing.Sequence[str]] + Regular expressions to ignore when detecting entities. + + restrict_regex : typing.Optional[typing.Sequence[str]] + Regular expressions to always restrict. Strings matching these regular expressions are replaced with 'RESTRICTED'. + + return_entities : typing.Optional[bool] + If `true`, returns the details for the detected entities. + + accuracy : typing.Optional[DetectDataAccuracy] + + audio : typing.Optional[V1AudioConfig] + + image : typing.Optional[V1ImageOptions] + + pdf : typing.Optional[V1PdfConfig] + + advanced_options : typing.Optional[V1AdvancedOptions] + + deidentify_token_format : typing.Optional[DetectRequestDeidentifyOption] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[V1DetectFileResponse] + A successful response. + """ + _response = await self._client_wrapper.httpx_client.request( + "v1/detect/file", + method="POST", + json={ + "file": file, + "data_format": data_format, + "input_type": input_type, + "vault_id": vault_id, + "session_id": session_id, + "restrict_entity_types": restrict_entity_types, + "allow_regex": allow_regex, + "restrict_regex": restrict_regex, + "return_entities": return_entities, + "accuracy": accuracy, + "audio": convert_and_respect_annotation_metadata( + object_=audio, annotation=V1AudioConfig, direction="write" + ), + "image": convert_and_respect_annotation_metadata( + object_=image, annotation=V1ImageOptions, direction="write" + ), + "pdf": convert_and_respect_annotation_metadata(object_=pdf, annotation=V1PdfConfig, direction="write"), + "advanced_options": convert_and_respect_annotation_metadata( + object_=advanced_options, annotation=V1AdvancedOptions, direction="write" + ), + "deidentify_token_format": deidentify_token_format, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + V1DetectFileResponse, + parse_obj_as( + type_=V1DetectFileResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def detect_service_detect_status( + self, id: str, *, vault_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[V1DetectStatusResponse]: + """ + Note: This operation is deprecated. Use Get Detect Run.

Returns the status of a file deidentification request. + + Parameters + ---------- + id : str + ID of the deidentification request. + + vault_id : typing.Optional[str] + ID of the vault. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[V1DetectStatusResponse] + A successful response. + """ + _response = await self._client_wrapper.httpx_client.request( + f"v1/detect/status/{jsonable_encoder(id)}", + method="GET", + params={ + "vault_id": vault_id, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + V1DetectStatusResponse, + parse_obj_as( + type_=V1DetectStatusResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def detect_service_detect_text( + self, + *, + text: str, + vault_id: str, + session_id: typing.Optional[str] = OMIT, + restrict_entity_types: typing.Optional[typing.Sequence[DetectDataEntities]] = OMIT, + deidentify_token_format: typing.Optional[DetectRequestDeidentifyOption] = OMIT, + allow_regex: typing.Optional[typing.Sequence[str]] = OMIT, + restrict_regex: typing.Optional[typing.Sequence[str]] = OMIT, + return_entities: typing.Optional[bool] = OMIT, + accuracy: typing.Optional[DetectDataAccuracy] = OMIT, + advanced_options: typing.Optional[V1AdvancedOptions] = OMIT, + store_entities: typing.Optional[bool] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[V1DetectTextResponse]: + """ + Note: This operation is deprecated. Use De-identify String.

Detects and deidentifies sensitive data from text. + + Parameters + ---------- + text : str + Data to deidentify. + + vault_id : str + ID of the vault. + + session_id : typing.Optional[str] + Will give a handle to delete the tokens generated during a specific interaction. + + restrict_entity_types : typing.Optional[typing.Sequence[DetectDataEntities]] + Entities to detect and deidentify. + + deidentify_token_format : typing.Optional[DetectRequestDeidentifyOption] + + allow_regex : typing.Optional[typing.Sequence[str]] + Regular expressions to ignore when detecting entities. + + restrict_regex : typing.Optional[typing.Sequence[str]] + Regular expressions to always restrict. Strings matching these regular expressions are replaced with 'RESTRICTED'. + + return_entities : typing.Optional[bool] + If `true`, returns the details for the detected entities. + + accuracy : typing.Optional[DetectDataAccuracy] + + advanced_options : typing.Optional[V1AdvancedOptions] + + store_entities : typing.Optional[bool] + Indicates whether entities should be stored in the vault. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[V1DetectTextResponse] + A successful response. + """ + _response = await self._client_wrapper.httpx_client.request( + "v1/detect/text", + method="POST", + json={ + "text": text, + "vault_id": vault_id, + "session_id": session_id, + "restrict_entity_types": restrict_entity_types, + "deidentify_token_format": deidentify_token_format, + "allow_regex": allow_regex, + "restrict_regex": restrict_regex, + "return_entities": return_entities, + "accuracy": accuracy, + "advanced_options": convert_and_respect_annotation_metadata( + object_=advanced_options, annotation=V1AdvancedOptions, direction="write" + ), + "store_entities": store_entities, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + V1DetectTextResponse, + parse_obj_as( + type_=V1DetectTextResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) diff --git a/skyflow/generated/rest/errors/__init__.py b/skyflow/generated/rest/errors/__init__.py index fdf6196c..27c36553 100644 --- a/skyflow/generated/rest/errors/__init__.py +++ b/skyflow/generated/rest/errors/__init__.py @@ -3,7 +3,8 @@ # isort: skip_file from .bad_request_error import BadRequestError +from .internal_server_error import InternalServerError from .not_found_error import NotFoundError from .unauthorized_error import UnauthorizedError -__all__ = ["BadRequestError", "NotFoundError", "UnauthorizedError"] +__all__ = ["BadRequestError", "InternalServerError", "NotFoundError", "UnauthorizedError"] diff --git a/skyflow/generated/rest/errors/bad_request_error.py b/skyflow/generated/rest/errors/bad_request_error.py index c5d0db48..baf5be4f 100644 --- a/skyflow/generated/rest/errors/bad_request_error.py +++ b/skyflow/generated/rest/errors/bad_request_error.py @@ -6,9 +6,5 @@ class BadRequestError(ApiError): - def __init__( - self, - body: typing.Dict[str, typing.Optional[typing.Any]], - headers: typing.Optional[typing.Dict[str, str]] = None, - ): + def __init__(self, body: typing.Optional[typing.Any], headers: typing.Optional[typing.Dict[str, str]] = None): super().__init__(status_code=400, headers=headers, body=body) diff --git a/skyflow/generated/rest/errors/internal_server_error.py b/skyflow/generated/rest/errors/internal_server_error.py new file mode 100644 index 00000000..d7a796c6 --- /dev/null +++ b/skyflow/generated/rest/errors/internal_server_error.py @@ -0,0 +1,11 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core.api_error import ApiError +from ..types.error_response import ErrorResponse + + +class InternalServerError(ApiError): + def __init__(self, body: ErrorResponse, headers: typing.Optional[typing.Dict[str, str]] = None): + super().__init__(status_code=500, headers=headers, body=body) diff --git a/skyflow/generated/rest/errors/not_found_error.py b/skyflow/generated/rest/errors/not_found_error.py index 66307415..dcd60e38 100644 --- a/skyflow/generated/rest/errors/not_found_error.py +++ b/skyflow/generated/rest/errors/not_found_error.py @@ -6,9 +6,5 @@ class NotFoundError(ApiError): - def __init__( - self, - body: typing.Dict[str, typing.Optional[typing.Any]], - headers: typing.Optional[typing.Dict[str, str]] = None, - ): + def __init__(self, body: typing.Optional[typing.Any], headers: typing.Optional[typing.Dict[str, str]] = None): super().__init__(status_code=404, headers=headers, body=body) diff --git a/skyflow/generated/rest/errors/unauthorized_error.py b/skyflow/generated/rest/errors/unauthorized_error.py index 3d58c2e6..c83b25c2 100644 --- a/skyflow/generated/rest/errors/unauthorized_error.py +++ b/skyflow/generated/rest/errors/unauthorized_error.py @@ -6,9 +6,5 @@ class UnauthorizedError(ApiError): - def __init__( - self, - body: typing.Dict[str, typing.Optional[typing.Any]], - headers: typing.Optional[typing.Dict[str, str]] = None, - ): + def __init__(self, body: typing.Optional[typing.Any], headers: typing.Optional[typing.Dict[str, str]] = None): super().__init__(status_code=401, headers=headers, body=body) diff --git a/skyflow/generated/rest/files/__init__.py b/skyflow/generated/rest/files/__init__.py new file mode 100644 index 00000000..1b10a15a --- /dev/null +++ b/skyflow/generated/rest/files/__init__.py @@ -0,0 +1,45 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +from .types import ( + DeidentifyAudioRequestFile, + DeidentifyAudioRequestFileDataFormat, + DeidentifyAudioRequestOutputTranscription, + DeidentifyDocumentRequestFile, + DeidentifyDocumentRequestFileDataFormat, + DeidentifyFileRequestFile, + DeidentifyFileRequestFileDataFormat, + DeidentifyImageRequestFile, + DeidentifyImageRequestFileDataFormat, + DeidentifyImageRequestMaskingMethod, + DeidentifyPdfRequestFile, + DeidentifyPresentationRequestFile, + DeidentifyPresentationRequestFileDataFormat, + DeidentifySpreadsheetRequestFile, + DeidentifySpreadsheetRequestFileDataFormat, + DeidentifyStructuredTextRequestFile, + DeidentifyStructuredTextRequestFileDataFormat, + DeidentifyTextRequestFile, +) + +__all__ = [ + "DeidentifyAudioRequestFile", + "DeidentifyAudioRequestFileDataFormat", + "DeidentifyAudioRequestOutputTranscription", + "DeidentifyDocumentRequestFile", + "DeidentifyDocumentRequestFileDataFormat", + "DeidentifyFileRequestFile", + "DeidentifyFileRequestFileDataFormat", + "DeidentifyImageRequestFile", + "DeidentifyImageRequestFileDataFormat", + "DeidentifyImageRequestMaskingMethod", + "DeidentifyPdfRequestFile", + "DeidentifyPresentationRequestFile", + "DeidentifyPresentationRequestFileDataFormat", + "DeidentifySpreadsheetRequestFile", + "DeidentifySpreadsheetRequestFileDataFormat", + "DeidentifyStructuredTextRequestFile", + "DeidentifyStructuredTextRequestFileDataFormat", + "DeidentifyTextRequestFile", +] diff --git a/skyflow/generated/rest/files/client.py b/skyflow/generated/rest/files/client.py new file mode 100644 index 00000000..913ccd59 --- /dev/null +++ b/skyflow/generated/rest/files/client.py @@ -0,0 +1,1547 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.request_options import RequestOptions +from ..types.allow_regex import AllowRegex +from ..types.deidentify_file_response import DeidentifyFileResponse +from ..types.deidentify_status_response import DeidentifyStatusResponse +from ..types.entity_types import EntityTypes +from ..types.resource_id import ResourceId +from ..types.restrict_regex import RestrictRegex +from ..types.token_type_without_vault import TokenTypeWithoutVault +from ..types.transformations import Transformations +from ..types.uuid_ import Uuid +from ..types.vault_id import VaultId +from .raw_client import AsyncRawFilesClient, RawFilesClient +from .types.deidentify_audio_request_file import DeidentifyAudioRequestFile +from .types.deidentify_audio_request_output_transcription import DeidentifyAudioRequestOutputTranscription +from .types.deidentify_document_request_file import DeidentifyDocumentRequestFile +from .types.deidentify_file_request_file import DeidentifyFileRequestFile +from .types.deidentify_image_request_file import DeidentifyImageRequestFile +from .types.deidentify_image_request_masking_method import DeidentifyImageRequestMaskingMethod +from .types.deidentify_pdf_request_file import DeidentifyPdfRequestFile +from .types.deidentify_presentation_request_file import DeidentifyPresentationRequestFile +from .types.deidentify_spreadsheet_request_file import DeidentifySpreadsheetRequestFile +from .types.deidentify_structured_text_request_file import DeidentifyStructuredTextRequestFile +from .types.deidentify_text_request_file import DeidentifyTextRequestFile + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class FilesClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawFilesClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawFilesClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawFilesClient + """ + return self._raw_client + + def deidentify_file( + self, + *, + vault_id: VaultId, + file: DeidentifyFileRequestFile, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> DeidentifyFileResponse: + """ + De-identifies sensitive data from a file. This operation includes options applicable to all supported file types.

For more specific options, see the category-specific operations (like De-identify Document) and the file type-specific opertions (like De-identify PDF). + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyFileRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeidentifyFileResponse + A successful response. + + Examples + -------- + 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", + ), + ) + """ + _response = self._raw_client.deidentify_file( + vault_id=vault_id, + file=file, + entity_types=entity_types, + token_type=token_type, + allow_regex=allow_regex, + restrict_regex=restrict_regex, + transformations=transformations, + request_options=request_options, + ) + return _response.data + + def deidentify_document( + self, + *, + vault_id: VaultId, + file: DeidentifyDocumentRequestFile, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> DeidentifyFileResponse: + """ + De-identifies sensitive data from a document file. This operation includes options applicable to all supported document file types.

For more specific options, see the file type-specific opertions (like De-identify PDF) where they're available. For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyDocumentRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeidentifyFileResponse + A successful response. + + Examples + -------- + 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", + ), + ) + """ + _response = self._raw_client.deidentify_document( + vault_id=vault_id, + file=file, + entity_types=entity_types, + token_type=token_type, + allow_regex=allow_regex, + restrict_regex=restrict_regex, + transformations=transformations, + request_options=request_options, + ) + return _response.data + + def deidentify_pdf( + self, + *, + vault_id: VaultId, + file: DeidentifyPdfRequestFile, + density: typing.Optional[int] = OMIT, + max_resolution: typing.Optional[int] = OMIT, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> DeidentifyFileResponse: + """ + De-identifies sensitive data from a PDF file. This operation includes options specific to PDF files.

For broader file type support, see De-identify Document and De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyPdfRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + density : typing.Optional[int] + Pixel density at which to process the PDF file. + + max_resolution : typing.Optional[int] + Max resolution at which to process the PDF file. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeidentifyFileResponse + A successful response. + + Examples + -------- + 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==", + ), + ) + """ + _response = self._raw_client.deidentify_pdf( + vault_id=vault_id, + file=file, + density=density, + max_resolution=max_resolution, + entity_types=entity_types, + token_type=token_type, + allow_regex=allow_regex, + restrict_regex=restrict_regex, + transformations=transformations, + request_options=request_options, + ) + return _response.data + + def deidentify_image( + self, + *, + vault_id: VaultId, + file: DeidentifyImageRequestFile, + output_processed_image: typing.Optional[bool] = OMIT, + output_ocr_text: typing.Optional[bool] = OMIT, + masking_method: typing.Optional[DeidentifyImageRequestMaskingMethod] = OMIT, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> DeidentifyFileResponse: + """ + De-identifies sensitive data from an image file. This operation includes options applicable to all supported image file types.

For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyImageRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + output_processed_image : typing.Optional[bool] + If `true`, includes processed image in the output. + + output_ocr_text : typing.Optional[bool] + If `true`, includes OCR text output in the response. + + masking_method : typing.Optional[DeidentifyImageRequestMaskingMethod] + Method to mask the entities in the image. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeidentifyFileResponse + A successful response. + + Examples + -------- + 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", + ), + ) + """ + _response = self._raw_client.deidentify_image( + vault_id=vault_id, + file=file, + output_processed_image=output_processed_image, + output_ocr_text=output_ocr_text, + masking_method=masking_method, + entity_types=entity_types, + token_type=token_type, + allow_regex=allow_regex, + restrict_regex=restrict_regex, + transformations=transformations, + request_options=request_options, + ) + return _response.data + + def deidentify_text( + self, + *, + vault_id: VaultId, + file: DeidentifyTextRequestFile, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> DeidentifyFileResponse: + """ + De-identifies sensitive data from a text file. This operation includes options applicable to all supported image text types.

For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyTextRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeidentifyFileResponse + A successful response. + + Examples + -------- + 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", + ), + ) + """ + _response = self._raw_client.deidentify_text( + vault_id=vault_id, + file=file, + entity_types=entity_types, + token_type=token_type, + allow_regex=allow_regex, + restrict_regex=restrict_regex, + transformations=transformations, + request_options=request_options, + ) + return _response.data + + def deidentify_structured_text( + self, + *, + vault_id: VaultId, + file: DeidentifyStructuredTextRequestFile, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> DeidentifyFileResponse: + """ + De-identifies sensitive data from a structured text file. This operation includes options applicable to all supported structured text file types.

For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyStructuredTextRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeidentifyFileResponse + A successful response. + + Examples + -------- + 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", + ), + ) + """ + _response = self._raw_client.deidentify_structured_text( + vault_id=vault_id, + file=file, + entity_types=entity_types, + token_type=token_type, + allow_regex=allow_regex, + restrict_regex=restrict_regex, + transformations=transformations, + request_options=request_options, + ) + return _response.data + + def deidentify_spreadsheet( + self, + *, + vault_id: VaultId, + file: DeidentifySpreadsheetRequestFile, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> DeidentifyFileResponse: + """ + De-identifies sensitive data from a spreadsheet file. This operation includes options applicable to all supported spreadsheet file types.

For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifySpreadsheetRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeidentifyFileResponse + A successful response. + + Examples + -------- + 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", + ), + ) + """ + _response = self._raw_client.deidentify_spreadsheet( + vault_id=vault_id, + file=file, + entity_types=entity_types, + token_type=token_type, + allow_regex=allow_regex, + restrict_regex=restrict_regex, + transformations=transformations, + request_options=request_options, + ) + return _response.data + + def deidentify_presentation( + self, + *, + vault_id: VaultId, + file: DeidentifyPresentationRequestFile, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> DeidentifyFileResponse: + """ + De-identifies sensitive data from a presentation file. This operation includes options applicable to all supported presentation file types.

For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyPresentationRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeidentifyFileResponse + A successful response. + + Examples + -------- + 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", + ), + ) + """ + _response = self._raw_client.deidentify_presentation( + vault_id=vault_id, + file=file, + entity_types=entity_types, + token_type=token_type, + allow_regex=allow_regex, + restrict_regex=restrict_regex, + transformations=transformations, + request_options=request_options, + ) + return _response.data + + def deidentify_audio( + self, + *, + vault_id: VaultId, + file: DeidentifyAudioRequestFile, + output_processed_audio: typing.Optional[bool] = OMIT, + output_transcription: typing.Optional[DeidentifyAudioRequestOutputTranscription] = OMIT, + bleep_gain: typing.Optional[float] = OMIT, + bleep_frequency: typing.Optional[float] = OMIT, + bleep_start_padding: typing.Optional[float] = OMIT, + bleep_stop_padding: typing.Optional[float] = OMIT, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> DeidentifyFileResponse: + """ + De-identifies sensitive data from an audio file. This operation includes options applicable to all supported audio file types.

For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyAudioRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + output_processed_audio : typing.Optional[bool] + If `true`, includes processed audio file in the response. + + output_transcription : typing.Optional[DeidentifyAudioRequestOutputTranscription] + Type of transcription to output. + + bleep_gain : typing.Optional[float] + Relative loudness of the bleep in dB. Positive values increase its loudness, and negative values decrease it. + + bleep_frequency : typing.Optional[float] + The pitch of the bleep sound, in Hz. The higher the number, the higher the pitch. + + bleep_start_padding : typing.Optional[float] + Padding added to the beginning of a bleep, in seconds. + + bleep_stop_padding : typing.Optional[float] + Padding added to the end of a bleep, in seconds. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeidentifyFileResponse + A successful response. + + Examples + -------- + 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", + ), + ) + """ + _response = self._raw_client.deidentify_audio( + vault_id=vault_id, + file=file, + output_processed_audio=output_processed_audio, + output_transcription=output_transcription, + bleep_gain=bleep_gain, + bleep_frequency=bleep_frequency, + bleep_start_padding=bleep_start_padding, + bleep_stop_padding=bleep_stop_padding, + entity_types=entity_types, + token_type=token_type, + allow_regex=allow_regex, + restrict_regex=restrict_regex, + transformations=transformations, + request_options=request_options, + ) + return _response.data + + def get_run( + self, run_id: Uuid, *, vault_id: ResourceId, request_options: typing.Optional[RequestOptions] = None + ) -> DeidentifyStatusResponse: + """ + Returns the status of the detect run. + + Parameters + ---------- + run_id : Uuid + ID of the detect run. + + vault_id : ResourceId + ID of the vault. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeidentifyStatusResponse + A successful response. + + Examples + -------- + from skyflow import Skyflow + + 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 + + +class AsyncFilesClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawFilesClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawFilesClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawFilesClient + """ + return self._raw_client + + async def deidentify_file( + self, + *, + vault_id: VaultId, + file: DeidentifyFileRequestFile, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> DeidentifyFileResponse: + """ + De-identifies sensitive data from a file. This operation includes options applicable to all supported file types.

For more specific options, see the category-specific operations (like De-identify Document) and the file type-specific opertions (like De-identify PDF). + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyFileRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeidentifyFileResponse + A successful response. + + Examples + -------- + import asyncio + + from skyflow import AsyncSkyflow + from skyflow.files import DeidentifyFileRequestFile + + 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", + ), + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.deidentify_file( + vault_id=vault_id, + file=file, + entity_types=entity_types, + token_type=token_type, + allow_regex=allow_regex, + restrict_regex=restrict_regex, + transformations=transformations, + request_options=request_options, + ) + return _response.data + + async def deidentify_document( + self, + *, + vault_id: VaultId, + file: DeidentifyDocumentRequestFile, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> DeidentifyFileResponse: + """ + De-identifies sensitive data from a document file. This operation includes options applicable to all supported document file types.

For more specific options, see the file type-specific opertions (like De-identify PDF) where they're available. For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyDocumentRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeidentifyFileResponse + A successful response. + + Examples + -------- + import asyncio + + from skyflow import AsyncSkyflow + from skyflow.files import DeidentifyDocumentRequestFile + + 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", + ), + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.deidentify_document( + vault_id=vault_id, + file=file, + entity_types=entity_types, + token_type=token_type, + allow_regex=allow_regex, + restrict_regex=restrict_regex, + transformations=transformations, + request_options=request_options, + ) + return _response.data + + async def deidentify_pdf( + self, + *, + vault_id: VaultId, + file: DeidentifyPdfRequestFile, + density: typing.Optional[int] = OMIT, + max_resolution: typing.Optional[int] = OMIT, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> DeidentifyFileResponse: + """ + De-identifies sensitive data from a PDF file. This operation includes options specific to PDF files.

For broader file type support, see De-identify Document and De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyPdfRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + density : typing.Optional[int] + Pixel density at which to process the PDF file. + + max_resolution : typing.Optional[int] + Max resolution at which to process the PDF file. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeidentifyFileResponse + A successful response. + + Examples + -------- + import asyncio + + from skyflow import AsyncSkyflow + from skyflow.files import DeidentifyPdfRequestFile + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.files.deidentify_pdf( + vault_id="f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b", + file=DeidentifyPdfRequestFile( + base_64="SGkgaSBhbSBEZXZhbnNodSwgbGl2...aW5nIGluIGNhbGlmb3JuaWEuIA==", + ), + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.deidentify_pdf( + vault_id=vault_id, + file=file, + density=density, + max_resolution=max_resolution, + entity_types=entity_types, + token_type=token_type, + allow_regex=allow_regex, + restrict_regex=restrict_regex, + transformations=transformations, + request_options=request_options, + ) + return _response.data + + async def deidentify_image( + self, + *, + vault_id: VaultId, + file: DeidentifyImageRequestFile, + output_processed_image: typing.Optional[bool] = OMIT, + output_ocr_text: typing.Optional[bool] = OMIT, + masking_method: typing.Optional[DeidentifyImageRequestMaskingMethod] = OMIT, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> DeidentifyFileResponse: + """ + De-identifies sensitive data from an image file. This operation includes options applicable to all supported image file types.

For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyImageRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + output_processed_image : typing.Optional[bool] + If `true`, includes processed image in the output. + + output_ocr_text : typing.Optional[bool] + If `true`, includes OCR text output in the response. + + masking_method : typing.Optional[DeidentifyImageRequestMaskingMethod] + Method to mask the entities in the image. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeidentifyFileResponse + A successful response. + + Examples + -------- + import asyncio + + from skyflow import AsyncSkyflow + from skyflow.files import DeidentifyImageRequestFile + + 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", + ), + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.deidentify_image( + vault_id=vault_id, + file=file, + output_processed_image=output_processed_image, + output_ocr_text=output_ocr_text, + masking_method=masking_method, + entity_types=entity_types, + token_type=token_type, + allow_regex=allow_regex, + restrict_regex=restrict_regex, + transformations=transformations, + request_options=request_options, + ) + return _response.data + + async def deidentify_text( + self, + *, + vault_id: VaultId, + file: DeidentifyTextRequestFile, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> DeidentifyFileResponse: + """ + De-identifies sensitive data from a text file. This operation includes options applicable to all supported image text types.

For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyTextRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeidentifyFileResponse + A successful response. + + Examples + -------- + import asyncio + + from skyflow import AsyncSkyflow + from skyflow.files import DeidentifyTextRequestFile + + client = AsyncSkyflow( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.files.deidentify_text( + vault_id="f4b3b3b33b3b3b3b3b3b3b3b3b3b3b3b", + file=DeidentifyTextRequestFile( + base_64="Zm9vYmFy", + ), + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.deidentify_text( + vault_id=vault_id, + file=file, + entity_types=entity_types, + token_type=token_type, + allow_regex=allow_regex, + restrict_regex=restrict_regex, + transformations=transformations, + request_options=request_options, + ) + return _response.data + + async def deidentify_structured_text( + self, + *, + vault_id: VaultId, + file: DeidentifyStructuredTextRequestFile, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> DeidentifyFileResponse: + """ + De-identifies sensitive data from a structured text file. This operation includes options applicable to all supported structured text file types.

For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyStructuredTextRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeidentifyFileResponse + A successful response. + + Examples + -------- + import asyncio + + from skyflow import AsyncSkyflow + from skyflow.files import DeidentifyStructuredTextRequestFile + + 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", + ), + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.deidentify_structured_text( + vault_id=vault_id, + file=file, + entity_types=entity_types, + token_type=token_type, + allow_regex=allow_regex, + restrict_regex=restrict_regex, + transformations=transformations, + request_options=request_options, + ) + return _response.data + + async def deidentify_spreadsheet( + self, + *, + vault_id: VaultId, + file: DeidentifySpreadsheetRequestFile, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> DeidentifyFileResponse: + """ + De-identifies sensitive data from a spreadsheet file. This operation includes options applicable to all supported spreadsheet file types.

For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifySpreadsheetRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeidentifyFileResponse + A successful response. + + Examples + -------- + import asyncio + + from skyflow import AsyncSkyflow + from skyflow.files import DeidentifySpreadsheetRequestFile + + 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", + ), + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.deidentify_spreadsheet( + vault_id=vault_id, + file=file, + entity_types=entity_types, + token_type=token_type, + allow_regex=allow_regex, + restrict_regex=restrict_regex, + transformations=transformations, + request_options=request_options, + ) + return _response.data + + async def deidentify_presentation( + self, + *, + vault_id: VaultId, + file: DeidentifyPresentationRequestFile, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> DeidentifyFileResponse: + """ + De-identifies sensitive data from a presentation file. This operation includes options applicable to all supported presentation file types.

For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyPresentationRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeidentifyFileResponse + A successful response. + + Examples + -------- + import asyncio + + from skyflow import AsyncSkyflow + from skyflow.files import DeidentifyPresentationRequestFile + + 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", + ), + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.deidentify_presentation( + vault_id=vault_id, + file=file, + entity_types=entity_types, + token_type=token_type, + allow_regex=allow_regex, + restrict_regex=restrict_regex, + transformations=transformations, + request_options=request_options, + ) + return _response.data + + async def deidentify_audio( + self, + *, + vault_id: VaultId, + file: DeidentifyAudioRequestFile, + output_processed_audio: typing.Optional[bool] = OMIT, + output_transcription: typing.Optional[DeidentifyAudioRequestOutputTranscription] = OMIT, + bleep_gain: typing.Optional[float] = OMIT, + bleep_frequency: typing.Optional[float] = OMIT, + bleep_start_padding: typing.Optional[float] = OMIT, + bleep_stop_padding: typing.Optional[float] = OMIT, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> DeidentifyFileResponse: + """ + De-identifies sensitive data from an audio file. This operation includes options applicable to all supported audio file types.

For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyAudioRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + output_processed_audio : typing.Optional[bool] + If `true`, includes processed audio file in the response. + + output_transcription : typing.Optional[DeidentifyAudioRequestOutputTranscription] + Type of transcription to output. + + bleep_gain : typing.Optional[float] + Relative loudness of the bleep in dB. Positive values increase its loudness, and negative values decrease it. + + bleep_frequency : typing.Optional[float] + The pitch of the bleep sound, in Hz. The higher the number, the higher the pitch. + + bleep_start_padding : typing.Optional[float] + Padding added to the beginning of a bleep, in seconds. + + bleep_stop_padding : typing.Optional[float] + Padding added to the end of a bleep, in seconds. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeidentifyFileResponse + A successful response. + + Examples + -------- + import asyncio + + from skyflow import AsyncSkyflow + from skyflow.files import DeidentifyAudioRequestFile + + 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", + ), + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.deidentify_audio( + vault_id=vault_id, + file=file, + output_processed_audio=output_processed_audio, + output_transcription=output_transcription, + bleep_gain=bleep_gain, + bleep_frequency=bleep_frequency, + bleep_start_padding=bleep_start_padding, + bleep_stop_padding=bleep_stop_padding, + entity_types=entity_types, + token_type=token_type, + allow_regex=allow_regex, + restrict_regex=restrict_regex, + transformations=transformations, + request_options=request_options, + ) + return _response.data + + async def get_run( + self, run_id: Uuid, *, vault_id: ResourceId, request_options: typing.Optional[RequestOptions] = None + ) -> DeidentifyStatusResponse: + """ + Returns the status of the detect run. + + Parameters + ---------- + run_id : Uuid + ID of the detect run. + + vault_id : ResourceId + ID of the vault. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeidentifyStatusResponse + A successful response. + + Examples + -------- + import asyncio + + 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", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_run(run_id, vault_id=vault_id, request_options=request_options) + return _response.data diff --git a/skyflow/generated/rest/files/raw_client.py b/skyflow/generated/rest/files/raw_client.py new file mode 100644 index 00000000..b3193544 --- /dev/null +++ b/skyflow/generated/rest/files/raw_client.py @@ -0,0 +1,2355 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ..core.api_error import ApiError +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.http_response import AsyncHttpResponse, HttpResponse +from ..core.jsonable_encoder import jsonable_encoder +from ..core.pydantic_utilities import parse_obj_as +from ..core.request_options import RequestOptions +from ..core.serialization import convert_and_respect_annotation_metadata +from ..errors.bad_request_error import BadRequestError +from ..errors.internal_server_error import InternalServerError +from ..errors.not_found_error import NotFoundError +from ..errors.unauthorized_error import UnauthorizedError +from ..types.allow_regex import AllowRegex +from ..types.deidentify_file_response import DeidentifyFileResponse +from ..types.deidentify_status_response import DeidentifyStatusResponse +from ..types.entity_types import EntityTypes +from ..types.error_response import ErrorResponse +from ..types.resource_id import ResourceId +from ..types.restrict_regex import RestrictRegex +from ..types.token_type_without_vault import TokenTypeWithoutVault +from ..types.transformations import Transformations +from ..types.uuid_ import Uuid +from ..types.vault_id import VaultId +from .types.deidentify_audio_request_file import DeidentifyAudioRequestFile +from .types.deidentify_audio_request_output_transcription import DeidentifyAudioRequestOutputTranscription +from .types.deidentify_document_request_file import DeidentifyDocumentRequestFile +from .types.deidentify_file_request_file import DeidentifyFileRequestFile +from .types.deidentify_image_request_file import DeidentifyImageRequestFile +from .types.deidentify_image_request_masking_method import DeidentifyImageRequestMaskingMethod +from .types.deidentify_pdf_request_file import DeidentifyPdfRequestFile +from .types.deidentify_presentation_request_file import DeidentifyPresentationRequestFile +from .types.deidentify_spreadsheet_request_file import DeidentifySpreadsheetRequestFile +from .types.deidentify_structured_text_request_file import DeidentifyStructuredTextRequestFile +from .types.deidentify_text_request_file import DeidentifyTextRequestFile + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawFilesClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def deidentify_file( + self, + *, + vault_id: VaultId, + file: DeidentifyFileRequestFile, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[DeidentifyFileResponse]: + """ + De-identifies sensitive data from a file. This operation includes options applicable to all supported file types.

For more specific options, see the category-specific operations (like De-identify Document) and the file type-specific opertions (like De-identify PDF). + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyFileRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[DeidentifyFileResponse] + A successful response. + """ + _response = self._client_wrapper.httpx_client.request( + "v1/detect/deidentify/file", + method="POST", + json={ + "vault_id": vault_id, + "file": convert_and_respect_annotation_metadata( + object_=file, annotation=DeidentifyFileRequestFile, direction="write" + ), + "entity_types": entity_types, + "token_type": convert_and_respect_annotation_metadata( + object_=token_type, annotation=TokenTypeWithoutVault, direction="write" + ), + "allow_regex": allow_regex, + "restrict_regex": restrict_regex, + "transformations": convert_and_respect_annotation_metadata( + object_=transformations, annotation=Transformations, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DeidentifyFileResponse, + parse_obj_as( + type_=DeidentifyFileResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + ErrorResponse, + parse_obj_as( + type_=ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def deidentify_document( + self, + *, + vault_id: VaultId, + file: DeidentifyDocumentRequestFile, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[DeidentifyFileResponse]: + """ + De-identifies sensitive data from a document file. This operation includes options applicable to all supported document file types.

For more specific options, see the file type-specific opertions (like De-identify PDF) where they're available. For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyDocumentRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[DeidentifyFileResponse] + A successful response. + """ + _response = self._client_wrapper.httpx_client.request( + "v1/detect/deidentify/file/document", + method="POST", + json={ + "vault_id": vault_id, + "file": convert_and_respect_annotation_metadata( + object_=file, annotation=DeidentifyDocumentRequestFile, direction="write" + ), + "entity_types": entity_types, + "token_type": convert_and_respect_annotation_metadata( + object_=token_type, annotation=TokenTypeWithoutVault, direction="write" + ), + "allow_regex": allow_regex, + "restrict_regex": restrict_regex, + "transformations": convert_and_respect_annotation_metadata( + object_=transformations, annotation=Transformations, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DeidentifyFileResponse, + parse_obj_as( + type_=DeidentifyFileResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + ErrorResponse, + parse_obj_as( + type_=ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def deidentify_pdf( + self, + *, + vault_id: VaultId, + file: DeidentifyPdfRequestFile, + density: typing.Optional[int] = OMIT, + max_resolution: typing.Optional[int] = OMIT, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[DeidentifyFileResponse]: + """ + De-identifies sensitive data from a PDF file. This operation includes options specific to PDF files.

For broader file type support, see De-identify Document and De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyPdfRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + density : typing.Optional[int] + Pixel density at which to process the PDF file. + + max_resolution : typing.Optional[int] + Max resolution at which to process the PDF file. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[DeidentifyFileResponse] + A successful response. + """ + _response = self._client_wrapper.httpx_client.request( + "v1/detect/deidentify/file/document/pdf", + method="POST", + json={ + "vault_id": vault_id, + "file": convert_and_respect_annotation_metadata( + object_=file, annotation=DeidentifyPdfRequestFile, direction="write" + ), + "density": density, + "max_resolution": max_resolution, + "entity_types": entity_types, + "token_type": convert_and_respect_annotation_metadata( + object_=token_type, annotation=TokenTypeWithoutVault, direction="write" + ), + "allow_regex": allow_regex, + "restrict_regex": restrict_regex, + "transformations": convert_and_respect_annotation_metadata( + object_=transformations, annotation=Transformations, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DeidentifyFileResponse, + parse_obj_as( + type_=DeidentifyFileResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + ErrorResponse, + parse_obj_as( + type_=ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def deidentify_image( + self, + *, + vault_id: VaultId, + file: DeidentifyImageRequestFile, + output_processed_image: typing.Optional[bool] = OMIT, + output_ocr_text: typing.Optional[bool] = OMIT, + masking_method: typing.Optional[DeidentifyImageRequestMaskingMethod] = OMIT, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[DeidentifyFileResponse]: + """ + De-identifies sensitive data from an image file. This operation includes options applicable to all supported image file types.

For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyImageRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + output_processed_image : typing.Optional[bool] + If `true`, includes processed image in the output. + + output_ocr_text : typing.Optional[bool] + If `true`, includes OCR text output in the response. + + masking_method : typing.Optional[DeidentifyImageRequestMaskingMethod] + Method to mask the entities in the image. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[DeidentifyFileResponse] + A successful response. + """ + _response = self._client_wrapper.httpx_client.request( + "v1/detect/deidentify/file/image", + method="POST", + json={ + "vault_id": vault_id, + "file": convert_and_respect_annotation_metadata( + object_=file, annotation=DeidentifyImageRequestFile, direction="write" + ), + "output_processed_image": output_processed_image, + "output_ocr_text": output_ocr_text, + "masking_method": masking_method, + "entity_types": entity_types, + "token_type": convert_and_respect_annotation_metadata( + object_=token_type, annotation=TokenTypeWithoutVault, direction="write" + ), + "allow_regex": allow_regex, + "restrict_regex": restrict_regex, + "transformations": convert_and_respect_annotation_metadata( + object_=transformations, annotation=Transformations, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DeidentifyFileResponse, + parse_obj_as( + type_=DeidentifyFileResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + ErrorResponse, + parse_obj_as( + type_=ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def deidentify_text( + self, + *, + vault_id: VaultId, + file: DeidentifyTextRequestFile, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[DeidentifyFileResponse]: + """ + De-identifies sensitive data from a text file. This operation includes options applicable to all supported image text types.

For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyTextRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[DeidentifyFileResponse] + A successful response. + """ + _response = self._client_wrapper.httpx_client.request( + "v1/detect/deidentify/file/text", + method="POST", + json={ + "vault_id": vault_id, + "file": convert_and_respect_annotation_metadata( + object_=file, annotation=DeidentifyTextRequestFile, direction="write" + ), + "entity_types": entity_types, + "token_type": convert_and_respect_annotation_metadata( + object_=token_type, annotation=TokenTypeWithoutVault, direction="write" + ), + "allow_regex": allow_regex, + "restrict_regex": restrict_regex, + "transformations": convert_and_respect_annotation_metadata( + object_=transformations, annotation=Transformations, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DeidentifyFileResponse, + parse_obj_as( + type_=DeidentifyFileResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + ErrorResponse, + parse_obj_as( + type_=ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def deidentify_structured_text( + self, + *, + vault_id: VaultId, + file: DeidentifyStructuredTextRequestFile, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[DeidentifyFileResponse]: + """ + De-identifies sensitive data from a structured text file. This operation includes options applicable to all supported structured text file types.

For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyStructuredTextRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[DeidentifyFileResponse] + A successful response. + """ + _response = self._client_wrapper.httpx_client.request( + "v1/detect/deidentify/file/structured_text", + method="POST", + json={ + "vault_id": vault_id, + "file": convert_and_respect_annotation_metadata( + object_=file, annotation=DeidentifyStructuredTextRequestFile, direction="write" + ), + "entity_types": entity_types, + "token_type": convert_and_respect_annotation_metadata( + object_=token_type, annotation=TokenTypeWithoutVault, direction="write" + ), + "allow_regex": allow_regex, + "restrict_regex": restrict_regex, + "transformations": convert_and_respect_annotation_metadata( + object_=transformations, annotation=Transformations, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DeidentifyFileResponse, + parse_obj_as( + type_=DeidentifyFileResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + ErrorResponse, + parse_obj_as( + type_=ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def deidentify_spreadsheet( + self, + *, + vault_id: VaultId, + file: DeidentifySpreadsheetRequestFile, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[DeidentifyFileResponse]: + """ + De-identifies sensitive data from a spreadsheet file. This operation includes options applicable to all supported spreadsheet file types.

For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifySpreadsheetRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[DeidentifyFileResponse] + A successful response. + """ + _response = self._client_wrapper.httpx_client.request( + "v1/detect/deidentify/file/spreadsheet", + method="POST", + json={ + "vault_id": vault_id, + "file": convert_and_respect_annotation_metadata( + object_=file, annotation=DeidentifySpreadsheetRequestFile, direction="write" + ), + "entity_types": entity_types, + "token_type": convert_and_respect_annotation_metadata( + object_=token_type, annotation=TokenTypeWithoutVault, direction="write" + ), + "allow_regex": allow_regex, + "restrict_regex": restrict_regex, + "transformations": convert_and_respect_annotation_metadata( + object_=transformations, annotation=Transformations, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DeidentifyFileResponse, + parse_obj_as( + type_=DeidentifyFileResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + ErrorResponse, + parse_obj_as( + type_=ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def deidentify_presentation( + self, + *, + vault_id: VaultId, + file: DeidentifyPresentationRequestFile, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[DeidentifyFileResponse]: + """ + De-identifies sensitive data from a presentation file. This operation includes options applicable to all supported presentation file types.

For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyPresentationRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[DeidentifyFileResponse] + A successful response. + """ + _response = self._client_wrapper.httpx_client.request( + "v1/detect/deidentify/file/presentation", + method="POST", + json={ + "vault_id": vault_id, + "file": convert_and_respect_annotation_metadata( + object_=file, annotation=DeidentifyPresentationRequestFile, direction="write" + ), + "entity_types": entity_types, + "token_type": convert_and_respect_annotation_metadata( + object_=token_type, annotation=TokenTypeWithoutVault, direction="write" + ), + "allow_regex": allow_regex, + "restrict_regex": restrict_regex, + "transformations": convert_and_respect_annotation_metadata( + object_=transformations, annotation=Transformations, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DeidentifyFileResponse, + parse_obj_as( + type_=DeidentifyFileResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + ErrorResponse, + parse_obj_as( + type_=ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def deidentify_audio( + self, + *, + vault_id: VaultId, + file: DeidentifyAudioRequestFile, + output_processed_audio: typing.Optional[bool] = OMIT, + output_transcription: typing.Optional[DeidentifyAudioRequestOutputTranscription] = OMIT, + bleep_gain: typing.Optional[float] = OMIT, + bleep_frequency: typing.Optional[float] = OMIT, + bleep_start_padding: typing.Optional[float] = OMIT, + bleep_stop_padding: typing.Optional[float] = OMIT, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[DeidentifyFileResponse]: + """ + De-identifies sensitive data from an audio file. This operation includes options applicable to all supported audio file types.

For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyAudioRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + output_processed_audio : typing.Optional[bool] + If `true`, includes processed audio file in the response. + + output_transcription : typing.Optional[DeidentifyAudioRequestOutputTranscription] + Type of transcription to output. + + bleep_gain : typing.Optional[float] + Relative loudness of the bleep in dB. Positive values increase its loudness, and negative values decrease it. + + bleep_frequency : typing.Optional[float] + The pitch of the bleep sound, in Hz. The higher the number, the higher the pitch. + + bleep_start_padding : typing.Optional[float] + Padding added to the beginning of a bleep, in seconds. + + bleep_stop_padding : typing.Optional[float] + Padding added to the end of a bleep, in seconds. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[DeidentifyFileResponse] + A successful response. + """ + _response = self._client_wrapper.httpx_client.request( + "v1/detect/deidentify/file/audio", + method="POST", + json={ + "vault_id": vault_id, + "file": convert_and_respect_annotation_metadata( + object_=file, annotation=DeidentifyAudioRequestFile, direction="write" + ), + "output_processed_audio": output_processed_audio, + "output_transcription": output_transcription, + "bleep_gain": bleep_gain, + "bleep_frequency": bleep_frequency, + "bleep_start_padding": bleep_start_padding, + "bleep_stop_padding": bleep_stop_padding, + "entity_types": entity_types, + "token_type": convert_and_respect_annotation_metadata( + object_=token_type, annotation=TokenTypeWithoutVault, direction="write" + ), + "allow_regex": allow_regex, + "restrict_regex": restrict_regex, + "transformations": convert_and_respect_annotation_metadata( + object_=transformations, annotation=Transformations, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DeidentifyFileResponse, + parse_obj_as( + type_=DeidentifyFileResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + ErrorResponse, + parse_obj_as( + type_=ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def get_run( + self, run_id: Uuid, *, vault_id: ResourceId, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[DeidentifyStatusResponse]: + """ + Returns the status of the detect run. + + Parameters + ---------- + run_id : Uuid + ID of the detect run. + + vault_id : ResourceId + ID of the vault. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[DeidentifyStatusResponse] + A successful response. + """ + _response = self._client_wrapper.httpx_client.request( + f"v1/detect/runs/{jsonable_encoder(run_id)}", + method="GET", + params={ + "vault_id": vault_id, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DeidentifyStatusResponse, + parse_obj_as( + type_=DeidentifyStatusResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + ErrorResponse, + parse_obj_as( + type_=ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + +class AsyncRawFilesClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def deidentify_file( + self, + *, + vault_id: VaultId, + file: DeidentifyFileRequestFile, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[DeidentifyFileResponse]: + """ + De-identifies sensitive data from a file. This operation includes options applicable to all supported file types.

For more specific options, see the category-specific operations (like De-identify Document) and the file type-specific opertions (like De-identify PDF). + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyFileRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[DeidentifyFileResponse] + A successful response. + """ + _response = await self._client_wrapper.httpx_client.request( + "v1/detect/deidentify/file", + method="POST", + json={ + "vault_id": vault_id, + "file": convert_and_respect_annotation_metadata( + object_=file, annotation=DeidentifyFileRequestFile, direction="write" + ), + "entity_types": entity_types, + "token_type": convert_and_respect_annotation_metadata( + object_=token_type, annotation=TokenTypeWithoutVault, direction="write" + ), + "allow_regex": allow_regex, + "restrict_regex": restrict_regex, + "transformations": convert_and_respect_annotation_metadata( + object_=transformations, annotation=Transformations, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DeidentifyFileResponse, + parse_obj_as( + type_=DeidentifyFileResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + ErrorResponse, + parse_obj_as( + type_=ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def deidentify_document( + self, + *, + vault_id: VaultId, + file: DeidentifyDocumentRequestFile, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[DeidentifyFileResponse]: + """ + De-identifies sensitive data from a document file. This operation includes options applicable to all supported document file types.

For more specific options, see the file type-specific opertions (like De-identify PDF) where they're available. For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyDocumentRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[DeidentifyFileResponse] + A successful response. + """ + _response = await self._client_wrapper.httpx_client.request( + "v1/detect/deidentify/file/document", + method="POST", + json={ + "vault_id": vault_id, + "file": convert_and_respect_annotation_metadata( + object_=file, annotation=DeidentifyDocumentRequestFile, direction="write" + ), + "entity_types": entity_types, + "token_type": convert_and_respect_annotation_metadata( + object_=token_type, annotation=TokenTypeWithoutVault, direction="write" + ), + "allow_regex": allow_regex, + "restrict_regex": restrict_regex, + "transformations": convert_and_respect_annotation_metadata( + object_=transformations, annotation=Transformations, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DeidentifyFileResponse, + parse_obj_as( + type_=DeidentifyFileResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + ErrorResponse, + parse_obj_as( + type_=ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def deidentify_pdf( + self, + *, + vault_id: VaultId, + file: DeidentifyPdfRequestFile, + density: typing.Optional[int] = OMIT, + max_resolution: typing.Optional[int] = OMIT, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[DeidentifyFileResponse]: + """ + De-identifies sensitive data from a PDF file. This operation includes options specific to PDF files.

For broader file type support, see De-identify Document and De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyPdfRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + density : typing.Optional[int] + Pixel density at which to process the PDF file. + + max_resolution : typing.Optional[int] + Max resolution at which to process the PDF file. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[DeidentifyFileResponse] + A successful response. + """ + _response = await self._client_wrapper.httpx_client.request( + "v1/detect/deidentify/file/document/pdf", + method="POST", + json={ + "vault_id": vault_id, + "file": convert_and_respect_annotation_metadata( + object_=file, annotation=DeidentifyPdfRequestFile, direction="write" + ), + "density": density, + "max_resolution": max_resolution, + "entity_types": entity_types, + "token_type": convert_and_respect_annotation_metadata( + object_=token_type, annotation=TokenTypeWithoutVault, direction="write" + ), + "allow_regex": allow_regex, + "restrict_regex": restrict_regex, + "transformations": convert_and_respect_annotation_metadata( + object_=transformations, annotation=Transformations, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DeidentifyFileResponse, + parse_obj_as( + type_=DeidentifyFileResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + ErrorResponse, + parse_obj_as( + type_=ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def deidentify_image( + self, + *, + vault_id: VaultId, + file: DeidentifyImageRequestFile, + output_processed_image: typing.Optional[bool] = OMIT, + output_ocr_text: typing.Optional[bool] = OMIT, + masking_method: typing.Optional[DeidentifyImageRequestMaskingMethod] = OMIT, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[DeidentifyFileResponse]: + """ + De-identifies sensitive data from an image file. This operation includes options applicable to all supported image file types.

For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyImageRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + output_processed_image : typing.Optional[bool] + If `true`, includes processed image in the output. + + output_ocr_text : typing.Optional[bool] + If `true`, includes OCR text output in the response. + + masking_method : typing.Optional[DeidentifyImageRequestMaskingMethod] + Method to mask the entities in the image. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[DeidentifyFileResponse] + A successful response. + """ + _response = await self._client_wrapper.httpx_client.request( + "v1/detect/deidentify/file/image", + method="POST", + json={ + "vault_id": vault_id, + "file": convert_and_respect_annotation_metadata( + object_=file, annotation=DeidentifyImageRequestFile, direction="write" + ), + "output_processed_image": output_processed_image, + "output_ocr_text": output_ocr_text, + "masking_method": masking_method, + "entity_types": entity_types, + "token_type": convert_and_respect_annotation_metadata( + object_=token_type, annotation=TokenTypeWithoutVault, direction="write" + ), + "allow_regex": allow_regex, + "restrict_regex": restrict_regex, + "transformations": convert_and_respect_annotation_metadata( + object_=transformations, annotation=Transformations, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DeidentifyFileResponse, + parse_obj_as( + type_=DeidentifyFileResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + ErrorResponse, + parse_obj_as( + type_=ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def deidentify_text( + self, + *, + vault_id: VaultId, + file: DeidentifyTextRequestFile, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[DeidentifyFileResponse]: + """ + De-identifies sensitive data from a text file. This operation includes options applicable to all supported image text types.

For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyTextRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[DeidentifyFileResponse] + A successful response. + """ + _response = await self._client_wrapper.httpx_client.request( + "v1/detect/deidentify/file/text", + method="POST", + json={ + "vault_id": vault_id, + "file": convert_and_respect_annotation_metadata( + object_=file, annotation=DeidentifyTextRequestFile, direction="write" + ), + "entity_types": entity_types, + "token_type": convert_and_respect_annotation_metadata( + object_=token_type, annotation=TokenTypeWithoutVault, direction="write" + ), + "allow_regex": allow_regex, + "restrict_regex": restrict_regex, + "transformations": convert_and_respect_annotation_metadata( + object_=transformations, annotation=Transformations, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DeidentifyFileResponse, + parse_obj_as( + type_=DeidentifyFileResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + ErrorResponse, + parse_obj_as( + type_=ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def deidentify_structured_text( + self, + *, + vault_id: VaultId, + file: DeidentifyStructuredTextRequestFile, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[DeidentifyFileResponse]: + """ + De-identifies sensitive data from a structured text file. This operation includes options applicable to all supported structured text file types.

For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyStructuredTextRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[DeidentifyFileResponse] + A successful response. + """ + _response = await self._client_wrapper.httpx_client.request( + "v1/detect/deidentify/file/structured_text", + method="POST", + json={ + "vault_id": vault_id, + "file": convert_and_respect_annotation_metadata( + object_=file, annotation=DeidentifyStructuredTextRequestFile, direction="write" + ), + "entity_types": entity_types, + "token_type": convert_and_respect_annotation_metadata( + object_=token_type, annotation=TokenTypeWithoutVault, direction="write" + ), + "allow_regex": allow_regex, + "restrict_regex": restrict_regex, + "transformations": convert_and_respect_annotation_metadata( + object_=transformations, annotation=Transformations, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DeidentifyFileResponse, + parse_obj_as( + type_=DeidentifyFileResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + ErrorResponse, + parse_obj_as( + type_=ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def deidentify_spreadsheet( + self, + *, + vault_id: VaultId, + file: DeidentifySpreadsheetRequestFile, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[DeidentifyFileResponse]: + """ + De-identifies sensitive data from a spreadsheet file. This operation includes options applicable to all supported spreadsheet file types.

For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifySpreadsheetRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[DeidentifyFileResponse] + A successful response. + """ + _response = await self._client_wrapper.httpx_client.request( + "v1/detect/deidentify/file/spreadsheet", + method="POST", + json={ + "vault_id": vault_id, + "file": convert_and_respect_annotation_metadata( + object_=file, annotation=DeidentifySpreadsheetRequestFile, direction="write" + ), + "entity_types": entity_types, + "token_type": convert_and_respect_annotation_metadata( + object_=token_type, annotation=TokenTypeWithoutVault, direction="write" + ), + "allow_regex": allow_regex, + "restrict_regex": restrict_regex, + "transformations": convert_and_respect_annotation_metadata( + object_=transformations, annotation=Transformations, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DeidentifyFileResponse, + parse_obj_as( + type_=DeidentifyFileResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + ErrorResponse, + parse_obj_as( + type_=ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def deidentify_presentation( + self, + *, + vault_id: VaultId, + file: DeidentifyPresentationRequestFile, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[DeidentifyFileResponse]: + """ + De-identifies sensitive data from a presentation file. This operation includes options applicable to all supported presentation file types.

For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyPresentationRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[DeidentifyFileResponse] + A successful response. + """ + _response = await self._client_wrapper.httpx_client.request( + "v1/detect/deidentify/file/presentation", + method="POST", + json={ + "vault_id": vault_id, + "file": convert_and_respect_annotation_metadata( + object_=file, annotation=DeidentifyPresentationRequestFile, direction="write" + ), + "entity_types": entity_types, + "token_type": convert_and_respect_annotation_metadata( + object_=token_type, annotation=TokenTypeWithoutVault, direction="write" + ), + "allow_regex": allow_regex, + "restrict_regex": restrict_regex, + "transformations": convert_and_respect_annotation_metadata( + object_=transformations, annotation=Transformations, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DeidentifyFileResponse, + parse_obj_as( + type_=DeidentifyFileResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + ErrorResponse, + parse_obj_as( + type_=ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def deidentify_audio( + self, + *, + vault_id: VaultId, + file: DeidentifyAudioRequestFile, + output_processed_audio: typing.Optional[bool] = OMIT, + output_transcription: typing.Optional[DeidentifyAudioRequestOutputTranscription] = OMIT, + bleep_gain: typing.Optional[float] = OMIT, + bleep_frequency: typing.Optional[float] = OMIT, + bleep_start_padding: typing.Optional[float] = OMIT, + bleep_stop_padding: typing.Optional[float] = OMIT, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenTypeWithoutVault] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[DeidentifyFileResponse]: + """ + De-identifies sensitive data from an audio file. This operation includes options applicable to all supported audio file types.

For broader file type support, see De-identify File. + + Parameters + ---------- + vault_id : VaultId + + file : DeidentifyAudioRequestFile + File to de-identify. Files are specified as Base64-encoded data. + + output_processed_audio : typing.Optional[bool] + If `true`, includes processed audio file in the response. + + output_transcription : typing.Optional[DeidentifyAudioRequestOutputTranscription] + Type of transcription to output. + + bleep_gain : typing.Optional[float] + Relative loudness of the bleep in dB. Positive values increase its loudness, and negative values decrease it. + + bleep_frequency : typing.Optional[float] + The pitch of the bleep sound, in Hz. The higher the number, the higher the pitch. + + bleep_start_padding : typing.Optional[float] + Padding added to the beginning of a bleep, in seconds. + + bleep_stop_padding : typing.Optional[float] + Padding added to the end of a bleep, in seconds. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenTypeWithoutVault] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[DeidentifyFileResponse] + A successful response. + """ + _response = await self._client_wrapper.httpx_client.request( + "v1/detect/deidentify/file/audio", + method="POST", + json={ + "vault_id": vault_id, + "file": convert_and_respect_annotation_metadata( + object_=file, annotation=DeidentifyAudioRequestFile, direction="write" + ), + "output_processed_audio": output_processed_audio, + "output_transcription": output_transcription, + "bleep_gain": bleep_gain, + "bleep_frequency": bleep_frequency, + "bleep_start_padding": bleep_start_padding, + "bleep_stop_padding": bleep_stop_padding, + "entity_types": entity_types, + "token_type": convert_and_respect_annotation_metadata( + object_=token_type, annotation=TokenTypeWithoutVault, direction="write" + ), + "allow_regex": allow_regex, + "restrict_regex": restrict_regex, + "transformations": convert_and_respect_annotation_metadata( + object_=transformations, annotation=Transformations, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DeidentifyFileResponse, + parse_obj_as( + type_=DeidentifyFileResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + ErrorResponse, + parse_obj_as( + type_=ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def get_run( + self, run_id: Uuid, *, vault_id: ResourceId, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[DeidentifyStatusResponse]: + """ + Returns the status of the detect run. + + Parameters + ---------- + run_id : Uuid + ID of the detect run. + + vault_id : ResourceId + ID of the vault. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[DeidentifyStatusResponse] + A successful response. + """ + _response = await self._client_wrapper.httpx_client.request( + f"v1/detect/runs/{jsonable_encoder(run_id)}", + method="GET", + params={ + "vault_id": vault_id, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DeidentifyStatusResponse, + parse_obj_as( + type_=DeidentifyStatusResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + ErrorResponse, + parse_obj_as( + type_=ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) diff --git a/skyflow/generated/rest/files/types/__init__.py b/skyflow/generated/rest/files/types/__init__.py new file mode 100644 index 00000000..e6343d60 --- /dev/null +++ b/skyflow/generated/rest/files/types/__init__.py @@ -0,0 +1,43 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +from .deidentify_audio_request_file import DeidentifyAudioRequestFile +from .deidentify_audio_request_file_data_format import DeidentifyAudioRequestFileDataFormat +from .deidentify_audio_request_output_transcription import DeidentifyAudioRequestOutputTranscription +from .deidentify_document_request_file import DeidentifyDocumentRequestFile +from .deidentify_document_request_file_data_format import DeidentifyDocumentRequestFileDataFormat +from .deidentify_file_request_file import DeidentifyFileRequestFile +from .deidentify_file_request_file_data_format import DeidentifyFileRequestFileDataFormat +from .deidentify_image_request_file import DeidentifyImageRequestFile +from .deidentify_image_request_file_data_format import DeidentifyImageRequestFileDataFormat +from .deidentify_image_request_masking_method import DeidentifyImageRequestMaskingMethod +from .deidentify_pdf_request_file import DeidentifyPdfRequestFile +from .deidentify_presentation_request_file import DeidentifyPresentationRequestFile +from .deidentify_presentation_request_file_data_format import DeidentifyPresentationRequestFileDataFormat +from .deidentify_spreadsheet_request_file import DeidentifySpreadsheetRequestFile +from .deidentify_spreadsheet_request_file_data_format import DeidentifySpreadsheetRequestFileDataFormat +from .deidentify_structured_text_request_file import DeidentifyStructuredTextRequestFile +from .deidentify_structured_text_request_file_data_format import DeidentifyStructuredTextRequestFileDataFormat +from .deidentify_text_request_file import DeidentifyTextRequestFile + +__all__ = [ + "DeidentifyAudioRequestFile", + "DeidentifyAudioRequestFileDataFormat", + "DeidentifyAudioRequestOutputTranscription", + "DeidentifyDocumentRequestFile", + "DeidentifyDocumentRequestFileDataFormat", + "DeidentifyFileRequestFile", + "DeidentifyFileRequestFileDataFormat", + "DeidentifyImageRequestFile", + "DeidentifyImageRequestFileDataFormat", + "DeidentifyImageRequestMaskingMethod", + "DeidentifyPdfRequestFile", + "DeidentifyPresentationRequestFile", + "DeidentifyPresentationRequestFileDataFormat", + "DeidentifySpreadsheetRequestFile", + "DeidentifySpreadsheetRequestFileDataFormat", + "DeidentifyStructuredTextRequestFile", + "DeidentifyStructuredTextRequestFileDataFormat", + "DeidentifyTextRequestFile", +] diff --git a/skyflow/generated/rest/files/types/deidentify_audio_request_file.py b/skyflow/generated/rest/files/types/deidentify_audio_request_file.py new file mode 100644 index 00000000..3ea4c16f --- /dev/null +++ b/skyflow/generated/rest/files/types/deidentify_audio_request_file.py @@ -0,0 +1,34 @@ +# 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 +from .deidentify_audio_request_file_data_format import DeidentifyAudioRequestFileDataFormat + + +class DeidentifyAudioRequestFile(UniversalBaseModel): + """ + File to de-identify. Files are specified as Base64-encoded data. + """ + + base_64: typing_extensions.Annotated[str, FieldMetadata(alias="base64")] = pydantic.Field() + """ + Base64-encoded data of the file to de-identify. + """ + + data_format: DeidentifyAudioRequestFileDataFormat = pydantic.Field() + """ + Data format of the file. + """ + + 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/files/types/deidentify_audio_request_file_data_format.py b/skyflow/generated/rest/files/types/deidentify_audio_request_file_data_format.py new file mode 100644 index 00000000..85f60bbb --- /dev/null +++ b/skyflow/generated/rest/files/types/deidentify_audio_request_file_data_format.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +DeidentifyAudioRequestFileDataFormat = typing.Union[typing.Literal["mp3", "wav"], typing.Any] diff --git a/skyflow/generated/rest/files/types/deidentify_audio_request_output_transcription.py b/skyflow/generated/rest/files/types/deidentify_audio_request_output_transcription.py new file mode 100644 index 00000000..4588b1d1 --- /dev/null +++ b/skyflow/generated/rest/files/types/deidentify_audio_request_output_transcription.py @@ -0,0 +1,14 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +DeidentifyAudioRequestOutputTranscription = typing.Union[ + typing.Literal[ + "diarized_transcription", + "medical_diarized_transcription", + "medical_transcription", + "plaintext_transcription", + "transcription", + ], + typing.Any, +] diff --git a/skyflow/generated/rest/files/types/deidentify_document_request_file.py b/skyflow/generated/rest/files/types/deidentify_document_request_file.py new file mode 100644 index 00000000..cbf36c59 --- /dev/null +++ b/skyflow/generated/rest/files/types/deidentify_document_request_file.py @@ -0,0 +1,34 @@ +# 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 +from .deidentify_document_request_file_data_format import DeidentifyDocumentRequestFileDataFormat + + +class DeidentifyDocumentRequestFile(UniversalBaseModel): + """ + File to de-identify. Files are specified as Base64-encoded data. + """ + + base_64: typing_extensions.Annotated[str, FieldMetadata(alias="base64")] = pydantic.Field() + """ + Base64-encoded data of the file to de-identify. + """ + + data_format: DeidentifyDocumentRequestFileDataFormat = pydantic.Field() + """ + Data format of the file. + """ + + 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/files/types/deidentify_document_request_file_data_format.py b/skyflow/generated/rest/files/types/deidentify_document_request_file_data_format.py new file mode 100644 index 00000000..a20f4fd8 --- /dev/null +++ b/skyflow/generated/rest/files/types/deidentify_document_request_file_data_format.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +DeidentifyDocumentRequestFileDataFormat = typing.Union[typing.Literal["doc", "docx", "pdf"], typing.Any] diff --git a/skyflow/generated/rest/files/types/deidentify_file_request_file.py b/skyflow/generated/rest/files/types/deidentify_file_request_file.py new file mode 100644 index 00000000..3e062bb2 --- /dev/null +++ b/skyflow/generated/rest/files/types/deidentify_file_request_file.py @@ -0,0 +1,34 @@ +# 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 +from .deidentify_file_request_file_data_format import DeidentifyFileRequestFileDataFormat + + +class DeidentifyFileRequestFile(UniversalBaseModel): + """ + File to de-identify. Files are specified as Base64-encoded data. + """ + + base_64: typing_extensions.Annotated[str, FieldMetadata(alias="base64")] = pydantic.Field() + """ + Base64-encoded data of the file to de-identify. + """ + + data_format: DeidentifyFileRequestFileDataFormat = pydantic.Field() + """ + Data format of the file. + """ + + 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/files/types/deidentify_file_request_file_data_format.py b/skyflow/generated/rest/files/types/deidentify_file_request_file_data_format.py new file mode 100644 index 00000000..20581451 --- /dev/null +++ b/skyflow/generated/rest/files/types/deidentify_file_request_file_data_format.py @@ -0,0 +1,28 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +DeidentifyFileRequestFileDataFormat = typing.Union[ + typing.Literal[ + "bmp", + "csv", + "doc", + "docx", + "jpeg", + "jpg", + "json", + "mp3", + "pdf", + "png", + "ppt", + "pptx", + "tif", + "tiff", + "txt", + "wav", + "xls", + "xlsx", + "xml", + ], + typing.Any, +] diff --git a/skyflow/generated/rest/files/types/deidentify_image_request_file.py b/skyflow/generated/rest/files/types/deidentify_image_request_file.py new file mode 100644 index 00000000..36677964 --- /dev/null +++ b/skyflow/generated/rest/files/types/deidentify_image_request_file.py @@ -0,0 +1,34 @@ +# 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 +from .deidentify_image_request_file_data_format import DeidentifyImageRequestFileDataFormat + + +class DeidentifyImageRequestFile(UniversalBaseModel): + """ + File to de-identify. Files are specified as Base64-encoded data. + """ + + base_64: typing_extensions.Annotated[str, FieldMetadata(alias="base64")] = pydantic.Field() + """ + Base64-encoded data of the file to de-identify. + """ + + data_format: DeidentifyImageRequestFileDataFormat = pydantic.Field() + """ + Data format of the file. + """ + + 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/files/types/deidentify_image_request_file_data_format.py b/skyflow/generated/rest/files/types/deidentify_image_request_file_data_format.py new file mode 100644 index 00000000..a2ca8f2a --- /dev/null +++ b/skyflow/generated/rest/files/types/deidentify_image_request_file_data_format.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +DeidentifyImageRequestFileDataFormat = typing.Union[ + typing.Literal["bmp", "jpeg", "jpg", "png", "tif", "tiff"], typing.Any +] diff --git a/skyflow/generated/rest/files/types/deidentify_image_request_masking_method.py b/skyflow/generated/rest/files/types/deidentify_image_request_masking_method.py new file mode 100644 index 00000000..d1ff8c83 --- /dev/null +++ b/skyflow/generated/rest/files/types/deidentify_image_request_masking_method.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +DeidentifyImageRequestMaskingMethod = typing.Union[typing.Literal["blackout", "blur"], typing.Any] diff --git a/skyflow/generated/rest/files/types/deidentify_pdf_request_file.py b/skyflow/generated/rest/files/types/deidentify_pdf_request_file.py new file mode 100644 index 00000000..da461fd1 --- /dev/null +++ b/skyflow/generated/rest/files/types/deidentify_pdf_request_file.py @@ -0,0 +1,33 @@ +# 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 DeidentifyPdfRequestFile(UniversalBaseModel): + """ + File to de-identify. Files are specified as Base64-encoded data. + """ + + base_64: typing_extensions.Annotated[str, FieldMetadata(alias="base64")] = pydantic.Field() + """ + Base64-encoded data of the file to de-identify. + """ + + data_format: typing.Literal["pdf"] = pydantic.Field(default="pdf") + """ + Data format of the file. + """ + + 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/files/types/deidentify_presentation_request_file.py b/skyflow/generated/rest/files/types/deidentify_presentation_request_file.py new file mode 100644 index 00000000..c618ccc1 --- /dev/null +++ b/skyflow/generated/rest/files/types/deidentify_presentation_request_file.py @@ -0,0 +1,34 @@ +# 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 +from .deidentify_presentation_request_file_data_format import DeidentifyPresentationRequestFileDataFormat + + +class DeidentifyPresentationRequestFile(UniversalBaseModel): + """ + File to de-identify. Files are specified as Base64-encoded data. + """ + + base_64: typing_extensions.Annotated[str, FieldMetadata(alias="base64")] = pydantic.Field() + """ + Base64-encoded data of the file to de-identify. + """ + + data_format: DeidentifyPresentationRequestFileDataFormat = pydantic.Field() + """ + Data format of the file. + """ + + 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/files/types/deidentify_presentation_request_file_data_format.py b/skyflow/generated/rest/files/types/deidentify_presentation_request_file_data_format.py new file mode 100644 index 00000000..d09f42f8 --- /dev/null +++ b/skyflow/generated/rest/files/types/deidentify_presentation_request_file_data_format.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +DeidentifyPresentationRequestFileDataFormat = typing.Union[typing.Literal["ppt", "pptx"], typing.Any] diff --git a/skyflow/generated/rest/files/types/deidentify_spreadsheet_request_file.py b/skyflow/generated/rest/files/types/deidentify_spreadsheet_request_file.py new file mode 100644 index 00000000..f97e1c03 --- /dev/null +++ b/skyflow/generated/rest/files/types/deidentify_spreadsheet_request_file.py @@ -0,0 +1,34 @@ +# 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 +from .deidentify_spreadsheet_request_file_data_format import DeidentifySpreadsheetRequestFileDataFormat + + +class DeidentifySpreadsheetRequestFile(UniversalBaseModel): + """ + File to de-identify. Files are specified as Base64-encoded data. + """ + + base_64: typing_extensions.Annotated[str, FieldMetadata(alias="base64")] = pydantic.Field() + """ + Base64-encoded data of the file to de-identify. + """ + + data_format: DeidentifySpreadsheetRequestFileDataFormat = pydantic.Field() + """ + Data format of the file. + """ + + 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/files/types/deidentify_spreadsheet_request_file_data_format.py b/skyflow/generated/rest/files/types/deidentify_spreadsheet_request_file_data_format.py new file mode 100644 index 00000000..20db2856 --- /dev/null +++ b/skyflow/generated/rest/files/types/deidentify_spreadsheet_request_file_data_format.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +DeidentifySpreadsheetRequestFileDataFormat = typing.Union[typing.Literal["csv", "xls", "xlsx"], typing.Any] diff --git a/skyflow/generated/rest/files/types/deidentify_structured_text_request_file.py b/skyflow/generated/rest/files/types/deidentify_structured_text_request_file.py new file mode 100644 index 00000000..aa2d0834 --- /dev/null +++ b/skyflow/generated/rest/files/types/deidentify_structured_text_request_file.py @@ -0,0 +1,34 @@ +# 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 +from .deidentify_structured_text_request_file_data_format import DeidentifyStructuredTextRequestFileDataFormat + + +class DeidentifyStructuredTextRequestFile(UniversalBaseModel): + """ + File to de-identify. Files are specified as Base64-encoded data. + """ + + base_64: typing_extensions.Annotated[str, FieldMetadata(alias="base64")] = pydantic.Field() + """ + Base64-encoded data of the file to de-identify. + """ + + data_format: DeidentifyStructuredTextRequestFileDataFormat = pydantic.Field() + """ + Data format of the file. + """ + + 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/files/types/deidentify_structured_text_request_file_data_format.py b/skyflow/generated/rest/files/types/deidentify_structured_text_request_file_data_format.py new file mode 100644 index 00000000..f956fe48 --- /dev/null +++ b/skyflow/generated/rest/files/types/deidentify_structured_text_request_file_data_format.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +DeidentifyStructuredTextRequestFileDataFormat = typing.Union[typing.Literal["json", "xml"], typing.Any] diff --git a/skyflow/generated/rest/files/types/deidentify_text_request_file.py b/skyflow/generated/rest/files/types/deidentify_text_request_file.py new file mode 100644 index 00000000..193aa7bd --- /dev/null +++ b/skyflow/generated/rest/files/types/deidentify_text_request_file.py @@ -0,0 +1,33 @@ +# 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 DeidentifyTextRequestFile(UniversalBaseModel): + """ + File to de-identify. Files are specified as Base64-encoded data. + """ + + base_64: typing_extensions.Annotated[str, FieldMetadata(alias="base64")] = pydantic.Field() + """ + Base64-encoded data of the file to de-identify. + """ + + data_format: typing.Literal["txt"] = pydantic.Field(default="txt") + """ + Data format of the file. + """ + + 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/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/query/raw_client.py b/skyflow/generated/rest/query/raw_client.py index 897d1e2d..5450e1bf 100644 --- a/skyflow/generated/rest/query/raw_client.py +++ b/skyflow/generated/rest/query/raw_client.py @@ -72,9 +72,9 @@ def query_service_execute_query( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -141,9 +141,9 @@ async def query_service_execute_query( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), 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 55b874c6..e2bfdc92 100644 --- a/skyflow/generated/rest/records/raw_client.py +++ b/skyflow/generated/rest/records/raw_client.py @@ -98,9 +98,9 @@ def record_service_batch_operation( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -207,9 +207,9 @@ def record_service_bulk_get_record( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -296,9 +296,9 @@ def record_service_insert_record( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -364,9 +364,9 @@ def record_service_bulk_delete_record( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -447,9 +447,9 @@ def record_service_get_record( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -529,9 +529,9 @@ def record_service_update_record( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -585,9 +585,9 @@ def record_service_delete_record( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -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: @@ -655,9 +662,9 @@ def file_service_upload_file( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -720,9 +727,9 @@ def file_service_delete_file( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -785,9 +792,9 @@ def file_service_get_file_scan_status( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -865,9 +872,9 @@ async def record_service_batch_operation( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -974,9 +981,9 @@ async def record_service_bulk_get_record( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -1063,9 +1070,9 @@ async def record_service_insert_record( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -1131,9 +1138,9 @@ async def record_service_bulk_delete_record( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -1214,9 +1221,9 @@ async def record_service_get_record( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -1296,9 +1303,9 @@ async def record_service_update_record( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -1352,9 +1359,9 @@ async def record_service_delete_record( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -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: @@ -1422,9 +1436,9 @@ async def file_service_upload_file( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -1487,9 +1501,9 @@ async def file_service_delete_file( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -1552,9 +1566,9 @@ async def file_service_get_file_scan_status( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), diff --git a/skyflow/generated/rest/strings/__init__.py b/skyflow/generated/rest/strings/__init__.py new file mode 100644 index 00000000..4cabb7fb --- /dev/null +++ b/skyflow/generated/rest/strings/__init__.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +from .types import ReidentifyStringRequestFormat + +__all__ = ["ReidentifyStringRequestFormat"] diff --git a/skyflow/generated/rest/strings/client.py b/skyflow/generated/rest/strings/client.py new file mode 100644 index 00000000..5c71662d --- /dev/null +++ b/skyflow/generated/rest/strings/client.py @@ -0,0 +1,289 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.request_options import RequestOptions +from ..types.allow_regex import AllowRegex +from ..types.deidentify_string_response import DeidentifyStringResponse +from ..types.entity_types import EntityTypes +from ..types.reidentify_string_response import ReidentifyStringResponse +from ..types.restrict_regex import RestrictRegex +from ..types.token_type import TokenType +from ..types.transformations import Transformations +from ..types.vault_id import VaultId +from .raw_client import AsyncRawStringsClient, RawStringsClient +from .types.reidentify_string_request_format import ReidentifyStringRequestFormat + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class StringsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawStringsClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawStringsClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawStringsClient + """ + return self._raw_client + + def deidentify_string( + self, + *, + vault_id: VaultId, + text: str, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenType] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> DeidentifyStringResponse: + """ + De-identifies sensitive data from a string. + + Parameters + ---------- + vault_id : VaultId + + text : str + String to de-identify. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenType] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeidentifyStringResponse + A successful response. + + 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.", + ) + """ + _response = self._raw_client.deidentify_string( + vault_id=vault_id, + text=text, + entity_types=entity_types, + token_type=token_type, + allow_regex=allow_regex, + restrict_regex=restrict_regex, + transformations=transformations, + request_options=request_options, + ) + return _response.data + + def reidentify_string( + self, + *, + text: str, + vault_id: str, + format: typing.Optional[ReidentifyStringRequestFormat] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> ReidentifyStringResponse: + """ + Re-identifies tokens in a string. + + Parameters + ---------- + text : str + String to re-identify. + + vault_id : str + ID of the vault where the entities are stored. + + format : typing.Optional[ReidentifyStringRequestFormat] + Mapping of perferred data formatting options to entity types. Returned values are dependent on the configuration of the vault storing the data and the permissions of the user or account making the request. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ReidentifyStringResponse + A successful response. + + 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", + ) + """ + _response = self._raw_client.reidentify_string( + text=text, vault_id=vault_id, format=format, request_options=request_options + ) + return _response.data + + +class AsyncStringsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawStringsClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawStringsClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawStringsClient + """ + return self._raw_client + + async def deidentify_string( + self, + *, + vault_id: VaultId, + text: str, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenType] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> DeidentifyStringResponse: + """ + De-identifies sensitive data from a string. + + Parameters + ---------- + vault_id : VaultId + + text : str + String to de-identify. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenType] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeidentifyStringResponse + A successful response. + + Examples + -------- + import asyncio + + 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.", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.deidentify_string( + vault_id=vault_id, + text=text, + entity_types=entity_types, + token_type=token_type, + allow_regex=allow_regex, + restrict_regex=restrict_regex, + transformations=transformations, + request_options=request_options, + ) + return _response.data + + async def reidentify_string( + self, + *, + text: str, + vault_id: str, + format: typing.Optional[ReidentifyStringRequestFormat] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> ReidentifyStringResponse: + """ + Re-identifies tokens in a string. + + Parameters + ---------- + text : str + String to re-identify. + + vault_id : str + ID of the vault where the entities are stored. + + format : typing.Optional[ReidentifyStringRequestFormat] + Mapping of perferred data formatting options to entity types. Returned values are dependent on the configuration of the vault storing the data and the permissions of the user or account making the request. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ReidentifyStringResponse + A successful response. + + Examples + -------- + import asyncio + + 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", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.reidentify_string( + text=text, vault_id=vault_id, format=format, request_options=request_options + ) + return _response.data diff --git a/skyflow/generated/rest/strings/raw_client.py b/skyflow/generated/rest/strings/raw_client.py new file mode 100644 index 00000000..ad67433a --- /dev/null +++ b/skyflow/generated/rest/strings/raw_client.py @@ -0,0 +1,445 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ..core.api_error import ApiError +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.http_response import AsyncHttpResponse, HttpResponse +from ..core.pydantic_utilities import parse_obj_as +from ..core.request_options import RequestOptions +from ..core.serialization import convert_and_respect_annotation_metadata +from ..errors.bad_request_error import BadRequestError +from ..errors.internal_server_error import InternalServerError +from ..errors.unauthorized_error import UnauthorizedError +from ..types.allow_regex import AllowRegex +from ..types.deidentify_string_response import DeidentifyStringResponse +from ..types.entity_types import EntityTypes +from ..types.error_response import ErrorResponse +from ..types.reidentify_string_response import ReidentifyStringResponse +from ..types.restrict_regex import RestrictRegex +from ..types.token_type import TokenType +from ..types.transformations import Transformations +from ..types.vault_id import VaultId +from .types.reidentify_string_request_format import ReidentifyStringRequestFormat + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawStringsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def deidentify_string( + self, + *, + vault_id: VaultId, + text: str, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenType] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[DeidentifyStringResponse]: + """ + De-identifies sensitive data from a string. + + Parameters + ---------- + vault_id : VaultId + + text : str + String to de-identify. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenType] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[DeidentifyStringResponse] + A successful response. + """ + _response = self._client_wrapper.httpx_client.request( + "v1/detect/deidentify/string", + method="POST", + json={ + "vault_id": vault_id, + "text": text, + "entity_types": entity_types, + "token_type": convert_and_respect_annotation_metadata( + object_=token_type, annotation=TokenType, direction="write" + ), + "allow_regex": allow_regex, + "restrict_regex": restrict_regex, + "transformations": convert_and_respect_annotation_metadata( + object_=transformations, annotation=Transformations, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DeidentifyStringResponse, + parse_obj_as( + type_=DeidentifyStringResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + ErrorResponse, + parse_obj_as( + type_=ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def reidentify_string( + self, + *, + text: str, + vault_id: str, + format: typing.Optional[ReidentifyStringRequestFormat] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[ReidentifyStringResponse]: + """ + Re-identifies tokens in a string. + + Parameters + ---------- + text : str + String to re-identify. + + vault_id : str + ID of the vault where the entities are stored. + + format : typing.Optional[ReidentifyStringRequestFormat] + Mapping of perferred data formatting options to entity types. Returned values are dependent on the configuration of the vault storing the data and the permissions of the user or account making the request. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[ReidentifyStringResponse] + A successful response. + """ + _response = self._client_wrapper.httpx_client.request( + "v1/detect/reidentify/string", + method="POST", + json={ + "text": text, + "vault_id": vault_id, + "format": convert_and_respect_annotation_metadata( + object_=format, annotation=ReidentifyStringRequestFormat, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ReidentifyStringResponse, + parse_obj_as( + type_=ReidentifyStringResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + ErrorResponse, + parse_obj_as( + type_=ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + +class AsyncRawStringsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def deidentify_string( + self, + *, + vault_id: VaultId, + text: str, + entity_types: typing.Optional[EntityTypes] = OMIT, + token_type: typing.Optional[TokenType] = OMIT, + allow_regex: typing.Optional[AllowRegex] = OMIT, + restrict_regex: typing.Optional[RestrictRegex] = OMIT, + transformations: typing.Optional[Transformations] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[DeidentifyStringResponse]: + """ + De-identifies sensitive data from a string. + + Parameters + ---------- + vault_id : VaultId + + text : str + String to de-identify. + + entity_types : typing.Optional[EntityTypes] + + token_type : typing.Optional[TokenType] + + allow_regex : typing.Optional[AllowRegex] + + restrict_regex : typing.Optional[RestrictRegex] + + transformations : typing.Optional[Transformations] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[DeidentifyStringResponse] + A successful response. + """ + _response = await self._client_wrapper.httpx_client.request( + "v1/detect/deidentify/string", + method="POST", + json={ + "vault_id": vault_id, + "text": text, + "entity_types": entity_types, + "token_type": convert_and_respect_annotation_metadata( + object_=token_type, annotation=TokenType, direction="write" + ), + "allow_regex": allow_regex, + "restrict_regex": restrict_regex, + "transformations": convert_and_respect_annotation_metadata( + object_=transformations, annotation=Transformations, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DeidentifyStringResponse, + parse_obj_as( + type_=DeidentifyStringResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + ErrorResponse, + parse_obj_as( + type_=ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def reidentify_string( + self, + *, + text: str, + vault_id: str, + format: typing.Optional[ReidentifyStringRequestFormat] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[ReidentifyStringResponse]: + """ + Re-identifies tokens in a string. + + Parameters + ---------- + text : str + String to re-identify. + + vault_id : str + ID of the vault where the entities are stored. + + format : typing.Optional[ReidentifyStringRequestFormat] + Mapping of perferred data formatting options to entity types. Returned values are dependent on the configuration of the vault storing the data and the permissions of the user or account making the request. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[ReidentifyStringResponse] + A successful response. + """ + _response = await self._client_wrapper.httpx_client.request( + "v1/detect/reidentify/string", + method="POST", + json={ + "text": text, + "vault_id": vault_id, + "format": convert_and_respect_annotation_metadata( + object_=format, annotation=ReidentifyStringRequestFormat, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ReidentifyStringResponse, + parse_obj_as( + type_=ReidentifyStringResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + ErrorResponse, + parse_obj_as( + type_=ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) diff --git a/skyflow/generated/rest/strings/types/__init__.py b/skyflow/generated/rest/strings/types/__init__.py new file mode 100644 index 00000000..97d06583 --- /dev/null +++ b/skyflow/generated/rest/strings/types/__init__.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +from .reidentify_string_request_format import ReidentifyStringRequestFormat + +__all__ = ["ReidentifyStringRequestFormat"] diff --git a/skyflow/generated/rest/strings/types/reidentify_string_request_format.py b/skyflow/generated/rest/strings/types/reidentify_string_request_format.py new file mode 100644 index 00000000..bfda392c --- /dev/null +++ b/skyflow/generated/rest/strings/types/reidentify_string_request_format.py @@ -0,0 +1,37 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ...types.entity_type import EntityType + + +class ReidentifyStringRequestFormat(UniversalBaseModel): + """ + Mapping of perferred data formatting options to entity types. Returned values are dependent on the configuration of the vault storing the data and the permissions of the user or account making the request. + """ + + redacted: typing.Optional[typing.List[EntityType]] = pydantic.Field(default=None) + """ + Entity types to fully redact. + """ + + masked: typing.Optional[typing.List[EntityType]] = pydantic.Field(default=None) + """ + Entity types to mask. + """ + + plaintext: typing.Optional[typing.List[EntityType]] = pydantic.Field(default=None) + """ + Entity types to return in plaintext. + """ + + 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/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/tokens/raw_client.py b/skyflow/generated/rest/tokens/raw_client.py index 057b9f68..4741631d 100644 --- a/skyflow/generated/rest/tokens/raw_client.py +++ b/skyflow/generated/rest/tokens/raw_client.py @@ -90,9 +90,9 @@ def record_service_detokenize( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -158,9 +158,9 @@ def record_service_tokenize( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -241,9 +241,9 @@ async def record_service_detokenize( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), @@ -309,9 +309,9 @@ async def record_service_tokenize( raise NotFoundError( headers=dict(_response.headers), body=typing.cast( - typing.Dict[str, typing.Optional[typing.Any]], + typing.Optional[typing.Any], parse_obj_as( - type_=typing.Dict[str, typing.Optional[typing.Any]], # type: ignore + type_=typing.Optional[typing.Any], # type: ignore object_=_response.json(), ), ), diff --git a/skyflow/generated/rest/types/__init__.py b/skyflow/generated/rest/types/__init__.py index 093756ee..74b8a5d1 100644 --- a/skyflow/generated/rest/types/__init__.py +++ b/skyflow/generated/rest/types/__init__.py @@ -2,6 +2,11 @@ # isort: skip_file +from .advanced_options_column_mapping import AdvancedOptionsColumnMapping +from .advanced_options_entity_column_map import AdvancedOptionsEntityColumnMap +from .advanced_options_vault_schema import AdvancedOptionsVaultSchema +from .allow_regex import AllowRegex +from .audio_config_transcription_type import AudioConfigTranscriptionType from .audit_event_audit_resource_type import AuditEventAuditResourceType from .audit_event_context import AuditEventContext from .audit_event_data import AuditEventData @@ -9,11 +14,45 @@ from .batch_record_method import BatchRecordMethod from .context_access_type import ContextAccessType from .context_auth_mode import ContextAuthMode +from .deidentify_file_output import DeidentifyFileOutput +from .deidentify_file_output_processed_file_type import DeidentifyFileOutputProcessedFileType +from .deidentify_file_response import DeidentifyFileResponse +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 +from .detect_file_request_data_type import DetectFileRequestDataType +from .detect_request_deidentify_option import DetectRequestDeidentifyOption +from .detected_entity import DetectedEntity from .detokenize_record_response_value_type import DetokenizeRecordResponseValueType +from .entity_location import EntityLocation +from .entity_type import EntityType +from .entity_types import EntityTypes +from .error_response import ErrorResponse +from .error_response_error import ErrorResponseError +from .error_string import ErrorString from .googlerpc_status import GooglerpcStatus +from .processed_file_output_processed_file_type import ProcessedFileOutputProcessedFileType from .protobuf_any import ProtobufAny from .redaction_enum_redaction import RedactionEnumRedaction +from .reidentify_string_response import ReidentifyStringResponse from .request_action_type import RequestActionType +from .resource_id import ResourceId +from .restrict_regex import RestrictRegex +from .token_type import TokenType +from .token_type_default import TokenTypeDefault +from .token_type_without_vault import TokenTypeWithoutVault +from .token_type_without_vault_default import TokenTypeWithoutVaultDefault +from .transformations import Transformations +from .transformations_shift_dates import TransformationsShiftDates +from .transformations_shift_dates_entity_types_item import TransformationsShiftDatesEntityTypesItem +from .uuid_ import Uuid +from .v_1_advanced_options import V1AdvancedOptions +from .v_1_audio_config import V1AudioConfig +from .v_1_audio_options import V1AudioOptions from .v_1_audit_after_options import V1AuditAfterOptions from .v_1_audit_event_response import V1AuditEventResponse from .v_1_audit_response import V1AuditResponse @@ -28,25 +67,43 @@ from .v_1_card import V1Card from .v_1_delete_file_response import V1DeleteFileResponse from .v_1_delete_record_response import V1DeleteRecordResponse +from .v_1_detect_file_response import V1DetectFileResponse +from .v_1_detect_status_response import V1DetectStatusResponse +from .v_1_detect_status_response_status import V1DetectStatusResponseStatus +from .v_1_detect_text_request import V1DetectTextRequest +from .v_1_detect_text_response import V1DetectTextResponse from .v_1_detokenize_record_request import V1DetokenizeRecordRequest from .v_1_detokenize_record_response import V1DetokenizeRecordResponse from .v_1_detokenize_response import V1DetokenizeResponse from .v_1_field_records import V1FieldRecords from .v_1_file_av_scan_status import V1FileAvScanStatus +from .v_1_file_data_format import V1FileDataFormat from .v_1_get_auth_token_response import V1GetAuthTokenResponse from .v_1_get_file_scan_status_response import V1GetFileScanStatusResponse from .v_1_get_query_response import V1GetQueryResponse +from .v_1_image_options import V1ImageOptions from .v_1_insert_record_response import V1InsertRecordResponse +from .v_1_locations import V1Locations from .v_1_member_type import V1MemberType +from .v_1_pdf_config import V1PdfConfig +from .v_1_pdf_options import V1PdfOptions +from .v_1_processed_file_output import V1ProcessedFileOutput from .v_1_record_meta_properties import V1RecordMetaProperties +from .v_1_response_entities import V1ResponseEntities from .v_1_tokenize_record_request import V1TokenizeRecordRequest from .v_1_tokenize_record_response import V1TokenizeRecordResponse from .v_1_tokenize_response import V1TokenizeResponse from .v_1_update_record_response import V1UpdateRecordResponse from .v_1_vault_field_mapping import V1VaultFieldMapping from .v_1_vault_schema_config import V1VaultSchemaConfig +from .vault_id import VaultId __all__ = [ + "AdvancedOptionsColumnMapping", + "AdvancedOptionsEntityColumnMap", + "AdvancedOptionsVaultSchema", + "AllowRegex", + "AudioConfigTranscriptionType", "AuditEventAuditResourceType", "AuditEventContext", "AuditEventData", @@ -54,11 +111,45 @@ "BatchRecordMethod", "ContextAccessType", "ContextAuthMode", + "DeidentifyFileOutput", + "DeidentifyFileOutputProcessedFileType", + "DeidentifyFileResponse", + "DeidentifyStatusResponse", + "DeidentifyStatusResponseOutputType", + "DeidentifyStatusResponseStatus", + "DeidentifyStatusResponseWordCharacterCount", + "DeidentifyStringResponse", + "DetectDataAccuracy", + "DetectDataEntities", + "DetectFileRequestDataType", + "DetectRequestDeidentifyOption", + "DetectedEntity", "DetokenizeRecordResponseValueType", + "EntityLocation", + "EntityType", + "EntityTypes", + "ErrorResponse", + "ErrorResponseError", + "ErrorString", "GooglerpcStatus", + "ProcessedFileOutputProcessedFileType", "ProtobufAny", "RedactionEnumRedaction", + "ReidentifyStringResponse", "RequestActionType", + "ResourceId", + "RestrictRegex", + "TokenType", + "TokenTypeDefault", + "TokenTypeWithoutVault", + "TokenTypeWithoutVaultDefault", + "Transformations", + "TransformationsShiftDates", + "TransformationsShiftDatesEntityTypesItem", + "Uuid", + "V1AdvancedOptions", + "V1AudioConfig", + "V1AudioOptions", "V1AuditAfterOptions", "V1AuditEventResponse", "V1AuditResponse", @@ -73,21 +164,34 @@ "V1Card", "V1DeleteFileResponse", "V1DeleteRecordResponse", + "V1DetectFileResponse", + "V1DetectStatusResponse", + "V1DetectStatusResponseStatus", + "V1DetectTextRequest", + "V1DetectTextResponse", "V1DetokenizeRecordRequest", "V1DetokenizeRecordResponse", "V1DetokenizeResponse", "V1FieldRecords", "V1FileAvScanStatus", + "V1FileDataFormat", "V1GetAuthTokenResponse", "V1GetFileScanStatusResponse", "V1GetQueryResponse", + "V1ImageOptions", "V1InsertRecordResponse", + "V1Locations", "V1MemberType", + "V1PdfConfig", + "V1PdfOptions", + "V1ProcessedFileOutput", "V1RecordMetaProperties", + "V1ResponseEntities", "V1TokenizeRecordRequest", "V1TokenizeRecordResponse", "V1TokenizeResponse", "V1UpdateRecordResponse", "V1VaultFieldMapping", "V1VaultSchemaConfig", + "VaultId", ] diff --git a/skyflow/generated/rest/types/advanced_options_column_mapping.py b/skyflow/generated/rest/types/advanced_options_column_mapping.py new file mode 100644 index 00000000..8369b329 --- /dev/null +++ b/skyflow/generated/rest/types/advanced_options_column_mapping.py @@ -0,0 +1,37 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .advanced_options_entity_column_map import AdvancedOptionsEntityColumnMap + + +class AdvancedOptionsColumnMapping(UniversalBaseModel): + """ + Contains map of what has to be stored in which column. + """ + + session_id: str = pydantic.Field() + """ + Table name of the vault. + """ + + default: str = pydantic.Field() + """ + Name of column to store data in when no explicit mapping exists. + """ + + entity_column_map: typing.Optional[typing.List[AdvancedOptionsEntityColumnMap]] = pydantic.Field(default=None) + """ + Column mapping for different entities. + """ + + 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/types/advanced_options_entity_column_map.py b/skyflow/generated/rest/types/advanced_options_entity_column_map.py new file mode 100644 index 00000000..debf836a --- /dev/null +++ b/skyflow/generated/rest/types/advanced_options_entity_column_map.py @@ -0,0 +1,28 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .detect_data_entities import DetectDataEntities + + +class AdvancedOptionsEntityColumnMap(UniversalBaseModel): + """ + Contains map of what entity has to be stored in which column. + """ + + entity_type: typing.Optional[DetectDataEntities] = None + column_name: typing.Optional[str] = pydantic.Field(default=None) + """ + Column name where the entity has to be stored. + """ + + 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/types/advanced_options_vault_schema.py b/skyflow/generated/rest/types/advanced_options_vault_schema.py new file mode 100644 index 00000000..8496eb97 --- /dev/null +++ b/skyflow/generated/rest/types/advanced_options_vault_schema.py @@ -0,0 +1,29 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .advanced_options_column_mapping import AdvancedOptionsColumnMapping + + +class AdvancedOptionsVaultSchema(UniversalBaseModel): + """ + Contains table name and column mapping. + """ + + table_name: str = pydantic.Field() + """ + Table name of the vault. + """ + + mapping: AdvancedOptionsColumnMapping + + 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/types/allow_regex.py b/skyflow/generated/rest/types/allow_regex.py new file mode 100644 index 00000000..f4164375 --- /dev/null +++ b/skyflow/generated/rest/types/allow_regex.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AllowRegex = typing.List[str] diff --git a/skyflow/generated/rest/types/audio_config_transcription_type.py b/skyflow/generated/rest/types/audio_config_transcription_type.py new file mode 100644 index 00000000..13ad88d9 --- /dev/null +++ b/skyflow/generated/rest/types/audio_config_transcription_type.py @@ -0,0 +1,19 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AudioConfigTranscriptionType = typing.Union[ + typing.Literal[ + "none", + "skyflow_transcription", + "aws_transcription", + "aws_transcription_diarize", + "aws_medical_transcription", + "aws_medical_transcription_diarize", + "aws_transcription_diarize_json", + "deepgram_transcription_diarize", + "deepgram_transcription_json", + "deepgram_wrapper", + ], + typing.Any, +] diff --git a/skyflow/generated/rest/types/deidentify_file_output.py b/skyflow/generated/rest/types/deidentify_file_output.py new file mode 100644 index 00000000..a4c2da4d --- /dev/null +++ b/skyflow/generated/rest/types/deidentify_file_output.py @@ -0,0 +1,45 @@ +# 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 +from .deidentify_file_output_processed_file_type import DeidentifyFileOutputProcessedFileType + + +class DeidentifyFileOutput(UniversalBaseModel): + """ + Details and contents of the processed file. + """ + + 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_extensions.Annotated[ + typing.Optional[DeidentifyFileOutputProcessedFileType], FieldMetadata(alias="processedFileType") + ] = pydantic.Field(default=None) + """ + Type of the processed file. + """ + + processed_file_extension: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="processedFileExtension") + ] = pydantic.Field(default=None) + """ + Extension of the processed file. + """ + + 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/types/deidentify_file_output_processed_file_type.py b/skyflow/generated/rest/types/deidentify_file_output_processed_file_type.py new file mode 100644 index 00000000..332ce445 --- /dev/null +++ b/skyflow/generated/rest/types/deidentify_file_output_processed_file_type.py @@ -0,0 +1,19 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +DeidentifyFileOutputProcessedFileType = typing.Union[ + typing.Literal[ + "entities", + "plaintext_transcription", + "redacted_audio", + "redacted_diarized_transcription", + "redacted_file", + "redacted_image", + "redacted_medical_diarized_transcription", + "redacted_medical_transcription", + "redacted_text", + "redacted_transcription", + ], + typing.Any, +] diff --git a/skyflow/generated/rest/types/deidentify_file_response.py b/skyflow/generated/rest/types/deidentify_file_response.py new file mode 100644 index 00000000..e4e6bf35 --- /dev/null +++ b/skyflow/generated/rest/types/deidentify_file_response.py @@ -0,0 +1,26 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class DeidentifyFileResponse(UniversalBaseModel): + """ + Response to de-identify a file. + """ + + run_id: str = pydantic.Field() + """ + Status URL for the detect run. + """ + + 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/types/deidentify_status_response.py b/skyflow/generated/rest/types/deidentify_status_response.py new file mode 100644 index 00000000..0ad91e62 --- /dev/null +++ b/skyflow/generated/rest/types/deidentify_status_response.py @@ -0,0 +1,76 @@ +# 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 +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): + """ + Response to get the status of a detect run. + """ + + status: DeidentifyStatusResponseStatus = pydantic.Field() + """ + Status of the detect run. + """ + + output: typing.List[DeidentifyFileOutput] = pydantic.Field() + """ + How the input file was specified. + """ + + output_type: typing_extensions.Annotated[ + typing.Optional[DeidentifyStatusResponseOutputType], FieldMetadata(alias="outputType") + ] = pydantic.Field(default=None) + """ + How the output file is specified. + """ + + message: str = pydantic.Field() + """ + Status details about the detect run. + """ + + word_character_count: typing_extensions.Annotated[ + typing.Optional[DeidentifyStatusResponseWordCharacterCount], FieldMetadata(alias="wordCharacterCount") + ] = pydantic.Field(default=None) + """ + Word and character count in the processed text. + """ + + size: typing.Optional[float] = pydantic.Field(default=None) + """ + Size of the processed text in kilobytes (KB). + """ + + duration: typing.Optional[float] = pydantic.Field(default=None) + """ + Duration of the processed audio in seconds. + """ + + pages: typing.Optional[int] = pydantic.Field(default=None) + """ + Number of pages in the processed PDF. + """ + + slides: typing.Optional[int] = pydantic.Field(default=None) + """ + Number of slides in the processed presentation. + """ + + 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/types/deidentify_status_response_output_type.py b/skyflow/generated/rest/types/deidentify_status_response_output_type.py new file mode 100644 index 00000000..571801c1 --- /dev/null +++ b/skyflow/generated/rest/types/deidentify_status_response_output_type.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +DeidentifyStatusResponseOutputType = typing.Union[typing.Literal["base64", "efs_path"], typing.Any] diff --git a/skyflow/generated/rest/types/deidentify_status_response_status.py b/skyflow/generated/rest/types/deidentify_status_response_status.py new file mode 100644 index 00000000..40262092 --- /dev/null +++ b/skyflow/generated/rest/types/deidentify_status_response_status.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +DeidentifyStatusResponseStatus = typing.Union[typing.Literal["failed", "in_progress", "success"], typing.Any] 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/types/deidentify_string_response.py b/skyflow/generated/rest/types/deidentify_string_response.py new file mode 100644 index 00000000..c141f841 --- /dev/null +++ b/skyflow/generated/rest/types/deidentify_string_response.py @@ -0,0 +1,42 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .detected_entity import DetectedEntity + + +class DeidentifyStringResponse(UniversalBaseModel): + """ + Response to deidentify a string. + """ + + processed_text: str = pydantic.Field() + """ + De-identified text. + """ + + entities: typing.List[DetectedEntity] = pydantic.Field() + """ + Detected entities. + """ + + word_count: int = pydantic.Field() + """ + Number of words from the input text. + """ + + character_count: int = pydantic.Field() + """ + Number of characters from the input text. + """ + + 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/types/detect_data_accuracy.py b/skyflow/generated/rest/types/detect_data_accuracy.py new file mode 100644 index 00000000..91e3619e --- /dev/null +++ b/skyflow/generated/rest/types/detect_data_accuracy.py @@ -0,0 +1,17 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +DetectDataAccuracy = typing.Union[ + typing.Literal[ + "unknown", + "standard", + "standard_plus", + "standard_plus_multilingual", + "standard_plus_automatic", + "high", + "high_multilingual", + "high_automatic", + ], + typing.Any, +] diff --git a/skyflow/generated/rest/types/detect_data_entities.py b/skyflow/generated/rest/types/detect_data_entities.py new file mode 100644 index 00000000..4ac0bd49 --- /dev/null +++ b/skyflow/generated/rest/types/detect_data_entities.py @@ -0,0 +1,72 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +DetectDataEntities = typing.Union[ + typing.Literal[ + "age", + "bank_account", + "credit_card", + "credit_card_expiration", + "cvv", + "date", + "date_interval", + "dob", + "driver_license", + "email_address", + "healthcare_number", + "ip_address", + "location", + "name", + "numerical_pii", + "phone_number", + "ssn", + "url", + "vehicle_id", + "medical_code", + "name_family", + "name_given", + "account_number", + "event", + "filename", + "gender_sexuality", + "language", + "location_address", + "location_city", + "location_coordinate", + "location_country", + "location_state", + "location_zip", + "marital_status", + "money", + "name_medical_professional", + "occupation", + "organization", + "organization_medical_facility", + "origin", + "passport_number", + "password", + "physical_attribute", + "political_affiliation", + "religion", + "time", + "username", + "zodiac_sign", + "blood_type", + "condition", + "dose", + "drug", + "injury", + "medical_process", + "statistics", + "routing_number", + "corporate_action", + "financial_metric", + "product", + "trend", + "duration", + "location_address_street", + "all", + ], + typing.Any, +] diff --git a/skyflow/generated/rest/types/detect_file_request_data_type.py b/skyflow/generated/rest/types/detect_file_request_data_type.py new file mode 100644 index 00000000..825d4778 --- /dev/null +++ b/skyflow/generated/rest/types/detect_file_request_data_type.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +DetectFileRequestDataType = typing.Union[typing.Literal["UNKNOWN", "BASE64"], typing.Any] diff --git a/skyflow/generated/rest/types/detect_request_deidentify_option.py b/skyflow/generated/rest/types/detect_request_deidentify_option.py new file mode 100644 index 00000000..caee5f16 --- /dev/null +++ b/skyflow/generated/rest/types/detect_request_deidentify_option.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +DetectRequestDeidentifyOption = typing.Union[typing.Literal["UNKNOWN", "ENTITY_UNQ_COUNTER", "ENTITY_ONLY"], typing.Any] diff --git a/skyflow/generated/rest/types/detected_entity.py b/skyflow/generated/rest/types/detected_entity.py new file mode 100644 index 00000000..c34ba2ca --- /dev/null +++ b/skyflow/generated/rest/types/detected_entity.py @@ -0,0 +1,43 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .entity_location import EntityLocation + + +class DetectedEntity(UniversalBaseModel): + """ + Detected entities. + """ + + token: typing.Optional[str] = pydantic.Field(default=None) + """ + Processed text of the entity. + """ + + value: typing.Optional[str] = pydantic.Field(default=None) + """ + Original text of the entity. + """ + + location: typing.Optional[EntityLocation] = None + entity_type: typing.Optional[str] = pydantic.Field(default=None) + """ + Highest-rated label. + """ + + entity_scores: typing.Optional[typing.Dict[str, float]] = pydantic.Field(default=None) + """ + entity_scores and their scores. + """ + + 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/types/entity_location.py b/skyflow/generated/rest/types/entity_location.py new file mode 100644 index 00000000..487f9c72 --- /dev/null +++ b/skyflow/generated/rest/types/entity_location.py @@ -0,0 +1,41 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class EntityLocation(UniversalBaseModel): + """ + Locations of an entity in the text. + """ + + start_index: typing.Optional[int] = pydantic.Field(default=None) + """ + Index of the first character of the string in the original text. + """ + + end_index: typing.Optional[int] = pydantic.Field(default=None) + """ + Index of the last character of the string in the original text. + """ + + start_index_processed: typing.Optional[int] = pydantic.Field(default=None) + """ + Index of the first character of the string in the processed text. + """ + + end_index_processed: typing.Optional[int] = pydantic.Field(default=None) + """ + Index of the last character of the string in the processed text. + """ + + 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/types/entity_type.py b/skyflow/generated/rest/types/entity_type.py new file mode 100644 index 00000000..6b48f1d8 --- /dev/null +++ b/skyflow/generated/rest/types/entity_type.py @@ -0,0 +1,72 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +EntityType = typing.Union[ + typing.Literal[ + "account_number", + "age", + "all", + "bank_account", + "blood_type", + "condition", + "corporate_action", + "credit_card", + "credit_card_expiration", + "cvv", + "date", + "date_interval", + "dob", + "dose", + "driver_license", + "drug", + "duration", + "email_address", + "event", + "filename", + "financial_metric", + "gender_sexuality", + "healthcare_number", + "injury", + "ip_address", + "language", + "location", + "location_address", + "location_address_street", + "location_city", + "location_coordinate", + "location_country", + "location_state", + "location_zip", + "marital_status", + "medical_code", + "medical_process", + "money", + "name", + "name_family", + "name_given", + "name_medical_professional", + "numerical_pii", + "occupation", + "organization", + "organization_medical_facility", + "origin", + "passport_number", + "password", + "phone_number", + "physical_attribute", + "political_affiliation", + "product", + "religion", + "routing_number", + "ssn", + "statistics", + "time", + "trend", + "url", + "username", + "vehicle_id", + "zodiac_sign", + ], + typing.Any, +] diff --git a/skyflow/generated/rest/types/entity_types.py b/skyflow/generated/rest/types/entity_types.py new file mode 100644 index 00000000..3adb0438 --- /dev/null +++ b/skyflow/generated/rest/types/entity_types.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .entity_type import EntityType + +EntityTypes = typing.List[EntityType] diff --git a/skyflow/generated/rest/types/error_response.py b/skyflow/generated/rest/types/error_response.py new file mode 100644 index 00000000..7c0491bb --- /dev/null +++ b/skyflow/generated/rest/types/error_response.py @@ -0,0 +1,20 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .error_response_error import ErrorResponseError + + +class ErrorResponse(UniversalBaseModel): + error: ErrorResponseError + + 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/types/error_response_error.py b/skyflow/generated/rest/types/error_response_error.py new file mode 100644 index 00000000..722b69cc --- /dev/null +++ b/skyflow/generated/rest/types/error_response_error.py @@ -0,0 +1,35 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class ErrorResponseError(UniversalBaseModel): + grpc_code: int = pydantic.Field() + """ + gRPC status codes. See https://grpc.io/docs/guides/status-codes. + """ + + http_code: int = pydantic.Field() + """ + HTTP status codes. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status. + """ + + http_status: str = pydantic.Field() + """ + HTTP status message. + """ + + message: str + details: typing.Optional[typing.List[typing.Dict[str, typing.Optional[typing.Any]]]] = 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/types/error_string.py b/skyflow/generated/rest/types/error_string.py new file mode 100644 index 00000000..068b4a84 --- /dev/null +++ b/skyflow/generated/rest/types/error_string.py @@ -0,0 +1,3 @@ +# This file was auto-generated by Fern from our API Definition. + +ErrorString = str diff --git a/skyflow/generated/rest/types/processed_file_output_processed_file_type.py b/skyflow/generated/rest/types/processed_file_output_processed_file_type.py new file mode 100644 index 00000000..18758eaa --- /dev/null +++ b/skyflow/generated/rest/types/processed_file_output_processed_file_type.py @@ -0,0 +1,19 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +ProcessedFileOutputProcessedFileType = typing.Union[ + typing.Literal[ + "none", + "redacted_audio", + "redacted_image", + "redacted_transcription", + "redacted_file", + "redacted_text", + "entities", + "redacted_aws_transcription_diarize_json", + "redacted_deepgram_transcription_diarize_json", + "plaintext_transcribed", + ], + typing.Any, +] diff --git a/skyflow/generated/rest/types/reidentify_string_response.py b/skyflow/generated/rest/types/reidentify_string_response.py new file mode 100644 index 00000000..8284806b --- /dev/null +++ b/skyflow/generated/rest/types/reidentify_string_response.py @@ -0,0 +1,26 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class ReidentifyStringResponse(UniversalBaseModel): + """ + Re-identify string response. + """ + + processed_text: typing.Optional[str] = pydantic.Field(default=None) + """ + Re-identified text. + """ + + 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/types/resource_id.py b/skyflow/generated/rest/types/resource_id.py new file mode 100644 index 00000000..211b4108 --- /dev/null +++ b/skyflow/generated/rest/types/resource_id.py @@ -0,0 +1,3 @@ +# This file was auto-generated by Fern from our API Definition. + +ResourceId = str diff --git a/skyflow/generated/rest/types/restrict_regex.py b/skyflow/generated/rest/types/restrict_regex.py new file mode 100644 index 00000000..06dd46b7 --- /dev/null +++ b/skyflow/generated/rest/types/restrict_regex.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +RestrictRegex = typing.List[str] diff --git a/skyflow/generated/rest/types/token_type.py b/skyflow/generated/rest/types/token_type.py new file mode 100644 index 00000000..200b9630 --- /dev/null +++ b/skyflow/generated/rest/types/token_type.py @@ -0,0 +1,39 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .entity_type import EntityType +from .token_type_default import TokenTypeDefault + + +class TokenType(UniversalBaseModel): + """ + Mapping of tokens to generation for detected entities. Can't be specified together with `token_type`. + """ + + default: typing.Optional[TokenTypeDefault] = None + vault_token: typing.Optional[typing.List[EntityType]] = pydantic.Field(default=None) + """ + Entity types to replace with vault tokens. + """ + + entity_unq_counter: typing.Optional[typing.List[EntityType]] = pydantic.Field(default=None) + """ + Entity types to replace with entity tokens with unique counters. + """ + + entity_only: typing.Optional[typing.List[EntityType]] = pydantic.Field(default=None) + """ + Entity types to replace with entity tokens. + """ + + 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/types/token_type_default.py b/skyflow/generated/rest/types/token_type_default.py new file mode 100644 index 00000000..cfda9f4b --- /dev/null +++ b/skyflow/generated/rest/types/token_type_default.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +TokenTypeDefault = typing.Union[typing.Literal["entity_only", "entity_unq_counter", "vault_token"], typing.Any] diff --git a/skyflow/generated/rest/types/token_type_without_vault.py b/skyflow/generated/rest/types/token_type_without_vault.py new file mode 100644 index 00000000..d79a3477 --- /dev/null +++ b/skyflow/generated/rest/types/token_type_without_vault.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .entity_type import EntityType +from .token_type_without_vault_default import TokenTypeWithoutVaultDefault + + +class TokenTypeWithoutVault(UniversalBaseModel): + """ + Mapping of tokens to generation for detected entities. Can't be specified together with `token_type`. + """ + + default: typing.Optional[TokenTypeWithoutVaultDefault] = None + entity_unq_counter: typing.Optional[typing.List[EntityType]] = pydantic.Field(default=None) + """ + Entity types to replace with entity tokens with unique counters. + """ + + entity_only: typing.Optional[typing.List[EntityType]] = pydantic.Field(default=None) + """ + Entity types to replace with entity tokens. + """ + + 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/types/token_type_without_vault_default.py b/skyflow/generated/rest/types/token_type_without_vault_default.py new file mode 100644 index 00000000..53d71dc6 --- /dev/null +++ b/skyflow/generated/rest/types/token_type_without_vault_default.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +TokenTypeWithoutVaultDefault = typing.Union[typing.Literal["entity_only", "entity_unq_counter"], typing.Any] diff --git a/skyflow/generated/rest/types/transformations.py b/skyflow/generated/rest/types/transformations.py new file mode 100644 index 00000000..352df144 --- /dev/null +++ b/skyflow/generated/rest/types/transformations.py @@ -0,0 +1,27 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .transformations_shift_dates import TransformationsShiftDates + + +class Transformations(UniversalBaseModel): + """ + Transformations to apply to the detected entities. + """ + + shift_dates: typing.Optional[TransformationsShiftDates] = pydantic.Field(default=None) + """ + Shift dates by a specified number of days. + """ + + 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/types/transformations_shift_dates.py b/skyflow/generated/rest/types/transformations_shift_dates.py new file mode 100644 index 00000000..21b21af8 --- /dev/null +++ b/skyflow/generated/rest/types/transformations_shift_dates.py @@ -0,0 +1,37 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .transformations_shift_dates_entity_types_item import TransformationsShiftDatesEntityTypesItem + + +class TransformationsShiftDates(UniversalBaseModel): + """ + Shift dates by a specified number of days. + """ + + max_days: typing.Optional[int] = pydantic.Field(default=None) + """ + Maximum number of days to shift the date by. + """ + + min_days: typing.Optional[int] = pydantic.Field(default=None) + """ + Minimum number of days to shift the date by. + """ + + entity_types: typing.Optional[typing.List[TransformationsShiftDatesEntityTypesItem]] = pydantic.Field(default=None) + """ + Entity types to shift dates for. + """ + + 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/types/transformations_shift_dates_entity_types_item.py b/skyflow/generated/rest/types/transformations_shift_dates_entity_types_item.py new file mode 100644 index 00000000..f8d98df6 --- /dev/null +++ b/skyflow/generated/rest/types/transformations_shift_dates_entity_types_item.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +TransformationsShiftDatesEntityTypesItem = typing.Union[typing.Literal["date", "date_interval", "dob"], typing.Any] diff --git a/skyflow/generated/rest/types/uuid_.py b/skyflow/generated/rest/types/uuid_.py new file mode 100644 index 00000000..cf319b43 --- /dev/null +++ b/skyflow/generated/rest/types/uuid_.py @@ -0,0 +1,3 @@ +# This file was auto-generated by Fern from our API Definition. + +Uuid = str diff --git a/skyflow/generated/rest/types/v_1_advanced_options.py b/skyflow/generated/rest/types/v_1_advanced_options.py new file mode 100644 index 00000000..ea893551 --- /dev/null +++ b/skyflow/generated/rest/types/v_1_advanced_options.py @@ -0,0 +1,38 @@ +# 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 +from .advanced_options_vault_schema import AdvancedOptionsVaultSchema + + +class V1AdvancedOptions(UniversalBaseModel): + """ + Advanced options for post processing. + """ + + date_shift: typing.Optional[int] = pydantic.Field(default=None) + """ + No. of days by which original date has to be shifted to. + """ + + custom_client: typing.Optional[bool] = pydantic.Field(default=None) + """ + Custom client specific logic. + """ + + schema_: typing_extensions.Annotated[typing.Optional[AdvancedOptionsVaultSchema], FieldMetadata(alias="schema")] = ( + 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/types/v_1_audio_config.py b/skyflow/generated/rest/types/v_1_audio_config.py new file mode 100644 index 00000000..dc866e47 --- /dev/null +++ b/skyflow/generated/rest/types/v_1_audio_config.py @@ -0,0 +1,31 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .audio_config_transcription_type import AudioConfigTranscriptionType +from .v_1_audio_options import V1AudioOptions + + +class V1AudioConfig(UniversalBaseModel): + """ + How to handle audio files. + """ + + output_transcription: typing.Optional[AudioConfigTranscriptionType] = None + output_processed_audio: typing.Optional[bool] = pydantic.Field(default=None) + """ + If `true`, includes processed audio file in the response. + """ + + options: typing.Optional[V1AudioOptions] = 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/types/v_1_audio_options.py b/skyflow/generated/rest/types/v_1_audio_options.py new file mode 100644 index 00000000..6e5b3df9 --- /dev/null +++ b/skyflow/generated/rest/types/v_1_audio_options.py @@ -0,0 +1,46 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class V1AudioOptions(UniversalBaseModel): + """ + Options for audio files. + """ + + bleep_start_padding: typing.Optional[float] = pydantic.Field(default=None) + """ + Padding added to the beginning of a bleep, in seconds. + """ + + bleep_end_padding: typing.Optional[float] = pydantic.Field(default=None) + """ + Padding added to the end of a bleep, in seconds. + """ + + distortion_steps: typing.Optional[int] = pydantic.Field(default=None) + """ + Specifies how the distortion will be made. Providing a number more than 0 will result in a higher tone and a coefficient less than 0 will result in a lower tone. + """ + + bleep_frequency: typing.Optional[int] = pydantic.Field(default=None) + """ + This parameter configures the frequency of the sine wave used for the bleep sound in an audio segment. + """ + + bleep_gain: typing.Optional[int] = pydantic.Field(default=None) + """ + It controls the relative loudness of the bleep,positive values increase its loudness, and negative values decrease it. + """ + + 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/types/v_1_detect_file_response.py b/skyflow/generated/rest/types/v_1_detect_file_response.py new file mode 100644 index 00000000..f933703e --- /dev/null +++ b/skyflow/generated/rest/types/v_1_detect_file_response.py @@ -0,0 +1,26 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class V1DetectFileResponse(UniversalBaseModel): + """ + Response to deidentify a file. + """ + + status_url: typing.Optional[str] = pydantic.Field(default=None) + """ + Status URL for the deidentification request. + """ + + 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/types/v_1_detect_status_response.py b/skyflow/generated/rest/types/v_1_detect_status_response.py new file mode 100644 index 00000000..ac859394 --- /dev/null +++ b/skyflow/generated/rest/types/v_1_detect_status_response.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .v_1_detect_status_response_status import V1DetectStatusResponseStatus +from .v_1_processed_file_output import V1ProcessedFileOutput + + +class V1DetectStatusResponse(UniversalBaseModel): + """ + Response to get the status of a file deidentification request. + """ + + status: typing.Optional[V1DetectStatusResponseStatus] = None + output: typing.Optional[typing.List[V1ProcessedFileOutput]] = pydantic.Field(default=None) + """ + How the input file was specified. + """ + + message: typing.Optional[str] = pydantic.Field(default=None) + """ + Status details about the deidentification request. + """ + + 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/types/v_1_detect_status_response_status.py b/skyflow/generated/rest/types/v_1_detect_status_response_status.py new file mode 100644 index 00000000..1b9531cb --- /dev/null +++ b/skyflow/generated/rest/types/v_1_detect_status_response_status.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +V1DetectStatusResponseStatus = typing.Union[typing.Literal["UNKNOWN", "FAILED", "SUCCESS", "IN_PROGRESS"], typing.Any] diff --git a/skyflow/generated/rest/types/v_1_detect_text_request.py b/skyflow/generated/rest/types/v_1_detect_text_request.py new file mode 100644 index 00000000..f832ef7b --- /dev/null +++ b/skyflow/generated/rest/types/v_1_detect_text_request.py @@ -0,0 +1,68 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .detect_data_accuracy import DetectDataAccuracy +from .detect_data_entities import DetectDataEntities +from .detect_request_deidentify_option import DetectRequestDeidentifyOption +from .v_1_advanced_options import V1AdvancedOptions + + +class V1DetectTextRequest(UniversalBaseModel): + """ + Request to deidentify a string. + """ + + text: str = pydantic.Field() + """ + Data to deidentify. + """ + + vault_id: str = pydantic.Field() + """ + ID of the vault. + """ + + session_id: typing.Optional[str] = pydantic.Field(default=None) + """ + Will give a handle to delete the tokens generated during a specific interaction. + """ + + restrict_entity_types: typing.Optional[typing.List[DetectDataEntities]] = pydantic.Field(default=None) + """ + Entities to detect and deidentify. + """ + + deidentify_token_format: typing.Optional[DetectRequestDeidentifyOption] = None + allow_regex: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + Regular expressions to ignore when detecting entities. + """ + + restrict_regex: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + Regular expressions to always restrict. Strings matching these regular expressions are replaced with 'RESTRICTED'. + """ + + return_entities: typing.Optional[bool] = pydantic.Field(default=None) + """ + If `true`, returns the details for the detected entities. + """ + + accuracy: typing.Optional[DetectDataAccuracy] = None + advanced_options: typing.Optional[V1AdvancedOptions] = None + store_entities: typing.Optional[bool] = pydantic.Field(default=None) + """ + Indicates whether entities should be stored in the vault. + """ + + 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/types/v_1_detect_text_response.py b/skyflow/generated/rest/types/v_1_detect_text_response.py new file mode 100644 index 00000000..954e7d07 --- /dev/null +++ b/skyflow/generated/rest/types/v_1_detect_text_response.py @@ -0,0 +1,32 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .v_1_response_entities import V1ResponseEntities + + +class V1DetectTextResponse(UniversalBaseModel): + """ + Response to deidentify a string. + """ + + processed_text: typing.Optional[str] = pydantic.Field(default=None) + """ + Deidentified text. If the input was a file, text that was extracted or transcribed from the file and deidentified. + """ + + entities: typing.Optional[typing.List[V1ResponseEntities]] = pydantic.Field(default=None) + """ + Detected entities. + """ + + 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/types/v_1_file_data_format.py b/skyflow/generated/rest/types/v_1_file_data_format.py new file mode 100644 index 00000000..f717c793 --- /dev/null +++ b/skyflow/generated/rest/types/v_1_file_data_format.py @@ -0,0 +1,28 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +V1FileDataFormat = typing.Union[ + typing.Literal[ + "bmp", + "csv", + "doc", + "docx", + "jpeg", + "jpg", + "json", + "mp3", + "pdf", + "png", + "ppt", + "pptx", + "tif", + "tiff", + "txt", + "unknown", + "wav", + "xls", + "xlsx", + ], + typing.Any, +] diff --git a/skyflow/generated/rest/types/v_1_image_options.py b/skyflow/generated/rest/types/v_1_image_options.py new file mode 100644 index 00000000..7f4143df --- /dev/null +++ b/skyflow/generated/rest/types/v_1_image_options.py @@ -0,0 +1,31 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class V1ImageOptions(UniversalBaseModel): + """ + How to handle image files. + """ + + output_processed_image: typing.Optional[bool] = pydantic.Field(default=None) + """ + If `true`, includes processed image in the output. + """ + + output_ocr_text: typing.Optional[bool] = pydantic.Field(default=None) + """ + If `true`, includes OCR text output in the response. + """ + + 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/types/v_1_locations.py b/skyflow/generated/rest/types/v_1_locations.py new file mode 100644 index 00000000..098d6b6e --- /dev/null +++ b/skyflow/generated/rest/types/v_1_locations.py @@ -0,0 +1,41 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class V1Locations(UniversalBaseModel): + """ + Locations of an entity in the text. + """ + + start_index: typing.Optional[int] = pydantic.Field(default=None) + """ + Index of the first character of the string in the original text. + """ + + end_index: typing.Optional[int] = pydantic.Field(default=None) + """ + Index of the last character of the string in the original text. + """ + + start_index_processed: typing.Optional[int] = pydantic.Field(default=None) + """ + Index of the first character of the string in the processed text. + """ + + end_index_processed: typing.Optional[int] = pydantic.Field(default=None) + """ + Index of the last character of the string in the processed text. + """ + + 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/types/v_1_pdf_config.py b/skyflow/generated/rest/types/v_1_pdf_config.py new file mode 100644 index 00000000..eff6107e --- /dev/null +++ b/skyflow/generated/rest/types/v_1_pdf_config.py @@ -0,0 +1,24 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .v_1_pdf_options import V1PdfOptions + + +class V1PdfConfig(UniversalBaseModel): + """ + How to handle PDF files. + """ + + options: typing.Optional[V1PdfOptions] = 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/types/v_1_pdf_options.py b/skyflow/generated/rest/types/v_1_pdf_options.py new file mode 100644 index 00000000..28fdf1bc --- /dev/null +++ b/skyflow/generated/rest/types/v_1_pdf_options.py @@ -0,0 +1,31 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class V1PdfOptions(UniversalBaseModel): + """ + How to handle PDF files. + """ + + density: typing.Optional[int] = pydantic.Field(default=None) + """ + Pixel density at which to process the PDF file. + """ + + max_resolution: typing.Optional[int] = pydantic.Field(default=None) + """ + Max resolution at which to process the PDF file. + """ + + 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/types/v_1_processed_file_output.py b/skyflow/generated/rest/types/v_1_processed_file_output.py new file mode 100644 index 00000000..80968814 --- /dev/null +++ b/skyflow/generated/rest/types/v_1_processed_file_output.py @@ -0,0 +1,31 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .detect_file_request_data_type import DetectFileRequestDataType +from .processed_file_output_processed_file_type import ProcessedFileOutputProcessedFileType + + +class V1ProcessedFileOutput(UniversalBaseModel): + """ + Contains details and contents of the processed file. + """ + + output_type: typing.Optional[DetectFileRequestDataType] = None + processed_file: typing.Optional[str] = pydantic.Field(default=None) + """ + URL or base64-encoded data of the output. + """ + + processed_file_type: typing.Optional[ProcessedFileOutputProcessedFileType] = 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/types/v_1_response_entities.py b/skyflow/generated/rest/types/v_1_response_entities.py new file mode 100644 index 00000000..fbc0ecf4 --- /dev/null +++ b/skyflow/generated/rest/types/v_1_response_entities.py @@ -0,0 +1,43 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .v_1_locations import V1Locations + + +class V1ResponseEntities(UniversalBaseModel): + """ + Detected entities. + """ + + processed_text: typing.Optional[str] = pydantic.Field(default=None) + """ + Processed text of the entity. + """ + + original_text: typing.Optional[str] = pydantic.Field(default=None) + """ + Original text of the entity. + """ + + location: typing.Optional[V1Locations] = None + best_label: typing.Optional[str] = pydantic.Field(default=None) + """ + Highest rated label. + """ + + labels: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = pydantic.Field(default=None) + """ + Labels and their scores. + """ + + 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/types/vault_id.py b/skyflow/generated/rest/types/vault_id.py new file mode 100644 index 00000000..02ae7d21 --- /dev/null +++ b/skyflow/generated/rest/types/vault_id.py @@ -0,0 +1,3 @@ +# This file was auto-generated by Fern from our API Definition. + +VaultId = str 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/__init__.py b/skyflow/utils/__init__.py index d5b072f4..67905512 100644 --- a/skyflow/utils/__init__.py +++ b/skyflow/utils/__init__.py @@ -2,4 +2,4 @@ from ._skyflow_messages import SkyflowMessages from ._version import SDK_VERSION from ._helpers import get_base_url, format_scope -from ._utils import get_credentials, get_vault_url, construct_invoke_connection_request, get_metrics, parse_insert_response, handle_exception, parse_update_record_response, parse_delete_response, parse_detokenize_response, parse_tokenize_response, parse_query_response, parse_get_response, parse_invoke_connection_response, validate_api_key, encode_column_values +from ._utils import get_credentials, get_vault_url, construct_invoke_connection_request, get_metrics, parse_insert_response, handle_exception, parse_update_record_response, parse_delete_response, parse_detokenize_response, parse_tokenize_response, parse_query_response, parse_get_response, parse_invoke_connection_response, validate_api_key, encode_column_values, parse_deidentify_text_response, parse_reidentify_text_response, convert_detected_entity_to_entity_info diff --git a/skyflow/utils/_skyflow_messages.py b/skyflow/utils/_skyflow_messages.py index 4bc95354..89935214 100644 --- a/skyflow/utils/_skyflow_messages.py +++ b/skyflow/utils/_skyflow_messages.py @@ -71,6 +71,15 @@ 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." + OUTPUT_DIRECTORY_NOT_FOUND = f"{error_prefix} Validation error. Invalid output directory. Directory {{}} not found." + 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,6 +156,57 @@ 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 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." VALIDATING_VAULT_CONFIG = f"{INFO}: [{error_prefix}] Validating vault config." @@ -154,6 +214,7 @@ class Info(Enum): UNABLE_TO_GENERATE_SDK_METRIC = f"{INFO}: [{error_prefix}] Unable to generate {{}} metric." VAULT_CONTROLLER_INITIALIZED = f"{INFO}: [{error_prefix}] Initialized vault controller with vault ID {{}}." CONNECTION_CONTROLLER_INITIALIZED = f"{INFO}: [{error_prefix}] Initialized connection controller with connection ID {{}}." + DETECT_CONTROLLER_INITIALIZED = f"{INFO}: [{error_prefix}] Initialized detect controller with vault ID {{}}." VAULT_CONFIG_EXISTS = f"{INFO}: [{error_prefix}] Vault config with vault ID {{}} already exists." VAULT_CONFIG_DOES_NOT_EXIST = f"{INFO}: [{error_prefix}] Vault config with vault ID {{}} doesn't exist." CONNECTION_CONFIG_EXISTS = f"{INFO}: [{error_prefix}] Connection config with connection ID {{}} already exists." @@ -166,9 +227,13 @@ class Info(Enum): GET_BEARER_TOKEN_SUCCESS = f"{INFO}: [{error_prefix}] Bearer token generated." GET_SIGNED_DATA_TOKENS_TRIGGERED = f"{INFO}: [{error_prefix}] generate_signed_data_tokens method triggered." GET_SIGNED_DATA_TOKEN_SUCCESS = f"{INFO}: [{error_prefix}] Signed data tokens generated." - GENERATE_BEARER_TOKEN_FROM_CREDENTIALS_STRING_TRIGGERED = f"{INFO}: [{error_prefix}] generate bearer_token_from_credential_string method triggered ." + 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." @@ -210,6 +275,28 @@ class Info(Enum): INVOKE_CONNECTION_REQUEST_RESOLVED = f"{INFO}: [{error_prefix}] Invoke connection request resolved." INVOKE_CONNECTION_SUCCESS = f"{INFO}: [{error_prefix}] Invoke Connection Success." + DEIDENTIFY_TEXT_TRIGGERED = f"{INFO}: [{error_prefix}] Deidentify text method triggered." + VALIDATING_DEIDENTIFY_TEXT_INPUT = f"{INFO}: [{error_prefix}] Validating deidentify text input." + DEIDENTIFY_TEXT_REQUEST_RESOLVED = f"{INFO}: [{error_prefix}] Deidentify text request is resolved." + DEIDENTIFY_TEXT_SUCCESS = f"{INFO}: [{error_prefix}] Data deidentified." + + REIDENTIFY_TEXT_TRIGGERED = f"{INFO}: [{error_prefix}] Reidentify text method triggered." + VALIDATING_REIDENTIFY_TEXT_INPUT = f"{INFO}: [{error_prefix}] Validating reidentify text input." + REIDENTIFY_TEXT_REQUEST_RESOLVED = f"{INFO}: [{error_prefix}] Reidentify text request is resolved." + REIDENTIFY_TEXT_SUCCESS = f"{INFO}: [{error_prefix}] Data reidentified." + + DEIDENTIFY_FILE_TRIGGERED = f"{INFO}: [{error_prefix}] Deidentify file triggered." + VALIDATING_DETECT_FILE_INPUT = f"{INFO}: [{error_prefix}] Validating deidentify file input." + DEIDENTIFY_FILE_REQUEST_RESOLVED = f"{INFO}: [{error_prefix}] Deidentify file request is resolved." + DEIDENTIFY_FILE_SUCCESS = f"{INFO}: [{error_prefix}] File deidentified." + + GET_DETECT_RUN_TRIGGERED = f"{INFO}: [{error_prefix}] Get detect run triggered." + VALIDATING_GET_DETECT_RUN_INPUT = f"{INFO}: [{error_prefix}] Validating get detect run input." + GET_DETECT_RUN_REQUEST_RESOLVED = f"{INFO}: [{error_prefix}] Get detect run request is resolved." + GET_DETECT_RUN_SUCCESS = f"{INFO}: [{error_prefix}] Get detect run success." + + DETECT_REQUEST_RESOLVED = f"{INFO}: [{error_prefix}] Detect request is resolved." + class ErrorLogs(Enum): VAULTID_IS_REQUIRED = f"{ERROR}: [{error_prefix}] Invalid vault config. Vault ID is required." EMPTY_VAULTID = f"{ERROR}: [{error_prefix}] Invalid vault config. Vault ID can not be empty." @@ -280,6 +367,14 @@ class ErrorLogs(Enum): QUERY_REQUEST_REJECTED = f"{ERROR}: [{error_prefix}] Query request resulted in failure." GET_REQUEST_REJECTED = f"{ERROR}: [{error_prefix}] Get request resulted in failure." INVOKE_CONNECTION_REQUEST_REJECTED = f"{ERROR}: [{error_prefix}] Invoke connection request resulted in failure." + + EMPTY_RUN_ID = f"{ERROR}: [{error_prefix}] Validation error. Run id cannot be empty. Specify a valid run id." + INVALID_RUN_ID = f"{ERROR}: [{error_prefix}] Validation error. Invalid run id. Specify a valid run id as string." + DEIDENTIFY_FILE_REQUEST_REJECTED = f"{ERROR}: [{error_prefix}] Deidentify file resulted in failure." + 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 4dbd32a3..6b013a85 100644 --- a/skyflow/utils/_utils.py +++ b/skyflow/utils/_utils.py @@ -13,9 +13,12 @@ from urllib.parse import quote from skyflow.error import SkyflowError from skyflow.generated.rest import V1UpdateRecordResponse, V1BulkDeleteRecordResponse, \ - V1DetokenizeResponse, V1TokenizeResponse, V1GetQueryResponse, V1BulkGetRecordResponse + V1DetokenizeResponse, V1TokenizeResponse, V1GetQueryResponse, V1BulkGetRecordResponse, \ + 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 +from skyflow.vault.detect import EntityInfo, TextIndex from . import SkyflowMessages, SDK_VERSION from .constants import PROTOCOL from .enums import Env, ContentType, EnvUrls @@ -82,6 +85,22 @@ def to_lowercase_keys(dict): return result +def convert_detected_entity_to_entity_info(detected_entity): + return EntityInfo( + token=detected_entity.token, + value=detected_entity.value, + text_index=TextIndex( + start=detected_entity.location.start_index, + end=detected_entity.location.end_index + ), + processed_index=TextIndex( + start=detected_entity.location.start_index_processed, + end=detected_entity.location.end_index_processed + ), + entity=detected_entity.entity_type, + scores=detected_entity.entity_scores + ) + def construct_invoke_connection_request(request, connection_url, logger) -> PreparedRequest: url = parse_path_params(connection_url.rstrip('/'), request.path_params) @@ -364,6 +383,18 @@ def parse_invoke_connection_response(api_response: requests.Response): message = SkyflowMessages.Error.RESPONSE_NOT_JSON.value.format(content) raise SkyflowError(message, status_code) +def parse_deidentify_text_response(api_response: DeidentifyStringResponse): + entities = [convert_detected_entity_to_entity_info(entity) for entity in api_response.entities] + return DeidentifyTextResponse( + processed_text=api_response.processed_text, + entities=entities, + word_count=api_response.word_count, + char_count=api_response.character_count + ) + +def parse_reidentify_text_response(api_response: ReidentifyStringResponse): + return ReidentifyTextResponse(api_response.text) + def log_and_reject_error(description, status_code, request_id, http_status=None, grpc_code=None, details=None, logger = None): raise SkyflowError(description, status_code, request_id, grpc_code, http_status, details) @@ -390,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/_version.py b/skyflow/utils/_version.py index 22cfc2df..5613ead9 100644 --- a/skyflow/utils/_version.py +++ b/skyflow/utils/_version.py @@ -1 +1 @@ -SDK_VERSION = '2.0.0b3' \ No newline at end of file +SDK_VERSION = '2.0.0b3.dev0+afd7def' \ No newline at end of file diff --git a/skyflow/utils/enums/__init__.py b/skyflow/utils/enums/__init__.py index 5456737b..af293ce2 100644 --- a/skyflow/utils/enums/__init__.py +++ b/skyflow/utils/enums/__init__.py @@ -1,6 +1,12 @@ from .env import Env, EnvUrls from .log_level import LogLevel from .content_types import ContentType +from .detect_entities import DetectEntities 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_entities.py b/skyflow/utils/enums/detect_entities.py new file mode 100644 index 00000000..23b36bdc --- /dev/null +++ b/skyflow/utils/enums/detect_entities.py @@ -0,0 +1,66 @@ +from enum import Enum + +class DetectEntities(Enum): + ACCOUNT_NUMBER = "account_number" + AGE = "age" + ALL = "all" + BANK_ACCOUNT = "bank_account" + BLOOD_TYPE = "blood_type" + CONDITION = "condition" + CORPORATE_ACTION = "corporate_action" + CREDIT_CARD = "credit_card" + CREDIT_CARD_EXPIRATION = "credit_card_expiration" + CVV = "cvv" + DATE = "date" + DATE_INTERVAL = "date_interval" + DOB = "dob" + DOSE = "dose" + DRIVER_LICENSE = "driver_license" + DRUG = "drug" + DURATION = "duration" + EMAIL_ADDRESS = "email_address" + EVENT = "event" + FILENAME = "filename" + FINANCIAL_METRIC = "financial_metric" + GENDER_SEXUALITY = "gender_sexuality" + HEALTHCARE_NUMBER = "healthcare_number" + INJURY = "injury" + IP_ADDRESS = "ip_address" + LANGUAGE = "language" + LOCATION = "location" + LOCATION_ADDRESS = "location_address" + LOCATION_ADDRESS_STREET = "location_address_street" + LOCATION_CITY = "location_city" + LOCATION_COORDINATE = "location_coordinate" + LOCATION_COUNTRY = "location_country" + LOCATION_STATE = "location_state" + LOCATION_ZIP = "location_zip" + MARITAL_STATUS = "marital_status" + MEDICAL_CODE = "medical_code" + MEDICAL_PROCESS = "medical_process" + MONEY = "money" + NAME = "name" + NAME_FAMILY = "name_family" + NAME_GIVEN = "name_given" + NAME_MEDICAL_PROFESSIONAL = "name_medical_professional" + NUMERICAL_PII = "numerical_pii" + OCCUPATION = "occupation" + ORGANIZATION = "organization" + ORGANIZATION_MEDICAL_FACILITY = "organization_medical_facility" + ORIGIN = "origin" + PASSPORT_NUMBER = "passport_number" + PASSWORD = "password" + PHONE_NUMBER = "phone_number" + PHYSICAL_ATTRIBUTE = "physical_attribute" + POLITICAL_AFFILIATION = "political_affiliation" + PRODUCT = "product" + RELIGION = "religion" + ROUTING_NUMBER = "routing_number" + SSN = "ssn" + STATISTICS = "statistics" + TIME = "time" + TREND = "trend" + URL = "url" + USERNAME = "username" + VEHICLE_ID = "vehicle_id" + ZODIAC_SIGN = "zodiac_sign" \ 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/enums/token_type.py b/skyflow/utils/enums/token_type.py new file mode 100644 index 00000000..9e9e5fcf --- /dev/null +++ b/skyflow/utils/enums/token_type.py @@ -0,0 +1,6 @@ +from enum import Enum + +class TokenType(Enum): + VAULT_TOKEN = "vault_token" + ENTITY_UNIQUE_COUNTER = "entity_unq_counter" + ENTITY_ONLY = "entity_only" diff --git a/skyflow/utils/validations/__init__.py b/skyflow/utils/validations/__init__.py index 17bc49a7..b8ce13c8 100644 --- a/skyflow/utils/validations/__init__.py +++ b/skyflow/utils/validations/__init__.py @@ -13,4 +13,8 @@ validate_detokenize_request, validate_tokenize_request, validate_invoke_connection_params, + validate_deidentify_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 93d10468..9a837133 100644 --- a/skyflow/utils/validations/_validations.py +++ b/skyflow/utils/validations/_validations.py @@ -1,9 +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, \ + GetDetectRunRequest, Bleep, DeidentifyFileRequest valid_vault_config_keys = ["vault_id", "cluster_id", "credentials", "env"] valid_connection_config_keys = ["connection_id", "connection_url", "credentials"] @@ -252,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.OUTPUT_DIRECTORY_NOT_FOUND.value.format(request.output_directory), 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): @@ -572,3 +677,48 @@ def validate_invoke_connection_params(logger, query_params, path_params): json.dumps(query_params) except TypeError: raise SkyflowError(SkyflowMessages.Error.INVALID_QUERY_PARAMS.value, invalid_input_error_code) + +def validate_deidentify_text_request(self, request: DeidentifyTextRequest): + if not request.text or not isinstance(request.text, str) or not request.text.strip(): + raise SkyflowError(SkyflowMessages.Error.INVALID_TEXT_IN_DEIDENTIFY.value, invalid_input_error_code) + + # Validate entities if present + if request.entities is not None and not isinstance(request.entities, list): + raise SkyflowError(SkyflowMessages.Error.INVALID_ENTITIES_IN_DEIDENTIFY.value, invalid_input_error_code) + + # Validate allowed_regex_list if present + if request.allow_regex_list is not None and not isinstance(request.allow_regex_list, list): + raise SkyflowError(SkyflowMessages.Error.INVALID_ALLOW_REGEX_LIST.value, invalid_input_error_code) + + # Validate restricted_regex_list if present + if request.restrict_regex_list is not None and not isinstance(request.restrict_regex_list, list): + raise SkyflowError(SkyflowMessages.Error.INVALID_RESTRICT_REGEX_LIST.value, invalid_input_error_code) + + # Validate token_format if present + 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) + + # Validate transformations if present + if request.transformations is not None and not isinstance(request.transformations, Transformations): + raise SkyflowError(SkyflowMessages.Error.INVALID_TRANSFORMATIONS.value, invalid_input_error_code) + +def validate_reidentify_text_request(self, request: ReidentifyTextRequest): + if not request.text or not isinstance(request.text, str) or not request.text.strip(): + raise SkyflowError(SkyflowMessages.Error.INVALID_TEXT_IN_REIDENTIFY.value, invalid_input_error_code) + + # Validate redacted_entities if present + if request.redacted_entities is not None and not isinstance(request.redacted_entities, list): + raise SkyflowError(SkyflowMessages.Error.INVALID_REDACTED_ENTITIES_IN_REIDENTIFY.value, invalid_input_error_code) + + # Validate masked_entities if present + if request.masked_entities is not None and not isinstance(request.masked_entities, list): + raise SkyflowError(SkyflowMessages.Error.INVALID_MASKED_ENTITIES_IN_REIDENTIFY.value, invalid_input_error_code) + + # 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/client/client.py b/skyflow/vault/client/client.py index e3e543ae..f47a525c 100644 --- a/skyflow/vault/client/client.py +++ b/skyflow/vault/client/client.py @@ -42,6 +42,12 @@ def get_tokens_api(self): def get_query_api(self): return self.__api_client.query + + def get_detect_text_api(self): + return self.__api_client.strings + + def get_detect_file_api(self): + return self.__api_client.files def get_vault_id(self): return self.__config.get("vault_id") diff --git a/skyflow/vault/controller/__init__.py b/skyflow/vault/controller/__init__.py index 14301fb3..681153c0 100644 --- a/skyflow/vault/controller/__init__.py +++ b/skyflow/vault/controller/__init__.py @@ -1,2 +1,3 @@ from ._vault import Vault -from ._connections import Connection \ No newline at end of file +from ._connections import Connection +from ._detect import Detect \ No newline at end of file diff --git a/skyflow/vault/controller/_detect.py b/skyflow/vault/controller/_detect.py new file mode 100644 index 00000000..4a1c184c --- /dev/null +++ b/skyflow/vault/controller/_detect.py @@ -0,0 +1,409 @@ +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, DeidentifyFileRequest, DeidentifyFileResponse, GetDetectRunRequest + +class Detect: + def __init__(self, vault_client): + self.__vault_client = vault_client + + def __initialize(self): + self.__vault_client.initialize_client_configuration() + + def __get_headers(self): + headers = { + SKY_META_DATA_HEADER: json.dumps(get_metrics()) + } + return headers + + def ___build_deidentify_text_body(self, request: DeidentifyTextRequest) -> Dict[str, Any]: + deidentify_text_body = {} + parsed_entity_types = request.entities + + deidentify_text_body['text'] = request.text + deidentify_text_body['entity_types'] = parsed_entity_types + 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'] = self.__get_transformations(request) + + return deidentify_text_body + + def ___build_reidentify_text_body(self, request: ReidentifyTextRequest) -> Dict[str, Any]: + parsed_format = ReidentifyStringRequestFormat( + redacted=request.redacted_entities, + masked=request.masked_entities, + plaintext=request.plain_text_entities + ) + reidentify_text_body = {} + reidentify_text_body['text'] = request.text + 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().with_raw_response + 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()).data + 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' or status == 'FAILED': + return response + 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) + log_info(SkyflowMessages.Info.DEIDENTIFY_TEXT_REQUEST_RESOLVED.value, self.__vault_client.get_logger()) + self.__initialize() + detect_api = self.__vault_client.get_detect_text_api() + deidentify_text_body = self.___build_deidentify_text_body(request) + + try: + log_info(SkyflowMessages.Info.DEIDENTIFY_TEXT_TRIGGERED.value, self.__vault_client.get_logger()) + api_response = detect_api.deidentify_string( + vault_id=self.__vault_client.get_vault_id(), + text=deidentify_text_body['text'], + entity_types=deidentify_text_body['entity_types'], + allow_regex=deidentify_text_body['allow_regex'], + restrict_regex=deidentify_text_body['restrict_regex'], + token_type=deidentify_text_body['token_type'], + transformations=deidentify_text_body['transformations'], + request_options=self.__get_headers() + ) + deidentify_text_response = parse_deidentify_text_response(api_response) + log_info(SkyflowMessages.Info.DEIDENTIFY_TEXT_SUCCESS.value, self.__vault_client.get_logger()) + return deidentify_text_response + + except Exception as e: + log_error_log(SkyflowMessages.ErrorLogs.DEIDENTIFY_TEXT_REQUEST_REJECTED.value, self.__vault_client.get_logger()) + handle_exception(e, self.__vault_client.get_logger()) + + def reidentify_text(self, request: ReidentifyTextRequest) -> ReidentifyTextResponse: + log_info(SkyflowMessages.Info.VALIDATING_REIDENTIFY_TEXT_INPUT.value, self.__vault_client.get_logger()) + validate_reidentify_text_request(self.__vault_client.get_logger(), request) + log_info(SkyflowMessages.Info.REIDENTIFY_TEXT_REQUEST_RESOLVED.value, self.__vault_client.get_logger()) + self.__initialize() + detect_api = self.__vault_client.get_detect_text_api() + reidentify_text_body = self.___build_reidentify_text_body(request) + + try: + log_info(SkyflowMessages.Info.REIDENTIFY_TEXT_TRIGGERED.value, self.__vault_client.get_logger()) + api_response = detect_api.reidentify_string( + vault_id=self.__vault_client.get_vault_id(), + text=reidentify_text_body['text'], + format=reidentify_text_body['format'], + request_options=self.__get_headers() + ) + reidentify_text_response = parse_reidentify_text_response(api_response) + log_info(SkyflowMessages.Info.REIDENTIFY_TEXT_SUCCESS.value, self.__vault_client.get_logger()) + return reidentify_text_response + + 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 new file mode 100644 index 00000000..e385a1f2 --- /dev/null +++ b/skyflow/vault/detect/__init__.py @@ -0,0 +1,13 @@ +from ._date_transformation import DateTransformation +from ._deidentify_text_request import DeidentifyTextRequest +from ._deidentify_text_response import DeidentifyTextResponse +from ._entity_info import EntityInfo +from ._reidentify_text_request import ReidentifyTextRequest +from ._reidentify_text_response import ReidentifyTextResponse +from ._text_index import TextIndex +from ._token_format import TokenFormat +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/_date_transformation.py b/skyflow/vault/detect/_date_transformation.py new file mode 100644 index 00000000..c12199c2 --- /dev/null +++ b/skyflow/vault/detect/_date_transformation.py @@ -0,0 +1,8 @@ +from typing import List +from skyflow.utils.enums.detect_entities import DetectEntities + +class DateTransformation: + def __init__(self, max_days: int, min_days: int, entities: List[DetectEntities]): + self.max = max_days + self.min = min_days + self.entities = entities 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/_deidentify_text_request.py b/skyflow/vault/detect/_deidentify_text_request.py new file mode 100644 index 00000000..8b4a440d --- /dev/null +++ b/skyflow/vault/detect/_deidentify_text_request.py @@ -0,0 +1,19 @@ +from typing import List, Optional +from skyflow.utils.enums.detect_entities import DetectEntities +from ._token_format import TokenFormat +from ._transformations import Transformations + +class DeidentifyTextRequest: + def __init__(self, + text: str, + 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): + self.text = text + self.entities = entities + self.allow_regex_list = allow_regex_list + self.restrict_regex_list = restrict_regex_list + self.token_format = token_format + self.transformations = transformations diff --git a/skyflow/vault/detect/_deidentify_text_response.py b/skyflow/vault/detect/_deidentify_text_response.py new file mode 100644 index 00000000..cdb6632e --- /dev/null +++ b/skyflow/vault/detect/_deidentify_text_response.py @@ -0,0 +1,19 @@ +from typing import List +from ._entity_info import EntityInfo + +class DeidentifyTextResponse: + def __init__(self, + processed_text: str, + entities: List[EntityInfo], + word_count: int, + char_count: int): + self.processed_text = processed_text + self.entities = entities + self.word_count = word_count + self.char_count = char_count + + def __repr__(self): + return f"DeidentifyTextResponse(processed_text='{self.processed_text}', entities={self.entities}, word_count={self.word_count}, char_count={self.char_count})" + + def __str__(self): + return self.__repr__() \ No newline at end of file diff --git a/skyflow/vault/detect/_entity_info.py b/skyflow/vault/detect/_entity_info.py new file mode 100644 index 00000000..1eb5f132 --- /dev/null +++ b/skyflow/vault/detect/_entity_info.py @@ -0,0 +1,20 @@ +from typing import Dict +from ._text_index import TextIndex + +class EntityInfo: + def __init__(self, token: str, value: str, text_index: TextIndex, + processed_index: TextIndex, entity: str, scores: Dict[str, float]): + self.token = token + self.value = value + self.text_index = text_index + self.processed_index = processed_index + self.entity = entity + self.scores = scores + + def __repr__(self) -> str: + return (f"EntityInfo(token='{self.token}', value='{self.value}', " + f"text_index={self.text_index}, processed_index={self.processed_index}, " + f"entity='{self.entity}', scores={self.scores})") + + def __str__(self) -> str: + 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/skyflow/vault/detect/_reidentify_text_request.py b/skyflow/vault/detect/_reidentify_text_request.py new file mode 100644 index 00000000..7a7a744d --- /dev/null +++ b/skyflow/vault/detect/_reidentify_text_request.py @@ -0,0 +1,12 @@ +from typing import List, Optional +from skyflow.utils.enums.detect_entities import DetectEntities + +class ReidentifyTextRequest: + def __init__(self, text: str, + redacted_entities: Optional[List[DetectEntities]] = None, + masked_entities: Optional[List[DetectEntities]] = None, + plain_text_entities: Optional[List[DetectEntities]] = None): + self.text = text + self.redacted_entities = redacted_entities + self.masked_entities = masked_entities + self.plain_text_entities = plain_text_entities diff --git a/skyflow/vault/detect/_reidentify_text_response.py b/skyflow/vault/detect/_reidentify_text_response.py new file mode 100644 index 00000000..50c3876d --- /dev/null +++ b/skyflow/vault/detect/_reidentify_text_response.py @@ -0,0 +1,9 @@ +class ReidentifyTextResponse: + def __init__(self, processed_text: str): + self.processed_text = processed_text + + def __repr__(self) -> str: + return f"ReidentifyTextResponse(processed_text='{self.processed_text}')" + + def __str__(self) -> str: + return self.__repr__() \ No newline at end of file diff --git a/skyflow/vault/detect/_text_index.py b/skyflow/vault/detect/_text_index.py new file mode 100644 index 00000000..add71c53 --- /dev/null +++ b/skyflow/vault/detect/_text_index.py @@ -0,0 +1,10 @@ +class TextIndex: + def __init__(self, start: int, end: int): + self.start = start + self.end = end + + def __repr__(self): + return f"TextIndex(start={self.start}, end={self.end})" + + def __str__(self): + return self.__repr__() diff --git a/skyflow/vault/detect/_token_format.py b/skyflow/vault/detect/_token_format.py new file mode 100644 index 00000000..a8d2b2db --- /dev/null +++ b/skyflow/vault/detect/_token_format.py @@ -0,0 +1,13 @@ +from typing import List +from skyflow.utils.enums.detect_entities import DetectEntities +from skyflow.utils.enums.token_type import TokenType + +class TokenFormat: + def __init__(self, default: TokenType = TokenType.ENTITY_UNIQUE_COUNTER, + vault_token: List[DetectEntities] = None, + entity_unique_counter: List[DetectEntities] = None, + entity_only: List[DetectEntities] = None): + self.default = default + self.vault_token = vault_token + self.entity_unique_counter = entity_unique_counter + self.entity_only = entity_only diff --git a/skyflow/vault/detect/_transformations.py b/skyflow/vault/detect/_transformations.py new file mode 100644 index 00000000..af6bff56 --- /dev/null +++ b/skyflow/vault/detect/_transformations.py @@ -0,0 +1,5 @@ +from skyflow.vault.detect._date_transformation import DateTransformation + +class Transformations: + def __init__(self, shift_dates: DateTransformation): + self.shift_dates = shift_dates diff --git a/tests/utils/test__utils.py b/tests/utils/test__utils.py index a7306e7b..6324d9a7 100644 --- a/tests/utils/test__utils.py +++ b/tests/utils/test__utils.py @@ -7,11 +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 -from skyflow.utils._utils import parse_path_params, to_lowercase_keys, get_metrics + 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, 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 @@ -66,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"} @@ -418,3 +479,114 @@ def test_encode_column_values(self): result = encode_column_values(get_request) self.assertEqual(result, expected_encoded_values) + + def test_parse_deidentify_text_response(self): + """Test parsing deidentify text response with multiple entities.""" + mock_entity = Mock() + mock_entity.token = "token123" + mock_entity.value = "sensitive_value" + mock_entity.entity_type = "EMAIL" + mock_entity.entity_scores = {"EMAIL": 0.95} + mock_entity.location = Mock( + start_index=10, + end_index=20, + start_index_processed=15, + end_index_processed=25 + ) + + mock_api_response = Mock() + mock_api_response.processed_text = "Sample processed text" + mock_api_response.entities = [mock_entity] + mock_api_response.word_count = 3 + mock_api_response.character_count = 20 + + result = parse_deidentify_text_response(mock_api_response) + + self.assertEqual(result.processed_text, "Sample processed text") + self.assertEqual(result.word_count, 3) + self.assertEqual(result.char_count, 20) + self.assertEqual(len(result.entities), 1) + + entity = result.entities[0] + self.assertEqual(entity.token, "token123") + self.assertEqual(entity.value, "sensitive_value") + self.assertEqual(entity.entity, "EMAIL") + self.assertEqual(entity.scores, {"EMAIL": 0.95}) + self.assertEqual(entity.text_index.start, 10) + self.assertEqual(entity.text_index.end, 20) + self.assertEqual(entity.processed_index.start, 15) + self.assertEqual(entity.processed_index.end, 25) + + def test_parse_deidentify_text_response_no_entities(self): + """Test parsing deidentify text response with no entities.""" + mock_api_response = Mock() + mock_api_response.processed_text = "Sample processed text" + mock_api_response.entities = [] + mock_api_response.word_count = 3 + mock_api_response.character_count = 20 + + result = parse_deidentify_text_response(mock_api_response) + + self.assertEqual(result.processed_text, "Sample processed text") + self.assertEqual(result.word_count, 3) + self.assertEqual(result.char_count, 20) + self.assertEqual(len(result.entities), 0) + + def test_parse_reidentify_text_response(self): + """Test parsing reidentify text response.""" + mock_api_response = Mock() + mock_api_response.text = "Reidentified text with actual values" + + result = parse_reidentify_text_response(mock_api_response) + + self.assertEqual(result.processed_text, "Reidentified text with actual values") + + def test__convert_detected_entity_to_entity_info(self): + """Test converting detected entity to EntityInfo object.""" + mock_detected_entity = Mock() + mock_detected_entity.token = "token123" + mock_detected_entity.value = "sensitive_value" + mock_detected_entity.entity_type = "EMAIL" + mock_detected_entity.entity_scores = {"EMAIL": 0.95} + mock_detected_entity.location = Mock( + start_index=10, + end_index=20, + start_index_processed=15, + end_index_processed=25 + ) + + result = convert_detected_entity_to_entity_info(mock_detected_entity) + + self.assertEqual(result.token, "token123") + self.assertEqual(result.value, "sensitive_value") + self.assertEqual(result.entity, "EMAIL") + self.assertEqual(result.scores, {"EMAIL": 0.95}) + self.assertEqual(result.text_index.start, 10) + self.assertEqual(result.text_index.end, 20) + self.assertEqual(result.processed_index.start, 15) + self.assertEqual(result.processed_index.end, 25) + + def test__convert_detected_entity_to_entity_info_with_minimal_data(self): + """Test converting detected entity with minimal required data.""" + mock_detected_entity = Mock() + mock_detected_entity.token = "token123" + mock_detected_entity.value = None + mock_detected_entity.entity_type = "UNKNOWN" + mock_detected_entity.entity_scores = {} + mock_detected_entity.location = Mock( + start_index=0, + end_index=0, + start_index_processed=0, + end_index_processed=0 + ) + + result = convert_detected_entity_to_entity_info(mock_detected_entity) + + self.assertEqual(result.token, "token123") + self.assertIsNone(result.value) + self.assertEqual(result.entity, "UNKNOWN") + self.assertEqual(result.scores, {}) + self.assertEqual(result.text_index.start, 0) + self.assertEqual(result.text_index.end, 0) + self.assertEqual(result.processed_index.start, 0) + self.assertEqual(result.processed_index.end, 0) diff --git a/tests/vault/controller/test__detect.py b/tests/vault/controller/test__detect.py new file mode 100644 index 00000000..29db32dc --- /dev/null +++ b/tests/vault/controller/test__detect.py @@ -0,0 +1,579 @@ +import unittest +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, DeidentifyFileRequest, GetDetectRunRequest, DeidentifyFileResponse +from skyflow.utils.enums import DetectEntities, TokenType + +VAULT_ID = "test_vault_id" + +class TestDetect(unittest.TestCase): + def setUp(self): + # Mock vault client + self.vault_client = Mock() + self.vault_client.get_vault_id.return_value = VAULT_ID + self.vault_client.get_logger.return_value = Mock() + + # Create a Detect instance with the mock client + self.detect = Detect(self.vault_client) + + @patch("skyflow.vault.controller._detect.validate_deidentify_text_request") + @patch("skyflow.vault.controller._detect.parse_deidentify_text_response") + def test_deidentify_text_success(self, mock_parse_response, mock_validate): + # Mock API response + mock_api_response = Mock() + mock_api_response.data = { + 'text': '[TOKEN_1] lives in [TOKEN_2]', + 'entities': [ + { + 'token': 'Token1', + 'value': 'John', + 'text_index': {'start': 0, 'end': 4}, + 'processed_index': {'start': 0, 'end': 8}, + 'entity': 'NAME', + 'scores': {'confidence': 0.9} + } + ], + 'word_count': 4, + 'char_count': 20 + } + + # Create request + request = DeidentifyTextRequest( + text="John lives in NYC", + entities=[DetectEntities.NAME], + token_format=TokenFormat(default=TokenType.ENTITY_ONLY) + ) + + # Mock detect API + detect_api = self.vault_client.get_detect_text_api.return_value + detect_api.deidentify_string.return_value = mock_api_response + + # Call deidentify_text + response = self.detect.deidentify_text(request) + + # Assertions + mock_validate.assert_called_once_with(self.vault_client.get_logger(), request) + mock_parse_response.assert_called_once_with(mock_api_response) + detect_api.deidentify_string.assert_called_once() + + @patch("skyflow.vault.controller._detect.validate_reidentify_text_request") + @patch("skyflow.vault.controller._detect.parse_reidentify_text_response") + def test_reidentify_text_success(self, mock_parse_response, mock_validate): + # Mock API response + mock_api_response = Mock() + mock_api_response.data = { + 'text': 'John lives in NYC' + } + + # Create request + request = ReidentifyTextRequest( + text="Token1 lives in Token2", + redacted_entities=[DetectEntities.NAME] + ) + + # Mock detect API + detect_api = self.vault_client.get_detect_text_api.return_value + detect_api.reidentify_string.return_value = mock_api_response + + # Call reidentify_text + response = self.detect.reidentify_text(request) + + # Assertions + mock_validate.assert_called_once_with(self.vault_client.get_logger(), request) + mock_parse_response.assert_called_once_with(mock_api_response) + detect_api.reidentify_string.assert_called_once() + + @patch("skyflow.vault.controller._detect.validate_deidentify_text_request") + def test_deidentify_text_handles_generic_error(self, mock_validate): + request = DeidentifyTextRequest( + text="John lives in NYC", + entities=[DetectEntities.NAME] + ) + detect_api = self.vault_client.get_detect_text_api.return_value + detect_api.deidentify_string.side_effect = Exception("Generic Error") + + with self.assertRaises(Exception): + self.detect.deidentify_text(request) + + detect_api.deidentify_string.assert_called_once() + + @patch("skyflow.vault.controller._detect.validate_reidentify_text_request") + def test_reidentify_text_handles_generic_error(self, mock_validate): + request = ReidentifyTextRequest( + text="Token1 lives in Token2", + redacted_entities=[DetectEntities.NAME] + ) + detect_api = self.vault_client.get_detect_text_api.return_value + detect_api.reidentify_string.side_effect = Exception("Generic Error") + + with self.assertRaises(Exception): + self.detect.reidentify_text(request) + + 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 + + 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.object(Detect, "_Detect__poll_for_processed_file") + def test_deidentify_file_all_branches(self, mock_poll, mock_open, mock_basename, mock_base64, mock_validate): + """Test all file type branches with optimized mocking""" + + # Common mocks + file_content = b"test content" + mock_base64.b64encode.return_value = b"dGVzdCBjb250ZW50" + + # Prepare a generic processed_response for all branches + processed_response = Mock() + processed_response.status = "SUCCESS" + processed_response.output = [ + {"processedFile": "dGVzdCBjb250ZW50", "processedFileType": "pdf", "processedFileExtension": "pdf"} + ] + processed_response.word_character_count = Mock(word_count=1, character_count=1) + processed_response.size = 1 + processed_response.duration = 1 + processed_response.pages = 1 + processed_response.slides = 1 + processed_response.message = "" + processed_response.run_id = "runid123" + mock_poll.return_value = processed_response + + # Patch __parse_deidentify_file_response to return a valid DeidentifyFileResponse + with patch.object(self.detect, "_Detect__parse_deidentify_file_response", + return_value=DeidentifyFileResponse( + file="dGVzdCBjb250ZW50", type="pdf", extension="pdf", + word_count=1, char_count=1, size_in_kb=1, + duration_in_seconds=1, page_count=1, slide_count=1, + entities=[], run_id="runid123", status="SUCCESS", errors=[] + )) as mock_parse: + # Test configuration for different file types + test_cases = [ + ("test.pdf", "pdf", "deidentify_pdf"), + ("test.jpg", "jpg", "deidentify_image"), + ("test.pptx", "pptx", "deidentify_presentation"), + ("test.csv", "csv", "deidentify_spreadsheet"), + ("test.docx", "docx", "deidentify_document"), + ("test.json", "json", "deidentify_structured_text"), + ("test.xml", "xml", "deidentify_structured_text"), + ("test.unknown", "unknown", "deidentify_file") + ] + + for file_name, extension, api_method in test_cases: + with self.subTest(file_type=extension): + # Setup file mock + file_obj = Mock() + file_obj.read.return_value = file_content + file_obj.name = file_name + mock_basename.return_value = file_name + + # Setup request + 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" + + # Setup API mock + files_api = Mock() + files_api.with_raw_response = files_api + api_method_mock = Mock() + setattr(files_api, api_method, api_method_mock) + self.vault_client.get_detect_file_api.return_value = files_api + + # Setup API response + api_response = Mock() + api_response.data = Mock(run_id="runid123") + api_method_mock.return_value = api_response + + # Actually run the method + result = self.detect.deidentify_file(req) + self.assertIsInstance(result, DeidentifyFileResponse) + self.assertEqual(result.status, "SUCCESS") + self.assertEqual(result.file, "dGVzdCBjb250ZW50") + self.assertEqual(result.type, "pdf") + self.assertEqual(result.extension, "pdf") + @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() + files_api.with_raw_response = files_api + self.vault_client.get_detect_file_api.return_value = files_api + + call_count = {"count": 0} + + def get_run_side_effect(*args, **kwargs): + if call_count["count"] < 1: + call_count["count"] += 1 + in_progress = Mock() + in_progress.status = "IN_PROGRESS" + in_progress.message = "" + return Mock(data=in_progress) + else: + success = Mock() + success.status = "SUCCESS" + return Mock(data=success) + + files_api.get_run.side_effect = get_run_side_effect + + # Use max_wait_time > 1 to allow the loop to reach the SUCCESS status + 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() + files_api.with_raw_response = files_api + self.vault_client.get_detect_file_api.return_value = files_api + + # Always return FAILED on first call + def get_run_side_effect(*args, **kwargs): + failed = Mock() + failed.status = "FAILED" + failed.message = "fail" + return Mock(data=failed) + + files_api.get_run.side_effect = get_run_side_effect + + result = self.detect._Detect__poll_for_processed_file("runid123", max_wait_time=1) + self.assertEqual(result.status, "FAILED") + self.assertEqual(result.message, "fail") + + 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) + + def test_get_transformations_with_shift_dates(self): + + class DummyShiftDates: + max = 30 + min = 10 + entities = ["SSN"] + + class DummyTransformations: + shift_dates = DummyShiftDates() + + class DummyRequest: + transformations = DummyTransformations() + + request = DummyRequest() + result = self.detect._Detect__get_transformations(request) + + self.assertEqual(result, { + 'shift_dates': { + 'max_days': 30, + 'min_days': 10, + 'entity_types': ["SSN"] + } + }) + + @patch("skyflow.vault.controller._detect.time.sleep", return_value=None) + def test_poll_for_processed_file_timeout(self, mock_sleep): + """Test polling timeout returns IN_PROGRESS status""" + files_api = Mock() + files_api.with_raw_response = files_api + self.vault_client.get_detect_file_api.return_value = files_api + + # Always return IN_PROGRESS + def get_run_side_effect(*args, **kwargs): + in_progress = Mock() + in_progress.status = "IN_PROGRESS" + return Mock(data=in_progress) + + files_api.get_run.side_effect = get_run_side_effect + + result = self.detect._Detect__poll_for_processed_file("runid123", max_wait_time=1) + self.assertIsInstance(result, DeidentifyFileResponse) + self.assertEqual(result.status, "IN_PROGRESS") + self.assertEqual(result.run_id, "runid123") + + @patch("skyflow.vault.controller._detect.time.sleep", return_value=None) + def test_poll_for_processed_file_wait_time_calculation(self, mock_sleep): + """Test wait time calculation in polling loop""" + files_api = Mock() + files_api.with_raw_response = files_api + self.vault_client.get_detect_file_api.return_value = files_api + + calls = [] + + def track_sleep(*args): + calls.append(args[0]) # Record wait time + + mock_sleep.side_effect = track_sleep + + # Return IN_PROGRESS twice then SUCCESS + responses = [ + Mock(data=Mock(status="IN_PROGRESS")), + Mock(data=Mock(status="IN_PROGRESS")), + Mock(data=Mock(status="SUCCESS")) + ] + files_api.get_run.side_effect = responses + + result = self.detect._Detect__poll_for_processed_file("runid123", max_wait_time=4) + + self.assertEqual(calls, [2, 2]) + self.assertEqual(result.status, "SUCCESS") + + + def test_parse_deidentify_file_response_output_conversion(self): + """Test output conversion in parse_deidentify_file_response""" + + class OutputObj: + processed_file = "file123" + processed_file_type = "pdf" + processed_file_extension = "pdf" + + data = Mock() + data.output = [OutputObj()] + data.word_character_count = Mock(word_count=1, character_count=1) + + result = self.detect._Detect__parse_deidentify_file_response(data) + + self.assertEqual(result.file, "file123") + self.assertEqual(result.type, "pdf") + self.assertEqual(result.extension, "pdf") \ No newline at end of file