Claude-code-plugins palantir-sdk-patterns
install
source · Clone the upstream repo
git clone https://github.com/jeremylongshore/claude-code-plugins-plus-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/jeremylongshore/claude-code-plugins-plus-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/saas-packs/palantir-pack/skills/palantir-sdk-patterns" ~/.claude/skills/jeremylongshore-claude-code-plugins-palantir-sdk-patterns && rm -rf "$T"
manifest:
plugins/saas-packs/palantir-pack/skills/palantir-sdk-patterns/SKILL.mdsource content
Palantir SDK Patterns
Overview
Production-ready patterns for Foundry Platform SDK and OSDK usage. Covers client singletons, typed error handling, pagination helpers, retry logic, and multi-tenant client factories.
Prerequisites
- Completed
setuppalantir-install-auth - Familiarity with async/await patterns
orfoundry-platform-sdk
installed@osdk/client
Instructions
Step 1: Singleton Client (Python)
# src/foundry_client.py import os import foundry from functools import lru_cache @lru_cache(maxsize=1) def get_client() -> foundry.FoundryClient: """Thread-safe singleton — cached after first call.""" auth = foundry.ConfidentialClientAuth( client_id=os.environ["FOUNDRY_CLIENT_ID"], client_secret=os.environ["FOUNDRY_CLIENT_SECRET"], hostname=os.environ["FOUNDRY_HOSTNAME"], scopes=["api:read-data", "api:write-data"], ) auth.sign_in_as_service_user() return foundry.FoundryClient(auth=auth, hostname=os.environ["FOUNDRY_HOSTNAME"])
Step 2: Typed Error Handling
import foundry from dataclasses import dataclass from typing import TypeVar, Generic, Optional T = TypeVar("T") @dataclass class Result(Generic[T]): data: Optional[T] = None error: Optional[str] = None status_code: Optional[int] = None def safe_call(fn, *args, **kwargs) -> Result: """Wrap any Foundry SDK call with structured error handling.""" try: return Result(data=fn(*args, **kwargs)) except foundry.ApiError as e: return Result(error=e.message, status_code=e.status_code) except Exception as e: return Result(error=str(e)) # Usage result = safe_call( get_client().ontologies.OntologyObject.list, ontology="my-company", object_type="Employee", page_size=10, ) if result.error: print(f"Error {result.status_code}: {result.error}") else: print(f"Found {len(result.data.data)} objects")
Step 3: Pagination Helper
def paginate_objects(client, ontology: str, object_type: str, page_size: int = 100): """Iterate through all objects with automatic pagination.""" page_token = None while True: result = client.ontologies.OntologyObject.list( ontology=ontology, object_type=object_type, page_size=page_size, page_token=page_token, ) yield from result.data page_token = result.next_page_token if not page_token: break # Usage for emp in paginate_objects(get_client(), "my-company", "Employee"): print(emp.properties["fullName"])
Step 4: Retry with Exponential Backoff
import time import random def retry_with_backoff(fn, max_retries=3, base_delay=1.0): """Retry on 429/5xx with jittered exponential backoff.""" for attempt in range(max_retries + 1): try: return fn() except foundry.ApiError as e: if attempt == max_retries or e.status_code not in (429, 500, 502, 503): raise delay = base_delay * (2 ** attempt) + random.uniform(0, 0.5) print(f"Retry {attempt + 1}/{max_retries} in {delay:.1f}s (HTTP {e.status_code})") time.sleep(delay)
Step 5: TypeScript OSDK Patterns
import { createClient, type Client } from "@osdk/client"; import { createConfidentialOauthClient } from "@osdk/oauth"; // Singleton with lazy initialization let _client: Client | null = null; export function getOsdkClient(): Client { if (!_client) { const oauth = createConfidentialOauthClient( process.env.FOUNDRY_CLIENT_ID!, process.env.FOUNDRY_CLIENT_SECRET!, `https://${process.env.FOUNDRY_HOSTNAME}/multipass/api/oauth2/token`, ); _client = createClient( `https://${process.env.FOUNDRY_HOSTNAME}`, process.env.ONTOLOGY_RID!, oauth, ); } return _client; }
Output
- Thread-safe singleton client with cached auth
- Structured Result type for error handling
- Automatic pagination for large object sets
- Retry logic with jittered backoff
Error Handling
| Pattern | Use Case | Benefit |
|---|---|---|
| Singleton | All API calls | One auth flow, reused connection |
| Result wrapper | Error propagation | No uncaught exceptions |
| Pagination helper | Large datasets | Memory-safe iteration |
| Retry with backoff | Transient failures | Resilient operations |
Examples
Multi-Tenant Client Factory
_clients: dict[str, foundry.FoundryClient] = {} def get_client_for_tenant(tenant_id: str) -> foundry.FoundryClient: if tenant_id not in _clients: hostname = get_tenant_hostname(tenant_id) token = get_tenant_token(tenant_id) _clients[tenant_id] = foundry.FoundryClient( auth=foundry.UserTokenAuth(hostname=hostname, token=token), hostname=hostname, ) return _clients[tenant_id]
Resources
Next Steps
Apply patterns in
palantir-core-workflow-a for real pipeline usage.