Python

Get started with the Nookara Python SDK

Install nookara from PyPI, sign people in through your registered app, and call any Nookara route as a Python method.

1. Install it

Needs Python 3.10 or newer, and nookara 0.9.0 or newer for the names on this page. The REST client has no dependencies.

pip install nookara

Add the extras you need: realtime for websockets, signing for signed chat messages, or all for both.

pip install "nookara[realtime]"
pip install "nookara[all]"

The package is nookara on PyPI. Version 0.9.0 removed the old Velora and Bonfire names, so older code needs the new ones: import velora_api is now import nookara, Bonfire is Ember, login_with_velora is login_with_nookara and bonfire_* helpers are ember_*. The changelog has the full list.

2. Create an app

  1. Go to My Account > Apps and press Create app.
  2. Add http://localhost to its authorized URLs. Without a port it covers any port, so the SDK can pick whichever one is free.
  3. Choose its scopes, then copy its ID. It looks like app_ followed by 20 letters and numbers.

A new app is in development: only you and up to 5 testers can sign in with it. Create a Nookara app explains verification and the scope choices.

3. Sign in

from nookara import Client, login_app

token, origin = login_app("app_0123456789abcdef0123")
nookara = Client(token, origin=origin)

me = nookara.get_account_me()
print(me["account"]["username"])
print(nookara.scope_names())       # what the person actually allowed

login_app opens the browser on Nookara's sign-in screen. When the person approves, the browser comes back to a small one-time server on this computer, and the SDK swaps the one-time grant for a token. It never sees a password.

An app's token only works from the app's authorized URLs, so always make the client with the origin that came back. To skip signing in next time, keep the token somewhere private, like your OS credential store, and load it with Client(token, origin="http://localhost").

People can turn scopes off. Your app asks for its scopes, but the person can switch any of them off on the sign-in screen. Check with nookara.has_scope("CHAT"), or catch ScopeError and ask them to sign in again.

4. Call the API

Every route has one method, named after its method and path. URL parameters are keyword arguments, query is the query string and json is the body.

nookara.post_friends_request(json={"username": "someone"})
nookara.storage_set("save", "level", "4")
print(nookara.storage_get("save", "level"))

# the same thing by name, or any path
nookara.call("get_account_me")
nookara.request("GET", "/currency/balance")

Storage IDs are your app's own: whatever ID you pick, it lives in your app's folder on that person's account, and nothing else can change it.

Ember servers

Every Ember server is its own address. Nookara gives your token a short ticket for one server at a time, so your Nookara token never reaches it.

from nookara import Ember, Instance

print(nookara.ember_instances())           # the Ember servers saved on this account

chat = Instance("https://chat.ikelene.net")
chat.login_with_nookara(nookara)           # needs Chat
channel = chat.channel_id("#general")
chat.send_message(channel, "Hello from Python!")

for item in Ember(nookara).communities():   # every saved server at once
    print(item["instance"], item["error"])

Realtime

import asyncio
from nookara import RealtimeClient

async def main():
    async with RealtimeClient(token, origin=origin) as live:
        async for event in live:
            print(event["type"])

asyncio.run(main())

Install nookara[realtime] first. Pass the same origin as for Client: Nookara's socket only takes an app's token from its authorized URLs.

Errors

from nookara import APIError, ScopeError, TransportError

try:
    nookara.post_friends_request(json={"username": "someone"})
except ScopeError as exc:
    print("Not allowed:", exc.label)      # sign in again to ask for it
except APIError as exc:
    print(exc.status, exc.error, exc.retry_after)
except TransportError:
    print("Network problem. The request may still have gone through.")

Nothing is retried for you and redirects are refused, so a token can't follow one somewhere else.

Bots

import os
from nookara import BotClient

bot = BotClient(os.environ["BOT_TOKEN"])

Bot tokens don't go through an app. The API guide covers the bot gateway, webhooks and Ember servers.

The old sign-in stops on December 3rd. login(project_name=..., scopes=...) is the legacy login with a permissions integer. It and the tokens it made stop working on 3 December 2026. Use login_app.

Questions

Do I still need the wheel from nookara.cc?

No. Install from PyPI with pip install nookara. The old wheel downloads are no longer updated.

Why does my token give origin_not_authorized?

An app's token only works from its authorized URLs. Make the client with Client(token, origin=...) using the origin login_app gave you, and keep http://localhost in the app's authorized URLs.

Where is every route listed?

The Nookara API guide has every route with its Python method name, scopes and a raw request.