Using SDKs and API

Complete guide to Python SDK, TypeScript SDK, and direct API usage

Using SDKs and API

Ducky provides multiple ways to integrate with our API, designed to fit different development preferences and environments. Whether you prefer type-safe SDKs or direct API calls, we've got you covered.

Available Integration Options

  • Python SDK: Full-featured SDK with sync/async support and context management
  • TypeScript SDK: Modern, zero-dependency SDK with tree-shaking support
  • Direct API: Use standard HTTP libraries like requests or fetch

Python SDK

Installation

Install the Python SDK using pip:

pip install duckyai

Quick Start

from duckyai import DuckyAI
import os

ducky = DuckyAI(api_key=os.getenv("DUCKYAI_API_KEY"))

# Index a document
res = ducky.documents.index(
    index_name="my-index",
    content="The quick brown fox jumps over the lazy dog",
    doc_id="example-doc",
    title="Example Document"
)
print(f"Indexed document: {res.doc_id}")

# Retrieve documents
results = ducky.documents.retrieve(
    index_name="my-index",
    query="brown fox",
    top_k=5
)
print(f"Found {len(results.documents)} documents")

Authentication

Set your API key using environment variables:

export DUCKYAI_API_KEY="your-api-key-here"

Or pass it directly to the client:

from duckyai import DuckyAI

ducky = DuckyAI(api_key="your-api-key-here")

Async Support

The Python SDK supports both synchronous and asynchronous operations:

import asyncio
from duckyai import DuckyAI

async def main():
    ducky = DuckyAI(api_key=os.getenv("DUCKYAI_API_KEY"))
    
    # Async document indexing
    res = await ducky.documents.index_async(
        index_name="my-index",
        content="Async content",
        doc_id="async-doc"
    )
    
    # Async document retrieval
    results = await ducky.documents.retrieve_async(
        index_name="my-index",
        query="async",
        top_k=3
    )
    
    print(f"Found {len(results.documents)} documents")

asyncio.run(main())

File Upload Support

Upload files directly with the Python SDK:

ducky = DuckyAI(api_key=os.getenv("DUCKYAI_API_KEY"))

with open("document.pdf", "rb") as file:
    res = ducky.documents.index_file(
        index_name="my-index",
        file={
            "file_name": "document.pdf",
            "content": file
        },
        doc_id="pdf-doc",
        title="My PDF Document"
    )

Available Operations

The Python SDK provides these core operations:

Documents:

  • index() - Index text content
  • index_file() - Upload and index files
  • batch_index() - Index multiple documents
  • retrieve() - Search and retrieve documents
  • get() - Get specific document by ID
  • delete() - Delete documents
  • list() - List all documents in index

Indexes:

  • create() - Create new index
  • list() - List all indexes
  • get() - Get index details
  • delete() - Delete index

TypeScript SDK

Installation

Install using your preferred package manager:

# npm
npm add duckyai-ts

# pnpm
pnpm add duckyai-ts

# bun
bun add duckyai-ts

# yarn (requires zod peer dependency)
yarn add duckyai-ts zod

Quick Start

import { Ducky } from "duckyai-ts";

const ducky = new Ducky({
  apiKey: process.env["DUCKY_API_KEY"] ?? "",
});

async function main() {
  // Index a document
  const indexResult = await ducky.documents.index({
    indexName: "my-index",
    content: "The quick brown fox jumps over the lazy dog",
    docId: "example-doc",
    title: "Example Document"
  });
  
  console.log(`Indexed document: ${indexResult.docId}`);
  
  // Retrieve documents
  const results = await ducky.documents.retrieve({
    indexName: "my-index",
    query: "brown fox",
    topK: 5
  });
  
  console.log(`Found ${results.documents.length} documents`);
}

main().catch(console.error);

Authentication

Set your API key using environment variables:

export DUCKY_API_KEY="your-api-key-here"

Or pass it directly to the client:

import { Ducky } from "duckyai-ts";

const ducky = new Ducky({
  apiKey: "your-api-key-here",
});

File Upload Support

Upload files with different JavaScript runtimes:

import { Ducky } from "duckyai-ts";
import { openAsBlob } from "node:fs"; // Node.js v20+

const ducky = new Ducky({
  apiKey: process.env["DUCKY_API_KEY"] ?? "",
});

async function uploadFile() {
  const result = await ducky.documents.indexFile({
    indexName: "my-index",
    file: await openAsBlob("document.pdf"),
    docId: "pdf-doc",
    title: "My PDF Document"
  });
  
  console.log(`Uploaded file: ${result.docId}`);
}

Standalone Functions

For applications where bundle size matters, use standalone functions:

import { documentsIndex, documentsRetrieve } from "duckyai-ts";

// Index a document
const indexResult = await documentsIndex({
  indexName: "my-index",
  content: "Standalone function example",
  docId: "standalone-doc"
}, {
  apiKey: process.env["DUCKY_API_KEY"] ?? "",
});

// Retrieve documents
const results = await documentsRetrieve({
  indexName: "my-index",
  query: "standalone",
  topK: 3
}, {
  apiKey: process.env["DUCKY_API_KEY"] ?? "",
});

Available Operations

The TypeScript SDK provides the same operations as Python:

Documents:

  • index() - Index text content
  • indexFile() - Upload and index files
  • batchIndex() - Index multiple documents
  • retrieve() - Search and retrieve documents
  • get() - Get specific document by ID
  • delete() - Delete documents
  • list() - List all documents in index

Indexes:

  • create() - Create new index
  • list() - List all indexes
  • get() - Get index details
  • delete() - Delete index

Direct API Usage

When to Use Direct API

Use direct API calls when:

  • Your language isn't supported by our SDKs
  • You need maximum control over HTTP requests
  • You're building a custom integration
  • You prefer working with raw HTTP responses

Authentication

Include your API key in the request headers:

curl -X POST "https://api.ducky.ai/v1/documents/index-text" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "index_name": "my-index",
    "content": "The quick brown fox jumps over the lazy dog",
    "doc_id": "example-doc",
    "title": "Example Document"
  }'

Python with requests

import requests
import os

api_key = os.getenv("DUCKYAI_API_KEY")
headers = {
    "x-api-key": api_key,
    "Content-Type": "application/json"
}

# Index a document
response = requests.post(
    "https://api.ducky.ai/v1/documents/index-text",
    headers=headers,
    json={
        "index_name": "my-index",
        "content": "The quick brown fox jumps over the lazy dog",
        "doc_id": "example-doc",
        "title": "Example Document"
    }
)

if response.status_code == 202:
    print(f"Document indexed: {response.json()['doc_id']}")
else:
    print(f"Error: {response.status_code} - {response.text}")

# Retrieve documents
response = requests.post(
    "https://api.ducky.ai/v1/documents/retrieve",
    headers=headers,
    json={
        "index_name": "my-index",
        "query": "brown fox",
        "top_k": 5
    }
)

if response.status_code == 200:
    results = response.json()
    print(f"Found {len(results['documents'])} documents")

JavaScript with fetch

const apiKey = process.env.DUCKY_API_KEY;
const headers = {
  'x-api-key': apiKey,
  'Content-Type': 'application/json'
};

// Index a document
const indexResponse = await fetch('https://api.ducky.ai/v1/documents/index-text', {
  method: 'POST',
  headers: headers,
  body: JSON.stringify({
    index_name: 'my-index',
    content: 'The quick brown fox jumps over the lazy dog',
    doc_id: 'example-doc',
    title: 'Example Document'
  })
});

if (indexResponse.ok) {
  const result = await indexResponse.json();
  console.log(`Document indexed: ${result.doc_id}`);
}

// Retrieve documents
const retrieveResponse = await fetch('https://api.ducky.ai/v1/documents/retrieve', {
  method: 'POST',
  headers: headers,
  body: JSON.stringify({
    index_name: 'my-index',
    query: 'brown fox',
    top_k: 5
  })
});

if (retrieveResponse.ok) {
  const results = await retrieveResponse.json();
  console.log(`Found ${results.documents.length} documents`);
}

Comparison Table

FeaturePython SDKTypeScript SDKDirect API
Type Safety✅ Full✅ Full❌ Manual
Error Handling✅ Built-in✅ Built-in⚠️ Manual
Async Support✅ Yes✅ Yes✅ Yes
File Uploads✅ Streamlined✅ Streamlined⚠️ Manual
Resource Management✅ Context Manager✅ Automatic⚠️ Manual
Bundle SizeN/A✅ Tree-shakeable✅ Minimal
Retry Logic✅ Built-in✅ Built-in⚠️ Manual
Documentation✅ Generated✅ Generated✅ API Reference

Best Practices

API Key Management

  • Store API keys in environment variables, never in code
  • Use different keys for development and production
  • Rotate keys regularly for security
# Development
export DUCKYAI_API_KEY="dk-dev-xxxxx"

# Production
export DUCKYAI_API_KEY="dk-prod-xxxxx"

Error Handling

Python SDK:

from duckyai import DuckyAI
from duckyai.models import APIError

try:
    ducky = DuckyAI(api_key=os.getenv("DUCKYAI_API_KEY"))
    result = ducky.documents.index(...)
except APIError as e:
    print(f"API Error: {e.status_code} - {e.message}")
except Exception as e:
    print(f"Unexpected error: {e}")

TypeScript SDK:

import { Ducky } from "duckyai-ts";
import * as errors from "duckyai-ts/models/errors";

try {
  const result = await ducky.documents.index(...);
} catch (error) {
  if (error instanceof errors.DuckyError) {
    console.log(`API Error: ${error.statusCode} - ${error.message}`);
  } else {
    console.log(`Unexpected error: ${error}`);
  }
}

Resource Management

Python SDK: The SDK handles resource management automatically, but for long-running applications, consider creating a single client instance:

# Good for simple scripts
ducky = DuckyAI(api_key=api_key)
result = ducky.documents.index(...)

# Good for long-running applications
class MyApp:
    def __init__(self):
        self.ducky = DuckyAI(api_key=api_key)
    
    def process_document(self, content):
        return self.ducky.documents.index(...)

TypeScript SDK: The SDK handles resource management automatically, but be mindful of connection limits in long-running applications.

Performance Tips

  1. Batch operations when possible using batch_index()
  2. Use appropriate top_k values - don't retrieve more documents than needed
  3. Implement client-side caching for frequently accessed documents
  4. Use async operations for better concurrency in I/O-bound applications

Links and Resources

🦆

Need help? Get in touch or check our roadmap