@palettelab/cli 0.3.35 → 0.3.36
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.
- package/README.md +14 -4
- package/docs/python-backend-sdk.md +30 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -275,7 +275,8 @@ async def create_invoice(body: InvoiceIn, ctx: PluginContext = Depends(get_plugi
|
|
|
275
275
|
|
|
276
276
|
Backend SDK features for app-owned data:
|
|
277
277
|
|
|
278
|
-
- `
|
|
278
|
+
- `PluginRouter`, `PluginContext`, and `get_plugin_context` provide the FastAPI route and request-context surface.
|
|
279
|
+
- `PluginContext` exposes `user_id`, `organization_id`, `org_role`, `plugin_id`, `permissions`, `storage`, `ctx.db`, `ctx.data_rooms`, `ctx.members`, `ctx.redis`, `ctx.vector`, `ctx.config`, and `ctx.logger`.
|
|
279
280
|
- `ctx.db` is the full scoped SQLAlchemy `AsyncSession` for app-owned database data.
|
|
280
281
|
- `ctx.repo(Model)` gives org-safe CRUD helpers for app tables.
|
|
281
282
|
- `ctx.data_rooms` gives backend access to Palette Data Rooms without importing platform internals.
|
|
@@ -283,10 +284,19 @@ Backend SDK features for app-owned data:
|
|
|
283
284
|
- `ctx.has_permission("...")`, `ctx.has_any_permission([...])`, and `ctx.has_all_permissions([...])` check declared permissions.
|
|
284
285
|
- `ctx.config_value("key")` and `ctx.require_config("key")` read app install/config values.
|
|
285
286
|
- `ctx.secret("KEY")` reads app secrets from config or environment variables.
|
|
287
|
+
- `get_config(ctx, key)` and `require_config(ctx, key)` are functional config helper forms.
|
|
288
|
+
- `require_permission(permission)`, `KNOWN_PERMISSIONS`, and `is_known_permission(permission)` support route and manifest permission checks.
|
|
286
289
|
- `ctx.redis` gives a Redis-backed, plugin/org-scoped Redis API when `"redis"` is declared in `platform_services`.
|
|
287
290
|
- `ctx.vector` gives a Qdrant-backed, plugin/org-scoped vector API when `"vector"` is declared in `platform_services`.
|
|
288
291
|
- `LifecycleHooks` lets apps define install/update/enable/disable/uninstall hooks.
|
|
289
292
|
- `OrgScopedTable` and `PluginBase` keep app data inside the plugin schema model set.
|
|
293
|
+
- `plugin_safe_id(...)`, `plugin_schema(...)`, `plugin_table_prefix(...)`, and `ensure_org_rls(...)` keep database names and row-level security consistent.
|
|
294
|
+
- `Event` and `subscribe_event(...)` register in-process platform event handlers.
|
|
295
|
+
- `sign_webhook(...)` and `verify_webhook_signature(...)` handle HMAC-SHA256 webhook signing checks.
|
|
296
|
+
- `ToolDefinition` is the base class for custom agent tools.
|
|
297
|
+
- `PluginManifest` and `load_manifest(...)` parse and validate `palette-plugin.json`.
|
|
298
|
+
- `SuccessResponse`, `ErrorResponse`, and `PaginatedResponse` are reusable response schemas.
|
|
299
|
+
- `route_permission_issues(router, public_routes=None)` is the test helper for detecting ungated backend routes.
|
|
290
300
|
|
|
291
301
|
Python backend Data Room example:
|
|
292
302
|
|
|
@@ -524,7 +534,7 @@ await ctx.redis.incr("counter")
|
|
|
524
534
|
await ctx.redis.decr("counter")
|
|
525
535
|
await ctx.redis.scan(prefix="cache:", limit=100)
|
|
526
536
|
|
|
527
|
-
# Redis hashes, lists, sets, sorted sets,
|
|
537
|
+
# Redis hashes, lists, sets, sorted sets, queues, locks
|
|
528
538
|
await ctx.redis.hset("hash", "field", {"value": 1})
|
|
529
539
|
await ctx.redis.hgetall("hash")
|
|
530
540
|
await ctx.redis.lpush("queue", {"job": 1})
|
|
@@ -533,8 +543,8 @@ await ctx.redis.sadd("tags", "red", "blue")
|
|
|
533
543
|
await ctx.redis.smembers("tags")
|
|
534
544
|
await ctx.redis.zadd("scores", {"alice": 10})
|
|
535
545
|
await ctx.redis.zrange("scores", 0, -1, with_scores=True)
|
|
536
|
-
await ctx.redis.
|
|
537
|
-
await ctx.redis.
|
|
546
|
+
await ctx.redis.enqueue("jobs", {"task": "sync"})
|
|
547
|
+
await ctx.redis.dequeue("jobs")
|
|
538
548
|
await ctx.redis.lock("invoice:1", token, ttl=30)
|
|
539
549
|
await ctx.redis.unlock("invoice:1", token)
|
|
540
550
|
|
|
@@ -125,6 +125,34 @@ Available context values:
|
|
|
125
125
|
| `ctx.require_config(key)` | Read required config or raise |
|
|
126
126
|
| `ctx.secret(key, default)` | Read a secret from app config or environment |
|
|
127
127
|
|
|
128
|
+
## 4a. Backend Helper API Index
|
|
129
|
+
|
|
130
|
+
These are the public Python helpers exported by `palette_sdk`.
|
|
131
|
+
|
|
132
|
+
| Helper | Use it for |
|
|
133
|
+
|---|---|
|
|
134
|
+
| `PluginRouter` | FastAPI router mounted under `/api/v1/plugins/<plugin-id>` |
|
|
135
|
+
| `PluginContext`, `get_plugin_context` | Authenticated request context dependency |
|
|
136
|
+
| `MissingSecretError` | Handling missing required declared secrets from `ctx.secret(...)` |
|
|
137
|
+
| `require_permission(permission)` | Route-level permission gate required for protected routes |
|
|
138
|
+
| `KNOWN_PERMISSIONS`, `is_known_permission(...)` | Permission vocabulary checks for manifests/tools |
|
|
139
|
+
| `DataRoomsClient`, `ctx.data_rooms` | Backend Data Room room/folder/file helpers |
|
|
140
|
+
| `OrganizationMembersClient`, `ctx.members` | Current-organization member lookup, invite, and role helpers |
|
|
141
|
+
| `OrgRepository`, `ctx.repo(Model)` | Org-safe convenience CRUD for app-owned models |
|
|
142
|
+
| `PluginBase`, `OrgScopedTable` | SQLAlchemy declarative bases for plugin-owned tables |
|
|
143
|
+
| `ensure_org_rls(op, table)` | Alembic helper that enables org row-level security |
|
|
144
|
+
| `plugin_safe_id(...)`, `plugin_schema(...)`, `plugin_table_prefix(...)` | Manifest id to database-safe naming helpers |
|
|
145
|
+
| `get_config(ctx, key)`, `require_config(ctx, key)` | Functional form of config reads when not using `ctx.config_value(...)` |
|
|
146
|
+
| `LocalRedisService`, `LocalVectorService` | Local `pltt dev` service emulators and test fakes |
|
|
147
|
+
| `PlatformServiceUnavailable`, `UnavailablePlatformService` | Clear errors when an undeclared platform service is used |
|
|
148
|
+
| `LifecycleHooks` | Install/update/enable/disable/uninstall callbacks |
|
|
149
|
+
| `Event`, `subscribe_event(...)` | In-process platform event subscriptions |
|
|
150
|
+
| `sign_webhook(...)`, `verify_webhook_signature(...)` | HMAC-SHA256 webhook signing and verification |
|
|
151
|
+
| `ToolDefinition` | Base class for custom agent tools |
|
|
152
|
+
| `PluginManifest`, `load_manifest(...)` | Typed manifest parsing from `palette-plugin.json` |
|
|
153
|
+
| `SuccessResponse`, `ErrorResponse`, `PaginatedResponse` | Common response schemas for plugin APIs |
|
|
154
|
+
| `route_permission_issues(router, public_routes=None)` | Test helper that reports routes missing `require_permission(...)` |
|
|
155
|
+
|
|
128
156
|
## 5. Permissions
|
|
129
157
|
|
|
130
158
|
Use route-level permission guards for normal APIs:
|
|
@@ -666,8 +694,6 @@ await ctx.redis.zrem("scores", "bob")
|
|
|
666
694
|
|
|
667
695
|
await ctx.redis.enqueue("jobs", {"task": "sync"})
|
|
668
696
|
await ctx.redis.dequeue("jobs")
|
|
669
|
-
await ctx.redis.xadd("events", {"type": "created"})
|
|
670
|
-
await ctx.redis.xread({"events": "0-0"}, count=10)
|
|
671
697
|
await ctx.redis.lock("invoice:1", token, ttl=30)
|
|
672
698
|
await ctx.redis.unlock("invoice:1", token)
|
|
673
699
|
```
|
|
@@ -747,12 +773,10 @@ Frontend code should call backend routes through the platform API helper, not by
|
|
|
747
773
|
hardcoding backend origins.
|
|
748
774
|
|
|
749
775
|
```tsx
|
|
750
|
-
import {
|
|
751
|
-
|
|
752
|
-
const palette = createPaletteClient()
|
|
776
|
+
import { apiFetch } from "@palettelab/sdk"
|
|
753
777
|
|
|
754
778
|
async function loadInvoices() {
|
|
755
|
-
const res = await
|
|
779
|
+
const res = await apiFetch("/api/v1/plugins/finance-tools/invoices")
|
|
756
780
|
return res.json()
|
|
757
781
|
}
|
|
758
782
|
```
|