Getting access to your tab
There is a key, and it is easier to find than most people expect — it is on your tab's home page. This page covers where it is, what these tools do and do not read with it, and what to say to whoever controls your tournament's tab.
The short version. Sign in to your tab in a browser. Go to
Change Password on the home page. Your API token is there. Copy it into
.env as TABBY_TOKEN and you are done.
Where the key is
Tabbycat generates an API token for every user account automatically. From Tabbycat's own documentation:
“To grant administrator access to an application, you can give it your token, which can be found under Tokens in the database or under Change Password on the site home page. Each user has a token automatically generated when registered.”
The second of those is the one to use. Change Password is an ordinary page that any signed-in user can open, so it works whether your tournament is self-hosted or on a managed host — and it does not need the Edit Database area, which managed hosts often close off to tournament accounts.
Prefer the token over your password, for the same reason you would prefer a key to a lock: you can revoke a token on its own, from that same page, without changing anything else you sign in to.
# .env
export TABBY_TOKEN=938fab3...
When you need your password as well
Two things the toolkit reads are not part of the API. Tabbycat's feedback-progress table and its check-in status are ordinary admin pages, and a token authenticates the API rather than a page — so those two need your ordinary sign-in too.
| Tool | Token alone | What you gain by adding a password |
|---|---|---|
| The fold and simulator | Everything works | Nothing |
| Judge feedback | Everything works | Nothing |
| Tester tracking | Everything except two columns | “Owes feedback” and “checked in” |
So: start with the token. Add TABBY_USER and
TABBY_PASS only if you want those two columns.
Why those two pages are different Technical
Tabbycat's REST API does not expose feedback progress or check-in status.
Both exist only as admin pages — but every Tabbycat admin page hydrates its
tables from a window.vueData global, so parsing that global out
of the HTML gives you the same structured rows the page itself renders. It is
still a GET of a page you are allowed to open in a browser; it is just not an
API call, which is why a bearer token does not authenticate it.
TabRead.needs_admin_pages() reports whether the client has a
session, and tester-tracking/pull.py skips those two reads with a
message rather than letting a 403 look like a fault. The fake Tabbycat in
demo/ enforces the same distinction — its admin routes refuse a
token-only client — so the behaviour is exercised by the demo rather than
discovered at a tournament.
Why this is for adjudication cores only
Whichever way you sign in, it has to be a tab-side account — adjudication core or tabulation. This is not a licensing decision; it is what the data requires. A public or participant account cannot see:
- written feedback about judges, which is the entire input to the feedback tool;
- who is on which panel, which is how tester tracking knows a judge has been watched;
- a draw before it is released, which is most of what makes any of this useful in the moment.
If you are not on the adjudication core or the tab team at your tournament, the person who is will need to run these, or give you an account. There is no version of this that works from the public tab alone.
What to send your tab director
You will probably have to ask for an account, and “can I have tab access so I can run some scripts” is a reasonable thing to be cautious about. So here is the case, in a form you can forward:
What it reads. Rounds, the draw, panels, break categories and the break, teams, judges, institutions, motions and written feedback — through Tabbycat's own API, plus two admin pages for feedback progress and check-in status.
What it writes. Nothing. It cannot. The single piece of code that talks to Tabbycat refuses any request that is not a GET, HEAD or OPTIONS before it leaves the machine — there is no write function in the toolkit to call, and no setting that enables one. The only exception is the sign-in form itself, if you use a password rather than a token.
Where the credentials live. In a file on the laptop running it, which is excluded from version control. They are never sent anywhere except to your own tab.
How to check any of that. python3 tests/test_release.py
in the repository. Among other things it parses every Python file and asserts
that nothing outside the sign-in form can write to a tab.
The line that enforces it Technical
If your TD would rather read the code than the claim, it is short. In
core/tabread.py:
SAFE = {"GET", "HEAD", "OPTIONS"}
class _GetOnlySession(requests.Session):
def request(self, method, url, *a, **kw):
if str(method).upper() not in SAFE:
raise ReadOnlyViolation(...)
return super().request(method, url, *a, **kw)
Every call in requests funnels through
Session.request, including the convenience methods, so
overriding it is sufficient rather than merely discouraging. A grep is enough
to check nothing else is going on:
grep -rn "\.post\|\.patch\|\.put\|\.delete" --include=*.py .
One warning that matters more than the rest
Tabbycat's API returns each participant's url_key, and that
value is their private URL. Anyone holding it can submit ballots
and feedback as that person.
So any file you save from a pull is credential material, not just data. The
feedback tool needs those keys — that is how it addresses a page to a judge —
and it keeps them in feedback/data/, which is excluded from
version control and written owner-readable only. Delete that directory when
your tournament is over.
Do not put a raw pull in a shared drive, a git repository, or a chat.
Technical This is why the published feedback
site is addressed by sha256(url_key) rather than by the key
itself. The site never contains a key, so a copy of the published directory is
not a set of credentials the way a raw pull is; and there is no index, listing
or search, so holding the site tells you nothing about who is in it. The
hashing happens in the reader's browser.
Things that will waste your afternoon
| What you see | What it is |
|---|---|
404 on an API path |
Nearly always the slug. It is the tournament's own bit of the web address, the part straight after the host name. |
/api/v1/ returns 404 but /api/v1 works |
Not a mistake — Tabbycat really does 404 on the trailing slash. The toolkit already gets this right; it matters if you are writing your own requests. |
| A list comes back short | Tabbycat pages long lists and puts the next page in a
Link: …; rel="next" header rather than in the body. Ignore
the header and you silently get the first page only. |
403 Forbidden after a successful sign-in |
The account is not tab-side. See above — this is the one that cannot be worked around. |
| “did not look like a Tabbycat login page” | The url points at a tournament path or a front page instead of the
site root. No trailing slash, no /admin. |
Full API documentation is Tabbycat's, not ours:
the API
guide, and your own tab serves its live schema at /api/schema.yml.