.fyi
Early access

Set up quibble, step by step

By the end of this page, a note filed from your app arrives as an issue in your tracker. Four steps, about ten minutes, and most of that is making the token. Here's the code for your framework and the settings for your tracker. Prefer to let your coding agent do it? Hand it the install recipe. This page is for quibble in your app; for quibble in your browser or on your computer, see the three places it works.

1. Install the package

Add quibble with the extra for your framework: quibble[fastapi], quibble[django], quibble[flask], quibble[starlette] or quibble[litestar]. Early access comes with the install line.

Not Python? On your computer, quibble serve runs quibble as a companion beside an app in any language. A hosted app in another language implements quibble's documented schema. More on other languages.

2. Give it a token

quibble files every note with one token that only your app holds. Make one with just enough access for where the notes go:

TrackerTokenSettings
GitHubIssues: read and write on the repository. Add Contents: read and write only to store screenshots in the repository.QUIBBLE_GITHUB_REPO=owner/repo
GitLabThe api scope.QUIBBLE_TRACKER=gitlab, QUIBBLE_TRACKER_API=https://gitlab.example.com/api/v4, QUIBBLE_GITHUB_REPO=group/project
Gitea, Forgejowrite:issue.QUIBBLE_TRACKER=gitea, QUIBBLE_TRACKER_API=https://git.example.com/api/v1, QUIBBLE_GITHUB_REPO=owner/repo
Jira CloudAn API token, used as [email protected]:API_TOKEN, for an account that can browse, create, transition and attach in the project.QUIBBLE_TRACKER=jira, QUIBBLE_TRACKER_API=https://your-site.atlassian.net, QUIBBLE_GITHUB_REPO=PROJ (the project key), QUIBBLE_ISSUE_TYPE=Task
LinearA restricted API key with read and write on one team.QUIBBLE_TRACKER=linear, QUIBBLE_GITHUB_REPO=ENG (the team key)

The token goes in QUIBBLE_GITHUB_TOKEN, or, better in production, a file named by QUIBBLE_GITHUB_TOKEN_FILE. The name says GitHub for history; it holds the token for whichever tracker you use.

3. Mount the endpoint

One line where your app starts. The endpoint sits behind your app's sign-in, like the rest of your routes.

FastAPI

from quibble import make_client
from quibble.backends.fastapi import add_quibble

add_quibble(app, make_client())

Django, in your root urls.py. Keep the /?: the widget posts to the bare /quibble.

from django.urls import include, re_path
from quibble import make_client
from quibble.backends.django import quibble_urlpatterns

urlpatterns += [re_path(r"^quibble/?", include(quibble_urlpatterns(make_client())))]

Flask or Starlette

from quibble import make_client
from quibble.backends.flask import add_quibble   # or quibble.backends.starlette

add_quibble(app, make_client())

Litestar, whose routes are fixed when the app is built:

from quibble import make_client
from quibble.backends.litestar import make_handlers

app = Litestar(route_handlers=[..., *make_handlers(make_client())])

4. Add the button

Put render_widget() just before </body> in your base template, and every page has the button. In Django, use quibble.render_widget("/quibble"). A single-page app can mount and unmount the widget as its routes change.

Who filed it

quibble names the reporter from the sign-in in front of your app. Behind Cloudflare Access there's nothing to set. Behind another proxy, name its header: QUIBBLE_IDENTITY_HEADERS=X-Auth-Request-Email. With no sign-in at all, QUIBBLE_ASK_EMAIL=on asks for an address and marks it self-declared.

Identity, and its limits

Check it works

Run quibble doctor with your app's settings: it checks the token, the repository or project and the labels, and never prints a secret. Then open your app, file a note from the button, and look for the issue in your tracker.

To switch quibble off without removing it, set QUIBBLE_ENABLED=off.

Once it works

Every note now arrives ready to fix. When you want more, you can:

quibble is in early access, and the install line comes with it.

Email for early access