Python SDK

neuctra-authix is the official Python SDK for Neuctra Authix. It mirrors the JavaScript and Dart SDKs — the same methods, the same routes and the same security model — expressed the way Python expects: keyword-only arguments, snake_case, generators for cursor traversal, and a typed exception per error code.

Python 3.8+Sync (requests)One dependency: requestsv2.0.0

In thirty seconds

Python
1import os
2from neuctra_authix import Authix
3
4authix = Authix(
5    app_id=os.environ["AUTHIX_APP_ID"],
6    secret_key=os.environ["AUTHIX_SECRET_KEY"],
7)
8
9# Every list is a bounded Page — 20 records by default, 100 maximum.
10page = authix.get_all_users_from_app(limit=50)
11
12for user in page:            # a Page iterates its records
13    print(user["email"])
14
15print(page.has_more)         # is there another page?
16print(page.next_cursor)      # pass back as `cursor` to fetch it

What this SDK is for

Python runs on your server, and that shapes what this SDK is good at. The natural fit is privileged work: administrative scripts, data exports, backfills, scheduled jobs, and a backend that signs users in on behalf of a mobile or web client.

Do not ship this SDK to an end user

A desktop or CLI application distributed to users is not a server. A secret key inside it is readable by anyone who has the file, and it carries full authority over every user on your account. If your Python program runs on someone else's machine, use a publishable key and accept the scoping that comes with it — or put the privileged call behind an API you control.

Which key to pass

The constructor takes exactly one credential, and passing the wrong one is rejected before any network call — the SDK parses the key, sees the mismatch, and raises ConfigurationError immediately.

CredentialWhat it can reachWhere it belongs
publishable_keypk_live_…End-user auth, and the signed-in user's own records. The server pins every request to the session it resolved.
secret_keysk_live_…Every user and every record on the account, plus app-wide data. Server-side only.

Sessions need a publishable key

The server only resolves an end-user session for publishable-key callers — a secret key can target any user directly, so it has no need of one. check_user_session() on a secret-key client returns authenticated: False even straight after a successful login_user(). That is correct, not a bug.

Same API, three languages

Method names convert to snake_case and arguments are keyword-only, but the routes and payloads are identical. Anything you learn in one SDK transfers.

Python
1# TypeScript
2await authix.addUserData({
3  userId: "u1",
4  dataCategory: "notes",
5  data: { title: "Hello" },
6});
7
8# Python — same method, same route, same payload
9authix.add_user_data(
10    user_id="u1",
11    data_category="notes",
12    data={"title": "Hello"},
13)

One client, reused

Python
1# The client holds a requests.Session, so use it as a context manager
2# when you want the connection pool closed deterministically.
3with Authix(app_id=APP_ID, secret_key=SECRET_KEY) as authix:
4    authix.get_user(id="u_1")
5
6# In a long-lived web process, build one client at startup instead and
7# let it live for the life of the process — reconnecting per request
8# throws away connection reuse.

The client wraps a requests.Session, so cookies set by login_user() persist for the life of the client and later calls act as that user. That is convenient in a script and a hazard in a shared web process — see the sessions note in the auth reference before reusing one client across requests from different people.

Package layout

Bash
1src/neuctra_authix/
2├── __init__.py       # single import — exports everything below
3├── client.py         # Authix — every API method
4├── pagination.py     # Page, iterate_pages, iterate_items
5├── keys.py           # key parsing, masking, misuse guards
6├── errors.py         # the typed exception hierarchy
7└── _version.py

Everything is re-exported from the package root, so from neuctra_authix import Authix, Page, VersionConflictError is all you ever need. The submodules are an implementation detail.

What you get over calling the API directly

  • Keys are validated and their type checked before the first request, so a swapped key fails at construction rather than as a confusing 403 in production.
  • Every list returns a Page that iterates its own records and carries has_more and next_cursor — and iter_* generators walk the cursor for you, with the infinite-loop guard already written.
  • Each error code maps to its own exception class, so you catch the one case you handle and let the rest surface.
  • A version conflict arrives as VersionConflictError carrying current_version, which is what makes a retry possible rather than just reportable.

Synchronous by design

The SDK is built on requests and every call blocks. In an async framework such as FastAPI, wrap calls in run_in_threadpool (or asyncio.to_thread) so a slow request does not stall the event loop. An async client is not available today.

Where to go next

Installation covers setup and configuration. Auth & users covers sign-up through deletion. User data and app data cover storage. Search covers cross-user queries, and types & errors is the full reference.

Related