From f3d1b8511a3ef33b36fa806a9fc56f96a4a70b84 Mon Sep 17 00:00:00 2001 From: Chad Retz Date: Wed, 13 Mar 2024 16:43:11 -0500 Subject: [PATCH] API key client option (#486) Fixes #482 --- temporalio/bridge/Cargo.lock | 453 ++++++++++++++++++++------------ temporalio/bridge/Cargo.toml | 9 +- temporalio/bridge/client.py | 5 + temporalio/bridge/sdk-core | 2 +- temporalio/bridge/src/client.rs | 21 +- temporalio/client.py | 21 ++ temporalio/service.py | 15 ++ tests/api/test_grpc_stub.py | 105 ++++++-- 8 files changed, 414 insertions(+), 217 deletions(-) diff --git a/temporalio/bridge/Cargo.lock b/temporalio/bridge/Cargo.lock index 5337090b..ecef9902 100644 --- a/temporalio/bridge/Cargo.lock +++ b/temporalio/bridge/Cargo.lock @@ -56,16 +56,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] -name = "anyhow" -version = "1.0.79" +name = "anstyle" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" [[package]] -name = "arc-swap" -version = "1.6.0" +name = "anyhow" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "async-stream" @@ -117,9 +117,9 @@ dependencies = [ "bitflags 1.3.2", "bytes", "futures-util", - "http", - "http-body", - "hyper", + "http 0.2.11", + "http-body 0.4.6", + "hyper 0.14.28", "itoa", "matchit", "memchr", @@ -143,8 +143,8 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http", - "http-body", + "http 0.2.11", + "http-body 0.4.6", "mime", "rustversion", "tower-layer", @@ -265,6 +265,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + [[package]] name = "chrono" version = "0.4.31" @@ -367,9 +373,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.14.4" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" dependencies = [ "darling_core", "darling_macro", @@ -377,27 +383,27 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.4" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] name = "darling_macro" -version = "0.14.4" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" dependencies = [ "darling_core", "quote", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] @@ -424,33 +430,33 @@ dependencies = [ [[package]] name = "derive_builder" -version = "0.12.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8" +checksum = "0350b5cb0331628a5916d6c5c0b72e97393b8b6b03b47a9284f4e7f5a405ffd7" dependencies = [ "derive_builder_macro", ] [[package]] name = "derive_builder_core" -version = "0.12.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f" +checksum = "d48cda787f839151732d396ac69e3473923d54312c070ee21e9effcaa8ca0b1d" dependencies = [ "darling", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] name = "derive_builder_macro" -version = "0.12.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e" +checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b" dependencies = [ "derive_builder_core", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] @@ -466,12 +472,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "difflib" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" - [[package]] name = "digest" version = "0.10.7" @@ -506,18 +506,18 @@ dependencies = [ [[package]] name = "enum-iterator" -version = "1.4.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7add3873b5dd076766ee79c8e406ad1a472c385476b9e38849f8eec24f1be689" +checksum = "600536cfe9e2da0820aa498e570f6b2b9223eec3ce2f835c8ae4861304fa4794" dependencies = [ "enum-iterator-derive", ] [[package]] name = "enum-iterator-derive" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eecf8589574ce9b895052fa12d69af7a233f99e6107f5cb8dd1044f2a17bfdcb" +checksum = "03cdc46ec28bd728e67540c528013c6a10eb69a02eb31078a1bda695438cbfb8" dependencies = [ "proc-macro2", "quote", @@ -595,15 +595,6 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "float-cmp" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" -dependencies = [ - "num-traits", -] - [[package]] name = "fnv" version = "1.0.7" @@ -784,16 +775,35 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.22" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.11", + "indexmap 2.1.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" +checksum = "31d030e59af851932b72ceebadf4a2b5986dba4c3b99dd2493f8273a0f151943" dependencies = [ "bytes", "fnv", "futures-core", "futures-sink", "futures-util", - "http", + "http 1.1.0", "indexmap 2.1.0", "slab", "tokio", @@ -858,6 +868,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http-body" version = "0.4.6" @@ -865,7 +886,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http", + "http 0.2.11", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +dependencies = [ + "bytes", + "futures-core", + "http 1.1.0", + "http-body 1.0.0", "pin-project-lite", ] @@ -891,9 +935,9 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", - "http", - "http-body", + "h2 0.3.24", + "http 0.2.11", + "http-body 0.4.6", "httparse", "httpdate", "itoa", @@ -905,6 +949,26 @@ dependencies = [ "want", ] +[[package]] +name = "hyper" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2 0.4.2", + "http 1.1.0", + "http-body 1.0.0", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", +] + [[package]] name = "hyper-rustls" version = "0.24.2" @@ -912,11 +976,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", - "http", - "hyper", - "rustls", + "http 0.2.11", + "hyper 0.14.28", + "rustls 0.21.10", "tokio", - "tokio-rustls", + "tokio-rustls 0.24.1", ] [[package]] @@ -925,12 +989,28 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ - "hyper", + "hyper 0.14.28", "pin-project-lite", "tokio", "tokio-io-timeout", ] +[[package]] +name = "hyper-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +dependencies = [ + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "hyper 1.2.0", + "pin-project-lite", + "socket2", + "tokio", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -1005,18 +1085,18 @@ checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "itertools" -version = "0.10.5" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" dependencies = [ "either", ] [[package]] name = "itertools" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" dependencies = [ "either", ] @@ -1053,9 +1133,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.152" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "linux-raw-sys" @@ -1081,9 +1161,9 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "lru" -version = "0.11.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a83fb7698b3643a0e34f9ae6f2e8f0178c0fd42f8b59d493aa271ff3a5bf21" +checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" dependencies = [ "hashbrown 0.14.3", ] @@ -1155,9 +1235,9 @@ dependencies = [ [[package]] name = "mockall" -version = "0.11.4" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c84490118f2ee2d74570d114f3d0493cbf02790df303d2707606c3e14e07c96" +checksum = "43766c2b5203b10de348ffe19f7e54564b64f3d6018ff7648d1e2d6d3a0f0a48" dependencies = [ "cfg-if", "downcast", @@ -1170,14 +1250,14 @@ dependencies = [ [[package]] name = "mockall_derive" -version = "0.11.4" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ce75669015c4f47b289fd4d4f56e894e4c96003ffdf3ac51313126f94c6cbb" +checksum = "af7cbce79ec385a1d4f54baa90a76401eb15d9cab93685f62e7e9f942aa00ae2" dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] @@ -1188,12 +1268,13 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" [[package]] name = "nix" -version = "0.27.1" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" dependencies = [ "bitflags 2.4.1", "cfg-if", + "cfg_aliases", "libc", ] @@ -1209,12 +1290,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" -[[package]] -name = "normalize-line-endings" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" - [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -1267,13 +1342,12 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "opentelemetry" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e32339a5dc40459130b3bd269e9892439f55b33e772d2a9d402a789baaf4e8a" +checksum = "900d57987be3f2aeb70d385fff9b27fb74c5723cc9a52d904d4f9c807a0667bf" dependencies = [ "futures-core", "futures-sink", - "indexmap 2.1.0", "js-sys", "once_cell", "pin-project-lite", @@ -1283,13 +1357,13 @@ dependencies = [ [[package]] name = "opentelemetry-otlp" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f24cda83b20ed2433c68241f918d0f6fdec8b1d43b7a9590ab4420c5095ca930" +checksum = "1a016b8d9495c639af2145ac22387dcb88e44118e45320d9238fbf4e7889abcb" dependencies = [ "async-trait", "futures-core", - "http", + "http 0.2.11", "opentelemetry", "opentelemetry-proto", "opentelemetry-semantic-conventions", @@ -1302,9 +1376,9 @@ dependencies = [ [[package]] name = "opentelemetry-prometheus" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f8f082da115b0dcb250829e3ed0b8792b8f963a1ad42466e48422fbe6a079bd" +checksum = "30bbcf6341cab7e2193e5843f0ac36c446a5b3fccb28747afaeda17996dcd02e" dependencies = [ "once_cell", "opentelemetry", @@ -1315,9 +1389,9 @@ dependencies = [ [[package]] name = "opentelemetry-proto" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2e155ce5cc812ea3d1dffbd1539aed653de4bf4882d60e6e04dcf0901d674e1" +checksum = "3a8fddc9b68f5b80dae9d6f510b88e02396f006ad48cac349411fbecc80caae4" dependencies = [ "opentelemetry", "opentelemetry_sdk", @@ -1327,18 +1401,15 @@ dependencies = [ [[package]] name = "opentelemetry-semantic-conventions" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5774f1ef1f982ef2a447f6ee04ec383981a3ab99c8e77a1a7b30182e65bbc84" -dependencies = [ - "opentelemetry", -] +checksum = "f9ab5bd6c42fb9349dcf28af2ba9a0667f697f9bdcca045d39f2cec5543e2910" [[package]] name = "opentelemetry_sdk" -version = "0.21.2" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f16aec8a98a457a52664d69e0091bac3a0abd18ead9b641cb00202ba4e0efe4" +checksum = "9e90c7113be649e31e9a0f8b5ee24ed7a16923b322c3c5ab6367469c049d6b7e" dependencies = [ "async-trait", "crossbeam-channel", @@ -1485,16 +1556,12 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "predicates" -version = "2.1.5" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd" +checksum = "68b87bfd4605926cdfefc1c3b5f8fe560e3feca9d5552cf68c466d3d8236c7e8" dependencies = [ - "difflib", - "float-cmp", - "itertools 0.10.5", - "normalize-line-endings", + "anstyle", "predicates-core", - "regex", ] [[package]] @@ -1515,12 +1582,12 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.1.25" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" +checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" dependencies = [ "proc-macro2", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] @@ -1549,9 +1616,9 @@ dependencies = [ [[package]] name = "prost" -version = "0.11.9" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" dependencies = [ "bytes", "prost-derive", @@ -1559,53 +1626,53 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.11.9" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" +checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" dependencies = [ "bytes", "heck", - "itertools 0.10.5", - "lazy_static", + "itertools 0.11.0", "log", "multimap", + "once_cell", "petgraph", "prettyplease", "prost", "prost-types", "regex", - "syn 1.0.109", + "syn 2.0.48", "tempfile", "which", ] [[package]] name = "prost-derive" -version = "0.11.9" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" dependencies = [ "anyhow", - "itertools 0.10.5", + "itertools 0.11.0", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] name = "prost-types" -version = "0.11.9" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" dependencies = [ "prost", ] [[package]] name = "prost-wkt" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562788060bcf2bfabe055194bd991ed2442457661744c88e0a0828ff9a08c08b" +checksum = "4d8ef9c3f0f1dab910d2b7e2c24a8e4322e122eba6d7a1921eeebcebbc046c40" dependencies = [ "chrono", "inventory", @@ -1618,9 +1685,9 @@ dependencies = [ [[package]] name = "prost-wkt-build" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4dca8bcead3b728a6a7da017cc95e7f4cb2320ec4f6896bc593a1c4700f7328" +checksum = "5b31cae9a54ca84fee1504740a82eebf2479532905e106f63ca0c3bc8d780321" dependencies = [ "heck", "prost", @@ -1631,9 +1698,9 @@ dependencies = [ [[package]] name = "prost-wkt-types" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2377c5680f2342871823045052e791b4487f7c90aae17e0feaee24cf59578a34" +checksum = "435be4a8704091b4c5fb1d79799de7f2dbff53af05edf29385237f8cf7ab37ee" dependencies = [ "chrono", "prost", @@ -1864,10 +1931,10 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2", - "http", - "http-body", - "hyper", + "h2 0.3.24", + "http 0.2.11", + "http-body 0.4.6", + "hyper 0.14.28", "hyper-rustls", "ipnet", "js-sys", @@ -1876,14 +1943,14 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls", - "rustls-pemfile", + "rustls 0.21.10", + "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", "system-configuration", "tokio", - "tokio-rustls", + "tokio-rustls 0.24.1", "tokio-util", "tower-service", "url", @@ -1977,18 +2044,33 @@ checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "log", "ring", - "rustls-webpki", + "rustls-webpki 0.101.7", "sct", ] +[[package]] +name = "rustls" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e87c9956bd9807afa1f77e0f7594af32566e830e088a5576d27c5b6f30f49d41" +dependencies = [ + "log", + "ring", + "rustls-pki-types", + "rustls-webpki 0.102.2", + "subtle", + "zeroize", +] + [[package]] name = "rustls-native-certs" -version = "0.6.3" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" dependencies = [ "openssl-probe", - "rustls-pemfile", + "rustls-pemfile 2.1.1", + "rustls-pki-types", "schannel", "security-framework", ] @@ -2002,6 +2084,22 @@ dependencies = [ "base64", ] +[[package]] +name = "rustls-pemfile" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f48172685e6ff52a556baa527774f61fcaa884f59daf3375c62a3f1cd2549dab" +dependencies = [ + "base64", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ede67b28608b4c60685c7d54122d4400d90f62b40caee7700e700380a390fa8" + [[package]] name = "rustls-webpki" version = "0.101.7" @@ -2012,6 +2110,17 @@ dependencies = [ "untrusted", ] +[[package]] +name = "rustls-webpki" +version = "0.102.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.14" @@ -2187,9 +2296,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.2" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" [[package]] name = "socket2" @@ -2309,9 +2418,8 @@ dependencies = [ "derive_more", "futures", "futures-retry", - "http", + "http 0.2.11", "once_cell", - "opentelemetry", "parking_lot", "prost-types", "slotmap", @@ -2333,7 +2441,6 @@ dependencies = [ "futures", "log", "once_cell", - "parking_lot", "prost", "prost-types", "pyo3", @@ -2355,7 +2462,6 @@ name = "temporal-sdk-core" version = "0.1.0" dependencies = [ "anyhow", - "arc-swap", "async-trait", "base64", "crossbeam-channel", @@ -2369,10 +2475,10 @@ dependencies = [ "futures", "futures-util", "governor", - "http", - "hyper", - "itertools 0.11.0", - "lazy_static", + "http-body-util", + "hyper 1.2.0", + "hyper-util", + "itertools 0.12.1", "log", "lru", "mockall", @@ -2406,7 +2512,6 @@ dependencies = [ "tonic", "tonic-build", "tracing", - "tracing-futures", "tracing-subscriber", "url", "uuid", @@ -2567,7 +2672,18 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls", + "rustls 0.21.10", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" +dependencies = [ + "rustls 0.22.2", + "rustls-pki-types", "tokio", ] @@ -2598,29 +2714,28 @@ dependencies = [ [[package]] name = "tonic" -version = "0.9.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" +checksum = "76c4eb7a4e9ef9d4763600161f12f5070b92a578e1b634db88a6887844c91a13" dependencies = [ "async-stream", "async-trait", "axum", "base64", "bytes", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", + "h2 0.3.24", + "http 0.2.11", + "http-body 0.4.6", + "hyper 0.14.28", "hyper-timeout", "percent-encoding", "pin-project", "prost", "rustls-native-certs", - "rustls-pemfile", + "rustls-pemfile 2.1.1", + "rustls-pki-types", "tokio", - "tokio-rustls", + "tokio-rustls 0.25.0", "tokio-stream", "tower", "tower-layer", @@ -2630,15 +2745,15 @@ dependencies = [ [[package]] name = "tonic-build" -version = "0.9.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6fdaae4c2c638bb70fe42803a26fbd6fc6ac8c72f5c59f67ecc2a2dcabf4b07" +checksum = "be4ef6dd70a610078cb4e338a0f79d06bc759ff1b22d2120c2ff02ae264ba9c2" dependencies = [ "prettyplease", "proc-macro2", "prost-build", "quote", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] @@ -2706,16 +2821,6 @@ dependencies = [ "valuable", ] -[[package]] -name = "tracing-futures" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" -dependencies = [ - "pin-project", - "tracing", -] - [[package]] name = "tracing-log" version = "0.2.0" @@ -3170,6 +3275,12 @@ dependencies = [ "syn 2.0.48", ] +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" + [[package]] name = "zip" version = "0.6.6" diff --git a/temporalio/bridge/Cargo.toml b/temporalio/bridge/Cargo.toml index 75fda97c..1e5d1335 100644 --- a/temporalio/bridge/Cargo.toml +++ b/temporalio/bridge/Cargo.toml @@ -10,10 +10,9 @@ crate-type = ["cdylib"] [dependencies] futures = "0.3" log = "0.4" -once_cell = "1.16.0" -parking_lot = "0.12" -prost = "0.11" -prost-types = "0.11" +once_cell = "1.16" +prost = "0.12" +prost-types = "0.12" pyo3 = { version = "0.19", features = ["extension-module", "abi3-py38"] } pyo3-asyncio = { version = "0.19", features = ["tokio-runtime"] } pythonize = "0.19" @@ -23,7 +22,7 @@ temporal-sdk-core-api = { version = "0.1.0", path = "./sdk-core/core-api" } temporal-sdk-core-protos = { version = "0.1.0", path = "./sdk-core/sdk-core-protos" } tokio = "1.26" tokio-stream = "0.1" -tonic = "0.9" +tonic = "0.11" tracing = "0.1" url = "2.2" diff --git a/temporalio/bridge/client.py b/temporalio/bridge/client.py index d82bc8bf..16d7b50d 100644 --- a/temporalio/bridge/client.py +++ b/temporalio/bridge/client.py @@ -52,6 +52,7 @@ class ClientConfig: target_url: str metadata: Mapping[str, str] + api_key: Optional[str] identity: str tls_config: Optional[ClientTlsConfig] retry_config: Optional[ClientRetryConfig] @@ -102,6 +103,10 @@ def update_metadata(self, metadata: Mapping[str, str]) -> None: """Update underlying metadata on Core client.""" self._ref.update_metadata(metadata) + def update_api_key(self, api_key: Optional[str]) -> None: + """Update underlying API key on Core client.""" + self._ref.update_api_key(api_key) + async def call( self, *, diff --git a/temporalio/bridge/sdk-core b/temporalio/bridge/sdk-core index f828a740..bcda5d9f 160000 --- a/temporalio/bridge/sdk-core +++ b/temporalio/bridge/sdk-core @@ -1 +1 @@ -Subproject commit f828a740a87e2ef271f3874d7bbe5771cb92435c +Subproject commit bcda5d9f73b082ddf6816921e15db5e68a8ce47e diff --git a/temporalio/bridge/src/client.rs b/temporalio/bridge/src/client.rs index b5bf4b63..995f0003 100644 --- a/temporalio/bridge/src/client.rs +++ b/temporalio/bridge/src/client.rs @@ -1,9 +1,7 @@ -use parking_lot::RwLock; use pyo3::exceptions::{PyException, PyRuntimeError, PyValueError}; use pyo3::prelude::*; use std::collections::HashMap; use std::str::FromStr; -use std::sync::Arc; use std::time::Duration; use temporal_client::{ ClientKeepAliveConfig as CoreClientKeepAliveConfig, ClientOptions, ClientOptionsBuilder, @@ -31,6 +29,7 @@ pub struct ClientConfig { client_name: String, client_version: String, metadata: HashMap, + api_key: Option, identity: String, tls_config: Option, retry_config: Option, @@ -75,20 +74,12 @@ pub fn connect_client<'a>( runtime_ref: &runtime::RuntimeRef, config: ClientConfig, ) -> PyResult<&'a PyAny> { - let headers = if config.metadata.is_empty() { - None - } else { - Some(Arc::new(RwLock::new(config.metadata.clone()))) - }; let opts: ClientOptions = config.try_into()?; let runtime = runtime_ref.runtime.clone(); runtime_ref.runtime.future_into_py(py, async move { Ok(ClientRef { retry_client: opts - .connect_no_namespace( - runtime.core.telemetry().get_temporal_metric_meter(), - headers, - ) + .connect_no_namespace(runtime.core.telemetry().get_temporal_metric_meter()) .await .map_err(|err| { PyRuntimeError::new_err(format!("Failed client connect: {}", err)) @@ -114,6 +105,10 @@ impl ClientRef { self.retry_client.get_client().set_headers(headers); } + fn update_api_key(&self, api_key: Option) { + self.retry_client.get_client().set_api_key(api_key); + } + fn call_workflow_service<'p>(&self, py: Python<'p>, call: RpcCall) -> PyResult<&'p PyAny> { let mut retry_client = self.retry_client.clone(); self.runtime.future_into_py(py, async move { @@ -396,7 +391,9 @@ impl TryFrom for ClientOptions { opts.retry_config .map_or(RetryConfig::default(), |c| c.into()), ) - .keep_alive(opts.keep_alive_config.map(Into::into)); + .keep_alive(opts.keep_alive_config.map(Into::into)) + .headers(Some(opts.metadata)) + .api_key(opts.api_key); // Builder does not allow us to set option here, so we have to make // a conditional to even call it if let Some(tls_config) = opts.tls_config { diff --git a/temporalio/client.py b/temporalio/client.py index cc29f433..90f007ce 100644 --- a/temporalio/client.py +++ b/temporalio/client.py @@ -97,6 +97,7 @@ async def connect( target_host: str, *, namespace: str = "default", + api_key: Optional[str] = None, data_converter: temporalio.converter.DataConverter = temporalio.converter.DataConverter.default, interceptors: Sequence[Interceptor] = [], default_workflow_query_reject_condition: Optional[ @@ -116,6 +117,9 @@ async def connect( target_host: ``host:port`` for the Temporal server. For local development, this is often "localhost:7233". namespace: Namespace to use for client calls. + api_key: API key for Temporal. This becomes the "Authorization" + HTTP header with "Bearer " prepended. This is only set if RPC + metadata doesn't already have an "authorization" key. data_converter: Data converter to use for all data conversions to/from payloads. interceptors: Set of interceptors that are chained together to allow @@ -152,6 +156,7 @@ async def connect( """ connect_config = temporalio.service.ConnectConfig( target_host=target_host, + api_key=api_key, tls=tls, retry_config=retry_config, keep_alive_config=keep_alive_config, @@ -261,6 +266,22 @@ def rpc_metadata(self, value: Mapping[str, str]) -> None: self.service_client.config.rpc_metadata = value self.service_client.update_rpc_metadata(value) + @property + def api_key(self) -> Optional[str]: + """API key for every call made by this client.""" + return self.service_client.config.api_key + + @api_key.setter + def api_key(self, value: Optional[str]) -> None: + """Update the API key for this client. + + This is only set if RPCmetadata doesn't already have an "authorization" + key. + """ + # Update config and perform update + self.service_client.config.api_key = value + self.service_client.update_api_key(value) + # Overload for no-param workflow @overload async def start_workflow( diff --git a/temporalio/service.py b/temporalio/service.py index 3575e4f0..6969ab6e 100644 --- a/temporalio/service.py +++ b/temporalio/service.py @@ -120,6 +120,7 @@ class ConnectConfig: """Config for connecting to the server.""" target_host: str + api_key: Optional[str] = None tls: Union[bool, TLSConfig] = False retry_config: Optional[RetryConfig] = None keep_alive_config: Optional[KeepAliveConfig] = KeepAliveConfig.default @@ -161,6 +162,7 @@ def _to_bridge_config(self) -> temporalio.bridge.client.ClientConfig: return temporalio.bridge.client.ClientConfig( target_url=target_url, + api_key=self.api_key, tls_config=tls_config, retry_config=self.retry_config._to_bridge_config() if self.retry_config @@ -238,6 +240,11 @@ def update_rpc_metadata(self, metadata: Mapping[str, str]) -> None: """Update service client's RPC metadata.""" raise NotImplementedError + @abstractmethod + def update_api_key(self, api_key: Optional[str]) -> None: + """Update service client's API key.""" + raise NotImplementedError + @abstractmethod async def _rpc_call( self, @@ -740,6 +747,14 @@ def update_rpc_metadata(self, metadata: Mapping[str, str]) -> None: if self._bridge_client: self._bridge_client.update_metadata(metadata) + def update_api_key(self, api_key: Optional[str]) -> None: + """Update Core client API key.""" + # Mutate the bridge config and then only mutate the running client + # metadata if already connected + self._bridge_config.api_key = api_key + if self._bridge_client: + self._bridge_client.update_api_key(api_key) + async def _rpc_call( self, rpc: str, diff --git a/tests/api/test_grpc_stub.py b/tests/api/test_grpc_stub.py index 61d0a931..25c3f5be 100644 --- a/tests/api/test_grpc_stub.py +++ b/tests/api/test_grpc_stub.py @@ -1,4 +1,5 @@ from datetime import timedelta +from typing import Mapping from google.protobuf.empty_pb2 import Empty from google.protobuf.timestamp_pb2 import Timestamp @@ -27,12 +28,6 @@ from temporalio.client import Client -def assert_metadata(context: ServicerContext, **kwargs) -> None: - metadata = dict(context.invocation_metadata()) - for k, v in kwargs.items(): - assert metadata.get(k) == v - - def assert_time_remaining(context: ServicerContext, expected: int) -> None: # Give or take 5 seconds assert expected - 5 <= context.time_remaining() <= expected + 5 @@ -41,14 +36,18 @@ def assert_time_remaining(context: ServicerContext, expected: int) -> None: class SimpleWorkflowServer(WorkflowServiceServicer): def __init__(self) -> None: super().__init__() - self.expected_client_key_value = "client_value" + self.last_metadata: Mapping[str, str] = {} + + def assert_last_metadata(self, expected: Mapping[str, str]) -> None: + for k, v in expected.items(): + assert self.last_metadata.get(k) == v async def GetSystemInfo( # type: ignore # https://github.com/nipunn1313/mypy-protobuf/issues/216 self, request: GetSystemInfoRequest, context: ServicerContext, ) -> GetSystemInfoResponse: - assert_metadata(context, client_key=self.expected_client_key_value) + self.last_metadata = dict(context.invocation_metadata()) return GetSystemInfoResponse() async def CountWorkflowExecutions( # type: ignore # https://github.com/nipunn1313/mypy-protobuf/issues/216 @@ -56,9 +55,7 @@ async def CountWorkflowExecutions( # type: ignore # https://github.com/nipunn13 request: CountWorkflowExecutionsRequest, context: ServicerContext, ) -> CountWorkflowExecutionsResponse: - assert_metadata( - context, client_key=self.expected_client_key_value, rpc_key="rpc_value" - ) + self.last_metadata = dict(context.invocation_metadata()) assert_time_remaining(context, 123) assert request.namespace == "my namespace" assert request.query == "my query" @@ -71,7 +68,6 @@ async def DeleteNamespace( # type: ignore # https://github.com/nipunn1313/mypy- request: DeleteNamespaceRequest, context: ServicerContext, ) -> DeleteNamespaceResponse: - assert_metadata(context, client_key="client_value", rpc_key="rpc_value") assert_time_remaining(context, 123) assert request.namespace == "my namespace" return DeleteNamespaceResponse(deleted_namespace="my namespace response") @@ -83,7 +79,6 @@ async def GetCurrentTime( # type: ignore # https://github.com/nipunn1313/mypy-p request: Empty, context: ServicerContext, ) -> GetCurrentTimeResponse: - assert_metadata(context, client_key="client_value", rpc_key="rpc_value") assert_time_remaining(context, 123) return GetCurrentTimeResponse(time=Timestamp(seconds=123)) @@ -101,34 +96,88 @@ async def test_python_grpc_stub(): await server.start() # Use our client to make a call to each service - client = await Client.connect( - f"localhost:{port}", rpc_metadata={"client_key": "client_value"} - ) - metadata = {"rpc_key": "rpc_value"} + client = await Client.connect(f"localhost:{port}") timeout = timedelta(seconds=123) count_resp = await client.workflow_service.count_workflow_executions( CountWorkflowExecutionsRequest(namespace="my namespace", query="my query"), - metadata=metadata, timeout=timeout, ) assert count_resp.count == 123 del_resp = await client.operator_service.delete_namespace( DeleteNamespaceRequest(namespace="my namespace"), - metadata=metadata, timeout=timeout, ) assert del_resp.deleted_namespace == "my namespace response" - time_resp = await client.test_service.get_current_time( - Empty(), metadata=metadata, timeout=timeout - ) + time_resp = await client.test_service.get_current_time(Empty(), timeout=timeout) assert time_resp.time.seconds == 123 - # Make another call to get system info after changing the client-level - # header - new_metadata = dict(client.rpc_metadata) - new_metadata["client_key"] = "changed_value" - client.rpc_metadata = new_metadata - workflow_server.expected_client_key_value = "changed_value" + await server.stop(grace=None) + + +async def test_grpc_metadata(): + # Start server + server = grpc_server() + workflow_server = SimpleWorkflowServer() # type: ignore[abstract] + add_WorkflowServiceServicer_to_server(workflow_server, server) + port = server.add_insecure_port("[::]:0") + await server.start() + + # Connect and confirm metadata of get system info call + client = await Client.connect( + f"localhost:{port}", + api_key="my-api-key", + rpc_metadata={"my-meta-key": "my-meta-val"}, + ) + workflow_server.assert_last_metadata( + { + "authorization": "Bearer my-api-key", + "my-meta-key": "my-meta-val", + } + ) + + # Overwrite API key via client RPC metadata, confirm there + client.rpc_metadata = { + "authorization": "my-auth-val1", + "my-meta-key": "my-meta-val", + } await client.workflow_service.get_system_info(GetSystemInfoRequest()) + workflow_server.assert_last_metadata( + { + "authorization": "my-auth-val1", + "my-meta-key": "my-meta-val", + } + ) + client.rpc_metadata = {"my-meta-key": "my-meta-val"} + + # Overwrite API key via call RPC metadata, confirm there + await client.workflow_service.get_system_info( + GetSystemInfoRequest(), metadata={"authorization": "my-auth-val2"} + ) + workflow_server.assert_last_metadata( + { + "authorization": "my-auth-val2", + "my-meta-key": "my-meta-val", + } + ) + + # Update API key, confirm updated + client.api_key = "my-new-api-key" + await client.workflow_service.get_system_info(GetSystemInfoRequest()) + workflow_server.assert_last_metadata( + { + "authorization": "Bearer my-new-api-key", + "my-meta-key": "my-meta-val", + } + ) + + # Remove API key, confirm removed + client.api_key = None + await client.workflow_service.get_system_info(GetSystemInfoRequest()) + workflow_server.assert_last_metadata( + { + "my-meta-key": "my-meta-val", + } + ) + assert "authorization" not in workflow_server.last_metadata await server.stop(grace=None)