NL ▾
API-sleutel aanvragen

Voorbeeld van DeepSeek API Python: chatten, streaming, tools

Een deepseek api python-setup vereist alleen het officiële openai-pakket, een base URL, een sleutel en een model-ID. De voorbeelden hieronder behandelen een gewoon verzoek, streaming, JSON-modus, toolaanroepen en retry's, allemaal tegen een OpenAI-compatibel endpoint.

Bijgewerkt

Terminal slab streaming gloeiende datatokens naar een serverblok, ter illustratie van Python API-aanroepen

Belangrijkste punten

  • Installeer openai, stel vervolgens base_url in op https://api.deepseekapi.top/v1 en model op uncensored.
  • Streaming, JSON-modus en toolaanroepen werken via de normale SDK-parameters.
  • Ga om met HTTP 429 door de Retry-After te lezen en het opnieuw te proberen.
  • De prijs is $0,15 per 1M inputtokens en $0,50 per 1M outputtokens.

Installeer en stuur een eerste verzoek

Deze service is niet de officiële DeepSeek API. Het is een gehost, OpenAI-compatibel endpoint dat één open-weight model draait, met de ID uncensored, beheerd door een onafhankelijke provider. Omdat het de OpenAI-indeling volgt, werkt de standaard Python SDK zonder wijzigingen, behalve voor de URL en sleutel.

pip install openai

Haal een sleutel op van de API-sleutelpagina. Na het aanmaken van een account claim je met één klik $0,50 aan gratis proeftegoed, zonder creditcard, geldig voor 7 dagen. Sla de sleutel op in een omgevingsvariabele in plaats van in het bronbestand:

export API_KEY="YOUR_KEY"
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.deepseekapi.top/v1",
    api_key=os.environ["API_KEY"],
)

resp = client.chat.completions.create(
    model="uncensored",
    messages=[
        {"role": "system", "content": "You are a concise assistant."},
        {"role": "user", "content": "Explain list comprehensions in two sentences."},
    ],
    temperature=0.7,
)

print(resp.choices[0].message.content)
print(resp.usage.prompt_tokens, resp.usage.completion_tokens)

De twee verbruikscijfers zijn waarover je wordt gefactureerd. Vermenigvuldig ze met de prijzen om de kosten van een verzoek te berekenen: inputtokens × $0,15 en outputtokens × $0,50, elk gedeeld door 1.000.000.

De asynchrone client gebruiken

Voor webservers en alles wat met veel gebruikers omgaat, gebruik je de asynchrone client. Deze heeft dezelfde parameters als de synchrone en is in de meeste code een drop-in vervanging.

import asyncio
import os
from openai import AsyncOpenAI

client = AsyncOpenAI(
    base_url="https://api.deepseekapi.top/v1",
    api_key=os.environ["API_KEY"],
)

sem = asyncio.Semaphore(8)

async def ask(prompt):
    async with sem:
        r = await client.chat.completions.create(
            model="uncensored",
            messages=[{"role": "user", "content": prompt}],
        )
        return r.choices[0].message.content

async def main():
    prompts = ["Define idempotent.", "Define monotonic.", "Define pure function."]
    answers = await asyncio.gather(*(ask(p) for p in prompts))
    for a in answers:
        print(a)

asyncio.run(main())

De semaphore is ingesteld op 8 omdat dat de concurrency van een volledige sleutel is. Gebruik bij een proefsleutel 2. Zonder limiet zal een burst van taken concurrency-fouten opleveren, zelfs als elk verzoek geldig is.

Streaming-antwoorden

Stel stream=True in en het endpoint stuurt server-verzonden gebeurtenissen. Elke chunk bevat een klein tekstgedeelte in delta.content. Als je om gebruik vraagt, rapporteert de laatste chunk het tokenaantal.

# client = OpenAI(base_url="https://api.deepseekapi.top/v1", ...) as above
stream = client.chat.completions.create(
    model="uncensored",
    messages=[{"role": "user", "content": "Write a haiku about debugging."}],
    stream=True,
    stream_options={"include_usage": True},
)

for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)
    if chunk.usage:
        print("\n", chunk.usage.prompt_tokens, chunk.usage.completion_tokens)

Twee details zorgen vaak voor problemen. De laatste usage-chunk kan een lege choices-lijst hebben, vandaar dat de lus eerst chunk.choices controleert. En een gestreamd verzoek houdt zijn concurrency-slot vast tot de stream eindigt, dus breek loops netjes af en sluit streams die je verlaat. Een volledige sleutel staat 8 gelijktijdige verzoeken toe; een proefsleutel staat er 2 toe.

JSON-modus

Voor uitvoer die een programma gaat parseren, gebruik je response_format met json_object. Noem ook het woord JSON in de prompt en beschrijf de vorm die je wilt. Het model heeft die instructie nodig; het vlaggetje alleen levert geen schema op.

# client = OpenAI(base_url="https://api.deepseekapi.top/v1", ...) as above
import json

resp = client.chat.completions.create(
    model="uncensored",
    messages=[
        {"role": "system", "content": "Reply with JSON only: {\"title\": str, \"tags\": [str]}"},
        {"role": "user", "content": "Summarize: a guide to caching HTTP responses."},
    ],
    response_format={"type": "json_object"},
    temperature=0,
)

data = json.loads(resp.choices[0].message.content)
print(data["title"], data["tags"])

Zet json.loads in een try/except. Als een antwoord wordt afgekapt door een tokenlimiet, wordt het niet geparsed, dus vermijd een kleine max_tokens met JSON. Het instellen van temperature op 0 en een seed maakt herhalingen reproduceerbaarder, omdat beide worden doorgegeven.

Function calling

De API accepteert tools en tool_choice, en retourneert tool_calls op het assistantbericht. Je voert de functie zelf uit en stuurt het resultaat terug als een bericht met role: "tool".

# client = OpenAI(base_url="https://api.deepseekapi.top/v1", ...) as above
import json

tools = [{
    "type": "function",
    "function": {
        "name": "add",
        "description": "Add two numbers.",
        "parameters": {
            "type": "object",
            "properties": {"a": {"type": "number"}, "b": {"type": "number"}},
            "required": ["a", "b"],
        },
    },
}]

messages = [{"role": "user", "content": "What is 17.5 plus 24.25?"}]
first = client.chat.completions.create(
    model="uncensored", messages=messages, tools=tools, tool_choice="auto"
)

msg = first.choices[0].message
if msg.tool_calls:
    messages.append(msg)
    for call in msg.tool_calls:
        args = json.loads(call.function.arguments)
        result = args["a"] + args["b"]
        messages.append({
            "role": "tool",
            "tool_call_id": call.id,
            "content": str(result),
        })
    final = client.chat.completions.create(
        model="uncensored", messages=messages, tools=tools
    )
    print(final.choices[0].message.content)
else:
    print(msg.content)

Parse arguments altijd voorzichtig. Het is een JSON-string gegenereerd door het model en een onjuiste string is mogelijk. Valideer deze voordat je erop reageert, vooral als de functie bestanden of een database raakt.

Fouten, limieten en retry's

Een verzoek boven een limiet retourneert HTTP 429. De foutcode vertelt je welke limiet: rate_limited voor verzoeken per minuut (300 op een volledige sleutel, 60 op een proefsleutel) en concurrency voor te veel tegelijk. Bij tijdelijke overbelasting krijg je ook 429 met Retry-After: 5. De SDK gooit openai.RateLimitError.

# client = OpenAI(base_url="https://api.deepseekapi.top/v1", ...) as above
import time
import openai

def ask(prompt, tries=4):
    for attempt in range(tries):
        try:
            r = client.chat.completions.create(
                model="uncensored",
                messages=[{"role": "user", "content": prompt}],
            )
            return r.choices[0].message.content
        except openai.RateLimitError as e:
            wait = int(e.response.headers.get("Retry-After", 5))
            time.sleep(wait * (attempt + 1))
    raise RuntimeError("still rate limited")

print(ask("Name three Python web frameworks."))

Als je veel verzoeken stuurt, beperk dan je eigen paralleliteit met een semaphore of een threadpool met 8 workers, of 2 op een proefaccount-sleutel. Dat voorkomt concurrency-fouten in plaats van ze met herhaalpogingen te omzeilen.

Headers lezen

Elk antwoord bevat X-Request-Id, X-Balance-USD, X-RateLimit-Limit-Requests en X-RateLimit-Limit-Concurrency. De SDK stelt ze beschikbaar via het ruwe antwoord:

# client = OpenAI(base_url="https://api.deepseekapi.top/v1", ...) as above
raw = client.chat.completions.with_raw_response.create(
    model="uncensored",
    messages=[{"role": "user", "content": "ping"}],
)
print(raw.headers.get("X-Balance-USD"), raw.headers.get("X-Request-Id"))
completion = raw.parse()

Het loggen van de verzoek-ID bij elke fout maakt het beantwoorden van supportvragen veel makkelijker. Mislukte of geweigerde verzoeken worden niet in rekening gebracht.

Een gesprek gaande houden

De API is stateless. Het onthoudt eerdere verzoeken niet, dus een multi-turn chat betekent dat je elke keer de hele geschiedenis stuurt. Houd een lijst bij en voeg eraan toe:

# client = OpenAI(base_url="https://api.deepseekapi.top/v1", ...) as above
history = [{"role": "system", "content": "You are a helpful tutor."}]

def chat(user_text):
    history.append({"role": "user", "content": user_text})
    r = client.chat.completions.create(model="uncensored", messages=history)
    reply = r.choices[0].message.content
    history.append({"role": "assistant", "content": reply})
    return reply

print(chat("What is a closure?"))
print(chat("Show me one in Python."))

Elke beurt stuurt alles opnieuw, dus inputtokens groeien per beurt. Knip oude berichten weg zodra de lijst lang wordt, of vraag het model om het vroege deel samen te vatten en vervang het. Met een contextvenster van 100.000 tokens heb je veel ruimte, maar de rekening groeit met de geschiedenis, dus een geknipte lijst is goedkoper.

Stekingswaarden kiezen

Gebruik temperature 0 tot 0,3 voor code en extractie, rond 0,7 voor algemene chat, en hoger voor fictie. top_p, stop, seed en de frequentie- en aanwezigheidsstraffen worden doorgegeven, dus ze gedragen zich zoals de OpenAI-documentatie beschrijft. Verander er één tegelijk en vergelijk.

Kosten en context plannen

Het contextvenster is 100.000 tokens, prompt plus voltooiing, en de body-limiet is 8 MB. Voltooiing kan alles gebruiken wat over is van het venster, en max_tokens is optioneel. Het instellen ervan is nog steeds goede praktijk voor batchtaken.

Een uitgewerkt voorbeeld: een batch van 1.000 samenvattingen, elk met 1.500 inputtokens en 200 outputtokens.

  • Input: 1.000 × 1.500 = 1.500.000 tokens, wat 1,5 × $0,15 = $0,225 is
  • Output: 1.000 × 200 = 200.000 tokens, wat 0,2 × $0,50 = $0,10 is
  • Totaal: $0,325

Prijzen zijn pay as you go van prepaid credit, zonder abonnement, en tegoed verloopt nooit. Opwaarderingen lopen van $20 tot $500 in hele bedragen, met +5% vanaf $50, +10% vanaf $100 en +15% vanaf $200, betaalbaar met kaart of crypto. Zie de prijzenpagina, en de quickstart docs voor curl- en Node-voorbeelden. Als je alleen je sleutel wilt vinden, dekt de API-sleuteloverzicht dit.

Prompts worden niet gebruikt voor training. De service is alleen tekst: geen afbeeldingen, audio, embeddings of fine-tuning, dus plan daar geen endpoints voor.

Vragen en antwoorden

Heb ik een speciale DeepSeek-bibliotheek nodig?

Nee. Installeer het openai-pakket, stel base_url in op https://api.deepseekapi.top/v1 en gebruik de model-ID uncensored. Dit is niet de officiële DeepSeek API.

Ondersteunt de Python SDK streaming hier?

Ja. Geef stream=True door en voeg stream_options toe met include_usage om tokenaantallen in de laatste chunk te krijgen.

Hoe ga ik om met een 429-fout?

Vang openai.RateLimitError af, lees de Retry-After-header en wacht voordat je opnieuw probeert. De foutcode vertelt je of het rate_limited of concurrency was.

Kan ik testen zonder te betalen?

Ja. Na het aanmaken van een account voeg je via één klik op de API-sleutelpagina $0,50 aan gratis proeftegoed toe, geldig voor 7 dagen, zonder dat een creditcard nodig is.

Je sleutel is nog maar één formulier verwijderd

Maak een account aan, kopieer de sleutel, pas de base URL aan. Dat is de hele setup.

API-sleutel aanvragen