trigora 1.0.0__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.
- trigora/__init__.py +13 -0
- trigora/sdk.py +54 -0
- trigora-1.0.0.dist-info/METADATA +105 -0
- trigora-1.0.0.dist-info/RECORD +6 -0
- trigora-1.0.0.dist-info/WHEEL +5 -0
- trigora-1.0.0.dist-info/top_level.txt +1 -0
trigora/__init__.py
ADDED
trigora/sdk.py
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Callable
|
|
4
|
+
from typing import TypeVar
|
|
5
|
+
|
|
6
|
+
T = TypeVar("T")
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def _require_runtime() -> None:
|
|
10
|
+
raise RuntimeError(
|
|
11
|
+
"Durable primitives can only run inside a Trigora execution. Start the program with the Trigora client while `trigora dev` is running."
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def program(fn: T) -> T:
|
|
16
|
+
return fn
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def effect(name: str, fn: Callable[[], T]) -> T:
|
|
20
|
+
if not isinstance(name, str) or not name.strip():
|
|
21
|
+
raise ValueError("effect(name, fn) requires a non-empty string key.")
|
|
22
|
+
if not callable(fn):
|
|
23
|
+
raise TypeError("effect(name, fn) requires a function.")
|
|
24
|
+
_require_runtime()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def wait_for_event(name: str) -> object:
|
|
28
|
+
if not isinstance(name, str) or not name.strip():
|
|
29
|
+
raise ValueError("wait_for_event(name) requires a non-empty string.")
|
|
30
|
+
_require_runtime()
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def sleep(duration: float | str) -> None:
|
|
34
|
+
del duration
|
|
35
|
+
_require_runtime()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def invoke(name: str, input: object | None = None) -> object:
|
|
39
|
+
del input
|
|
40
|
+
if not isinstance(name, str) or not name.strip():
|
|
41
|
+
raise ValueError("invoke(name, input) requires a non-empty program name.")
|
|
42
|
+
_require_runtime()
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def gather(*awaitables: object) -> object:
|
|
46
|
+
if not awaitables:
|
|
47
|
+
raise ValueError("gather() requires at least one awaitable.")
|
|
48
|
+
_require_runtime()
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def race(*awaitables: object) -> object:
|
|
52
|
+
if not awaitables:
|
|
53
|
+
raise ValueError("race() requires at least one awaitable.")
|
|
54
|
+
_require_runtime()
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: trigora
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Authoring package for Trigora durable programs
|
|
5
|
+
Author: Trigora
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://trigora.dev
|
|
8
|
+
Project-URL: Repository, https://github.com/trigora-dev/trigora-python
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Requires-Python: >=3.10
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
Requires-Dist: tcc-engine==26.10.2
|
|
14
|
+
Requires-Dist: trigora-cli==1.0.0
|
|
15
|
+
|
|
16
|
+
# trigora
|
|
17
|
+
|
|
18
|
+
Python authoring SDK for Trigora durable programs.
|
|
19
|
+
|
|
20
|
+
Build long-running programs that can call external systems, wait for events, sleep durably, invoke child executions, and recover from committed continuation state.
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install trigora
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Quick example
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
from trigora import effect, program, wait_for_event
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@program
|
|
35
|
+
async def approval():
|
|
36
|
+
result = await effect("generate", lambda: 42)
|
|
37
|
+
review = await wait_for_event("approved")
|
|
38
|
+
return {"result": result, "review": review}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Run it locally with:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
trigora dev
|
|
45
|
+
trigora start approval
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Program entry
|
|
49
|
+
|
|
50
|
+
Trigora discovers programs from the paths configured in `trigora.toml`:
|
|
51
|
+
|
|
52
|
+
```toml
|
|
53
|
+
[project]
|
|
54
|
+
name = "my-project"
|
|
55
|
+
programs = ["src/**/*.py"]
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Each matching file has one `@program` async function. That function is the program entry. The program id is the file name, so `src/approval.py` starts with `trigora start approval`.
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
@program
|
|
62
|
+
async def research(topic, depth="full"):
|
|
63
|
+
return {"topic": topic, "depth": depth}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The Python frontend implements `py.subset.v1`.
|
|
67
|
+
|
|
68
|
+
Program parameters are plain. A default must be a constant: `None`, a bool, a finite number, or a string. A missing argument uses that default. Extra arguments are rejected.
|
|
69
|
+
|
|
70
|
+
`*args`, keyword-only parameters, and positional-only parameters are not supported.
|
|
71
|
+
|
|
72
|
+
A bare `async def` is not a program entry.
|
|
73
|
+
|
|
74
|
+
## Durable primitives
|
|
75
|
+
|
|
76
|
+
- `effect(name, fn)` — run a durable external effect
|
|
77
|
+
- `sleep(duration)` — suspend on a durable timer
|
|
78
|
+
- `wait_for_event(name)` — wait for an external event
|
|
79
|
+
- `invoke(program, input)` — invoke a durable child execution
|
|
80
|
+
- `gather(*awaitables)` — wait for every durable branch
|
|
81
|
+
- `race(*awaitables)` — wait for the first durable branch
|
|
82
|
+
|
|
83
|
+
Effect keys and event names are string literals in the current Python subset.
|
|
84
|
+
|
|
85
|
+
## Local development
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
trigora init
|
|
89
|
+
trigora dev
|
|
90
|
+
trigora start approval
|
|
91
|
+
trigora send <execution> approved --payload '"ok"'
|
|
92
|
+
trigora result <execution>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Programs execute through the Trigora runtime rather than by running the source file directly.
|
|
96
|
+
|
|
97
|
+
## Learn more
|
|
98
|
+
|
|
99
|
+
- [Quickstart](https://trigora.dev/docs/quickstart)
|
|
100
|
+
- [Trigora documentation](https://trigora.dev/docs)
|
|
101
|
+
- [TCC Python semantics](https://github.com/trigora-dev/tcc-engine/blob/main/spec/python-subset.md)
|
|
102
|
+
|
|
103
|
+
## License
|
|
104
|
+
|
|
105
|
+
MIT © 2026 Trigora, Inc.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
trigora/__init__.py,sha256=XiG7-veFcDhmJ7RLMvJDc7X8q27gswaNODkUFzjqH1o,233
|
|
2
|
+
trigora/sdk.py,sha256=eVGO_U49QNb33eFeupbAzsrTCK-n3sP5-T2ioSH81BI,1501
|
|
3
|
+
trigora-1.0.0.dist-info/METADATA,sha256=l3spbZA6uRwjyY5RkWrR-G_26kg5lbjmqKkCXdZKwS8,2854
|
|
4
|
+
trigora-1.0.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
5
|
+
trigora-1.0.0.dist-info/top_level.txt,sha256=LCCNkZ4F9lAMKCBEGO-s4EDBZbL-q_1Mm2u42TS2d5E,8
|
|
6
|
+
trigora-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
trigora
|