encore-dev 2.0.0a15__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.
Files changed (52) hide show
  1. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/PKG-INFO +24 -217
  2. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/README.md +23 -216
  3. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/config/__init__.py +1 -1
  4. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/pyproject.toml +1 -1
  5. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/pyproject.toml.orig +1 -1
  6. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/__init__.py +0 -0
  7. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/config/_build.py +0 -0
  8. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/config/_markers.py +0 -0
  9. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/cron/__init__.py +0 -0
  10. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/env/__init__.py +0 -0
  11. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/internal/__init__.py +0 -0
  12. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/internal/_loader.py +0 -0
  13. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/internal/_native.pyi +0 -0
  14. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/internal/lazy.py +0 -0
  15. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/internal/runtime.py +0 -0
  16. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/internal/startup.py +0 -0
  17. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/logs/__init__.py +0 -0
  18. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/logs/_console.py +0 -0
  19. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/logs/_runtime.py +0 -0
  20. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/metrics/__init__.py +0 -0
  21. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/metrics/_instrument.py +0 -0
  22. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/metrics/_metrics.py +0 -0
  23. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/metrics/_provider.py +0 -0
  24. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/pubsub/__init__.py +0 -0
  25. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/py.typed +0 -0
  26. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/secrets/__init__.py +0 -0
  27. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/services/__init__.py +0 -0
  28. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/shutdown/__init__.py +0 -0
  29. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/storage/__init__.py +0 -0
  30. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/storage/objects/__init__.py +0 -0
  31. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/storage/postgres/__init__.py +0 -0
  32. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/storage/redis/__init__.py +0 -0
  33. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/storage/redis/_base.py +0 -0
  34. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/storage/redis/_responses.py +0 -0
  35. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/storage/redis/_values.py +0 -0
  36. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/storage/redis/bitmap.py +0 -0
  37. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/storage/redis/generic.py +0 -0
  38. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/storage/redis/geo.py +0 -0
  39. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/storage/redis/hash.py +0 -0
  40. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/storage/redis/json.py +0 -0
  41. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/storage/redis/list.py +0 -0
  42. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/storage/redis/pubsub.py +0 -0
  43. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/storage/redis/set.py +0 -0
  44. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/storage/redis/sorted_set.py +0 -0
  45. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/storage/redis/stream.py +0 -0
  46. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/storage/redis/string.py +0 -0
  47. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/tracing/__init__.py +0 -0
  48. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/tracing/_context.py +0 -0
  49. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/tracing/_encode.py +0 -0
  50. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/tracing/_provider.py +0 -0
  51. {encore_dev-2.0.0a15 → encore_dev-2.0.0a16}/encore/tracing/_span.py +0 -0
  52. {encore_dev-2.0.0a15 → 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.0a15
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's parser discovers them for provisioning and wiring, and the native runtime
23
- binding (`encore_sdk_core` over PyO3) connects them to the provisioned
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 — this SDK is infrastructure-only (the counterpart of the Go/TS/Rust SDKs).
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
- Like the Rust SDK, handles share the database's pool. A `read()` handle runs on
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 native Encore runtime, matching
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. SDK unit tests supply a minimal runtime configuration
402
- in `tests/conftest.py`; integration tests use `encore test`.
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's parser discovers them for provisioning and wiring, and the native runtime
10
- binding (`encore_sdk_core` over PyO3) connects them to the provisioned
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 — this SDK is infrastructure-only (the counterpart of the Go/TS/Rust SDKs).
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
- Like the Rust SDK, handles share the database's pool. A `read()` handle runs on
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 native Encore runtime, matching
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. SDK unit tests supply a minimal runtime configuration
389
- in `tests/conftest.py`; integration tests use `encore test`.
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
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "encore-dev"
7
- version = "2.0.0a15"
7
+ version = "2.0.0a16"
8
8
  description = "Encore SDK for Python — infrastructure resources"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "encore-dev"
7
- version = "2.0.0a15"
7
+ version = "2.0.0a16"
8
8
  description = "Encore SDK for Python — infrastructure resources"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"