encore-dev 2.0.0a14__tar.gz → 2.0.0a16__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.
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/PKG-INFO +24 -217
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/README.md +23 -216
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/config/__init__.py +1 -1
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/pyproject.toml +1 -1
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/pyproject.toml.orig +1 -1
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/__init__.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/config/_build.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/config/_markers.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/cron/__init__.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/env/__init__.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/internal/__init__.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/internal/_loader.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/internal/_native.pyi +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/internal/lazy.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/internal/runtime.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/internal/startup.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/logs/__init__.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/logs/_console.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/logs/_runtime.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/metrics/__init__.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/metrics/_instrument.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/metrics/_metrics.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/metrics/_provider.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/pubsub/__init__.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/py.typed +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/secrets/__init__.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/services/__init__.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/shutdown/__init__.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/storage/__init__.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/storage/objects/__init__.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/storage/postgres/__init__.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/storage/redis/__init__.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/storage/redis/_base.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/storage/redis/_responses.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/storage/redis/_values.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/storage/redis/bitmap.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/storage/redis/generic.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/storage/redis/geo.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/storage/redis/hash.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/storage/redis/json.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/storage/redis/list.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/storage/redis/pubsub.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/storage/redis/set.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/storage/redis/sorted_set.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/storage/redis/stream.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/storage/redis/string.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/tracing/__init__.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/tracing/_context.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/tracing/_encode.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/tracing/_provider.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/tracing/_span.py +0 -0
- {encore_dev-2.0.0a14 → encore_dev-2.0.0a16}/encore/tracing/_tracer.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: encore-dev
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.0a16
|
|
4
4
|
Summary: Encore SDK for Python — infrastructure resources
|
|
5
5
|
Author: Encore
|
|
6
6
|
License: MPL-2.0
|
|
@@ -15,16 +15,29 @@ Description-Content-Type: text/markdown
|
|
|
15
15
|
|
|
16
16
|
The Python SDK for [Encore](https://encore.dev) — **infrastructure resources only**.
|
|
17
17
|
|
|
18
|
-
The distribution is named `encore-dev`; Python code imports it as `encore`.
|
|
19
|
-
|
|
20
18
|
Declare infrastructure (SQL databases, pub/sub topics & subscriptions, object
|
|
21
19
|
storage buckets, Redis databases, cron jobs, metrics, secrets) as module-level variables.
|
|
22
|
-
Encore
|
|
23
|
-
|
|
24
|
-
infrastructure at run time.
|
|
20
|
+
Encore discovers these declarations, provisions the resources, and connects your
|
|
21
|
+
application to them at runtime.
|
|
25
22
|
|
|
26
23
|
Services are declared by the language-agnostic `encore.service.json` file, not in
|
|
27
|
-
Python
|
|
24
|
+
Python. Use the SDK with your preferred Python web framework.
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
Requires Python 3.9 or later. Install from PyPI with pip:
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
python -m pip install encore-dev
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Or add it to a uv project:
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
uv add encore-dev
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Declare resources
|
|
28
41
|
|
|
29
42
|
```python
|
|
30
43
|
from encore import pubsub, secrets
|
|
@@ -91,7 +104,7 @@ select `read()`, `write()`, or `admin()` before handing it to another function.
|
|
|
91
104
|
Direct database operations infer writer permissions. Reference creation records
|
|
92
105
|
reader, writer, or admin permissions at that call site.
|
|
93
106
|
|
|
94
|
-
|
|
107
|
+
Handles share the database's pool. A `read()` handle runs on
|
|
95
108
|
read-only connections, so its writes fail with SQLSTATE 25006 and its
|
|
96
109
|
transactions are read-only; it reads from the database's read-only pool on a
|
|
97
110
|
replica if the runtime config has one, unless `primary=True` is set.
|
|
@@ -122,11 +135,6 @@ async def first_order():
|
|
|
122
135
|
return row
|
|
123
136
|
```
|
|
124
137
|
|
|
125
|
-
Native Postgres integration tests can be enabled with
|
|
126
|
-
`ENCORE_PYTHON_POSTGRES_TEST_HOST=host:port`. They expect an isolated Postgres
|
|
127
|
-
instance with database/user `postgres` and password `encore-test`, and create and
|
|
128
|
-
remove a temporary schema.
|
|
129
|
-
|
|
130
138
|
## Pub/Sub payloads
|
|
131
139
|
|
|
132
140
|
Use `pubsub.Subscription[T]` to choose how payloads are decoded. Encore validates
|
|
@@ -303,94 +311,9 @@ If cleanup panics after the deadline has already recorded `Timeout`, the core
|
|
|
303
311
|
logs the failure and preserves `Timeout` as the reported result. A timeout is
|
|
304
312
|
not evidence that all cleanup operations eventually succeeded.
|
|
305
313
|
|
|
306
|
-
## Packaging
|
|
307
|
-
|
|
308
|
-
`encore-dev` contains the Python SDK and is built with uv:
|
|
309
|
-
|
|
310
|
-
```sh
|
|
311
|
-
uv build sdk/py/infra
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
For release packaging, stage the SDK and stamp its version without changing the
|
|
315
|
-
checked-in manifest:
|
|
316
|
-
|
|
317
|
-
```sh
|
|
318
|
-
cargo xtask pack-python --version v2.0.0-alpha.1
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
This writes `encore_dev-2.0.0a1-py3-none-any.whl`, the source distribution, and
|
|
322
|
-
SHA-256 sidecars to `dist/python/` (override with `--output`). Alpha and beta
|
|
323
|
-
versions become `aN` and `bN`; nightly and development versions become `.devN`.
|
|
324
|
-
The command requires uv and the native build prerequisites (including Protoc).
|
|
325
|
-
It builds the native runtime to generate fresh type stubs, but packages only the
|
|
326
|
-
pure Python SDK and does not publish to PyPI.
|
|
327
|
-
|
|
328
|
-
The Rust extension lives in the parent `sdk/py/` directory and is packaged separately by Maturin.
|
|
329
|
-
Its `encore-runtime` wheel is an internal artifact for the CLI, not a dependency
|
|
330
|
-
of the public SDK:
|
|
331
|
-
|
|
332
|
-
```sh
|
|
333
|
-
# With Maturin installed:
|
|
334
|
-
cargo xtask build-py-runtime --release --wheel
|
|
335
|
-
# Optionally select the wheel's target (requires a suitable toolchain):
|
|
336
|
-
cargo xtask build-py-runtime --release --wheel --target aarch64-apple-darwin
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
SDK distributions are written to `sdk/py/infra/dist/`; native wheels go to
|
|
340
|
-
`sdk/py/dist/`.
|
|
341
|
-
|
|
342
|
-
## Building locally
|
|
343
|
-
|
|
344
|
-
From the repository root:
|
|
345
|
-
|
|
346
|
-
```sh
|
|
347
|
-
cargo xtask build-py-runtime
|
|
348
|
-
```
|
|
349
|
-
|
|
350
|
-
This stages `_encore_runtime` inside `infra/encore/` for the SDK's local loader,
|
|
351
|
-
and in `runtimes/python/` for the development CLI. It also regenerates
|
|
352
|
-
`encore/internal/_native.pyi` from the compiled extension. Edit native signatures
|
|
353
|
-
in Rust, then rerun this command to update the stub. An editable install of the SDK
|
|
354
|
-
can then load the native extension without setting `PYTHONPATH`:
|
|
355
|
-
|
|
356
|
-
```sh
|
|
357
|
-
uv run --project sdk/py/infra pytest sdk/py/infra/tests
|
|
358
|
-
```
|
|
359
|
-
|
|
360
|
-
The CLI sets `ENCORE_PYTHON_RUNTIME_DIR` for runs, tests, and exec commands.
|
|
361
|
-
The SDK selects the native library using the running interpreter's build ABI:
|
|
362
|
-
standard CPython uses the root `abi3` library; free-threaded Python 3.14 uses
|
|
363
|
-
`cp314t/_encore_runtime.so` (`.pyd` on Windows). This selection is unchanged if
|
|
364
|
-
a free-threaded interpreter temporarily enables its GIL. Unsupported ABIs fail
|
|
365
|
-
with a missing-runtime error instead of falling back to an incompatible library.
|
|
366
|
-
|
|
367
|
-
Build the local free-threaded variant separately:
|
|
368
|
-
|
|
369
|
-
```sh
|
|
370
|
-
cargo xtask build-py-runtime --python-runtime cp314t
|
|
371
|
-
```
|
|
372
|
-
|
|
373
|
-
The default builds `abi3`. Both variants can coexist. Native-only wheel builds
|
|
374
|
-
(`--wheel`) continue to use maturin's interpreter selection instead.
|
|
375
|
-
|
|
376
|
-
`ENCORE_PYTHON_RUNTIME_LIB` overrides directory selection with an explicit library.
|
|
377
|
-
An explicit library or directory is authoritative; failures do not fall back.
|
|
378
|
-
Without either variable, the loader searches beside itself and in parent
|
|
379
|
-
and `dist/` directories using the same ABI layout.
|
|
380
|
-
|
|
381
|
-
Configure the development CLI's `ENCORE_RUNTIMES_PATH` to point at this checkout's
|
|
382
|
-
`runtimes/` directory. Published SDK wheels exclude native libraries; standalone
|
|
383
|
-
use requires a runtime directory or explicit library from the CLI installation.
|
|
384
|
-
|
|
385
|
-
App builds install `encore-dev` and copy the runtime directory, preserving its ABI
|
|
386
|
-
variants for selection by the deployment interpreter. An explicit library override
|
|
387
|
-
is packaged separately and remains authoritative. Cross-platform runtime retrieval
|
|
388
|
-
is not yet supported.
|
|
389
|
-
|
|
390
314
|
## Resource initialization
|
|
391
315
|
|
|
392
|
-
Importing the SDK synchronously initializes the
|
|
393
|
-
TypeScript. Run applications through Encore so runtime configuration is available
|
|
316
|
+
Importing the SDK synchronously initializes the Encore runtime. Run applications through Encore so runtime configuration is available
|
|
394
317
|
before imports. Initialization failures surface during import, before normal
|
|
395
318
|
application startup completes.
|
|
396
319
|
|
|
@@ -398,39 +321,12 @@ Buckets, SQL databases, pub/sub topics, and secrets store their declarations and
|
|
|
398
321
|
resolve native handles on first use, caching the results with thread-safe
|
|
399
322
|
initialization. These lookups are synchronous against the already initialized
|
|
400
323
|
runtime. Importing application modules requires the configured runtime and native
|
|
401
|
-
extension.
|
|
402
|
-
|
|
324
|
+
extension. Use `encore test` to run application tests with Encore-managed
|
|
325
|
+
resources.
|
|
403
326
|
|
|
404
327
|
Initialize independently in each worker process. Forking an already initialized
|
|
405
328
|
native runtime is not supported by this startup model.
|
|
406
329
|
|
|
407
|
-
## Linting and formatting
|
|
408
|
-
|
|
409
|
-
From the repository root, lint the SDK and its tests:
|
|
410
|
-
|
|
411
|
-
```sh
|
|
412
|
-
uv run --locked --project sdk/py/infra ruff check sdk/py/infra
|
|
413
|
-
```
|
|
414
|
-
|
|
415
|
-
Add `--fix` to apply safe fixes. The enabled rules check syntax/style errors,
|
|
416
|
-
undefined and unused names, common bug patterns, and Google-style docstrings
|
|
417
|
-
(`E4`, `E7`, `E9`, `F`, `B`, `D`).
|
|
418
|
-
|
|
419
|
-
From the repository root, format the SDK and its tests with Ruff:
|
|
420
|
-
|
|
421
|
-
```sh
|
|
422
|
-
uv run --project sdk/py/infra ruff format sdk/py/infra
|
|
423
|
-
```
|
|
424
|
-
|
|
425
|
-
To check formatting without changing files:
|
|
426
|
-
|
|
427
|
-
```sh
|
|
428
|
-
uv run --project sdk/py/infra ruff format --check sdk/py/infra
|
|
429
|
-
```
|
|
430
|
-
|
|
431
|
-
The generated `_native.pyi` is excluded from linting and formatting because it
|
|
432
|
-
is owned by the PyO3 stub generator. It is still checked by ty.
|
|
433
|
-
|
|
434
330
|
## Metrics
|
|
435
331
|
|
|
436
332
|
Metrics are OpenTelemetry instruments of the meter `encore`, declared at module
|
|
@@ -483,63 +379,6 @@ trace.set_tracer_provider(tracer_provider())
|
|
|
483
379
|
metrics.set_meter_provider(meter_provider())
|
|
484
380
|
```
|
|
485
381
|
|
|
486
|
-
## Documentation style
|
|
487
|
-
|
|
488
|
-
Follow the [Google Python docstring guide](https://google.github.io/styleguide/pyguide.html#docstrings)
|
|
489
|
-
for modules, classes, functions, methods, and Python examples in documentation.
|
|
490
|
-
Start docstrings with a concise summary on the opening triple-double-quote line.
|
|
491
|
-
End the summary with punctuation, keep it within 80 characters, and separate any
|
|
492
|
-
further explanation with a blank line. Use imperative summaries for functions
|
|
493
|
-
("Return the current phase.") and noun phrases for classes and properties.
|
|
494
|
-
|
|
495
|
-
Use `Args:`, `Returns:`, `Yields:`, `Raises:`, and `Attributes:` as appropriate,
|
|
496
|
-
with four-space indentation for entries and continuation lines. Document behavior
|
|
497
|
-
callers need to know: units, defaults, side effects, resource ownership, and
|
|
498
|
-
relevant exceptions. Parameter names must match the signature, including `*args`
|
|
499
|
-
and `**kwargs`; type annotations usually make repeated type descriptions
|
|
500
|
-
unnecessary. Document public data attributes in the class's `Attributes:` section
|
|
501
|
-
and constructor arguments in `__init__`.
|
|
502
|
-
|
|
503
|
-
Simple APIs can use a one-line docstring when the summary and signature explain
|
|
504
|
-
their behavior completely. Omit `Returns:` for functions returning only `None`;
|
|
505
|
-
use `Yields:` for generators, describing each yielded item. For a decorated
|
|
506
|
-
context manager, describe the context manager returned to the caller. Put module
|
|
507
|
-
examples under `Typical usage example:`. Keep README prose and examples consistent
|
|
508
|
-
with these API contracts; Markdown guides retain their normal heading structure.
|
|
509
|
-
|
|
510
|
-
Ruff enforces the Google docstring convention through the existing lint command
|
|
511
|
-
and pre-commit hook. Test docstrings are optional; add them to explain unusual
|
|
512
|
-
setup or behavior rather than repeating test names. Existing test docstrings
|
|
513
|
-
still follow the same formatting rules. Review documentation for accuracy as
|
|
514
|
-
well as formatting: Ruff cannot verify behavioral contracts.
|
|
515
|
-
|
|
516
|
-
## Type checking
|
|
517
|
-
|
|
518
|
-
From the repository root, check the SDK, native stubs, and tests with ty:
|
|
519
|
-
|
|
520
|
-
```sh
|
|
521
|
-
uv run --project sdk/py/infra ty check --project sdk/py/infra
|
|
522
|
-
```
|
|
523
|
-
|
|
524
|
-
The checker uses the minimum Python version from `requires-python` and resolves
|
|
525
|
-
dependencies from the SDK's virtual environment.
|
|
526
|
-
|
|
527
|
-
## Pre-commit hooks
|
|
528
|
-
|
|
529
|
-
From the repository root, install the prek hooks once per checkout:
|
|
530
|
-
|
|
531
|
-
```sh
|
|
532
|
-
uv run --locked --project sdk/py/infra prek install
|
|
533
|
-
```
|
|
534
|
-
|
|
535
|
-
The hooks apply safe Ruff lint fixes, format the SDK, and check it with ty when
|
|
536
|
-
relevant SDK files change. If a hook changes files, stage those changes and commit
|
|
537
|
-
again. All hooks use the same locked tools as CI. To run them manually:
|
|
538
|
-
|
|
539
|
-
```sh
|
|
540
|
-
uv run --locked --project sdk/py/infra prek run --all-files
|
|
541
|
-
```
|
|
542
|
-
|
|
543
382
|
## Object storage
|
|
544
383
|
|
|
545
384
|
Declare a bucket at module scope, then use its async methods:
|
|
@@ -747,35 +586,3 @@ is cancelled.
|
|
|
747
586
|
`db.connection_string` (also available on write handles) returns the direct server
|
|
748
587
|
URL and grants broad read-write access. External clients using that URL do not
|
|
749
588
|
apply Encore's key prefixes or tracing. Read-only handles do not expose this URL.
|
|
750
|
-
|
|
751
|
-
## Testing Postgres
|
|
752
|
-
|
|
753
|
-
Build the native runtime from the repository root:
|
|
754
|
-
|
|
755
|
-
```sh
|
|
756
|
-
cargo xtask build-py-runtime
|
|
757
|
-
```
|
|
758
|
-
|
|
759
|
-
Then run the Postgres tests from `sdk/py/infra`:
|
|
760
|
-
|
|
761
|
-
```sh
|
|
762
|
-
uv sync --locked
|
|
763
|
-
uv run pytest tests/test_sqldb.py tests/test_postgres_runner.py -v
|
|
764
|
-
```
|
|
765
|
-
|
|
766
|
-
The integration runner starts one disposable `postgres:17` Docker container and
|
|
767
|
-
removes it after the suite. To use an existing test server, set
|
|
768
|
-
`ENCORE_PYTHON_POSTGRES_TEST_HOST=localhost:5432`. The server must provide a
|
|
769
|
-
`postgres` database and user with password `encore-test` and schema creation
|
|
770
|
-
privileges. Use a dedicated test server.
|
|
771
|
-
|
|
772
|
-
`tests/test_postgres_runner.py` launches `tests/postgres_integration_suite.py`
|
|
773
|
-
in a separate process to isolate the native runtime configuration. The suite is
|
|
774
|
-
collected explicitly by the runner and excluded from normal pytest discovery
|
|
775
|
-
by its filename.
|
|
776
|
-
Each test and Hypothesis example gets a fresh schema. The suite includes
|
|
777
|
-
parameter round trips, generated transaction and cursor operation sequences,
|
|
778
|
-
and synchronized cancellation regressions. Hypothesis uses deterministic generation and reports minimized failing examples.
|
|
779
|
-
Sequences are repeatable for unchanged tests and the same Hypothesis version.
|
|
780
|
-
Resource cleanup and bounded polling live in `tests/postgres_test_support.py`.
|
|
781
|
-
These integration tests are run locally and are not executed by CI.
|
|
@@ -2,16 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
The Python SDK for [Encore](https://encore.dev) — **infrastructure resources only**.
|
|
4
4
|
|
|
5
|
-
The distribution is named `encore-dev`; Python code imports it as `encore`.
|
|
6
|
-
|
|
7
5
|
Declare infrastructure (SQL databases, pub/sub topics & subscriptions, object
|
|
8
6
|
storage buckets, Redis databases, cron jobs, metrics, secrets) as module-level variables.
|
|
9
|
-
Encore
|
|
10
|
-
|
|
11
|
-
infrastructure at run time.
|
|
7
|
+
Encore discovers these declarations, provisions the resources, and connects your
|
|
8
|
+
application to them at runtime.
|
|
12
9
|
|
|
13
10
|
Services are declared by the language-agnostic `encore.service.json` file, not in
|
|
14
|
-
Python
|
|
11
|
+
Python. Use the SDK with your preferred Python web framework.
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
Requires Python 3.9 or later. Install from PyPI with pip:
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
python -m pip install encore-dev
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Or add it to a uv project:
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
uv add encore-dev
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Declare resources
|
|
15
28
|
|
|
16
29
|
```python
|
|
17
30
|
from encore import pubsub, secrets
|
|
@@ -78,7 +91,7 @@ select `read()`, `write()`, or `admin()` before handing it to another function.
|
|
|
78
91
|
Direct database operations infer writer permissions. Reference creation records
|
|
79
92
|
reader, writer, or admin permissions at that call site.
|
|
80
93
|
|
|
81
|
-
|
|
94
|
+
Handles share the database's pool. A `read()` handle runs on
|
|
82
95
|
read-only connections, so its writes fail with SQLSTATE 25006 and its
|
|
83
96
|
transactions are read-only; it reads from the database's read-only pool on a
|
|
84
97
|
replica if the runtime config has one, unless `primary=True` is set.
|
|
@@ -109,11 +122,6 @@ async def first_order():
|
|
|
109
122
|
return row
|
|
110
123
|
```
|
|
111
124
|
|
|
112
|
-
Native Postgres integration tests can be enabled with
|
|
113
|
-
`ENCORE_PYTHON_POSTGRES_TEST_HOST=host:port`. They expect an isolated Postgres
|
|
114
|
-
instance with database/user `postgres` and password `encore-test`, and create and
|
|
115
|
-
remove a temporary schema.
|
|
116
|
-
|
|
117
125
|
## Pub/Sub payloads
|
|
118
126
|
|
|
119
127
|
Use `pubsub.Subscription[T]` to choose how payloads are decoded. Encore validates
|
|
@@ -290,94 +298,9 @@ If cleanup panics after the deadline has already recorded `Timeout`, the core
|
|
|
290
298
|
logs the failure and preserves `Timeout` as the reported result. A timeout is
|
|
291
299
|
not evidence that all cleanup operations eventually succeeded.
|
|
292
300
|
|
|
293
|
-
## Packaging
|
|
294
|
-
|
|
295
|
-
`encore-dev` contains the Python SDK and is built with uv:
|
|
296
|
-
|
|
297
|
-
```sh
|
|
298
|
-
uv build sdk/py/infra
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
For release packaging, stage the SDK and stamp its version without changing the
|
|
302
|
-
checked-in manifest:
|
|
303
|
-
|
|
304
|
-
```sh
|
|
305
|
-
cargo xtask pack-python --version v2.0.0-alpha.1
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
This writes `encore_dev-2.0.0a1-py3-none-any.whl`, the source distribution, and
|
|
309
|
-
SHA-256 sidecars to `dist/python/` (override with `--output`). Alpha and beta
|
|
310
|
-
versions become `aN` and `bN`; nightly and development versions become `.devN`.
|
|
311
|
-
The command requires uv and the native build prerequisites (including Protoc).
|
|
312
|
-
It builds the native runtime to generate fresh type stubs, but packages only the
|
|
313
|
-
pure Python SDK and does not publish to PyPI.
|
|
314
|
-
|
|
315
|
-
The Rust extension lives in the parent `sdk/py/` directory and is packaged separately by Maturin.
|
|
316
|
-
Its `encore-runtime` wheel is an internal artifact for the CLI, not a dependency
|
|
317
|
-
of the public SDK:
|
|
318
|
-
|
|
319
|
-
```sh
|
|
320
|
-
# With Maturin installed:
|
|
321
|
-
cargo xtask build-py-runtime --release --wheel
|
|
322
|
-
# Optionally select the wheel's target (requires a suitable toolchain):
|
|
323
|
-
cargo xtask build-py-runtime --release --wheel --target aarch64-apple-darwin
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
SDK distributions are written to `sdk/py/infra/dist/`; native wheels go to
|
|
327
|
-
`sdk/py/dist/`.
|
|
328
|
-
|
|
329
|
-
## Building locally
|
|
330
|
-
|
|
331
|
-
From the repository root:
|
|
332
|
-
|
|
333
|
-
```sh
|
|
334
|
-
cargo xtask build-py-runtime
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
This stages `_encore_runtime` inside `infra/encore/` for the SDK's local loader,
|
|
338
|
-
and in `runtimes/python/` for the development CLI. It also regenerates
|
|
339
|
-
`encore/internal/_native.pyi` from the compiled extension. Edit native signatures
|
|
340
|
-
in Rust, then rerun this command to update the stub. An editable install of the SDK
|
|
341
|
-
can then load the native extension without setting `PYTHONPATH`:
|
|
342
|
-
|
|
343
|
-
```sh
|
|
344
|
-
uv run --project sdk/py/infra pytest sdk/py/infra/tests
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
The CLI sets `ENCORE_PYTHON_RUNTIME_DIR` for runs, tests, and exec commands.
|
|
348
|
-
The SDK selects the native library using the running interpreter's build ABI:
|
|
349
|
-
standard CPython uses the root `abi3` library; free-threaded Python 3.14 uses
|
|
350
|
-
`cp314t/_encore_runtime.so` (`.pyd` on Windows). This selection is unchanged if
|
|
351
|
-
a free-threaded interpreter temporarily enables its GIL. Unsupported ABIs fail
|
|
352
|
-
with a missing-runtime error instead of falling back to an incompatible library.
|
|
353
|
-
|
|
354
|
-
Build the local free-threaded variant separately:
|
|
355
|
-
|
|
356
|
-
```sh
|
|
357
|
-
cargo xtask build-py-runtime --python-runtime cp314t
|
|
358
|
-
```
|
|
359
|
-
|
|
360
|
-
The default builds `abi3`. Both variants can coexist. Native-only wheel builds
|
|
361
|
-
(`--wheel`) continue to use maturin's interpreter selection instead.
|
|
362
|
-
|
|
363
|
-
`ENCORE_PYTHON_RUNTIME_LIB` overrides directory selection with an explicit library.
|
|
364
|
-
An explicit library or directory is authoritative; failures do not fall back.
|
|
365
|
-
Without either variable, the loader searches beside itself and in parent
|
|
366
|
-
and `dist/` directories using the same ABI layout.
|
|
367
|
-
|
|
368
|
-
Configure the development CLI's `ENCORE_RUNTIMES_PATH` to point at this checkout's
|
|
369
|
-
`runtimes/` directory. Published SDK wheels exclude native libraries; standalone
|
|
370
|
-
use requires a runtime directory or explicit library from the CLI installation.
|
|
371
|
-
|
|
372
|
-
App builds install `encore-dev` and copy the runtime directory, preserving its ABI
|
|
373
|
-
variants for selection by the deployment interpreter. An explicit library override
|
|
374
|
-
is packaged separately and remains authoritative. Cross-platform runtime retrieval
|
|
375
|
-
is not yet supported.
|
|
376
|
-
|
|
377
301
|
## Resource initialization
|
|
378
302
|
|
|
379
|
-
Importing the SDK synchronously initializes the
|
|
380
|
-
TypeScript. Run applications through Encore so runtime configuration is available
|
|
303
|
+
Importing the SDK synchronously initializes the Encore runtime. Run applications through Encore so runtime configuration is available
|
|
381
304
|
before imports. Initialization failures surface during import, before normal
|
|
382
305
|
application startup completes.
|
|
383
306
|
|
|
@@ -385,39 +308,12 @@ Buckets, SQL databases, pub/sub topics, and secrets store their declarations and
|
|
|
385
308
|
resolve native handles on first use, caching the results with thread-safe
|
|
386
309
|
initialization. These lookups are synchronous against the already initialized
|
|
387
310
|
runtime. Importing application modules requires the configured runtime and native
|
|
388
|
-
extension.
|
|
389
|
-
|
|
311
|
+
extension. Use `encore test` to run application tests with Encore-managed
|
|
312
|
+
resources.
|
|
390
313
|
|
|
391
314
|
Initialize independently in each worker process. Forking an already initialized
|
|
392
315
|
native runtime is not supported by this startup model.
|
|
393
316
|
|
|
394
|
-
## Linting and formatting
|
|
395
|
-
|
|
396
|
-
From the repository root, lint the SDK and its tests:
|
|
397
|
-
|
|
398
|
-
```sh
|
|
399
|
-
uv run --locked --project sdk/py/infra ruff check sdk/py/infra
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
Add `--fix` to apply safe fixes. The enabled rules check syntax/style errors,
|
|
403
|
-
undefined and unused names, common bug patterns, and Google-style docstrings
|
|
404
|
-
(`E4`, `E7`, `E9`, `F`, `B`, `D`).
|
|
405
|
-
|
|
406
|
-
From the repository root, format the SDK and its tests with Ruff:
|
|
407
|
-
|
|
408
|
-
```sh
|
|
409
|
-
uv run --project sdk/py/infra ruff format sdk/py/infra
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
To check formatting without changing files:
|
|
413
|
-
|
|
414
|
-
```sh
|
|
415
|
-
uv run --project sdk/py/infra ruff format --check sdk/py/infra
|
|
416
|
-
```
|
|
417
|
-
|
|
418
|
-
The generated `_native.pyi` is excluded from linting and formatting because it
|
|
419
|
-
is owned by the PyO3 stub generator. It is still checked by ty.
|
|
420
|
-
|
|
421
317
|
## Metrics
|
|
422
318
|
|
|
423
319
|
Metrics are OpenTelemetry instruments of the meter `encore`, declared at module
|
|
@@ -470,63 +366,6 @@ trace.set_tracer_provider(tracer_provider())
|
|
|
470
366
|
metrics.set_meter_provider(meter_provider())
|
|
471
367
|
```
|
|
472
368
|
|
|
473
|
-
## Documentation style
|
|
474
|
-
|
|
475
|
-
Follow the [Google Python docstring guide](https://google.github.io/styleguide/pyguide.html#docstrings)
|
|
476
|
-
for modules, classes, functions, methods, and Python examples in documentation.
|
|
477
|
-
Start docstrings with a concise summary on the opening triple-double-quote line.
|
|
478
|
-
End the summary with punctuation, keep it within 80 characters, and separate any
|
|
479
|
-
further explanation with a blank line. Use imperative summaries for functions
|
|
480
|
-
("Return the current phase.") and noun phrases for classes and properties.
|
|
481
|
-
|
|
482
|
-
Use `Args:`, `Returns:`, `Yields:`, `Raises:`, and `Attributes:` as appropriate,
|
|
483
|
-
with four-space indentation for entries and continuation lines. Document behavior
|
|
484
|
-
callers need to know: units, defaults, side effects, resource ownership, and
|
|
485
|
-
relevant exceptions. Parameter names must match the signature, including `*args`
|
|
486
|
-
and `**kwargs`; type annotations usually make repeated type descriptions
|
|
487
|
-
unnecessary. Document public data attributes in the class's `Attributes:` section
|
|
488
|
-
and constructor arguments in `__init__`.
|
|
489
|
-
|
|
490
|
-
Simple APIs can use a one-line docstring when the summary and signature explain
|
|
491
|
-
their behavior completely. Omit `Returns:` for functions returning only `None`;
|
|
492
|
-
use `Yields:` for generators, describing each yielded item. For a decorated
|
|
493
|
-
context manager, describe the context manager returned to the caller. Put module
|
|
494
|
-
examples under `Typical usage example:`. Keep README prose and examples consistent
|
|
495
|
-
with these API contracts; Markdown guides retain their normal heading structure.
|
|
496
|
-
|
|
497
|
-
Ruff enforces the Google docstring convention through the existing lint command
|
|
498
|
-
and pre-commit hook. Test docstrings are optional; add them to explain unusual
|
|
499
|
-
setup or behavior rather than repeating test names. Existing test docstrings
|
|
500
|
-
still follow the same formatting rules. Review documentation for accuracy as
|
|
501
|
-
well as formatting: Ruff cannot verify behavioral contracts.
|
|
502
|
-
|
|
503
|
-
## Type checking
|
|
504
|
-
|
|
505
|
-
From the repository root, check the SDK, native stubs, and tests with ty:
|
|
506
|
-
|
|
507
|
-
```sh
|
|
508
|
-
uv run --project sdk/py/infra ty check --project sdk/py/infra
|
|
509
|
-
```
|
|
510
|
-
|
|
511
|
-
The checker uses the minimum Python version from `requires-python` and resolves
|
|
512
|
-
dependencies from the SDK's virtual environment.
|
|
513
|
-
|
|
514
|
-
## Pre-commit hooks
|
|
515
|
-
|
|
516
|
-
From the repository root, install the prek hooks once per checkout:
|
|
517
|
-
|
|
518
|
-
```sh
|
|
519
|
-
uv run --locked --project sdk/py/infra prek install
|
|
520
|
-
```
|
|
521
|
-
|
|
522
|
-
The hooks apply safe Ruff lint fixes, format the SDK, and check it with ty when
|
|
523
|
-
relevant SDK files change. If a hook changes files, stage those changes and commit
|
|
524
|
-
again. All hooks use the same locked tools as CI. To run them manually:
|
|
525
|
-
|
|
526
|
-
```sh
|
|
527
|
-
uv run --locked --project sdk/py/infra prek run --all-files
|
|
528
|
-
```
|
|
529
|
-
|
|
530
369
|
## Object storage
|
|
531
370
|
|
|
532
371
|
Declare a bucket at module scope, then use its async methods:
|
|
@@ -734,35 +573,3 @@ is cancelled.
|
|
|
734
573
|
`db.connection_string` (also available on write handles) returns the direct server
|
|
735
574
|
URL and grants broad read-write access. External clients using that URL do not
|
|
736
575
|
apply Encore's key prefixes or tracing. Read-only handles do not expose this URL.
|
|
737
|
-
|
|
738
|
-
## Testing Postgres
|
|
739
|
-
|
|
740
|
-
Build the native runtime from the repository root:
|
|
741
|
-
|
|
742
|
-
```sh
|
|
743
|
-
cargo xtask build-py-runtime
|
|
744
|
-
```
|
|
745
|
-
|
|
746
|
-
Then run the Postgres tests from `sdk/py/infra`:
|
|
747
|
-
|
|
748
|
-
```sh
|
|
749
|
-
uv sync --locked
|
|
750
|
-
uv run pytest tests/test_sqldb.py tests/test_postgres_runner.py -v
|
|
751
|
-
```
|
|
752
|
-
|
|
753
|
-
The integration runner starts one disposable `postgres:17` Docker container and
|
|
754
|
-
removes it after the suite. To use an existing test server, set
|
|
755
|
-
`ENCORE_PYTHON_POSTGRES_TEST_HOST=localhost:5432`. The server must provide a
|
|
756
|
-
`postgres` database and user with password `encore-test` and schema creation
|
|
757
|
-
privileges. Use a dedicated test server.
|
|
758
|
-
|
|
759
|
-
`tests/test_postgres_runner.py` launches `tests/postgres_integration_suite.py`
|
|
760
|
-
in a separate process to isolate the native runtime configuration. The suite is
|
|
761
|
-
collected explicitly by the runner and excluded from normal pytest discovery
|
|
762
|
-
by its filename.
|
|
763
|
-
Each test and Hypothesis example gets a fresh schema. The suite includes
|
|
764
|
-
parameter round trips, generated transaction and cursor operation sequences,
|
|
765
|
-
and synchronized cancellation regressions. Hypothesis uses deterministic generation and reports minimized failing examples.
|
|
766
|
-
Sequences are repeatable for unchanged tests and the same Hypothesis version.
|
|
767
|
-
Resource cleanup and bounded polling live in `tests/postgres_test_support.py`.
|
|
768
|
-
These integration tests are run locally and are not executed by CI.
|
|
@@ -59,7 +59,7 @@ Changes:
|
|
|
59
59
|
Files:
|
|
60
60
|
A config's value is written in a file named after it,
|
|
61
61
|
``checkout.config.toml`` (or ``.json``), beside the declaring service's
|
|
62
|
-
``encore.service.json``, or beside ``encore.app`` for a shared or global
|
|
62
|
+
``encore.service.json``, or beside ``encore.app.json`` for a shared or global
|
|
63
63
|
config. Overlays change it for some environments only:
|
|
64
64
|
``checkout.production.config.toml`` for an environment type,
|
|
65
65
|
``checkout.@prod-eu.config.toml`` for one environment, and
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|