encore-dev 2.0.0a7__py3-none-any.whl
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/__init__.py +43 -0
- encore/cron/__init__.py +50 -0
- encore/internal/__init__.py +1 -0
- encore/internal/_loader.py +79 -0
- encore/internal/_native.pyi +734 -0
- encore/internal/lazy.py +35 -0
- encore/internal/runtime.py +133 -0
- encore/internal/startup.py +24 -0
- encore/logs/__init__.py +19 -0
- encore/logs/_console.py +155 -0
- encore/logs/_runtime.py +56 -0
- encore/meta/__init__.py +228 -0
- encore/metrics/__init__.py +390 -0
- encore/pubsub/__init__.py +425 -0
- encore/py.typed +0 -0
- encore/secrets/__init__.py +139 -0
- encore/shutdown/__init__.py +164 -0
- encore/storage/__init__.py +5 -0
- encore/storage/objects/__init__.py +396 -0
- encore/storage/postgres/__init__.py +737 -0
- encore/storage/redis/__init__.py +200 -0
- encore/storage/redis/_base.py +42 -0
- encore/storage/redis/_responses.py +150 -0
- encore/storage/redis/_values.py +189 -0
- encore/storage/redis/bitmap.py +142 -0
- encore/storage/redis/generic.py +367 -0
- encore/storage/redis/geo.py +508 -0
- encore/storage/redis/hash.py +504 -0
- encore/storage/redis/json.py +614 -0
- encore/storage/redis/list.py +511 -0
- encore/storage/redis/pubsub.py +276 -0
- encore/storage/redis/set.py +570 -0
- encore/storage/redis/sorted_set.py +753 -0
- encore/storage/redis/stream.py +773 -0
- encore/storage/redis/string.py +654 -0
- encore/tracing/__init__.py +19 -0
- encore/tracing/_context.py +27 -0
- encore/tracing/_encode.py +351 -0
- encore/tracing/_provider.py +62 -0
- encore/tracing/_span.py +226 -0
- encore/tracing/_tracer.py +93 -0
- encore_dev-2.0.0a7.dist-info/METADATA +791 -0
- encore_dev-2.0.0a7.dist-info/RECORD +44 -0
- encore_dev-2.0.0a7.dist-info/WHEEL +4 -0
encore/__init__.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""Encore SDK for Python — infrastructure resources.
|
|
2
|
+
|
|
3
|
+
Declare infrastructure (SQL databases, pub/sub, object storage, Redis, cron jobs,
|
|
4
|
+
metrics, secrets) as module-level variables; Encore's parser discovers them for
|
|
5
|
+
provisioning and wiring, and this package's runtime binding (``encore_sdk_core`` over
|
|
6
|
+
PyO3) connects them to the provisioned infrastructure at run time.
|
|
7
|
+
|
|
8
|
+
Services are declared by the language-agnostic ``encore.service.json`` file, not in
|
|
9
|
+
Python — this SDK is infrastructure-only.
|
|
10
|
+
|
|
11
|
+
After importing resource declarations, call ``await encore.start()`` once from
|
|
12
|
+
your async main or framework startup hook. This starts all registered subscription
|
|
13
|
+
handlers on the application's loop and returns so the application can serve.
|
|
14
|
+
|
|
15
|
+
from encore import pubsub, secrets
|
|
16
|
+
from encore.storage import postgres
|
|
17
|
+
|
|
18
|
+
db = postgres.Database("orders", migrations="./migrations")
|
|
19
|
+
events = pubsub.Topic("order-events")
|
|
20
|
+
api_key = secrets.Secret("ApiKey")
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
from . import cron, meta, metrics, pubsub, secrets, shutdown, storage
|
|
26
|
+
from .internal.runtime import EncoreError, run_forever, version
|
|
27
|
+
from .internal.startup import start
|
|
28
|
+
from .meta import app_meta
|
|
29
|
+
|
|
30
|
+
__all__ = [
|
|
31
|
+
"storage",
|
|
32
|
+
"pubsub",
|
|
33
|
+
"cron",
|
|
34
|
+
"meta",
|
|
35
|
+
"metrics",
|
|
36
|
+
"secrets",
|
|
37
|
+
"shutdown",
|
|
38
|
+
"EncoreError",
|
|
39
|
+
"app_meta",
|
|
40
|
+
"run_forever",
|
|
41
|
+
"start",
|
|
42
|
+
"version",
|
|
43
|
+
]
|
encore/cron/__init__.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""Cron jobs.
|
|
2
|
+
|
|
3
|
+
Typical usage example:
|
|
4
|
+
|
|
5
|
+
from encore import cron
|
|
6
|
+
|
|
7
|
+
_ = cron.Job("cleanup", path="/internal/cleanup", title="Nightly cleanup", every="24h")
|
|
8
|
+
|
|
9
|
+
A cron job is a parse-time declaration: the parser discovers it and, when the
|
|
10
|
+
job is due, the platform sends a ``POST`` request for ``path`` to the service
|
|
11
|
+
that declares the job. There is no runtime client.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Job:
|
|
18
|
+
"""A scheduled HTTP request declared at module scope."""
|
|
19
|
+
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
name: str,
|
|
23
|
+
*,
|
|
24
|
+
path: str,
|
|
25
|
+
title: str | None = None,
|
|
26
|
+
every: str | None = None,
|
|
27
|
+
schedule: str | None = None,
|
|
28
|
+
) -> None:
|
|
29
|
+
"""Declare a cron job with exactly one scheduling option.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
name: The cron job's resource name.
|
|
33
|
+
path: The service path to call with POST, starting with a slash.
|
|
34
|
+
title: An optional human-readable title.
|
|
35
|
+
every: The interval between calls, such as "24h". Excludes schedule.
|
|
36
|
+
schedule: A cron expression. Excludes every.
|
|
37
|
+
|
|
38
|
+
Raises:
|
|
39
|
+
ValueError: Both or neither scheduling options are set, or path does
|
|
40
|
+
not start with a slash.
|
|
41
|
+
"""
|
|
42
|
+
if (every is None) == (schedule is None):
|
|
43
|
+
raise ValueError("set exactly one of `every` or `schedule`")
|
|
44
|
+
if not path.startswith("/"):
|
|
45
|
+
raise ValueError("`path` must start with `/`")
|
|
46
|
+
self._name = name
|
|
47
|
+
self._path = path
|
|
48
|
+
self._title = title
|
|
49
|
+
self._every = every
|
|
50
|
+
self._schedule = schedule
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Internal plumbing for the Encore SDK. Not part of the public API."""
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""Loading the native extension without starting the runtime.
|
|
2
|
+
|
|
3
|
+
The log handler uses _encore_runtime for encoding before runtime startup.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import importlib.util
|
|
9
|
+
import os
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
import sys
|
|
12
|
+
import sysconfig
|
|
13
|
+
from typing import TYPE_CHECKING
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _runtime_relative_path() -> Path:
|
|
17
|
+
"""Select the runtime directory using the interpreter ABI.
|
|
18
|
+
|
|
19
|
+
A free-threaded build uses its own ABI even when its GIL is enabled.
|
|
20
|
+
"""
|
|
21
|
+
if sysconfig.get_config_var("Py_GIL_DISABLED"):
|
|
22
|
+
variant = f"cp{sys.version_info.major}{sys.version_info.minor}t"
|
|
23
|
+
filename = (
|
|
24
|
+
"_encore_runtime.pyd" if sys.platform == "win32" else "_encore_runtime.so"
|
|
25
|
+
)
|
|
26
|
+
return Path(variant) / filename
|
|
27
|
+
return Path(
|
|
28
|
+
"_encore_runtime.pyd" if sys.platform == "win32" else "_encore_runtime.abi3.so"
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _load_native():
|
|
33
|
+
explicit = os.environ.get("ENCORE_PYTHON_RUNTIME_LIB")
|
|
34
|
+
root = os.environ.get("ENCORE_PYTHON_RUNTIME_DIR")
|
|
35
|
+
relative = _runtime_relative_path()
|
|
36
|
+
if explicit:
|
|
37
|
+
path = Path(explicit)
|
|
38
|
+
elif root:
|
|
39
|
+
path = Path(root) / relative
|
|
40
|
+
else:
|
|
41
|
+
# Deployment builds preserve an explicit library override separately.
|
|
42
|
+
override = (
|
|
43
|
+
"_encore_runtime_override.pyd"
|
|
44
|
+
if sys.platform == "win32"
|
|
45
|
+
else "_encore_runtime_override.so"
|
|
46
|
+
)
|
|
47
|
+
path = next(
|
|
48
|
+
(
|
|
49
|
+
candidate
|
|
50
|
+
for directory in Path(__file__).resolve().parents
|
|
51
|
+
for base in (directory, directory / "dist")
|
|
52
|
+
for candidate in (base / override, base / relative)
|
|
53
|
+
if candidate.is_file()
|
|
54
|
+
),
|
|
55
|
+
None,
|
|
56
|
+
)
|
|
57
|
+
if path is None or not path.is_file():
|
|
58
|
+
raise ImportError(
|
|
59
|
+
f"Could not find the Encore Python runtime for {relative}"
|
|
60
|
+
+ (f" at {path}" if path is not None else "")
|
|
61
|
+
+ ". Run through the Encore CLI, set ENCORE_PYTHON_RUNTIME_DIR to a "
|
|
62
|
+
"directory containing the matching ABI, or set ENCORE_PYTHON_RUNTIME_LIB "
|
|
63
|
+
"to the native library. For SDK development, run "
|
|
64
|
+
"`cargo xtask build-py-runtime` with the matching --python-runtime."
|
|
65
|
+
)
|
|
66
|
+
spec = importlib.util.spec_from_file_location("_encore_runtime", path)
|
|
67
|
+
if spec is None or spec.loader is None:
|
|
68
|
+
raise ImportError(f"Cannot load the Encore Python runtime from {path}")
|
|
69
|
+
native = importlib.util.module_from_spec(spec)
|
|
70
|
+
spec.loader.exec_module(native)
|
|
71
|
+
sys.modules[spec.name] = native
|
|
72
|
+
return native
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
if TYPE_CHECKING:
|
|
76
|
+
# Stub-only module; the implementation is loaded dynamically below.
|
|
77
|
+
from . import _native # pyright: ignore[reportMissingModuleSource]
|
|
78
|
+
else:
|
|
79
|
+
_native = _load_native()
|