Open
Description
If you're using Temporal Cloud with API key authentication for a namespace:
$ tcld namespace auth-method get -namespace quickstart-jack.xxxxx
api_key
And connecting with Python:
TASK_QUEUE = os.environ.get("TASK_QUEUE", "tasks")
TEMPORAL_ADDRESS = os.environ.get("TEMPORAL_ADDRESS", "localhost:7233")
TEMPORAL_NAMESPACE = os.environ.get("TEMPORAL_NAMESPACE", "default")
TEMPORAL_API_KEY = os.environ.get("TEMPORAL_API_KEY", "")
async def main() -> None:
client = await Client.connect(TEMPORAL_ADDRESS, namespace=TEMPORAL_NAMESPACE, api_key=TEMPORAL_API_KEY)
executor = ThreadPoolExecutor()
worker = Worker(
client,
task_queue=TASK_QUEUE,
workflows=load_workflows(),
activities=load_activities(),
activity_executor=executor,
)
await worker.run()
This will raise this error:
$ poetry run python worker.py
Traceback (most recent call last):
File "/Users/pearkes/code/jack/temporal/worker.py", line 75, in <module>
asyncio.run(main())
~~~~~~~~~~~^^^^^^^^
File "/Users/pearkes/.local/share/uv/python/cpython-3.13.2-macos-aarch64-none/lib/python3.13/asyncio/runners.py", line 195, in run
return runner.run(main)
~~~~~~~~~~^^^^^^
File "/Users/pearkes/.local/share/uv/python/cpython-3.13.2-macos-aarch64-none/lib/python3.13/asyncio/runners.py", line 118, in run
return self._loop.run_until_complete(task)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
File "/Users/pearkes/.local/share/uv/python/cpython-3.13.2-macos-aarch64-none/lib/python3.13/asyncio/base_events.py", line 725, in run_until_complete
return future.result()
~~~~~~~~~~~~~^^
File "/Users/pearkes/code/jack/temporal/worker.py", line 62, in main
client = await Client.connect(TEMPORAL_ADDRESS, namespace=TEMPORAL_NAMESPACE, api_key=TEMPORAL_API_KEY)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/pearkes/code/jack/temporal/.venv/lib/python3.13/site-packages/temporalio/client.py", line 177, in connect
await temporalio.service.ServiceClient.connect(connect_config), ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/pearkes/code/jack/temporal/.venv/lib/python3.13/site-packages/temporalio/service.py", line 209, in connect
return await _BridgeServiceClient.connect(config) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/pearkes/code/jack/temporal/.venv/lib/python3.13/site-packages/temporalio/service.py", line 1212, in connect await client._connected_client()
File "/Users/pearkes/code/jack/temporal/.venv/lib/python3.13/site-packages/temporalio/service.py", line 1225, in _connected_client self._bridge_client = await temporalio.bridge.client.Client.connect(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...<2 lines>... ) ^
File "/Users/pearkes/code/jack/temporal/.venv/lib/python3.13/site-packages/temporalio/bridge/client.py", line 97, in connect await temporalio.bridge.temporal_sdk_bridge.connect_client( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
runtime._ref, config ^^^^^^^^^^^^^^^^^^^^
), ^
RuntimeError: Failed client connect: `get_system_info` call error after connection: Status { code: Unknown, message: "transport error", source: Some(tonic::transport::Error(Transport, hyper::Error(Io, Kind(ConnectionReset)))) }
Status { code: Unknown, message: "transport error" ...
is quite inscrutable and could be considerably improved.- You need to set TLS to
True
– this wasn't clear in the getting started docs, nor were API keys as an auth method mentioned. I found a reference to it in the Python client docs and figured that may be it.
This works:
TASK_QUEUE = os.environ.get("TASK_QUEUE", "tasks")
TEMPORAL_ADDRESS = os.environ.get("TEMPORAL_ADDRESS", "localhost:7233")
TEMPORAL_NAMESPACE = os.environ.get("TEMPORAL_NAMESPACE", "default")
TEMPORAL_API_KEY = os.environ.get("TEMPORAL_API_KEY", "")
TEMPORAL_TLS = bool(os.environ.get("TEMPORAL_TLS", False))
async def main() -> None:
client = await Client.connect(TEMPORAL_ADDRESS, namespace=TEMPORAL_NAMESPACE, api_key=TEMPORAL_API_KEY, tls=TEMPORAL_TLS)
# Use a thread pool executor for synchronous activities
executor = ThreadPoolExecutor()
worker = Worker(
client,
task_queue=TASK_QUEUE,
workflows=load_workflows(),
activities=load_activities(),
activity_executor=executor,
)
await worker.run()