norbix 1.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. norbix-1.1.0/.github/workflows/ci.yml +26 -0
  2. norbix-1.1.0/.github/workflows/release.yml +61 -0
  3. norbix-1.1.0/.gitignore +9 -0
  4. norbix-1.1.0/ArchitectOverview.md +142 -0
  5. norbix-1.1.0/CHANGELOG.md +58 -0
  6. norbix-1.1.0/LICENSE +21 -0
  7. norbix-1.1.0/Makefile +37 -0
  8. norbix-1.1.0/PKG-INFO +181 -0
  9. norbix-1.1.0/README.md +165 -0
  10. norbix-1.1.0/docs/README.md +4 -0
  11. norbix-1.1.0/docs/api/_index.md +8 -0
  12. norbix-1.1.0/docs/api/chat.md +7 -0
  13. norbix-1.1.0/docs/api/database.md +24 -0
  14. norbix-1.1.0/docs/api/echo.md +7 -0
  15. norbix-1.1.0/docs/api/membership.md +24 -0
  16. norbix-1.1.0/docs/hub/_index.md +17 -0
  17. norbix-1.1.0/docs/hub/account.md +43 -0
  18. norbix-1.1.0/docs/hub/ai.md +20 -0
  19. norbix-1.1.0/docs/hub/database.md +47 -0
  20. norbix-1.1.0/docs/hub/echo.md +7 -0
  21. norbix-1.1.0/docs/hub/email.md +7 -0
  22. norbix-1.1.0/docs/hub/files.md +21 -0
  23. norbix-1.1.0/docs/hub/internal.md +7 -0
  24. norbix-1.1.0/docs/hub/logs.md +15 -0
  25. norbix-1.1.0/docs/hub/membership.md +31 -0
  26. norbix-1.1.0/docs/hub/notifications.md +74 -0
  27. norbix-1.1.0/docs/hub/payments.md +22 -0
  28. norbix-1.1.0/docs/hub/scheduler.md +14 -0
  29. norbix-1.1.0/docs/hub/webhooks.md +14 -0
  30. norbix-1.1.0/pyproject.toml +83 -0
  31. norbix-1.1.0/references/api2.dtos.ts +4855 -0
  32. norbix-1.1.0/references/api_dtos.py +1727 -0
  33. norbix-1.1.0/references/hub2.dtos.ts +12211 -0
  34. norbix-1.1.0/references/hub_dtos.py +8617 -0
  35. norbix-1.1.0/scripts/generate_endpoints.py +511 -0
  36. norbix-1.1.0/src/norbix_python/__init__.py +27 -0
  37. norbix-1.1.0/src/norbix_python/api/__init__.py +23 -0
  38. norbix-1.1.0/src/norbix_python/api/chat.py +41 -0
  39. norbix-1.1.0/src/norbix_python/api/database.py +483 -0
  40. norbix-1.1.0/src/norbix_python/api/echo.py +41 -0
  41. norbix-1.1.0/src/norbix_python/api/membership.py +483 -0
  42. norbix-1.1.0/src/norbix_python/client.py +318 -0
  43. norbix-1.1.0/src/norbix_python/errors.py +98 -0
  44. norbix-1.1.0/src/norbix_python/hub/__init__.py +50 -0
  45. norbix-1.1.0/src/norbix_python/hub/account.py +977 -0
  46. norbix-1.1.0/src/norbix_python/hub/ai.py +379 -0
  47. norbix-1.1.0/src/norbix_python/hub/database.py +1081 -0
  48. norbix-1.1.0/src/norbix_python/hub/echo.py +41 -0
  49. norbix-1.1.0/src/norbix_python/hub/email.py +41 -0
  50. norbix-1.1.0/src/norbix_python/hub/files.py +405 -0
  51. norbix-1.1.0/src/norbix_python/hub/internal.py +41 -0
  52. norbix-1.1.0/src/norbix_python/hub/logs.py +249 -0
  53. norbix-1.1.0/src/norbix_python/hub/membership.py +665 -0
  54. norbix-1.1.0/src/norbix_python/hub/notifications.py +1783 -0
  55. norbix-1.1.0/src/norbix_python/hub/payments.py +431 -0
  56. norbix-1.1.0/src/norbix_python/hub/scheduler.py +223 -0
  57. norbix-1.1.0/src/norbix_python/hub/webhooks.py +223 -0
  58. norbix-1.1.0/src/norbix_python/models.py +21 -0
  59. norbix-1.1.0/src/norbix_python/transport.py +325 -0
  60. norbix-1.1.0/tests/__init__.py +1 -0
  61. norbix-1.1.0/tests/api/__init__.py +1 -0
  62. norbix-1.1.0/tests/api/test_chat.py +18 -0
  63. norbix-1.1.0/tests/api/test_database.py +154 -0
  64. norbix-1.1.0/tests/api/test_echo.py +18 -0
  65. norbix-1.1.0/tests/api/test_membership.py +154 -0
  66. norbix-1.1.0/tests/helpers.py +48 -0
  67. norbix-1.1.0/tests/hub/__init__.py +1 -0
  68. norbix-1.1.0/tests/hub/test_account.py +639 -0
  69. norbix-1.1.0/tests/hub/test_ai.py +122 -0
  70. norbix-1.1.0/tests/hub/test_database.py +338 -0
  71. norbix-1.1.0/tests/hub/test_echo.py +18 -0
  72. norbix-1.1.0/tests/hub/test_email.py +18 -0
  73. norbix-1.1.0/tests/hub/test_files.py +130 -0
  74. norbix-1.1.0/tests/hub/test_internal.py +18 -0
  75. norbix-1.1.0/tests/hub/test_logs.py +82 -0
  76. norbix-1.1.0/tests/hub/test_membership.py +210 -0
  77. norbix-1.1.0/tests/hub/test_notifications.py +563 -0
  78. norbix-1.1.0/tests/hub/test_payments.py +138 -0
  79. norbix-1.1.0/tests/hub/test_scheduler.py +74 -0
  80. norbix-1.1.0/tests/hub/test_webhooks.py +74 -0
  81. norbix-1.1.0/tests/test_async_client_smoke.py +13 -0
  82. norbix-1.1.0/tests/test_client.py +61 -0
  83. norbix-1.1.0/uv.lock +1217 -0
@@ -0,0 +1,26 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches: [main, next, beta]
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-22.04
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+ - uses: astral-sh/setup-uv@v5
14
+ with:
15
+ version: "latest"
16
+ - uses: actions/setup-python@v5
17
+ with:
18
+ python-version: "3.12"
19
+ - name: Install dependencies
20
+ run: uv sync --all-groups
21
+ - name: Lint
22
+ run: uv run ruff check .
23
+ - name: Typecheck
24
+ run: uv run mypy src
25
+ - name: Test
26
+ run: uv run pytest
@@ -0,0 +1,61 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ branches: [main, next, beta]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: write
10
+ issues: write
11
+ pull-requests: write
12
+ id-token: write
13
+
14
+ jobs:
15
+ release:
16
+ runs-on: ubuntu-22.04
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+ with:
20
+ fetch-depth: 0
21
+
22
+ - uses: astral-sh/setup-uv@v5
23
+ with:
24
+ version: "latest"
25
+
26
+ - uses: actions/setup-python@v5
27
+ with:
28
+ python-version: "3.12"
29
+ - name: Install dependencies
30
+ run: uv sync --all-groups
31
+
32
+ - name: Test before release
33
+ run: |
34
+ uv run pytest
35
+
36
+ - name: Bootstrap initial semantic-release tag
37
+ env:
38
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
39
+ run: |
40
+ if ! git tag -l "v*" | grep -q .; then
41
+ echo "No semantic-release tags found. Bootstrapping v0.0.0"
42
+ git tag v0.0.0
43
+ git push origin v0.0.0
44
+ else
45
+ echo "Existing semantic-release tags found. Skipping bootstrap."
46
+ fi
47
+
48
+ - name: Semantic release version
49
+ env:
50
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
51
+ run: uv run semantic-release version
52
+
53
+ - name: Publish to PyPI
54
+ env:
55
+ PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
56
+ run: |
57
+ if ls dist/*.whl >/dev/null 2>&1; then
58
+ uv publish --token "$PYPI_TOKEN" dist/*
59
+ else
60
+ echo "No new release artifacts produced; skipping PyPI publish."
61
+ fi
@@ -0,0 +1,9 @@
1
+ .venv/
2
+ __pycache__/
3
+ .pytest_cache/
4
+ .mypy_cache/
5
+ .ruff_cache/
6
+ dist/
7
+ build/
8
+ *.pyc
9
+ scripts/sync_types.py
@@ -0,0 +1,142 @@
1
+ # Architect Overview — norbix-python SDK
2
+
3
+ > Author role: Python Architect (20+ years).
4
+ > Scope: developer UX of the Python SDK — how config is initiated, how the library feels when imported and used in real scripts.
5
+ > Reviewed paths: `src/norbix_python/__init__.py`, `src/norbix_python/client.py`, `src/norbix_python/transport.py`, `src/norbix_python/errors.py`, `src/norbix_python/api/*.py`, `src/norbix_python/hub/*.py`, `tests/*.py`, `pyproject.toml`, `README.md`.
6
+
7
+ ---
8
+
9
+ ## Suggestions list (sorted by impact)
10
+
11
+ ### Naming and Python idioms
12
+
13
+ 1. **Method names are camelCase, not snake_case.** `findOne`, `getDatabaseSchemas`, `deleteMany` look like JavaScript / C#. Python community uses `find_one`, `get_database_schemas`, `delete_many`. PyMongo, boto3, requests, stripe, openai — all use snake_case. This is the single biggest UX issue.
14
+ 2. **`LoginCredentials` fields use camelCase (`userName`).** Should be `user_name` with a serialization alias for the wire format.
15
+ 3. **Module class names like `DatabaseModule` are noisy.** `Database`, `Files`, `Ai` is enough. Users do not write these names anyway.
16
+
17
+ ### API ergonomics — the "import and use" feeling
18
+
19
+ 4. **Every method takes one big `dict[str, Any]`.** No autocomplete, no type hints, no IDE help. User cannot tell which keys are path parameters, which are query, which are body.
20
+ - Now: `db.findOne({"collectionName": "orders", "id": "123"})`
21
+ - Better: `db.find_one("orders", id="123")` or `db.collection("orders").find_one("123")`
22
+ 5. **No fluent / resource-oriented API.** Best Python SDKs feel like: `s3.objects("bucket").list()`, `db["orders"].find_one(id)`. Norbix forces you to build a dict every call.
23
+ 6. **Return type is always `Any`.** README itself shows the pain:
24
+ ```python
25
+ items = response.get("results", []) if isinstance(response, dict) else []
26
+ ```
27
+ This is a code smell. Return Pydantic models or at minimum `TypedDict`.
28
+ 7. **No `download()` / `upload()` / `execute()` style methods.** The `db.FindAll()`, `files.Download()`, `code.Execute()` style is missing. `hub/files.py` only has trigger and integration management (`enableFiles`, `saveFilesIntegration`). There is no real file upload / download / list. There is no `code.execute()` module at all.
29
+
30
+ ### Configuration / initialization UX
31
+
32
+ 8. **Env variables are supported (good).** `NORBIX_PROJECT_ID`, `NORBIX_API_KEY`, etc. are read in `src/norbix_python/client.py` lines 42–54. This part is solid.
33
+ 9. **No `.env` auto-loading.** Most modern SDKs (or their docs) suggest `python-dotenv`. The README does not mention it.
34
+ 10. **No global / default client pattern.** OpenAI and stripe let you do `stripe.api_key = "..."` then `stripe.Customer.list()`. Norbix forces explicit `Norbix(...)` every time. For scripts, a module-level client is friendlier.
35
+ 11. **`project_id` always required.** Even for endpoints that don't need it (`/auth`). This forces users to set it before login is even possible, which is strange.
36
+ 12. **API key and bearer token are mixed under one `Authorization: Bearer` header** (`transport.py` line 74). Most APIs use `Authorization: ApiKey ...` or a separate header for API keys. Mixing them is unclear and risky.
37
+
38
+ ### Architecture / safety
39
+
40
+ 13. **Path parameters are extracted from the request dict by string matching** (`_build_url_and_body`, `transport.py` lines 115–144). This is "magic" — caller does not know which keys vanish from the body. Case-insensitive lookup (`_lookup_case_insensitive`, lines 147–154) makes it worse: `id` and `Id` collide silently.
41
+ 14. **Private attribute mutation.** `client.py` line 81 does `self._transport._cfg.bearer_token = str(...)` — touching a private field. The `set_bearer_token()` method already exists (line 87) but `login()` does not use it. Inconsistent.
42
+ 15. **`NorbixError` is a `@dataclass` AND an `Exception`.** This works in Python 3.10+ but is fragile — `Exception.__init__` is bypassed. A normal class with `__init__` calling `super().__init__(message)` is safer.
43
+ 16. **No `__enter__` / `__exit__`** on `Norbix`. Should support `with Norbix(...) as client:` so the underlying `httpx.Client` is closed automatically.
44
+ 17. **No async client.** `httpx` already gives you `AsyncClient`. Modern Python SDKs ship `AsyncNorbix` for free.
45
+ 18. **No retries, no backoff, no rate-limit handling.** Stripe's SDK retries idempotent calls automatically.
46
+ 19. **No pagination helper.** `find()` returns `{"results": [...]}` but the user has to handle `skip`/`take` themselves. An iterator (`for order in db.orders.iter_all()`) is the standard.
47
+
48
+ ### Tests / docs
49
+
50
+ 20. **Only 3 tests in `tests/test_client.py`.** Coverage of modules (`database`, `files`, `ai`) is zero. The boilerplate of every method is identical — one parametrized test would cover all of them.
51
+ 21. **README example uses `getCurrentUser({})`** but this method is not in `src/norbix_python/api/membership.py`. Either the doc is stale or the method is missing.
52
+ 22. **`per-file-ignores` in `pyproject.toml`** (lines 47–50) disables `E501` and `I001` for all generated modules. This hides real issues. Generated code should still be linted.
53
+
54
+ ---
55
+
56
+ ## Summary
57
+
58
+ The SDK is a thin, generated wrapper over the HTTP API. The transport layer (`src/norbix_python/transport.py`) is clean and the env-variable support in `src/norbix_python/client.py` (lines 42–54) is well done. The **biggest weakness is developer UX** — the SDK feels like a TypeScript library translated to Python rather than a Python library. A senior Python developer using this for the first time will not feel "at home".
59
+
60
+ ### Where it hurts most — config initiation
61
+
62
+ The env-variable story is fine, but the constructor surface in `src/norbix_python/client.py` (lines 27–65) is wide (10+ parameters). A user who only wants `Norbix()` from `.env` is fine, but a user who wants explicit credentials has to pass several keyword arguments. Splitting into `Norbix.from_env()` and `Norbix(api_key=..., project_id=...)` would clarify intent. Adding a top-level helper like:
63
+
64
+ ```python
65
+ import norbix
66
+ norbix.configure(api_key="sk_live_...", project_id="proj_123")
67
+ norbix.db.find_all("orders")
68
+ ```
69
+
70
+ would match the OpenAI / stripe style users expect.
71
+
72
+ ### Where it hurts most — calling style
73
+
74
+ The request style `db.FindAll()`, `files.Download()`, `code.Execute()` is not possible today.
75
+
76
+ Today (from `README.md` lines 46–53):
77
+
78
+ ```python
79
+ response = norbix.api.database.find(
80
+ {"collectionName": "orders", "take": 20, "skip": 0,
81
+ "orderBy": [{"field": "createdAt", "direction": "desc"}]}
82
+ )
83
+ items = response.get("results", []) if isinstance(response, dict) else []
84
+ ```
85
+
86
+ What it should look like (PyMongo / stripe style):
87
+
88
+ ```python
89
+ orders = norbix.db("orders").find_all(take=20, order_by="-createdAt")
90
+ for order in orders:
91
+ print(order.id)
92
+ ```
93
+
94
+ The current style is caused by `src/norbix_python/api/database.py` lines 143–153 where `find` accepts only a dict and returns `Any`. The dict-only signature comes from the code generator. To fix this without rewriting the generator, add a thin **hand-written facade layer** on top of the generated modules — for example `src/norbix_python/db.py` exposing `Collection.find_all()`, `find_one()`, `insert_one()` with typed kwargs, calling the generated `database.find(...)` underneath.
95
+
96
+ ### File operations are missing
97
+
98
+ `src/norbix_python/hub/files.py` only manages triggers and integrations (`enableFiles`, `saveFilesIntegration`, lines 23–177). There is no `upload()`, `download()`, `list()`, `delete_object()`. If the backend supports file storage, the SDK is not exposing it. If it does not, then the module name `files` is misleading.
99
+
100
+ ### Path parameter handling is magical
101
+
102
+ `transport.py` lines 121–134 walks the URL template and pulls keys from the request dict — case-insensitive (`_lookup_case_insensitive`, lines 147–154). The user has no way to tell from the method signature `database.findOne(request)` which dict keys are path parameters (`collectionName`, `id`) and which are body. Promote them to explicit positional arguments in the generated code:
103
+
104
+ ```python
105
+ def find_one(self, collection_name: str, id: str, *, timeout: float | None = None) -> Any:
106
+ ...
107
+ ```
108
+
109
+ ### Auth state is leaky
110
+
111
+ `client.py` line 81 writes directly to `self._transport._cfg.bearer_token` — bypassing `set_bearer_token()` (line 87) which exists for exactly this. Replace with `self.set_bearer_token(str(result["bearerToken"]))`. Also, `transport.py` line 74 sends `api_key` as `Authorization: Bearer ...` together with JWT tokens — most APIs separate these. Add a clear header strategy.
112
+
113
+ ### Errors swallow detail
114
+
115
+ `NorbixError` (`src/norbix_python/errors.py`) is a `@dataclass(Exception)`. It works but is fragile. Convert to a normal exception class with `super().__init__(message)`, keep `code`, `status`, `details` as attributes, and add subclasses (`AuthenticationError`, `RateLimitError`, `NotFoundError`, `ValidationError`) so users can write:
116
+
117
+ ```python
118
+ try:
119
+ norbix.db.find_one("orders", id="123")
120
+ except NotFoundError:
121
+ ...
122
+ except RateLimitError:
123
+ ...
124
+ ```
125
+
126
+ like in stripe and openai SDKs.
127
+
128
+ ### Quality of the plan / generation pipeline
129
+
130
+ The architecture (one `Transport` + one module per resource + namespaces `api` / `hub`) is reasonable and extendable. The `pyproject.toml` is professional — `ruff`, `mypy --strict`, `pytest`, semantic-release. But `tool.ruff.lint.per-file-ignores` (lines 47–50) silences linting for the generated modules — that hides bugs in the very code most users will read.
131
+
132
+ ---
133
+
134
+ ## Top 5 actions, in order
135
+
136
+ 1. **Rename methods to snake_case in the generator.** This alone removes 80% of the "this feels foreign" feeling.
137
+ 2. **Promote path parameters to explicit function arguments.** Stop reading them out of the request dict.
138
+ 3. **Add a hand-written facade** for the most-used resources: `db.collection("orders").find_all()`, `files.upload(path)`, etc. — backed by the generated code.
139
+ 4. **Return typed objects (Pydantic v2 models)**, since you already require Python 3.10+. Stop returning `Any`.
140
+ 5. **Add `__enter__`/`__exit__`, an `AsyncNorbix`, and basic retries on idempotent verbs.**
141
+
142
+ If you do these five, the SDK will feel like a first-class Python library and not a generated transport.
@@ -0,0 +1,58 @@
1
+ # CHANGELOG
2
+
3
+ <!-- version list -->
4
+
5
+ ## v1.1.0 (2026-04-28)
6
+
7
+ ### Features
8
+
9
+ - **pypi**: Rename distribution package to norbix
10
+ ([`2ab5e75`](https://github.com/norbix-code/sdk-python/commit/2ab5e7508f5b465f1b81add49191213c9440a252))
11
+
12
+
13
+ ## v1.0.2 (2026-04-28)
14
+
15
+ ### Bug Fixes
16
+
17
+ - **ci**: Publish python package to pypi via uv
18
+ ([`3ec7ba5`](https://github.com/norbix-code/sdk-python/commit/3ec7ba58c5c0e2ee27330696f022cc251e2068cd))
19
+
20
+
21
+ ## v1.0.1 (2026-04-28)
22
+
23
+ ### Bug Fixes
24
+
25
+ - **ci**: Run semantic-release publish after version
26
+ ([`6deb16d`](https://github.com/norbix-code/sdk-python/commit/6deb16dec02d2c739e216c5a82b72078acdebf7a))
27
+
28
+
29
+ ## v1.0.0 (2026-04-28)
30
+
31
+ ### Bug Fixes
32
+
33
+ - Normalize generated python imports for ruff
34
+ ([`3bb658a`](https://github.com/norbix-code/sdk-python/commit/3bb658a47c96df81825e0cd38cbd418adbcab3e3))
35
+
36
+ - Trigger initial pypi publish
37
+ ([`9d32ddc`](https://github.com/norbix-code/sdk-python/commit/9d32ddcf604920b2ecac84d59f5b5d574071f7c6))
38
+
39
+ - **ci**: Use semantic-release version for pypi publishing
40
+ ([`d2a4a81`](https://github.com/norbix-code/sdk-python/commit/d2a4a816b33ad0c0144fdeacee556a74f35efece))
41
+
42
+ ### Continuous Integration
43
+
44
+ - Normalize generated python modules before drift check
45
+ ([`4e8d920`](https://github.com/norbix-code/sdk-python/commit/4e8d9200d8792b6c5569f71bb18b18267b41e071))
46
+
47
+ - Remove endpoint generation from python pipeline
48
+ ([`aae4e66`](https://github.com/norbix-code/sdk-python/commit/aae4e66d47380c476f79f139f78658642bd8257e))
49
+
50
+ ### Features
51
+
52
+ - Split python clients into api and hub surfaces
53
+ ([`3864f46`](https://github.com/norbix-code/sdk-python/commit/3864f4623ed33c959785cf757c0588eac305ddf1))
54
+
55
+
56
+ ## v0.0.0 (2026-04-28)
57
+
58
+ - Initial Release
norbix-1.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 UAB Isidos
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
norbix-1.1.0/Makefile ADDED
@@ -0,0 +1,37 @@
1
+ PYTHON := python
2
+ UV := uv
3
+
4
+ .PHONY: help sync install lint typecheck test check build release-dry
5
+
6
+ help:
7
+ @echo "Available targets:"
8
+ @echo " make install - install all dependencies with uv"
9
+ @echo " make sync - alias for install"
10
+ @echo " make lint - run ruff"
11
+ @echo " make typecheck - run mypy"
12
+ @echo " make test - run pytest"
13
+ @echo " make check - run lint + typecheck + tests"
14
+ @echo " make build - build wheel/sdist"
15
+ @echo " make release-dry - semantic-release dry run (no publish)"
16
+
17
+ install:
18
+ $(UV) sync --all-groups
19
+
20
+ sync: install
21
+
22
+ lint:
23
+ $(UV) run ruff check .
24
+
25
+ typecheck:
26
+ $(UV) run mypy src
27
+
28
+ test:
29
+ $(UV) run pytest
30
+
31
+ check: lint typecheck test
32
+
33
+ build:
34
+ $(UV) build
35
+
36
+ release-dry:
37
+ $(UV) run semantic-release --noop version
norbix-1.1.0/PKG-INFO ADDED
@@ -0,0 +1,181 @@
1
+ Metadata-Version: 2.4
2
+ Name: norbix
3
+ Version: 1.1.0
4
+ Summary: Official Python SDK for Norbix — split API and Hub clients with flat module access.
5
+ Project-URL: Homepage, https://norbix.dev
6
+ Project-URL: Repository, https://github.com/norbix-dev/norbix-python
7
+ Project-URL: Issues, https://github.com/norbix-dev/norbix-python/issues
8
+ Author: UAB Isidos
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: api,baas,hub,norbix,python,sdk
12
+ Requires-Python: >=3.10
13
+ Requires-Dist: httpx>=0.27.0
14
+ Requires-Dist: pydantic>=2.0
15
+ Description-Content-Type: text/markdown
16
+
17
+ # norbix-python
18
+
19
+ [![CI](https://github.com/norbix-dev/norbix-python/actions/workflows/ci.yml/badge.svg)](https://github.com/norbix-dev/norbix-python/actions/workflows/ci.yml)
20
+ [![PyPI](https://img.shields.io/pypi/v/norbix.svg)](https://pypi.org/project/norbix/)
21
+ [![Python](https://img.shields.io/badge/python-%3E=3.10-blue)](https://python.org)
22
+ [![License](https://img.shields.io/pypi/l/norbix.svg)](./LICENSE)
23
+
24
+ Official Python SDK for [Norbix](https://norbix.dev).
25
+ Use split clients with flat module access:
26
+
27
+ - `NorbixApi` for API scope (`client.database`, `client.membership`, ...)
28
+ - `NorbixHub` for Hub scope (`client.database`, `client.account`, ...)
29
+
30
+ ## Install
31
+
32
+ ```bash
33
+ uv add norbix
34
+ ```
35
+
36
+ Optional: load `.env` in apps with `python-dotenv` (`load_dotenv()` before constructing `Norbix()`).
37
+
38
+ ## Quickstart
39
+
40
+ ```python
41
+ from norbix_python import NorbixApi
42
+
43
+ # Service mode
44
+ norbix = NorbixApi(api_key="<api_key>", project_id="proj_123")
45
+
46
+ norbix.database.find("orders", take=20, skip=0, orderBy=[{"field": "createdAt", "direction": "desc"}])
47
+ ```
48
+
49
+ ```python
50
+ # User mode
51
+ from norbix_python import LoginCredentials, NorbixApi
52
+
53
+ norbix = NorbixApi(project_id="proj_123")
54
+ norbix.login(LoginCredentials(user_name="alice@team.io", password="secret"))
55
+ norbix.database.find("orders", take=10)
56
+ ```
57
+
58
+ ### Async client
59
+
60
+ ```python
61
+ from norbix_python import AsyncNorbix
62
+
63
+ async def main() -> None:
64
+ async with AsyncNorbix(api_key="...", project_id="proj_123") as client:
65
+ await client.api.echo.echo()
66
+
67
+ # asyncio.run(main())
68
+ ```
69
+
70
+ ## Real-world examples
71
+
72
+ ### 1) List recent orders (API scope)
73
+
74
+ ```python
75
+ from norbix_python import DatabaseFindResult, NorbixApi, NorbixError
76
+
77
+ norbix = NorbixApi(api_key="sk_live_xxx", project_id="proj_123")
78
+
79
+ try:
80
+ raw = norbix.database.find("orders", take=20, skip=0, orderBy=[{"field": "createdAt", "direction": "desc"}])
81
+ typed = DatabaseFindResult.model_validate(raw) if isinstance(raw, dict) else DatabaseFindResult()
82
+ items = typed.results
83
+ print(f"Fetched {len(items)} orders")
84
+ except NorbixError as exc:
85
+ print(exc.code, exc.status, exc.message)
86
+ ```
87
+
88
+ ### 2) Login as user and load profile
89
+
90
+ ```python
91
+ from norbix_python import LoginCredentials, NorbixApi
92
+
93
+ norbix = NorbixApi(project_id="proj_123")
94
+
95
+ auth = norbix.login(LoginCredentials(user_name="alice@team.io", password="secret"))
96
+ print("Logged in, token prefix:", str(auth.get("bearerToken", ""))[:16])
97
+
98
+ users = norbix.membership.get_users()
99
+ print("Users response:", users)
100
+ ```
101
+
102
+ ### 3) Account-scoped Hub call (requires account_id)
103
+
104
+ ```python
105
+ from norbix_python import NorbixHub
106
+
107
+ norbix = NorbixHub(
108
+ api_key="sk_live_xxx",
109
+ project_id="proj_123",
110
+ account_id="acc_456", # required for account-scoped endpoints
111
+ )
112
+
113
+ account = norbix.hub.account.get_account_profile()
114
+ print(account)
115
+ ```
116
+
117
+ ## Breaking changes (recent major-style refresh)
118
+
119
+ - Methods use **snake_case** (`find_one`, `get_database_schemas`) instead of camelCase.
120
+ - Path parameters are **positional or keyword** arguments (for example `find("orders", ...)`,
121
+ `find_one("orders", id)`). Remaining query/body fields are passed as keyword args.
122
+ - Use **typed errors** where helpful: `AuthenticationError`, `NotFoundError`, `RateLimitError`,
123
+ `ValidationError` (all subclass `NorbixError`).
124
+
125
+ ## Authentication
126
+
127
+ - API key: set `api_key` or `NORBIX_API_KEY`
128
+ - JWT bearer: set `bearer_token`, `NORBIX_BEARER_TOKEN`, or call `norbix.login(...)`
129
+ - If both are configured, bearer token wins
130
+ - If neither is configured, SDK raises `NORBIX_NOT_AUTHENTICATED`
131
+
132
+ API keys and JWTs are sent as `Authorization: Bearer ...` (document your backend expectations).
133
+
134
+ ## Configuration from environment
135
+
136
+ ```bash
137
+ NORBIX_API_KEY=sk_live_...
138
+ NORBIX_PROJECT_ID=proj_123
139
+ NORBIX_ACCOUNT_ID=acc_456
140
+ NORBIX_API_URL=https://api.norbix.ai
141
+ NORBIX_HUB_URL=https://hub.norbix.ai
142
+ ```
143
+
144
+ ```python
145
+ norbix = NorbixApi() # reads from environment when values omitted
146
+ ```
147
+
148
+ ## Project vs account scope
149
+
150
+ - `project_id` is required (set explicitly or via env).
151
+ - `account_id` is optional
152
+ - Account-scoped Hub methods raise `NORBIX_ACCOUNT_SCOPE_REQUIRED` if `account_id` is not configured
153
+
154
+ ## SDK maintenance
155
+
156
+ Regenerate API and Hub modules from DTO stubs:
157
+
158
+ ```bash
159
+ uv run python scripts/generate_endpoints.py
160
+ ```
161
+
162
+ This refreshes `src/norbix_python/api/`, `hub/`, matching tests under `tests/api` and `tests/hub`, and docs under `docs/`.
163
+
164
+ ## Development
165
+
166
+ ```bash
167
+ uv sync
168
+ uv run ruff check .
169
+ uv run mypy src
170
+ uv run pytest
171
+ ```
172
+
173
+ ## Releases
174
+
175
+ Pushes to `main`, `next`, and `beta` run
176
+ [python-semantic-release](https://python-semantic-release.readthedocs.io/)
177
+ and publish to PyPI.
178
+
179
+ ## License
180
+
181
+ MIT