-
Notifications
You must be signed in to change notification settings - Fork 89
External client configuration sample #228
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
196d681
External client configuration sample
THardy98 d6be352
Merge branch 'main' into env_config_sample
THardy98 c207986
Merge branch 'main' into env_config_sample
THardy98 a9d0eb1
update sample
THardy98 c499599
Merge branch 'main' into env_config_sample
THardy98 473de51
linting
THardy98 61fc2fc
address review
THardy98 77472f2
Merge branch 'main' into env_config_sample
THardy98 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
THardy98 marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# Temporal External Client Configuration Samples | ||
|
||
This directory contains Python samples that demonstrate how to use the Temporal SDK's external client configuration feature. This feature allows you to configure a `temporalio.client.Client` using a TOML file and/or programmatic overrides, decoupling connection settings from your application code. | ||
|
||
## Prerequisites | ||
|
||
To run, first see [README.md](../README.md) for prerequisites. | ||
|
||
## Configuration File | ||
|
||
The `config.toml` file defines three profiles for different environments: | ||
|
||
- `[profile.default]`: A working configuration for local development. | ||
- `[profile.staging]`: A configuration with an intentionally **incorrect** address (`localhost:9999`) to demonstrate how it can be corrected by an override. | ||
- `[profile.prod]`: A non-runnable, illustrative-only configuration showing a realistic setup for Temporal Cloud with placeholder credentials. This profile is not used by the samples but serves as a reference. | ||
|
||
## Samples | ||
|
||
The following Python scripts demonstrate different ways to load and use these configuration profiles. Each runnable sample highlights a unique feature. | ||
|
||
### `load_from_file.py` | ||
|
||
This sample shows the most common use case: loading the `default` profile from the `config.toml` file. | ||
|
||
**To run this sample:** | ||
|
||
```bash | ||
uv run env_config/load_from_file.py | ||
``` | ||
|
||
### `load_profile.py` | ||
|
||
This sample demonstrates loading the `staging` profile by name (which has an incorrect address) and then correcting the address programmatically. This highlights the recommended approach for overriding configuration values at runtime. | ||
|
||
**To run this sample:** | ||
|
||
```bash | ||
uv run env_config/load_profile.py | ||
``` | ||
|
||
## Running the Samples | ||
|
||
You can run each sample script directly from the root of the `samples-python` repository. Ensure you have the necessary dependencies installed by running `pip install -e .` (or the equivalent for your environment). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# This is a sample configuration file for demonstrating Temporal's environment | ||
# configuration feature. It defines multiple profiles for different environments, | ||
# such as local development, production, and staging. | ||
|
||
# Default profile for local development | ||
[profile.default] | ||
address = "localhost:7233" | ||
namespace = "default" | ||
|
||
# Optional: Add custom gRPC headers | ||
[profile.default.grpc_meta] | ||
my-custom-header = "development-value" | ||
trace-id = "dev-trace-123" | ||
|
||
# Staging profile with inline certificate data | ||
[profile.staging] | ||
address = "localhost:9999" | ||
namespace = "staging" | ||
|
||
# An example production profile for Temporal Cloud | ||
[profile.prod] | ||
address = "your-namespace.a1b2c.tmprl.cloud:7233" | ||
namespace = "your-namespace" | ||
# Replace with your actual Temporal Cloud API key | ||
api_key = "your-api-key-here" | ||
|
||
# TLS configuration for production | ||
[profile.prod.tls] | ||
# TLS is auto-enabled when an API key is present, but you can configure it | ||
# explicitly. | ||
# disabled = false | ||
|
||
# Use certificate files for mTLS. Replace with actual paths. | ||
client_cert_path = "/etc/temporal/certs/client.pem" | ||
client_key_path = "/etc/temporal/certs/client.key" | ||
|
||
# Custom headers for production | ||
[profile.prod.grpc_meta] | ||
environment = "production" | ||
service-version = "v1.2.3" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
""" | ||
This sample demonstrates loading the default environment configuration profile | ||
from a TOML file. | ||
""" | ||
|
||
import asyncio | ||
from pathlib import Path | ||
|
||
from temporalio.client import Client | ||
from temporalio.envconfig import ClientConfig | ||
|
||
|
||
async def main(): | ||
""" | ||
Loads the default profile from the config.toml file in this directory. | ||
""" | ||
print("--- Loading default profile from config.toml ---") | ||
|
||
# For this sample to be self-contained, we explicitly provide the path to | ||
# the config.toml file included in this directory. | ||
# By default though, the config.toml file will be loaded from | ||
# ~/.config/temporalio/temporal.toml (or the equivalent standard config directory on your OS). | ||
config_file = Path(__file__).parent / "config.toml" | ||
|
||
# load_client_connect_config is a helper that loads a profile and prepares | ||
# the config dictionary for Client.connect. By default, it loads the | ||
# "default" profile. | ||
connect_config = ClientConfig.load_client_connect_config( | ||
config_file=str(config_file) | ||
) | ||
|
||
print(f"Loaded 'default' profile from {config_file}.") | ||
print(f" Address: {connect_config.get('target_host')}") | ||
print(f" Namespace: {connect_config.get('namespace')}") | ||
print(f" gRPC Metadata: {connect_config.get('rpc_metadata')}") | ||
|
||
print("\nAttempting to connect to client...") | ||
try: | ||
await Client.connect(**connect_config) # type: ignore | ||
print("✅ Client connected successfully!") | ||
except Exception as e: | ||
print(f"❌ Failed to connect: {e}") | ||
|
||
|
||
if __name__ == "__main__": | ||
asyncio.run(main()) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
""" | ||
This sample demonstrates loading a named environment configuration profile and | ||
programmatically overriding its values. | ||
""" | ||
|
||
import asyncio | ||
from pathlib import Path | ||
|
||
from temporalio.client import Client | ||
from temporalio.envconfig import ClientConfig | ||
|
||
|
||
async def main(): | ||
""" | ||
Demonstrates loading a named profile and overriding values programmatically. | ||
""" | ||
print("--- Loading 'staging' profile with programmatic overrides ---") | ||
|
||
config_file = Path(__file__).parent / "config.toml" | ||
profile_name = "staging" | ||
|
||
print( | ||
"The 'staging' profile in config.toml has an incorrect address (localhost:9999)." | ||
) | ||
print("We'll programmatically override it to the correct address.") | ||
|
||
# Load the 'staging' profile. | ||
connect_config = ClientConfig.load_client_connect_config( | ||
profile=profile_name, | ||
config_file=str(config_file), | ||
) | ||
|
||
# Override the target host to the correct address. | ||
# This is the recommended way to override configuration values. | ||
connect_config["target_host"] = "localhost:7233" | ||
|
||
print(f"\nLoaded '{profile_name}' profile from {config_file} with overrides.") | ||
print( | ||
f" Address: {connect_config.get('target_host')} (overridden from localhost:9999)" | ||
) | ||
print(f" Namespace: {connect_config.get('namespace')}") | ||
|
||
print("\nAttempting to connect to client...") | ||
try: | ||
await Client.connect(**connect_config) # type: ignore | ||
print("✅ Client connected successfully!") | ||
except Exception as e: | ||
print(f"❌ Failed to connect: {e}") | ||
|
||
|
||
if __name__ == "__main__": | ||
asyncio.run(main()) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume the updating of all existing samples to leverage the one-liner for loading from env config will be a separate PR?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes - I am updating samples to have their own TOML config (or shared) and loading from there.
Would need to release new version of Python SDK with temporalio/sdk-python#1004 included, to avoid samples needing to have TOML config for the
default
profile.But I'd rather update these samples than wait for another release. Once the new release is out, we can update it accordingly (would be a small diff).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#233