smart-search-sdk 0.0.12
SDK for Smart Search API backend
Requires Python: >=3.11

<p align="center">
  🔍 Smart Search SDK 🐍
</p>

<p align="center">
    <a href="https://pypi.org/project/smart-search-sdk/"><img src="https://img.shields.io/pypi/v/smart-search-sdk" alt="PyPI Latest Release"></a>
    <a href="https://github.com/GDP-ADMIN/smart-search-sdk/blob/main/python/smart-search-sdk/LICENSE"><img src="https://img.shields.io/pypi/l/smart-search-sdk" alt="License"></a>
</p>

A comprehensive Python SDK for interacting with Smart Search services, including web search, connector search, deep research, and authentication email management. Built with a clean, intuitive API design for rapid development of search applications.

## 📋 Overview

Smart Search SDK is a Python library that simplifies interaction with Smart Search services. It provides a clean, intuitive API for performing web searches, connector searches, deep research, and managing authentication emails, enabling rapid development of search applications.

## 📋 Requirements

**Python 3.11.x** or higher is required.

## ✨ Features

- **🌐 Web Search**: Search the web for documents, URLs, and extract content from web pages
- **🔗 Connector Search**: Search and manage third-party service connectors (GitHub, Google Drive, Google Mail, Google Calendar)
- **🔬 Deep Research**: Conduct comprehensive research using various research types
- **📧 Authentication Email Management**: Retrieve and manage authentication emails
- **🔐 Authentication Support**: Built-in token-based authentication
- **🚀 Simple API**: Send requests and receive responses with minimal code
- **🎯 Type Safety**: Comprehensive type hints for better development experience
- **🔄 Flexible Response Handling**: Choose between different response formats
- **📚 Comprehensive Documentation**: Extensive documentation and examples

## 📦 Installation

To install the package:

```bash
pip install smart-search-sdk
```

After installation, you can verify it works by trying to import it from any directory:

```python
from smart_search_sdk.web.client import WebSearchClient
from smart_search_sdk.connector.client import ConnectorClient
from smart_search_sdk.search.client import SmartSearchSearchClient
from smart_search_sdk.deep_research.client import SmartSearchDeepResearchClient
```

## 🚀 Quick Start

Creating a web search client with Smart Search SDK is incredibly simple:

```python
import asyncio
from smart_search_sdk.web.client import WebSearchClient
from smart_search_sdk.web.models import GetWebSearchResultsRequest

async def main():
    # Initialize the Web Search client
    client = WebSearchClient(base_url="your-api-url")
    await client.authenticate(token="your-token")

    # Perform a web search
    request = GetWebSearchResultsRequest(
        query="What is artificial intelligence?",
        result_type="snippets",
        size=5
    )
    response = client.search_web(request)
    print(response)

asyncio.run(main())
```

Note: Make sure you have the correct API URL and token before running examples.

## 📦 Available Clients

### 1. 🌐 Web Search Client

* `search_web`: Search the web for documents or pages relevant to the input query
* `search_web_urls`: Search the web for pages and return their URLs
* `fetch_web_page`: Fetch a single web page by URL
* `get_web_page_snippets`: Extract relevant text snippets from a web page
* `get_web_page_keypoints`: Extract key points from a web page

```python
from smart_search_sdk.web.client import WebSearchClient
from smart_search_sdk.web.models import GetWebSearchResultsRequest

client = WebSearchClient(base_url="your-api-url")
await client.authenticate(token="your-token")

request = GetWebSearchResultsRequest(
    query="Python programming tutorials",
    result_type="snippets",
    size=5
)
response = client.search_web(request)
```

### 2. 🔗 Connector Client

* `search_connector`: Search a connector for the specified app
* `connect_connector`: Initiate integration with a third-party connector
* `disconnect_connector`: Remove integration with a third-party connector

```python
from smart_search_sdk.connector.client import ConnectorClient
from smart_search_sdk.connector.models import ConnectorRequest, AppName

client = ConnectorClient(base_url="your-api-url")
await client.authenticate(token="your-token")

request = ConnectorRequest(query="Find all Smart Search emails")
response = client.search_connector(
    app_name=AppName.GOOGLE_CALENDAR,
    gl_token="your-gl-token",
    request=request
)
```

### 3. 🔍 Smart Search Client

* `search`: Perform a search operation using specified search profile names and query
* `deep_search`: Perform deep research based on input data

```python
from smart_search_sdk.search.client import SmartSearchSearchClient
from smart_search_sdk.search.models import SmartSearchKeyPointsRequest

client = SmartSearchSearchClient(base_url="your-api-url")
await client.authenticate(token="your-token")

request = SmartSearchKeyPointsRequest(
    query="artificial intelligence",
    search_profile_names=["general", "github"],
    size=5
)
response = client.search(request)
```

### 4. 🔬 Deep Research Client

* `deep_research`: Perform comprehensive research using various research types

```python
from smart_search_sdk.deep_research.client import SmartSearchDeepResearchClient

client = SmartSearchDeepResearchClient(base_url="your-api-url")
await client.authenticate(token="your-token")

response = client.deep_research(query="your research query")
```

## 🔐 Environment Variables

Smart Search SDK uses `os.getenv()` to read environment variables. **You are responsible for loading environment variables** in your application before initializing the Smart Search clients. You can use libraries like `python-dotenv`, `python-decouple`, or set them directly in your shell.

**Available environment variables:**

- `SMARTSEARCH_BASE_URL`: The base URL for the Smart Search API
- `SMARTSEARCH_TOKEN`: Your Smart Search authentication token
- `GL_CONNECTORS_USER_TOKEN`: Optional GL Connectors token for connector authentication

**Example using python-dotenv:**

First, install python-dotenv:

```bash
pip install python-dotenv
```

Create a `.env` file:

```bash
SMARTSEARCH_BASE_URL=https://your-api-endpoint.com/
SMARTSEARCH_TOKEN=your-authentication-token
GL_CONNECTORS_USER_TOKEN=your-gl-token
```

Load environment variables in your code:

```python
from dotenv import load_dotenv
from smart_search_sdk.web.client import WebSearchClient

# Load environment variables from .env file
load_dotenv()

# Will automatically use environment variables
client = WebSearchClient()
await client.authenticate()
```

**Example using shell export:**

```bash
export SMARTSEARCH_BASE_URL="https://your-api-endpoint.com/"
export SMARTSEARCH_TOKEN="your-authentication-token"
export GL_CONNECTORS_USER_TOKEN="your-gl-token"
```

Then initialize the client without parameters:

```python
from smart_search_sdk.web.client import WebSearchClient

# Will automatically use environment variables
client = WebSearchClient()
await client.authenticate()
```

## 🔧 Advanced Usage

### 🌐 Web Search with Different Result Types

```python
from smart_search_sdk.web.client import WebSearchClient
from smart_search_sdk.web.models import GetWebSearchResultsRequest

client = WebSearchClient(base_url="your-api-url")
await client.authenticate(token="your-token")

# Search with snippets
snippets_request = GetWebSearchResultsRequest(
    query="Python programming best practices",
    result_type="snippets",
    size=5
)
snippets_response = client.search_web(snippets_request)

# Search with keypoints
keypoints_request = GetWebSearchResultsRequest(
    query="Machine learning algorithms",
    result_type="keypoints",
    size=3
)
keypoints_response = client.search_web(keypoints_request)
```

### 🔗 Connector Management

```python
from smart_search_sdk.connector.client import ConnectorClient
from smart_search_sdk.connector.models import ConnectorRequest, ConnectorConnectRequest, AppName

client = ConnectorClient(base_url="your-api-url")
await client.authenticate(token="your-token")

# Connect to a connector
connect_request = ConnectorConnectRequest(
    callback_url="https://your-app.com/callback"
)
connect_response = client.connect_connector(
    app_name=AppName.GOOGLE_CALENDAR,
    gl_token="your-gl-token",
    request=connect_request
)

# Search the connector
search_request = ConnectorRequest(query="Find meetings next week")
search_response = client.search_connector(
    app_name=AppName.GOOGLE_CALENDAR,
    gl_token="your-gl-token",
    request=search_request
)
```

### 🔍 Smart Search with Multiple Profiles

```python
from smart_search_sdk.search.client import SmartSearchSearchClient
from smart_search_sdk.search.models import SmartSearchKeyPointsRequest

client = SmartSearchSearchClient(base_url="your-api-url")
await client.authenticate(token="your-token")

# Search with multiple profiles
request = SmartSearchKeyPointsRequest(
    query="artificial intelligence trends",
    search_profile_names=["general", "github", "google_drive"],
    size=10
)
response = client.search(request)
```

## 📚 API Reference

### WebSearchClient

The client class for performing web search operations.

#### 🔧 Initialization

```python
client = WebSearchClient(base_url: str = "")
```

**Parameters:**

- `base_url`: The base URL for the Smart Search API 🌐 (or set SMARTSEARCH_BASE_URL env var)

#### Methods

##### 🌐 search_web

Search the web for documents or pages relevant to the input query.

```python
response = client.search_web(request: GetWebSearchResultsRequest) -> dict
```

**Parameters:**

- `request`: GetWebSearchResultsRequest containing query, result_type, and size 🔍

**Returns:**

- `dict`: Web search response data 📄

##### 🔗 search_web_urls

Search the web for pages and return their URLs.

```python
response = client.search_web_urls(request: GetWebSearchUrlsRequest) -> dict
```

##### 📄 fetch_web_page

Fetch a single web page by URL.

```python
response = client.fetch_web_page(request: GetWebPageRequest) -> dict
```

### ConnectorClient

The client class for managing third-party service connectors.

#### 🔧 Initialization

```python
client = ConnectorClient(base_url: str = "")
```

#### Methods

##### 🔍 search_connector

Search a connector for the specified app.

```python
response = client.search_connector(
    app_name: AppName,
    gl_token: str,
    request: ConnectorRequest
) -> dict
```

##### 🔗 connect_connector

Initiate integration with a third-party connector.

```python
response = client.connect_connector(
    app_name: AppName,
    gl_token: str,
    request: ConnectorConnectRequest
) -> dict
```

##### ❌ disconnect_connector

Remove integration with a third-party connector.

```python
response = client.disconnect_connector(
    app_name: AppName,
    gl_token: str
) -> dict
```

### SmartSearchSearchClient

The client class for performing smart search operations.

#### 🔧 Initialization

```python
client = SmartSearchSearchClient(base_url: str = "")
```

#### Methods

##### 🔍 search

Perform a search operation using specified search profile names and query.

```python
response = client.search(request: SmartSearchKeyPointsRequest) -> dict
```

##### 🔬 deep_search

Perform deep research based on input data.

```python
response = client.deep_search(query: str) -> dict
```

## 🔐 Authentication

The clients support token-based authentication with flexible configuration options. The authentication token can be provided either as a parameter during the authenticate method or through environment variables.

### 🔑 Token Configuration

**Option 1: Direct Parameter**

```python
client = WebSearchClient(base_url="your-api-url")
await client.authenticate(token="your-token")
```

**Option 2: Environment Variable**

```bash
export SMARTSEARCH_TOKEN="your-token"
```

```python
client = WebSearchClient(base_url="your-api-url")
await client.authenticate()  # Automatically uses SMARTSEARCH_TOKEN environment variable
```

**Option 3: Priority System**

```python
# Parameter takes priority over environment variable
client = WebSearchClient(base_url="your-api-url")
await client.authenticate(token="explicit-token")  # Uses explicit token even if env var is set
```

### 🔒 Authentication Headers

When a token is provided (via parameter or environment variable), it's automatically included in the Authorization header for all requests:

```python
# Token is automatically used in requests 🔑
client = WebSearchClient(base_url="your-api-url")
await client.authenticate(token="your-token")
response = client.search_web(request)
```

### ⚠️ Required Configuration

**Authentication is required** - you must provide it either:

- As the `token` parameter when calling `authenticate()`, OR
- Set the `SMARTSEARCH_TOKEN` environment variable

If neither is provided, the client will raise an error:

```python
client = WebSearchClient(base_url="your-api-url")
await client.authenticate()  # Raises error if SMARTSEARCH_TOKEN is not set
```

## 🚀 Examples

To see the SDK in action, we provide comprehensive example scripts:

### 📁 Available Examples

1. **`simple.py`** - Interactive CLI example with menu-driven interface
2. **`web_search.py`** - Non-interactive web search demonstrations
3. **`connector_search.py`** - Non-interactive connector search demonstrations

### 🚀 How to Run Examples

Navigate to the examples directory and run:

```bash
# Interactive example with full menu
python simple.py

# Web search demonstrations
python web_search.py

# Connector search demonstrations
python connector_search.py
```

### 📋 Prerequisites

Before running examples, set up your environment variables:

```bash
export SMARTSEARCH_BASE_URL="https://your-api-endpoint.com/"
export SMARTSEARCH_TOKEN="your-authentication-token"
export GL_CONNECTORS_USER_TOKEN="your-gl-token"  # Optional, for connector operations
```

Or create a `.env` file in the examples directory:

```bash
SMARTSEARCH_BASE_URL=https://your-api-endpoint.com/
SMARTSEARCH_TOKEN=your-authentication-token
GL_CONNECTORS_USER_TOKEN=your-gl-token
```

## 📄 Documentation

### 📘 General Documentation

1. [Product Requirements](https://docs.google.com/document/d/1fngiR4ouPsAbCZpXgHFRbJHeLIJVLJPrIE89MC5M7do/edit?usp=sharing)
2. [Architecture Overview](https://docs.google.com/document/d/16_E1neWkqWf1Nt4gSfvtiEMcdjx5cCHTjv0a1wC4Sko/edit?usp=sharing)
3. [Design Documents](https://docs.google.com/document/d/1-wZC0d2gkId6caLwe_vn_3REJEaUd73cpTOX73aML0M/edit?usp=sharing)
4. [Implementation Guide](https://docs.google.com/document/d/1sYXQbaWkUQomZUTkJ7dSO2_6ZF3b7UvOjnOljQAYSqI/edit?usp=sharing)
5. Deployment Documents:

   * [GLoria / GL Chat Internal](https://docs.google.com/document/d/1pUHanTO5fDmydS45fV7NxBIia0CqZDchpVnO6ppqvlw/edit?usp=sharing)
   * [BCA Project](https://docs.google.com/document/d/1NiyfeLA9xL9FNrADM5U6I1hLKnLJS2f2P02TiPiVZL8/edit?usp=sharing)

### 🚀 Onboarding & Features

6. [Smart Search Onboarding Guide](https://docs.google.com/document/d/1KRo4ifJLO8H4_JC-E0WZfhbzGAUElxD0EtDZD9m7qhY/edit?usp=sharing)
7. [Smart Search Features Roadmap](https://docs.google.com/spreadsheets/d/1lZXSp1XyFn9yzQ_zF67DL4p8Wd68G-5ARZydMjwzNkI/edit?usp=sharing)
8. [Environment Information](https://docs.google.com/document/d/1WNS_7K3qOCeTDp5Dw485zryJcEt5qIvyjghMgev4oW4/edit?usp=drive_link)
9. [Swirl's Search Providers](https://docs.google.com/document/d/1OzCz3A2ykCfUs_JF6DsCaOrMlqBI_nEXBdBNJbQf_zw/edit?usp=drive_link)

### 🔍 Deep Search Documentation

10. [Deep Search Product Requirements](https://docs.google.com/document/d/1li1tnauQvh-fA1n5_jc0UIRnpEG1rfjDtIjHanJcpyg/edit?usp=sharing)
11. [Deep Search Architecture](https://docs.google.com/document/d/1eIAQkObbQ8eNJE-9LNKGPJ4AJYIDS_c2zFmoOv7_6gE/edit?usp=sharing)
12. [Deep Search Design](https://docs.google.com/document/d/1SkwsoJybWNPd2im315k2GFjzwblI12iepuj5AdjguYQ/edit?usp=sharing)
13. [Deep Search Implementation](https://docs.google.com/document/d/1lEscMV1rjKO5jMuKBId-mOz1GA5WkJXJQXlJI3JDaKU/edit?usp=sharing)

### 📚 API Reference

14. [API Documentation](https://search-api.gdplabs.id/docs)

## 🧭 Notes

* For the most up-to-date SDK usage, please refer to the inline docstrings or API Docs.
* Deprecated methods will be removed in future releases—please migrate to their updated alternatives.

## ⚠️ Error Handling

The clients use `httpx` for HTTP requests and will raise appropriate exceptions for HTTP errors. Make sure to handle these exceptions in your code:

```python
import asyncio
from smart_search_sdk.web.client import WebSearchClient
from smart_search_sdk.web.models import GetWebSearchResultsRequest

async def safe_web_search():
    try:
        client = WebSearchClient(base_url="your-api-url")
        await client.authenticate(token="your-token")

        request = GetWebSearchResultsRequest(
            query="Python programming",
            result_type="snippets",
            size=5
        )
        response = client.search_web(request)
        return response

    except Exception as e:
        print(f"Error occurred: {str(e)}")
        return None

# Run the safe search
result = asyncio.run(safe_web_search())
```

## 🧭 Notes

* For the most up-to-date SDK usage, please refer to the inline docstrings or API Docs.
* All clients inherit from `BaseSmartSearchClient` which provides common authentication and HTTP request functionality.
* The SDK supports both synchronous and asynchronous operations, with async being the recommended approach.
* Deprecated methods will be removed in future releases—please migrate to their updated alternatives.