Skip to main content

vikky

Python client for Vikky, VSP's AI API gateway. Vikky speaks the OpenAI API, so this package is a thin wrapper over the official openai package: anything in the OpenAI Python docs works here too.

Install

pip install vikky

In Colab or Jupyter, use %pip install vikky.

Get a key

Sign in to the Vikky console at https://vikkyverse.com/platform and create an API key. Keep it secret: anyone with the key spends your quota.

Set VIKKY_API_KEY

On your laptop:

export VIKKY_API_KEY="your-key"

In Google Colab: click the key icon in the left sidebar, add a secret named VIKKY_API_KEY, turn on "Notebook access", then run:

import os
from google.colab import userdata

os.environ["VIKKY_API_KEY"] = userdata.get("VIKKY_API_KEY")

Never paste the key into a notebook cell you might share.

First call (JSON out)

import json
from vikky import Vikky

client = Vikky()  # reads VIKKY_API_KEY

resp = client.chat.completions.create(
    model="vikky-chat",
    messages=[
        {"role": "system", "content": "Reply in JSON."},
        {"role": "user", "content": 'List 3 planets as {"planets": [...]}'},
    ],
    response_format={"type": "json_object"},
)
data = json.loads(resp.choices[0].message.content)
print(data["planets"])

JSON mode works best when your messages say "JSON" and show the shape you want.

Streaming

stream = client.chat.completions.create(
    model="vikky-chat",
    messages=[{"role": "user", "content": "Explain PID control in 3 lines."}],
    stream=True,
)
for chunk in stream:
    if chunk.choices:
        print(chunk.choices[0].delta.content or "", end="", flush=True)

Models

Model What it does Call it with
vikky-chat chat, JSON output, tool calling chat.completions.create, or responses.create
vikky-vision chat that also takes images chat.completions.create with an image_url part
vikky-embed embeddings embeddings.create
vikky-transcribe audio to text audio.transcriptions.create
vikky-speech text to audio audio.speech.create
vikky-image image generation and editing images.generate, images.edit
vikky-video video generation, async videos.create_and_poll
vikky-rerank rank documents against a query rerank
vikky-ocr text out of a document ocr
vikky-moderate content moderation moderations.create

Every row except the last two is a method the openai package already has, so the OpenAI Python docs apply unchanged. rerank and ocr are not OpenAI routes: they are the only two methods this package adds, and they return a plain dict instead of a typed object.

Tool calling

resp = client.chat.completions.create(
    model="vikky-chat",
    messages=[{"role": "user", "content": "Weather in Hyderabad?"}],
    tools=[{"type": "function", "function": {
        "name": "get_weather",
        "parameters": {"type": "object", "properties": {"city": {"type": "string"}}},
    }}],
)
call = resp.choices[0].message.tool_calls[0]
print(call.function.name, call.function.arguments)

Responses API

resp = client.responses.create(model="vikky-chat", input="Say hello.")
print(resp.output_text)

Vision

resp = client.chat.completions.create(
    model="vikky-vision",
    messages=[{"role": "user", "content": [
        {"type": "text", "text": "What is in this picture?"},
        {"type": "image_url", "image_url": {"url": "https://example.com/arm.jpg"}},
    ]}],
)
print(resp.choices[0].message.content)

For a local image, pass a data URL as the url:

import base64, pathlib

raw = base64.b64encode(pathlib.Path("arm.png").read_bytes()).decode()
url = f"data:image/png;base64,{raw}"

Embeddings

resp = client.embeddings.create(model="vikky-embed", input=["robot arm", "pizza"])
arm, pizza = (d.embedding for d in resp.data)
print(len(arm), len(pizza))

Pass a list to embed a batch in one call. Results come back in the order you sent them, and d.index tells you which input each vector belongs to.

Audio to text

with open("meeting.m4a", "rb") as f:
    resp = client.audio.transcriptions.create(model="vikky-transcribe", file=f)
print(resp.text)

Text to audio

resp = client.audio.speech.create(
    model="vikky-speech",
    voice="alloy",
    input="The arm is homed and ready.",
)
resp.write_to_file("ready.mp3")

Images

resp = client.images.generate(model="vikky-image", prompt="a blue robot arm on a bench", n=1)
item = resp.data[0]
print(item.url or "returned as base64")  # either one, see "Saving generated media"

with open("arm.png", "rb") as f:
    edited = client.images.edit(model="vikky-image", image=f, prompt="make the bench wooden")

Video

Video generation takes minutes, so it is a job, not a call. Submit it, wait for it, then download it. Keep the id create gave you and download with that one.

job = client.videos.create(model="vikky-video", prompt="a robot arm picking up a cube")
done = client.videos.poll(job.id, poll_interval_ms=5000)
assert done.status == "completed", done.error
client.videos.download_content(job.id).write_to_file("clip.mp4")

client.videos.retrieve(job.id) is the single-shot version of poll, if you want to show video.progress in your own loop. Do not use videos.create_and_poll: it only returns the polled job, and Vikky's polled id cannot be downloaded from.

Saving generated media

An image comes back as either a URL or base64, depending on what you asked for. Audio and video come back as a binary response with write_to_file.

import base64, pathlib, urllib.request

item = client.images.generate(model="vikky-image", prompt="a blue cube").data[0]
if item.b64_json:
    pathlib.Path("cube.png").write_bytes(base64.b64decode(item.b64_json))
else:
    with urllib.request.urlopen(item.url) as r:
        pathlib.Path("cube.png").write_bytes(r.read())

Ask for response_format="b64_json" and you never have to fetch a URL at all.

A generated file's URL is temporary. Download it in the same run that created it. Do not store the URL in a database or a notebook output and expect it to still work tomorrow.

Rerank

resp = client.rerank(
    query="how do I reset the arm?",
    documents=[
        "Press the red button to reset the arm.",
        "Our office is in Hyderabad.",
    ],
    top_n=1,
)
for r in resp["results"]:
    print(r["index"], r["relevance_score"])

Results come back best first. r["index"] points back into the documents list you sent.

OCR

resp = client.ocr(document={"type": "document_url", "document_url": "https://example.com/invoice.pdf"})
for page in resp["pages"]:
    print(page["markdown"])

For an image instead of a PDF, send {"type": "image_url", "image_url": "https://..."}. A data URL works too.

Moderation

resp = client.moderations.create(model="vikky-moderate", input="Some user text.")
result = resp.results[0]
print(result.flagged, [name for name, hit in result.categories if hit])

Async

import asyncio
from vikky import AsyncVikky

async def main():
    client = AsyncVikky()
    resp = await client.chat.completions.create(
        model="vikky-chat",
        messages=[{"role": "user", "content": "Say hello."}],
    )
    print(resp.choices[0].message.content)

asyncio.run(main())  # in Colab or Jupyter, use: await main()

Every model above works on AsyncVikky, rerank and ocr included: same arguments, awaited.

Environment variables

Variable Required Default
VIKKY_API_KEY yes none. OPENAI_API_KEY is never used.
VIKKY_BASE_URL no https://api.vikkyverse.com/v1

Arguments win over environment: Vikky(api_key=..., base_url=...). Every other argument (timeout, max_retries, ...) goes straight to openai.OpenAI. A missing key raises vikky.VikkyError.

If Vikky is down

Write lab code so the model name comes from the environment:

import os
from vikky import Vikky

MODEL = os.environ.get("VIKKY_MODEL", "vikky-chat")
client = Vikky()
resp = client.chat.completions.create(model=MODEL, messages=[...])

Then a trainer can set VIKKY_BASE_URL, VIKKY_API_KEY and VIKKY_MODEL to any other OpenAI-compatible endpoint, and the notebook runs unchanged.

License

MIT

Release files for vikky 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for vikky 0.1.0
File Size Uploaded
vikky-0.1.0.tar.gz 6.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for vikky 0.1.0
File Interpreter ABI Platform
vikky-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 13.3 kB

Release files / vikky-0.1.0.tar.gz

Download URL vikky-0.1.0.tar.gz
Size 6.2 kB
Tags Source
SHA-256 checksum
How to use checksums
d4ad28041719425a6968ae4231d34bd3b56f2bb6d2110e0c2a97086d4b39b2ec
BLAKE2b-256 checksum
How to use checksums
6b74b664fc3dda08218a77fd48b5693c058ed12f96c018121c34bb3229dce4fe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / vikky-0.1.0-py3-none-any.whl

Download URL vikky-0.1.0-py3-none-any.whl
Size 7.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b6770947fbd95d55f8647d7cc0073984031cdc25594f1a1614e0817f34e2fdf5
BLAKE2b-256 checksum
How to use checksums
5252cd4a687e6e20e7caf96675dd9ee03bd12c4425dae585b854d4ce817a5d56
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page