home / skills / jeremylongshore / claude-code-plugins-plus-skills / perplexity-sdk-patterns

This skill provides production-ready Perplexity SDK patterns for TypeScript and Python to standardize usage, error handling, and retries.

npx playbooks add skill jeremylongshore/claude-code-plugins-plus-skills --skill perplexity-sdk-patterns

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
3.8 KB
---
name: perplexity-sdk-patterns
description: |
  Apply production-ready Perplexity SDK patterns for TypeScript and Python.
  Use when implementing Perplexity integrations, refactoring SDK usage,
  or establishing team coding standards for Perplexity.
  Trigger with phrases like "perplexity SDK patterns", "perplexity best practices",
  "perplexity code patterns", "idiomatic perplexity".
allowed-tools: Read, Write, Edit
version: 1.0.0
license: MIT
author: Jeremy Longshore <[email protected]>
---

# Perplexity SDK Patterns

## Overview
Production-ready patterns for Perplexity SDK usage in TypeScript and Python.

## Prerequisites
- Completed `perplexity-install-auth` setup
- Familiarity with async/await patterns
- Understanding of error handling best practices

## Instructions

### Step 1: Implement Singleton Pattern (Recommended)
```typescript
// src/perplexity/client.ts
import { PerplexityClient } from '@perplexity/sdk';

let instance: PerplexityClient | null = null;

export function getPerplexityClient(): PerplexityClient {
  if (!instance) {
    instance = new PerplexityClient({
      apiKey: process.env.PERPLEXITY_API_KEY!,
      // Additional options
    });
  }
  return instance;
}
```

### Step 2: Add Error Handling Wrapper
```typescript
import { PerplexityError } from '@perplexity/sdk';

async function safePerplexityCall<T>(
  operation: () => Promise<T>
): Promise<{ data: T | null; error: Error | null }> {
  try {
    const data = await operation();
    return { data, error: null };
  } catch (err) {
    if (err instanceof PerplexityError) {
      console.error({
        code: err.code,
        message: err.message,
      });
    }
    return { data: null, error: err as Error };
  }
}
```

### Step 3: Implement Retry Logic
```typescript
async function withRetry<T>(
  operation: () => Promise<T>,
  maxRetries = 3,
  backoffMs = 1000
): Promise<T> {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      return await operation();
    } catch (err) {
      if (attempt === maxRetries) throw err;
      const delay = backoffMs * Math.pow(2, attempt - 1);
      await new Promise(r => setTimeout(r, delay));
    }
  }
  throw new Error('Unreachable');
}
```

## Output
- Type-safe client singleton
- Robust error handling with structured logging
- Automatic retry with exponential backoff
- Runtime validation for API responses

## Error Handling
| Pattern | Use Case | Benefit |
|---------|----------|---------|
| Safe wrapper | All API calls | Prevents uncaught exceptions |
| Retry logic | Transient failures | Improves reliability |
| Type guards | Response validation | Catches API changes |
| Logging | All operations | Debugging and monitoring |

## Examples

### Factory Pattern (Multi-tenant)
```typescript
const clients = new Map<string, PerplexityClient>();

export function getClientForTenant(tenantId: string): PerplexityClient {
  if (!clients.has(tenantId)) {
    const apiKey = getTenantApiKey(tenantId);
    clients.set(tenantId, new PerplexityClient({ apiKey }));
  }
  return clients.get(tenantId)!;
}
```

### Python Context Manager
```python
from contextlib import asynccontextmanager
from perplexity import PerplexityClient

@asynccontextmanager
async def get_perplexity_client():
    client = PerplexityClient()
    try:
        yield client
    finally:
        await client.close()
```

### Zod Validation
```typescript
import { z } from 'zod';

const perplexityResponseSchema = z.object({
  id: z.string(),
  status: z.enum(['active', 'inactive']),
  createdAt: z.string().datetime(),
});
```

## Resources
- [Perplexity SDK Reference](https://docs.perplexity.com/sdk)
- [Perplexity API Types](https://docs.perplexity.com/types)
- [Zod Documentation](https://zod.dev/)

## Next Steps
Apply patterns in `perplexity-core-workflow-a` for real-world usage.

Overview

This skill applies production-ready Perplexity SDK patterns for TypeScript and Python. It packages singleton/factory client creation, safe error handling, retry strategies, and response validation into practical, team-ready examples. Use it to standardize Perplexity integrations and reduce runtime issues in production systems.

How this skill works

The skill provides concrete code patterns: a singleton client and multi-tenant factory for managing Perplexity clients, an error-safe wrapper that normalizes errors and logs structured diagnostics, and an exponential-backoff retry helper. It also shows runtime validation (Zod) and an async context manager for Python to ensure clean resource shutdowns.

When to use it

  • Implementing Perplexity integrations in new services
  • Refactoring existing code to follow consistent SDK usage
  • Establishing team coding standards and templates for API clients
  • Handling transient network or API failures reliably
  • Validating and safeguarding against API schema changes

Best practices

  • Create a single shared client instance per process or a tenant-scoped factory for multi-tenant apps
  • Wrap all SDK calls in a safe error handler that returns structured {data,error} results
  • Use exponential-backoff retry for transient failures and limit retries for idempotent operations only
  • Validate API responses at runtime with a schema validator (Zod or type guards) to detect breaking changes early
  • Log structured error fields (code, message, metadata) for observability and alerting

Example use cases

  • Server backend that calls Perplexity for knowledge retrieval with a process-level singleton client
  • Multi-tenant SaaS using a client factory mapping tenantId -> client with separate API keys
  • CLI or worker process that retries transient failures with backoff and surfaces stable errors to monitoring
  • Python async service using an asynccontextmanager to ensure client.close() runs reliably
  • API gateway layer that validates Perplexity responses before forwarding data to downstream services

FAQ

How should I choose between singleton and factory patterns?

Use a singleton for single-tenant or single-key deployments to minimize resource usage. Use a factory or tenant map when each tenant requires its own API key or isolated client configuration.

When should I use retries vs failing fast?

Apply retries for transient errors (timeouts, 5xx). Fail fast for client errors (4xx) or non-idempotent operations where retry could cause unintended effects.

Do I need runtime validation if I have TypeScript types?

Yes. Runtime validation catches API contract changes and malformed responses that static types alone cannot detect at runtime.