plano/concepts/llm_providers/client_libraries.html
2026-02-04 20:40:48 +00:00

673 lines
No EOL
80 KiB
HTML
Executable file
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html :class="{ 'dark' : darkMode === true }" data-content_root="../../" lang="en" x-data="{ darkMode: $persist(window.matchMedia('(prefers-color-scheme: dark)').matches), activeSection: ''}">
<head>
<script>
(function () {
// Set initial color scheme
if ((localStorage.getItem("_x_darkMode") === "true") || (window.matchMedia("(prefers-color-scheme: dark)").matches)) {
document.documentElement.classList.add("dark");
}
// Watch for media preference changes
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", (event) => {
localStorage.setItem("_x_darkMode", event.matches);
document.documentElement.classList.toggle("dark", event.matches);
});
})();
</script>
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
<meta charset="utf-8"/>
<meta content="#ffffff" media="(prefers-color-scheme: light)" name="theme-color"/>
<meta content="#030711" media="(prefers-color-scheme: dark)" name="theme-color"/>
<meta content="width=device-width, initial-scale=1" name="viewport"/>
<title>Client Libraries | Plano Docs v0.4.4</title>
<meta content="Client Libraries | Plano Docs v0.4.4" property="og:title"/>
<meta content="Client Libraries | Plano Docs v0.4.4" name="twitter:title"/>
<link href="../../_static/pygments.css?v=73db4dac" rel="stylesheet" type="text/css"/>
<link href="../../_static/theme.css?v=73505e79" rel="stylesheet" type="text/css"/>
<link href="../../_static/sphinx-design.min.css?v=95c83b7e" rel="stylesheet" type="text/css"/>
<link href="../../_static/css/custom.css?v=2929376a" rel="stylesheet" type="text/css"/>
<link href="../../_static/awesome-sphinx-design.css?v=c54898a4" rel="stylesheet" type="text/css"/>
<link href="./docs/concepts/llm_providers/client_libraries.html" rel="canonical"/>
<link href="../../_static/favicon.ico" rel="icon"/>
<link href="../../search.html" rel="search" title="Search"/>
<link href="model_aliases.html" rel="next" title="Model Aliases"/>
<link href="supported_providers.html" rel="prev" title="Supported Providers &amp; Configuration"/>
</head>
<body :class="{ 'overflow-hidden': showSidebar }" class="min-h-screen font-sans antialiased bg-background text-foreground" x-data="{ showSidebar: false, showScrollTop: false }">
<div @click.self="showSidebar = false" class="fixed inset-0 z-50 overflow-hidden bg-background/80 backdrop-blur-sm md:hidden" x-cloak="" x-show="showSidebar"></div><div class="relative flex flex-col min-h-screen" id="page"><a class="absolute top-0 left-0 z-[100] block bg-background p-4 text-xl transition -translate-x-full opacity-0 focus:translate-x-0 focus:opacity-100" href="#content">
Skip to content
</a><header class="sticky top-0 z-40 w-full border-b shadow-xs border-border bg-background/90 backdrop-blur"><div class="container flex items-center h-14">
<div class="hidden mr-4 md:flex">
<a class="flex items-center mr-6" href="../../index.html">
<img alt="Logo" class="mr-2 dark:invert" height="24" src="../../_static/favicon.ico" width="24"/><span class="hidden font-bold sm:inline-block text-clip whitespace-nowrap">Plano Docs v0.4.4</span>
</a></div><button @click="showSidebar = true" class="inline-flex items-center justify-center h-10 px-0 py-2 mr-2 text-base font-medium transition-colors rounded-md hover:text-accent-foreground hover:bg-transparent md:hidden" type="button">
<svg aria-hidden="true" fill="currentColor" height="24" viewbox="0 96 960 960" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M152.587 825.087q-19.152 0-32.326-13.174t-13.174-32.326q0-19.152 13.174-32.326t32.326-13.174h440q19.152 0 32.326 13.174t13.174 32.326q0 19.152-13.174 32.326t-32.326 13.174h-440Zm0-203.587q-19.152 0-32.326-13.174T107.087 576q0-19.152 13.174-32.326t32.326-13.174h320q19.152 0 32.326 13.174T518.087 576q0 19.152-13.174 32.326T472.587 621.5h-320Zm0-203.587q-19.152 0-32.326-13.174t-13.174-32.326q0-19.152 13.174-32.326t32.326-13.174h440q19.152 0 32.326 13.174t13.174 32.326q0 19.152-13.174 32.326t-32.326 13.174h-440ZM708.913 576l112.174 112.174q12.674 12.674 12.674 31.826t-12.674 31.826Q808.413 764.5 789.261 764.5t-31.826-12.674l-144-144Q600 594.391 600 576t13.435-31.826l144-144q12.674-12.674 31.826-12.674t31.826 12.674q12.674 12.674 12.674 31.826t-12.674 31.826L708.913 576Z"></path>
</svg>
<span class="sr-only">Toggle navigation menu</span>
</button>
<div class="flex items-center justify-between flex-1 gap-2 sm:gap-4 md:justify-end">
<div class="flex-1 w-full md:w-auto md:flex-none"><form @keydown.k.window.meta="$refs.search.focus()" action="../../search.html" class="relative flex items-center group" id="searchbox" method="get">
<input aria-label="Search the docs" class="inline-flex items-center font-medium transition-colors bg-transparent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ring-offset-background border border-input hover:bg-accent focus:bg-accent hover:text-accent-foreground focus:text-accent-foreground hover:placeholder-accent-foreground py-2 px-4 relative h-9 w-full justify-start rounded-[0.5rem] text-sm text-muted-foreground sm:pr-12 md:w-40 lg:w-64" id="search-input" name="q" placeholder="Search ..." type="search" x-ref="search"/>
<kbd class="pointer-events-none absolute right-1.5 top-2 hidden h-5 select-none text-muted-foreground items-center gap-1 rounded border border-border bg-muted px-1.5 font-mono text-[10px] font-medium opacity-100 sm:flex group-hover:bg-accent group-hover:text-accent-foreground">
<span class="text-xs"></span>
K
</kbd>
</form>
</div>
<nav class="flex items-center gap-1">
<a href="https://github.com/katanemo/plano" rel="noopener nofollow" title="Visit repository on GitHub">
<div class="inline-flex items-center justify-center px-0 text-sm font-medium transition-colors rounded-md hover:bg-accent hover:text-accent-foreground h-9 w-9">
<svg fill="currentColor" height="26px" style="margin-top:-2px;display:inline" viewbox="0 0 45 44" xmlns="http://www.w3.org/2000/svg"><path clip-rule="evenodd" d="M22.477.927C10.485.927.76 10.65.76 22.647c0 9.596 6.223 17.736 14.853 20.608 1.087.2 1.483-.47 1.483-1.047 0-.516-.019-1.881-.03-3.693-6.04 1.312-7.315-2.912-7.315-2.912-.988-2.51-2.412-3.178-2.412-3.178-1.972-1.346.149-1.32.149-1.32 2.18.154 3.327 2.24 3.327 2.24 1.937 3.318 5.084 2.36 6.321 1.803.197-1.403.759-2.36 1.379-2.903-4.823-.548-9.894-2.412-9.894-10.734 0-2.37.847-4.31 2.236-5.828-.224-.55-.969-2.759.214-5.748 0 0 1.822-.584 5.972 2.226 1.732-.482 3.59-.722 5.437-.732 1.845.01 3.703.25 5.437.732 4.147-2.81 5.967-2.226 5.967-2.226 1.185 2.99.44 5.198.217 5.748 1.392 1.517 2.232 3.457 2.232 5.828 0 8.344-5.078 10.18-9.916 10.717.779.67 1.474 1.996 1.474 4.021 0 2.904-.027 5.247-.027 5.96 0 .58.392 1.256 1.493 1.044C37.981 40.375 44.2 32.24 44.2 22.647c0-11.996-9.726-21.72-21.722-21.72" fill="currentColor" fill-rule="evenodd"></path></svg>
</div>
</a>
<button @click="darkMode = !darkMode" class="relative inline-flex items-center justify-center px-0 text-sm font-medium transition-colors rounded-md hover:bg-accent hover:text-accent-foreground h-9 w-9" title="Toggle color scheme" type="button">
<svg class="absolute transition-all scale-100 rotate-0 dark:-rotate-90 dark:scale-0" fill="currentColor" height="16" viewbox="0 96 960 960" width="16" xmlns="http://www.w3.org/2000/svg">
<path d="M480 685q45.456 0 77.228-31.772Q589 621.456 589 576q0-45.456-31.772-77.228Q525.456 467 480 467q-45.456 0-77.228 31.772Q371 530.544 371 576q0 45.456 31.772 77.228Q434.544 685 480 685Zm0 91q-83 0-141.5-58.5T280 576q0-83 58.5-141.5T480 376q83 0 141.5 58.5T680 576q0 83-58.5 141.5T480 776ZM80 621.5q-19.152 0-32.326-13.174T34.5 576q0-19.152 13.174-32.326T80 530.5h80q19.152 0 32.326 13.174T205.5 576q0 19.152-13.174 32.326T160 621.5H80Zm720 0q-19.152 0-32.326-13.174T754.5 576q0-19.152 13.174-32.326T800 530.5h80q19.152 0 32.326 13.174T925.5 576q0 19.152-13.174 32.326T880 621.5h-80Zm-320-320q-19.152 0-32.326-13.174T434.5 256v-80q0-19.152 13.174-32.326T480 130.5q19.152 0 32.326 13.174T525.5 176v80q0 19.152-13.174 32.326T480 301.5Zm0 720q-19.152 0-32.326-13.17Q434.5 995.152 434.5 976v-80q0-19.152 13.174-32.326T480 850.5q19.152 0 32.326 13.174T525.5 896v80q0 19.152-13.174 32.33-13.174 13.17-32.326 13.17ZM222.174 382.065l-43-42Q165.5 327.391 166 308.239t13.174-33.065q13.435-13.674 32.587-13.674t32.065 13.674l42.239 43q12.674 13.435 12.555 31.706-.12 18.272-12.555 31.946-12.674 13.674-31.445 13.413-18.772-.261-32.446-13.174Zm494 494.761-42.239-43q-12.674-13.435-12.674-32.087t12.674-31.565Q686.609 756.5 705.38 757q18.772.5 32.446 13.174l43 41.761Q794.5 824.609 794 843.761t-13.174 33.065Q767.391 890.5 748.239 890.5t-32.065-13.674Zm-42-494.761Q660.5 369.391 661 350.62q.5-18.772 13.174-32.446l41.761-43Q728.609 261.5 747.761 262t33.065 13.174q13.674 13.435 13.674 32.587t-13.674 32.065l-43 42.239q-13.435 12.674-31.706 12.555-18.272-.12-31.946-12.555Zm-495 494.761Q165.5 863.391 165.5 844.239t13.674-32.065l43-42.239q13.435-12.674 32.087-12.674t31.565 12.674Q299.5 782.609 299 801.38q-.5 18.772-13.174 32.446l-41.761 43Q231.391 890.5 212.239 890t-33.065-13.174ZM480 576Z"></path>
</svg>
<svg class="absolute transition-all scale-0 rotate-90 dark:rotate-0 dark:scale-100" fill="currentColor" height="16" viewbox="0 96 960 960" width="16" xmlns="http://www.w3.org/2000/svg">
<path d="M480 936q-151 0-255.5-104.5T120 576q0-138 90-239.5T440 218q25-3 39 18t-1 44q-17 26-25.5 55t-8.5 61q0 90 63 153t153 63q31 0 61.5-9t54.5-25q21-14 43-1.5t19 39.5q-14 138-117.5 229T480 936Zm0-80q88 0 158-48.5T740 681q-20 5-40 8t-40 3q-123 0-209.5-86.5T364 396q0-20 3-40t8-40q-78 32-126.5 102T200 576q0 116 82 198t198 82Zm-10-270Z"></path>
</svg>
</button>
</nav>
</div>
</div>
</header>
<div class="flex-1"><div class="container md:grid md:grid-cols-[220px_minmax(0,1fr)] md:gap-6 lg:grid-cols-[240px_minmax(0,1fr)] lg:gap-10"><aside :aria-hidden="!showSidebar" :class="{ 'translate-x-0': showSidebar }" class="fixed inset-y-0 left-0 md:top-14 z-50 md:z-30 bg-background md:bg-transparent transition-all duration-100 -translate-x-full md:translate-x-0 ml-0 p-6 md:p-0 md:-ml-2 md:h-[calc(100vh-3.5rem)] w-5/6 md:w-full overflow-y-auto border-r border-border md:sticky" id="left-sidebar">
<a class="justify-start text-sm md:!hidden bg-background" href="../../index.html">
<img alt="Logo" class="mr-2 dark:invert" height="16" src="../../_static/favicon.ico" width="16"/><span class="font-bold text-clip whitespace-nowrap">Plano Docs v0.4.4</span>
</a>
<div class="relative overflow-hidden md:overflow-auto my-4 md:my-0">
<div class="overflow-y-auto h-full w-full relative pr-6">
<script async="" src="https://www.googletagmanager.com/gtag/js?id=G-EH2VW19FXE"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-EH2VW19FXE');
</script>
<nav class="table w-full min-w-full my-6 lg:my-8">
<p class="caption" role="heading"><span class="caption-text">Get Started</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../get_started/overview.html">Overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../get_started/intro_to_plano.html">Intro to Plano</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../get_started/quickstart.html">Quickstart</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../get_started/quickstart.html#next-steps">Next Steps</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Concepts</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../listeners.html">Listeners</a></li>
<li class="toctree-l1"><a class="reference internal" href="../agents.html">Agents</a></li>
<li class="toctree-l1"><a class="reference internal" href="../filter_chain.html">Filter Chains</a></li>
<li class="toctree-l1 current" x-data="{ expanded: $el.classList.contains('current') ? true : false }"><a :class="{ 'expanded' : expanded }" @click="expanded = !expanded" class="reference internal expandable" href="llm_providers.html">Model (LLM) Providers<button @click.prevent.stop="expanded = !expanded" type="button" x-cloak=""><span class="sr-only"></span><svg fill="currentColor" height="18px" stroke="none" viewbox="0 0 24 24" width="18px" xmlns="http://www.w3.org/2000/svg"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"></path></svg></button></a><ul class="current" x-show="expanded">
<li class="toctree-l2"><a class="reference internal" href="supported_providers.html">Supported Providers &amp; Configuration</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Client Libraries</a></li>
<li class="toctree-l2"><a class="reference internal" href="model_aliases.html">Model Aliases</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../prompt_target.html">Prompt Target</a></li>
<li class="toctree-l1"><a class="reference internal" href="../signals.html">Signals™</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Guides</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../guides/orchestration.html">Orchestration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../guides/llm_router.html">LLM Routing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../guides/function_calling.html">Function Calling</a></li>
<li class="toctree-l1" x-data="{ expanded: $el.classList.contains('current') ? true : false }"><a :class="{ 'expanded' : expanded }" @click="expanded = !expanded" class="reference internal expandable" href="../../guides/observability/observability.html">Observability<button @click.prevent.stop="expanded = !expanded" type="button" x-cloak=""><span class="sr-only"></span><svg fill="currentColor" height="18px" stroke="none" viewbox="0 0 24 24" width="18px" xmlns="http://www.w3.org/2000/svg"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"></path></svg></button></a><ul x-cloak="" x-show="expanded">
<li class="toctree-l2"><a class="reference internal" href="../../guides/observability/tracing.html">Tracing</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../guides/observability/monitoring.html">Monitoring</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../guides/observability/access_logging.html">Access Logging</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../guides/prompt_guard.html">Guardrails</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../guides/state.html">Conversational State</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Resources</span></p>
<ul>
<li class="toctree-l1" x-data="{ expanded: $el.classList.contains('current') ? true : false }"><a :class="{ 'expanded' : expanded }" @click="expanded = !expanded" class="reference internal expandable" href="../../resources/tech_overview/tech_overview.html">Tech Overview<button @click.prevent.stop="expanded = !expanded" type="button" x-cloak=""><span class="sr-only"></span><svg fill="currentColor" height="18px" stroke="none" viewbox="0 0 24 24" width="18px" xmlns="http://www.w3.org/2000/svg"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"></path></svg></button></a><ul x-cloak="" x-show="expanded">
<li class="toctree-l2"><a class="reference internal" href="../../resources/tech_overview/request_lifecycle.html">Request Lifecycle</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../resources/tech_overview/model_serving.html">Bright Staff</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../resources/tech_overview/threading_model.html">Threading Model</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../resources/deployment.html">Deployment</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../resources/configuration_reference.html">Configuration Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../resources/llms_txt.html">llms.txt</a></li>
</ul>
</nav>
</div>
</div>
<button @click="showSidebar = false" class="absolute md:hidden right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100" type="button">
<svg class="h-4 w-4" fill="currentColor" height="24" stroke="none" viewbox="0 96 960 960" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M480 632 284 828q-11 11-28 11t-28-11q-11-11-11-28t11-28l196-196-196-196q-11-11-11-28t11-28q11-11 28-11t28 11l196 196 196-196q11-11 28-11t28 11q11 11 11 28t-11 28L536 576l196 196q11 11 11 28t-11 28q-11 11-28 11t-28-11L480 632Z"></path>
</svg>
</button>
</aside>
<main class="relative py-6 lg:gap-10 lg:py-8 xl:grid xl:grid-cols-[1fr_300px]">
<div class="w-full min-w-0 mx-auto">
<nav aria-label="breadcrumbs" class="flex items-center mb-4 space-x-1 text-sm text-muted-foreground">
<a class="overflow-hidden text-ellipsis whitespace-nowrap hover:text-foreground" href="../../index.html">
<span class="hidden md:inline">Plano Docs v0.4.4</span>
<svg aria-label="Home" class="md:hidden" fill="currentColor" height="18" stroke="none" viewbox="0 96 960 960" width="18" xmlns="http://www.w3.org/2000/svg">
<path d="M240 856h120V616h240v240h120V496L480 316 240 496v360Zm-80 80V456l320-240 320 240v480H520V696h-80v240H160Zm320-350Z"></path>
</svg>
</a>
<div class="mr-1">/</div><a class="hover:text-foreground overflow-hidden text-ellipsis whitespace-nowrap" href="llm_providers.html">Model (LLM) Providers</a>
<div class="mr-1">/</div><span aria-current="page" class="font-medium text-foreground overflow-hidden text-ellipsis whitespace-nowrap">Client Libraries</span>
</nav>
<div id="content" role="main">
<section id="client-libraries">
<span id="id1"></span><h1>Client Libraries<a @click.prevent="window.navigator.clipboard.writeText($el.href); $el.setAttribute('data-tooltip', 'Copied!'); setTimeout(() =&gt; $el.setAttribute('data-tooltip', 'Copy link to this element'), 2000)" aria-label="Copy link to this element" class="headerlink" data-tooltip="Copy link to this element" href="#client-libraries"><svg height="1em" viewbox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"></path></svg></a></h1>
<p>Plano provides a unified interface that works seamlessly with multiple client libraries and tools. You can use your preferred client library without changing your existing code - just point it to Planos gateway endpoints.</p>
<section id="supported-clients">
<h2>Supported Clients<a @click.prevent="window.navigator.clipboard.writeText($el.href); $el.setAttribute('data-tooltip', 'Copied!'); setTimeout(() =&gt; $el.setAttribute('data-tooltip', 'Copy link to this element'), 2000)" aria-label="Copy link to this element" class="headerlink" data-tooltip="Copy link to this element" href="#supported-clients" x-intersect.margin.0%.0%.-70%.0%="activeSection = '#supported-clients'"><svg height="1em" viewbox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"></path></svg></a></h2>
<ul class="simple">
<li><p><strong>OpenAI SDK</strong> - Full compatibility with OpenAIs official client</p></li>
<li><p><strong>Anthropic SDK</strong> - Native support for Anthropics client library</p></li>
<li><p><strong>cURL</strong> - Direct HTTP requests for any programming language</p></li>
<li><p><strong>Custom HTTP Clients</strong> - Any HTTP client that supports REST APIs</p></li>
</ul>
</section>
<section id="gateway-endpoints">
<h2>Gateway Endpoints<a @click.prevent="window.navigator.clipboard.writeText($el.href); $el.setAttribute('data-tooltip', 'Copied!'); setTimeout(() =&gt; $el.setAttribute('data-tooltip', 'Copy link to this element'), 2000)" aria-label="Copy link to this element" class="headerlink" data-tooltip="Copy link to this element" href="#gateway-endpoints" x-intersect.margin.0%.0%.-70%.0%="activeSection = '#gateway-endpoints'"><svg height="1em" viewbox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"></path></svg></a></h2>
<p>Plano exposes three main endpoints:</p>
<table class="docutils align-default">
<colgroup>
<col style="width: 40.0%"/>
<col style="width: 60.0%"/>
</colgroup>
<thead>
<tr class="row-odd"><th class="head"><p>Endpoint</p></th>
<th class="head"><p>Purpose</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">http://127.0.0.1:12000/v1/chat/completions</span></code></p></td>
<td><p>OpenAI-compatible chat completions (LLM Gateway)</p></td>
</tr>
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">http://127.0.0.1:12000/v1/responses</span></code></p></td>
<td><p>OpenAI Responses API with <a class="reference internal" href="../../guides/state.html#managing-conversational-state"><span class="std std-ref">conversational state management</span></a> (LLM Gateway)</p></td>
</tr>
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">http://127.0.0.1:12000/v1/messages</span></code></p></td>
<td><p>Anthropic-compatible messages (LLM Gateway)</p></td>
</tr>
</tbody>
</table>
</section>
<section id="openai-python-sdk">
<h2>OpenAI (Python) SDK<a @click.prevent="window.navigator.clipboard.writeText($el.href); $el.setAttribute('data-tooltip', 'Copied!'); setTimeout(() =&gt; $el.setAttribute('data-tooltip', 'Copy link to this element'), 2000)" aria-label="Copy link to this element" class="headerlink" data-tooltip="Copy link to this element" href="#openai-python-sdk" x-intersect.margin.0%.0%.-70%.0%="activeSection = '#openai-python-sdk'"><svg height="1em" viewbox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"></path></svg></a></h2>
<p>The OpenAI SDK works with any provider through Planos OpenAI-compatible endpoint.</p>
<p><strong>Installation:</strong></p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><code><span id="line-1">pip<span class="w"> </span>install<span class="w"> </span>openai
</span></code></pre></div>
</div>
<p><strong>Basic Usage:</strong></p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><code><span id="line-1"><span class="kn">from</span><span class="w"> </span><span class="nn">openai</span><span class="w"> </span><span class="kn">import</span> <span class="n">OpenAI</span>
</span><span id="line-2">
</span><span id="line-3"><span class="c1"># Point to Plano's LLM Gateway</span>
</span><span id="line-4"><span class="n">client</span> <span class="o">=</span> <span class="n">OpenAI</span><span class="p">(</span>
</span><span id="line-5"> <span class="n">api_key</span><span class="o">=</span><span class="s2">"test-key"</span><span class="p">,</span> <span class="c1"># Can be any value for local testing</span>
</span><span id="line-6"> <span class="n">base_url</span><span class="o">=</span><span class="s2">"http://127.0.0.1:12000/v1"</span>
</span><span id="line-7"><span class="p">)</span>
</span><span id="line-8">
</span><span id="line-9"><span class="c1"># Use any model configured in your arch_config.yaml</span>
</span><span id="line-10"><span class="n">completion</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">chat</span><span class="o">.</span><span class="n">completions</span><span class="o">.</span><span class="n">create</span><span class="p">(</span>
</span><span id="line-11"> <span class="n">model</span><span class="o">=</span><span class="s2">"gpt-4o-mini"</span><span class="p">,</span> <span class="c1"># Or use :ref:`model aliases &lt;model_aliases&gt;` like "fast-model"</span>
</span><span id="line-12"> <span class="n">max_tokens</span><span class="o">=</span><span class="mi">50</span><span class="p">,</span>
</span><span id="line-13"> <span class="n">messages</span><span class="o">=</span><span class="p">[</span>
</span><span id="line-14"> <span class="p">{</span>
</span><span id="line-15"> <span class="s2">"role"</span><span class="p">:</span> <span class="s2">"user"</span><span class="p">,</span>
</span><span id="line-16"> <span class="s2">"content"</span><span class="p">:</span> <span class="s2">"Hello, how are you?"</span>
</span><span id="line-17"> <span class="p">}</span>
</span><span id="line-18"> <span class="p">]</span>
</span><span id="line-19"><span class="p">)</span>
</span><span id="line-20">
</span><span id="line-21"><span class="nb">print</span><span class="p">(</span><span class="n">completion</span><span class="o">.</span><span class="n">choices</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">message</span><span class="o">.</span><span class="n">content</span><span class="p">)</span>
</span></code></pre></div>
</div>
<p><strong>Streaming Responses:</strong></p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><code><span id="line-1"><span class="kn">from</span><span class="w"> </span><span class="nn">openai</span><span class="w"> </span><span class="kn">import</span> <span class="n">OpenAI</span>
</span><span id="line-2">
</span><span id="line-3"><span class="n">client</span> <span class="o">=</span> <span class="n">OpenAI</span><span class="p">(</span>
</span><span id="line-4"> <span class="n">api_key</span><span class="o">=</span><span class="s2">"test-key"</span><span class="p">,</span>
</span><span id="line-5"> <span class="n">base_url</span><span class="o">=</span><span class="s2">"http://127.0.0.1:12000/v1"</span>
</span><span id="line-6"><span class="p">)</span>
</span><span id="line-7">
</span><span id="line-8"><span class="n">stream</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">chat</span><span class="o">.</span><span class="n">completions</span><span class="o">.</span><span class="n">create</span><span class="p">(</span>
</span><span id="line-9"> <span class="n">model</span><span class="o">=</span><span class="s2">"gpt-4o-mini"</span><span class="p">,</span>
</span><span id="line-10"> <span class="n">max_tokens</span><span class="o">=</span><span class="mi">50</span><span class="p">,</span>
</span><span id="line-11"> <span class="n">messages</span><span class="o">=</span><span class="p">[</span>
</span><span id="line-12"> <span class="p">{</span>
</span><span id="line-13"> <span class="s2">"role"</span><span class="p">:</span> <span class="s2">"user"</span><span class="p">,</span>
</span><span id="line-14"> <span class="s2">"content"</span><span class="p">:</span> <span class="s2">"Tell me a short story"</span>
</span><span id="line-15"> <span class="p">}</span>
</span><span id="line-16"> <span class="p">],</span>
</span><span id="line-17"> <span class="n">stream</span><span class="o">=</span><span class="kc">True</span>
</span><span id="line-18"><span class="p">)</span>
</span><span id="line-19">
</span><span id="line-20"><span class="c1"># Collect streaming chunks</span>
</span><span id="line-21"><span class="k">for</span> <span class="n">chunk</span> <span class="ow">in</span> <span class="n">stream</span><span class="p">:</span>
</span><span id="line-22"> <span class="k">if</span> <span class="n">chunk</span><span class="o">.</span><span class="n">choices</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">delta</span><span class="o">.</span><span class="n">content</span><span class="p">:</span>
</span><span id="line-23"> <span class="nb">print</span><span class="p">(</span><span class="n">chunk</span><span class="o">.</span><span class="n">choices</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">delta</span><span class="o">.</span><span class="n">content</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s2">""</span><span class="p">)</span>
</span></code></pre></div>
</div>
<p><strong>Using with Non-OpenAI Models:</strong></p>
<p>The OpenAI SDK can be used with any provider configured in Plano:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><code><span id="line-1"><span class="c1"># Using Claude model through OpenAI SDK</span>
</span><span id="line-2"><span class="n">completion</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">chat</span><span class="o">.</span><span class="n">completions</span><span class="o">.</span><span class="n">create</span><span class="p">(</span>
</span><span id="line-3"> <span class="n">model</span><span class="o">=</span><span class="s2">"claude-3-5-sonnet-20241022"</span><span class="p">,</span>
</span><span id="line-4"> <span class="n">max_tokens</span><span class="o">=</span><span class="mi">50</span><span class="p">,</span>
</span><span id="line-5"> <span class="n">messages</span><span class="o">=</span><span class="p">[</span>
</span><span id="line-6"> <span class="p">{</span>
</span><span id="line-7"> <span class="s2">"role"</span><span class="p">:</span> <span class="s2">"user"</span><span class="p">,</span>
</span><span id="line-8"> <span class="s2">"content"</span><span class="p">:</span> <span class="s2">"Explain quantum computing briefly"</span>
</span><span id="line-9"> <span class="p">}</span>
</span><span id="line-10"> <span class="p">]</span>
</span><span id="line-11"><span class="p">)</span>
</span><span id="line-12">
</span><span id="line-13"><span class="c1"># Using Ollama model through OpenAI SDK</span>
</span><span id="line-14"><span class="n">completion</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">chat</span><span class="o">.</span><span class="n">completions</span><span class="o">.</span><span class="n">create</span><span class="p">(</span>
</span><span id="line-15"> <span class="n">model</span><span class="o">=</span><span class="s2">"llama3.1"</span><span class="p">,</span>
</span><span id="line-16"> <span class="n">max_tokens</span><span class="o">=</span><span class="mi">50</span><span class="p">,</span>
</span><span id="line-17"> <span class="n">messages</span><span class="o">=</span><span class="p">[</span>
</span><span id="line-18"> <span class="p">{</span>
</span><span id="line-19"> <span class="s2">"role"</span><span class="p">:</span> <span class="s2">"user"</span><span class="p">,</span>
</span><span id="line-20"> <span class="s2">"content"</span><span class="p">:</span> <span class="s2">"What's the capital of France?"</span>
</span><span id="line-21"> <span class="p">}</span>
</span><span id="line-22"> <span class="p">]</span>
</span><span id="line-23"><span class="p">)</span>
</span></code></pre></div>
</div>
</section>
<section id="openai-responses-api-conversational-state">
<h2>OpenAI Responses API (Conversational State)<a @click.prevent="window.navigator.clipboard.writeText($el.href); $el.setAttribute('data-tooltip', 'Copied!'); setTimeout(() =&gt; $el.setAttribute('data-tooltip', 'Copy link to this element'), 2000)" aria-label="Copy link to this element" class="headerlink" data-tooltip="Copy link to this element" href="#openai-responses-api-conversational-state" x-intersect.margin.0%.0%.-70%.0%="activeSection = '#openai-responses-api-conversational-state'"><svg height="1em" viewbox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"></path></svg></a></h2>
<p>The OpenAI Responses API (<code class="docutils literal notranslate"><span class="pre">v1/responses</span></code>) enables multi-turn conversations with automatic state management. Plano handles conversation history for you, so you dont need to manually include previous messages in each request.</p>
<p>See <a class="reference internal" href="../../guides/state.html#managing-conversational-state"><span class="std std-ref">Conversational State</span></a> for detailed configuration and storage backend options.</p>
<p><strong>Installation:</strong></p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><code><span id="line-1">pip<span class="w"> </span>install<span class="w"> </span>openai
</span></code></pre></div>
</div>
<p><strong>Basic Multi-Turn Conversation:</strong></p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><code><span id="line-1"><span class="kn">from</span><span class="w"> </span><span class="nn">openai</span><span class="w"> </span><span class="kn">import</span> <span class="n">OpenAI</span>
</span><span id="line-2">
</span><span id="line-3"><span class="c1"># Point to Plano's LLM Gateway</span>
</span><span id="line-4"><span class="n">client</span> <span class="o">=</span> <span class="n">OpenAI</span><span class="p">(</span>
</span><span id="line-5"> <span class="n">api_key</span><span class="o">=</span><span class="s2">"test-key"</span><span class="p">,</span>
</span><span id="line-6"> <span class="n">base_url</span><span class="o">=</span><span class="s2">"http://127.0.0.1:12000/v1"</span>
</span><span id="line-7"><span class="p">)</span>
</span><span id="line-8">
</span><span id="line-9"><span class="c1"># First turn - creates a new conversation</span>
</span><span id="line-10"><span class="n">response</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">chat</span><span class="o">.</span><span class="n">completions</span><span class="o">.</span><span class="n">create</span><span class="p">(</span>
</span><span id="line-11"> <span class="n">model</span><span class="o">=</span><span class="s2">"gpt-4o-mini"</span><span class="p">,</span>
</span><span id="line-12"> <span class="n">messages</span><span class="o">=</span><span class="p">[</span>
</span><span id="line-13"> <span class="p">{</span><span class="s2">"role"</span><span class="p">:</span> <span class="s2">"user"</span><span class="p">,</span> <span class="s2">"content"</span><span class="p">:</span> <span class="s2">"My name is Alice"</span><span class="p">}</span>
</span><span id="line-14"> <span class="p">]</span>
</span><span id="line-15"><span class="p">)</span>
</span><span id="line-16">
</span><span id="line-17"><span class="c1"># Extract response_id for conversation continuity</span>
</span><span id="line-18"><span class="n">response_id</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">id</span>
</span><span id="line-19"><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Assistant: </span><span class="si">{</span><span class="n">response</span><span class="o">.</span><span class="n">choices</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">message</span><span class="o">.</span><span class="n">content</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span><span id="line-20">
</span><span id="line-21"><span class="c1"># Second turn - continues the conversation</span>
</span><span id="line-22"><span class="c1"># Plano automatically retrieves and merges previous context</span>
</span><span id="line-23"><span class="n">response</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">chat</span><span class="o">.</span><span class="n">completions</span><span class="o">.</span><span class="n">create</span><span class="p">(</span>
</span><span id="line-24"> <span class="n">model</span><span class="o">=</span><span class="s2">"gpt-4o-mini"</span><span class="p">,</span>
</span><span id="line-25"> <span class="n">messages</span><span class="o">=</span><span class="p">[</span>
</span><span id="line-26"> <span class="p">{</span><span class="s2">"role"</span><span class="p">:</span> <span class="s2">"user"</span><span class="p">,</span> <span class="s2">"content"</span><span class="p">:</span> <span class="s2">"What's my name?"</span><span class="p">}</span>
</span><span id="line-27"> <span class="p">],</span>
</span><span id="line-28"> <span class="n">metadata</span><span class="o">=</span><span class="p">{</span><span class="s2">"response_id"</span><span class="p">:</span> <span class="n">response_id</span><span class="p">}</span> <span class="c1"># Reference previous conversation</span>
</span><span id="line-29"><span class="p">)</span>
</span><span id="line-30">
</span><span id="line-31"><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Assistant: </span><span class="si">{</span><span class="n">response</span><span class="o">.</span><span class="n">choices</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">message</span><span class="o">.</span><span class="n">content</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span><span id="line-32"><span class="c1"># Output: "Your name is Alice"</span>
</span></code></pre></div>
</div>
<p><strong>Using with Any Provider:</strong></p>
<p>The Responses API works with any LLM provider configured in Plano:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><code><span id="line-1"><span class="c1"># Multi-turn conversation with Claude</span>
</span><span id="line-2"><span class="n">response</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">chat</span><span class="o">.</span><span class="n">completions</span><span class="o">.</span><span class="n">create</span><span class="p">(</span>
</span><span id="line-3"> <span class="n">model</span><span class="o">=</span><span class="s2">"claude-3-5-sonnet-20241022"</span><span class="p">,</span>
</span><span id="line-4"> <span class="n">messages</span><span class="o">=</span><span class="p">[</span>
</span><span id="line-5"> <span class="p">{</span><span class="s2">"role"</span><span class="p">:</span> <span class="s2">"user"</span><span class="p">,</span> <span class="s2">"content"</span><span class="p">:</span> <span class="s2">"Let's discuss quantum physics"</span><span class="p">}</span>
</span><span id="line-6"> <span class="p">]</span>
</span><span id="line-7"><span class="p">)</span>
</span><span id="line-8">
</span><span id="line-9"><span class="n">response_id</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">id</span>
</span><span id="line-10">
</span><span id="line-11"><span class="c1"># Continue conversation - Plano manages state regardless of provider</span>
</span><span id="line-12"><span class="n">response</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">chat</span><span class="o">.</span><span class="n">completions</span><span class="o">.</span><span class="n">create</span><span class="p">(</span>
</span><span id="line-13"> <span class="n">model</span><span class="o">=</span><span class="s2">"claude-3-5-sonnet-20241022"</span><span class="p">,</span>
</span><span id="line-14"> <span class="n">messages</span><span class="o">=</span><span class="p">[</span>
</span><span id="line-15"> <span class="p">{</span><span class="s2">"role"</span><span class="p">:</span> <span class="s2">"user"</span><span class="p">,</span> <span class="s2">"content"</span><span class="p">:</span> <span class="s2">"Tell me more about entanglement"</span><span class="p">}</span>
</span><span id="line-16"> <span class="p">],</span>
</span><span id="line-17"> <span class="n">metadata</span><span class="o">=</span><span class="p">{</span><span class="s2">"response_id"</span><span class="p">:</span> <span class="n">response_id</span><span class="p">}</span>
</span><span id="line-18"><span class="p">)</span>
</span></code></pre></div>
</div>
<p><strong>Key Benefits:</strong></p>
<ul class="simple">
<li><p><strong>Reduced payload size</strong>: No need to send full conversation history in each request</p></li>
<li><p><strong>Provider flexibility</strong>: Use any configured LLM provider with state management</p></li>
<li><p><strong>Automatic context merging</strong>: Plano handles conversation continuity behind the scenes</p></li>
<li><p><strong>Production-ready storage</strong>: Configure <a class="reference internal" href="../../guides/state.html#managing-conversational-state"><span class="std std-ref">PostgreSQL or memory storage</span></a> based on your needs</p></li>
</ul>
</section>
<section id="anthropic-python-sdk">
<h2>Anthropic (Python) SDK<a @click.prevent="window.navigator.clipboard.writeText($el.href); $el.setAttribute('data-tooltip', 'Copied!'); setTimeout(() =&gt; $el.setAttribute('data-tooltip', 'Copy link to this element'), 2000)" aria-label="Copy link to this element" class="headerlink" data-tooltip="Copy link to this element" href="#anthropic-python-sdk" x-intersect.margin.0%.0%.-70%.0%="activeSection = '#anthropic-python-sdk'"><svg height="1em" viewbox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"></path></svg></a></h2>
<p>The Anthropic SDK works with any provider through Planos Anthropic-compatible endpoint.</p>
<p><strong>Installation:</strong></p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><code><span id="line-1">pip<span class="w"> </span>install<span class="w"> </span>anthropic
</span></code></pre></div>
</div>
<p><strong>Basic Usage:</strong></p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><code><span id="line-1"><span class="kn">import</span><span class="w"> </span><span class="nn">anthropic</span>
</span><span id="line-2">
</span><span id="line-3"><span class="c1"># Point to Plano's LLM Gateway</span>
</span><span id="line-4"><span class="n">client</span> <span class="o">=</span> <span class="n">anthropic</span><span class="o">.</span><span class="n">Anthropic</span><span class="p">(</span>
</span><span id="line-5"> <span class="n">api_key</span><span class="o">=</span><span class="s2">"test-key"</span><span class="p">,</span> <span class="c1"># Can be any value for local testing</span>
</span><span id="line-6"> <span class="n">base_url</span><span class="o">=</span><span class="s2">"http://127.0.0.1:12000"</span>
</span><span id="line-7"><span class="p">)</span>
</span><span id="line-8">
</span><span id="line-9"><span class="c1"># Use any model configured in your arch_config.yaml</span>
</span><span id="line-10"><span class="n">message</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">messages</span><span class="o">.</span><span class="n">create</span><span class="p">(</span>
</span><span id="line-11"> <span class="n">model</span><span class="o">=</span><span class="s2">"claude-3-5-sonnet-20241022"</span><span class="p">,</span>
</span><span id="line-12"> <span class="n">max_tokens</span><span class="o">=</span><span class="mi">50</span><span class="p">,</span>
</span><span id="line-13"> <span class="n">messages</span><span class="o">=</span><span class="p">[</span>
</span><span id="line-14"> <span class="p">{</span>
</span><span id="line-15"> <span class="s2">"role"</span><span class="p">:</span> <span class="s2">"user"</span><span class="p">,</span>
</span><span id="line-16"> <span class="s2">"content"</span><span class="p">:</span> <span class="s2">"Hello, please respond briefly!"</span>
</span><span id="line-17"> <span class="p">}</span>
</span><span id="line-18"> <span class="p">]</span>
</span><span id="line-19"><span class="p">)</span>
</span><span id="line-20">
</span><span id="line-21"><span class="nb">print</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">content</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">text</span><span class="p">)</span>
</span></code></pre></div>
</div>
<p><strong>Streaming Responses:</strong></p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><code><span id="line-1"><span class="kn">import</span><span class="w"> </span><span class="nn">anthropic</span>
</span><span id="line-2">
</span><span id="line-3"><span class="n">client</span> <span class="o">=</span> <span class="n">anthropic</span><span class="o">.</span><span class="n">Anthropic</span><span class="p">(</span>
</span><span id="line-4"> <span class="n">api_key</span><span class="o">=</span><span class="s2">"test-key"</span><span class="p">,</span>
</span><span id="line-5"> <span class="n">base_url</span><span class="o">=</span><span class="s2">"http://127.0.0.1:12000"</span>
</span><span id="line-6"><span class="p">)</span>
</span><span id="line-7">
</span><span id="line-8"><span class="k">with</span> <span class="n">client</span><span class="o">.</span><span class="n">messages</span><span class="o">.</span><span class="n">stream</span><span class="p">(</span>
</span><span id="line-9"> <span class="n">model</span><span class="o">=</span><span class="s2">"claude-3-5-sonnet-20241022"</span><span class="p">,</span>
</span><span id="line-10"> <span class="n">max_tokens</span><span class="o">=</span><span class="mi">50</span><span class="p">,</span>
</span><span id="line-11"> <span class="n">messages</span><span class="o">=</span><span class="p">[</span>
</span><span id="line-12"> <span class="p">{</span>
</span><span id="line-13"> <span class="s2">"role"</span><span class="p">:</span> <span class="s2">"user"</span><span class="p">,</span>
</span><span id="line-14"> <span class="s2">"content"</span><span class="p">:</span> <span class="s2">"Tell me about artificial intelligence"</span>
</span><span id="line-15"> <span class="p">}</span>
</span><span id="line-16"> <span class="p">]</span>
</span><span id="line-17"><span class="p">)</span> <span class="k">as</span> <span class="n">stream</span><span class="p">:</span>
</span><span id="line-18"> <span class="c1"># Collect text deltas</span>
</span><span id="line-19"> <span class="k">for</span> <span class="n">text</span> <span class="ow">in</span> <span class="n">stream</span><span class="o">.</span><span class="n">text_stream</span><span class="p">:</span>
</span><span id="line-20"> <span class="nb">print</span><span class="p">(</span><span class="n">text</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s2">""</span><span class="p">)</span>
</span><span id="line-21">
</span><span id="line-22"> <span class="c1"># Get final assembled message</span>
</span><span id="line-23"> <span class="n">final_message</span> <span class="o">=</span> <span class="n">stream</span><span class="o">.</span><span class="n">get_final_message</span><span class="p">()</span>
</span><span id="line-24"> <span class="n">final_text</span> <span class="o">=</span> <span class="s2">""</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">block</span><span class="o">.</span><span class="n">text</span> <span class="k">for</span> <span class="n">block</span> <span class="ow">in</span> <span class="n">final_message</span><span class="o">.</span><span class="n">content</span> <span class="k">if</span> <span class="n">block</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="s2">"text"</span><span class="p">)</span>
</span></code></pre></div>
</div>
<p><strong>Using with Non-Anthropic Models:</strong></p>
<p>The Anthropic SDK can be used with any provider configured in Plano:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><code><span id="line-1"><span class="c1"># Using OpenAI model through Anthropic SDK</span>
</span><span id="line-2"><span class="n">message</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">messages</span><span class="o">.</span><span class="n">create</span><span class="p">(</span>
</span><span id="line-3"> <span class="n">model</span><span class="o">=</span><span class="s2">"gpt-4o-mini"</span><span class="p">,</span>
</span><span id="line-4"> <span class="n">max_tokens</span><span class="o">=</span><span class="mi">50</span><span class="p">,</span>
</span><span id="line-5"> <span class="n">messages</span><span class="o">=</span><span class="p">[</span>
</span><span id="line-6"> <span class="p">{</span>
</span><span id="line-7"> <span class="s2">"role"</span><span class="p">:</span> <span class="s2">"user"</span><span class="p">,</span>
</span><span id="line-8"> <span class="s2">"content"</span><span class="p">:</span> <span class="s2">"Explain machine learning in simple terms"</span>
</span><span id="line-9"> <span class="p">}</span>
</span><span id="line-10"> <span class="p">]</span>
</span><span id="line-11"><span class="p">)</span>
</span><span id="line-12">
</span><span id="line-13"><span class="c1"># Using Ollama model through Anthropic SDK</span>
</span><span id="line-14"><span class="n">message</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">messages</span><span class="o">.</span><span class="n">create</span><span class="p">(</span>
</span><span id="line-15"> <span class="n">model</span><span class="o">=</span><span class="s2">"llama3.1"</span><span class="p">,</span>
</span><span id="line-16"> <span class="n">max_tokens</span><span class="o">=</span><span class="mi">50</span><span class="p">,</span>
</span><span id="line-17"> <span class="n">messages</span><span class="o">=</span><span class="p">[</span>
</span><span id="line-18"> <span class="p">{</span>
</span><span id="line-19"> <span class="s2">"role"</span><span class="p">:</span> <span class="s2">"user"</span><span class="p">,</span>
</span><span id="line-20"> <span class="s2">"content"</span><span class="p">:</span> <span class="s2">"What is Python programming?"</span>
</span><span id="line-21"> <span class="p">}</span>
</span><span id="line-22"> <span class="p">]</span>
</span><span id="line-23"><span class="p">)</span>
</span></code></pre></div>
</div>
</section>
<section id="curl-examples">
<h2>cURL Examples<a @click.prevent="window.navigator.clipboard.writeText($el.href); $el.setAttribute('data-tooltip', 'Copied!'); setTimeout(() =&gt; $el.setAttribute('data-tooltip', 'Copy link to this element'), 2000)" aria-label="Copy link to this element" class="headerlink" data-tooltip="Copy link to this element" href="#curl-examples" x-intersect.margin.0%.0%.-70%.0%="activeSection = '#curl-examples'"><svg height="1em" viewbox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"></path></svg></a></h2>
<p>For direct HTTP requests or integration with any programming language:</p>
<p><strong>OpenAI-Compatible Endpoint:</strong></p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><code><span id="line-1"><span class="c1"># Basic request</span>
</span><span id="line-2">curl<span class="w"> </span>-X<span class="w"> </span>POST<span class="w"> </span>http://127.0.0.1:12000/v1/chat/completions<span class="w"> </span><span class="se">\</span>
</span><span id="line-3"><span class="w"> </span>-H<span class="w"> </span><span class="s2">"Content-Type: application/json"</span><span class="w"> </span><span class="se">\</span>
</span><span id="line-4"><span class="w"> </span>-H<span class="w"> </span><span class="s2">"Authorization: Bearer test-key"</span><span class="w"> </span><span class="se">\</span>
</span><span id="line-5"><span class="w"> </span>-d<span class="w"> </span><span class="s1">'{</span>
</span><span id="line-6"><span class="s1"> "model": "gpt-4o-mini",</span>
</span><span id="line-7"><span class="s1"> "messages": [</span>
</span><span id="line-8"><span class="s1"> {"role": "user", "content": "Hello!"}</span>
</span><span id="line-9"><span class="s1"> ],</span>
</span><span id="line-10"><span class="s1"> "max_tokens": 50</span>
</span><span id="line-11"><span class="s1"> }'</span>
</span><span id="line-12">
</span><span id="line-13"><span class="c1"># Using :ref:`model aliases &lt;model_aliases&gt;`</span>
</span><span id="line-14">curl<span class="w"> </span>-X<span class="w"> </span>POST<span class="w"> </span>http://127.0.0.1:12000/v1/chat/completions<span class="w"> </span><span class="se">\</span>
</span><span id="line-15"><span class="w"> </span>-H<span class="w"> </span><span class="s2">"Content-Type: application/json"</span><span class="w"> </span><span class="se">\</span>
</span><span id="line-16"><span class="w"> </span>-d<span class="w"> </span><span class="s1">'{</span>
</span><span id="line-17"><span class="s1"> "model": "fast-model",</span>
</span><span id="line-18"><span class="s1"> "messages": [</span>
</span><span id="line-19"><span class="s1"> {"role": "user", "content": "Summarize this text..."}</span>
</span><span id="line-20"><span class="s1"> ],</span>
</span><span id="line-21"><span class="s1"> "max_tokens": 100</span>
</span><span id="line-22"><span class="s1"> }'</span>
</span><span id="line-23">
</span><span id="line-24"><span class="c1"># Streaming request</span>
</span><span id="line-25">curl<span class="w"> </span>-X<span class="w"> </span>POST<span class="w"> </span>http://127.0.0.1:12000/v1/chat/completions<span class="w"> </span><span class="se">\</span>
</span><span id="line-26"><span class="w"> </span>-H<span class="w"> </span><span class="s2">"Content-Type: application/json"</span><span class="w"> </span><span class="se">\</span>
</span><span id="line-27"><span class="w"> </span>-d<span class="w"> </span><span class="s1">'{</span>
</span><span id="line-28"><span class="s1"> "model": "gpt-4o-mini",</span>
</span><span id="line-29"><span class="s1"> "messages": [</span>
</span><span id="line-30"><span class="s1"> {"role": "user", "content": "Tell me a story"}</span>
</span><span id="line-31"><span class="s1"> ],</span>
</span><span id="line-32"><span class="s1"> "stream": true,</span>
</span><span id="line-33"><span class="s1"> "max_tokens": 200</span>
</span><span id="line-34"><span class="s1"> }'</span>
</span></code></pre></div>
</div>
<p><strong>Anthropic-Compatible Endpoint:</strong></p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><code><span id="line-1"><span class="c1"># Basic request</span>
</span><span id="line-2">curl<span class="w"> </span>-X<span class="w"> </span>POST<span class="w"> </span>http://127.0.0.1:12000/v1/messages<span class="w"> </span><span class="se">\</span>
</span><span id="line-3"><span class="w"> </span>-H<span class="w"> </span><span class="s2">"Content-Type: application/json"</span><span class="w"> </span><span class="se">\</span>
</span><span id="line-4"><span class="w"> </span>-H<span class="w"> </span><span class="s2">"x-api-key: test-key"</span><span class="w"> </span><span class="se">\</span>
</span><span id="line-5"><span class="w"> </span>-H<span class="w"> </span><span class="s2">"anthropic-version: 2023-06-01"</span><span class="w"> </span><span class="se">\</span>
</span><span id="line-6"><span class="w"> </span>-d<span class="w"> </span><span class="s1">'{</span>
</span><span id="line-7"><span class="s1"> "model": "claude-3-5-sonnet-20241022",</span>
</span><span id="line-8"><span class="s1"> "max_tokens": 50,</span>
</span><span id="line-9"><span class="s1"> "messages": [</span>
</span><span id="line-10"><span class="s1"> {"role": "user", "content": "Hello Claude!"}</span>
</span><span id="line-11"><span class="s1"> ]</span>
</span><span id="line-12"><span class="s1"> }'</span>
</span></code></pre></div>
</div>
</section>
<section id="cross-client-compatibility">
<h2>Cross-Client Compatibility<a @click.prevent="window.navigator.clipboard.writeText($el.href); $el.setAttribute('data-tooltip', 'Copied!'); setTimeout(() =&gt; $el.setAttribute('data-tooltip', 'Copy link to this element'), 2000)" aria-label="Copy link to this element" class="headerlink" data-tooltip="Copy link to this element" href="#cross-client-compatibility" x-intersect.margin.0%.0%.-70%.0%="activeSection = '#cross-client-compatibility'"><svg height="1em" viewbox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"></path></svg></a></h2>
<p>One of Planos key features is cross-client compatibility. You can:</p>
<p><strong>Use OpenAI SDK with Claude Models:</strong></p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><code><span id="line-1"><span class="c1"># OpenAI client calling Claude model</span>
</span><span id="line-2"><span class="kn">from</span><span class="w"> </span><span class="nn">openai</span><span class="w"> </span><span class="kn">import</span> <span class="n">OpenAI</span>
</span><span id="line-3">
</span><span id="line-4"><span class="n">client</span> <span class="o">=</span> <span class="n">OpenAI</span><span class="p">(</span><span class="n">base_url</span><span class="o">=</span><span class="s2">"http://127.0.0.1:12000/v1"</span><span class="p">,</span> <span class="n">api_key</span><span class="o">=</span><span class="s2">"test"</span><span class="p">)</span>
</span><span id="line-5">
</span><span id="line-6"><span class="n">response</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">chat</span><span class="o">.</span><span class="n">completions</span><span class="o">.</span><span class="n">create</span><span class="p">(</span>
</span><span id="line-7"> <span class="n">model</span><span class="o">=</span><span class="s2">"claude-3-5-sonnet-20241022"</span><span class="p">,</span> <span class="c1"># Claude model</span>
</span><span id="line-8"> <span class="n">messages</span><span class="o">=</span><span class="p">[{</span><span class="s2">"role"</span><span class="p">:</span> <span class="s2">"user"</span><span class="p">,</span> <span class="s2">"content"</span><span class="p">:</span> <span class="s2">"Hello"</span><span class="p">}]</span>
</span><span id="line-9"><span class="p">)</span>
</span></code></pre></div>
</div>
<p><strong>Use Anthropic SDK with OpenAI Models:</strong></p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><code><span id="line-1"><span class="c1"># Anthropic client calling OpenAI model</span>
</span><span id="line-2"><span class="kn">import</span><span class="w"> </span><span class="nn">anthropic</span>
</span><span id="line-3">
</span><span id="line-4"><span class="n">client</span> <span class="o">=</span> <span class="n">anthropic</span><span class="o">.</span><span class="n">Anthropic</span><span class="p">(</span><span class="n">base_url</span><span class="o">=</span><span class="s2">"http://127.0.0.1:12000"</span><span class="p">,</span> <span class="n">api_key</span><span class="o">=</span><span class="s2">"test"</span><span class="p">)</span>
</span><span id="line-5">
</span><span id="line-6"><span class="n">response</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">messages</span><span class="o">.</span><span class="n">create</span><span class="p">(</span>
</span><span id="line-7"> <span class="n">model</span><span class="o">=</span><span class="s2">"gpt-4o-mini"</span><span class="p">,</span> <span class="c1"># OpenAI model</span>
</span><span id="line-8"> <span class="n">max_tokens</span><span class="o">=</span><span class="mi">50</span><span class="p">,</span>
</span><span id="line-9"> <span class="n">messages</span><span class="o">=</span><span class="p">[{</span><span class="s2">"role"</span><span class="p">:</span> <span class="s2">"user"</span><span class="p">,</span> <span class="s2">"content"</span><span class="p">:</span> <span class="s2">"Hello"</span><span class="p">}]</span>
</span><span id="line-10"><span class="p">)</span>
</span></code></pre></div>
</div>
<p><strong>Mix and Match with</strong> <a class="reference internal" href="model_aliases.html#model-aliases"><span class="std std-ref">Model Aliases</span></a>:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><code><span id="line-1"><span class="c1"># Same code works with different underlying models</span>
</span><span id="line-2"><span class="k">def</span><span class="w"> </span><span class="nf">ask_question</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">question</span><span class="p">):</span>
</span><span id="line-3"> <span class="k">return</span> <span class="n">client</span><span class="o">.</span><span class="n">chat</span><span class="o">.</span><span class="n">completions</span><span class="o">.</span><span class="n">create</span><span class="p">(</span>
</span><span id="line-4"> <span class="n">model</span><span class="o">=</span><span class="s2">"reasoning-model"</span><span class="p">,</span> <span class="c1"># Alias could point to any provider</span>
</span><span id="line-5"> <span class="n">messages</span><span class="o">=</span><span class="p">[{</span><span class="s2">"role"</span><span class="p">:</span> <span class="s2">"user"</span><span class="p">,</span> <span class="s2">"content"</span><span class="p">:</span> <span class="n">question</span><span class="p">}]</span>
</span><span id="line-6"> <span class="p">)</span>
</span><span id="line-7">
</span><span id="line-8"><span class="c1"># Works regardless of what "reasoning-model" actually points to</span>
</span><span id="line-9"><span class="n">openai_client</span> <span class="o">=</span> <span class="n">OpenAI</span><span class="p">(</span><span class="n">base_url</span><span class="o">=</span><span class="s2">"http://127.0.0.1:12000/v1"</span><span class="p">,</span> <span class="n">api_key</span><span class="o">=</span><span class="s2">"test"</span><span class="p">)</span>
</span><span id="line-10"><span class="n">response</span> <span class="o">=</span> <span class="n">ask_question</span><span class="p">(</span><span class="n">openai_client</span><span class="p">,</span> <span class="s2">"Solve this math problem..."</span><span class="p">)</span>
</span></code></pre></div>
</div>
</section>
<section id="error-handling">
<h2>Error Handling<a @click.prevent="window.navigator.clipboard.writeText($el.href); $el.setAttribute('data-tooltip', 'Copied!'); setTimeout(() =&gt; $el.setAttribute('data-tooltip', 'Copy link to this element'), 2000)" aria-label="Copy link to this element" class="headerlink" data-tooltip="Copy link to this element" href="#error-handling" x-intersect.margin.0%.0%.-70%.0%="activeSection = '#error-handling'"><svg height="1em" viewbox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"></path></svg></a></h2>
<p><strong>OpenAI SDK Error Handling:</strong></p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><code><span id="line-1"><span class="kn">from</span><span class="w"> </span><span class="nn">openai</span><span class="w"> </span><span class="kn">import</span> <span class="n">OpenAI</span>
</span><span id="line-2"><span class="kn">import</span><span class="w"> </span><span class="nn">openai</span>
</span><span id="line-3">
</span><span id="line-4"><span class="n">client</span> <span class="o">=</span> <span class="n">OpenAI</span><span class="p">(</span><span class="n">base_url</span><span class="o">=</span><span class="s2">"http://127.0.0.1:12000/v1"</span><span class="p">,</span> <span class="n">api_key</span><span class="o">=</span><span class="s2">"test"</span><span class="p">)</span>
</span><span id="line-5">
</span><span id="line-6"><span class="k">try</span><span class="p">:</span>
</span><span id="line-7"> <span class="n">completion</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">chat</span><span class="o">.</span><span class="n">completions</span><span class="o">.</span><span class="n">create</span><span class="p">(</span>
</span><span id="line-8"> <span class="n">model</span><span class="o">=</span><span class="s2">"nonexistent-model"</span><span class="p">,</span>
</span><span id="line-9"> <span class="n">messages</span><span class="o">=</span><span class="p">[{</span><span class="s2">"role"</span><span class="p">:</span> <span class="s2">"user"</span><span class="p">,</span> <span class="s2">"content"</span><span class="p">:</span> <span class="s2">"Hello"</span><span class="p">}]</span>
</span><span id="line-10"> <span class="p">)</span>
</span><span id="line-11"><span class="k">except</span> <span class="n">openai</span><span class="o">.</span><span class="n">NotFoundError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="line-12"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Model not found: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span><span id="line-13"><span class="k">except</span> <span class="n">openai</span><span class="o">.</span><span class="n">APIError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="line-14"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"API error: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></code></pre></div>
</div>
<p><strong>Anthropic SDK Error Handling:</strong></p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><code><span id="line-1"><span class="kn">import</span><span class="w"> </span><span class="nn">anthropic</span>
</span><span id="line-2">
</span><span id="line-3"><span class="n">client</span> <span class="o">=</span> <span class="n">anthropic</span><span class="o">.</span><span class="n">Anthropic</span><span class="p">(</span><span class="n">base_url</span><span class="o">=</span><span class="s2">"http://127.0.0.1:12000"</span><span class="p">,</span> <span class="n">api_key</span><span class="o">=</span><span class="s2">"test"</span><span class="p">)</span>
</span><span id="line-4">
</span><span id="line-5"><span class="k">try</span><span class="p">:</span>
</span><span id="line-6"> <span class="n">message</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">messages</span><span class="o">.</span><span class="n">create</span><span class="p">(</span>
</span><span id="line-7"> <span class="n">model</span><span class="o">=</span><span class="s2">"nonexistent-model"</span><span class="p">,</span>
</span><span id="line-8"> <span class="n">max_tokens</span><span class="o">=</span><span class="mi">50</span><span class="p">,</span>
</span><span id="line-9"> <span class="n">messages</span><span class="o">=</span><span class="p">[{</span><span class="s2">"role"</span><span class="p">:</span> <span class="s2">"user"</span><span class="p">,</span> <span class="s2">"content"</span><span class="p">:</span> <span class="s2">"Hello"</span><span class="p">}]</span>
</span><span id="line-10"> <span class="p">)</span>
</span><span id="line-11"><span class="k">except</span> <span class="n">anthropic</span><span class="o">.</span><span class="n">NotFoundError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="line-12"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Model not found: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span><span id="line-13"><span class="k">except</span> <span class="n">anthropic</span><span class="o">.</span><span class="n">APIError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="line-14"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"API error: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></code></pre></div>
</div>
</section>
<section id="best-practices">
<h2>Best Practices<a @click.prevent="window.navigator.clipboard.writeText($el.href); $el.setAttribute('data-tooltip', 'Copied!'); setTimeout(() =&gt; $el.setAttribute('data-tooltip', 'Copy link to this element'), 2000)" aria-label="Copy link to this element" class="headerlink" data-tooltip="Copy link to this element" href="#best-practices" x-intersect.margin.0%.0%.-70%.0%="activeSection = '#best-practices'"><svg height="1em" viewbox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"></path></svg></a></h2>
<p><strong>Use</strong> <a class="reference internal" href="model_aliases.html#model-aliases"><span class="std std-ref">Model Aliases</span></a>:
Instead of hardcoding provider-specific model names, use semantic aliases:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><code><span id="line-1"><span class="c1"># Good - uses semantic alias</span>
</span><span id="line-2"><span class="n">model</span> <span class="o">=</span> <span class="s2">"fast-model"</span>
</span><span id="line-3">
</span><span id="line-4"><span class="c1"># Less ideal - hardcoded provider model</span>
</span><span id="line-5"><span class="n">model</span> <span class="o">=</span> <span class="s2">"openai/gpt-4o-mini"</span>
</span></code></pre></div>
</div>
<p><strong>Environment-Based Configuration:</strong>
Use different <a class="reference internal" href="model_aliases.html#model-aliases"><span class="std std-ref">model aliases</span></a> for different environments:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><code><span id="line-1"><span class="kn">import</span><span class="w"> </span><span class="nn">os</span>
</span><span id="line-2">
</span><span id="line-3"><span class="c1"># Development uses cheaper/faster models</span>
</span><span id="line-4"><span class="n">model</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">getenv</span><span class="p">(</span><span class="s2">"MODEL_ALIAS"</span><span class="p">,</span> <span class="s2">"dev.chat.v1"</span><span class="p">)</span>
</span><span id="line-5">
</span><span id="line-6"><span class="n">response</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">chat</span><span class="o">.</span><span class="n">completions</span><span class="o">.</span><span class="n">create</span><span class="p">(</span>
</span><span id="line-7"> <span class="n">model</span><span class="o">=</span><span class="n">model</span><span class="p">,</span>
</span><span id="line-8"> <span class="n">messages</span><span class="o">=</span><span class="p">[{</span><span class="s2">"role"</span><span class="p">:</span> <span class="s2">"user"</span><span class="p">,</span> <span class="s2">"content"</span><span class="p">:</span> <span class="s2">"Hello"</span><span class="p">}]</span>
</span><span id="line-9"><span class="p">)</span>
</span></code></pre></div>
</div>
<p><strong>Graceful Fallbacks:</strong>
Implement fallback logic for better reliability:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><code><span id="line-1"><span class="k">def</span><span class="w"> </span><span class="nf">chat_with_fallback</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">messages</span><span class="p">,</span> <span class="n">primary_model</span><span class="o">=</span><span class="s2">"smart-model"</span><span class="p">,</span> <span class="n">fallback_model</span><span class="o">=</span><span class="s2">"fast-model"</span><span class="p">):</span>
</span><span id="line-2"> <span class="k">try</span><span class="p">:</span>
</span><span id="line-3"> <span class="k">return</span> <span class="n">client</span><span class="o">.</span><span class="n">chat</span><span class="o">.</span><span class="n">completions</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">model</span><span class="o">=</span><span class="n">primary_model</span><span class="p">,</span> <span class="n">messages</span><span class="o">=</span><span class="n">messages</span><span class="p">)</span>
</span><span id="line-4"> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="line-5"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Primary model failed, trying fallback: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span><span id="line-6"> <span class="k">return</span> <span class="n">client</span><span class="o">.</span><span class="n">chat</span><span class="o">.</span><span class="n">completions</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">model</span><span class="o">=</span><span class="n">fallback_model</span><span class="p">,</span> <span class="n">messages</span><span class="o">=</span><span class="n">messages</span><span class="p">)</span>
</span></code></pre></div>
</div>
</section>
<section id="see-also">
<h2>See Also<a @click.prevent="window.navigator.clipboard.writeText($el.href); $el.setAttribute('data-tooltip', 'Copied!'); setTimeout(() =&gt; $el.setAttribute('data-tooltip', 'Copy link to this element'), 2000)" aria-label="Copy link to this element" class="headerlink" data-tooltip="Copy link to this element" href="#see-also" x-intersect.margin.0%.0%.-70%.0%="activeSection = '#see-also'"><svg height="1em" viewbox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"></path></svg></a></h2>
<ul class="simple">
<li><p><a class="reference internal" href="supported_providers.html#supported-providers"><span class="std std-ref">Supported Providers &amp; Configuration</span></a> - Configure your providers and see available models</p></li>
<li><p><a class="reference internal" href="model_aliases.html#model-aliases"><span class="std std-ref">Model Aliases</span></a> - Create semantic model names</p></li>
<li><p><a class="reference internal" href="../../guides/llm_router.html#llm-router"><span class="std std-ref">LLM Routing</span></a> - Intelligent routing capabilities</p></li>
</ul>
</section>
</section>
</div><div class="flex justify-between items-center pt-6 mt-12 border-t border-border gap-4">
<div class="mr-auto">
<a class="inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors border border-input hover:bg-accent hover:text-accent-foreground py-2 px-4" href="supported_providers.html">
<svg class="mr-2 h-4 w-4" fill="none" height="24" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<polyline points="15 18 9 12 15 6"></polyline>
</svg>
Supported Providers &amp; Configuration
</a>
</div>
<div class="ml-auto">
<a class="inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors border border-input hover:bg-accent hover:text-accent-foreground py-2 px-4" href="model_aliases.html">
Model Aliases
<svg class="ml-2 h-4 w-4" fill="none" height="24" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<polyline points="9 18 15 12 9 6"></polyline>
</svg>
</a>
</div>
</div></div><aside class="hidden text-sm xl:block" id="right-sidebar">
<div class="sticky top-16 -mt-10 max-h-[calc(100vh-5rem)] h-full overflow-y-auto pt-6 space-y-2"><p class="font-medium">On this page</p>
<ul>
<li><a :data-current="activeSection === '#supported-clients'" class="reference internal" href="#supported-clients">Supported Clients</a></li>
<li><a :data-current="activeSection === '#gateway-endpoints'" class="reference internal" href="#gateway-endpoints">Gateway Endpoints</a></li>
<li><a :data-current="activeSection === '#openai-python-sdk'" class="reference internal" href="#openai-python-sdk">OpenAI (Python) SDK</a></li>
<li><a :data-current="activeSection === '#openai-responses-api-conversational-state'" class="reference internal" href="#openai-responses-api-conversational-state">OpenAI Responses API (Conversational State)</a></li>
<li><a :data-current="activeSection === '#anthropic-python-sdk'" class="reference internal" href="#anthropic-python-sdk">Anthropic (Python) SDK</a></li>
<li><a :data-current="activeSection === '#curl-examples'" class="reference internal" href="#curl-examples">cURL Examples</a></li>
<li><a :data-current="activeSection === '#cross-client-compatibility'" class="reference internal" href="#cross-client-compatibility">Cross-Client Compatibility</a></li>
<li><a :data-current="activeSection === '#error-handling'" class="reference internal" href="#error-handling">Error Handling</a></li>
<li><a :data-current="activeSection === '#best-practices'" class="reference internal" href="#best-practices">Best Practices</a></li>
<li><a :data-current="activeSection === '#see-also'" class="reference internal" href="#see-also">See Also</a></li>
</ul>
</div>
</aside>
</main>
</div>
</div><footer class="py-6 border-t border-border md:py-0">
<div class="container flex flex-col items-center justify-between gap-4 md:h-24 md:flex-row">
<div class="flex flex-col items-center gap-4 px-8 md:flex-row md:gap-2 md:px-0">
<p class="text-sm leading-loose text-center text-muted-foreground md:text-left">© 2025, Katanemo Labs, Inc Last updated: Feb 04, 2026. </p>
</div>
</div>
</footer>
</div>
<script src="../../_static/documentation_options.js?v=2dc42696"></script>
<script src="../../_static/doctools.js?v=9bcbadda"></script>
<script src="../../_static/sphinx_highlight.js?v=dc90522c"></script>
<script defer="defer" src="../../_static/theme.js?v=582b20c5"></script>
<script src="../../_static/design-tabs.js?v=f930bc37"></script>
</body>
</html>