From ff46ae8360c48f01cd7782c69e6bafa6f9a25817 Mon Sep 17 00:00:00 2001 From: Himanshu Rahul Date: Wed, 26 Nov 2025 18:31:59 +0530 Subject: [PATCH 1/8] SK-2415 Updated Readme --- README.md | 127 +++++++----------------------------------------------- 1 file changed, 16 insertions(+), 111 deletions(-) diff --git a/README.md b/README.md index bb5d1c0..17d5e7e 100644 --- a/README.md +++ b/README.md @@ -130,14 +130,11 @@ credentials = { - Use only ONE authentication method. - API Key or Environment Variables are recommended for production use. - Secure storage of credentials is essential. -- For overriding behavior and priority order of credentials, please refer to [Initialize the client](#initialize-the-client) section in [Quickstart](#quickstart). ### Initializing the client In V2, we have introduced a Builder design pattern for client initialization and added support for multi-vault. This allows you to configure multiple vaults during client initialization. -In V2, the log level is tied to each individual client instance. - During client initialization, you can pass the following parameters: - **`vault_id`** and **`cluster_id`**: These values are derived from the vault ID & vault URL. @@ -330,123 +327,31 @@ credentials = { ### Initialize the client -To get started, you must first initialize the skyflow client. While initializing the skyflow client, you can specify different types of credentials. -**1. API keys** -- A unique identifier used to authenticate and authorize requests to an API. - -**2. Bearer tokens** -- A temporary access token used to authenticate API requests, typically included in the -Authorization header. - -**3. Service account credentials file path** -- The file path pointing to a JSON file containing credentials for a service account, used -for secure API access. - -**4. Service account credentials string** -- A JSON-formatted string containing service account credentials, often used as an alternative to a file for programmatic authentication. - -Note: Only one type of credential can be used at a time. +To get started, you must first initialize the skyflow client. While initializing the skyflow client, you can specify different types of credentials. ```python -import json -from skyflow import Skyflow -from skyflow import LogLevel -from skyflow import Env - -""" -Example program to initialize the Skyflow client with various configurations. -The Skyflow client facilitates secure interactions with the Skyflow vault, -such as securely managing sensitive data. -""" - -# Step 1: Define the primary credentials for authentication. -# Note: Only one type of credential can be used at a time. You can choose between: -# - API key -# - Bearer token -# - A credentials string (JSON-formatted) -# - A file path to a credentials file. - -# Initialize primary credentials using a Bearer token for authentication. -primary_credentials = { - 'token': '' # Replace with your actual authentication token. -} - -# Step 2: Configure the primary vault details. -# VaultConfig stores all necessary details to connect to a specific Skyflow vault. -primary_vault_config = { - 'vault_id': '', # Replace with your primary vault's ID. - 'cluster_id': '', # Replace with the cluster ID (part of the vault URL, e.g., https://{clusterId}.vault.skyflowapis.com). - 'env': Env.PROD, # Set the environment (PROD, SANDBOX, STAGE, DEV). - 'credentials': primary_credentials # Attach the primary credentials to this vault configuration. -} +from skyflow import Skyflow, LogLevel, Env -# Step 3: Create credentials as a JSON object (if a Bearer Token is not provided). -# Demonstrates an alternate approach to authenticate with Skyflow using a credentials object. -skyflow_credentials = { - 'clientID': '', # Replace with your Client ID. - 'clientName': '', # Replace with your Client Name. - 'tokenURI': '', # Replace with the Token URI. - 'keyID': '', # Replace with your Key ID. - 'privateKey': '' # Replace with your Private Key. -} - -# Step 4: Convert the JSON object to a string and use it as credentials. -# This approach allows the use of dynamically generated or pre-configured credentials. -credentials_string = json.dumps(skyflow_credentials) # Converts JSON object to string for use as credentials. - -# Step 5: Define secondary credentials (API key-based authentication as an example). -# Demonstrates a different type of authentication mechanism for Skyflow vaults. -secondary_credentials = { - 'token': '' # Replace with your API Key for authentication. -} - -# Step 6: Configure the secondary vault details. -# A secondary vault configuration can be used for operations involving multiple vaults. -secondary_vault_config = { - 'vault_id': '', # Replace with your secondary vault's ID. - 'cluster_id': '', # Replace with the corresponding cluster ID. - 'env': Env.PROD, # Set the environment for this vault. - 'credentials': secondary_credentials # Attach the secondary credentials to this configuration. -} - -# Step 7: Define tertiary credentials using a path to a credentials JSON file. -# This method demonstrates an alternative authentication method. -tertiary_credentials = { - 'token': '' # Replace with the path to your credentials file. -} - -# Step 8: Configure the tertiary vault details. -tertiary_vault_config = { - 'vault_id': '', # Replace with the tertiary vault ID. - 'cluster_id': '', # Replace with the corresponding cluster ID. - 'env': Env.PROD, # Set the environment for this vault. - 'credentials': tertiary_credentials # Attach the tertiary credentials. +# Configure vault +config = { + 'vault_id': '', # Replace with your Vault ID + 'cluster_id': '', # Replace with your Cluster ID (e.g., from the Vault URL) + 'env': Env.PROD, # Environment (SANDBOX, DEV, PROD) + 'credentials': { + 'token': '' # Your Bearer Token + } } -# Step 9: Build and initialize the Skyflow client. -# Skyflow client is configured with multiple vaults and credentials. -skyflow_client = ( +# Initialize Skyflow client +client = ( Skyflow.builder() - .add_vault_config(primary_vault_config) # Add the primary vault configuration. - .add_vault_config(secondary_vault_config) # Add the secondary vault configuration. - .add_vault_config(tertiary_vault_config) # Add the tertiary vault configuration. - .add_skyflow_credentials(skyflow_credentials) # Add JSON-formatted credentials if applicable. - .set_log_level(LogLevel.ERROR) # Set log level for debugging or monitoring purposes. + .add_vault_config(config) + .set_log_level(LogLevel.ERROR) .build() ) - -# The Skyflow client is now fully initialized. -# Use the `skyflow_client` object to perform secure operations such as: -# - Inserting data -# - Retrieving data -# - Deleting data -# within the configured Skyflow vaults. - ``` -Notes -- If both Skyflow common credentials and individual credentials at the configuration level are specified, the individual credentials at the configuration level will take precedence. -- If neither Skyflow common credentials nor individual configuration-level credentials are provided, the SDK attempts to retrieve credentials from the SKYFLOW_CREDENTIALS environment variable. -- All Vault operations require a client instance. + +See [docs/advanced_initialization.md](docs/advanced_initialization.md) for advanced initialization examples including multiple vaults and different credential types. ### Insert data into the vault To insert data into your vault, use the `insert` method. The `InsertRequest` class creates an insert request, which includes the values to be inserted as a list of records. Below is a simple example to get started. For advanced options, check out [Insert data into the vault](#insert-data-into-the-vault-1) section. From 51a72e5ab0bbc8294adeaa9880a8e2c3b4524544 Mon Sep 17 00:00:00 2001 From: skyflow-himanshu Date: Wed, 26 Nov 2025 18:57:34 +0530 Subject: [PATCH 2/8] SK-2415 Added advanced initialization docs --- docs/advanced_initialization.md | 123 ++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 docs/advanced_initialization.md diff --git a/docs/advanced_initialization.md b/docs/advanced_initialization.md new file mode 100644 index 0000000..8fe2911 --- /dev/null +++ b/docs/advanced_initialization.md @@ -0,0 +1,123 @@ +# Advanced Skyflow Client Initialization + +This guide demonstrates advanced initialization patterns for the Skyflow Python SDK, including multiple vault configurations and different credential types. + +Use multiple vault configurations when your application needs to access data across different Skyflow vaults, such as managing data across different geographic regions or distinct environments. + +To get started, you must first initialize the skyflow client. While initializing the skyflow client, you can specify different types of credentials. +**1. API keys** +- A unique identifier used to authenticate and authorize requests to an API. + +**2. Bearer tokens** +- A temporary access token used to authenticate API requests, typically included in the +Authorization header. + +**3. Service account credentials file path** +- The file path pointing to a JSON file containing credentials for a service account, used +for secure API access. + +**4. Service account credentials string** +- A JSON-formatted string containing service account credentials, often used as an alternative to a file for programmatic authentication. + +Note: Only one type of credential can be used at a time. + +```python +import json +from skyflow import Skyflow +from skyflow import LogLevel +from skyflow import Env + +""" +Example program to initialize the Skyflow client with various configurations. +The Skyflow client facilitates secure interactions with the Skyflow vault, +such as securely managing sensitive data. +""" + +# Step 1: Define the primary credentials for authentication. +# Note: Only one type of credential can be used at a time. You can choose between: +# - API key +# - Bearer token +# - A credentials string (JSON-formatted) +# - A file path to a credentials file. + +# Initialize primary credentials using a Bearer token for authentication. +primary_credentials = { + 'token': '' # Replace with your actual authentication token. +} + +# Step 2: Configure the primary vault details. +# VaultConfig stores all necessary details to connect to a specific Skyflow vault. +primary_vault_config = { + 'vault_id': '', # Replace with your primary vault's ID. + 'cluster_id': '', # Replace with the cluster ID (part of the vault URL, e.g., https://{clusterId}.vault.skyflowapis.com). + 'env': Env.PROD, # Set the environment (PROD, SANDBOX, STAGE, DEV). + 'credentials': primary_credentials # Attach the primary credentials to this vault configuration. +} + +# Step 3: Create credentials as a JSON object (if a Bearer Token is not provided). +# Demonstrates an alternate approach to authenticate with Skyflow using a credentials object. +skyflow_credentials = { + 'clientID': '', # Replace with your Client ID. + 'clientName': '', # Replace with your Client Name. + 'tokenURI': '', # Replace with the Token URI. + 'keyID': '', # Replace with your Key ID. + 'privateKey': '' # Replace with your Private Key. +} + +# Step 4: Convert the JSON object to a string and use it as credentials. +# This approach allows the use of dynamically generated or pre-configured credentials. +credentials_string = json.dumps(skyflow_credentials) # Converts JSON object to string for use as credentials. + +# Step 5: Define secondary credentials (API key-based authentication as an example). +# Demonstrates a different type of authentication mechanism for Skyflow vaults. +secondary_credentials = { + 'token': '' # Replace with your API Key for authentication. +} + +# Step 6: Configure the secondary vault details. +# A secondary vault configuration can be used for operations involving multiple vaults. +secondary_vault_config = { + 'vault_id': '', # Replace with your secondary vault's ID. + 'cluster_id': '', # Replace with the corresponding cluster ID. + 'env': Env.PROD, # Set the environment for this vault. + 'credentials': secondary_credentials # Attach the secondary credentials to this configuration. +} + +# Step 7: Define tertiary credentials using a path to a credentials JSON file. +# This method demonstrates an alternative authentication method. +tertiary_credentials = { + 'token': '' # Replace with the path to your credentials file. +} + +# Step 8: Configure the tertiary vault details. +tertiary_vault_config = { + 'vault_id': '', # Replace with the tertiary vault ID. + 'cluster_id': '', # Replace with the corresponding cluster ID. + 'env': Env.PROD, # Set the environment for this vault. + 'credentials': tertiary_credentials # Attach the tertiary credentials. +} + +# Step 9: Build and initialize the Skyflow client. +# Skyflow client is configured with multiple vaults and credentials. +skyflow_client = ( + Skyflow.builder() + .add_vault_config(primary_vault_config) # Add the primary vault configuration. + .add_vault_config(secondary_vault_config) # Add the secondary vault configuration. + .add_vault_config(tertiary_vault_config) # Add the tertiary vault configuration. + .add_skyflow_credentials(skyflow_credentials) # Add JSON-formatted credentials if applicable. + .set_log_level(LogLevel.ERROR) # Set log level for debugging or monitoring purposes. + .build() +) + +# The Skyflow client is now fully initialized. +# Use the `skyflow_client` object to perform secure operations such as: +# - Inserting data +# - Retrieving data +# - Deleting data +# within the configured Skyflow vaults. + +``` +Notes +- If both Skyflow common credentials and individual credentials at the configuration level are specified, the individual credentials at the configuration level will take precedence. +- If neither Skyflow common credentials nor individual configuration-level credentials are provided, the SDK attempts to retrieve credentials from the SKYFLOW_CREDENTIALS environment variable. +- All Vault operations require a client instance. \ No newline at end of file From 604b29361210c2a8ead8b6520bd6eb4d6cf52ce1 Mon Sep 17 00:00:00 2001 From: skyflow-himanshu Date: Thu, 27 Nov 2025 18:54:25 +0530 Subject: [PATCH 3/8] SK-2415 Added v2 migration guide and auth credentials into docs --- docs/advanced_initialization.md | 6 +- docs/auth_credentials.md | 44 ++++++ docs/migrate_to_v2.md | 242 ++++++++++++++++++++++++++++++++ 3 files changed, 287 insertions(+), 5 deletions(-) create mode 100644 docs/auth_credentials.md create mode 100644 docs/migrate_to_v2.md diff --git a/docs/advanced_initialization.md b/docs/advanced_initialization.md index 8fe2911..3eb5532 100644 --- a/docs/advanced_initialization.md +++ b/docs/advanced_initialization.md @@ -116,8 +116,4 @@ skyflow_client = ( # - Deleting data # within the configured Skyflow vaults. -``` -Notes -- If both Skyflow common credentials and individual credentials at the configuration level are specified, the individual credentials at the configuration level will take precedence. -- If neither Skyflow common credentials nor individual configuration-level credentials are provided, the SDK attempts to retrieve credentials from the SKYFLOW_CREDENTIALS environment variable. -- All Vault operations require a client instance. \ No newline at end of file +``` \ No newline at end of file diff --git a/docs/auth_credentials.md b/docs/auth_credentials.md new file mode 100644 index 0000000..42409dc --- /dev/null +++ b/docs/auth_credentials.md @@ -0,0 +1,44 @@ +# Authentication credentials options + +> **Note:** Only one type of credential can be used at a time. If multiple credentials are provided, the order of precedence depends on how they are passed to the configuration. + +1. **API keys** + A unique identifier used to authenticate and authorize requests to an API. + + ```python + credentials = { + "api_key": "" + } + ``` + +2. **Bearer tokens** + A temporary access token used to authenticate API requests, typically included in the + Authorization header. + + ```python + credentials = { + "token": "" + } + ``` + +3. **Service account credentials file path** + The file path pointing to a JSON file containing credentials for a service account, used + for secure API access. + + ```python + credentials = { + "path": "" + } + ``` + +4. **Service account credentials string** + JSON-formatted string containing service account credentials, often used as an alternative to a file for programmatic authentication. + + ```python + credentials = { + "credentials_string": os.getenv("SKYFLOW_CREDENTIALS_JSON_STRING") + } + ``` + +5. **Environment variables** + If no credentials are explicitly provided the SDK automatically looks for the SKYFLOW_CREDENTIALS environment variable. This variable must return an object like one of the examples above. diff --git a/docs/migrate_to_v2.md b/docs/migrate_to_v2.md new file mode 100644 index 0000000..833129a --- /dev/null +++ b/docs/migrate_to_v2.md @@ -0,0 +1,242 @@ +# Migrate from V1 to V2 + +This guide outlines the steps required to migrate the Skyflow Python SDK from version 1 (V1) to version 2 (V2). + +## Authentication + +In V2, multiple authentication options have been introduced. You can now provide credentials in the following ways: + +- **Passing credentials in ENV** (`SKYFLOW_CREDENTIALS`) (**Recommended**) +- **API Key** +- **Path to your credentials JSON file** +- **Stringified JSON of your credentials** +- **Bearer token** + +These options allow you to choose the authentication method that best suits your use case. + +### V1 (Old): Passing the token provider function below as a parameter to the Configuration. + +```python +# User defined function to provide access token to the vault apis +def token_provider(): + global bearerToken + if !(is_expired(bearerToken)): + return bearerToken + bearerToken, _ = generate_bearer_token('') + return bearerToken +``` + +#### V2 (New): Passing one of the following: + +```python +# Option 1: API Key (Recommended) +credentials = { + 'api_key': '', # API key +} + +# Option 2: Environment Variables (Recommended) +# Set SKYFLOW_CREDENTIALS in your environment + +# Option 3: Credentials File +credentials = { + 'path': '', # Path to credentials file +} + +# Option 4: Stringified JSON +credentials = { + 'credentials_string': '', # Credentials as string +} + +# Option 5: Bearer Token +credentials = { + 'token': '', # Bearer token +} +``` + +**Notes:** +- Use only ONE authentication method. +- API Key or Environment Variables are recommended for production use. +- Secure storage of credentials is essential. + +### Initializing the client + +In V2, we have introduced a Builder design pattern for client initialization and added support for multi-vault. This allows you to configure multiple vaults during client initialization. + +During client initialization, you can pass the following parameters: + +- **`vault_id`** and **`cluster_id`**: These values are derived from the vault ID & vault URL. +- **`env`**: Specify the environment (e.g., SANDBOX or PROD). +- **`credentials`**: The necessary authentication credentials. + +#### V1 (Old): + +```python +# Initializing a Skyflow Client instance with a SkyflowConfiguration object +config = Configuration('', '', token_provider) +client = Client(config) +``` + +#### V2 (New): + +```python +# Initializing a Skyflow Client instance +client = ( + Skyflow.builder() + .add_vault_config({ + 'vault_id': '', # Primary vault + 'cluster_id': '', # ID from your vault URL e.g., https://{clusterId}.vault.skyflowapis.com + 'env': Env.PROD, # Env by default it is set to PROD + 'credentials': credentials # Individual credentials + }) + .add_skyflow_credentials(credentials) # Skyflow credentials will be used if no individual credentials are passed + .set_log_level(LogLevel.INFO) # set log level by default it is set to ERROR + .build() +) +``` + +**Key Changes:** +- `vault_url` replaced with `cluster_Id`. +- Added environment specification (`env`). +- Instance-specific log levels. + +### Request & Response Structure + +In V2, with the introduction of constructor parameters, you can now pass parameters to `InsertRequest`. This request need +- **`table_name`**: The name of the table. +- **`values`**: An array of objects containing the data to be inserted. +The response will be of type `InsertResponse` class, which contains `inserted_fields` and errors. + +**Note:** Similar patterns apply to other operations like Get, Update, Delete. See the [README](../README.md) for complete examples. + +#### V1 (Old): Request Building + +```python +client.insert( + { + "records": [ + { + "table": "cards", + "fields": { + "cardNumber": "41111111111", + "cvv": "123", + }, + } + ] + }, + InsertOptions(True), +) +``` + +#### V2 (New): Request Building + +```python +# Prepare Insertion Data +insert_data = [ + { + 'card_number': '', + 'cvv': '', + }, +] + +table_name = '' # Replace with your actual table name + +# Create Insert Request +insert_request = InsertRequest( + table=table_name, + values=insert_data, + return_tokens=True, # Optional: Get tokens for inserted data + continue_on_error=True # Optional: Continue on partial errors +) + +# Perform Secure Insertion +response = skyflow_client.vault(primary_vault_config.get('')).insert(insert_request) +``` + +#### V1 (Old): Response Structure + +```json +{ + "records": [ + { + "table": "cards", + "fields": { + "cardNumber": "f3907186-e7e2-466f-91e5-48e12c2bcbc1", + "cvv": "1989cb56-63da-4482-a2df-1f74cd0dd1a5", + "skyflow_id": "d863633c-8c75-44fc-b2ed-2b58162d1117" + }, + "request_index": 0 + } + ] +} +``` + +#### V2 (New): Response Structure + +```python +InsertResponse( + inserted_fields=[ + { + 'skyflow_id': 'a8f3ed5d-55eb-4f32-bf7e-2dbf4b9d9097', + 'card_number': '5479-4229-4622-1393' + } + ], + errors=[] +) +``` + +### Request Options + +In V2, we have introduced constructor parameters, allowing you to set options as key-value pairs as parameters in request. + +#### V1 (Old): + +```python +options = InsertOptions( + tokens = True +) +``` + +#### V2 (New): + +```python +insert_request = InsertRequest( + table=table_name, # Replace with the table name + values=insert_data, + return_tokens=False, # Do not return tokens + continue_on_error=False, # Stop inserting if any record fails + upsert='', # Replace with the column name used for upsert logic + token_mode=TokenMode.DISABLE, # Disable BYOT + tokens='' # Replace with tokens when TokenMode is ENABLE. +) +``` + +### Error Structure + +In V2, we have enriched the error details to provide better debugging capabilities. +The error response now includes: +- **http_status**: The HTTP status code. +- **grpc_code**: The gRPC code associated with the error. +- **details** & **message**: A detailed description of the error. +- **request_id**: A unique request identifier for easier debugging. + +#### V1 (Old) Error Structure: + +```json +{ + "code": "", + "message": "" +} +``` + +#### V2 (New) Error Structure: + +```typescript +{ + "http_status": "", + "grpc_code": , + "http_code": , + "message": "", + "request_id": "", + "details": [ "
" ] +} +``` \ No newline at end of file From f4f41d24cb533f80f4601e36c33406058cee8259 Mon Sep 17 00:00:00 2001 From: skyflow-himanshu Date: Fri, 28 Nov 2025 19:33:53 +0530 Subject: [PATCH 4/8] SK-2415 Refactored Readme to reduce lines of codes under 1000 --- README.md | 3058 +++++++++-------------------------------------------- 1 file changed, 514 insertions(+), 2544 deletions(-) diff --git a/README.md b/README.md index 17d5e7e..8562e6c 100644 --- a/README.md +++ b/README.md @@ -1,65 +1,78 @@ -# Skyflow Python +# Skyflow Python SDK The Skyflow Python SDK is designed to help with integrating Skyflow into a Python backend. ## Table of Contents -- [Table of Contents](#table-of-contents) -- [Overview](#overview) -- [Install](#installation) - - [Requirements](#requirements) - - [Configuration](#configuration) -- [Migration from v1 to v2](#migration-from-v1-to-v2) - - [Authentication options](#authentication-options) - - [Initializing the client](#initializing-the-client) - - [Request & response structure](#request--response-structure) - - [Request options](#request-options) - - [Error structure](#error-structure) -- [Quickstart](#quickstart) - - [Authenticate](#authenticate) - - [Initialize the client](#initialize-the-client) - - [Insert data into the vault](#insert-data-into-the-vault) -- [Vault](#vault) - - [Insert data into the vault](#insert-data-into-the-vault) - - [Detokenize](#detokenize) - - [Tokenize](#tokenize) - - [Get](#get) - - [Get by skyflow IDs](#get-by-skyflow-ids) - - [Get tokens](#get-tokens) - - [Get by column name and column values](#get-by-column-name-and-column-values) - - [Redaction types](#redaction-types) - - [Update](#update) - - [Delete](#delete) - - [Query](#query) - - [Upload File](#upload-file) -- [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) - - [Generate a bearer token](#generate-a-bearer-token) - - [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) +- [Skyflow Python SDK](#skyflow-python-sdk) + - [Table of Contents](#table-of-contents) + - [Overview](#overview) + - [Installation](#installation) + - [Require](#require) + - [Configuration](#configuration) + - [Quickstart](#quickstart) + - [Authenticate](#authenticate) + - [API Key](#api-key) + - [Bearer Token (static)](#bearer-token-static) + - [Initialize the client](#initialize-the-client) + - [Insert data into the vault, get tokens back](#insert-data-into-the-vault-get-tokens-back) + - [Upgrade from v1 to v2](#upgrade-from-v1-to-v2) + - [Vault](#vault) + - [Insert and tokenize data: `.insert(request)`](#insert-and-tokenize-data-insertrequest) + - [Insert example with `continue_on_error` option](#insert-example-with-continue_on_error-option) + - [Upsert request](#upsert-request) + - [Detokenize: `.detokenize(request, options)`](#detokenize-detokenizerequest-options) + - [Construct a detokenize request](#construct-a-detokenize-request) + - [Get Record(s): `.get(request)`](#get-records-getrequest) + - [Construct a get request](#construct-a-get-request) + - [Get by Skyflow IDs](#get-by-skyflow-ids) + - [Get tokens for records](#get-tokens-for-records) + - [Get by column name and column values](#get-by-column-name-and-column-values) + - [Redaction Types](#redaction-types) + - [Update Records](#update-records) + - [Construct an update request](#construct-an-update-request) + - [Delete Records](#delete-records) + - [Query](#query) + - [Upload File](#upload-file) + - [Retrieve Existing Tokens: `.tokenize(request)`](#retrieve-existing-tokens-tokenizerequest) + - [Construct a `.tokenize()` request](#construct-a-tokenize-request) + - [Detect](#detect) + - [De-identify Text: `.deidentify_text(request)`](#de-identify-text-deidentify_textrequest) + - [Re-identify Text: `.reidentify_text(request)`](#re-identify-text-reidentify_textrequest) + - [De-identify File: `.deidentify_file(request)`](#de-identify-file-deidentify_filerequest) + - [Get Run: `.get_detect_run(request)`](#get-run-get_detect_runrequest) + - [Connections](#connections) + - [Invoke a connection](#invoke-a-connection) + - [Construct an invoke connection request](#construct-an-invoke-connection-request) + - [Authentication & authorization](#authentication--authorization) + - [Types of `credentials`](#types-of-credentials) + - [Generate bearer tokens for authentication & authorization](#generate-bearer-tokens-for-authentication--authorization) + - [Generate a bearer token](#generate-a-bearer-token) + - [`generate_bearer_token(filepath)`](#generate_bearer_tokenfilepath) + - [`generate_bearer_token_from_creds(credentials)`](#generate_bearer_token_from_credscredentials) + - [Generate bearer tokens scoped to certain roles](#generate-bearer-tokens-scoped-to-certain-roles) + - [Generate bearer tokens with `ctx` for context-aware authorization](#generate-bearer-tokens-with-ctx-for-context-aware-authorization) + - [Generate signed data tokens: `generate_signed_data_tokens(filepath, options)`](#generate-signed-data-tokens-generate_signed_data_tokensfilepath-options) + - [Logging](#logging) + - [Example: Setting LogLevel to INFO](#example-setting-loglevel-to-info) + - [Error handling](#error-handling) + - [Catching `SkyflowError` instances](#catching-skyflowerror-instances) + - [Bearer token expiration edge cases](#bearer-token-expiration-edge-cases) + - [Security](#security) + - [Reporting a Vulnerability](#reporting-a-vulnerability) ## Overview -- Authenticate using a Skyflow service account and generate bearer tokens for secure access. - -- Perform Vault API operations such as inserting, retrieving, and tokenizing sensitive data with ease. - -- Invoke connections to third-party APIs without directly handling sensitive data, ensuring compliance and data protection. +The Skyflow SDK enables you to connect to your Skyflow Vault(s) to securely handle sensitive data at rest, in-transit, and in-use. +> [!IMPORTANT] +> This readme documents SDK version 2. +> For version 1 see the [v1.16.0 README](https://github.com/skyflowapi/skyflow-python/tree/v1). +> For more information on how to migrate see [MIGRATE_TO_V2.md](docs/migrate_to_v2.md). ## Installation -### Requirements +### Require - Python 3.8.0 and above (tested with Python 3.8.0) @@ -70,2686 +83,644 @@ The package can be installed using pip: ```bash pip install skyflow ``` -## Migration from V1 to V2 - -Below are the steps to migrate the Python SDK from V1 to V2. - -### Authentication Options -In V2, we have introduced multiple authentication options. -You can now provide credentials in the following ways: - -- **Passing credentials in ENV.** (`SKYFLOW_CREDENTIALS`) (**Recommended**) -- **API Key** -- **Path to your credentials JSON file** -- **Stringified JSON of your credentials** -- **Bearer token** +## Quickstart -These options allow you to choose the authentication method that best suits your use case. +Get started quickly with the essential steps: authenticate, initialize the client, and perform a basic vault operation. This section shows you a minimal working example. -#### V1 (Old): Passing the token provider function below as a parameter to the Configuration. +### Authenticate -```python -# User defined function to provide access token to the vault apis -def token_provider(): - global bearerToken - if !(is_expired(bearerToken)): - return bearerToken - bearerToken, _ = generate_bearer_token('') - return bearerToken -``` +You can use an API key or a personal bearer token to directly authenticate and authorize requests with the SDK. Use API keys for long-term service authentication. Use bearer tokens for optimal security. -#### V2 (New): Passing one of the following: +### API Key ```python -# Option 1: API Key (Recommended) -credentials = { - 'api_key': '', # API key -} - -# Option 2: Environment Variables (Recommended) -# Set SKYFLOW_CREDENTIALS in your environment - -# Option 3: Credentials File credentials = { - 'path': '', # Path to credentials file + "api_key": "" } +``` -# Option 4: Stringified JSON -credentials = { - 'credentials_string': '', # Credentials as string -} +### Bearer Token (static) -# Option 5: Bearer Token +```python credentials = { - 'token': '', # Bearer token + "token": "" } ``` -**Notes:** -- Use only ONE authentication method. -- API Key or Environment Variables are recommended for production use. -- Secure storage of credentials is essential. - -### Initializing the client - -In V2, we have introduced a Builder design pattern for client initialization and added support for multi-vault. This allows you to configure multiple vaults during client initialization. +For authenticating via generated bearer tokens including support for scoped tokens, context-aware access tokens, and more, refer to the [Authentication & Authorization](#authentication--authorization) section. -During client initialization, you can pass the following parameters: - -- **`vault_id`** and **`cluster_id`**: These values are derived from the vault ID & vault URL. -- **`env`**: Specify the environment (e.g., SANDBOX or PROD). -- **`credentials`**: The necessary authentication credentials. +### Initialize the client -#### V1 (Old): +Initialize the Skyflow client first. You can specify different credential types during initialization. ```python -# Initializing a Skyflow Client instance with a SkyflowConfiguration object -config = Configuration('', '', token_provider) -client = Client(config) -``` +from skyflow import Skyflow, LogLevel, Env -#### V2 (New): +# Configure vault +config = { + 'vault_id': '', + 'cluster_id': '', + 'env': Env.PROD, + 'credentials': { + 'api_key': '' + } +} -```python -# Initializing a Skyflow Client instance +# Initialize Skyflow client client = ( Skyflow.builder() - .add_vault_config({ - 'vault_id': '', # Primary vault - 'cluster_id': '', # ID from your vault URL e.g., https://{clusterId}.vault.skyflowapis.com - 'env': Env.PROD, # Env by default it is set to PROD - 'credentials': credentials # Individual credentials - }) - .add_skyflow_credentials(credentials) # Skyflow credentials will be used if no individual credentials are passed - .set_log_level(LogLevel.INFO) # set log level by default it is set to ERROR + .add_vault_config(config) + .set_log_level(LogLevel.ERROR) .build() ) ``` -**Key Changes:** -- `vault_url` replaced with `cluster_Id`. -- Added environment specification (`env`). -- Instance-specific log levels. - -### Request & Response Structure +See [docs/advanced_initialization.md](docs/advanced_initialization.md) for advanced initialization examples including multiple vaults and different credential types. -In V2, with the introduction of constructor parameters, you can now pass parameters to `InsertRequest`. This request need -- **`table_name`**: The name of the table. -- **`values`**: An array of objects containing the data to be inserted. -The response will be of type `InsertResponse` class, which contains `inserted_fields` and errors. +### Insert data into the vault, get tokens back -#### V1 (Old): Request Building +Insert data into your vault using the `insert` method. Set `return_tokens=True` in the request to ensure values are tokenized in the response. -```python -client.insert( - { - "records": [ - { - "table": "cards", - "fields": { - "cardNumber": "41111111111", - "cvv": "123", - }, - } - ] - }, - InsertOptions(True), -) -``` +Create an insert request with the `InsertRequest` class, which includes the values to be inserted as a list of records. -#### V2 (New): Request Building +Below is a simple example to get started. See the [Insert and tokenize data](#insert-and-tokenize-data-insertrequest) section for advanced options. ```python -# Prepare Insertion Data +from skyflow.vault.data import InsertRequest + +# Insert sensitive data into the vault insert_data = [ - { - 'card_number': '', - 'cvv': '', - }, + { 'card_number': '4111111111111111', 'cardholder_name': 'John Doe' }, ] -table_name = '' # Replace with your actual table name - -# Create Insert Request insert_request = InsertRequest( - table=table_name, - values=insert_data, - return_tokens=True, # Optional: Get tokens for inserted data - continue_on_error=True # Optional: Continue on partial errors + table='table1', + values=insert_data, + return_tokens=True ) -# Perform Secure Insertion -response = skyflow_client.vault(primary_vault_config.get('')).insert(insert_request) +insert_response = skyflow_client.vault('').insert(insert_request) +print('Insert response:', insert_response) ``` -#### V1 (Old): Response Structure +## Upgrade from V1 to V2 -```json -{ - "records": [ - { - "table": "cards", - "fields": { - "cardNumber": "f3907186-e7e2-466f-91e5-48e12c2bcbc1", - "cvv": "1989cb56-63da-4482-a2df-1f74cd0dd1a5", - "skyflow_id": "d863633c-8c75-44fc-b2ed-2b58162d1117" - }, - "request_index": 0 - } - ] -} -``` +Upgrade from `skyflow-python` v1 using the dedicated guide in [docs/migrate_to_v2.md](docs/migrate_to_v2.md). + +## Vault + +The [Vault](https://docs.skyflow.com/docs/vaults) performs operations on the vault, including inserting records, detokenizing tokens, and retrieving tokens associated with a skyflow_id. -#### V2 (New): Response Structure +### Insert and tokenize data: `.insert(request)` + +Pass options to the `insert` method to enable additional functionality such as returning tokenized data, upserting records, or allowing bulk operations to continue despite errors. See [Quickstart](#quickstart) for a basic example. ```python -InsertResponse( - inserted_fields=[ - { - 'skyflow_id': 'a8f3ed5d-55eb-4f32-bf7e-2dbf4b9d9097', - 'card_number': '5479-4229-4622-1393' - } - ], - errors=[] +from skyflow.vault.data import InsertRequest + +insert_request = InsertRequest( + table='table1', + values=[ + { + '': '', + '': '' + }, + { + '': '', + '': '' + } + ], + return_tokens=True ) + +response = skyflow_client.vault('').insert(insert_request) +print('Insert response:', response) ``` -### Request Options +#### Insert example with `continue_on_error` option -In V2, we have introduced constructor parameters, allowing you to set options as key-value pairs as parameters in request. +Set the `continue_on_error` flag to `True` to allow insert operations to proceed despite encountering partial errors. -#### V1 (Old): +> [!TIP] +> See the full example in the samples directory: [insert_records.py](samples/vault_api/insert_records.py) -```python -options = InsertOptions( - tokens = True -) -``` +#### Upsert request -#### V2 (New): +Turn an insert into an 'update-or-insert' operation using the upsert option. The vault checks for an existing record with the same value in the specified column. If a match exists, the record updates; otherwise, a new record inserts. ```python +# Specify the column to use as the index for the upsert. +# Note: The column must have the `unique` constraint configured in the vault. insert_request = InsertRequest( - table=table_name, # Replace with the table name - values=insert_data, - return_tokens=False, # Do not return tokens - continue_on_error=False, # Stop inserting if any record fails - upsert='', # Replace with the column name used for upsert logic - token_mode=TokenMode.DISABLE, # Disable BYOT - tokens='' # Replace with tokens when TokenMode is ENABLE. + table='table1', + values=insert_data, + upsert='' ) ``` -### Error Structure +### Detokenize: `.detokenize(request, options)` -In V2, we have enriched the error details to provide better debugging capabilities. -The error response now includes: -- **http_status**: The HTTP status code. -- **grpc_code**: The gRPC code associated with the error. -- **details** & **message**: A detailed description of the error. -- **request_id**: A unique request identifier for easier debugging. +Convert tokens back into plaintext values (or masked values) using the `.detokenize()` method. Detokenization accepts tokens and returns values. -#### V1 (Old) Error Structure: +Create a detokenization request with the `DetokenizeRequest` class, which requires a list of tokens and column groups as input. -```json -{ - "code": "", - "message": "" -} -``` +Provide optional parameters such as the redaction type and the option to continue on error. -#### V2 (New) Error Structure: +#### Construct a detokenize request -```typescript -{ - "http_status": "", - "grpc_code": , - "http_code": , - "message": "", - "request_id": "", - "details": [ "
" ] -} +```python +from skyflow.vault.tokens import DetokenizeRequest +from skyflow.utils.enums import RedactionType + +detokenize_request = DetokenizeRequest( + data=[ + {'token': 'token1', 'redaction': RedactionType.PLAIN_TEXT}, + {'token': 'token2', 'redaction': RedactionType.PLAIN_TEXT} + ], + continue_on_error=True +) + +response = skyflow_client.vault('').detokenize(detokenize_request) +print('Detokenization response:', response) ``` -## Quickstart -Get started quickly with the essential steps: authenticate, initialize the client, and perform a basic vault operation. This section provides a minimal setup to help you integrate the SDK efficiently. +> [!TIP] +> See the full example in the samples directory: [detokenize_records.py](samples/vault_api/detokenize_records.py) -### Authenticate -You can use an API key to authenticate and authorize requests to an API. For authenticating via bearer tokens and different supported bearer token types, refer to the [Authenticate with bearer tokens](#authenticate-with-bearer-tokens) section. +### Get Record(s): `.get(request)` -```python -# create a new credentials dictionary -credentials = { - api_key: "", # add your API key in credentials -} -``` +Retrieve data using Skyflow IDs or unique column values with the `get` method. Create a get request with the `GetRequest` class, specifying parameters such as the table name, redaction type, Skyflow IDs, column names, and column values. -### Initialize the client +> [!NOTE] +> You can't use both Skyflow IDs and column name/value pairs in the same request. -To get started, you must first initialize the skyflow client. While initializing the skyflow client, you can specify different types of credentials. +#### Construct a get request ```python -from skyflow import Skyflow, LogLevel, Env - -# Configure vault -config = { - 'vault_id': '', # Replace with your Vault ID - 'cluster_id': '', # Replace with your Cluster ID (e.g., from the Vault URL) - 'env': Env.PROD, # Environment (SANDBOX, DEV, PROD) - 'credentials': { - 'token': '' # Your Bearer Token - } -} +from skyflow.vault.data import GetRequest +from skyflow.utils.enums import RedactionType -# Initialize Skyflow client -client = ( - Skyflow.builder() - .add_vault_config(config) - .set_log_level(LogLevel.ERROR) - .build() +get_request = GetRequest( + table='table1', + ids=['', ''], + redaction_type=RedactionType.PLAIN_TEXT, + return_tokens=False ) + +response = skyflow_client.vault('').get(get_request) +print('Get response:', response) ``` -See [docs/advanced_initialization.md](docs/advanced_initialization.md) for advanced initialization examples including multiple vaults and different credential types. +#### Get by Skyflow IDs -### Insert data into the vault -To insert data into your vault, use the `insert` method. The `InsertRequest` class creates an insert request, which includes the values to be inserted as a list of records. Below is a simple example to get started. For advanced options, check out [Insert data into the vault](#insert-data-into-the-vault-1) section. +Retrieve specific records using Skyflow IDs. Use this method when you know the exact record IDs. ```python -from skyflow.error import SkyflowError -from skyflow.vault.data import InsertRequest - -""" - * This example demonstrates how to insert sensitive data (e.g., card information) into a Skyflow vault using the Skyflow client. - * - * 1. Initializes the Skyflow client. - * 2. Prepares a record with sensitive data (e.g., card number and cardholder name). - * 3. Creates an insert request for inserting the data into the Skyflow vault. - * 4. Prints the response of the insert operation. -""" +from skyflow.vault.data import GetRequest +from skyflow.utils.enums import RedactionType -try: - # Step 1: Initialize data to be inserted into the Skyflow vault - insert_data = [ - { - 'card_number': '4111111111111111', # Replace with actual card number (sensitive data) - 'cardholder_name': 'John Doe', # Replace with actual cardholder name (sensitive data) - }, - ] +get_request = GetRequest( + table='table1', + ids=['', ''], + redaction_type=RedactionType.PLAIN_TEXT +) - # Step 2: Create Insert Request - insert_request = InsertRequest( - table='table1', # Specify the table in the vault where the data will be inserted - values=insert_data, # Attach the data (records) to be inserted - return_tokens=True, # Specify if tokens should be returned upon successful insertion - continue_on_error=True # Optional: Continue on partial errors - ) +response = skyflow_client.vault('').get(get_request) - # Step 3: Perform the insert operation using the Skyflow client - insert_response = skyflow_client.vault('9f27764a10f7946fe56b3258e117').insert(insert_request) - # Replace the vault ID "9f27764a10f7946fe56b3258e117" with your actual Skyflow vault ID +print('Data retrieval successful:', response) +``` - # Step 4: Print the response from the insert operation - print('Insert Response: ', insert_response) +#### Get tokens for records -except SkyflowError as error: - # Step 5: 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 -``` -Skyflow returns tokens for the record that was just inserted. +Return tokens for records to securely process sensitive data while maintaining data privacy. ```python -InsertResponse( - inserted_fields= - [ - { - 'skyflow_id': 'a8f3ed5d-55eb-4f32-bf7e-2dbf4b9d9097', - 'card_number': '5484-7829-1702-9110', - 'cardholder_name': 'b2308e2a-c1f5-469b-97b7-1f193159399b' - } - ], - errors=[] +get_request = GetRequest( + table='table1', + ids=[''], + return_tokens=True # Set to `True` to get tokens ) ``` +> [!TIP] +> See the full example in the samples directory: [get_records.py](samples/vault_api/get_records.py) -## Vault +#### Get by column name and column values -The [Vault](https://github.com/skyflowapi/skyflow-python/tree/v2/skyflow/vault) module performs operations on the vault, including inserting records, detokenizing tokens, and retrieving tokens associated with a skyflow_id. +Retrieve records by unique column values when you don't know the Skyflow IDs. Use this method to query data with alternate unique identifiers. +```python +get_request = GetRequest( + table='table1', + column_name='email', + column_values=['user@email.com'], # Column values of the records to return +) +``` -### Insert data into the vault +> [!TIP] +> See the full example in the samples directory: [get_column_values.py](samples/vault_api/get_column_values.py) -Apart from using the `insert` method to insert data into your vault covered in [Quickstart](#quickstart), you can also specify options in `InsertRequest`, such as returning tokenized data, upserting records, or continuing the operation in case of errors. +#### Redaction Types -#### Construct an insert request +Use redaction types to control how sensitive data displays when retrieved from the vault. -```python -from skyflow.error import SkyflowError -from skyflow.vault.data import InsertRequest +**Available Redaction Types** -""" -Example program to demonstrate inserting data into a Skyflow vault, along with corresponding InsertRequest schema. -""" +- `DEFAULT`: Applies the vault-configured default redaction setting. +- `REDACTED`: Completely removes sensitive data from view. +- `MASKED`: Partially obscures sensitive information. +- `PLAIN_TEXT`: Displays the full, unmasked data. -try: - # Initialize Skyflow client - # Step 1: Prepare the data to be inserted into the Skyflow vault - insert_data = [ - # Create the first record with field names and their respective values - { - '': '', # Replace with actual field name and value - '': '', # Replace with actual field name and value - }, - # Create the second record with field names and their respective values - { - '': '', # Replace with actual field name and value - '': '', # Replace with actual field name and value - } - ] +**Choosing the Right Redaction Type** - # Step 2: Build an InsertRequest object with the table name and the data to insert - insert_request = InsertRequest( - table='', # Replace with the actual table name in your Skyflow vault - values=insert_data, # Attach the data to be inserted - ) +- Use `REDACTED` for scenarios requiring maximum data protection to prevent exposure of sensitive information. +- Use `MASKED` to provide partial visibility of sensitive data for less critical use cases. +- Use `PLAIN_TEXT` for internal, authorized access where full data visibility is necessary. - # Step 3: Use the Skyflow client to perform the insert operation - insert_response = skyflow_client.vault('').insert(insert_request) - # Replace with your actual vault ID +### Update Records - # Print the response from the insert operation - print('Insert Response: ', insert_response) +Update data in your vault using the `update` method. Create an update request with the `UpdateRequest` class, specifying parameters such as the table name and data (as a dictionary). -# Step 5: Handle any exceptions that occur during the insert operation -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) # Print the stack trace for debugging purposes -``` +You can pass options like `return_tokens` directly to the request. When `True`, Skyflow returns tokens for the updated records. When `False`, it returns IDs. -#### Insert call example with `continue_on_error` option -The `continue_on_error` flag is a boolean that determines whether insert operation should proceed despite encountering partial errors. Set to `True` to allow the process to continue even if some errors occur. +#### Construct an update request ```python -from skyflow.error import SkyflowError -from skyflow.vault.data import InsertRequest +from skyflow.vault.data import UpdateRequest -""" -This example demonstrates how to insert sensitive data (e.g., card information) into a Skyflow vault using the Skyflow client. +update_request = UpdateRequest( + table='table1', + data={ + 'skyflow_id': '', + '': '', + '': '' + } +) -1. Initializes the Skyflow client. -2. Prepares a record with sensitive data (e.g., card number and cardholder name). -3. Creates an insert request for inserting the data into the Skyflow vault. -4. Specifies options to continue on error and return tokens. -5. Prints the response of the insert operation. -""" +response = skyflow_client.vault('').update(update_request) +print('Update response:', response) +``` -try: - # Initialize Skyflow client - # Step 1: Initialize a list to hold the data records to be inserted into the vault - insert_data = [ - # Step 2: Create the first record with card number and cardholder name - { - 'card_number': '4111111111111111', # Replace with actual card number (sensitive data) - 'cardholder_name': 'John Doe', # Replace with actual cardholder name (sensitive data) - }, - # Step 3: Create the second record with card number and cardholder name - { - 'card_number': '4111111111111111', # Ensure field name matches ("card_number") - 'cardholder_name': 'Jane Doe', # Replace with actual cardholder name (sensitive data) - } - ] +> [!TIP] +> See the full example in the samples directory: [update_record.py](samples/vault_api/update_record.py) - # Step 4: Build the InsertRequest object with the data records to insert - insert_request = InsertRequest( - table='table1', # Specify the table in the vault where the data will be inserted - values=insert_data, # Attach the data (records) to be inserted - return_tokens=True, # Specify if tokens should be returned upon successful insertion - continue_on_error=True # Specify to continue inserting records even if an error occurs for some records - ) +### Delete Records - # Step 5: Perform the insert operation using the Skyflow client - insert_response = skyflow_client.vault('9f27764a10f7946fe56b3258e117').insert(insert_request) - # Replace the vault ID "9f27764a10f7946fe56b3258e117" with your actual Skyflow vault ID +Delete records using Skyflow IDs with the `delete` method. Create a delete request with the `DeleteRequest` class, which accepts a list of Skyflow IDs: - # Step 6: Print the response from the insert operation - print('Insert Response: ', insert_response) +```python +from skyflow.vault.data import DeleteRequest -except SkyflowError as error: - # Step 7: 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 +delete_request = DeleteRequest( + table='', + ids=['', '', ''] +) + +response = skyflow_client.vault('').delete(delete_request) +print('Delete response:', response) ``` -Sample Response +> [!TIP] +> See the full example in the samples directory: [delete_records.py](samples/vault_api/delete_records.py) + +### Query + +Retrieve data with SQL queries using the `query` method. Create a query request with the `QueryRequest` class, which takes the `query` parameter as follows: ```python -InsertResponse( - inserted_fields= - [ - { - 'card_number': '5484-7829-1702-9110', - 'request_index': 0, - 'skyflow_id': '9fac9201-7b8a-4446-93f8-5244e1213bd1', - 'cardholder_name': 'b2308e2a-c1f5-469b-97b7-1f193159399b', - - } - ], - errors= - [ - { - 'request_index': 1, - 'error': 'Insert failed. Column card_numbe is invalid. Specify a valid column.' - } - ] +from skyflow.vault.data import QueryRequest + +query_request = QueryRequest( + query="SELECT * FROM table1 WHERE column1 = 'value'" ) +response = skyflow_client.vault('').query(query_request) +print('Query response:', response) ``` -**Insert call example with `upsert` option** -An upsert operation checks for a record based on a unique column's value. If a match exists, the record is updated; otherwise, a new record is inserted. +> [!TIP] +> See the full example in the samples directory: [query_records.py](samples/vault_api/query_records.py) -```python -from skyflow.error import SkyflowError -from skyflow.vault.data import InsertRequest +Refer to [Query your data](https://docs.skyflow.com/query-data/) and [Execute Query](https://docs.skyflow.com/record/#QueryService_ExecuteQuery) for guidelines and restrictions on supported SQL statements, operators, and keywords. -""" -This example demonstrates how to insert sensitive data (e.g., card information) into a Skyflow vault using the Skyflow client. +### Upload File -1. Initializes the Skyflow client. -2. Prepares a record with sensitive data (e.g., card number and cardholder name). -3. Creates an insert request for inserting the data into the Skyflow vault. -4. Specifies the field (cardholder_name) for upsert operations. -5. Prints the response of the insert operation. -""" +Upload files to a Skyflow vault using the `upload_file` method. Create a file upload request with the `FileUploadRequest` class, which accepts parameters such as the table name, column name, and Skyflow ID. -try: - # Initialize Skyflow client - # Step 1: Initialize a list to hold the data records for the insert/upsert operation - insert_data = [ - # Step 2: Create a record with the field 'cardholder_name' to insert or upsert - { - 'cardholder_name': 'John Doe', # Replace with the actual cardholder name - } - ] +```python +from skyflow.vault.data import FileUploadRequest - # Step 3: Build the InsertRequest object with the upsertData - insert_request = InsertRequest( - table='table1', # Specify the table in the vault where the data will be inserted - values=insert_data, # Attach the data (records) to be inserted - return_tokens=True, # Specify if tokens should be returned upon successful insertion - upsert='cardholder_name' # Specify the field to be used for upsert operations (e.g., cardholder_name) +# Open the file in binary read mode +with open('path/to/file.pdf', 'rb') as file_obj: + upload_request = FileUploadRequest( + table='documents', # Table name + column_name='attachment', # Column name to store file + skyflow_id='', # Skyflow ID of the record + file_object=file_obj # Pass file object ) + + # Perform File Upload + response = skyflow_client.vault('').upload_file(upload_request) + print('File upload:', response) +``` - # Step 4: Perform the insert/upsert operation using the Skyflow client - insert_response = skyflow_client.vault('9f27764a10f7946fe56b3258e117').insert(insert_request) - # Replace the vault ID "9f27764a10f7946fe56b3258e117" with your actual Skyflow vault ID +> [!TIP] +> See the full example in the samples directory: [upload_file.py](samples/vault_api/upload_file.py) - # Step 5: Print the response from the insert/upsert operation - print('Insert Response: ', insert_response) +### Retrieve Existing Tokens: `.tokenize(request)` -except SkyflowError as error: - # Step 6: Handle any exceptions that may occur during the insert/upsert 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 -``` +Retrieve tokens for values that already exist in the vault using the `.tokenize()` method. This method returns existing tokens only and does not generate new tokens. -Skyflow returns tokens, with `upsert` support, for the record you just inserted. +#### Construct a `.tokenize()` request ```python -InsertResponse( - inserted_fields= - [ - { - 'skyflow_id': '9fac9201-7b8a-4446-93f8-5244e1213bd1', - 'name': '73ce45ce-20fd-490e-9310-c1d4f603ee83' - } - ], - errors=[] -) -``` +from skyflow.vault.tokens import TokenizeRequest -### Detokenize +tokenize_request = TokenizeRequest( + values=[ + {"value": "", "column_group": ""}, + {"value": "", "column_group": ""} + ] +) -To retrieve tokens from your vault, use the `detokenize` method. The `DetokenizeRequest` class requires a list of detokenization data as input. Additionally, you can provide optional parameters, such as the redaction type and the option to continue on error. -#### Construct a detokenize request -```python -from skyflow.error import SkyflowError -from skyflow.utils.enums import RedactionType -from skyflow.vault.tokens import DetokenizeRequest -""" -This example demonstrates how to detokenize sensitive data from tokens stored in a Skyflow vault, along with corresponding DetokenizeRequest schema. -""" -try: - # Initialize Skyflow client - # Step 1: Step 1: Initialize a list of tokens to be detokenized (replace with actual tokens) - detokenize_data = ['', '', ''] # Replace with your actual token values - - # Step 2: Create the DetokenizeRequest object with the tokens and redaction type - detokenize_request = DetokenizeRequest( - tokens=detokenize_data, # Provide the list of tokens to be detokenized - continue_on_error=True, # Continue even if one token cannot be detokenized - redaction_type=RedactionType.PLAIN_TEXT # Specify how the detokenized data should be returned (plain text) - ) +response = skyflow_client.vault('').tokenize(tokenize_request) +print('Tokenization result:', response) +``` - # Step 3: Call the Skyflow vault to detokenize the provided tokens - detokenize_response = skyflow_client.vault('').detokenize(detokenize_request) - # Replace with your actual Skyflow vault ID +> [!TIP] +> See the full example in the samples directory: [tokenize_records.py](samples/vault_api/tokenize_records.py) - # Step 4: Print the detokenization response, which contains the detokenized data - print('Response:', detokenize_response) -# Step 5: Handle any errors that occur during the detokenization process -except SkyflowError as error: - print('Skyflow Specific Error: ', { - 'code': error.http_code, - 'message': error.message, - 'details': error.details - }) +## Detect -except Exception as error: - print('Unexpected Error:', error) # Print the exception for debugging purposes -``` +De-identify and reidentify sensitive data in text and files using Skyflow Detect, which supports advanced privacy-preserving workflows. -Notes: +### De-identify Text: `.deidentify_text(request)` -- `redaction_type` defaults to `RedactionType.PLAIN_TEXT`. -- `continue_on_error` default valus is `False`. +De-identify or anonymize text using the `deidentify_text` method. -#### An [example](https://github.com/skyflowapi/skyflow-python/blob/main/samples/vault_api/detokenize_records.py) of a detokenize call +Create a de-identify text request with the `DeidentifyTextRequest` class. ```python -from skyflow.error import SkyflowError -from skyflow.utils.enums import RedactionType -from skyflow.vault.tokens import DetokenizeRequest -""" -This example demonstrates how to detokenize sensitive data from tokens stored in a Skyflow vault. - -1. Initializes the Skyflow client. -2. Creates a list of tokens (e.g., credit card tokens) that represent the sensitive data. -3. Builds a detokenization request using the provided tokens and specifies how the redacted data should be returned. -4. Calls the Skyflow vault to detokenize the tokens and retrieves the detokenized data. -5. Prints the detokenization response, which contains the detokenized values or errors. -""" -try: - # Initialize Skyflow client - # Step 1: Step 1: Initialize a list of tokens to be detokenized (replace with actual tokens) - tokens = ['9738-1683-0486-1480', '6184-6357-8409-6668', '4914-9088-2814-3840'] # Replace with your actual token values - - # Step 2: Create the DetokenizeRequest object with the tokens and redaction type - detokenize_request = DetokenizeRequest( - tokens=tokens, # Provide the list of tokens to be detokenized - continue_on_error=False, # Stop the process if any token cannot be detokenized - redaction_type=RedactionType.PLAIN_TEXT # Specify how the detokenized data should be returned (plain text) +from skyflow.vault.detect import DeidentifyTextRequest, TokenFormat, Transformations, DateTransformation +from skyflow.utils.enums import DetectEntities, TokenType + +request = DeidentifyTextRequest( + text="", + entities=[DetectEntities.SSN, DetectEntities.CREDIT_CARD], + token_format=TokenFormat(default=TokenType.VAULT_TOKEN), + transformations=Transformations( + shift_dates=DateTransformation( + max_days=30, # Maximum days to shift + min_days=10, # Minimum days to shift + entities=[DetectEntities.DOB] + ) ) +) - # Step 3: Call the Skyflow vault to detokenize the provided tokens - detokenize_response = skyflow_client.vault('9f27764a10f7946fe56b3258e117').detokenize(detokenize_request) - # Replace "9f27764a10f7946fe56b3258e117" with your actual Skyflow vault ID +response = skyflow_client.detect('').deidentify_text(request) +print('De-identify Text Response:', response) +``` - # Step 4: Print the detokenization response, which contains the detokenized data - print('Response:', detokenize_response) -# Step 5: Handle any errors that occur during the detokenization process -except SkyflowError as error: - print('Skyflow Specific Error: ', { - 'code': error.http_code, - 'message': error.message, - 'details': error.details - }) +> [!TIP] +> See the full example in the samples directory: [deidentify_text.py](samples/detect_api/deidentify_text.py) -except Exception as error: - print('Unexpected Error:', error) # Print the exception for debugging purposes -``` +### Re-identify Text: `.reidentify_text(request)` -Sample response: +Re-identify text using the `reidentify_text` method. Create a reidentify text request with the `ReidentifyTextRequest` class, which includes the redacted or de-identified text to be re-identified. ```python -DetokenizeResponse( - detokenized_fields=[ - {'token': '9738-1683-0486-1480', 'value': '4111111111111115', 'type': 'STRING'}, - {'token': '6184-6357-8409-6668', 'value': '4111111111111119', 'type': 'STRING'}, - {'token': '4914-9088-2814-3840', 'value': '4111111111111118', 'type': 'STRING'} - ], - errors=[] +from skyflow.vault.detect import ReidentifyTextRequest +from skyflow.utils.enums import DetectEntities + +request = ReidentifyTextRequest( + text="", + redacted_entities=[DetectEntities.SSN], # Keep redacted + masked_entities=[DetectEntities.CREDIT_CARD], # Mask + plain_text_entities=[DetectEntities.NAME] # Reveal ) + +response = skyflow_client.detect().reidentify_text(request) +print('Re-identify Text Response:', response) ``` -#### An example of a detokenize call with `continue_on_error` option: +> [!TIP] +> See the full example in the samples directory: [reidentify_text.py](samples/detect_api/reidentify_text.py) -```python -from skyflow.error import SkyflowError -from skyflow.utils.enums import RedactionType -from skyflow.vault.tokens import DetokenizeRequest -""" -This example demonstrates how to detokenize sensitive data from tokens stored in a Skyflow vault. - -1. Initializes the Skyflow client. -2. Creates a list of tokens (e.g., credit card tokens) that represent the sensitive data. -3. Builds a detokenization request using the provided tokens and specifies how the redacted data should be returned. -4. Calls the Skyflow vault to detokenize the tokens and retrieves the detokenized data. -5. Prints the detokenization response, which contains the detokenized values or errors. -""" -try: - # Initialize Skyflow client - # Step 1: Step 1: Initialize a list of tokens to be detokenized (replace with actual tokens) - tokens = ['9738-1683-0486-1480', '6184-6357-8409-6668', '4914-9088-2814-3840'] # Replace with your actual token values - - # Step 2: Create the DetokenizeRequest object with the tokens and redaction type - detokenize_request = DetokenizeRequest( - tokens=tokens, # Provide the list of tokens to be detokenized - continue_on_error=True, # Continue even if some tokens cannot be detokenized - redaction_type=RedactionType.PLAIN_TEXT # Specify how the detokenized data should be returned (plain text) - ) +### De-identify File: `.deidentify_file(request)` - # Step 3: Call the Skyflow vault to detokenize the provided tokens - detokenize_response = skyflow_client.vault('9f27764a10f7946fe56b3258e117').detokenize(detokenize_request) - # Replace "9f27764a10f7946fe56b3258e117" with your actual Skyflow vault ID +De-identify files using the `deidentify_file` method. Create a request with the `DeidentifyFileRequest` class, which includes the file to be deidentified. Provide optional parameters to control how entities are detected and deidentified. - # Step 4: Print the detokenization response, which contains the detokenized data - print('Response:', detokenize_response) -# Step 5: Handle any errors that occur during the detokenization process -except SkyflowError as error: - print('Skyflow Specific Error: ', { - 'code': error.http_code, - 'message': error.message, - 'details': error.details - }) +```python +from skyflow.vault.detect import DeidentifyFileRequest, TokenFormat, FileInput +from skyflow.utils.enums import DetectEntities, TokenType -except Exception as error: - print('Unexpected Error:', error) # Print the exception for debugging purposes +# Open file in binary mode +with open('path/to/file.pdf', 'rb') as file_obj: + request = DeidentifyFileRequest( + file=FileInput(file_obj), + entities=[DetectEntities.SSN, DetectEntities.CREDIT_CARD], + token_format=TokenFormat(default=TokenType.ENTITY_ONLY), + output_directory='', + wait_time=64 + ) + + response = skyflow_client.detect().deidentify_file(request) + print('De-identify File Response:', response) ``` -Sample response: +**Supported file types:** -```python -DetokenizeResponse( - detokenized_fields=[ - { - 'token': '9738-1683-0486-1480', - 'value': '4111111111111115', - 'type': 'STRING' - }, - { - 'token': '6184-6357-8409-6668', - 'value': '4111111111111119', - 'type': 'STRING' - } - ], - errors=[ - { - 'token': '4914-9088-2814-384', - 'error': 'Token Not Found' - } - ] -) +- Documents: `doc`, `docx`, `pdf` +- PDFs: `pdf` +- Images: `bmp`, `jpeg`, `jpg`, `png`, `tif`, `tiff` +- Structured text: `json`, `xml` +- Spreadsheets: `csv`, `xls`, `xlsx` +- Presentations: `ppt`, `pptx` +- Audio: `mp3`, `wav` -``` +**Notes:** -### Tokenize +- Transformations can't be applied to Documents, Images, or PDFs file formats. +- The `wait_time` option must be ≤ 64 seconds; otherwise, an error is thrown. +- If the API takes more than 64 seconds to process the file, it will return only the `run_id` and `status` in the response. -Tokenization replaces sensitive data with unique identifier tokens. This approach protects sensitive information by securely storing the original data while allowing the use of tokens within your application. +> [!TIP] +> See the full example in the samples directory: [deidentify_file.py](samples/detect_api/deidentify_file.py) -To tokenize data, use the `tokenize` method. The `TokenizeRequest` class creates a tokenize request. In this request, you specify the values parameter, which is a list of column values objects. Each column value contains two properties: `value` and `column_group`. +### Get Run: `.get_detect_run(request)` -#### Construct a tokenize request +Retrieve the results of a previously started file de-identification operation using the `get_detect_run` method. Initialize the request with the `run_id` returned from a prior .`deidentify_file` call. ```python -from skyflow.error import SkyflowError -from skyflow.vault.tokens import TokenizeRequest +from skyflow.vault.detect import GetDetectRunRequest -""" -This example demonstrates how to tokenize sensitive data (e.g., credit card information) using the Skyflow client, along with corresponding TokenizeRequest schema. -""" -try: - # Initialize Skyflow client - # Step 1: Initialize a list of column values to be tokenized (replace with actual sensitive data) - column_values = [ - # Step 2: Create column values for each sensitive data field (e.g., card number and cardholder name) - {"value": "", "column_group": ""}, # Replace and with actual data - {"value": "", "column_group": ""} # Replace and with actual data - ] +request = GetDetectRunRequest( + run_id='' +) - # Step 3: Build the TokenizeRequest with the column values - tokenize_request = TokenizeRequest( - values=column_values - ) +response = skyflow_client.detect().get_detect_run(request) +print('Get Detect Run Response:', response) +``` - # Step 4: Call the Skyflow vault to tokenize the sensitive data - tokenize_response = skyflow_client.vault('').tokenize(tokenize_request) - # Replace with your actual Skyflow vault ID +> [!TIP] +> See the full example in the samples directory: [get_detect_run.py](samples/detect_api/get_detect_run.py) - # Step 5: Print the tokenization response, which contains the generated tokens or errors - print(tokenize_response) +## Connections -# Step 6: Handle any errors that occur during the tokenization process -except SkyflowError as error: - print('Skyflow Specific Error: ', { - 'code': error.http_code, - 'message': error.message, - 'details': error.details - }) +Securely send and receive data between your systems and first- or third-party services using Skyflow Connections. The [connections](https://github.com/skyflowapi/skyflow-python/tree/v2/skyflow/vault/connection) module invokes both inbound and/or outbound connections. -except Exception as error: - print('Unexpected Error:', error) # Print the stack trace for debugging purposes -``` +- **Inbound connections**: Act as intermediaries between your client and server, tokenizing sensitive data before it reaches your backend, ensuring downstream services handle only tokenized data. +- **Outbound connections**: Enable secure extraction of data from the vault and transfer it to third-party services via your backend server, such as processing checkout or card issuance flows. -#### An [example](https://github.com/skyflowapi/skyflow-python/blob/main/samples/vault_api/tokenize_records.py) of Tokenize call +### Invoke a connection -```python -from skyflow.error import SkyflowError -from skyflow.vault.tokens import TokenizeRequest - -""" -This example demonstrates how to tokenize sensitive data (e.g., credit card information) using the Skyflow client. - -1. Initializes the Skyflow client. -2. Creates a column value for sensitive data (e.g., credit card number). -3. Builds a tokenize request with the column value to be tokenized. -4. Sends the request to the Skyflow vault for tokenization. -5. Prints the tokenization response, which includes the token or errors. -""" -try: - # Initialize Skyflow client - # Step 1: Initialize a list of column values to be tokenized (replace with actual sensitive data) - column_values = [ - # Step 2: Create column values for each sensitive data field (e.g., card number and cardholder name) - {"value": "4111111111111111", "column_group": "card_number_cg"}, # Replace and with actual data - ] - - # Step 3: Build the TokenizeRequest with the column values - tokenize_request = TokenizeRequest( - values=column_values - ) - - # Step 4: Call the Skyflow vault to tokenize the sensitive data - tokenize_response = skyflow_client.vault('9f27764a10f7946fe56b3258e117').tokenize(tokenize_request) - # Replace "9f27764a10f7946fe56b3258e117" with your actual Skyflow vault ID - - # Step 5: Print the tokenization response, which contains the generated tokens or errors - print(tokenize_response) - -# Step 6: Handle any errors that occur during the tokenization process -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) # Print the stack trace for debugging purposes - -``` - -Sample response: - -```python -TokenizeResponse( - tokenized_fields=[ - { - 'token': '5479-4229-4622-1393' - } - ] -) - -``` - -### Get - -To retrieve data using Skyflow IDs or unique column values, use the get method. The `GetRequest` class creates a get request, where you specify parameters such as the table name, redaction type, Skyflow IDs, column names, column values, and whether to return tokens. If you specify Skyflow IDs, you can't use column names and column values, and the inverse is true—if you specify column names and column values, you can't use Skyflow IDs. - -#### Construct a get request - -```python -from skyflow.error import SkyflowError -from skyflow.utils.enums import RedactionType -from skyflow.vault.data import GetRequest - -""" -This example demonstrates how to retrieve data from the Skyflow vault using different methods, along with corresponding GetRequest schema. -""" -try: - # Initialize Skyflow client - # Step 1: Initialize a list of Skyflow IDs to retrieve records (replace with actual Skyflow IDs) - ids = ['', ''] # Replace with actual Skyflow IDs - - # Step 2: Create a GetRequest to retrieve records by Skyflow ID without returning tokens - get_by_id_request = GetRequest( - table='', # Replace with your actual table name - ids=ids, - return_tokens=False, # Set to false to avoid returning tokens - redaction_type=RedactionType.PLAIN_TEXT # Redact data as plain text - ) - - # Send the request to the Skyflow vault and retrieve the records - get_by_id_response = skyflow_client.vault('').get(get_by_id_request) - # Replace with your actual Skyflow vault ID - - print(get_by_id_response) - - # Step 3: Create another GetRequest to retrieve records by Skyflow ID with tokenized values - get_tokens_request = GetRequest( - table='', # Replace with your actual table name - ids=ids, - return_tokens=True # Set to True to return tokenized values - ) - - # Send the request to the Skyflow vault and retrieve the tokenized records - get_tokens_response = skyflow_client.vault('').get(get_tokens_request) - print(get_tokens_response) - - column_values = [ - '', # Replace with the actual column value - '' # Replace with the actual column value - ] - - # Step 4: Create a GetRequest to retrieve records based on specific column values - get_by_column_request = GetRequest( - table='', # Replace with the actual table name - column_name='', # Replace with the column name - column_values=column_values, # Add the list of column values to filter by - redaction_type=RedactionType.PLAIN_TEXT # Redact data as plain text - ) - - # Send the request to the Skyflow vault and retrieve the filtered records - get_by_column_response = skyflow_client.vault('').get(get_by_column_request) - print(get_by_column_response) -# Step 5: Handle any errors that occur during the retrieval process -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) # Print the stack trace for debugging purposes - -``` - -#### Get by skyflow IDs -Retrieve specific records using skyflow `ids`. Ideal for fetching exact records when IDs are known. - - -#### An [example](https://github.com/skyflowapi/skyflow-python/blob/main/samples/vault_api/get_records.py) of a get call to retrieve data using Redaction type: - -```python -from skyflow.error import SkyflowError -from skyflow.utils.enums import RedactionType -from skyflow.vault.data import GetRequest - -""" -This example demonstrates how to retrieve data from the Skyflow vault using a list of Skyflow IDs. - -1. Initializes the Skyflow client with a given vault ID. -2. Creates a request to retrieve records based on Skyflow IDs. -3. Specifies that the response should not return tokens. -4. Uses plain text redaction type for the retrieved records. -5. Prints the response to display the retrieved records. -""" -try: - # Initialize Skyflow client - # Step 1: Initialize a list of Skyflow IDs to retrieve records (replace with actual Skyflow IDs) - ids = ['a581d205-1969-4350-acbe-a2a13eb871a6', '5ff887c3-b334-4294-9acc-70e78ae5164a'] # Replace with actual Skyflow IDs - - # Step 2: Create a GetRequest to retrieve records by Skyflow ID without returning tokens - # The request specifies: - # - `ids`: The list of Skyflow IDs to retrieve - # - `table`: The table from which the records will be retrieved - # - `return_tokens`: Set to false, meaning tokens will not be returned in the response - # - `redaction_type`: Set to PLAIN_TEXT, meaning the retrieved records will have data redacted as plain text - get_by_id_request = GetRequest( - table='table1', # Replace with the actual table name - ids=ids, - return_tokens=False, # Set to false to avoid returning tokens - redaction_type=RedactionType.PLAIN_TEXT # Redact data as plain text - ) - - # Step 3: Send the request to the Skyflow vault and retrieve the records - get_by_id_response = skyflow_client.vault('9f27764a10f7946fe56b3258e117').get(get_by_id_request) - # Replace with actual Vault ID - - print(get_by_id_response) # Print the response to the console - -# Step 5: Handle any errors that occur during the retrieval process -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) # Print the stack trace for debugging purposes -``` - -Sample response: - -```python -GetResponse( - data=[ - { - 'card_number': '4555555555555553', - 'email': 'john.doe@gmail.com', - 'name': 'john doe', - 'skyflow_id': 'a581d205-1969-4350-acbe-a2a13eb871a6' - }, - { - 'card_number': '4555555555555559', - 'email': 'jane.doe@gmail.com', - 'name': 'jane doe', - 'skyflow_id': '5ff887c3-b334-4294-9acc-70e78ae5164a' - } - ], - errors=[] -) -``` - -#### Get tokens -Return tokens for records. Ideal for securely processing sensitive data while maintaining data privacy. - -#### An [example](https://github.com/skyflowapi/skyflow-python/blob/main/samples/vault_api/get_records.py) of get call to retrieve tokens using Skyflow IDs: - - -```python -from skyflow.error import SkyflowError -from skyflow.utils.enums import RedactionType -from skyflow.vault.data import GetRequest - -""" -This example demonstrates how to retrieve data from the Skyflow vault and return tokens along with the records. - -1. Initializes the Skyflow client with a given vault ID. -2. Creates a request to retrieve records based on Skyflow IDs and ensures tokens are returned. -3. Prints the response to display the retrieved records along with the tokens. -""" -try: - # Initialize Skyflow client - # Step 1: Initialize a list of Skyflow IDs (replace with actual Skyflow IDs) - ids = ['a581d205-1969-4350-acbe-a2a13eb871a6', '5ff887c3-b334-4294-9acc-70e78ae5164a'] # Replace with actual Skyflow IDs - - # Step 2: Create a GetRequest to retrieve records based on Skyflow IDs - # The request specifies: - # - `ids`: The list of Skyflow IDs to retrieve - # - `table`: The table from which the records will be retrieved - # - `return_tokens`: Set to false, meaning tokens will not be returned in the response - get_tokens_request = GetRequest( - table='table1', # Replace with the actual table name - ids=ids, - return_tokens=True, # Set to false to avoid returning tokens - ) - - # Step 3: Send the request to the Skyflow vault and retrieve the records - get_tokens_response = skyflow_client.vault('9f27764a10f7946fe56b3258e117').get(get_tokens_request) - # Replace with actual Vault ID - - print(get_tokens_response) # Print the response to the console - -# Step 5: Handle any errors that occur during the retrieval process -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) # Print the stack trace for debugging purposes -``` - -Sample response: - -```python -GetResponse( - data=[ - { - 'card_number': '3998-2139-0328-0697', - 'email': 'c9a6c9555060@82c092e7.bd52', - 'name': '82c092e7-74c0-4e60-bd52-c9a6c9555060', - 'skyflow_id': 'a581d205-1969-4350-acbe-a2a13eb871a6' - }, - { - 'card_number': '3562-0140-8820-7499', - 'email': '6174366e2bc6@59f82e89.93fc', - 'name': '59f82e89-138e-4f9b-93fc-6174366e2bc6', - 'skyflow_id': '5ff887c3-b334-4294-9acc-70e78ae5164a' - } - ], - errors=[] -) -``` - -#### Get by column name and column values -Retrieve records by unique column values. Ideal for querying data without knowing Skyflow IDs, using alternate unique identifiers. - -#### An [example](https://github.com/skyflowapi/skyflow-python/blob/v2/samples/vault_api/get_column_values.py) of get call to retrieve data using column name and column values: - -```python -from skyflow.error import SkyflowError -from skyflow.utils.enums import RedactionType -from skyflow.vault.data import GetRequest - -""" -This example demonstrates how to retrieve data from the Skyflow vault based on column values. - -1. Initializes the Skyflow client with a given vault ID. -2. Creates a request to retrieve records based on specific column values (e.g., email addresses). -3. Prints the response to display the retrieved records after redacting sensitive data based on the specified redaction type. -""" -try: - # Initialize Skyflow client - # Step 1: Initialize a list of column values (email addresses in this case) - column_values = [ - 'john.doe@gmail.com', # Example email address - 'jane.doe@gmail.com' # Example email address - ] - - # Step 2: Step 2: Create a GetRequest to retrieve records based on column values - # The request specifies: - # - `ids`: The list of Skyflow IDs to retrieve - # - `table`: The table from which the records will be retrieved - # - `return_tokens`: Set to false, meaning tokens will not be returned in the response - get_by_column_request = GetRequest( - table='table1', # Replace with the actual table name - column_name='email', # The column name to filter by (e.g., "email") - column_values=column_values, # The list of column values to match - redaction_type=RedactionType.PLAIN_TEXT # Set the redaction type (e.g., PLAIN_TEXT) - ) - - # Step 3: Send the request to the Skyflow vault and retrieve the records - get_by_column_response = skyflow_client.vault('9f27764a10f7946fe56b3258e117').get(get_by_column_request) - # Replace with actual Vault ID - - print(get_by_column_response) # Print the response to the console - -# Step 5: Handle any errors that occur during the retrieval process -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) # Print the stack trace for debugging purposes - -``` - -Sample response: - -```python -GetResponse( - data=[ - { - 'card_number': '4555555555555553', - 'email': 'john.doe@gmail.com', - 'name': 'john doe', - 'skyflow_id': 'a581d205-1969-4350-acbe-a2a13eb871a6' - }, - { - 'card_number': '4555555555555559', - 'email': 'jane.doe@gmail.com', - 'name': 'jane doe', - 'skyflow_id': '5ff887c3-b334-4294-9acc-70e78ae5164a' - } - ], - errors=[] -) -``` - -#### Redaction Types -Redaction types determine how sensitive data is displayed when retrieved from the vault. - -**Available Redaction Types** - -- `DEFAULT`: Applies the vault-configured default redaction setting. -- `DEFAULT`: Completely removes sensitive data from view. -- `MASKED`: Partially obscures sensitive information. -- `PLAIN_TEXT`: Displays the full, unmasked data. - -**Choosing the Right Redaction Type** -- Use `REDACTED` for scenarios requiring maximum data protection to prevent exposure of sensitive information. -- Use `MASKED` to provide partial visibility of sensitive data for less critical use cases. -- Use `PLAIN_TEXT` for internal, authorized access where full data visibility is necessary. - -### Update - -To update data in your vault, use the `update` method. The `UpdateRequest` class is used to create an update request, where you specify parameters such as the table name, data (as a dictionary), tokens, return_tokens, and token_strict. If `return_tokens` is set to True, Skyflow returns tokens for the updated records. If `return_tokens` is set to False, Skyflow returns IDs for the updated records. - -#### Construct an update request - -```python -from skyflow.error import SkyflowError -from skyflow.utils.enums import TokenMode -from skyflow.vault.data import UpdateRequest - -""" -This example demonstrates how to update records in the Skyflow vault by providing new data and/or tokenized values, along with the corresponding UpdateRequest schema. -""" - -try: - # Initialize Skyflow client - # Step 1: Prepare the data to update in the vault - # Use a dictionary to store the data that will be updated in the specified table - update_data = { - 'skyflow_id': '', # Skyflow ID for identifying the record to update - '': '', # Example of a column name and its value to update - '': '' # Another example of a column name and its value to update - } - - # Step 2: Prepare the tokens (if necessary) for certain columns that require tokenization - # Use a dictionary to specify columns that need tokens in the update request - tokens = { - '': '' # Example of a column name that should be tokenized - } - - # Step 3: Create an UpdateRequest to specify the update operation - # The request includes the table name, data, tokens, and the returnTokens flag - update_request = UpdateRequest( - table='', # Replace with the actual table name to update - token_mode=TokenMode.ENABLE, # Specifies the tokenization mode (ENABLE means tokenization is applied) - data=update_data, # The data to update in the record - tokens=tokens, # The tokens associated with specific columns - return_tokens=True # Specify whether to return tokens in the response - ) - - # Step 4: Send the request to the Skyflow vault and update the record - update_response = skyflow_client.vault('').update(update_request) # Replace with actual Vault ID - - # Step 5: Print the response to confirm the update result - print(update_response) - -except SkyflowError as error: - # Step 6: Handle any errors that occur during the update 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](https://github.com/skyflowapi/skyflow-python/blob/main/samples/vault_api/update_record.py) of update call - -```python -from skyflow.error import SkyflowError -from skyflow.utils.enums import TokenMode -from skyflow.vault.data import UpdateRequest - -""" -This example demonstrates how to update a record in the Skyflow vault with specified data and tokens. - -1. Initializes the Skyflow client with a given vault ID. -2. Constructs an update request with data to modify and tokens to include. -3. Sends the request to update the record in the vault. -4. Prints the response to confirm the success or failure of the update operation. -""" - -try: - # Initialize Skyflow client - # Step 1: Prepare the data to update in the vault - # Use a dictionary to store the data that will be updated in the specified table - update_data = { - 'skyflow_id': '5b699e2c-4301-4f9f-bcff-0a8fd3057413', # Skyflow ID for identifying the record to update - 'name': 'john doe', # Example of a column name and its value to update - 'card_number': '4111111111111115' # Another example of a column name and its value to update - } - - # Step 2: Prepare the tokens (if necessary) for certain columns that require tokenization - # Use a dictionary to specify columns that need tokens in the update request - tokens = { - 'name': '72b8ffe3-c8d3-4b4f-8052-38b2a7405b5a' # Example of a column name that should be tokenized - } - - # Step 3: Create an UpdateRequest to specify the update operation - # The request includes the table name, data, tokens, and the returnTokens flag - update_request = UpdateRequest( - table='table1', # Replace with the actual table name to update - token_mode=TokenMode.ENABLE, # Token mode enabled to allow tokenization of sensitive data - data=update_data, # The data to update in the record - tokens=tokens, # The tokenized values for sensitive columns - ) - - # Step 4: Send the request to the Skyflow vault and update the record - update_response = skyflow_client.vault('9f27764a10f7946fe56b3258e117').update(update_request) # Replace with actual Vault ID - - # Step 5: Print the response to confirm the update result - print(update_response) - -except SkyflowError as error: - # Step 6: Handle any errors that occur during the update 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 - -- When `return_tokens` is set to `True` - -```python -UpdateResponse( - updated_field={ - 'skyflow_id': '5b699e2c-4301-4f9f-bcff-0a8fd3057413', - 'name': '72b8ffe3-c8d3-4b4f-8052-38b2a7405b5a', - 'card_number': '4131-1751-0217-8491' - }, - errors=[] -) - -``` - -- When `return_tokens` is set to `False` - -```python -UpdateResponse( - updated_field={'skyflow_id': '5b699e2c-4301-4f9f-bcff-0a8fd3057413'}, - errors=[] -) - -``` - -### Delete - -To delete records using Skyflow IDs, use the `delete` method. The `DeleteRequest` class accepts a list of Skyflow IDs that you want to delete, as shown below: - -#### Construct a delete request - -```python -from skyflow.error import SkyflowError -from skyflow.vault.data import DeleteRequest - -""" -This example demonstrates how to delete records from a Skyflow vault using specified Skyflow IDs, along with corresponding DeleteRequest schema. -""" - -try: - # Initialize Skyflow client - # Step 1: Prepare a list of Skyflow IDs for the records to delete - # The list stores the Skyflow IDs of the records that need to be deleted from the vault - delete_ids = ['', '', ''] # Replace with actual Skyflow IDs - - # Step 2: Create a DeleteRequest to define the delete operation - # The request specifies the table from which to delete the records and the IDs of the records to delete - delete_request = DeleteRequest( - table='', # Replace with the actual table name from which to delete - ids=delete_ids # List of Skyflow IDs to delete - ) - - # Step 3: Send the delete request to the Skyflow vault - delete_response = skyflow_client.vault('').delete(delete_request) # Replace with your actual Vault ID - print(delete_response) # Print the response to confirm the delete result - -except SkyflowError as error: - # Step 4: Handle any exceptions that occur during the delete 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 exception stack trace for debugging purposes -``` - -#### An [example](https://github.com/skyflowapi/skyflow-python/blob/main/samples/vault_api/delete_records.py) of delete call - -```python -from skyflow.error import SkyflowError -from skyflow.vault.data import DeleteRequest - -""" -This example demonstrates how to delete records from a Skyflow vault using specified Skyflow IDs. - -1. Initializes the Skyflow client with a given Vault ID. -2. Constructs a delete request by specifying the IDs of the records to delete. -3. Sends the delete request to the Skyflow vault to delete the specified records. -4. Prints the response to confirm the success or failure of the delete operation. -""" - -try: - # Initialize Skyflow client - # Step 1: Prepare a list of Skyflow IDs for the records to delete - # The list stores the Skyflow IDs of the records that need to be deleted from the vault - delete_ids = ['9cbf66df-6357-48f3-b77b-0f1acbb69280', 'ea74bef4-f27e-46fe-b6a0-a28e91b4477b', '47700796-6d3b-4b54-9153-3973e281cafb'] # Replace with actual Skyflow IDs - - # Step 2: Create a DeleteRequest to define the delete operation - # The request specifies the table from which to delete the records and the IDs of the records to delete - delete_request = DeleteRequest( - table='table1', # Replace with the actual table name from which to delete - ids=delete_ids # List of Skyflow IDs to delete - ) - - # Step 3: Send the delete request to the Skyflow vault - delete_response = skyflow_client.vault('9f27764a10f7946fe56b3258e117').delete(delete_request) # Replace with your actual Vault ID - print(delete_response) # Print the response to confirm the delete result -# Step 4: Handle any exceptions that occur during the delete operation -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) # Print the exception stack trace for debugging purposes -``` - -Sample response: - -```python -DeleteResponse( - deleted_ids=[ - '9cbf66df-6357-48f3-b77b-0f1acbb69280', - 'ea74bef4-f27e-46fe-b6a0-a28e91b4477b', - '47700796-6d3b-4b54-9153-3973e281cafb' - ], - errors=[] -) - -``` - -### Query - -To retrieve data with SQL queries, use the `query` method. `QueryRequest` is class that takes the `query` parameter as follows: - -#### Construct a query request -Refer to [Query your data](https://docs.skyflow.com/query-data/) and [Execute Query](https://docs.skyflow.com/record/#QueryService_ExecuteQuery) for guidelines and restrictions on supported SQL statements, operators, and keywords. - -```python -from skyflow.error import SkyflowError -from skyflow.vault.data import QueryRequest - -""" -This example demonstrates how to execute a custom SQL query on a Skyflow vault, along with QueryRequest schema. -""" - -try: - # Initialize Skyflow client - # Step 1: Define the SQL query to execute on the Skyflow vault - # Replace "" with the actual SQL query you want to run - query = '' # Example: "SELECT * FROM table1 WHERE column1 = 'value'" - - # Step 2: Create a QueryRequest with the specified SQL query - query_request = QueryRequest( - query=query # SQL query to execute - ) - - # Step 3: Execute the query request on the specified Skyflow vault - query_response = skyflow_client.vault('').query(query_request) # Replace with your actual Vault ID - - # Step 4: Print the response containing the query results - print('Query Result:', query_response) - -except SkyflowError as error: - # Step 5: Handle any exceptions that occur during the query execution - print('Skyflow Specific Error:', { - 'code': error.http_code, - 'message': error.message, - 'details': error.details - }) - -except Exception as error: - # Handle any unexpected errors during execution - print('Unexpected Error:', error) # Print the stack trace for debugging purposes -``` -#### An [example](https://github.com/skyflowapi/skyflow-python/blob/main/samples/vault_api/query_records.py) of query call - -```python -from skyflow.error import SkyflowError -from skyflow.vault.data import QueryRequest - -""" -This example demonstrates how to execute a SQL query on a Skyflow vault to retrieve data. - -1. Initializes the Skyflow client with the Vault ID. -2. Constructs a query request with a specified SQL query. -3. Executes the query against the Skyflow vault. -4. Prints the response from the query execution. -""" - -try: - # Initialize Skyflow client - # Step 1: Define the SQL query - # Example query: Retrieve all records from the "cards" table with a specific skyflow_id - query = "SELECT * FROM cards WHERE skyflow_id='3ea3861-x107-40w8-la98-106sp08ea83f'" # Example: "SELECT * FROM table1 WHERE column1 = 'value'" - - # Step 2: Create a QueryRequest with the SQL query - query_request = QueryRequest( - query=query # SQL query to execute - ) - - # Step 3: Execute the query request on the specified Skyflow vault - query_response = skyflow_client.vault('9f27764a10f7946fe56b3258e117').query(query_request) # Vault ID: 9f27764a10f7946fe56b3258e117 - - # Step 4: Print the response containing the query results - print(query_response) - -except SkyflowError as error: - # Step 5: Handle any exceptions that occur during the query execution - 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 -QueryResponse( - fields=[ - { - 'card_number': 'XXXXXXXXXXXX1112', - 'name': 'S***ar', - 'skyflow_id': '3ea3861-x107-40w8-la98-106sp08ea83f', - 'tokenized_data': {} - } - ], - errors=[] -) -``` - -### Upload File -To upload files to a Skyflow vault, use the `upload_file` method. The `FileUploadRequest` class accepts parameters such as the table name, column name, skyflow ID, and either a file path, a file object or a base64 encoded file. - -#### Construct an upload file request - -You can upload a file by providing either a file path or a file object: - -```python -from skyflow.error import SkyflowError -from skyflow.vault.data import FileUploadRequest - -try: - with open('', 'rb') as file_obj: - file_upload_request = FileUploadRequest( - table='', # Table to upload file to - column_name='', # Column to upload file into - file_object=file_obj, # File object opened in binary mode - skyflow_id='' # Record ID to associate the file with - ) - response = skyflow_client.vault('').upload_file(file_upload_request) - print('File upload successful:', response) - -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) -``` - -#### An [example](https://github.com/skyflowapi/skyflow-python/blob/main/samples/vault_api/upload_file.py) of upload file call - -```python -from skyflow.error import SkyflowError -from skyflow.vault.data import FileUploadRequest - -""" -This example demonstrates how to upload a file to a Skyflow vault using a file object. - -1. Initializes the Skyflow client with the Vault ID. -2. Constructs an upload file request. -3. Uploads the file into the Skyflow vault. -4. Prints the response to confirm the success or failure of the upload file operation. -""" - -try: - # Initialize Skyflow client - # Step 1: Open a file - with open('my_document.pdf', 'rb') as file_obj: - # Step 2: Create a FileIploadRequest to define the upload file operation - file_upload_request = FileUploadRequest( - table='documents', - column_name='attachment', - file_object=file_obj, - skyflow_id='123e4567-e89b-12d3-a456-426614174000' - ) - - # Step 3: Execute the upload file request on the specified Skyflow vault - response = skyflow_client.vault('9f27764a10f7946fe56b3258e117').upload_file(file_upload_request) - - # Step 4: Print the response containing the query results - print('File upload successful:', response) - -except SkyflowError as error: - # Step 5: Handle any exceptions that occur during the query execution - 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 -``` - -## 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, supports providing either a file or a file path in class FileInput for de-identification, along with 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, FileInput -""" -This example demonstrates how to deidentify file, along with corresponding DeidentifyFileRequest schema. -""" -try: - # Initialize Skyflow client - # Step 1: Open file for deidentification - file_path="" - file = open(file_path, 'rb') # Open the file in read-binary mode - # Step 2: Create deidentify file request - request = DeidentifyFileRequest( - file=FileInput(file), # File to de-identify (can also provide a file path) - 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.BLACKBOX, # 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, FileInput -""" - * 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=FileInput(file), # File to de-identify (can also provide a file path) - 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', -) -``` - -### 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', -) -``` - -Incase of invalid/expired RunId: - -```python -DeidentifyFileResponse( - file_base64=None, - file=None, - type='UNKNOWN', - extension=None, - word_count=None, - char_count=None, - size_in_kb=0.0, - duration_in_seconds=None, - page_count=None, - slide_count=None, - entities=[], - run_id='1e9f321f-dd51-4ab1-a014-21212fsdfsd', - status='UNKNOWN' -) -``` - -### 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. -- **Inbound connections**: Act as intermediaries between your client and server, tokenizing sensitive data before it reaches your backend, ensuring downstream services handle only tokenized data. -- **Outbound connections**: Enable secure extraction of data from the vault and transfer it to third-party services via your backend server, such as processing checkout or card issuance flows. - -#### Invoke a connection To invoke a connection, use the `invoke` method of the Skyflow client. + #### Construct an invoke connection request ```python -from skyflow.error import SkyflowError -from skyflow.utils.enums import RequestMethod from skyflow.vault.connection import InvokeConnectionRequest +from skyflow.utils.enums import RequestMethod -""" -This example demonstrates how to invoke an external connection using the Skyflow SDK, along with corresponding InvokeConnectionRequest schema. -""" - -try: - # Initialize Skyflow client - # Step 1: Define the request body parameters - # These are the values you want to send in the request body - request_body = { - '': '', - '': '' - } - - # Step 2: Define the request headers - # Add any required headers that need to be sent with the request - request_headers = { - '': '', - '': '', - } - - # Step 3: Define the path parameters - # Path parameters are part of the URL and typically used in RESTful APIs - path_params = { - '': '', - '': '' - } - - # Step 4: Define the query parameters - # Query parameters are included in the URL after a '?' and are used to filter or modify the response - query_params = { - '': '', - '': '', - } - - # Step 5: Build the InvokeConnectionRequest using the provided parameters - invoke_connection_request = InvokeConnectionRequest( - method=RequestMethod.POST, # The HTTP method to use for the request (POST in this case) - body=request_body, # The body of the request - headers=request_headers, # The headers to include in the request - path_params=path_params, # The path parameters for the URL - query_params=query_params # The query parameters to append to the URL - ) - - # Step 6: Invoke the connection using the request - # Replace '' with the actual connection ID you are using - response = skyflow_client.connection('').invoke(invoke_connection_request) - - # Step 7: Print the response from the invoked connection - # This response contains the result of the request sent to the external system - print('Connection invocation successful: ', response) - -except SkyflowError as error: - # Step 8: Handle any exceptions that occur during the connection invocation - print('Skyflow Specific Error: ', { - 'code': error.http_code, - 'message': error.message, - 'details': error.details - }) -except Exception as error: - # Print the exception stack trace for debugging - print('Unexpected Error:', error) +invoke_request = InvokeConnectionRequest( + method=RequestMethod.POST, + body={ '': '' }, + headers={ '': '' }, + path_params={ '': '' }, + query_params={ '': '' } +) +response = skyflow_client.connection().invoke(invoke_request) +print('Connection response:', response) ``` `method` supports the following methods: -- GET -- POST -- PUT -- PATCH -- DELETE +- `GET` +- `POST` +- `PUT` +- `PATCH` +- `DELETE` **path_params, query_params, header, body** are the JSON objects represented as dictionaries that will be sent through the connection integration url. -#### An [example](https://github.com/skyflowapi/skyflow-python/blob/main/samples/vault_api/invoke_connection.py) of Invoke Connection - -```python -from skyflow import Skyflow, LogLevel -from skyflow.error import SkyflowError -from skyflow.utils.enums import RequestMethod -from skyflow.vault.connection import InvokeConnectionRequest +> [!TIP] +> See the full example in the samples directory: [invoke_connection.py](samples/vault_api/invoke_connection.py) +> See [docs.skyflow.com](https://docs.skyflow.com) for more details on integrations with Connections, Functions, and Pipelines. -""" -This example demonstrates how to invoke an external connection using the Skyflow SDK. -It configures a connection, sets up the request, and sends a POST request to the external service. +## Authentication & authorization -1. Initialize Skyflow client with connection details. -2. Define the request body, headers, and method. -3. Execute the connection request. -4. Print the response from the invoked connection. -""" +### Types of `credentials` -try: - # Initialize Skyflow client - # Step 1: Set up credentials and connection configuration - # Load credentials from a JSON file (you need to provide the correct path) - credentials = { - 'path': '/path/to/credentials.json' - } +The SDK accepts one of several types of credentials object. - # Define the connection configuration (URL and credentials) - connection_config = { - 'connection_id': '', # Replace with actual connection ID - 'connection_url': 'https://connection.url.com', # Replace with actual connection URL - 'credentials': credentials # Set credentials for the connection - } +1. **API keys** + A unique identifier used to authenticate and authorize requests to an API. Use for long-term service authentication. To create an API key, first create a 'Service Account' in Skyflow and choose the 'API key' option during creation. - # Initialize the Skyflow client with the connection configuration - skyflow_client = ( - Skyflow.builder() - .add_connection_config(connection_config) # Add connection configuration to client - .set_log_level(LogLevel.DEBUG) # Set log level to DEBUG for detailed logs - .build() # Build the Skyflow client instance - ) + ```python + credentials = { + "api_key": "" + } + ``` - # Step 2: Define the request body and headers - request_body = { - 'card_number': '4337-1696-5866-0865', # Example card number - 'ssn': '524-41-4248' # Example SSN - } +2. **Bearer tokens** + A temporary access token used to authenticate API requests. Use for optimal security. As a developer with the right access, you can generate a temporary personal bearer token in Skyflow in the user menu. - # Add any required headers that need to be sent with the request - request_headers = { - 'Content-Type': 'application/json', # Set content type for the request + ```python + credentials = { + "token": "" } + ``` - # Step 3: Build the InvokeConnectionRequest with required parameters - # Set HTTP method to POST, include the request body and headers - invoke_connection_request = InvokeConnectionRequest( - method=RequestMethod.POST, # The HTTP method to use for the request (POST in this case) - body=request_body, # The body of the request - headers=request_headers, # The headers to include in the request - ) - - # Step 4: Invoke the connection using the request - # Replace '' with the actual connection ID you are using - response = skyflow_client.connection('').invoke(invoke_connection_request) - - # Step 5: Print the response from the invoked connection - # This response contains the result of the request sent to the external system - print('Connection invocation successful: ', response) +3. **Service account credentials file path** + The file path pointing to a JSON file containing credentials for a service account. Use when credentials are managed externally or stored in secure file systems. -except SkyflowError as error: - # Step 6: Handle any exceptions that occur during the connection invocation - print('Skyflow Specific Error: ', { - 'code': error.http_code, - 'message': error.message, - 'details': error.details - }) -except Exception as error: - # Print the exception stack trace for debugging - print('Unexpected Error:', error) -``` - -Sample response: - -```python -ConnectionResponse( - { - 'card_number': '4337-1696-5866-0865', - 'ssn': '524-41-4248', - 'request_id': '4a3453b5-7aa4-4373-98d7-cf102b1f6f97' + ```python + credentials = { + "path": "" } -) - -``` - -### Authenticate with bearer tokens -This section covers methods for generating and managing tokens to authenticate API calls: - -- **Generate a bearer token:** -Enable the creation of bearer tokens using service account credentials. These tokens, valid for 60 minutes, provide secure access to Vault services and management APIs based on the service account's permissions. Use this for general API calls when you only need basic authentication without additional context or role-based restrictions. -- **Generate a bearer token with context:** -Support embedding context values into bearer tokens, enabling dynamic access control and the ability to track end-user identity. These tokens include context claims and allow flexible authorization for Vault services. Use this when policies depend on specific contextual attributes or when tracking end-user identity is required. -- **Generate a scoped bearer token:** -Facilitate the creation of bearer tokens with role-specific access, ensuring permissions are limited to the operations allowed by the designated role. This is particularly useful for service accounts with multiple roles. Use this to enforce fine-grained role-based access control, ensuring tokens only grant permissions for a specific role. -- **Generate signed data tokens:** -Add an extra layer of security by digitally signing data tokens with the service account's private key. These signed tokens can be securely detokenized, provided the necessary bearer token and permissions are available. Use this to add cryptographic protection to sensitive data, enabling secure detokenization with verified integrity and authenticity. - -#### Generate a bearer token -The [Service Account](https://github.com/skyflowapi/skyflow-python/tree/v2/skyflow/service_account) Python package generates service account tokens using a service account credentials file, which is provided when a service account is created. The tokens generated by this module are valid for 60 minutes and can be used to make API calls to the [Data](https://docs.skyflow.com/record/) and [Management](https://docs.skyflow.com/management/) APIs, depending on the permissions assigned to the service account. - -The `generate_bearer_token(filepath)` function takes the credentials file path for token generation, alternatively, you can also send the entire credentials as string, by using `generate_bearer_token_from_creds(credentials)` - -#### [Example](https://github.com/skyflowapi/skyflow-python/blob/main/samples/service_account/token_generation_example.py): + ``` -```python -import json -from skyflow.error import SkyflowError -from skyflow.service_account import ( - generate_bearer_token, - generate_bearer_token_from_creds, - is_expired, -) - -# Example program to generate a Bearer Token using Skyflow's service account utilities. -# The token can be generated in two ways: -# 1. Using the file path to a credentials.json file. -# 2. Using the JSON content of the credentials file as a string. - -# Variable to store the generated token -bearer_token = '' +4. **Service account credentials string** + JSON-formatted string containing service account credentials. Use when integrating with secret management systems or when credentials are passed programmatically. -# Example 1: Generate Bearer Token using a credentials.json file -try: - # Specify the full file path to the credentials.json file - file_path = 'CREDENTIALS_FILE_PATH' - - # Check if the token is already generated and still valid - if not is_expired(bearer_token): - print("Generated Bearer Token (from file):", bearer_token) - else: - # Generate a new Bearer Token from the credentials file - token, _ = generate_bearer_token(file_path) # Set credentials from the file path - bearer_token = token - # Print the generated Bearer Token to the console - print("Generated Bearer Token (from file):", bearer_token) -except SkyflowError as error: - # Handle any exceptions encountered during the token generation process - print(f"Error generating token from file path: {error}") -except Exception as e: - # Handle any other unexpected exceptions - print(f"Error generating token from file path: {e}") - -# Example 2: Generate Bearer Token using the credentials JSON string -try: - # Provide the credentials JSON content as a string - skyflow_credentials = { - 'clientID': '', - 'clientName': '', - 'tokenURI': '', - 'keyID': '', - 'privateKey': '', + ```python + credentials = { + "credentials_string": os.getenv("SKYFLOW_CREDENTIALS") } + ``` - # Convert credentials dictionary to JSON string - credentials_string = json.dumps(skyflow_credentials) - - # Check if the token is either not initialized or has expired - if not is_expired(bearer_token): - print("Generated Bearer Token (from string):", bearer_token) - else: - # Generate a new Bearer Token from the credentials string - token, _ = generate_bearer_token_from_creds(credentials_string) - bearer_token = token - print("Generated Bearer Token (from string):", bearer_token) -except SkyflowError as error: - # Handle any exceptions encountered during the token generation process - print(f"Error generating token from credentials string: {error}") -except Exception as e: - # Handle any other unexpected exceptions - print(f"Error generating token from credentials string: {e}") -``` - -#### Generate bearer tokens with context -**Context-aware authorization** embeds context values into a bearer token during its generation and so you can reference those values in your policies. This enables more flexible access controls, such as helping you track end-user identity when making API calls using service accounts, and facilitates using signed data tokens during detokenization. - -A service account with the context_id identifier generates bearer tokens containing context information, represented as a JWT claim in a Skyflow-generated bearer token. Tokens generated from such service accounts include a context_identifier claim, are valid for 60 minutes, and can be used to make API calls to the Data and Management APIs, depending on the service account's permissions. - -#### [Example](https://github.com/skyflowapi/skyflow-python/blob/main/samples/service_account/token_generation_with_context_example.py): -```python -import json -from skyflow.error import SkyflowError -from skyflow.service_account import ( - generate_bearer_token, - generate_bearer_token_from_creds, - is_expired, -) - -""" -Example program to generate a Bearer Token using Skyflow's BearerToken utility. -The token is generated using two approaches: -1. By providing the credentials.json file path. -2. By providing the contents of credentials.json as a string. -""" +5. **Environment variables** + If no credentials are explicitly provided, the SDK automatically looks for the SKYFLOW_CREDENTIALS environment variable. Use to avoid hardcoding credentials in source code. This variable must return an object like one of the examples above. -# Variable to store the generated token -bearer_token = '' +> [!NOTE] +> Only one type of credential can be used at a time. If multiple credentials are provided, the last one added will take precedence. -# Approach 1: Generate Bearer Token by specifying the path to the credentials.json file -try: - # Replace with the full path to your credentials.json file - file_path = 'YOUR_CREDENTIALS_FILE_PATH' - - # Set context string (example: "abc") - options = {'ctx': 'abc'} - - # Check if the token is already generated and still valid - if not is_expired(bearer_token): - print("Generated Bearer Token (from file):", bearer_token) - else: - # Generate a new Bearer Token from the credentials file - token, _ = generate_bearer_token(file_path, options) # Set credentials from the file path and options - bearer_token = token - # Print the generated Bearer Token to the console - print("Generated Bearer Token (from file):", bearer_token) -except SkyflowError as error: - # Handle any exceptions encountered during the token generation process - print(f"Error generating token from file path: {error}") -except Exception as e: - # Handle any other unexpected exceptions - print(f"Error generating token from file path: {e}") +### Generate bearer tokens for authentication & authorization -# Approach 2: Generate Bearer Token by specifying the contents of credentials.json as a string -try: - # Provide the credentials JSON content as a string - skyflow_credentials = { - 'clientID': '', - 'clientName': '', - 'tokenURI': '', - 'keyID': '', - 'privateKey': '', - } +Generate and manage bearer tokens to authenticate API calls. This section covers options for scoping to certain roles, passing context, and signing data tokens. - # Convert credentials dictionary to JSON string - credentials_string = json.dumps(skyflow_credentials) +#### Generate a bearer token - # Set context string (example: "abc") - options = {'ctx': 'abc'} +Generate service account tokens using the [Service Account](https://github.com/skyflowapi/skyflow-python/tree/main/skyflow/service_account) Python package with a service account credentials file provided when a service account is created. Tokens generated by this module are valid for 60 minutes and can be used to make API calls to the [Data](https://docs.skyflow.com/record/) and [Management](https://docs.skyflow.com/management/) APIs, depending on the permissions assigned to the service account. - # Check if the token is either not initialized or has expired - if not is_expired(bearer_token): - print("Generated Bearer Token (from string):", bearer_token) - else: - # Generate a new Bearer Token from the credentials string and options - token, _ = generate_bearer_token_from_creds(credentials_string, options) - bearer_token = token - print("Generated Bearer Token (from string):", bearer_token) -except SkyflowError as error: - # Handle any exceptions encountered during the token generation process - print(f"Error generating token from file path: {error}") -except Exception as e: - # Handle any other unexpected exceptions - print(f"Error generating token from credentials string: {e}") -``` +##### `generate_bearer_token(filepath)` -#### Generate scoped bearer tokens -A service account with multiple roles can generate bearer tokens with access limited to a specific role by specifying the appropriate roleID. This can be used to limit access to specific roles for services with multiple responsibilities, such as segregating access for billing and analytics. The generated bearer tokens are valid for 60 minutes and can only execute operations permitted by the permissions associated with the designated role. +The `generate_bearer_token(filepath)` function takes the `credentials.json` file path for token generation. -#### [Example](https://github.com/skyflowapi/skyflow-python/blob/main/samples/service_account/scoped_token_generation_example.py): ```python -import json -from skyflow.error import SkyflowError -from skyflow.service_account import ( - generate_bearer_token, - generate_bearer_token_from_creds, - is_expired, -) +from skyflow.service_account import generate_bearer_token -""" -Example program to generate a Scoped Token using Skyflow's BearerToken utility. -The token is generated by providing the file path to the credentials.json file -and specifying roles associated with the token. -""" - -# Variable to store the generated token -scoped_token = '' - -# Example: Generate Scoped Token by specifying the credentials.json file path -try: - # Specify the full file path to the service account's credentials.json file - file_path = 'YOUR_CREDENTIALS_FILE_PATH' - - # Set context string (example: "abc") - options = {'role_ids': ['ROLE_ID']} - - # Check if the token is already generated and still valid - if not is_expired(scoped_token): - print("Generated Bearer Token (from file):", scoped_token) - else: - # Generate a new Bearer Token from the credentials file and associated roles - scoped_token, _ = generate_bearer_token(file_path, options) # Set credentials from the file path and options - # Print the generated Bearer Token to the console - print("Generated Bearer Token (from file):", scoped_token) -except SkyflowError as error: - # Handle any exceptions encountered during the token generation process - print(f"Error generating token from file path: {error}") -except Exception as e: - # Handle any other unexpected exceptions - print(f"Error generating token from file path: {e}") +token, _ = generate_bearer_token('path/to/credentials.json') +print("Bearer Token:", token) ``` -#### Generate signed data tokens -Skyflow generates data tokens when sensitive data is inserted into the vault. These data tokens can be digitally signed with a service account's private key, adding an extra layer of protection. Signed tokens can only be detokenized by providing the signed data token along with a bearer token generated from the service account's credentials. The service account must have the necessary permissions and context to successfully detokenize the signed data tokens. - -#### [Example](https://github.com/skyflowapi/skyflow-python/blob/main/samples/service_account/signed_token_generation_example.py): -```python -import json -from skyflow.error import SkyflowError -from skyflow.service_account import ( - generate_signed_data_tokens, - generate_signed_data_tokens_from_creds, -) - -# Example program to generate Signed Data Tokens using Skyflow's utilities. -# Signed Data Tokens can be generated in two ways: -# 1. By specifying the file path to the credentials.json file. -# 2. By providing the credentials as a JSON string. +##### `generate_bearer_token_from_creds(credentials)` -# Example 1: Generate Signed Data Tokens using a credentials file -try: - # File path to the service account's credentials.json file - file_path = "CREDENTIALS_FILE_PATH" - - # Options for generating signed data tokens - options = { - "ctx": "CONTEX_ID", # Set the context value - "data_tokens": ["DATA_TOKEN1", "DATA_TOKEN2"], # Set the data tokens to be signed - "time_to_live": 30, # Set the data tokens to be signed - } - - # Generate and retrieve the signed data tokens - data_token, signed_data_token = generate_signed_data_tokens(file_path, options) - # Print the signed data tokens to the console - print("Signed Data Tokens (from file):", data_token, signed_data_token) -except SkyflowError as error: - # Handle any exceptions encountered during the token generation process - print(f"Error generating signed token from file path: {error}") -except Exception as e: - # Handle any other unexpected exceptions - print(f"Error generating signed token from file path: {e}") - -# Example 2: Generate Signed Data Tokens using credentials as a JSON string -try: - # JSON object containing Skyflow credentials - skyflow_credentials = { - "clientID": "", - "clientName": "", - "tokenURI": "", - "keyID": "", - "privateKey": "", - } - - # Convert credentials dictionary to JSON string - credentials_string = json.dumps(skyflow_credentials) +Alternatively, you can also send the entire credentials as string by using `generate_bearer_token_from_creds(string)`. - options = { - "ctx": "CONTEX_ID", # Context value associated with the token - "data_tokens": ["DATA_TOKEN1", "DATA_TOKEN2"], # Set the data tokens to be signed - "time_to_live": 30, # Set the token's time-to-live (TTL) in seconds - } - - # Generate and retrieve the signed data tokens - data_token, signed_data_token = generate_signed_data_tokens_from_creds(credentials_string, options) - # Print the signed data tokens to the console - print("Signed Data Tokens (from string):", data_token, signed_data_token) -except SkyflowError as error: - # Handle any exceptions encountered during the token generation process - print(f"Error generating signed token from credentials string: {error}") -except Exception as e: - # Handle any other unexpected exceptions - print(f"Error generating signed token from credentials string: {e}") - -``` - -Notes: -- The `time_to_live` (TTL) value should be specified in seconds. -- By default, the TTL value is set to 60 seconds. +> [!TIP] +> See the full example in the samples directory: [token_generation_example.py](https://github.com/skyflowapi/skyflow-python/blob/main/samples/service_account/token_generation_example.py) -#### 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/ -``` +#### Generate bearer tokens scoped to certain roles -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. +Generate bearer tokens with access limited to a specific role by specifying the appropriate roleID when using a service account with multiple roles. Use this to limit access for services with multiple responsibilities, such as segregating access for billing and analytics. Generated bearer tokens are valid for 60 minutes and can only execute operations permitted by the permissions associated with the designated role. -#### [Example](https://github.com/skyflowapi/skyflow-python/blob/main/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 +options = { + 'role_ids': ['roleID1', 'roleID2'] +} +``` - except Exception as error: - print("Unexpected error occurred:", error) - raise +> [!TIP] +> See the full example in the samples directory: [scoped_token_generation_example.py](samples/service_account/scoped_token_generation_example.py) +> See [docs.skyflow.com](https://docs.skyflow.com) for more details on authentication, access control, and governance for Skyflow. +#### Generate bearer tokens with `ctx` for context-aware authorization -def perform_detokenization(): - try: - # Setting up credentials for accessing the Skyflow vault - cred = { - 'clientID': '', - 'clientName': '', - 'tokenURI': '', - 'keyID': '', - 'privateKey': '', - } +Embed context values into a bearer token during generation so you can reference those values in your policies. This enables more flexible access controls, such as tracking end-user identity when making API calls using service accounts, and facilitates using signed data tokens during detokenization. - skyflow_credentials = { - 'credentials_string': json.dumps(cred) # Credentials string for authentication - } +Generate bearer tokens containing context information using a service account with the context_id identifier. Context information is represented as a JWT claim in a Skyflow-generated bearer token. Tokens generated from such service accounts include a context_identifier claim, are valid for 60 minutes, and can be used to make API calls to the Data and Management APIs, depending on the service account's permissions. - credentials = { - 'token': '' - } +> [!TIP] +> See the full example in the samples directory: [token_generation_with_context_example.py](samples/service_account/token_generation_with_context_example.py) +> See [docs.skyflow.com](https://docs.skyflow.com) for more details on authentication, access control, and governance for Skyflow. - # 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 - } +#### Generate signed data tokens: `generate_signed_data_tokens(filepath, options)` - # 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() - ) +Digitally sign data tokens with a service account's private key to add an extra layer of protection. Skyflow generates data tokens when sensitive data is inserted into the vault. Detokenize signed tokens only by providing the signed data token along with a bearer token generated from the service account's credentials. The service account must have the necessary permissions and context to successfully detokenize the signed data tokens. - # 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() -``` +> [!TIP] +> See the full example in the samples directory: [signed_token_generation_example.py](samples/service_account/signed_token_generation_example.py) +> See [docs.skyflow.com](https://docs.skyflow.com) for more details on authentication, access control, and governance for Skyflow. ## 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: Currently, the following five log levels are supported: + - `DEBUG`: When `LogLevel.DEBUG` is passed, logs at all levels will be printed (DEBUG, INFO, WARN, ERROR). - `INFO`: @@ -2763,60 +734,59 @@ When `LogLevel.ERROR` is passed, only ERROR logs will be printed. **Note:** The ranking of logging levels is as follows: `DEBUG` < `INFO` < `WARN` < `ERROR` < `OFF`. -```python -import json -from skyflow import Skyflow -from skyflow import LogLevel -from skyflow import Env - -""" -This example demonstrates how to configure the Skyflow client with custom log levels and authentication credentials (either token, credentials string, or other methods). It also shows how to configure a vault connection using specific parameters. -1. Set up credentials with a Bearer token or credentials string. -2. Define the Vault configuration. -3. Build the Skyflow client with the chosen configuration and set log level. -4. Example of changing the log level from ERROR (default) to INFO. -""" - -# Step 1: Set up credentials - either pass token or use credentials string -# In this case, we are using a Bearer token for authentication -credentials = { - 'token': '', # Replace with actual Bearer token -} - -# Step 2: Define the Vault configuration -# Configure the vault with necessary details like vault ID, cluster ID, and environment -vault_config = { - 'vault_id': '', # Replace with actual Vault ID (primary vault) - 'cluster_id': '', # Replace with actual Cluster ID (from vault URL) - 'env': Env.PROD, # Set the environment (default is PROD) - 'credentials': credentials # Set credentials for the vault (either token or credentials) -} - -# Step 3: Define additional Skyflow credentials (optional, if needed for credentials string) -skyflow_credentials = { - 'clientID': '', # Replace with your client ID - 'clientName': '', # Replace with your client name - 'tokenURI': '', # Replace with your token URI - 'keyID': '', # Replace with your key ID - 'privateKey': '', # Replace with your private key -} +### Example: Setting LogLevel to INFO -# Convert the credentials object to a json string format to be used for generating a Bearer Token -credentials_string = json.dumps(skyflow_credentials) # Set credentials string +```python +from skyflow import Skyflow, LogLevel -# Step 4: Build the Skyflow client with the chosen configuration and log level skyflow_client = ( Skyflow.builder() - .add_vault_config(vault_config) # Add the Vault configuration - .add_skyflow_credentials(skyflow_credentials) # Use Skyflow credentials if no token is passed - .set_log_level(LogLevel.INFO) # Set log level to INFO (default is ERROR) - .build() # Build the Skyflow client + .add_vault_config(vault_config) + .set_log_level(LogLevel.INFO) # Recommended to use LogLevel.ERROR in production + .build() ) +``` + +## Error handling + +### Catching `SkyflowError` instances -# Now, the Skyflow client is ready to use with the specified log level and credentials -print('Skyflow client has been successfully configured with log level: INFO.') +Wrap your calls to the Skyflow SDK in try/except blocks as a best practice. Use the `SkyflowError` class to identify errors coming from Skyflow versus general request/response errors. + +```python +try: + # ...call the Skyflow SDK + pass +except SkyflowError as error: + # Handle Skyflow specific errors + print("Skyflow Specific Error:", { + "code": error.http_code, + "message": error.message, + "details": error.details, + }) +except Exception as error: + # Handle generic errors + print("Unexpected Error:", error) +``` + +### Bearer token expiration edge cases + +When using bearer tokens for authentication and API requests, a token may expire after verification but before the actual API call completes. This causes the request to fail unexpectedly. An error from this edge case looks like this: + +```txt +message: Authentication failed. Bearer token is expired. Use a valid bearer token. See https://docs.skyflow.com/api-authentication/ ``` -## Reporting a Vulnerability +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. + +> [!TIP] +> See the full example in the samples directory: [bearer_token_expiry_example.py](samples/service_account/bearer_token_expiry_example.py) +> See [docs.skyflow.com](https://docs.skyflow.com) for more details on authentication, access control, and governance for Skyflow. + +## Security + +### Reporting a Vulnerability + +If you discover a potential security issue in this project, reach out to us at [security@skyflow.com](mailto:security@skyflow.com). -If you discover a potential security issue in this project, please reach out to us at **security@skyflow.com**. Please do not create public GitHub issues or Pull Requests, as malicious actors could potentially view them. +Don't create public GitHub issues or Pull Requests, as malicious actors could potentially view them. From 8e3e949e5493808e6b1f5837eb08a1c39b297e42 Mon Sep 17 00:00:00 2001 From: skyflow-himanshu Date: Mon, 1 Dec 2025 15:54:26 +0530 Subject: [PATCH 5/8] SK-2415 Addressed co-pilot changes --- docs/advanced_initialization.md | 4 ++-- docs/migrate_to_v2.md | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/advanced_initialization.md b/docs/advanced_initialization.md index 3eb5532..23cb957 100644 --- a/docs/advanced_initialization.md +++ b/docs/advanced_initialization.md @@ -71,7 +71,7 @@ credentials_string = json.dumps(skyflow_credentials) # Converts JSON object to # Step 5: Define secondary credentials (API key-based authentication as an example). # Demonstrates a different type of authentication mechanism for Skyflow vaults. secondary_credentials = { - 'token': '' # Replace with your API Key for authentication. + 'api_key': '' # Replace with your API Key for authentication. } # Step 6: Configure the secondary vault details. @@ -86,7 +86,7 @@ secondary_vault_config = { # Step 7: Define tertiary credentials using a path to a credentials JSON file. # This method demonstrates an alternative authentication method. tertiary_credentials = { - 'token': '' # Replace with the path to your credentials file. + 'path': '' # Replace with the path to your credentials file. } # Step 8: Configure the tertiary vault details. diff --git a/docs/migrate_to_v2.md b/docs/migrate_to_v2.md index 833129a..5e74c2e 100644 --- a/docs/migrate_to_v2.md +++ b/docs/migrate_to_v2.md @@ -19,11 +19,11 @@ These options allow you to choose the authentication method that best suits your ```python # User defined function to provide access token to the vault apis def token_provider(): - global bearerToken - if !(is_expired(bearerToken)): - return bearerToken - bearerToken, _ = generate_bearer_token('') - return bearerToken + global bearer_token + if not is_expired(bearer_token): + return bearer_token + bearer_token, _ = generate_bearer_token('') + return bearer_token ``` #### V2 (New): Passing one of the following: @@ -44,7 +44,7 @@ credentials = { # Option 4: Stringified JSON credentials = { - 'credentials_string': '', # Credentials as string + 'credentials_string': '', # Credentials as string } # Option 5: Bearer Token @@ -95,13 +95,13 @@ client = ( ``` **Key Changes:** -- `vault_url` replaced with `cluster_Id`. +- `vault_url` replaced with `cluster_id`. - Added environment specification (`env`). - Instance-specific log levels. ### Request & Response Structure -In V2, with the introduction of constructor parameters, you can now pass parameters to `InsertRequest`. This request need +In V2, with the introduction of constructor parameters, you can now pass parameters to `InsertRequest`. This request needs - **`table_name`**: The name of the table. - **`values`**: An array of objects containing the data to be inserted. The response will be of type `InsertResponse` class, which contains `inserted_fields` and errors. @@ -230,7 +230,7 @@ The error response now includes: #### V2 (New) Error Structure: -```typescript +```python { "http_status": "", "grpc_code": , From c481a5fee852f3ff625aa03f5f8030b3294ecd02 Mon Sep 17 00:00:00 2001 From: skyflow-himanshu Date: Fri, 5 Dec 2025 17:29:36 +0530 Subject: [PATCH 6/8] SK-2415 Addressed review comments --- README.md | 20 ++++++++++++--- docs/auth_credentials.md | 4 +-- docs/migrate_to_v2.md | 54 +++++++++++++++++++++------------------- 3 files changed, 46 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 8562e6c..b9d4ca8 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,7 @@ config = { } # Initialize Skyflow client -client = ( +skyflow_client = ( Skyflow.builder() .add_vault_config(config) .set_log_level(LogLevel.ERROR) @@ -164,7 +164,7 @@ insert_response = skyflow_client.vault('').insert(insert_request) print('Insert response:', insert_response) ``` -## Upgrade from V1 to V2 +## Upgrade from v1 to v2 Upgrade from `skyflow-python` v1 using the dedicated guide in [docs/migrate_to_v2.md](docs/migrate_to_v2.md). @@ -646,6 +646,8 @@ The SDK accepts one of several types of credentials object. JSON-formatted string containing service account credentials. Use when integrating with secret management systems or when credentials are passed programmatically. ```python + import os + credentials = { "credentials_string": os.getenv("SKYFLOW_CREDENTIALS") } @@ -717,7 +719,7 @@ Digitally sign data tokens with a service account's private key to add an extra ## 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: +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: Currently, the following five log levels are supported: @@ -737,7 +739,15 @@ When `LogLevel.ERROR` is passed, only ERROR logs will be printed. ### Example: Setting LogLevel to INFO ```python -from skyflow import Skyflow, LogLevel +from skyflow import Skyflow, LogLevel, Env + +# Define vault configuration +vault_config = { + 'vault_id': '', + 'cluster_id': '', + 'env': Env.PROD, + 'credentials': {'api_key': ''} +} skyflow_client = ( Skyflow.builder() @@ -754,6 +764,8 @@ skyflow_client = ( Wrap your calls to the Skyflow SDK in try/except blocks as a best practice. Use the `SkyflowError` class to identify errors coming from Skyflow versus general request/response errors. ```python +from skyflow.error import SkyflowError + try: # ...call the Skyflow SDK pass diff --git a/docs/auth_credentials.md b/docs/auth_credentials.md index 42409dc..a3b81c6 100644 --- a/docs/auth_credentials.md +++ b/docs/auth_credentials.md @@ -1,6 +1,6 @@ # Authentication credentials options -> **Note:** Only one type of credential can be used at a time. If multiple credentials are provided, the order of precedence depends on how they are passed to the configuration. +> **Note:** Only one type of credential can be used at a time. If multiple credentials are provided, the last one added takes precedence. 1. **API keys** A unique identifier used to authenticate and authorize requests to an API. @@ -41,4 +41,4 @@ ``` 5. **Environment variables** - If no credentials are explicitly provided the SDK automatically looks for the SKYFLOW_CREDENTIALS environment variable. This variable must return an object like one of the examples above. + If no credentials are explicitly provided, the SDK automatically looks for the `SKYFLOW_CREDENTIALS` environment variable. This variable must contain a JSON string like one of the examples above. diff --git a/docs/migrate_to_v2.md b/docs/migrate_to_v2.md index 5e74c2e..60a39fa 100644 --- a/docs/migrate_to_v2.md +++ b/docs/migrate_to_v2.md @@ -1,10 +1,10 @@ -# Migrate from V1 to V2 +# Migrate from v1 to v2 -This guide outlines the steps required to migrate the Skyflow Python SDK from version 1 (V1) to version 2 (V2). +This guide outlines the steps required to migrate the Skyflow Python SDK from version 1 (v1) to version 2 (v2). ## Authentication -In V2, multiple authentication options have been introduced. You can now provide credentials in the following ways: +In v2, multiple authentication options have been introduced. You can now provide credentials in the following ways: - **Passing credentials in ENV** (`SKYFLOW_CREDENTIALS`) (**Recommended**) - **API Key** @@ -14,7 +14,7 @@ In V2, multiple authentication options have been introduced. You can now provide These options allow you to choose the authentication method that best suits your use case. -### V1 (Old): Passing the token provider function below as a parameter to the Configuration. +### v1 (Old): Passing the token provider function below as a parameter to the Configuration. ```python # User defined function to provide access token to the vault apis @@ -26,7 +26,7 @@ def token_provider(): return bearer_token ``` -#### V2 (New): Passing one of the following: +#### v2 (New): Passing one of the following: ```python # Option 1: API Key (Recommended) @@ -60,7 +60,7 @@ credentials = { ### Initializing the client -In V2, we have introduced a Builder design pattern for client initialization and added support for multi-vault. This allows you to configure multiple vaults during client initialization. +In v2, we have introduced a Builder design pattern for client initialization and added support for multi-vault. This allows you to configure multiple vaults during client initialization. During client initialization, you can pass the following parameters: @@ -68,7 +68,7 @@ During client initialization, you can pass the following parameters: - **`env`**: Specify the environment (e.g., SANDBOX or PROD). - **`credentials`**: The necessary authentication credentials. -#### V1 (Old): +#### v1 (Old): ```python # Initializing a Skyflow Client instance with a SkyflowConfiguration object @@ -76,7 +76,7 @@ config = Configuration('', '', token_provider) client = Client(config) ``` -#### V2 (New): +#### v2 (New): ```python # Initializing a Skyflow Client instance @@ -101,14 +101,14 @@ client = ( ### Request & Response Structure -In V2, with the introduction of constructor parameters, you can now pass parameters to `InsertRequest`. This request needs +In v2, with the introduction of constructor parameters, you can now pass parameters to `InsertRequest`. This request needs - **`table_name`**: The name of the table. - **`values`**: An array of objects containing the data to be inserted. The response will be of type `InsertResponse` class, which contains `inserted_fields` and errors. **Note:** Similar patterns apply to other operations like Get, Update, Delete. See the [README](../README.md) for complete examples. -#### V1 (Old): Request Building +#### v1 (Old): Request Building ```python client.insert( @@ -127,9 +127,11 @@ client.insert( ) ``` -#### V2 (New): Request Building +#### v2 (New): Request Building ```python +from skyflow.vault.data import InsertRequest + # Prepare Insertion Data insert_data = [ { @@ -152,7 +154,7 @@ insert_request = InsertRequest( response = skyflow_client.vault(primary_vault_config.get('')).insert(insert_request) ``` -#### V1 (Old): Response Structure +#### v1 (Old): Response Structure ```json { @@ -170,7 +172,7 @@ response = skyflow_client.vault(primary_vault_config.get('')).insert(i } ``` -#### V2 (New): Response Structure +#### v2 (New): Response Structure ```python InsertResponse( @@ -186,9 +188,9 @@ InsertResponse( ### Request Options -In V2, we have introduced constructor parameters, allowing you to set options as key-value pairs as parameters in request. +In v2, we have introduced constructor parameters, allowing you to set options as key-value pairs as parameters in request. -#### V1 (Old): +#### v1 (Old): ```python options = InsertOptions( @@ -196,30 +198,30 @@ options = InsertOptions( ) ``` -#### V2 (New): +#### v2 (New): ```python insert_request = InsertRequest( - table=table_name, # Replace with the table name - values=insert_data, - return_tokens=False, # Do not return tokens - continue_on_error=False, # Stop inserting if any record fails - upsert='', # Replace with the column name used for upsert logic - token_mode=TokenMode.DISABLE, # Disable BYOT - tokens='' # Replace with tokens when TokenMode is ENABLE. + table=table_name, # Replace with the table name + values=insert_data, + return_tokens=False, # Do not return tokens + continue_on_error=False, # Stop inserting if any record fails + upsert='', # Replace with the column name used for upsert logic, if any + token_mode=TokenMode.DISABLE, # Disable BYOT + tokens='' # Set with tokens when TokenMode is ENABLE ) ``` ### Error Structure -In V2, we have enriched the error details to provide better debugging capabilities. +In v2, we have enriched the error details to provide better debugging capabilities. The error response now includes: - **http_status**: The HTTP status code. - **grpc_code**: The gRPC code associated with the error. - **details** & **message**: A detailed description of the error. - **request_id**: A unique request identifier for easier debugging. -#### V1 (Old) Error Structure: +#### v1 (Old) Error Structure: ```json { @@ -228,7 +230,7 @@ The error response now includes: } ``` -#### V2 (New) Error Structure: +#### v2 (New) Error Structure: ```python { From ab36fa389a5d7bb89ba32f08a58996cf7ccef767 Mon Sep 17 00:00:00 2001 From: Manny Silva <102989456+manny-silva@users.noreply.github.com> Date: Fri, 5 Dec 2025 09:26:00 -0800 Subject: [PATCH 7/8] Fix rendering issues based on spacing --- docs/auth_credentials.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/auth_credentials.md b/docs/auth_credentials.md index a3b81c6..7db462e 100644 --- a/docs/auth_credentials.md +++ b/docs/auth_credentials.md @@ -3,6 +3,7 @@ > **Note:** Only one type of credential can be used at a time. If multiple credentials are provided, the last one added takes precedence. 1. **API keys** + A unique identifier used to authenticate and authorize requests to an API. ```python @@ -12,6 +13,7 @@ ``` 2. **Bearer tokens** + A temporary access token used to authenticate API requests, typically included in the Authorization header. @@ -22,6 +24,7 @@ ``` 3. **Service account credentials file path** + The file path pointing to a JSON file containing credentials for a service account, used for secure API access. @@ -32,6 +35,7 @@ ``` 4. **Service account credentials string** + JSON-formatted string containing service account credentials, often used as an alternative to a file for programmatic authentication. ```python @@ -41,4 +45,5 @@ ``` 5. **Environment variables** + If no credentials are explicitly provided, the SDK automatically looks for the `SKYFLOW_CREDENTIALS` environment variable. This variable must contain a JSON string like one of the examples above. From 33ce48e8c6015082141eb6cd83433d17c162a9d9 Mon Sep 17 00:00:00 2001 From: skyflow-himanshu Date: Mon, 8 Dec 2025 11:41:29 +0530 Subject: [PATCH 8/8] SK-2415: address comment about primary_vault_config.get() --- docs/migrate_to_v2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/migrate_to_v2.md b/docs/migrate_to_v2.md index 60a39fa..4c94eb0 100644 --- a/docs/migrate_to_v2.md +++ b/docs/migrate_to_v2.md @@ -151,7 +151,7 @@ insert_request = InsertRequest( ) # Perform Secure Insertion -response = skyflow_client.vault(primary_vault_config.get('')).insert(insert_request) +response = skyflow_client.vault('').insert(insert_request) ``` #### v1 (Old): Response Structure