<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mandar Shinde</title>
    <description>The latest articles on DEV Community by Mandar Shinde (@mandarvshinde).</description>
    <link>https://dev.to/mandarvshinde</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1407450%2Fdf1b8a38-b5ba-4fef-bb53-010ba228a5b1.jpeg</url>
      <title>DEV Community: Mandar Shinde</title>
      <link>https://dev.to/mandarvshinde</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mandarvshinde"/>
    <language>en</language>
    <item>
      <title>I built an async wrapper for OpenAI/Anthropic SDKs because I didn't want a proxy in my request path</title>
      <dc:creator>Mandar Shinde</dc:creator>
      <pubDate>Sat, 08 Aug 2026 12:46:54 +0000</pubDate>
      <link>https://dev.to/mandarvshinde/i-built-an-async-wrapper-for-openaianthropic-sdks-because-i-didnt-want-a-proxy-in-my-request-path-1h1p</link>
      <guid>https://dev.to/mandarvshinde/i-built-an-async-wrapper-for-openaianthropic-sdks-because-i-didnt-want-a-proxy-in-my-request-path-1h1p</guid>
      <description>&lt;p&gt;I kept running into the same tradeoff building cost tooling for teams shipping LLM features. Every attribution tool in this space works the same way: you point &lt;code&gt;base_url&lt;/code&gt; at a proxy, and it sees every call before it happens. That's genuinely useful if you want to block or downgrade a call before it fires. It also means the proxy's uptime is now your uptime, and you've added a network hop to every single request.&lt;/p&gt;

&lt;p&gt;I wanted the attribution without touching the request path at all. So I wrote a wrapper instead.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Cognocient&lt;/code&gt; wraps the OpenAI and Anthropic Python clients directly. You still call &lt;code&gt;client.chat.completions.create()&lt;/code&gt; exactly the way you always did. The wrapper times the call, then fires a cost report on a background thread after your real response has already returned to your code.&lt;/p&gt;

&lt;p&gt;The part I actually spent the most time on wasn't the happy path, it was making sure a dead reporting endpoint can never touch your application. If Cognocient's ingestion API is slow, down, or just does not exist, that failure has to stay invisible to whatever you're building. No exception bubbling up, no retry pile-up blocking your real call. There is a test, &lt;code&gt;test_reporter_failure_isolation.py&lt;/code&gt;, that specifically points the reporter at an unreachable host and asserts the actual API call still returns clean. Writing that test is what convinced me the design was sound, not the other way around.&lt;/p&gt;

&lt;p&gt;What you get: per-call cost, and tags for feature/team/user if you want chargeback-style reporting later.&lt;/p&gt;

&lt;p&gt;What you do not get, on purpose: pre-call blocking. If a call is about to blow your budget, this wrapper finds out after it already happened, same as any billing dashboard does. If you need to stop a call before it fires, you want a proxy, and honestly LiteLLM or Portkey do that well. This is for people who've already decided visibility without a critical-path dependency is the right tradeoff for their setup.&lt;/p&gt;

&lt;p&gt;Also worth knowing before you reach for it: streaming responses (&lt;code&gt;stream=True&lt;/code&gt;) aren't reported yet. If most of your traffic streams, this won't give you complete numbers right now. Non-streaming is solid, I would call it production-safe there. Streaming is next.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;cognocient&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CognocientOpenAI&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sk-...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cognocient_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sk-cog-...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# everything else about the client works exactly like before
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MIT licensed, signed provenance on the PyPI release, genuinely early (v0.1.x). If you're already routing through a gateway and it is working for you, this probably isn't for you. If you have been putting off cost visibility specifically because you didn't want another hop in the path, I would like to hear if this is useful or if I have missed something obvious.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/mandarvshinde/cognocient-python-wrapper" rel="noopener noreferrer"&gt;https://github.com/mandarvshinde/cognocient-python-wrapper&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;PyPI&lt;/strong&gt;: &lt;code&gt;pip install cognocient&lt;/code&gt;&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>python</category>
      <category>ai</category>
      <category>llm</category>
    </item>
  </channel>
</rss>
