> ## Documentation Index
> Fetch the complete documentation index at: https://novita.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Gebruiksgids voor de GPUs SDK

Deze gids legt uit hoe je de `novita-gpus` SDK gebruikt om een Async Serverless Endpoint aan te roepen en hoe je een worker-handler aanpast.

## 1. SDK installeren

Installeer de SDK in je clientomgeving of worker-runtimeomgeving:

```bash theme={"system"}
pip install novita-gpus
```

## 2. Taken indienen met SDK

De standaard aanvraag-URL van de `novita-gpus` SDK is `https://async-public.serverless.novita.ai/v1`. Stel je API Key in en maak een client met de Endpoint-naam om een Endpoint aan te roepen.

```python theme={"system"}
import novita_gpus

novita_gpus.api_key = "sk_xxxx"

endpoint = novita_gpus.Endpoint("0f43a6867e05fddd")
job = endpoint.run({
    "prompt": "a red apple on a table"
})

print(job.status())
output = job.output(timeout=300)
print(output)
```

## 3. Voorbeeld van ComfyUI-taak

Voor `novitalabs/comfyui-worker:v0.0.1` moet de taakinvoer een ComfyUI-workflow bevatten. Het volgende minimale voorbeeld komt overeen met de geteste case:

```python theme={"system"}
import novita_gpus

novita_gpus.api_key = "sk_xxxx"

endpoint = novita_gpus.Endpoint("0f43a6867e05fddd")

job = endpoint.run({
    "workflow": {
        "4": {
            "class_type": "CheckpointLoaderSimple",
            "inputs": {"ckpt_name": "flux1-dev-fp8.safetensors"},
        },
        "5": {
            "class_type": "EmptyLatentImage",
            "inputs": {"width": 512, "height": 512, "batch_size": 1},
        },
        "6": {
            "class_type": "CLIPTextEncode",
            "inputs": {"clip": ["4", 1], "text": "a red apple on a table"},
        },
        "7": {
            "class_type": "CLIPTextEncode",
            "inputs": {"clip": ["4", 1], "text": "blurry, low quality"},
        },
        "3": {
            "class_type": "KSampler",
            "inputs": {
                "model": ["4", 0],
                "positive": ["6", 0],
                "negative": ["7", 0],
                "latent_image": ["5", 0],
                "seed": 42,
                "steps": 10,
                "cfg": 7,
                "sampler_name": "euler",
                "scheduler": "normal",
                "denoise": 1,
            },
        },
        "8": {
            "class_type": "VAEDecode",
            "inputs": {"samples": ["3", 0], "vae": ["4", 2]},
        },
        "9": {
            "class_type": "SaveImage",
            "inputs": {"filename_prefix": "test", "images": ["8", 0]},
        },
    },
    "output_node_id": "9",
})

print(job.status())
print(job.output(timeout=300))
```

## 4. Aangepaste handler

Roep aan de workerzijde `novita_gpus.start({"handler": handler})` aan om de taaklus te starten. Het platform geeft taakgegevens door aan `handler(job)`:

* `job["id"]`: huidige taak-id
* `job["input"]`: invoerinhoud die door de client is ingediend
* De retourwaarde van de handler wordt gebruikt als taakuitvoer
* Als de geretourneerde dict een veld `error` bevat, wordt de taak als mislukt gemarkeerd

Minimaal handler-voorbeeld:

```python theme={"system"}
import time
import novita_gpus


def handler(job: dict) -> dict:
    job_id = job["id"]
    job_input = job.get("input", {})
    prompt = job_input.get("prompt", "hello")

    novita_gpus.progress_update(job, {
        "status": "running",
        "message": "job accepted",
    })

    time.sleep(1)

    return {
        "job_id": job_id,
        "prompt": prompt,
        "result": "ok",
    }


if __name__ == "__main__":
    novita_gpus.start({"handler": handler})
```

## 5. Volledige worker-voorbeelden

Voor volledige worker-broncode, instructies voor het bouwen van Docker-images en scripts voor het indienen van taken, zie de <Link href="https://github.com/novitalabs/gpus-python-example" target="_blank">Novita GPUs Python-voorbeelden</Link>.

De repository bevat twee voorbeelden:

* <Link href="https://github.com/novitalabs/gpus-python-example/tree/main/workers/comfyui-worker" target="_blank">comfyui-worker</Link>: voert ComfyUI uit vanuit `handler.py` en retourneert gegenereerde afbeeldingen.
* <Link href="https://github.com/novitalabs/gpus-python-example/tree/main/workers/sleep-worker" target="_blank">sleep-worker</Link>: een minimale `handler.py` die wacht gedurende een aangevraagde duur en een JSON-resultaat retourneert.

Elke voorbeeldmap bevat:

* `handler.py`: definieert `handler(job)` en start de worker met `novita_gpus.start({"handler": handler})`.
* `Dockerfile`: bouwt de worker-image.
* `requirements.txt`: installeert `novita-gpus`.
* `submit_task.py`: dient een taak in met de `novita-gpus` client-SDK.

Bouw en push je worker-image naar je eigen registry:

```bash theme={"system"}
IMAGE=<your-registry>/comfyui-worker:v0.0.1

docker buildx build --platform linux/amd64 \
  -t "$IMAGE" \
  --push .
```

Taakindiening gebruikt de Endpoint-naamindeling `<endpoint-id>-<app-name>`.
Bijvoorbeeld: Endpoint ID `o8UJWkag5WTn` en appnaam `async` leveren op:

```text theme={"system"}
o8UJWkag5WTn-async
```

De `submit_task.py` voorbeelden accepteren de Endpoint ID en appnaam afzonderlijk en stellen vervolgens de uiteindelijke Endpoint-naam samen:

```bash theme={"system"}
export NOVITA_API_KEY="sk_xxxx"
export NOVITA_ENDPOINT_ID="o8UJWkag5WTn"
export NOVITA_APP_NAME="async"

python submit_task.py \
  --endpoint "$NOVITA_ENDPOINT_ID" \
  --app-name "$NOVITA_APP_NAME" \
  --api-key "$NOVITA_API_KEY"
```

Binnen het script wordt de SDK-client gemaakt met de samengestelde Endpoint-naam:

```python theme={"system"}
endpoint_name = f"{args.endpoint}-{args.app_name}"
endpoint = novita_gpus.Endpoint(endpoint_name, api_key=args.api_key)
```

## 6. Afbeeldingen of bestanden retourneren

De Async Serverless Endpoint `status` API heeft een limiet voor de uitvoergrootte. Upload grote bestanden zoals afbeeldingen en video’s eerst naar objectopslag en retourneer URL’s in de uitvoer.

Configureer omgevingsvariabelen voor objectopslag in de Endpoint:

```bash theme={"system"}
BUCKET_ENDPOINT_URL=https://<your-bucket-endpoint>
BUCKET_ACCESS_KEY_ID=<your-access-key-id>
BUCKET_SECRET_ACCESS_KEY=<your-secret-access-key>
BUCKET_NAME=<your-bucket-name>
```

Upload een afbeelding in de handler:

```python theme={"system"}
import novita_gpus


def handler(job: dict) -> dict:
    image_url = novita_gpus.upload_image(job["id"], "/tmp/output.png")

    return {
        "images": [
            {
                "filename": "output.png",
                "url": image_url,
            }
        ]
    }


if __name__ == "__main__":
    novita_gpus.start({"handler": handler})
```

Je kunt ook gewone bestanden of bytes uploaden:

```python theme={"system"}
import novita_gpus

file_url = novita_gpus.upload_file("result.json", "/tmp/result.json")
bytes_url = novita_gpus.upload_bytes("result.txt", b"hello")
```

## 7. FAQ

### Moet ik een API Key in de worker configureren?

Meestal niet. API Keys worden voornamelijk door clients gebruikt om taken in te dienen, op te vragen en te annuleren.

### Welke handler-retourwaarde markeert een taak als mislukt?

Als de handler een dict retourneert die een veld `error` bevat, wordt de taak als mislukt gemarkeerd:

```python theme={"system"}
return {"error": "invalid input"}
```
