<?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: Fundiman</title>
    <description>The latest articles on DEV Community by Fundiman (@fundiman).</description>
    <link>https://dev.to/fundiman</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3920349%2F9b3819f7-038a-41ad-84f8-7117de3c83a8.png</url>
      <title>DEV Community: Fundiman</title>
      <link>https://dev.to/fundiman</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fundiman"/>
    <language>en</language>
    <item>
      <title>dsk++ — I rewrote a forgotten DeepSeek library to be fully async (and added a bunch of stuff)</title>
      <dc:creator>Fundiman</dc:creator>
      <pubDate>Fri, 08 May 2026 15:34:14 +0000</pubDate>
      <link>https://dev.to/fundiman/dsk-i-rewrote-a-forgotten-deepseek-library-to-be-fully-async-and-added-a-bunch-of-stuff-4bek</link>
      <guid>https://dev.to/fundiman/dsk-i-rewrote-a-forgotten-deepseek-library-to-be-fully-async-and-added-a-bunch-of-stuff-4bek</guid>
      <description>&lt;p&gt;A while back, &lt;a href="https://github.com/xtekky" rel="noopener noreferrer"&gt;xtekky&lt;/a&gt; wrote a small library called &lt;code&gt;deepseek4free&lt;/code&gt; for interacting with DeepSeek's chat infrastructure. It worked, but it was synchronous — meaning it blocked the event loop on every API call, making it painful to use in any async Python project.&lt;/p&gt;

&lt;p&gt;I needed it for a Discord bot I was building, and the blocking behavior was causing real problems. So I rewrote it.&lt;/p&gt;

&lt;p&gt;The result is &lt;a href="https://github.com/Fundiman/dskpp" rel="noopener noreferrer"&gt;dskpp (dsk++)&lt;/a&gt; — a drop-in async replacement that adds a few things the original never had.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's new in dsk++
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fully async&lt;/strong&gt; — built on &lt;code&gt;curl_cffi&lt;/code&gt; async sessions, &lt;code&gt;async for&lt;/code&gt; streaming, &lt;code&gt;asyncio.to_thread()&lt;/code&gt; for WASM PoW&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Concurrent file uploads&lt;/strong&gt; — &lt;code&gt;asyncio.gather()&lt;/code&gt; uploads multiple files simultaneously&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Session deletion&lt;/strong&gt; — &lt;code&gt;await api.delete_chat_session(session_id)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conversation history&lt;/strong&gt; — &lt;code&gt;await api.get_history(session_id)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proper error hierarchy&lt;/strong&gt; — &lt;code&gt;AuthenticationError&lt;/code&gt;, &lt;code&gt;RateLimitError&lt;/code&gt;, &lt;code&gt;NetworkError&lt;/code&gt;, &lt;code&gt;CloudflareError&lt;/code&gt;, &lt;code&gt;UploadFilesUnavailable&lt;/code&gt;, &lt;code&gt;APIError&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Automatic Cloudflare detection and cookie refresh&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker support&lt;/strong&gt; via &lt;code&gt;DOCKERMODE=true&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The architecture
&lt;/h2&gt;

&lt;p&gt;The library has three layers:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;API layer&lt;/strong&gt; (&lt;code&gt;api.py&lt;/code&gt;) handles session management, streaming SSE parsing, file uploads, and automatic retry on Cloudflare blocks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bypass layer&lt;/strong&gt; (&lt;code&gt;server.py&lt;/code&gt;) is a FastAPI + Chromium automation server that solves Cloudflare challenges and extracts cookies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PoW layer&lt;/strong&gt; (&lt;code&gt;pow.py&lt;/code&gt;) runs the WASM-based proof-of-work solver via &lt;code&gt;asyncio.to_thread()&lt;/code&gt; so it doesn't block your event loop during CPU-bound hashing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dskpp.api&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;DeepSeekAPI&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;api&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DeepSeekAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your_token_here&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_chat_session&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# Upload files concurrently
&lt;/span&gt;    &lt;span class="n"&gt;file_ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upload_files&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;report.pdf&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data.xlsx&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="c1"&gt;# Stream response
&lt;/span&gt;    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;chunk&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chat_completion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Summarize these files&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;ref_file_ids&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;file_ids&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;search_enabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;
    &lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete_chat_session&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before using the API, you need to generate cookies once:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python run_and_get_cookies.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This launches Chromium, solves the Cloudflare challenge, and stores cookies locally. After that, the client handles refresh automatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  Getting your token
&lt;/h2&gt;

&lt;p&gt;Log into &lt;a href="https://chat.deepseek.com" rel="noopener noreferrer"&gt;chat.deepseek.com&lt;/a&gt;, open DevTools, go to Application → Local Storage → chat.deepseek.com → &lt;code&gt;USER_TOKEN&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  A word of caution
&lt;/h2&gt;

&lt;p&gt;This is built on reverse-engineered infrastructure. DeepSeek can change their API at any time and break things. It may also violate their ToS — use at your own risk and don't do anything that would get your account banned.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why bother?
&lt;/h2&gt;

&lt;p&gt;The original library was solid but unmaintained and sync-only. For anyone building bots, automation tools, or anything async in Python, a blocking DeepSeek client is a dead end. This fixes that. Also not everyone can afford the DeepSeek API, so this helps people automate the web interface endpoints for chat.&lt;/p&gt;

&lt;p&gt;Credit to &lt;a href="https://github.com/xtekky/deepseek4free" rel="noopener noreferrer"&gt;xtekky&lt;/a&gt; and &lt;a href="https://github.com/Doremii109/deepseek4free-fix" rel="noopener noreferrer"&gt;Doremii109&lt;/a&gt; whose work this builds on.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://github.com/Fundiman/dskpp" rel="noopener noreferrer"&gt;GitHub → Fundiman/dskpp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Stars appreciated 🥺&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>programming</category>
      <category>deepseek</category>
    </item>
  </channel>
</rss>
