GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — GitHub - copyleftdev/tokentip-python: Official Python SDK for the TokenTip API — tips that buy AI inference credit. Sync + async, typed.

BranchesTags
Open more actions menu

Latest commit

 

History

2 Commits
2 Commits

Folders and files

NameName
Last commit message
Last commit date
tests
tests
 
 
tokentip
tokentip
 
 
.gitignore
.gitignore
 
 
LICENSE
LICENSE
 
 
README.md
README.md
 
 
pyproject.toml
pyproject.toml
 
 

Repository files navigation

tokentip — Python SDK

Tip my tokens

Official Python client for the TokenTip API. Tips that buy AI inference credit for open-source maintainers. Typed, sync and async, with webhook signature verification and a live event stream.

pip install tokentip

Requires Python 3.10+. The only runtime dependency is httpx.

Quickstart

Mint an API token in your dashboard (tt_…), then:

from tokentip import TokenTip

with TokenTip("tt_your_token") as tt:
    me = tt.me()
    print(me.handle, me.credit)          # credit is a decimal.Decimal, never a float

    tips = tt.tips.list(status="settled", limit=20)
    for tip in tips.data:
        print(tip.id, tip.net_to_tokens)

Money is always parsed to decimal.Decimal — exact, never binary-rounded.

Async

Every call has an async twin with the same shape:

from tokentip import AsyncTokenTip

async with AsyncTokenTip("tt_your_token") as tt:
    balance = await tt.balance()
    async for event in tt.events():
        if event.type == "tip.settled":
            print("settled", event.tip.creator_handle, "→", event.balance)

The live event stream (SSE)

events() opens GET /v1/events and yields decoded Event objects until you stop iterating. Pass operator=True (operator token) for the system-wide stream.

with TokenTip("tt_your_token") as tt:
    for event in tt.events():
        match event.type:
            case "tip.settled":
                print("credit granted:", event.tip.net_to_tokens)
            case "key.rotated":
                print("key rotated for", event.data["creator_handle"])

Events carry an idempotency id — dedupe on it, TokenTip may redeliver.

Webhooks

Register an endpoint and receive the same events over signed POSTs:

created = tt.webhooks.create("https://you.example/hook", events=["tip.settled"])
print(created.secret)   # whsec_… — shown once, store it now

Verify each delivery (constant-time, with timestamp tolerance):

from tokentip import webhooks

# in your web handler:
event = webhooks.verify(
    request.body,                                    # raw bytes/str, unparsed
    request.headers["X-TokenTip-Signature"],
    signing_secret,                                  # the whsec_… from create()
)
# raises SignatureVerificationError on a bad signature or stale timestamp

Operator

With an operator-scoped token:

overview = tt.operator.overview()
print(overview.pool.state, overview.pool.committed)

result = tt.operator.settle(tip_id)                  # force-settle a held tip
tt.operator.disable_key("some-handle")               # fraud kill-switch

Errors

Non-2xx responses raise a typed subclass of APIError, carrying the RFC 7807 problem detail:

HTTP Exception
401 AuthenticationError
403 ForbiddenError
404 NotFoundError
409 ConflictError
502 UpstreamError
from tokentip import NotFoundError

try:
    tt.tips.get("does-not-exist")
except NotFoundError as e:
    print(e.status, e.title, e.detail)

Idempotency

Mutating calls that can safely be retried accept an idempotency key:

tt.key.rotate(idempotency_key="rotate-2026-07-19")
tt.operator.settle(tip_id, idempotency_key=tip_id)

Reference

The full contract lives in the api/ OpenAPI + AsyncAPI specs; this SDK is generated to match them.

About

Official Python SDK for the TokenTip API — tips that buy AI inference credit. Sync + async, typed.

Resources

Readme
MIT license
Activity

Stars

0 stars

Watchers

0 watching

Forks

0 forks
Report repository

Releases

Packages

Contributors

Languages

You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.