Skip to content

Commit 73cf6b1

Browse files
authored
Merge branch 'main' into python_314_ci
2 parents 5fb5223 + 13b27be commit 73cf6b1

File tree

19 files changed

+394
-188
lines changed

19 files changed

+394
-188
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ on:
66
- main
77
- "releases/*"
88

9+
env:
10+
COLUMNS: 120
11+
912
jobs:
1013
# Build and test the project
1114
build-lint-test:

README.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,7 @@ starting a workflow with an `int` parameter when it accepts a `str` parameter wo
2525

2626
**Different Activity Types**
2727

28-
The activity worker has been developed to work with `async def`, threaded, and multiprocess activities. While
29-
`async def` activities are the easiest and recommended, care has been taken to make heartbeating and cancellation also
30-
work across threads/processes.
28+
The activity worker has been developed to work with `async def`, threaded, and multiprocess activities. Threaded activities are the initial recommendation, and further guidance can be found in [the docs](https://docs.temporal.io/develop/python/python-sdk-sync-vs-async).
3129

3230
**Custom `asyncio` Event Loop**
3331

@@ -316,10 +314,11 @@ The default data converter supports converting multiple types including:
316314
* Iterables including ones JSON dump may not support by default, e.g. `set`
317315
* [IntEnum, StrEnum](https://docs.python.org/3/library/enum.html) based enumerates
318316
* [UUID](https://docs.python.org/3/library/uuid.html)
317+
* `datetime.datetime`
319318

320319
To use pydantic model instances, see [Pydantic Support](#pydantic-support).
321320

322-
`datetime.date`, `datetime.time`, and `datetime.datetime` can only be used with the Pydantic data converter.
321+
`datetime.date` and `datetime.time` can only be used with the Pydantic data converter.
323322

324323
Although workflows, updates, signals, and queries can all be defined with multiple input parameters, users are strongly
325324
encouraged to use a single `dataclass` or Pydantic model parameter, so that fields with defaults can be easily added

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ dev = [
4949
"twine>=4.0.1,<5",
5050
"ruff>=0.5.0,<0.6",
5151
"maturin>=1.8.2",
52+
"pytest-pretty>=1.3.0",
5253
]
5354

5455
[tool.poe.tasks]

temporalio/bridge/Cargo.lock

Lines changed: 22 additions & 29 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

temporalio/bridge/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ async-trait = "0.1"
2121
futures = "0.3"
2222
log = "0.4"
2323
prost = "0.13"
24-
pyo3 = { version = "0.20", features = ["extension-module", "abi3-py39", "anyhow"] }
25-
pyo3-asyncio = { version = "0.20", features = ["tokio-runtime"] }
26-
pythonize = "0.20"
24+
pyo3 = { version = "0.25", features = ["extension-module", "abi3-py39", "anyhow"] }
25+
pyo3-async-runtimes = { version = "0.25", features = ["tokio-runtime"] }
26+
pythonize = "0.25"
2727
temporal-client = { version = "0.1.0", path = "./sdk-core/client" }
2828
temporal-sdk-core = { version = "0.1.0", path = "./sdk-core/core", features = ["ephemeral-server"] }
2929
temporal-sdk-core-api = { version = "0.1.0", path = "./sdk-core/core-api" }

temporalio/bridge/src/client.rs

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ pub fn connect_client<'a>(
8080
py: Python<'a>,
8181
runtime_ref: &runtime::RuntimeRef,
8282
config: ClientConfig,
83-
) -> PyResult<&'a PyAny> {
83+
) -> PyResult<Bound<'a, PyAny>> {
8484
let opts: ClientOptions = config.try_into()?;
8585
let runtime = runtime_ref.runtime.clone();
8686
runtime_ref.runtime.future_into_py(py, async move {
@@ -126,7 +126,11 @@ impl ClientRef {
126126
self.retry_client.get_client().set_api_key(api_key);
127127
}
128128

129-
fn call_workflow_service<'p>(&self, py: Python<'p>, call: RpcCall) -> PyResult<&'p PyAny> {
129+
fn call_workflow_service<'p>(
130+
&self,
131+
py: Python<'p>,
132+
call: RpcCall,
133+
) -> PyResult<Bound<'p, PyAny>> {
130134
let mut retry_client = self.retry_client.clone();
131135
self.runtime.future_into_py(py, async move {
132136
let bytes = match call.rpc.as_str() {
@@ -361,12 +365,15 @@ impl ClientRef {
361365
)))
362366
}
363367
}?;
364-
let bytes: &[u8] = &bytes;
365-
Ok(Python::with_gil(|py| bytes.into_py(py)))
368+
Ok(bytes)
366369
})
367370
}
368371

369-
fn call_operator_service<'p>(&self, py: Python<'p>, call: RpcCall) -> PyResult<&'p PyAny> {
372+
fn call_operator_service<'p>(
373+
&self,
374+
py: Python<'p>,
375+
call: RpcCall,
376+
) -> PyResult<Bound<'p, PyAny>> {
370377
use temporal_client::OperatorService;
371378

372379
let mut retry_client = self.retry_client.clone();
@@ -403,12 +410,11 @@ impl ClientRef {
403410
)))
404411
}
405412
}?;
406-
let bytes: &[u8] = &bytes;
407-
Ok(Python::with_gil(|py| bytes.into_py(py)))
413+
Ok(bytes)
408414
})
409415
}
410416

411-
fn call_cloud_service<'p>(&self, py: Python<'p>, call: RpcCall) -> PyResult<&'p PyAny> {
417+
fn call_cloud_service<'p>(&self, py: Python<'p>, call: RpcCall) -> PyResult<Bound<'p, PyAny>> {
412418
use temporal_client::CloudService;
413419

414420
let mut retry_client = self.retry_client.clone();
@@ -466,12 +472,11 @@ impl ClientRef {
466472
)))
467473
}
468474
}?;
469-
let bytes: &[u8] = &bytes;
470-
Ok(Python::with_gil(|py| bytes.into_py(py)))
475+
Ok(bytes)
471476
})
472477
}
473478

474-
fn call_test_service<'p>(&self, py: Python<'p>, call: RpcCall) -> PyResult<&'p PyAny> {
479+
fn call_test_service<'p>(&self, py: Python<'p>, call: RpcCall) -> PyResult<Bound<'p, PyAny>> {
475480
let mut retry_client = self.retry_client.clone();
476481
self.runtime.future_into_py(py, async move {
477482
let bytes = match call.rpc.as_str() {
@@ -490,12 +495,11 @@ impl ClientRef {
490495
)))
491496
}
492497
}?;
493-
let bytes: &[u8] = &bytes;
494-
Ok(Python::with_gil(|py| bytes.into_py(py)))
498+
Ok(bytes)
495499
})
496500
}
497501

498-
fn call_health_service<'p>(&self, py: Python<'p>, call: RpcCall) -> PyResult<&'p PyAny> {
502+
fn call_health_service<'p>(&self, py: Python<'p>, call: RpcCall) -> PyResult<Bound<'p, PyAny>> {
499503
let mut retry_client = self.retry_client.clone();
500504
self.runtime.future_into_py(py, async move {
501505
let bytes = match call.rpc.as_str() {
@@ -507,8 +511,7 @@ impl ClientRef {
507511
)))
508512
}
509513
}?;
510-
let bytes: &[u8] = &bytes;
511-
Ok(Python::with_gil(|py| bytes.into_py(py)))
514+
Ok(bytes)
512515
})
513516
}
514517
}
@@ -539,13 +542,13 @@ where
539542
match res {
540543
Ok(resp) => Ok(resp.get_ref().encode_to_vec()),
541544
Err(err) => {
542-
Err(Python::with_gil(move |py| {
545+
Python::with_gil(move |py| {
543546
// Create tuple of "status", "message", and optional "details"
544547
let code = err.code() as u32;
545548
let message = err.message().to_owned();
546-
let details = err.details().into_py(py);
547-
RPCError::new_err((code, message, details))
548-
}))
549+
let details = err.details().into_pyobject(py)?.unbind();
550+
Err(RPCError::new_err((code, message, details)))
551+
})
549552
}
550553
}
551554
}

temporalio/bridge/src/lib.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ mod testing;
88
mod worker;
99

1010
#[pymodule]
11-
fn temporal_sdk_bridge(py: Python, m: &PyModule) -> PyResult<()> {
11+
fn temporal_sdk_bridge(py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
1212
// Client stuff
1313
m.add("RPCError", py.get_type::<client::RPCError>())?;
1414
m.add_class::<client::ClientRef>()?;
@@ -62,7 +62,7 @@ fn connect_client<'a>(
6262
py: Python<'a>,
6363
runtime_ref: &runtime::RuntimeRef,
6464
config: client::ClientConfig,
65-
) -> PyResult<&'a PyAny> {
65+
) -> PyResult<Bound<'a, PyAny>> {
6666
client::connect_client(py, runtime_ref, config)
6767
}
6868

@@ -77,7 +77,7 @@ fn init_runtime(telemetry_config: runtime::TelemetryConfig) -> PyResult<runtime:
7777
}
7878

7979
#[pyfunction]
80-
fn raise_in_thread(py: Python, thread_id: std::os::raw::c_long, exc: &PyAny) -> bool {
80+
fn raise_in_thread(py: Python, thread_id: std::os::raw::c_long, exc: &Bound<'_, PyAny>) -> bool {
8181
runtime::raise_in_thread(py, thread_id, exc)
8282
}
8383

@@ -86,7 +86,7 @@ fn start_dev_server<'a>(
8686
py: Python<'a>,
8787
runtime_ref: &runtime::RuntimeRef,
8888
config: testing::DevServerConfig,
89-
) -> PyResult<&'a PyAny> {
89+
) -> PyResult<Bound<'a, PyAny>> {
9090
testing::start_dev_server(py, runtime_ref, config)
9191
}
9292

@@ -95,7 +95,7 @@ fn start_test_server<'a>(
9595
py: Python<'a>,
9696
runtime_ref: &runtime::RuntimeRef,
9797
config: testing::TestServerConfig,
98-
) -> PyResult<&'a PyAny> {
98+
) -> PyResult<Bound<'a, PyAny>> {
9999
testing::start_test_server(py, runtime_ref, config)
100100
}
101101

@@ -113,6 +113,6 @@ fn new_replay_worker<'a>(
113113
py: Python<'a>,
114114
runtime_ref: &runtime::RuntimeRef,
115115
config: worker::WorkerConfig,
116-
) -> PyResult<&'a PyTuple> {
116+
) -> PyResult<Bound<'a, PyTuple>> {
117117
worker::new_replay_worker(py, runtime_ref, config)
118118
}

0 commit comments

Comments
 (0)