Skip to content

feat!: require project_id and move Client API under /projects/{project_id}#1

Closed
jeroenrinzema wants to merge 1 commit into
mainfrom
feat/project-in-url
Closed

feat!: require project_id and move Client API under /projects/{project_id}#1
jeroenrinzema wants to merge 1 commit into
mainfrom
feat/project-in-url

Conversation

@jeroenrinzema

Copy link
Copy Markdown
Contributor

Summary

The Lunogram Client API now scopes every authenticated endpoint to a project: /api/client/... becomes /api/client/projects/{projectID}/.... This is an intentional, breaking hard cut — there is no backwards compatibility.

This PR makes the project a required client-construction parameter. You pass the project UUID once when instantiating the client, and the SDK injects /projects/<project_id> into every Client API path automatically. Callers never pass the project per call.

Authentication is unchanged (same API key / token) — only the URL gained the project segment.

Breaking change

Lunogram(api_key) is now Lunogram(api_key, project_id). The project_id is required and validated as a non-empty UUID string.

Before

from lunogram import Lunogram

client = Lunogram("your-api-key")
client.user.upsert(user)            # POST /api/client/users

After

from lunogram import Lunogram

client = Lunogram("your-api-key", "11111111-2222-3333-4444-555555555555")
client.user.upsert(user)            # POST /api/client/projects/<project_id>/users

Old → new paths

All paths move under /api/client/projects/{projectID}/:

Old New
/api/client/users …/projects/{projectID}/users
/api/client/users/events …/projects/{projectID}/users/events
/api/client/users/scheduled …/projects/{projectID}/users/scheduled
/api/client/users/devices …/projects/{projectID}/users/devices
/api/client/users/inbox (/count,/read,/archived) …/projects/{projectID}/users/inbox…
/api/client/organizations …/projects/{projectID}/organizations
/api/client/organizations/users …/projects/{projectID}/organizations/users
/api/client/organizations/events …/projects/{projectID}/organizations/events
/api/client/organizations/scheduled …/projects/{projectID}/organizations/scheduled
/api/client/organizations/inbox (/count,/read,/archived) …/projects/{projectID}/organizations/inbox…
/api/client/push/vapid …/projects/{projectID}/push/vapid
/api/client/auth-methods/{authMethodID}/sessions …/projects/{projectID}/auth-methods/{authMethodID}/sessions

Implementation

  • client.py: Lunogram.__init__ now takes a required project_id; builds a project-scoped path reference and threads it through user/organization.
  • utils/reference.py: the path reference becomes a project-scoped factory (client(project_id)) that validates a non-empty UUID and centralizes the single /projects/<project_id>/ injection. Added paths for user devices, user/org inbox (+ /count, /read, /archived), push/vapid, and auth-methods/{id}/sessions.
  • app/objects.py and app/models/**: accept and use the injected reference rather than a module-level singleton. No path is double-prefixed.
  • README.md: documents constructing the client with the project and the new URLs.

Validation

  • Wheel builds with hatchling (python -m build --wheel).
  • Built wheel installs and imports in a clean env; every resource path (including the auth-method session endpoint) resolves to a single /projects/<project_id>/… prefix; empty/invalid project_id is rejected with ValueError.
  • The repo defines no pytest/ruff/mypy config, so there is no existing test or lint suite to update or run beyond build + import verification.

Dependency / merge order

This depends on the platform Client API change that moves endpoints under /projects/{projectID}. It should merge once that ships.

…t_id}

Every authenticated Lunogram Client API endpoint is now scoped to a project.
The project UUID is supplied once when constructing the client and is injected
into every Client API path as a `/projects/<project_id>/` segment; callers no
longer pass it per request.

BREAKING CHANGE: `Lunogram(api_key)` becomes `Lunogram(api_key, project_id)`.
Auth is unchanged (same API key / token); only the URL gains the project.

- client.py: add required `project_id`, build a project-scoped reference and
  thread it through `user`/`organization`.
- utils/reference.py: turn the path reference into a project-scoped factory
  (validates non-empty UUID); add inbox/devices/push/auth-method-session paths.
- app/objects.py and app/models/**: accept and use the injected reference.
- README: document construction with the project and the new URLs.
@jeroenrinzema

Copy link
Copy Markdown
Contributor Author

Superseded by #2, which now targets main and already contains this branch's require project_id commit in its ancestry. Closing in favor of #2.

@jeroenrinzema jeroenrinzema deleted the feat/project-in-url branch June 25, 2026 15:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant