What is a Temporal Client?
A Temporal Client allows you to communicate with the Temporal Service. Communication with a Temporal Service lets you perform actions such as starting Workflow Executions, sending Signals to Workflow Executions, sending Queries to Workflow Executions, getting the results of a Workflow Execution, and providing Activity Task Tokens. When Standalone Activities are supported and enabled, a Temporal Client can also start and manage Standalone Activities directly, without involving a Workflow.
Code examples
The following examples show how to connect a Temporal Client to a local development Temporal Service.
- Go
- Java
- .NET
- PHP
- Python
- Ruby
- Rust
- TypeScript
- Configuration File
- Environment Variables
- Code
You can use a TOML configuration file to set connection options for the Temporal Client. The configuration file lets you
configure multiple profiles, each with its own set of connection options. You can then specify which profile to use when
creating the Temporal Client. You can use the environment variable TEMPORAL_CONFIG_FILE to specify the location of the
TOML file or provide the path to the file directly in code. If you don't provide the configuration file path, the SDK
looks for it at the path ~/.config/temporalio/temporal.toml. For a list of all available configuration options, refer
to Environment Configuration
The connection options set in configuration files have lower precedence than environment variables. This means that if you set the same option in both the configuration file and as an environment variable, the environment variable value overrides the option set in the configuration file.
For example, the following TOML configuration file defines two profiles: default and prod. Each profile has its own
set of connection options.
# Default profile for local development
[profile.default]
address = "localhost:7233"
namespace = "default"
# Custom gRPC headers
[profile.default.grpc_meta]
my-custom-header = "development-value"
trace-id = "dev-trace-123"
# Production profile for Temporal Cloud
[profile.prod]
address = "your-namespace.a1b2c.tmprl.cloud:7233"
namespace = "your-namespace"
api_key = "your-api-key-here"
# TLS configuration for production
[profile.prod.tls]
# TLS is auto-enabled when this TLS config or API key is present, but you can configure it explicitly
# disabled = false
# Use certificate files for mTLS
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"
You can create a Temporal Client using a specific profile from the configuration file as follows:
package main
import (
"fmt"
"log"
"go.temporal.io/sdk/client"
"go.temporal.io/sdk/contrib/envconfig"
)
func main() {
// Load a specific profile from the TOML config file.
// This requires a [profile.prod] section in your config.
opts, err := envconfig.LoadClientOptions(envconfig.LoadClientOptionsRequest{
ConfigFileProfile: "prod",
})
if err != nil {
log.Fatalf("Failed to load 'prod' profile: %v", err)
}
c, err := client.Dial(opts)
if err != nil {
log.Fatalf("Failed to connect using 'prod' profile: %v", err)
}
defer c.Close()
fmt.Printf("✅ Connected to Temporal namespace %q on %s using 'prod' profile\n", c.Options().Namespace, c.Options().HostPort)
}
Use the envconfig package to set connection options for the Temporal Client using environment variables. For a list of
all available environment variables and their default values, refer to
Environment Configuration.
For example, the following code snippet loads all environment variables and creates a Temporal Client with the options
specified in those variables. If you have defined a configuration file at either the default location
(~/.config/temporalio/temporal.toml) or a custom location specified by the TEMPORAL_CONFIG_FILE environment
variable, this will also load the default profile in the configuration file. However, any options set via environment
variables will take precedence.
package main
import (
"fmt"
"log"
"go.temporal.io/sdk/client"
"go.temporal.io/sdk/contrib/envconfig"
)
func main() {
// Loads the "default" profile from the standard location and environment variables.
c, err := client.Dial(envconfig.MustLoadDefaultClientOptions())
if err != nil {
log.Fatalf("Failed to create client: %v", err)
}
defer c.Close()
fmt.Printf("✅ Connected to Temporal namespace %q on %s\n", c.Options().Namespace, c.Options().HostPort)
}
If you don't want to use environment variables or a configuration file, you can specify connection options directly in code. This is convenient for local development and testing. You can also load a base configuration from environment variables or a configuration file, and then override specific options in code.
package main
import (
"context"
"encoding/json"
"log"
"net/http"
"documentation-samples-go/yourapp"
"go.temporal.io/sdk/client"
)
func main() {
// Create a Temporal Client to communicate with the Temporal Cluster.
// A Temporal Client is a heavyweight object that should be created just once per process.
temporalClient, err := client.Dial(client.Options{
HostPort: client.DefaultHostPort,
})
if err != nil {
log.Fatalln("Unable to create Temporal Client", err)
}
defer temporalClient.Close()
// ...
}
- Configuration File
- Environment Variables
- Code
You can use a TOML configuration file to set connection options for the Temporal Client. The configuration file lets you
configure multiple profiles, each with its own set of connection options. You can then specify which profile to use when
creating the Temporal Client. You can use the environment variable TEMPORAL_CONFIG_FILE to specify the location of the
TOML file or provide the path to the file directly in code. If you don't provide the configuration file path, the SDK
looks for it at the path ~/.config/temporalio/temporal.toml. For a list of all available configuration options, refer
to Environment Configuration
The connection options set in configuration files have lower precedence than environment variables. This means that if you set the same option in both the configuration file and as an environment variable, the environment variable value overrides the option set in the configuration file.
For example, the following TOML configuration file defines two profiles: default and prod. Each profile has its own
set of connection options.
# Default profile for local development
[profile.default]
address = "localhost:7233"
namespace = "default"
# Custom gRPC headers
[profile.default.grpc_meta]
my-custom-header = "development-value"
trace-id = "dev-trace-123"
# Production profile for Temporal Cloud
[profile.prod]
address = "your-namespace.a1b2c.tmprl.cloud:7233"
namespace = "your-namespace"
api_key = "your-api-key-here"
# TLS configuration for production
[profile.prod.tls]
# TLS is auto-enabled when this TLS config or API key is present, but you can configure it explicitly
# disabled = false
# Use certificate files for mTLS
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"
You can create a Temporal Client using a specific profile from the configuration file as follows. First use
ClientConfigProfile.load to load the profile from the configuration file. Then use
profile.toWorkflowServiceStubsOptions and profile.toWorkflowClientOptions to convert the profile to
WorkflowServiceStubsOptions and WorkflowClientOptions respectively. Then use WorkflowClient.newInstance to create
a Temporal Client.
import io.temporal.client.WorkflowClient;
import io.temporal.client.WorkflowClientOptions;
import io.temporal.envconfig.ClientConfigProfile;
import io.temporal.envconfig.LoadClientConfigProfileOptions;
import io.temporal.serviceclient.WorkflowServiceStubs;
import io.temporal.serviceclient.WorkflowServiceStubsOptions;
import java.nio.file.Paths;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LoadFromFile {
private static final Logger logger = LoggerFactory.getLogger(LoadFromFile.class);
public static void main(String[] args) {
try {
String configFilePath =
Paths.get(LoadFromFile.class.getResource("/config.toml").toURI()).toString();
ClientConfigProfile profile =
ClientConfigProfile.load(
LoadClientConfigProfileOptions.newBuilder()
.setConfigFilePath(configFilePath)
.build());
WorkflowServiceStubsOptions serviceStubsOptions = profile.toWorkflowServiceStubsOptions();
WorkflowClientOptions clientOptions = profile.toWorkflowClientOptions();
try {
// Create the workflow client using the loaded configuration
WorkflowClient client =
WorkflowClient.newInstance(
WorkflowServiceStubs.newServiceStubs(serviceStubsOptions), clientOptions);
// Test the connection by getting system info
var systemInfo =
client
.getWorkflowServiceStubs()
.blockingStub()
.getSystemInfo(
io.temporal.api.workflowservice.v1.GetSystemInfoRequest.getDefaultInstance());
logger.info("✅ Client connected successfully!");
logger.info(" Server version: {}", systemInfo.getServerVersion());
} catch (Exception e) {
logger.error("❌ Failed to connect: {}", e.getMessage());
}
} catch (Exception e) {
logger.error("Failed to load configuration: {}", e.getMessage(), e);
System.exit(1);
}
}
}
Use the envconfig package to set connection options for the Temporal Client using environment variables. For a list of
all available environment variables and their default values, refer to
Environment Configuration.
For example, the following code snippet loads all environment variables and creates a Temporal Client with the options
specified in those variables. If you have defined a configuration file at either the default location
(~/.config/temporalio/temporal.toml) or a custom location specified by the TEMPORAL_CONFIG_FILE environment
variable, this will also load the default profile in the configuration file. However, any options set via environment
variables will take precedence.
import io.temporal.client.WorkflowClient;
import io.temporal.client.WorkflowClientOptions;
import io.temporal.envconfig.ClientConfigProfile;
import io.temporal.envconfig.LoadClientConfigProfileOptions;
import io.temporal.serviceclient.WorkflowServiceStubs;
import io.temporal.serviceclient.WorkflowServiceStubsOptions;
import java.nio.file.Paths;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LoadFromFile {
private static final Logger logger = LoggerFactory.getLogger(LoadFromFile.class);
public static void main(String[] args) {
try {
ClientConfigProfile profile =
ClientConfigProfile.load(LoadClientConfigProfileOptions.newBuilder().build());
WorkflowServiceStubsOptions serviceStubsOptions = profile.toWorkflowServiceStubsOptions();
WorkflowClientOptions clientOptions = profile.toWorkflowClientOptions();
try {
// Create the workflow client using the loaded configuration
WorkflowClient client =
WorkflowClient.newInstance(
WorkflowServiceStubs.newServiceStubs(serviceStubsOptions), clientOptions);
// Test the connection by getting system info
var systemInfo =
client
.getWorkflowServiceStubs()
.blockingStub()
.getSystemInfo(
io.temporal.api.workflowservice.v1.GetSystemInfoRequest.getDefaultInstance());
logger.info("✅ Client connected successfully!");
logger.info(" Server version: {}", systemInfo.getServerVersion());
} catch (Exception e) {
logger.error("❌ Failed to connect: {}", e.getMessage());
}
} catch (Exception e) {
logger.error("Failed to load configuration: {}", e.getMessage(), e);
System.exit(1);
}
}
}
If you don't want to use environment variables or a configuration file, you can specify connection options directly in code. This is convenient for local development and testing. You can also load a base configuration from environment variables or a configuration file, and then override specific options in code.
// ...
// Add the Namespace as a Client Option
WorkflowClientOptions clientOptions = WorkflowClientOptions
.newBuilder()
.setNamespace(namespace)
.build();
// Initialize the Temporal Client
// This application uses the Client to communicate with the Temporal Service
WorkflowClient client = WorkflowClient.newInstance(service, clientOptions);
- Configuration File
- Environment Variables
- Code
You can use a TOML configuration file to set connection options for the Temporal Client. The configuration file lets you
configure multiple profiles, each with its own set of connection options. You can then specify which profile to use when
creating the Temporal Client. You can use the environment variable TEMPORAL_CONFIG_FILE to specify the location of the
TOML file or provide the path to the file directly in code. If you don't provide the configuration file path, the SDK
looks for it at the path ~/.config/temporalio/temporal.toml or the equivalent on your OS. Refer to
Environment Configuration for more details about configuration
files and profiles.
The connection options set in configuration files have lower precedence than environment variables. This means that if you set the same option in both the configuration file and as an environment variable, the environment variable value overrides the option set in the configuration file.
For example, the following TOML configuration file defines two profiles: default and prod. Each profile has its own
set of connection options.
# 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"
# Production profile for Temporal Cloud
[profile.prod]
address = "your-namespace.a1b2c.tmprl.cloud:7233"
namespace = "your-namespace"
api_key = "your-api-key-here"
# TLS configuration for production
[profile.prod.tls]
# TLS auto-enables when TLS config or an API key is present
# disabled = false
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"
You can create a Temporal Client using a profile from the configuration file as follows. In this example, you load the
default profile for local development:
using Temporalio.Client;
using Temporalio.Client.EnvConfig;
namespace TemporalioSamples.EnvConfig;
/// <summary>
/// Sample demonstrating loading the default environment configuration profile
/// from a TOML file.
/// </summary>
public static class LoadFromFile
{
public static async Task RunAsync()
{
Console.WriteLine("--- Loading default profile from config.toml ---");
try
{
// 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).
var configFile = Path.Combine(Directory.GetCurrentDirectory(), "config.toml");
// LoadClientConnectOptions is a helper that loads a profile and prepares
// the config for TemporalClient.ConnectAsync. By default, it loads the
// "default" profile.
var connectOptions = ClientEnvConfig.LoadClientConnectOptions(new ClientEnvConfig.ProfileLoadOptions
{
ConfigSource = DataSource.FromPath(configFile),
});
Console.WriteLine($"Loaded 'default' profile from {configFile}.");
Console.WriteLine($" Address: {connectOptions.TargetHost}");
Console.WriteLine($" Namespace: {connectOptions.Namespace}");
if (connectOptions.RpcMetadata?.Count > 0)
{
Console.WriteLine($" gRPC Metadata: {string.Join(", ", connectOptions.RpcMetadata.Select(kv => $"{kv.Key}={kv.Value}"))}");
}
Console.WriteLine("\nAttempting to connect to client...");
var client = await TemporalClient.ConnectAsync(connectOptions);
Console.WriteLine("✅ Client connected successfully!");
// Test the connection by checking the service
var sysInfo = await client.Connection.WorkflowService.GetSystemInfoAsync(new());
Console.WriteLine("✅ Successfully verified connection to Temporal server!\n{0}", sysInfo);
}
catch (Exception ex) when (ex is not OperationCanceledException)
{
Console.WriteLine($"❌ Failed to connect: {ex.Message}");
}
}
}
Use the EnvConfig package to set connection options for the Temporal Client using environment variables. For a list of
all available environment variables and their default values, refer to
Environment Configuration.
For example, the following code snippet loads all environment variables and creates a Temporal Client with the options
specified in those variables. If you have defined a configuration file at either the default location
(~/.config/temporalio/temporal.toml) or a custom location specified by the TEMPORAL_CONFIG_FILE environment
variable, this will also load the default profile in the configuration file. However, any options set via environment
variables will take precedence.
Set the following environment variables before running your .NET application. Replace the placeholder values with your
actual configuration. Since this is for a local development Temporal Service, the values connect to localhost:7233 and
the default Namespace. You may omit these variables entirely since they're the defaults.
export TEMPORAL_NAMESPACE="default"
export TEMPORAL_ADDRESS="localhost:7233"
After setting the environment variables, use the following code to create the Temporal Client:
using Temporalio.Client;
using Temporalio.Client.EnvConfig;
namespace TemporalioSamples.EnvConfig;
/// <summary>
/// Sample demonstrating loading the default environment configuration profile
/// from a TOML file.
/// </summary>
public static class LoadFromFile
{
public static async Task RunAsync()
{
try
{
var connectOptions = ClientEnvConfig.LoadClientConnectOptions();
Console.WriteLine("\nAttempting to connect to client...");
var client = await TemporalClient.ConnectAsync(connectOptions);
Console.WriteLine("✅ Client connected successfully!");
}
catch (Exception ex) when (ex is not OperationCanceledException)
{
Console.WriteLine($"❌ Failed to connect: {ex.Message}");
}
}
}
If you don't want to use environment variables or a configuration file, you can specify connection options directly in code. This is convenient for local development and testing. You can also load a base configuration from environment variables or a configuration file, and then override specific options in code.
using System;
using System.Threading.Tasks;
using Temporalio.Client;
namespace TemporalioSamples.Manual
{
public static class ManualConnect
{
public static async Task RunAsync()
{
Console.WriteLine("--- Connecting manually to Temporal ---");
var client = await TemporalClient.ConnectAsync(new TemporalClientConnectOptions
{
TargetHost = "localhost:7233",
Namespace = "default",
});
Console.WriteLine("✅ Connected to local Temporal service!");
}
}
}
Use create() factory methods to create clients.
use Temporal\Client\GRPC\ServiceClient;
use Temporal\Client\WorkflowClient;
$serviceClient = ServiceClient::create('localhost:7233');
$workflowClient = WorkflowClient::create($serviceClient);
// Use $workflowClient to work with Workflows ...
- Configuration File
- Environment Variables
- Code
You can use a TOML configuration file to set connection options for the Temporal Client. The configuration file lets you
configure multiple profiles, each with its own set of connection options. You can then specify which profile to use when
creating the Temporal Client. You can use the environment variable TEMPORAL_CONFIG_FILE to specify the location of the
TOML file or provide the path to the file directly in code. If you don't provide the configuration file path, the SDK
looks for it at the path ~/.config/temporalio/temporal.toml or the equivalent on your OS. Refer to
Environment Configuration for more details about
configuration files and profiles.
The connection options set in configuration files have lower precedence than environment variables. This means that if you set the same option in both the configuration file and as an environment variable, the environment variable value overrides the option set in the configuration file.
For example, the following TOML configuration file defines two profiles: default and prod. Each profile has its own
set of connection options.
# 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"
# Production profile for Temporal Cloud
[profile.prod]
address = "your-namespace.a1b2c.tmprl.cloud:7233"
namespace = "your-namespace"
api_key = "your-api-key-here"
# TLS configuration for production
[profile.prod.tls]
# TLS auto-enables when TLS config or an API key is present
# disabled = false
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"
You can create a Temporal Client using a profile from the configuration file using the
ClientConfig.load_client_connect_config function as follows. In this example, you load the default profile for local
development:
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())
Use the envconfig package to set connection options for the Temporal Client using environment variables. For a list of
all available environment variables and their default values, refer to
Environment Configuration.
For example, the following code snippet loads all environment variables and creates a Temporal Client with the options
specified in those variables. If you have defined a configuration file at either the default location
(~/.config/temporalio/temporal.toml) or a custom location specified by the TEMPORAL_CONFIG_FILE environment
variable, this will also load the default profile in the configuration file. However, any options set via environment
variables will take precedence.
Set the following environment variables before running your Python application. Replace the placeholder values with your
actual configuration. Since this is for a local development Temporal Service, the values connect to localhost:7233 and
the default Namespace. You may omit these variables entirely since they're the defaults.
export TEMPORAL_NAMESPACE="default"
export TEMPORAL_ADDRESS="localhost:7233"
After setting the environment variables, you can create a Temporal Client as follows:
import asyncio
from pathlib import Path
from temporalio.client import Client
from temporalio.envconfig import ClientConfig
async def main():
# 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()
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())
If you don't want to use environment variables or a configuration file, you can specify connection options directly in code. This is convenient for local development and testing. You can also load a base configuration from environment variables or a configuration file, and then override specific options in code.
Use the connect() method on the Client class to create and connect to a Temporal Client to the Temporal Service.
# ...
async def main():
client = await Client.connect("localhost:7233")
result = await client.execute_workflow(
YourWorkflow.run,
"your name",
id="your-workflow-id",
task_queue="your-task-queue",
)
print(f"Result: {result}")
if __name__ == "__main__":
asyncio.run(main())
- Configuration File
- Environment Variables
- Code
You can use a TOML configuration file to set connection options for the Temporal Client. The configuration file lets you
configure multiple profiles, each with its own set of connection options. You can then specify which profile to use when
creating the Temporal Client. You can use the environment variable TEMPORAL_CONFIG_FILE to specify the location of the
TOML file or provide the path to the file directly in code. If you don't provide the configuration file path, the SDK
looks for it at the path ~/.config/temporalio/temporal.toml or the equivalent on your OS. Refer to
Environment Configuration for more details about configuration
files and profiles.
The connection options set in configuration files have lower precedence than environment variables. This means that if you set the same option in both the configuration file and as an environment variable, the environment variable value overrides the option set in the configuration file.
For example, the following TOML configuration file defines two profiles: default and prod. Each profile has its own
set of connection options.
# 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"
# Production profile for Temporal Cloud
[profile.prod]
address = "your-namespace.a1b2c.tmprl.cloud:7233"
namespace = "your-namespace"
api_key = "your-api-key-here"
# TLS configuration for production
[profile.prod.tls]
# TLS auto-enables when TLS config or an API key is present
# disabled = false
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"
You can create a Temporal Client using a profile from the configuration file using the
ClientConfig.load_client_connect_options function as follows. In this example, you load the default profile for
local development:
require 'temporalio/client'
require 'temporalio/env_config'
def main
puts '--- 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 = File.join(__dir__, 'config.toml')
# load_client_connect_options is a helper that loads a profile and prepares
# the configuration for Client.connect. By default, it loads the
# "default" profile.
args, kwargs = Temporalio::EnvConfig::ClientConfig.load_client_connect_options(
config_source: Pathname.new(config_file)
)
puts "Loaded 'default' profile from #{config_file}."
puts " Address: #{args[0]}"
puts " Namespace: #{args[1]}"
puts " gRPC Metadata: #{kwargs[:rpc_metadata]}"
puts "\nAttempting to connect to client..."
begin
client = Temporalio::Client.connect(*args, **kwargs)
puts '✅ Client connected successfully!'
sys_info = client.workflow_service.get_system_info(Temporalio::Api::WorkflowService::V1::GetSystemInfoRequest.new)
puts "✅ Successfully verified connection to Temporal server!\n#{sys_info}"
rescue StandardError => e
puts "❌ Failed to connect: #{e}"
end
end
main if $PROGRAM_NAME == __FILE__
Use the EnvConfig package to set connection options for the Temporal Client using environment variables. For a list of
all available environment variables and their default values, refer to
Environment Configuration.
For example, the following code snippet loads all environment variables and creates a Temporal Client with the options
specified in those variables. If you have defined a configuration file at either the default location
(~/.config/temporalio/temporal.toml) or a custom location specified by the TEMPORAL_CONFIG_FILE environment
variable, this will also load the default profile in the configuration file. However, any options set via environment
variables will take precedence.
Set the following environment variables before running your application. Replace the placeholder values with your actual
configuration. Since this is for a local development Temporal Service, the values connect to localhost:7233 and the
default Namespace. You may omit these variables entirely since they're the defaults.
export TEMPORAL_NAMESPACE="default"
export TEMPORAL_ADDRESS="localhost:7233"
After setting the environment variables, you can create a Temporal Client as follows:
require 'temporalio/client'
require 'temporalio/env_config'
def main
# load_client_connect_options is a helper that loads a profile and prepares
# the configuration for Client.connect. By default, it loads the
# "default" profile and also reads from environment variables. The environment
# variables take precedence over the config file.
args, kwargs = Temporalio::EnvConfig::ClientConfig.load_client_connect_options()
puts " Address: #{args[0]}"
puts " Namespace: #{args[1]}"
puts " gRPC Metadata: #{kwargs[:rpc_metadata]}"
puts "\nAttempting to connect to client..."
begin
client = Temporalio::Client.connect(*args, **kwargs)
puts '✅ Client connected successfully!'
sys_info = client.workflow_service.get_system_info(Temporalio::Api::WorkflowService::V1::GetSystemInfoRequest.new)
puts "✅ Successfully verified connection to Temporal server!\n#{sys_info}"
rescue StandardError => e
puts "❌ Failed to connect: #{e}"
end
end
main if $PROGRAM_NAME == __FILE__
If you don't want to use environment variables or a configuration file, you can specify connection options directly in code. This is convenient for local development and testing. You can also load a base configuration from environment variables or a configuration file, and then override specific options in code.
Use the connect class method on the Temporalio::Client class to create and connect to a Temporal Client to the
Temporal Service.
client = Temporalio::Client.connect('localhost:7233', 'default')
- Configuration File
- Environment Variables
- Code
You can use a TOML configuration file to set connection options for the Temporal Client. The configuration file supports multiple profiles, each with its own connection options.
If you don't specify a configuration file path, the SDK looks in the default OS-specific location. Environment variables take precedence over values from the configuration file.
For example, the following TOML file defines two profiles:
# 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"
# Production profile for Temporal Cloud
[profile.prod]
address = "your-namespace.a1b2c.tmprl.cloud:7233"
namespace = "your-namespace"
api_key = "your-api-key-here"
# TLS configuration for production
[profile.prod.tls]
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"
Load the configuration and connect with the prod profile as follows:
use temporalio_client::{
Client, ClientOptions, Connection
};
use temporalio_common::{envconfig::LoadClientConfigProfileOptions, telemetry::TelemetryOptions};
use temporalio_sdk::{Worker, WorkerOptions};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let runtime = CoreRuntime::new_assume_tokio(
RuntimeOptions::builder()
.telemetry_options(TelemetryOptions::builder().build())
.build()?,
)?;
let (conn_opts, client_opts) =
ClientOptions::load_from_config(LoadClientConfigProfileOptions {
config_file_profile: "prod".to_string().into(),
..Default::default()
})?;
let connection = Connection::connect(conn_opts).await?;
let client = Client::new(connection, client_opts)?;
...
Ok(())
}
You can also configure the Temporal Client with environment variables using envconfig. This is useful for local development, CI, and production deployments.
use temporalio_client::{
Client, ClientOptions, Connection
};
use temporalio_common::{envconfig::LoadClientConfigProfileOptions, telemetry::TelemetryOptions};
use temporalio_sdk::{Worker, WorkerOptions};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let runtime = CoreRuntime::new_assume_tokio(
RuntimeOptions::builder()
.telemetry_options(TelemetryOptions::builder().build())
.build()?,
)?;
let (conn_opts, client_opts) =
ClientOptions::load_from_config(LoadClientConfigProfileOptions::default())?;
let connection = Connection::connect(conn_opts).await?;
let client = Client::new(connection, client_opts)?;
let worker_options = WorkerOptions::new("hello-world")
.register_workflow::<HelloWorldWorkflow>()
.register_activities(GreetingActivities)
.build();
let mut worker = Worker::new(&runtime, client, worker_options)?;
println!("Worker started on task queue: hello-world");
worker.run().await?;
Ok(())
}
You can also specify connection options directly in code. This is convenient for local development and testing.
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let runtime = CoreRuntime::new_assume_tokio(
RuntimeOptions::builder()
.telemetry_options(TelemetryOptions::builder().build())
.build()?,
)?;
let (conn_opts, client_opts) =
ClientOptions::load_from_config(LoadClientConfigProfileOptions::default())?;
let connection = Connection::connect(conn_opts).await?;
let client = Client::new(connection, client_opts)?;
let wf_handle = client.start_workflow(
GreetingsWorkflow::run,
(),
WorkflowStartOptions::new(
"my-task-queue",
"greetings-workflow-10",
).build()
).await?;
}
- Configuration File
- Environment Variables
- Code
You can use a TOML configuration file to set connection options for the Temporal Client. The configuration file lets you configure multiple profiles, each with its own set of connection options. You can then specify which profile to use when creating the Temporal Client.
You can use the environment variable TEMPORAL_CONFIG_FILE to specify the location of the TOML file or provide the path
to the file directly in code. If you don't provide the configuration file path, the SDK looks for it at the path
~/.config/temporalio/temporal.toml or the equivalent on your OS. Refer to
Environment Configuration for more details about configuration files and profiles.
The connection options set in configuration files have lower precedence than environment variables. This means that if you set the same option in both the configuration file and as an environment variable, the environment variable value overrides the option set in the configuration file.
For example, the following TOML configuration file defines two profiles: default and prod. Each profile has its own
set of connection options.
# 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"
# Production profile for Temporal Cloud
[profile.prod]
address = "your-namespace.a1b2c.tmprl.cloud:7233"
namespace = "your-namespace"
api_key = "your-api-key-here"
# TLS configuration for production
[profile.prod.tls]
# TLS auto-enables when TLS config or an API key is present
# disabled = false
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"
You can create a Temporal Client using a profile from the configuration file as follows. In this example, you load the
default profile for local development:
import { Connection, Client } from '@temporalio/client';
import { loadClientConnectConfig } from '@temporalio/envconfig';
import { resolve } from 'path';
async function main() {
console.log('--- 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).
const configFile = resolve(__dirname, '../config.toml');
// loadClientConnectConfig is a helper that loads a profile and prepares
// the configuration for Connection.connect and Client. By default, it loads the
// "default" profile.
const config = loadClientConnectConfig({
configSource: { path: configFile },
});
console.log(`Loaded 'default' profile from ${configFile}.`);
console.log(` Address: ${config.connectionOptions.address}`);
console.log(` Namespace: ${config.namespace}`);
console.log(` gRPC Metadata: ${JSON.stringify(config.connectionOptions.metadata)}`);
console.log('\nAttempting to connect to client...');
try {
const connection = await Connection.connect(config.connectionOptions);
const client = new Client({ connection, namespace: config.namespace });
console.log('✅ Client connected successfully!');
await connection.close();
} catch (err) {
console.log(`❌ Failed to connect: ${err}`);
}
}
main().catch((err) => {
console.error(err);
process.exit(1);
});
Use the @temporalio/envconfig module to set connection options for the Temporal Client using environment variables.
For a list of all available environment variables and their default values, refer to
Environment Configuration.
For example, the following code snippet loads all environment variables and creates a Temporal Client with the options
specified in those variables. If you have defined a configuration file at either the default location
(~/.config/temporalio/temporal.toml) or a custom location specified by the TEMPORAL_CONFIG_FILE environment
variable, this will also load the default profile in the configuration file. However, any options set via environment
variables will take precedence.
Set the following environment variables before running your application. Replace the placeholder values with your actual
configuration. Since this is for a local development Temporal Service, the values connect to localhost:7233 and the
default Namespace. You may omit these variables entirely since they're the defaults.
export TEMPORAL_NAMESPACE="default"
export TEMPORAL_ADDRESS="localhost:7233"
After setting the environment variables, use the following code to create the Temporal Client. Since the environment
variables take precedence, they will override any values set in the configuration file. Therefore, you may leave
loadClientConnectConfig's arguments empty:
import { Connection, Client } from '@temporalio/client';
import { loadClientConnectConfig } from '@temporalio/envconfig';
import { resolve } from 'path';
async function main() {
// ...
const config = loadClientConnectConfig({
// ...
});
// ...
console.log(` Address: ${config.connectionOptions.address}`);
console.log(` Namespace: ${config.namespace}`);
console.log(` gRPC Metadata: ${JSON.stringify(config.connectionOptions.metadata)}`);
console.log('\nAttempting to connect to client...');
try {
const connection = await Connection.connect(config.connectionOptions);
const client = new Client({ connection, namespace: config.namespace });
console.log('✅ Client connected successfully!');
await connection.close();
} catch (err) {
console.log(`❌ Failed to connect: ${err}`);
}
}
main().catch((err) => {
console.error(err);
process.exit(1);
});
If you don't want to use environment variables or a configuration file, you can specify connection options directly in code. This is convenient for local development and testing. You can also load a base configuration from environment variables or a configuration file, and then override specific options in code.
const connection = await Connection.connect({
address: <endpoint>,
tls: true,
apiKey: <APIKey>,
});
const client = new Client({
connection,
namespace: <namespace_id>.<account_id>,
});