diff --git a/.prettierrc b/.prettierrc index e6c7a09257..e5adf502ba 100644 --- a/.prettierrc +++ b/.prettierrc @@ -7,5 +7,5 @@ "semi": true, "arrowParens": "always", "bracketSpacing": true, - "overrides": [{ "files": "**/*.{md,mx}", "options": { "parser": "mdx" } }] + "overrides": [{ "files": "**/*.{md,mdx}", "options": { "parser": "mdx" } }] } diff --git a/docs/cli/cmd-options.mdx b/docs/cli/cmd-options.mdx index 70b233f006..bc35e9a468 100644 --- a/docs/cli/cmd-options.mdx +++ b/docs/cli/cmd-options.mdx @@ -2,7 +2,9 @@ id: cmd-options title: Temporal CLI command options reference sidebar_label: cmd options -description: Discover how to manage Temporal Workflows, from Activity Execution to Workflow Ids, using clusters, cron schedules, dynamic configurations, and logging. Perfect for developers. +description: + Discover how to manage Temporal Workflows, from Activity Execution to Workflow Ids, using clusters, cron schedules, + dynamic configurations, and logging. Perfect for developers. toc_max_heading_level: 4 keywords: - actions @@ -152,12 +154,12 @@ Caution: `--archived` is experimental. ## build-id -Identifies the build to retrieve reachability information for. -Can be specified multiple times. +Identifies the build to retrieve reachability information for. Can be specified multiple times. ## calendar -Calendar specification in JSON `({"dayOfWeek":"Fri","hour":"17","minute":"5"})` or as a Cron string `("30 2 \* \* 5" or "@daily")`. +Calendar specification in JSON `({"dayOfWeek":"Fri","hour":"17","minute":"5"})` or as a Cron string +`("30 2 \* \* 5" or "@daily")`. ## catchup-window @@ -209,23 +211,19 @@ Values must be in JSON format. ## db-filename -File in which to persist Temporal state. -By default, Workflows are lost when the process dies. +File in which to persist Temporal state. By default, Workflows are lost when the process dies. ## depth -The number of Child Workflows to fetch and expand. -Use `-1` to fetch Child Workflows at any depth. +The number of Child Workflows to fetch and expand. Use `-1` to fetch Child Workflows at any depth. ## description -Namespace description or Nexus Endpoint description. -You may use Markdown formatting in the Nexus Endpoint description. +Namespace description or Nexus Endpoint description. You may use Markdown formatting in the Nexus Endpoint description. ## description-file -Path to the Nexus Endpoint description file. -The contents of the description file may use Markdown formatting. +Path to the Nexus Endpoint description file. The contents of the description file may use Markdown formatting. ## detail @@ -237,8 +235,7 @@ Simulate reset without resetting any Workflow Executions. ## dynamic-config-value -Dynamic config value, formatted as `KEY=JSON_VALUE`. -String values require quotation marks. +Dynamic config value, formatted as `KEY=JSON_VALUE`. String values require quotation marks. ## email @@ -254,17 +251,16 @@ Backfill end time. ## env -Name of the environment to read environmental variables from. +Name of the environment to read environment variables from. ## env-file -Path to environment settings file. -Defaults to `$HOME/.config/temporalio/temporal.yaml`. +Path to environment settings file. Defaults to `$HOME/.config/temporalio/temporal.yaml`. ## event-id -The Event Id for any Event after WorkflowTaskStarted you want to reset to (exclusive). -It can be WorkflowTaskCompleted, WorkflowTaskFailed or others. +The Event Id for any Event after WorkflowTaskStarted you want to reset to (exclusive). It can be WorkflowTaskCompleted, +WorkflowTaskFailed or others. ## exclude-file @@ -276,13 +272,12 @@ Timeout (in seconds) for a [Workflow Execution](/workflow-execution), including ## existing-compatible-build-id -A Build Id that already exists in the version sets known by the Task Queue. -New Build Ids are stored in the version set containing this Id, making them compatible with the versions in that set. +A Build Id that already exists in the version sets known by the Task Queue. New Build Ids are stored in the version set +containing this Id, making them compatible with the versions in that set. ## fields -Customize fields to print. -Set to 'long' to automatically print more of main fields. +Customize fields to print. Set to 'long' to automatically print more of main fields. ## first-execution-run-id @@ -307,8 +302,7 @@ Flag to indicate whether a Namespace is a Global Namespace. ## grpc-meta -Contains gRPC metadata to send with requests (format: `key=value`). -Values must be in a valid JSON format. +Contains gRPC metadata to send with requests (format: `key=value`). Values must be in a valid JSON format. ## headless @@ -320,8 +314,7 @@ Maximum permitted time between successful Worker Heartbeats. ## history-archival-state -Sets the history archival state. -Valid values are "disabled" and "enabled". +Sets the history archival state. Valid values are "disabled" and "enabled". ## history-uri @@ -329,8 +322,8 @@ Optionally specify history archival URI (cannot be changed after first time arch ## id-reuse-policy -Allows the same Workflow Id to be used in a new Workflow Execution. -Options: AllowDuplicate, AllowDuplicateFailedOnly, RejectDuplicate, TerminateIfRunning. +Allows the same Workflow Id to be used in a new Workflow Execution. Options: AllowDuplicate, AllowDuplicateFailedOnly, +RejectDuplicate, TerminateIfRunning. ## identity @@ -340,11 +333,11 @@ Specify operator's identity. Use the `--input` command option to include data in the command. -This command option accepts a valid JSON string. -If the entity that the command is acting on accepts multiple parameters, pass "null" for null values within the JSON string. +This command option accepts a valid JSON string. If the entity that the command is acting on accepts multiple +parameters, pass "null" for null values within the JSON string. -The following is an example of starting a Workflow with the `--input` command option. -This Workflow expects a single string as a parameter: +The following is an example of starting a Workflow with the `--input` command option. This Workflow expects a single +string as a parameter: ```shell temporal workflow start --input '"+1 555-555-5555"' @@ -352,14 +345,12 @@ temporal workflow start --input '"+1 555-555-5555"' ## input-file -Passes optional input for the Workflow from a JSON file. -If there are multiple JSON files, concatenate them and separate by space or newline. -Input from the command line will overwrite file input. +Passes optional input for the Workflow from a JSON file. If there are multiple JSON files, concatenate them and separate +by space or newline. Input from the command line will overwrite file input. ## input-parallelism -Number of goroutines to run in parallel. -Each goroutine processes one line for every second. +Number of goroutines to run in parallel. Each goroutine processes one line for every second. ## input-separator @@ -371,8 +362,7 @@ Interval duration, such as 90m, or 90m/13m to include phase offset. ## ip -IPv4 address to bind the frontend service to. -(default: 127.0.0.1) +IPv4 address to bind the frontend service to. (default: 127.0.0.1) ## jitter @@ -392,13 +382,11 @@ Number of items to print on a page. ## log-format -Set the log formatting. -Options: ["json", "pretty"]. +Set the log formatting. Options: ["json", "pretty"]. ## log-level -Set the log level. -Options: ["debug" "info" "warn" "error" "fatal"]. +Set the log level. Options: ["debug" "info" "warn" "error" "fatal"]. ## match-all @@ -410,25 +398,20 @@ Maximum length for each attribute field. ## max-sets -Limits how many compatible sets will be returned. -Specify 1 to return only the current default major version set. -0 returns all sets. +Limits how many compatible sets will be returned. Specify 1 to return only the current default major version set. 0 +returns all sets. ## memo -Set a memo on a schedule (format: key=value). -Use valid JSON formats for value. +Set a memo on a schedule (format: key=value). Use valid JSON formats for value. ## memo-file -Set a memo from a file. -Each line should follow the format key=value. -Use valid JSON formats for value. +Set a memo from a file. Each line should follow the format key=value. Use valid JSON formats for value. ## metrics-port -Port for `/metrics`. -Enabled by default with a randomly assigned port. +Port for `/metrics`. Enabled by default with a randomly assigned port. ## name @@ -444,8 +427,7 @@ Namespace Id. ## no-fold -Disable folding. -All Child Workflows within the set depth will be fetched and displayed. +Disable folding. All Child Workflows within the set depth will be fetched and displayed. ## no-json-shorthand-payloads @@ -465,18 +447,15 @@ Initial value of notes field. ## output -Format of output. -Options: table, json, card. +Format of output. Options: table, json, card. ## overlap-policy -Overlap policy. -Options: Skip, BufferOne, BufferAll, CancelOther, TerminateOther, AllowAll. +Overlap policy. Options: Skip, BufferOne, BufferAll, CancelOther, TerminateOther, AllowAll. ## pager -Sets the pager for the Temporal CLI to use. -Options are less, more, and favoritePager. +Sets the pager for the Temporal CLI to use. Options are less, more, and favoritePager. ## pause @@ -496,18 +475,16 @@ Promote local Namespace to Global Namespace. ## query -Provides a SQL-like Query of Search Attributes to return Workflow Executions to reset. -For more information, refer to the [`temporal workflow list`](/cli/workflow#list) command. +Provides a SQL-like Query of Search Attributes to return Workflow Executions to reset. For more information, refer to +the [`temporal workflow list`](/cli/workflow#list) command. ## raw -Print raw data in a JSON format. -For scripting, we recommend using this option instead of `-o json`. +Print raw data in a JSON format. For scripting, we recommend using this option instead of `-o json`. ## reachability-type -Specify how you'd like to filter the reachability of Build IDs. -The following are valid choices: +Specify how you'd like to filter the reachability of Build IDs. The following are valid choices: - `open`: reachable by one or more open Workflows. - `closed`: reachable by one or more closed Workflows. @@ -517,8 +494,7 @@ Build IDs that are reachable by new Workflows are always reported. ## reapply-type -Event types to reapply after the reset point. -Options: Signal, None. +Event types to reapply after the reset point. Options: Signal, None. ## reason @@ -526,8 +502,7 @@ Reason for the operation. ## reject-condition -Optional flag for rejecting Queries based on Workflow state. -Valid values are "not_open" and "not_completed_cleanly". +Optional flag for rejecting Queries based on Workflow state. Valid values are "not_open" and "not_completed_cleanly". ## remaining-actions @@ -555,9 +530,8 @@ Workflow Execution retention. ## retry-backoff-coefficient -Coefficient used to calculate the next retry interval. -The next retry interval is previous interval multiplied by the coefficient. -Must be 1 or larger. +Coefficient used to calculate the next retry interval. The next retry interval is previous interval multiplied by the +coefficient. Must be 1 or larger. ## retry-initial-interval @@ -565,13 +539,13 @@ Interval of the first retry. If retryBackoffCoefficient is 1.0 then it is used f ## retry-maximum-attempts -Maximum number of attempts. When exceeded the retries stop even if not expired yet. -1 disables retries. 0 means unlimited (up to the timeouts). +Maximum number of attempts. When exceeded the retries stop even if not expired yet. 1 disables retries. 0 means +unlimited (up to the timeouts). ## retry-maximum-interval -Maximum interval between retries. Exponential backoff leads to interval increase. -This value is the cap of the increase. Default is 100x of the initial interval. +Maximum interval between retries. Exponential backoff leads to interval increase. This value is the cap of the increase. +Default is 100x of the initial interval. ## run-id @@ -587,19 +561,17 @@ Schedule Id. ## schedule-to-close-timeout -Indicates how long the caller is willing to wait for an Activity completion. -Limits how long retries will be attempted. +Indicates how long the caller is willing to wait for an Activity completion. Limits how long retries will be attempted. ## schedule-to-start-timeout -Limits time an Activity Task can stay in a task queue before a Worker picks it up. -This timeout is always non retryable, as all a retry would achieve is to put it back into the same queue. -Defaults to `schedule_to_close_timeout` or workflow execution timeout if not specified. +Limits time an Activity Task can stay in a task queue before a Worker picks it up. This timeout is always non retryable, +as all a retry would achieve is to put it back into the same queue. Defaults to `schedule_to_close_timeout` or workflow +execution timeout if not specified. ## search-attribute -Set Search Attribute on a Schedule (formatted as `key=value`). -Use valid JSON formats for value. +Set Search Attribute on a Schedule (formatted as `key=value`). Use valid JSON formats for value. ## set-as-default @@ -617,8 +589,7 @@ Skip a Workflow Execution if the current Run is open for the same Workflow Id as ## sqlite-pragma -Specify sqlite pragma statements in pragma=value format. -Pragma options: ["journal_mode" "synchronous"]. +Specify sqlite pragma statements in pragma=value format. Pragma options: ["journal_mode" "synchronous"]. ## start-delay @@ -630,8 +601,7 @@ Backfill start time. ## start-to-close-timeout -Maximum time an Activity is allowed to execute after being picked up by a Worker. -This Timeout is always retryable. +Maximum time an Activity is allowed to execute after being picked up by a Worker. This Timeout is always retryable. ## target-namespace @@ -643,8 +613,8 @@ Task Queue in which a handler Worker will poll for Nexus tasks. ## target-url -An external Nexus Endpoint where Nexus requests are forwarded to. -May be used as an alternative to `--target-namespace` and `--target-task-queue`. +An external Nexus Endpoint where Nexus requests are forwarded to. May be used as an alternative to `--target-namespace` +and `--target-task-queue`. :::note @@ -658,8 +628,7 @@ Task Queue. ## task-queue-type -Task Queue type, which can be either Workflow or Activity. -The default type is Workflow. +Task Queue type, which can be either Workflow or Activity. The default type is Workflow. ## task-timeout @@ -711,8 +680,7 @@ Overrides the target TLS server name. ## type -Search attribute type. -Options: Text, Keyword, Int, Double, Bool, Datetime, KeywordList. +Search attribute type. Options: Text, Keyword, Int, Double, Bool, Datetime, KeywordList. ## ui-asset-path @@ -728,8 +696,7 @@ IPv4 address to bind the Web UI to. ## ui-port -Port for the Web UI. -Default: `--port` + 1000 (for example, 4000). +Port for the Web UI. Default: `--port` + 1000 (for example, 4000). ## unpause @@ -745,13 +712,11 @@ Print applied Namespace changes. ## visibility-archival-state -Visibility Archival state. -Valid values: "disabled", "enabled". +Visibility Archival state. Valid values: "disabled", "enabled". ## visibility-uri -Specify URI for Visibility Archival. -This cannot be changed after Archival is enabled. +Specify URI for Visibility Archival. This cannot be changed after Archival is enabled. ## workflow-id diff --git a/docs/cli/config.mdx b/docs/cli/config.mdx index f9d0216660..e432faa2df 100644 --- a/docs/cli/config.mdx +++ b/docs/cli/config.mdx @@ -2,7 +2,9 @@ id: config title: Temporal CLI config command reference sidebar_label: config -description: Temporal CLI 'config' commands allow the getting, setting, deleting, and listing of configuration properties for connecting to Temporal. +description: + Temporal CLI 'config' commands allow the getting, setting, deleting, and listing of configuration properties for + connecting to Temporal. toc_max_heading_level: 4 keywords: - cli reference @@ -19,8 +21,9 @@ tags: - Temporal CLI --- -{/* NOTE: This is an auto-generated file. Any edit to this file will be overwritten. -This file is generated from https://github.com/temporalio/cli/blob/main/temporalcli/commandsgen/commands.yml */} +{/* NOTE: This is an auto-generated file. Any edit to this file will be overwritten. This file is generated from +https://github.com/temporalio/cli/blob/main/temporalcli/commandsgen/commands.yml */} + ## delete Remove a property within a profile. @@ -66,7 +69,8 @@ Remote Codec Server endpoint. **--codec-header** _string[]_ -HTTP headers for requests to codec server. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple headers. +HTTP headers for requests to codec server. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple +headers. **--color** _string-enum_ @@ -78,7 +82,8 @@ The command execution timeout. 0s means no timeout. **--config-file** _string_ -File path to read TOML config from, defaults to `$CONFIG_PATH/temporalio/temporal.toml` where `$CONFIG_PATH` is defined as `$HOME/.config` on Unix, "$HOME/Library/Application Support" on macOS, and %AppData% on Windows. +File path to read TOML config from, defaults to `$CONFIG_PATH/temporalio/temporal.toml` where `$CONFIG_PATH` is defined +as `$HOME/.config` on Unix, "$HOME/Library/Application Support" on macOS, and %AppData% on Windows. :::note @@ -116,7 +121,8 @@ Path to environment settings file. Defaults to `$HOME/.config/temporalio/tempora **--grpc-meta** _string[]_ -HTTP headers for requests. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple headers. Can also be made available via environment variable as `TEMPORAL_GRPC_META_[name]`. +HTTP headers for requests. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple headers. Can also +be made available via environment variable as `TEMPORAL_GRPC_META_[name]`. **--identity** _string_ @@ -128,7 +134,8 @@ Log format. Accepted values: text, json. (default "text") **--log-level** _string-enum_ -Log level. Default is "info" for most commands and "warn" for `server start-dev`. Accepted values: debug, info, warn, error, never. (default "info") +Log level. Default is "info" for most commands and "warn" for `server start-dev`. Accepted values: debug, info, warn, +error, never. (default "info") **--namespace**, **-n** _string_ @@ -158,7 +165,8 @@ Time format. Accepted values: relative, iso, raw. (default "relative") **--tls** _bool_ -Enable base TLS encryption. Does not have additional options like mTLS or client certs. This is defaulted to true if api-key or any other TLS options are present. Use --tls=false to explicitly disable. +Enable base TLS encryption. Does not have additional options like mTLS or client certs. This is defaulted to true if +api-key or any other TLS options are present. Use --tls=false to explicitly disable. **--tls-ca-data** _string_ @@ -231,7 +239,8 @@ Remote Codec Server endpoint. **--codec-header** _string[]_ -HTTP headers for requests to codec server. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple headers. +HTTP headers for requests to codec server. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple +headers. **--color** _string-enum_ @@ -243,7 +252,8 @@ The command execution timeout. 0s means no timeout. **--config-file** _string_ -File path to read TOML config from, defaults to `$CONFIG_PATH/temporal/temporal.toml` where `$CONFIG_PATH` is defined as `$HOME/.config` on Unix, "$HOME/Library/Application Support" on macOS, and %AppData% on Windows. +File path to read TOML config from, defaults to `$CONFIG_PATH/temporal/temporal.toml` where `$CONFIG_PATH` is defined as +`$HOME/.config` on Unix, "$HOME/Library/Application Support" on macOS, and %AppData% on Windows. :::note @@ -281,7 +291,8 @@ Path to environment settings file. Defaults to `$HOME/.config/temporalio/tempora **--grpc-meta** _string[]_ -HTTP headers for requests. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple headers. Can also be made available via environment variable as `TEMPORAL_GRPC_META_[name]`. +HTTP headers for requests. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple headers. Can also +be made available via environment variable as `TEMPORAL_GRPC_META_[name]`. **--identity** _string_ @@ -293,7 +304,8 @@ Log format. Accepted values: text, json. (default "text") **--log-level** _string-enum_ -Log level. Default is "info" for most commands and "warn" for `server start-dev`. Accepted values: debug, info, warn, error, never. (default "info") +Log level. Default is "info" for most commands and "warn" for `server start-dev`. Accepted values: debug, info, warn, +error, never. (default "info") **--namespace**, **-n** _string_ @@ -323,7 +335,8 @@ Time format. Accepted values: relative, iso, raw. (default "relative") **--tls** _bool_ -Enable base TLS encryption. Does not have additional options like mTLS or client certs. This is defaulted to true if api-key or any other TLS options are present. Use --tls=false to explicitly disable. +Enable base TLS encryption. Does not have additional options like mTLS or client certs. This is defaulted to true if +api-key or any other TLS options are present. Use --tls=false to explicitly disable. **--tls-ca-data** _string_ @@ -408,7 +421,8 @@ Remote Codec Server endpoint. **--codec-header** _string[]_ -HTTP headers for requests to codec server. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple headers. +HTTP headers for requests to codec server. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple +headers. **--color** _string-enum_ @@ -420,7 +434,8 @@ The command execution timeout. 0s means no timeout. **--config-file** _string_ -File path to read TOML config from, defaults to `$CONFIG_PATH/temporal/temporal.toml` where `$CONFIG_PATH` is defined as `$HOME/.config` on Unix, "$HOME/Library/Application Support" on macOS, and %AppData% on Windows. +File path to read TOML config from, defaults to `$CONFIG_PATH/temporal/temporal.toml` where `$CONFIG_PATH` is defined as +`$HOME/.config` on Unix, "$HOME/Library/Application Support" on macOS, and %AppData% on Windows. :::note @@ -458,7 +473,8 @@ Path to environment settings file. Defaults to `$HOME/.config/temporalio/tempora **--grpc-meta** _string[]_ -HTTP headers for requests. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple headers. Can also be made available via environment variable as `TEMPORAL_GRPC_META_[name]`. +HTTP headers for requests. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple headers. Can also +be made available via environment variable as `TEMPORAL_GRPC_META_[name]`. **--identity** _string_ @@ -470,7 +486,8 @@ Log format. Accepted values: text, json. (default "text") **--log-level** _string-enum_ -Log level. Default is "info" for most commands and "warn" for `server start-dev`. Accepted values: debug, info, warn, error, never. (default "info") +Log level. Default is "info" for most commands and "warn" for `server start-dev`. Accepted values: debug, info, warn, +error, never. (default "info") **--namespace**, **-n** _string_ @@ -500,7 +517,8 @@ Time format. Accepted values: relative, iso, raw. (default "relative") **--tls** _bool_ -Enable base TLS encryption. Does not have additional options like mTLS or client certs. This is defaulted to true if api-key or any other TLS options are present. Use --tls=false to explicitly disable. +Enable base TLS encryption. Does not have additional options like mTLS or client certs. This is defaulted to true if +api-key or any other TLS options are present. Use --tls=false to explicitly disable. **--tls-ca-data** _string_ @@ -572,7 +590,8 @@ Remote Codec Server endpoint. **--codec-header** _string[]_ -HTTP headers for requests to codec server. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple headers. +HTTP headers for requests to codec server. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple +headers. **--color** _string-enum_ @@ -584,7 +603,8 @@ The command execution timeout. 0s means no timeout. **--config-file** _string_ -File path to read TOML config from, defaults to `$CONFIG_PATH/temporal/temporal.toml` where `$CONFIG_PATH` is defined as `$HOME/.config` on Unix, "$HOME/Library/Application Support" on macOS, and %AppData% on Windows. +File path to read TOML config from, defaults to `$CONFIG_PATH/temporal/temporal.toml` where `$CONFIG_PATH` is defined as +`$HOME/.config` on Unix, "$HOME/Library/Application Support" on macOS, and %AppData% on Windows. :::note @@ -622,7 +642,8 @@ Path to environment settings file. Defaults to `$HOME/.config/temporalio/tempora **--grpc-meta** _string[]_ -HTTP headers for requests. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple headers. Can also be made available via environment variable as `TEMPORAL_GRPC_META_[name]`. +HTTP headers for requests. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple headers. Can also +be made available via environment variable as `TEMPORAL_GRPC_META_[name]`. **--identity** _string_ @@ -634,7 +655,8 @@ Log format. Accepted values: text, json. (default "text") **--log-level** _string-enum_ -Log level. Default is "info" for most commands and "warn" for `server start-dev`. Accepted values: debug, info, warn, error, never. (default "info") +Log level. Default is "info" for most commands and "warn" for `server start-dev`. Accepted values: debug, info, warn, +error, never. (default "info") **--namespace**, **-n** _string_ @@ -664,7 +686,8 @@ Time format. Accepted values: relative, iso, raw. (default "relative") **--tls** _bool_ -Enable base TLS encryption. Does not have additional options like mTLS or client certs. This is defaulted to true if api-key or any other TLS options are present. Use --tls=false to explicitly disable. +Enable base TLS encryption. Does not have additional options like mTLS or client certs. This is defaulted to true if +api-key or any other TLS options are present. Use --tls=false to explicitly disable. **--tls-ca-data** _string_ @@ -748,7 +771,8 @@ Remote Codec Server endpoint. **--codec-header** _string[]_ -HTTP headers for requests to codec server. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple headers. +HTTP headers for requests to codec server. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple +headers. **--color** _string-enum_ @@ -760,7 +784,8 @@ The command execution timeout. 0s means no timeout. **--config-file** _string_ -File path to read TOML config from, defaults to `$CONFIG_PATH/temporal/temporal.toml` where `$CONFIG_PATH` is defined as `$HOME/.config` on Unix, "$HOME/Library/Application Support" on macOS, and %AppData% on Windows. +File path to read TOML config from, defaults to `$CONFIG_PATH/temporal/temporal.toml` where `$CONFIG_PATH` is defined as +`$HOME/.config` on Unix, "$HOME/Library/Application Support" on macOS, and %AppData% on Windows. :::note @@ -798,7 +823,8 @@ Path to environment settings file. Defaults to `$HOME/.config/temporalio/tempora **--grpc-meta** _string[]_ -HTTP headers for requests. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple headers. Can also be made available via environment variable as `TEMPORAL_GRPC_META_[name]`. +HTTP headers for requests. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple headers. Can also +be made available via environment variable as `TEMPORAL_GRPC_META_[name]`. **--identity** _string_ @@ -810,7 +836,8 @@ Log format. Accepted values: text, json. (default "text") **--log-level** _string-enum_ -Log level. Default is "info" for most commands and "warn" for `server start-dev`. Accepted values: debug, info, warn, error, never. (default "info") +Log level. Default is "info" for most commands and "warn" for `server start-dev`. Accepted values: debug, info, warn, +error, never. (default "info") **--namespace**, **-n** _string_ @@ -840,7 +867,8 @@ Time format. Accepted values: relative, iso, raw. (default "relative") **--tls** _bool_ -Enable base TLS encryption. Does not have additional options like mTLS or client certs. This is defaulted to true if api-key or any other TLS options are present. Use --tls=false to explicitly disable. +Enable base TLS encryption. Does not have additional options like mTLS or client certs. This is defaulted to true if +api-key or any other TLS options are present. Use --tls=false to explicitly disable. **--tls-ca-data** _string_ @@ -873,4 +901,3 @@ Path to x509 private key. Can't be used with --tls-key-data. **--tls-server-name** _string_ Override target TLS server name. - diff --git a/docs/cli/env.mdx b/docs/cli/env.mdx index 97dd6a47c9..3b37c2d392 100644 --- a/docs/cli/env.mdx +++ b/docs/cli/env.mdx @@ -2,7 +2,9 @@ id: env title: Temporal CLI env command reference sidebar_label: env -description: Temporal CLI 'env' commands allow the configuration, setting, deleting, and listing of environmental properties, making it easy to manage Temporal Server instances. +description: + Temporal CLI 'env' commands allow the configuration, setting, deleting, and listing of environment properties, making + it easy to manage Temporal Server instances. toc_max_heading_level: 4 keywords: - cli reference @@ -19,13 +21,13 @@ tags: - Temporal CLI --- -{/* NOTE: This is an auto-generated file. Any edit to this file will be overwritten. -This file is generated from https://github.com/temporalio/cli/blob/main/temporalcli/commandsgen/commands.yml */} +{/* NOTE: This is an auto-generated file. Any edit to this file will be overwritten. This file is generated from +https://github.com/temporalio/cli/blob/main/temporalcli/commandsgen/commands.yml */} + ## delete -Remove a presets environment entirely _or_ remove a key-value pair within an -environment. If you don't specify an environment (with `--env` or by setting -the `TEMPORAL_ENV` variable), this command updates the "default" environment: +Remove a presets environment entirely _or_ remove a key-value pair within an environment. If you don't specify an +environment (with `--env` or by setting the `TEMPORAL_ENV` variable), this command updates the "default" environment: ``` temporal env delete \ @@ -76,7 +78,8 @@ Remote Codec Server endpoint. **--codec-header** _string[]_ -HTTP headers for requests to codec server. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple headers. +HTTP headers for requests to codec server. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple +headers. **--color** _string-enum_ @@ -88,7 +91,8 @@ The command execution timeout. 0s means no timeout. **--config-file** _string_ -File path to read TOML config from, defaults to `$CONFIG_PATH/temporal/temporal.toml` where `$CONFIG_PATH` is defined as `$HOME/.config` on Unix, "$HOME/Library/Application Support" on macOS, and %AppData% on Windows. +File path to read TOML config from, defaults to `$CONFIG_PATH/temporal/temporal.toml` where `$CONFIG_PATH` is defined as +`$HOME/.config` on Unix, "$HOME/Library/Application Support" on macOS, and %AppData% on Windows. :::note @@ -126,7 +130,8 @@ Path to environment settings file. Defaults to `$HOME/.config/temporalio/tempora **--grpc-meta** _string[]_ -HTTP headers for requests. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple headers. Can also be made available via environment variable as `TEMPORAL_GRPC_META_[name]`. +HTTP headers for requests. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple headers. Can also +be made available via environment variable as `TEMPORAL_GRPC_META_[name]`. **--identity** _string_ @@ -138,7 +143,8 @@ Log format. Accepted values: text, json. (default "text") **--log-level** _string-enum_ -Log level. Default is "info" for most commands and "warn" for `server start-dev`. Accepted values: debug, info, warn, error, never. (default "info") +Log level. Default is "info" for most commands and "warn" for `server start-dev`. Accepted values: debug, info, warn, +error, never. (default "info") **--namespace**, **-n** _string_ @@ -168,7 +174,8 @@ Time format. Accepted values: relative, iso, raw. (default "relative") **--tls** _bool_ -Enable base TLS encryption. Does not have additional options like mTLS or client certs. This is defaulted to true if api-key or any other TLS options are present. Use --tls=false to explicitly disable. +Enable base TLS encryption. Does not have additional options like mTLS or client certs. This is defaulted to true if +api-key or any other TLS options are present. Use --tls=false to explicitly disable. **--tls-ca-data** _string_ @@ -219,9 +226,8 @@ temporal env get \ --key YourPropertyKey ``` -If you don't specify an environment (with `--env` or by setting the -`TEMPORAL_ENV` variable), this command lists properties of the "default" -environment. +If you don't specify an environment (with `--env` or by setting the `TEMPORAL_ENV` variable), this command lists +properties of the "default" environment. Use the following options to change the behavior of this command. @@ -259,7 +265,8 @@ Remote Codec Server endpoint. **--codec-header** _string[]_ -HTTP headers for requests to codec server. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple headers. +HTTP headers for requests to codec server. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple +headers. **--color** _string-enum_ @@ -271,7 +278,8 @@ The command execution timeout. 0s means no timeout. **--config-file** _string_ -File path to read TOML config from, defaults to `$CONFIG_PATH/temporal/temporal.toml` where `$CONFIG_PATH` is defined as `$HOME/.config` on Unix, "$HOME/Library/Application Support" on macOS, and %AppData% on Windows. +File path to read TOML config from, defaults to `$CONFIG_PATH/temporal/temporal.toml` where `$CONFIG_PATH` is defined as +`$HOME/.config` on Unix, "$HOME/Library/Application Support" on macOS, and %AppData% on Windows. :::note @@ -309,7 +317,8 @@ Path to environment settings file. Defaults to `$HOME/.config/temporalio/tempora **--grpc-meta** _string[]_ -HTTP headers for requests. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple headers. Can also be made available via environment variable as `TEMPORAL_GRPC_META_[name]`. +HTTP headers for requests. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple headers. Can also +be made available via environment variable as `TEMPORAL_GRPC_META_[name]`. **--identity** _string_ @@ -321,7 +330,8 @@ Log format. Accepted values: text, json. (default "text") **--log-level** _string-enum_ -Log level. Default is "info" for most commands and "warn" for `server start-dev`. Accepted values: debug, info, warn, error, never. (default "info") +Log level. Default is "info" for most commands and "warn" for `server start-dev`. Accepted values: debug, info, warn, +error, never. (default "info") **--namespace**, **-n** _string_ @@ -351,7 +361,8 @@ Time format. Accepted values: relative, iso, raw. (default "relative") **--tls** _bool_ -Enable base TLS encryption. Does not have additional options like mTLS or client certs. This is defaulted to true if api-key or any other TLS options are present. Use --tls=false to explicitly disable. +Enable base TLS encryption. Does not have additional options like mTLS or client certs. This is defaulted to true if +api-key or any other TLS options are present. Use --tls=false to explicitly disable. **--tls-ca-data** _string_ @@ -387,8 +398,8 @@ Override target TLS server name. ## list -List the environments you have set up on your local computer. Environments are -stored in "$HOME/.config/temporalio/temporal.yaml". +List the environments you have set up on your local computer. Environments are stored in +"$HOME/.config/temporalio/temporal.yaml". Use the following options to change the behavior of this command. @@ -420,7 +431,8 @@ Remote Codec Server endpoint. **--codec-header** _string[]_ -HTTP headers for requests to codec server. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple headers. +HTTP headers for requests to codec server. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple +headers. **--color** _string-enum_ @@ -432,7 +444,8 @@ The command execution timeout. 0s means no timeout. **--config-file** _string_ -File path to read TOML config from, defaults to `$CONFIG_PATH/temporal/temporal.toml` where `$CONFIG_PATH` is defined as `$HOME/.config` on Unix, "$HOME/Library/Application Support" on macOS, and %AppData% on Windows. +File path to read TOML config from, defaults to `$CONFIG_PATH/temporal/temporal.toml` where `$CONFIG_PATH` is defined as +`$HOME/.config` on Unix, "$HOME/Library/Application Support" on macOS, and %AppData% on Windows. :::note @@ -470,7 +483,8 @@ Path to environment settings file. Defaults to `$HOME/.config/temporalio/tempora **--grpc-meta** _string[]_ -HTTP headers for requests. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple headers. Can also be made available via environment variable as `TEMPORAL_GRPC_META_[name]`. +HTTP headers for requests. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple headers. Can also +be made available via environment variable as `TEMPORAL_GRPC_META_[name]`. **--identity** _string_ @@ -482,7 +496,8 @@ Log format. Accepted values: text, json. (default "text") **--log-level** _string-enum_ -Log level. Default is "info" for most commands and "warn" for `server start-dev`. Accepted values: debug, info, warn, error, never. (default "info") +Log level. Default is "info" for most commands and "warn" for `server start-dev`. Accepted values: debug, info, warn, +error, never. (default "info") **--namespace**, **-n** _string_ @@ -512,7 +527,8 @@ Time format. Accepted values: relative, iso, raw. (default "relative") **--tls** _bool_ -Enable base TLS encryption. Does not have additional options like mTLS or client certs. This is defaulted to true if api-key or any other TLS options are present. Use --tls=false to explicitly disable. +Enable base TLS encryption. Does not have additional options like mTLS or client certs. This is defaulted to true if +api-key or any other TLS options are present. Use --tls=false to explicitly disable. **--tls-ca-data** _string_ @@ -557,13 +573,11 @@ temporal env set \ --value value ``` -If you don't specify an environment (with `--env` or by setting the -`TEMPORAL_ENV` variable), this command sets properties in the "default" -environment. +If you don't specify an environment (with `--env` or by setting the `TEMPORAL_ENV` variable), this command sets +properties in the "default" environment. -Storing keys with CLI option names lets the CLI automatically set those -options for you. This reduces effort and helps avoid typos when issuing -commands. +Storing keys with CLI option names lets the CLI automatically set those options for you. This reduces effort and helps +avoid typos when issuing commands. Use the following options to change the behavior of this command. @@ -605,7 +619,8 @@ Remote Codec Server endpoint. **--codec-header** _string[]_ -HTTP headers for requests to codec server. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple headers. +HTTP headers for requests to codec server. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple +headers. **--color** _string-enum_ @@ -617,7 +632,8 @@ The command execution timeout. 0s means no timeout. **--config-file** _string_ -File path to read TOML config from, defaults to `$CONFIG_PATH/temporal/temporal.toml` where `$CONFIG_PATH` is defined as `$HOME/.config` on Unix, "$HOME/Library/Application Support" on macOS, and %AppData% on Windows. +File path to read TOML config from, defaults to `$CONFIG_PATH/temporal/temporal.toml` where `$CONFIG_PATH` is defined as +`$HOME/.config` on Unix, "$HOME/Library/Application Support" on macOS, and %AppData% on Windows. :::note @@ -655,7 +671,8 @@ Path to environment settings file. Defaults to `$HOME/.config/temporalio/tempora **--grpc-meta** _string[]_ -HTTP headers for requests. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple headers. Can also be made available via environment variable as `TEMPORAL_GRPC_META_[name]`. +HTTP headers for requests. Format as a `KEY=VALUE` pair. May be passed multiple times to set multiple headers. Can also +be made available via environment variable as `TEMPORAL_GRPC_META_[name]`. **--identity** _string_ @@ -667,7 +684,8 @@ Log format. Accepted values: text, json. (default "text") **--log-level** _string-enum_ -Log level. Default is "info" for most commands and "warn" for `server start-dev`. Accepted values: debug, info, warn, error, never. (default "info") +Log level. Default is "info" for most commands and "warn" for `server start-dev`. Accepted values: debug, info, warn, +error, never. (default "info") **--namespace**, **-n** _string_ @@ -697,7 +715,8 @@ Time format. Accepted values: relative, iso, raw. (default "relative") **--tls** _bool_ -Enable base TLS encryption. Does not have additional options like mTLS or client certs. This is defaulted to true if api-key or any other TLS options are present. Use --tls=false to explicitly disable. +Enable base TLS encryption. Does not have additional options like mTLS or client certs. This is defaulted to true if +api-key or any other TLS options are present. Use --tls=false to explicitly disable. **--tls-ca-data** _string_ @@ -730,4 +749,3 @@ Path to x509 private key. Can't be used with --tls-key-data. **--tls-server-name** _string_ Override target TLS server name. - diff --git a/docs/cli/index.mdx b/docs/cli/index.mdx index 1491ba7c9b..87a72c88c9 100644 --- a/docs/cli/index.mdx +++ b/docs/cli/index.mdx @@ -2,7 +2,9 @@ id: index title: Temporal CLI command reference sidebar_label: Temporal CLI -description: The Temporal CLI offers terminal access to Temporal Services for managing, monitoring, and debugging Workflows and Activities, including Namespace and Task Queue management, with embedded development support. +description: + The Temporal CLI offers terminal access to Temporal Services for managing, monitoring, and debugging Workflows and + Activities, including Namespace and Task Queue management, with embedded development support. slug: /cli toc_max_heading_level: 4 keywords: @@ -15,17 +17,17 @@ tags: - Temporal CLI --- -The Temporal CLI provides direct access to a Temporal Service via the terminal. -It's a powerful tool for managing, monitoring, and debugging Temporal Applications. -You can use it to start, stop, inspect and operate on Workflows and Activities, and perform administrative tasks such as Namespace, Schedule, and Task Queue management. +The Temporal CLI provides direct access to a Temporal Service via the terminal. It's a powerful tool for managing, +monitoring, and debugging Temporal Applications. You can use it to start, stop, inspect and operate on Workflows and +Activities, and perform administrative tasks such as Namespace, Schedule, and Task Queue management. -The Temporal CLI also includes an embedded Temporal Service suitable for use in development and CI/CD. -It includes the [Temporal Server](/temporal-service/temporal-server), SQLite persistence, and the [Temporal Web UI](/web-ui). +The Temporal CLI also includes an embedded Temporal Service suitable for use in development and CI/CD. It includes the +[Temporal Server](/temporal-service/temporal-server), SQLite persistence, and the [Temporal Web UI](/web-ui). :::note -When upgrading from [tctl](/tctl-v1) to the Temporal CLI, make sure to update your environment variables and use updated commands. -For details, see [CLI release notes](https://github.com/temporalio/cli/releases/). +When upgrading from [tctl](/tctl-v1) to the Temporal CLI, make sure to update your environment variables and use updated +commands. For details, see [CLI release notes](https://github.com/temporalio/cli/releases/). ::: @@ -88,7 +90,8 @@ Choose one of the following methods to install the Temporal CLI on Windows: ### How to run the Temporal CLI inside Docker -Temporal CLI container image is available on [DockerHub](https://hub.docker.com/r/temporalio/temporal) and can be run directly: +Temporal CLI container image is available on [DockerHub](https://hub.docker.com/r/temporalio/temporal) and can be run +directly: ```shell docker run --rm temporalio/temporal --help @@ -96,8 +99,8 @@ docker run --rm temporalio/temporal --help :::note -When running the CLI inside Docker, for the development server to be accessible from the host system, -the server needs to be configured to listen on external IP and the ports need to be forwarded: +When running the CLI inside Docker, for the development server to be accessible from the host system, the server needs +to be configured to listen on external IP and the ports need to be forwarded: ```shell docker run --rm -p 7233:7233 -p 8233:8233 temporalio/temporal server start-dev --ip 0.0.0.0 @@ -123,8 +126,8 @@ The following information provides important configuration details. ### Namespace registration -Namespaces are pre-registered at startup for immediate use. -Customize pre-registered Namespaces with the following command: +Namespaces are pre-registered at startup for immediate use. Customize pre-registered Namespaces with the following +command: ```shell temporal server start-dev --namespace foo --namespace bar @@ -138,8 +141,8 @@ temporal operator namespace create --namespace foo ### Enable or disable Temporal UI -By default, the Temporal UI is enabled when running the development server using the Temporal CLI. -To disable the UI, use the `--headless` modifier: +By default, the Temporal UI is enabled when running the development server using the Temporal CLI. To disable the UI, +use the `--headless` modifier: ```shell temporal server start-dev --headless @@ -149,8 +152,8 @@ temporal server start-dev --headless Advanced Temporal CLI configuration requires a dynamic configuration file. -To set values on the command line, use `--dynamic-config-value KEY=JSON_VALUE`. -For example, enable the Search Attribute cache: +To set values on the command line, use `--dynamic-config-value KEY=JSON_VALUE`. For example, enable the Search Attribute +cache: ```bash temporal server start-dev --dynamic-config-value system.forceSearchAttributesCacheRefreshOnRead=false @@ -188,13 +191,13 @@ Do not confuse environment variables, set with your shell, with temporal env opt ## Proxy support -The Temporal CLI provides support for users who are operating behind a proxy. -This feature ensures seamless communication even in network-restricted environments. +The Temporal CLI provides support for users who are operating behind a proxy. This feature ensures seamless +communication even in network-restricted environments. #### Setting up proxy support -If you are behind a proxy, you'll need to instruct the Temporal CLI to route its requests via that proxy. -You can achieve this by setting the `HTTPS_PROXY` environment variable. +If you are behind a proxy, you'll need to instruct the Temporal CLI to route its requests via that proxy. You can +achieve this by setting the `HTTPS_PROXY` environment variable. ```command export HTTPS_PROXY=: @@ -206,14 +209,17 @@ Once set, you can run the Temporal CLI commands as you normally would. :::note -Temporal CLI uses the gRPC library which natively supports HTTP CONNECT proxies. The gRPC library checks for the `HTTPS_PROXY` (and its case-insensitive variants) environment variable to determine if it should route requests through a proxy. +Temporal CLI uses the gRPC library which natively supports HTTP CONNECT proxies. The gRPC library checks for the +`HTTPS_PROXY` (and its case-insensitive variants) environment variable to determine if it should route requests through +a proxy. ::: -In addition to `HTTPS_PROXY`, gRPC also respects the `NO_PROXY` environment variable. -This can be useful if there are specific addresses or domains you wish to exclude from proxying. +In addition to `HTTPS_PROXY`, gRPC also respects the `NO_PROXY` environment variable. This can be useful if there are +specific addresses or domains you wish to exclude from proxying. -For more information, see [Proxy](https://github.com/grpc/grpc-go/blob/master/Documentation/proxy.md) in the gRPC documentation. +For more information, see [Proxy](https://github.com/grpc/grpc-go/blob/master/Documentation/proxy.md) in the gRPC +documentation. ## Auto-completion @@ -235,7 +241,8 @@ Enable auto-completion using the following commands. ### Bash auto-completion -1. Install [bash-completion](https://github.com/scop/bash-completion#installation) and add the software to your `~/.bashrc`. +1. Install [bash-completion](https://github.com/scop/bash-completion#installation) and add the software to your + `~/.bashrc`. 2. Add the following line to your `~/.bashrc` startup script: @@ -251,7 +258,9 @@ Enable auto-completion using the following commands. :::note -If auto-completion fails with the error: `bash: _get_comp_words_by_ref: command not found`, you did not successfully install [bash-completion](https://github.com/scop/bash-completion#installation). This package must be loaded into your shell for `temporal` auto-completion to work. +If auto-completion fails with the error: `bash: _get_comp_words_by_ref: command not found`, you did not successfully +install [bash-completion](https://github.com/scop/bash-completion#installation). This package must be loaded into your +shell for `temporal` auto-completion to work. ::: @@ -263,7 +272,8 @@ If auto-completion fails with the error: `bash: _get_comp_words_by_ref: command mkdir -p ~/.config/fish/completions ``` -2. Configure the completions to load when needed. Note: the file name must be `temporal.fish` or the completions will not be found: +2. Configure the completions to load when needed. Note: the file name must be `temporal.fish` or the completions will + not be found: ```fish echo 'eval "$(temporal completion fish)"' >~/.config/fish/completions/temporal.fish @@ -285,13 +295,14 @@ To start the Temporal development server run the following command: temporal server start-dev ``` -This command automatically starts the Web UI, creates the `default` [Namespace](/namespaces), and uses an in-memory database. +This command automatically starts the Web UI, creates the `default` [Namespace](/namespaces), and uses an in-memory +database. -The Temporal Server should be available on `localhost:7233` and the Temporal Web UI should be available at [`http://localhost:8233`](http://localhost:8233/). +The Temporal Server should be available on `localhost:7233` and the Temporal Web UI should be available at +[`http://localhost:8233`](http://localhost:8233/). -The in-memory SQLite database does not persist if you stop the dev server. -Use the `--db-filename` option to specify a database file, persisting application state. -This is helpful if you plan on stopping and re-starting the dev server. +The in-memory SQLite database does not persist if you stop the dev server. Use the `--db-filename` option to specify a +database file, persisting application state. This is helpful if you plan on stopping and re-starting the dev server. ```shell temporal server start-dev --db-filename temporal.db @@ -299,8 +310,8 @@ temporal server start-dev --db-filename temporal.db :::note -Local databases created with `--db-filename` may not be compatible with newer versions of the Temporal CLI. -The `temporal server` command is only intended for development environments. +Local databases created with `--db-filename` may not be compatible with newer versions of the Temporal CLI. The +`temporal server` command is only intended for development environments. ::: @@ -316,8 +327,7 @@ The following are some of the more common operations you can perform with the Te ### Start a Workflow -In another terminal, use the following commands to interact with the Server. -The following command starts a Workflow: +In another terminal, use the following commands to interact with the Server. The following command starts a Workflow: ```shell $ temporal workflow start \ @@ -432,7 +442,8 @@ $ temporal workflow list --fields long --output json | jq '.[].type.name' | uniq 2 "MyWorkflow" ``` -To see the full range of Workflow-related commands, run `temporal workflow` or see the [Temporal CLI workflow command reference](/cli/workflow). +To see the full range of Workflow-related commands, run `temporal workflow` or see the +[Temporal CLI workflow command reference](/cli/workflow). For a full list of available commands, run `temporal` without arguments or see [Available commands](#command-set). @@ -481,7 +492,7 @@ OPTIONS: --codec-auth value Sets the authorization header on requests to the Codec Server. [$TEMPORAL_CLI_CODEC_AUTH] --codec-endpoint value Endpoint for a remote Codec Server. [$TEMPORAL_CLI_CODEC_ENDPOINT] --command-timeout duration Timeout for the span of a command. (default 0s) - --env value Name of the environment to read environmental variables from. (default: "default") + --env value Name of the environment to read environment variables from. (default: "default") --grpc-meta value [ --grpc-meta value ] Contains gRPC metadata to send with requests (format: key=value). Values must be in a valid JSON format. --namespace value, -n value Identifies a Namespace in the Temporal Workflow. (default: "default") [$TEMPORAL_CLI_NAMESPACE] --tls-ca-path value Path to server CA certificate. [$TEMPORAL_CLI_TLS_CA] diff --git a/docs/develop/dotnet/index.mdx b/docs/develop/dotnet/index.mdx index 581b479c44..d669264802 100644 --- a/docs/develop/dotnet/index.mdx +++ b/docs/develop/dotnet/index.mdx @@ -2,7 +2,9 @@ id: index title: .Net SDK developer guide sidebar_label: .NET SDK -description: Use the Temporal .NET SDK to develop Temporal Applications, connect to the Temporal Service, test Workflows and Activities, handle failures, send messages, and more. +description: + Use the Temporal .NET SDK to develop Temporal Applications, connect to the Temporal Service, test Workflows and + Activities, handle failures, send messages, and more. toc_max_heading_level: 4 keywords: - dotnet @@ -18,7 +20,8 @@ import * as Components from '@site/src/components'; ![.NET SDK Banner](/img/assets/banner-dotnet-temporal.png) -:::info .NET SPECIFIC RESOURCES +:::info .NET SPECIFIC RESOURCES + Build Temporal Applications with the .NET SDK. **Temporal .NET Technical Resources:** @@ -32,48 +35,68 @@ Build Temporal Applications with the .NET SDK. **Get Connected with the Temporal .NET Community:** - [Temporal .NET Community Slack](https://temporalio.slack.com/archives/C012SHMPDDZ) -- [.NET SDK Forum](https://community.temporal.io/tag/dotnet-sdk) - ::: +- [.NET SDK Forum](https://community.temporal.io/tag/dotnet-sdk) -## [Core Application](/develop/dotnet/core-application) +::: -Use the essential components of a Temporal Application (Workflows, Activities, and Workers) to build and run a Temporal application. +## [Core Application](/develop/dotnet/core-application) -- [Develop a basic Workflow Definition](/develop/dotnet/core-application#develop-workflow): Workflows are the fundamental unit of a Temporal Application, and it all starts with the development of a Workflow Definition. -- [Develop a basic Activity Definition](/develop/dotnet/core-application#develop-activity): One of the primary things that Workflows do is orchestrate the execution of Activities. -- [Start an Activity from a Workflow](/develop/dotnet/core-application#activity-execution): Calls to spawn Activity Executions are written within a Workflow Definition. -- [Run a Worker Process](/develop/dotnet/core-application#run-worker-process): The Worker Process is where Workflow Functions and Activity Functions are executed. -- [Set a Dynamic Workflow](/develop/dotnet/core-application#set-a-dynamic-workflow): Set a Workflow that can be invoked dynamically at runtime. -- [Set a Dynamic Activity](/develop/dotnet/core-application#set-a-dynamic-activity): Set an Activity that can be invoked dynamically at runtime. +Use the essential components of a Temporal Application (Workflows, Activities, and Workers) to build and run a Temporal +application. + +- [Develop a basic Workflow Definition](/develop/dotnet/core-application#develop-workflow): Workflows are the + fundamental unit of a Temporal Application, and it all starts with the development of a Workflow Definition. +- [Develop a basic Activity Definition](/develop/dotnet/core-application#develop-activity): One of the primary things + that Workflows do is orchestrate the execution of Activities. +- [Start an Activity from a Workflow](/develop/dotnet/core-application#activity-execution): Calls to spawn Activity + Executions are written within a Workflow Definition. +- [Run a Worker Process](/develop/dotnet/core-application#run-worker-process): The Worker Process is where Workflow + Functions and Activity Functions are executed. +- [Set a Dynamic Workflow](/develop/dotnet/core-application#set-a-dynamic-workflow): Set a Workflow that can be invoked + dynamically at runtime. +- [Set a Dynamic Activity](/develop/dotnet/core-application#set-a-dynamic-activity): Set an Activity that can be invoked + dynamically at runtime. ## [Temporal Client](/develop/dotnet/temporal-client) Connect to a Temporal Service and start a Workflow Execution. -- [Create a Temporal Client](/develop/dotnet/temporal-client#create-a-client): Instantiate and configure a client to interact with the Temporal Service. -- [Connect to Temporal Cloud](/develop/dotnet/temporal-client#connect-to-temporal-cloud): Securely connect to the Temporal Cloud for a fully managed service. +- [Create a Temporal Client](/develop/dotnet/temporal-client#connect-to-development-service): Instantiate and configure + a client to interact with the Temporal Service. +- [Connect to Temporal Cloud](/develop/dotnet/temporal-client#connect-to-temporal-cloud): Securely connect to the + Temporal Cloud for a fully managed service. - [Start a Workflow](/develop/dotnet/temporal-client#start-workflow): Initiate Workflows seamlessly via the .NET SDK. -- [Get Workflow results](/develop/dotnet/temporal-client#get-workflow-results): Retrieve and process the results of your Workflows efficiently. +- [Get Workflow results](/develop/dotnet/temporal-client#get-workflow-results): Retrieve and process the results of your + Workflows efficiently. ## [Testing](/develop/dotnet/testing-suite) Set up the testing suite and test Workflows and Activities. -- [Test frameworks](/develop/dotnet/testing-suite#test-frameworks): Testing provides a framework to facilitate Workflow and integration testing. -- [Testing Workflows](/develop/dotnet/testing-suite#testing-workflows): Ensure the functionality and reliability of your Workflows. -- [Testing Activities](/develop/dotnet/testing-suite#test-activities): Validate the execution and outcomes of your Activities. +- [Test frameworks](/develop/dotnet/testing-suite#test-frameworks): Testing provides a framework to facilitate Workflow + and integration testing. +- [Testing Workflows](/develop/dotnet/testing-suite#testing-workflows): Ensure the functionality and reliability of your + Workflows. +- [Testing Activities](/develop/dotnet/testing-suite#test-activities): Validate the execution and outcomes of your + Activities. - [Replay test](/develop/dotnet/testing-suite#replay): Replay recreates the exact state of a Workflow Execution. ## [Failure detection](/develop/dotnet/failure-detection) Explore how your application can detect failures using timeouts and automatically attempt to mitigate them with retries. -- [Workflow timeouts](/develop/dotnet/failure-detection#workflow-timeouts): Each Workflow timeout controls the maximum duration of a different aspect of a Workflow Execution. -- [Workflow retries](/develop/dotnet/failure-detection#workflow-retries): A Workflow Retry Policy can be used to retry a Workflow Execution in the event of a failure. -- [Activity timeouts](/develop/dotnet/failure-detection#activity-timeouts): Each Activity timeout controls the maximum duration of a different aspect of an Activity Execution. -- [Set an Activity Retry Policy](/develop/dotnet/failure-detection#activity-retries): Define retry logic for Activities to handle failures. -- [Heartbeat an Activity](/develop/dotnet/failure-detection#activity-heartbeats): An Activity Heartbeat is a ping from the Worker that is executing the Activity to the Temporal Service. -- [Heartbeat Timeout](/develop/dotnet/failure-detection#heartbeat-timeout): A Heartbeat Timeout works in conjunction with Activity Heartbeats. +- [Workflow timeouts](/develop/dotnet/failure-detection#workflow-timeouts): Each Workflow timeout controls the maximum + duration of a different aspect of a Workflow Execution. +- [Workflow retries](/develop/dotnet/failure-detection#workflow-retries): A Workflow Retry Policy can be used to retry a + Workflow Execution in the event of a failure. +- [Activity timeouts](/develop/dotnet/failure-detection#activity-timeouts): Each Activity timeout controls the maximum + duration of a different aspect of an Activity Execution. +- [Set an Activity Retry Policy](/develop/dotnet/failure-detection#activity-retries): Define retry logic for Activities + to handle failures. +- [Heartbeat an Activity](/develop/dotnet/failure-detection#activity-heartbeats): An Activity Heartbeat is a ping from + the Worker that is executing the Activity to the Temporal Service. +- [Heartbeat Timeout](/develop/dotnet/failure-detection#heartbeat-timeout): A Heartbeat Timeout works in conjunction + with Activity Heartbeats. ## [Workflow message passing](/develop/dotnet/message-passing) @@ -82,35 +105,46 @@ Send messages to and read the state of Workflow Executions. ### Signals - [Define Signal](/develop/dotnet/message-passing#signals): A Signal is a message sent to a running Workflow Execution. -- [Send a Signal from a Temporal Client](/develop/dotnet/message-passing#send-signal-from-client): Send a Signal to a Workflow from a Temporal Client. -- [Send a Signal from a Workflow](/develop/dotnet/message-passing#send-signal-from-workflow): Send a Signal to another Workflow from within a Workflow, this would also be called an External Signal. -- [Signal-With-Start](/develop/dotnet/message-passing#signal-with-start): Start a Workflow and send it a Signal in a single operation used from the Client. -- [Dynamic Handler](/develop/dotnet/message-passing#dynamic-handler): Dynamic Handlers provide flexibility to handle cases where the names of Workflows, Activities, Signals, or Queries aren't known at run time. -- [Set a Dynamic Signal](/develop/dotnet/message-passing#set-a-dynamic-signal): A Dynamic Signal in Temporal is a Signal that is invoked dynamically at runtime if no other Signal with the same input is registered. +- [Send a Signal from a Temporal Client](/develop/dotnet/message-passing#send-signal-from-client): Send a Signal to a + Workflow from a Temporal Client. +- [Send a Signal from a Workflow](/develop/dotnet/message-passing#send-signal-from-workflow): Send a Signal to another + Workflow from within a Workflow, this would also be called an External Signal. +- [Signal-With-Start](/develop/dotnet/message-passing#signal-with-start): Start a Workflow and send it a Signal in a + single operation used from the Client. +- [Dynamic Handler](/develop/dotnet/message-passing#dynamic-handler): Dynamic Handlers provide flexibility to handle + cases where the names of Workflows, Activities, Signals, or Queries aren't known at run time. +- [Set a Dynamic Signal](/develop/dotnet/message-passing#set-a-dynamic-signal): A Dynamic Signal in Temporal is a Signal + that is invoked dynamically at runtime if no other Signal with the same input is registered. ### Queries -- [Define a Query](/develop/dotnet/message-passing#queries): A Query is a synchronous operation that is used to get the state of a Workflow Execution. +- [Define a Query](/develop/dotnet/message-passing#queries): A Query is a synchronous operation that is used to get the + state of a Workflow Execution. - [Send Queries](/develop/dotnet/message-passing#send-query): Queries are sent from the Temporal Client. -- [Set a Dynamic Query](/develop/dotnet/message-passing#set-a-dynamic-signal): A Dynamic Query in Temporal is a Query that is invoked dynamically at runtime if no other Query with the same name is registered. +- [Set a Dynamic Query](/develop/dotnet/message-passing#set-a-dynamic-signal): A Dynamic Query in Temporal is a Query + that is invoked dynamically at runtime if no other Query with the same name is registered. ### Updates -- [Define an Update](/develop/dotnet/message-passing#updates): An Update is an operation that can mutate the state of a Workflow Execution and return a response. +- [Define an Update](/develop/dotnet/message-passing#updates): An Update is an operation that can mutate the state of a + Workflow Execution and return a response. - [Send an Update](/develop/dotnet/message-passing#send-update-from-client): An Update is sent from the Temporal Client. ## [Interrupt a Workflow](/develop/dotnet/cancellation) Interrupt a Workflow Execution with a Cancel or Terminate action. -- [Cancel a Workflow](/develop/dotnet/cancellation#cancellation): Interrupt a Workflow Execution and its Activities through Workflow cancellation. -- [Terminate a Workflow](/develop/dotnet/cancellation#termination): Interrupt a Workflow Execution and its Activities through Workflow termination. +- [Cancel a Workflow](/develop/dotnet/cancellation#cancellation): Interrupt a Workflow Execution and its Activities + through Workflow cancellation. +- [Terminate a Workflow](/develop/dotnet/cancellation#termination): Interrupt a Workflow Execution and its Activities + through Workflow termination. ## [Asynchronous Activity completion](/develop/dotnet/asynchronous-activity) Complete Activities asynchronously. -- [Asynchronous Activity](/develop/dotnet/asynchronous-activity): Asynchronous Activity completion enables the Activity Function to return without the Activity Execution completing. +- [Asynchronous Activity](/develop/dotnet/asynchronous-activity): Asynchronous Activity completion enables the Activity + Function to return without the Activity Execution completing. ## [Versioning](/develop/dotnet/versioning) @@ -122,39 +156,58 @@ Change Workflow Definitions without causing non-deterministic behavior in runnin Configure and use the Temporal Observability APIs. -- [Emit Metrics](/develop/dotnet/observability#metrics): Each Temporal SDK is capable of emitting an optional set of metrics from either the Client or the Worker process. -- [Set up Tracing](/develop/dotnet/observability#tracing): Explains how the Go SDK supports tracing and custom context propagation. -- [Log from a Workflow](/develop/dotnet/observability#logging): Send logs and errors to a logging service, so that when things go wrong, you can see what happened. -- [Use Visibility APIs](/develop/dotnet/observability#visibility): The term Visibility, within the Temporal Platform, refers to the subsystems and APIs that enable an operator to view Workflow Executions that currently exist within a Terminal Service. +- [Emit Metrics](/develop/dotnet/observability#metrics): Each Temporal SDK is capable of emitting an optional set of + metrics from either the Client or the Worker process. +- [Set up Tracing](/develop/dotnet/observability#tracing): Explains how the Go SDK supports tracing and custom context + propagation. +- [Log from a Workflow](/develop/dotnet/observability#logging): Send logs and errors to a logging service, so that when + things go wrong, you can see what happened. +- [Use Visibility APIs](/develop/dotnet/observability#visibility): The term Visibility, within the Temporal Platform, + refers to the subsystems and APIs that enable an operator to view Workflow Executions that currently exist within a + Terminal Service. ## [Debugging](/develop/dotnet/debugging) Explore various ways to debug your application. -- [Debug in a development environment](/develop/dotnet/debugging#debug-in-a-development-environment): In addition to the normal development tools of logging and a debugger, you can also see what’s happening in your Workflow by using the Web UI and the Temporal CLI. -- [Debug in a development production](/develop/dotnet/debugging#debug-in-a-development-production): Debug production Workflows using the Web UI, the Temporal CLI, Replays, Tracing, or Logging. +- [Debug in a development environment](/develop/dotnet/debugging#debug-in-a-development-environment): In addition to the + normal development tools of logging and a debugger, you can also see what’s happening in your Workflow by using the + Web UI and the Temporal CLI. +- [Debug in a development production](/develop/dotnet/debugging#debug-in-a-development-production): Debug production + Workflows using the Web UI, the Temporal CLI, Replays, Tracing, or Logging. ## [Schedules](/develop/dotnet/schedules) Run Workflows on a schedule and delay the start of a Workflow. - [Schedule a Workflow](/develop/dotnet/schedules#schedule-a-workflow) - - [Create a Scheduled Workflow](/develop/dotnet/schedules#create-a-workflow): Create a new schedule for a scheduled Workflow. - - [Backfill a Scheduled Workflow](/develop/dotnet/schedules#backfill-a-scheduled-workflow): Backfills a past time range of actions for a scheduled Workflow. - - [Delete a Scheduled Workflow](/develop/dotnet/schedules#delete-a-scheduled-workflow): Deletes a schedule for a scheduled Workflow. - - [Describe a Scheduled Workflow](/develop/dotnet/schedules#describe-a-scheduled-workflow): Get schedule configuration and current state for a scheduled Workflow. - - [List a Scheduled Workflow](/develop/dotnet/schedules#list-a-scheduled-workflow): List a schedule for a scheduled Workflow. - - [Pause a Scheduled Workflow](/develop/dotnet/schedules#pause-a-scheduled-workflow): Pause a schedule for a scheduled Workflow. - - [Trigger a Scheduled Workflow](/develop/dotnet/schedules#trigger-a-scheduled-workflow): Triggers an immediate action for a scheduled Workflow. - - [Update a Scheduled Workflow](/develop/dotnet/schedules#update-a-scheduled-workflow): Updates a schedule with a new definition for a scheduled Workflow. -- [Use Start Delay](/develop/dotnet/schedules#start-delay): Start delay functionality if you need to delay the execution of the Workflow without the need for regular launches. + - [Create a Scheduled Workflow](/develop/dotnet/schedules#create-a-workflow): Create a new schedule for a scheduled + Workflow. + - [Backfill a Scheduled Workflow](/develop/dotnet/schedules#backfill-a-scheduled-workflow): Backfills a past time + range of actions for a scheduled Workflow. + - [Delete a Scheduled Workflow](/develop/dotnet/schedules#delete-a-scheduled-workflow): Deletes a schedule for a + scheduled Workflow. + - [Describe a Scheduled Workflow](/develop/dotnet/schedules#describe-a-scheduled-workflow): Get schedule configuration + and current state for a scheduled Workflow. + - [List a Scheduled Workflow](/develop/dotnet/schedules#list-a-scheduled-workflow): List a schedule for a scheduled + Workflow. + - [Pause a Scheduled Workflow](/develop/dotnet/schedules#pause-a-scheduled-workflow): Pause a schedule for a scheduled + Workflow. + - [Trigger a Scheduled Workflow](/develop/dotnet/schedules#trigger-a-scheduled-workflow): Triggers an immediate action + for a scheduled Workflow. + - [Update a Scheduled Workflow](/develop/dotnet/schedules#update-a-scheduled-workflow): Updates a schedule with a new + definition for a scheduled Workflow. +- [Use Start Delay](/develop/dotnet/schedules#start-delay): Start delay functionality if you need to delay the execution + of the Workflow without the need for regular launches. ## [Data encryption](/develop/dotnet/converters-and-encryption) Use compression, encryption, and other data handling by implementing custom converters and codecs. -- [Use a custom Payload Codec](/develop/dotnet/converters-and-encryption#custom-payload-codec): Create a custom PayloadCodec implementation and define your encryption/compression and decryption/decompression logic. -- [Use a custom Payload Converter](/develop/dotnet/converters-and-encryption#custom-payload-converter): A custom data converter can be set via the `DataConverter` option when creating a client. +- [Use a custom Payload Codec](/develop/dotnet/converters-and-encryption#custom-payload-codec): Create a custom + PayloadCodec implementation and define your encryption/compression and decryption/decompression logic. +- [Use a custom Payload Converter](/develop/dotnet/converters-and-encryption#custom-payload-converter): A custom data + converter can be set via the `DataConverter` option when creating a client. ## [Durable Timers](/develop/dotnet/durable-timers) @@ -164,7 +217,8 @@ Use Timers to make a Workflow Execution pause or "sleep" for seconds, minutes, d ## Temporal Nexus -The [Temporal Nexus](/develop/dotnet/nexus) feature guide shows how to use Temporal Nexus to connect Durable Executions within and across Namespaces using a Nexus Endpoint, a Nexus Service contract, and Nexus Operations. +The [Temporal Nexus](/develop/dotnet/nexus) feature guide shows how to use Temporal Nexus to connect Durable Executions +within and across Namespaces using a Nexus Endpoint, a Nexus Service contract, and Nexus Operations. - [Create a Nexus Endpoint to route requests from caller to handler](/develop/dotnet/nexus#create-nexus-endpoint) - [Define the Nexus Service contract](/develop/dotnet/nexus#define-nexus-service-contract) @@ -177,14 +231,18 @@ The [Temporal Nexus](/develop/dotnet/nexus) feature guide shows how to use Tempo Explore how to spawn a Child Workflow Execution and handle Child Workflow Events. -- [Start a Child Workflow Execution](/develop/dotnet/child-workflows): A Child Workflow Execution is a Workflow Execution that is scheduled from within another Workflow using a Child Workflow API. -- [Set a Parent Close Policy](/develop/dotnet/child-workflows#parent-close-policy): A Parent Close Policy determines what happens to a Child Workflow Execution if its Parent changes to a Closed status. +- [Start a Child Workflow Execution](/develop/dotnet/child-workflows): A Child Workflow Execution is a Workflow + Execution that is scheduled from within another Workflow using a Child Workflow API. +- [Set a Parent Close Policy](/develop/dotnet/child-workflows#parent-close-policy): A Parent Close Policy determines + what happens to a Child Workflow Execution if its Parent changes to a Closed status. ## [Continue-As-New](/develop/dotnet/continue-as-new) Continue the Workflow Execution with a new Workflow Execution using the same Workflow ID. -- [Continue-As-New](/develop/dotnet/continue-as-new): Continue-As-New enables a Workflow Execution to close successfully and create a new Workflow Execution in a single atomic operation if the number of Events in the Event History is becoming too large. +- [Continue-As-New](/develop/dotnet/continue-as-new): Continue-As-New enables a Workflow Execution to close successfully + and create a new Workflow Execution in a single atomic operation if the number of Events in the Event History is + becoming too large. ## [Enriching the User Interface](/develop/dotnet/enriching-ui) diff --git a/docs/develop/dotnet/temporal-client.mdx b/docs/develop/dotnet/temporal-client.mdx index b53878afcc..7dcc036416 100644 --- a/docs/develop/dotnet/temporal-client.mdx +++ b/docs/develop/dotnet/temporal-client.mdx @@ -2,7 +2,9 @@ id: temporal-client title: Temporal Client - .NET SDK sidebar_label: Temporal Client -description: Create a Temporal Client, connect to Temporal Cloud, start a Workflow, and get Workflow results using the Temporal .NET SDK with detailed steps and code examples. +description: + Create a Temporal Client, connect to Temporal Cloud, start a Workflow, and get Workflow results using the Temporal + .NET SDK with detailed steps and code examples. keywords: - developer guide - sdk @@ -15,118 +17,465 @@ tags: - Certificates --- -This page shows how to do the following: +A [Temporal Client](https://chatgpt.com/encyclopedia/temporal-sdks#temporal-client) enables you to communicate with the +Temporal Service. Communication with a Temporal Service lets you perform actions such as starting Workflow Executions, +sending Signals and Queries to Workflow Executions, getting Workflow results, and more. -- [Create a Temporal Client](#create-a-client) +This page shows you how to do the following using the .NET SDK with the Temporal Client: + +- [Connect to a local development Temporal Service](#connect-to-development-service) - [Connect to Temporal Cloud](#connect-to-temporal-cloud) -- [Start a Workflow](#start-workflow) +- [Start a Workflow Execution](#start-workflow) - [Get Workflow results](#get-workflow-results) -## Create a Temporal Client {#create-a-client} +A Temporal Client cannot be initialized and used inside a Workflow. However, it is acceptable and common to use a +Temporal Client inside an Activity to communicate with a Temporal Service. + +## Connect to development Temporal Service {#connect-to-development-service} + +Use +[`TemporalClient.ConnectAsync`](https://dotnet.temporal.io/api/Temporalio.Client.TemporalClient.html#Temporalio_Client_TemporalClient_ConnectAsync_Temporalio_Client_TemporalClientConnectOptions_) +to create a client. Connection options include the Temporal Server address, Namespace, and (optionally) TLS +configuration. You can provide these options directly in code, or load them from **environment variables** and/or a +**TOML configuration file** using the `Temporalio.Client.EnvConfig` helpers. We recommend environment variables or a +configuration file for secure, repeatable configuration. -**How to create a Temporal Client using the Temporal .NET SDK** +When you’re running a Temporal Service locally (such as with the +[Temporal CLI dev server](https://docs.temporal.io/cli/server#start-dev)), the required options are minimal. If you +don't specify a host/port, most connections default to `127.0.0.1:7233` and the `default` Namespace. -A [Temporal Client](/encyclopedia/temporal-sdks#temporal-client) enables you to communicate with the [Temporal Service](/temporal-service). -Communication with a Temporal Service includes, but isn't limited to, the following: + -- Starting Workflow Executions. -- Sending Signals to Workflow Executions. -- Sending Queries to Workflow Executions. -- Getting the results of a Workflow Execution. -- Providing an Activity Task Token. + -:::caution +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](../environment-configuration.mdx#configuration-methods) for more details about configuration +files and profiles. -A Temporal Client cannot be initialized and used inside a Workflow. -However, it is acceptable and common to use a Temporal Client inside an Activity to communicate with a Temporal Service. +:::info + +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. ::: -When you are running a Temporal Service locally (such as the [Temporal CLI](https://docs.temporal.io/cli/server#start-dev)), the number of connection options you must provide is minimal. -Many SDKs default to the local host or IP address and port that Temporalite and [Docker Compose](https://github.com/temporalio/docker-compose) serve (`127.0.0.1:7233`). +For example, the following TOML configuration file defines two profiles: `default` and `prod`. Each profile has its own +set of connection options. + +```toml title="config.toml" +# 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: + +```csharp title="LoadFromFile.cs" {27-30} +using Temporalio.Client; +using Temporalio.Client.EnvConfig; + +namespace TemporalioSamples.EnvConfig; + +/// +/// Sample demonstrating loading the default environment configuration profile +/// from a TOML file. +/// +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](/references/client-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. + +```bash +export TEMPORAL_NAMESPACE="default" +export TEMPORAL_ADDRESS="localhost:7233" +``` + +After setting the environment variables, use the following code to create the Temporal Client: + +```csharp +using Temporalio.Client; +using Temporalio.Client.EnvConfig; + +namespace TemporalioSamples.EnvConfig; + +/// +/// Sample demonstrating loading the default environment configuration profile +/// from a TOML file. +/// +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}"); + } + } +} +``` -Use the `ConnectAsync()` static method on the `Temporalio.Client.TemporalClient` class to create and connect to a Temporal Client to the Temporal Service. + + + + +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. ```csharp -var client = await TemporalClient.ConnectAsync(new("localhost:7233")); +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!"); + } + } +} + ``` -## Connect to Temporal Cloud {#connect-to-temporal-cloud} + + + -### How to connect to Temporal Cloud using an API Key {#connect-to-temporal-cloud-api-key} +## Connect to Temporal Cloud {#connect-to-temporal-cloud} -To use an [API key](/cloud/api-keys) with the Temporal .NET SDK, you will need to provide additional connection options: +You can connect to Temporal Cloud using either an [API key](/cloud/api-keys) or through mTLS. Connection to Temporal +Cloud or any secured Temporal Service requires additional connection options compared to connecting to an unsecured +local development instance: -- Your _API Key_ value -- Your _Namespace and Account id_ combination, which follows the format `.`. -- The _endpoint_ may vary. The most common endpoint used is the gRPC regional endpoint, which follows the format: `..api.temporal.io:7233`. -- For Namespaces with High Availability features with API key authentication enabled, use the gRPC Namespace endpoint: `..tmprl.cloud:7233`. - This allows automated failover without needing to switch endpoints. +- Your credentials for authentication. + - If you are using an API key, provide the API key value. + - If you are using mTLS, provide the mTLS CA certificate and mTLS private key. +- Your _Namespace and Account ID_ combination, which follows the format `.`. +- The _endpoint_ may vary. The most common endpoint used is the gRPC regional endpoint, which follows the format: + `..api.temporal.io:7233`. +- For Namespaces with High Availability features with API key authentication enabled, use the gRPC Namespace endpoint: + `..tmprl.cloud:7233`. This allows automated failover without needing to switch endpoints. You can find the Namespace and Account ID, as well as the endpoint, on the Namespaces tab: ![The Namespace and Account ID combination on the left, and the regional endpoint on the right](/img/cloud/apikeys/namespaces-and-regional-endpoints.png) -Now, when instantiating a Temporal client in your .NET SDK code, provide the `Namespace` and `ApiKey` values. +You can provide these connection options using environment variables, a configuration file, or directly in code. -To create an initial connection: + -```csharp -var myClient = TemporalClient.ConnectAsync(new() -{ - Namespace = ".", - ApiKey = "", - Tls = new(), -}); + + +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. For a list of all available configuration options you can set in the TOML file, refer to +[Environment Configuration](/references/client-environment-configuration). + +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 path to the configuration file, the SDK looks for it at the +default path `~/.config/temporalio/temporal.toml`. + +:::info + +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 a `cloud` profile with the necessary connection options to +connect to Temporal Cloud via an API key: + +```toml +# Cloud profile for Temporal Cloud +[profile.cloud] +address = "your-namespace.a1b2c.tmprl.cloud:7233" +namespace = "your-namespace" +api_key = "your-api-key-here" ``` -To update an API key, update the value of `ApiKey`: +If you want to use mTLS authentication instead of an API key, replace the `api_key` field with your mTLS certificate and +private key: -```csharp -myClient.Connection.ApiKey = myKeyUpdated; +```toml +# Cloud profile for Temporal Cloud +[profile.cloud] +address = "your-namespace.a1b2c.tmprl.cloud:7233" +namespace = "your-namespace" +tls_client_cert_data = "your-tls-client-cert-data" +tls_client_key_path = "your-tls-client-key-path" +``` + +With the connections options defined in the configuration file, use the `ClientEnvConfig.LoadClientConnectOptions` +method to create a Temporal Client using the `staging` profile as follows. After loading the profile, you can also +programmatically override specific connection options before creating the client. + +```csharp title="LoadProfile.cs" {25. 41} +using Temporalio.Client; +using Temporalio.Client.EnvConfig; + +namespace TemporalioSamples.EnvConfig; + +/// +/// Sample demonstrating loading a named environment configuration profile and +/// programmatically overriding its values. +/// +public static class LoadProfile +{ + public static async Task RunAsync() + { + Console.WriteLine("--- Loading 'staging' profile with programmatic overrides ---"); + + try + { + var configFile = Path.Combine(Directory.GetCurrentDirectory(), "config.toml"); + var profileName = "staging"; + + Console.WriteLine("The 'staging' profile in config.toml has an incorrect address (localhost:9999)."); + Console.WriteLine("We'll programmatically override it to the correct address."); + + // Load the 'staging' profile + var connectOptions = ClientEnvConfig.LoadClientConnectOptions(new ClientEnvConfig.ProfileLoadOptions + { + Profile = profileName, + ConfigSource = DataSource.FromPath(configFile), + }); + + // Override the target host to the correct address. + // This is the recommended way to override configuration values. + connectOptions.TargetHost = "localhost:7233"; + + Console.WriteLine($"\nLoaded '{profileName}' profile from {configFile} with overrides."); + Console.WriteLine($" Address: {connectOptions.TargetHost} (overridden from localhost:9999)"); + Console.WriteLine($" Namespace: {connectOptions.Namespace}"); + + 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}"); + } + } +} ``` -### How to connect to Temporal Cloud using mTLS {#connect-to-temporal-cloud-tls} + -When you connect to [Temporal Cloud](/cloud) with mTLS, you need to provide additional connection and client options that include the following: + -- The [Temporal Cloud Namespace Id](/cloud/namespaces#temporal-cloud-namespace-id). -- The [Namespace's gRPC endpoint](/cloud/namespaces#temporal-cloud-grpc-endpoint). - An endpoint listing is available at the [Temporal Cloud Website](https://cloud.temporal.io/namespaces) on each Namespace detail page. - The endpoint contains the Namespace Id and port. -- mTLS CA certificate. -- mTLS private key. +The following environment variables are required to connect to Temporal Cloud: -For more information about managing and generating client certificates for Temporal Cloud, see [How to manage certificates in Temporal Cloud](/cloud/certificates). +- `TEMPORAL_NAMESPACE`: Your Namespace and Account ID combination in the format `.`. +- `TEMPORAL_ADDRESS`: The gRPC endpoint for your Temporal Cloud Namespace. +- `TEMPORAL_API_KEY`: Your API key value. Required if you are using API key authentication. +- `TEMPORAL_TLS_CLIENT_CERT_DATA` or `TEMPORAL_TLS_CLIENT_CERT_PATH`: Your mTLS client certificate data or file path. + Required if you are using mTLS authentication. +- `TEMPORAL_TLS_CLIENT_KEY_DATA` or `TEMPORAL_TLS_CLIENT_KEY_PATH`: Your mTLS client private key data or file path. + Required if you are using mTLS authentication. -For more information about configuring TLS to secure inter- and intra-network communication for a Temporal Service, see [Temporal Customization Samples](https://github.com/temporalio/samples-server). +Ensure these environment variables exist in your environment before running your .NET application. -Use the `ConnectAsync()` static method on the `Temporalio.Client.TemporalClient` class to create and connect to a Temporal Client to the Temporal Service. -Specify the `Tls` property of the connection options to connect to a Temporal Service with TLS enabled. +Import the `EnvConfig` package to set connection options for the Temporal Client using environment variables. The +`MustLoadDefaultClientOptions` function will automatically load all environment variables. For a list of all available +environment variables and their default values, refer to +[Environment Configuration](/references/client-environment-configuration). -```csharp -var client = await TemporalClient.ConnectAsync(new("my-namespace.a1b2c.tmprl.cloud:7233") +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. + +```csharp {16,20} +using Temporalio.Client; +using Temporalio.Client.EnvConfig; + +namespace TemporalioSamples.EnvConfig; + +/// +/// Sample demonstrating loading the default environment configuration profile +/// from a TOML file. +/// +public static class LoadFromFile { - Namespace = "my-namespace.a1b2c", - Tls = new() + public static async Task RunAsync() { - ClientCert = await File.ReadAllBytesAsync("my-cert.pem"), - ClientPrivateKey = await File.ReadAllBytesAsync("my-key.pem"), - }, + 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}"); + } + } +} +``` + + + + + +You can also provide connections options in your Go code directly. To create an initial connection, provide the +Namespace and API key values to the ` TemporalClient.ConnectAsync` method. + +```csharp +var myClient = TemporalClient.ConnectAsync(new() +{ + Namespace = ".", + ApiKey = "", + Tls = new(), }); ``` +To update an API key, update the value of `ApiKey` on the existing client connection: + +```csharp +myClient.Connection.ApiKey = myKeyUpdated; +``` + + + + + ## Start a Workflow {#start-workflow} **How to start a Workflow using the Temporal .NET SDK** -[Workflow Execution](/workflow-execution) semantics rely on several parameters—that is, to start a Workflow Execution you must supply a Task Queue that will be used for the Tasks (one that a Worker is polling), the Workflow Type, language-specific contextual data, and Workflow Function parameters. +[Workflow Execution](/workflow-execution) semantics rely on several parameters—that is, to start a Workflow Execution +you must supply a Task Queue that will be used for the Tasks (one that a Worker is polling), the Workflow Type, +language-specific contextual data, and Workflow Function parameters. -A request to spawn a Workflow Execution causes the Temporal Service to create the first Event ([WorkflowExecutionStarted](/references/events#workflowexecutionstarted)) in the Workflow Execution Event History. -The Temporal Service then creates the first Workflow Task, resulting in the first [WorkflowTaskScheduled](/references/events#workflowtaskscheduled) Event. +A request to spawn a Workflow Execution causes the Temporal Service to create the first Event +([WorkflowExecutionStarted](/references/events#workflowexecutionstarted)) in the Workflow Execution Event History. The +Temporal Service then creates the first Workflow Task, resulting in the first +[WorkflowTaskScheduled](/references/events#workflowtaskscheduled) Event. -To start a Workflow Execution in .NET, use either the `StartWorkflowAsync()` or `ExecuteWorkflowAsync()` methods in the Client. -You must set a [Workflow Id](/workflow-execution/workflowid-runid#workflow-id) and [Task Queue](/task-queue) in the `WorkflowOptions` given to the method. +To start a Workflow Execution in .NET, use either the `StartWorkflowAsync()` or `ExecuteWorkflowAsync()` methods in the +Client. You must set a [Workflow Id](/workflow-execution/workflowid-runid#workflow-id) and [Task Queue](/task-queue) in +the `WorkflowOptions` given to the method. ```csharp var result = await client.ExecuteWorkflowAsync( @@ -141,19 +490,23 @@ Console.WriteLine("Result: {0}", result); If the call to start a Workflow Execution is successful, you will gain access to the Workflow Execution's Run Id. -The Workflow Id, Run Id, and Namespace may be used to uniquely identify a Workflow Execution in the system and get its result. +The Workflow Id, Run Id, and Namespace may be used to uniquely identify a Workflow Execution in the system and get its +result. -It's possible to both block progress on the result (synchronous execution) or get the result at some other point in time (asynchronous execution). +It's possible to both block progress on the result (synchronous execution) or get the result at some other point in time +(asynchronous execution). -In the Temporal Platform, it's also acceptable to use Queries as the preferred method for accessing the state and results of Workflow Executions. +In the Temporal Platform, it's also acceptable to use Queries as the preferred method for accessing the state and +results of Workflow Executions. -Use `StartWorkflowAsync()` or `GetWorkflowHandle()` to return a Workflow handle. -Then use the `GetResultAsync()` method to await on the result of the Workflow. +Use `StartWorkflowAsync()` or `GetWorkflowHandle()` to return a Workflow handle. Then use the `GetResultAsync()` method +to await on the result of the Workflow. To get a handle for an existing Workflow by its Id, you can use `GetWorkflowHandle()`. -Then use [`DescribeAsync()`](https://dotnet.temporal.io/api/Temporalio.Client.WorkflowHandle.html#Temporalio_Client_WorkflowHandle_DescribeAsync_Temporalio_Client_WorkflowDescribeOptions_) to get the current status of the Workflow. -If the Workflow does not exist, this call fails. +Then use +[`DescribeAsync()`](https://dotnet.temporal.io/api/Temporalio.Client.WorkflowHandle.html#Temporalio_Client_WorkflowHandle_DescribeAsync_Temporalio_Client_WorkflowDescribeOptions_) +to get the current status of the Workflow. If the Workflow does not exist, this call fails. ```csharp var handle = client.GetWorkflowHandle("my-workflow-id"); diff --git a/docs/develop/environment-configuration.mdx b/docs/develop/environment-configuration.mdx index 5fe1e1f9ca..f782f24749 100644 --- a/docs/develop/environment-configuration.mdx +++ b/docs/develop/environment-configuration.mdx @@ -10,53 +10,52 @@ tags: - TOML --- -Temporal Environment Configuration is a feature that allows you to configure a Temporal Client using environment variables and/or TOML configuration files, rather than setting connection options programmatically in your code. This decouples connection settings from application logic, making it easier to manage different environments (like development, staging, and production) without code changes. +import { LANGUAGE_TAB_GROUP, getLanguageLabel } from '@site/src/constants/languageTabs'; +import SdkTabs from '@site/src/components'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; -:::tip SUPPORT, STABILITY, and DEPENDENCY INFO - -This feature is currently in Pre-release in the Go and Python Temporal SDKs, as well as the Temporal CLI. - -::: +Temporal CLI and SDKs support configuring a Temporal Client using environment variables and TOML configuration files, +rather than setting connection options programmatically in your code. This decouples connection settings from +application logic, making it easier to manage different environments such as development, staging, and production +without code changes. -## Configuration Methods +For a list of all available configuration settings, their corresponding environment variables, and TOML file paths, +refer to [Temporal Client Environment Configuration Reference](../references/client-environment-configuration). -You can configure your client using a TOML file, environment variables, or a combination of both. The configuration is loaded with a specific order of precedence: +:::tip SUPPORT, STABILITY, and DEPENDENCY INFO -1. Environment Variables: These have the highest precedence. -If a setting is defined as an environment variable, it will always override any value set in a configuration file (useful for dynamic environments or for providing secrets). -2. TOML Configuration File: A TOML file can be used to define one or more configuration "profiles". This file is located by checking the following sources in order: - 1. The path specified by the TEMPORAL\_CONFIG\_FILE environment variable. - 2. The default configuration path: \~/.config/temporalio/temporal.toml (or the equivalent standard user config directory on your OS). +Environment configuration is in +[Public Preview](../evaluate/development-production-features/release-stages.mdx#public-preview) in the Temporal Go, +Python, Ruby, and .NET SDKs, as well as the Temporal CLI. -## Configuration Profiles +::: -You can use configuration “profiles” to maintain separate configurations within a single file (for different environments). The "default" profile is used unless another is specified via the TEMPORAL\_PROFILE environment variable or in the SDK's load options. If a specific profile is requested but doesn’t exist, an error will be returned. +## Configuration methods -## Configuration Settings +You can configure your client using a TOML file, environment variables, or a combination of both. The configuration is +loaded with a specific order of precedence: -The following table details all available settings, their corresponding environment variables, and their TOML file paths. +1. Environment variables: These have the highest precedence. If an environment variable defines a setting, it will + always override any value set in a configuration file. This makes it easy to provide secrets in dynamic environments. +2. TOML configuration file: A TOML file can be used to define one or more configuration profiles. This file is located + by checking the following sources in order: + 1. The path specified by the `TEMPORAL_CONFIG_FILE` environment variable. + 2. The default configuration path for your operating system: + - Linux: `~/.config/temporalio/temporal.toml` + - macOS: `$HOME/Library/Application Support/temporal/temporal.toml` + - Windows: `%AppData%\temporal\temporal.toml` -| Setting | Environment Variable | TOML Path | Description | -| :---- | :---- | :---- | :---- | -| Configuration File Path | TEMPORAL\_CONFIG\_FILE | **NA** | Path to the TOML configuration file | -| Server Address | TEMPORAL\_ADDRESS | profile.\.address | The host and port of the Temporal Frontend service (e.g., "localhost:7233"). | -| Namespace | TEMPORAL\_NAMESPACE | profile.\.namespace | The Temporal Namespace to connect to. | -| API Key | TEMPORAL\_API\_KEY | profile.\.api\_key | An API key for authentication. If present, TLS is enabled by default. | -| Enable/Disable TLS | TEMPORAL\_TLS | profile.\.tls.disabled | Set to "true" to enable TLS, "false" to disable. In TOML, disabled \= true turns TLS off. | -| Client Certificate | TEMPORAL\_TLS\_CLIENT\_CERT\_DATA / \_PATH | profile.\.tls.client\_cert\_data / \_path | The client's public TLS certificate. Can be provided as raw PEM data or a file path. | -| Client Key | TEMPORAL\_TLS\_CLIENT\_KEY\_DATA / \_PATH | profile.\.tls.client\_key\_data / \_path | The client's private TLS key. Can be provided as raw PEM data or a file path. | -| Server CA Cert | TEMPORAL\_TLS\_SERVER\_CA\_CERT\_DATA / \_PATH | profile.\.tls.server\_ca\_cert\_path / \_data | The Certificate Authority certificate for the server. Used to verify the server's cert. | -| TLS Server Name | TEMPORAL\_TLS\_SERVER\_NAME | profile.\.tls.server\_name | Overrides the server name used for SNI (Server Name Indication) in the TLS handshake. | -| Disable Host Verification | TEMPORAL\_TLS\_DISABLE\_HOST\_VERIFICATION | profile.\.tls.disable\_host\_verification | A boolean (true/false) to disable server hostname verification. Use with caution. Not supported by all SDKs. | -| Codec Endpoint | TEMPORAL\_CODEC\_ENDPOINT | profile.\.codec.endpoint | The endpoint for a remote data converter. Not supported by all SDKs (where supported, not applied by default). Intended mostly for CLI use. | -| Codec Auth | TEMPORAL\_CODEC\_AUTH | profile.\.codec.auth | The authorization header value for the remote data converter. | -| gRPC Metadata | TEMPORAL\_GRPC\_META\_\* | profile.\.grpc\_meta | Sets gRPC headers. The part after \_META\_ becomes the header key (e.g., \_SOME\_KEY \-\> some-key). | +## TOML file configuration -## TOML Configuration Example +You can use configuration profiles to maintain separate configurations within a single file for different environments. +The Temporal client uses the `default` profile unless you specify another via the `TEMPORAL_PROFILE` environment +variable or in the SDK's load options. If a requested profile doesn't exist, the application will return an error. -Here is an example temporal.toml file that defines two profiles: default for local development and prod for production. +Here is an example `temporal.toml` file that defines two profiles: `default` for local development and `prod` for +production. -```textproto +```toml # Default profile for local development [profile.default] address = "localhost:7233" @@ -101,63 +100,81 @@ MIIPrivateKeyDataHere... -----END PRIVATE KEY-----""" ``` -## CLI Integration +## CLI integration -The Temporal CLI tool includes temporal config commands that allow you to read and write to the TOML configuration file. This provides a convenient way to manage your connection profiles without manually editing the file. +The Temporal CLI tool includes `temporal config` commands that allow you to read and write to the TOML configuration +file. This provides a convenient way to manage your connection profiles without manually editing the file. Refer to +[Temporal CLI Reference - `temporal config`](../cli/config.mdx) for more details. -* temporal config get \: Reads a specific value from the current profile. -* temporal config set \ \: Sets a property in the current profile. -* temporal config delete \: Deletes a property from the current profile. -* temporal config list: Lists all available profiles in the config file. +- `temporal config get `: Reads a specific value from the current profile. +- `temporal config set `: Sets a property in the current profile. +- `temporal config delete `: Deletes a property from the current profile. +- `temporal config list`: Lists all available profiles in the config file. -These CLI commands directly manipulate the temporal.toml file. -This differs from the SDKs, which only *read* from the file and environment at runtime to establish a client connection. -The CLI is a tool for managing the configuration source, while the SDKs are consumers of that configuration. -You can select a profile for the CLI to use with the \--profile flag (for example, temporal \--profile prod ...). +These CLI commands directly manipulate the `temporal.toml` file. This differs from the SDKs, which only _read_ from the +file and environment at runtime to establish a client connection. You can select a profile for the CLI to use with the +`--profile` flag. For example, `temporal --profile prod ...`. -CLI Usage Example +The following code blocks provide copy-paste-friendly examples for setting up CLI profiles for both local development +and Temporal Cloud. -```textproto -# Set a specific property for the current profile -temporal config set --prop address --value "prod.temporal.io:7233" + + -# Delete a property for the current profile -temporal config delete --prop tls.client_cert_path +This example shows how to set up a default profile for local development and a `prod` profile for Temporal Cloud using +an API key. -# Get a specific property for the current profile -temporal config get --prop address +```bash +# (Optional) initialize the default profile for local development +temporal config set --prop address --value "localhost:7233" +temporal config set --prop namespace --value "default" -# Get all settings for the current profile -temporal config get +# Configure a Temporal Cloud profile that authenticates with an API key +temporal --profile prod config set --prop address --value "..api.temporal.io:7233" +temporal --profile prod config set --prop namespace --value "." +temporal --profile prod config set --prop api_key --value "" +``` -# Use a specific profile -temporal --profile prod config get --prop address + + -# List all profiles -temporal config list +This example shows how to set up a more advanced Temporal Cloud profile with TLS overrides and custom gRPC metadata. -# Connect to a client with the default profile, list its workflows -temporal workflow list +```bash +# Base API key properties (replace the placeholders) +temporal --profile prod config set --prop address --value "..api.temporal.io:7233" +temporal --profile prod config set --prop namespace --value "." +temporal --profile prod config set --prop api_key --value "" -# Connect to a client with the 'prod' profile, list its workflows -temporal --profile prod workflow list +# Optional TLS overrides (only needed when you must pin certs or tweak SNI) +temporal --profile prod config set --prop tls.server_name --value "." +temporal --profile prod config set --prop tls.ca_cert_path --value "/path/to/ca.pem" -# Start a workflow using the 'prod' profile -temporal --profile prod workflow start \ ---type YourWorkflow \ ---task-queue your-task-queue \ ---input '"your-workflow-input"' +# Optional gRPC metadata for observability or routing +temporal --profile prod config set --prop grpc_meta.environment --value "production" +temporal --profile prod config set --prop grpc_meta.service-version --value "v1.2.3" ``` -## SDK Usage Example (Python) + + + +## Load configuration profile and environment variables -The following Python examples demonstrate how to use `temporalio.envconfig` to load configuration from environment variables and TOML files. +If you don't specify a profile, the SDKs load the `default` profile and the environment variables. If you haven't set +`TEMPORAL_CONFIG_FILE`, the SDKs will look for the configuration file in the default location. Refer to +[Configuration methods](#configuration-methods) for the default locations for your operating system. -### Load the default profile +No matter what profile you choose to load, environment variables are always loaded when you use the APIs in the +environment configuration package to load Temporal Client connection options. They always take precedence over TOML file +settings in the profiles. -The most common use case is to load the "default" profile from environment variables and the default TOML file location (`~/.config/temporalio/temporal.toml`). The `ClientConfigProfile.load()` method handles this automatically. Any `TEMPORAL_*` environment variables will override settings from the TOML file. + + -```py +To load the `default` profile along with any environment variables in Python, use the `ClientConfigProfile.load()` +method from the `temporalio.envconfig` package. + +```python {7-8} import asyncio from temporalio.client import Client from temporalio.envconfig import ClientConfigProfile @@ -171,96 +188,231 @@ async def main(): client = await Client.connect(**connect_config) print(f"✅ Client connected to {client.service_client.config.target_host} in namespace '{client.namespace}'") -if __name__ == "__main__": - asyncio.run(main()) + + if __name__ == "__main__": + asyncio.run(main()) ``` -### Load a specific profile by name + + -If your TOML configuration file contains multiple profiles, you can select one by passing its name to `ClientConfigProfile.load(profile="")`. +To load the `default` profile along with any environment variables in Go, use the +`envconfig.MustLoadDefaultClientOptions()` function from the `temporalio.envconfig` package. -```py -import asyncio -from temporalio.client import Client -from temporalio.envconfig import ClientConfigProfile +```go {13} +package main -async def main(): - # Load a specific, named profile from default locations. - # This requires a [profile.prod] section in your TOML file. - prod_profile = ClientConfigProfile.load(profile="prod") - connect_config = prod_profile.to_client_connect_config() +import ( + "fmt" + "log" - # Connect to the client using the loaded configuration. - client = await Client.connect(**connect_config) - print(f"✅ Client connected to {client.target} in namespace '{client.namespace}'") + "go.temporal.io/sdk/client" + "go.temporal.io/sdk/contrib/envconfig" +) -if __name__ == "__main__": - asyncio.run(main()) +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 Service") +} ``` -### Load configuration from a custom file path + + + +To load the `default` profile along with any environment variables in Ruby, use the +`EnvConfig::ClientConfig.load_client_connect_options()` method from the `temporalio.env_config` package. + +```Ruby {16-18} +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 +``` -To load configuration from a non-standard file location, you can use the `ClientConfig.load_client_connect_config()` shorthand. This is useful if you store application-specific configurations separately. + + + + +To load the `default` profile along with any environment variables in .NET C#, use the +`ClientEnvConfig.LoadClientConnectOptions()` method from the `Temporalio.Client.EnvConfig` package. + +```csharp {22,27-30} +using Temporalio.Client; +using Temporalio.Client.EnvConfig; + +namespace TemporalioSamples.EnvConfig; + +/// +/// Sample demonstrating loading the default environment configuration profile +/// from a TOML file. +/// +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}"); + } + } +} +``` -```py -import asyncio -from pathlib import Path -from temporalio.client import Client -from temporalio.envconfig import ClientConfig + + -async def main(): - # This file would need to exist on your filesystem. - config_file = Path.home() / ".config" / "my-app" / "temporal.toml" +## Load configuration from a custom path - # Use ClientConfig.load_client_connect_config as a convenient shorthand for - # loading a profile from a specific file and preparing it for connection. - connect_config = ClientConfig.load_client_connect_config( - config_file=str(config_file), - ) +To load configuration from a non-standard file location without relying on the `TEMPORAL_CONFIG_FILE` environment +variable, you can use a function from the `temporalio.envconfig` package. The specific method you need to call depends +on the SDK you are using. - # Connect to the client using the loaded configuration. - client = await Client.connect(**connect_config) - print(f"✅ Client connected to {client.target} in namespace '{client.namespace}'") +This is useful if you store application-specific configurations separately. Loading connection options using this method +will still respect environment variables, which take precedence over the file settings. -if __name__ == "__main__": - asyncio.run(main()) -``` + + + -### Override configuration programmatically +To load a specific profile from a custom path in Python, use the `ClientConfig.load_client_connect_config()` method with +the `config_file` parameter. In this example, we construct the path to a `config.toml` file located in the same +directory as the script. -You can also load a base configuration and then override specific settings programmatically in your code. The loaded configuration is a dictionary, so you can modify it before passing it to `Client.connect()`. +After loading the connection options, you can override specific settings programmatically before passing them to +`Client.connect()`. -```py +```py {12-13,21-23} import asyncio +from pathlib import Path from temporalio.client import Client from temporalio.envconfig import ClientConfig async def main(): - # Load the default profile configuration. - connect_config = ClientConfig.load_client_connect_config() + """ + 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" - # Apply custom configuration overrides. - print("Applying custom configuration overrides...") + 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" - connect_config["namespace"] = "test-namespace" - # Connect to the client using the modified configuration. - client = await Client.connect(**connect_config) - print(f"✅ Client connected to {client.target} in namespace '{client.namespace}'") + 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()) ``` -## SDK Usage Example (Go) + -The following Go examples demonstrate how to use `envconfig` to load configuration from different sources to connect a client. + -### Load the default profile +To load a specific profile from a custom filepath in Go, use the `envconfig.LoadClientOptions()` function with the +`ConfigFilePath` field set in the `LoadClientOptionsRequest` struct. Use the `ConfigFileProfile` field to specify the +profile name. -The most common use case is to load the "default" profile from environment variables and the default TOML file location (`~/.config/temporalio/temporal.toml`). The `envconfig.MustLoadDefaultClientOptions()` function handles this automatically. Any `TEMPORAL_*` environment variables will override settings from the TOML file. +After loading the connection options, you can override specific settings programmatically before passing them to +`client.Dial()`. Refer to the [GO SDK API documentation](https://pkg.go.dev/go.temporal.io/sdk/contrib/envconfig) for +all available options. -```go +```go {14-16} package main import ( @@ -272,117 +424,150 @@ import ( ) 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) + // 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", + ConfigFilePath: "/Users/yourname/.config/my-app/temporal.toml", + }) + if err != nil { + log.Fatalf("Failed to load 'prod' profile: %v", err) + } + + // Programmatically override the Namespace value. + opts.Namespace = "new-namespace" + + 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) } ``` -### Load a specific profile by name + -If your TOML configuration file contains multiple profiles, you can select one by passing its name in `envconfig.LoadClientOptionsRequest`. + -```go -package main +To load a specific profile from a custom path in Ruby, use the `EnvConfig::ClientConfig.load_client_connect_options()` +method with the `config_source` parameter. In this example, we construct the path to a `config.toml` file located in the +same directory as the script. Use the `profile` parameter to specify the profile name. -import ( - "fmt" - "log" +After loading the connection options, you can override specific settings programmatically before passing them to +`Client.connect()`. Refer to the [Ruby SDK API documentation](https://ruby.temporal.io/Temporalio/EnvConfig.html) for +all available options. - "go.temporal.io/sdk/client" - "go.temporal.io/sdk/contrib/envconfig" -) +```Ruby {7-8,14-16} +require 'temporalio/client' +require 'temporalio/env_config' -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) - } +def main + puts "--- Loading 'staging' profile with programmatic overrides ---" - c, err := client.Dial(opts) - if err != nil { - log.Fatalf("Failed to connect using 'prod' profile: %v", err) - } - defer c.Close() + config_file = File.join(__dir__, 'config.toml') + profile_name = 'staging' - fmt.Printf("✅ Connected to Temporal namespace %q on %s using 'prod' profile\n", c.Options().Namespace, c.Options().HostPort) -} -``` - -### Load configuration from a custom file path + puts "The 'staging' profile in config.toml has an incorrect address (localhost:9999)." + puts "We'll programmatically override it to the correct address." -To load configuration from a non-standard file location, specify the path in `envconfig.LoadClientOptionsRequest`. This is useful if you store application-specific configurations separately. - -```go -package main - -import ( - "fmt" - "log" + # Load the 'staging' profile. + args, kwargs = Temporalio::EnvConfig::ClientConfig.load_client_connect_options( + profile: profile_name, + config_source: Pathname.new(config_file) + ) - "go.temporal.io/sdk/client" - "go.temporal.io/sdk/contrib/envconfig" -) + # Override the target host to the correct address. + # This is the recommended way to override configuration values. + args[0] = 'localhost:7233' -func main() { - // Replace with the actual path to your TOML file. - configFilePath := "/Users/yourname/.config/my-app/temporal.toml" + puts "\nLoaded '#{profile_name}' profile from #{config_file} with overrides." + puts " Address: #{args[0]} (overridden from localhost:9999)" + puts " Namespace: #{args[1]}" - opts, err := envconfig.LoadClientOptions(envconfig.LoadClientOptionsRequest{ - ConfigFilePath: configFilePath, - }) - if err != nil { - log.Fatalf("Failed to load client config from custom file: %v", err) - } + 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 - c, err := client.Dial(opts) - if err != nil { - log.Fatalf("Failed to connect using custom config file: %v", err) - } - defer c.Close() +main if $PROGRAM_NAME == __FILE__ +``` - fmt.Printf("✅ Connected using custom config at: %s\n", configFilePath) + + + + +To load a specific profile from a custom path in .NET C#, use the `ClientEnvConfig.LoadClientConnectOptions()` method +with the `ProfileLoadOptions` parameter. Use the `Profile` property to specify the profile name and the `ConfigSource` +property to specify the file path. + +After loading the connection options, you can override specific settings programmatically before passing them to +`TemporalClient.ConnectAsync()`. Refer to the +[C# SDK API documentation](https://dotnet.temporal.io/api/Temporalio.Common.EnvConfig.html) for all available options. + +```csharp {18-19,25-28} +using Temporalio.Client; +using Temporalio.Client.EnvConfig; + +namespace TemporalioSamples.EnvConfig; + +/// +/// Sample demonstrating loading a named environment configuration profile and +/// programmatically overriding its values. +/// +public static class LoadProfile +{ + public static async Task RunAsync() + { + Console.WriteLine("--- Loading 'staging' profile with programmatic overrides ---"); + + try + { + var configFile = Path.Combine(Directory.GetCurrentDirectory(), "config.toml"); + var profileName = "staging"; + + Console.WriteLine("The 'staging' profile in config.toml has an incorrect address (localhost:9999)."); + Console.WriteLine("We'll programmatically override it to the correct address."); + + // Load the 'staging' profile + var connectOptions = ClientEnvConfig.LoadClientConnectOptions(new ClientEnvConfig.ProfileLoadOptions + { + Profile = profileName, + ConfigSource = DataSource.FromPath(configFile), + }); + + // Override the target host to the correct address. + // This is the recommended way to override configuration values. + connectOptions.TargetHost = "localhost:7233"; + + Console.WriteLine($"\nLoaded '{profileName}' profile from {configFile} with overrides."); + Console.WriteLine($" Address: {connectOptions.TargetHost} (overridden from localhost:9999)"); + Console.WriteLine($" Namespace: {connectOptions.Namespace}"); + + 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}"); + } + } } ``` -### Override configuration programmatically - -You can also load a base configuration and then override specific settings programmatically in your code. The loaded `client.Options` struct can be modified before passing it to `client.Dial()`. + -```go -package main - -import ( - "fmt" - "log" - - "go.temporal.io/sdk/client" - "go.temporal.io/sdk/contrib/envconfig" -) - -func main() { - // Load the base configuration (e.g., from the default profile). - opts := envconfig.MustLoadDefaultClientOptions() - - // Apply overrides programmatically. - opts.HostPort = "localhost:7233" - opts.Namespace = "test-namespace" - - c, err := client.Dial(opts) - if err != nil { - log.Fatalf("Failed to connect with overridden options: %v", err) - } - defer c.Close() - - fmt.Printf("✅ Connected with overridden config to: %s in namespace: %s\n", opts.HostPort, opts.Namespace) -} -``` + diff --git a/docs/develop/go/temporal-client.mdx b/docs/develop/go/temporal-client.mdx index 1a8035b5d4..2e429402db 100644 --- a/docs/develop/go/temporal-client.mdx +++ b/docs/develop/go/temporal-client.mdx @@ -2,7 +2,9 @@ id: temporal-client title: Temporal Client - Go SDK sidebar_label: Temporal Client -description: Connect to Temporal Service or Cloud, start Workflow Executions, manage Workflow options, and retrieve Workflow results using the Go SDK. Follow detailed steps and code examples to effectively use Temporal’s capabilities. +description: + Connect to Temporal Service or Cloud, start Workflow Executions, manage Workflow options, and retrieve Workflow + results using the Go SDK. Follow detailed steps and code examples to effectively use Temporal’s capabilities. toc_max_heading_level: 4 keywords: - temporal go sdk @@ -30,44 +32,183 @@ tags: - Certificates --- -The pages shows how to do the following: +A [Temporal Client](/encyclopedia/temporal-sdks#temporal-client) enables you to communicate with the +[Temporal Service](/temporal-service). Communication with a Temporal Service includes 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. + +This page shows you how to do the following using the Go SDK with the Temporal Client: - [Connect to a local development Temporal Service](#connect-to-development-service) - [Connect to Temporal Cloud](#connect-to-temporal-cloud) - [Start a Workflow Execution](#start-workflow-execution) -- [How to start a Workflow Execution](/develop/go/temporal-client#start-workflow-execution) +- [Get Workflow results](#get-workflow-results) + +:::caution + +A Temporal Client cannot be initialized and used inside a Workflow. However, it is acceptable and common to use a +Temporal Client inside an Activity to communicate with a Temporal Service. + +::: ## Connect to development Temporal Service {#connect-to-development-service} -**How to connect to the local Temporal CLI development Temporal Service using the Go SDK** +Use the [`Dial()`](https://pkg.go.dev/go.temporal.io/sdk/client#Dial) API available in the +[`go.temporal.io/sdk/client`](https://pkg.go.dev/go.temporal.io/sdk/client) package to create a +[`Client`](https://pkg.go.dev/go.temporal.io/sdk/client#Client). The `Dial()` API expects connection options such as the +Temporal Server address, the Namespace to connect to, and Transport Layer Security (TLS) configuration. You can specify +these options in the function call, or specify them using environment variables or a configuration file. We recommend +you use environment variables or a configuration file to manage these connection options securely. -A [Temporal Client](/encyclopedia/temporal-sdks#temporal-client) enables you to communicate with the [Temporal Service](/temporal-service). -Communication with a Temporal Service includes, but isn't limited to, the following: +:::info Versioning Requirements -- Starting Workflow Executions. -- Sending Signals to Workflow Executions. -- Sending Queries to Workflow Executions. -- Getting the results of a Workflow Execution. -- Providing an Activity Task Token. +Environment variable and configuration file support were added in Go SDK v1.28.0. -:::caution +::: + +When you are running a Temporal Service locally, such as the +[Temporal CLI](https://docs.temporal.io/cli/server#start-dev), the connection options you must provide are minimal. + +If you don't provide [`HostPort`](https://pkg.go.dev/go.temporal.io/sdk/internal#ClientOptions), the Client defaults the +address and port number to `127.0.0.1:7233`, which is the port of the development Temporal Service. If you don't set a +custom Namespace name in the Namespace field, the client connects to the default Namespace. + + -A Temporal Client cannot be initialized and used inside a Workflow. -However, it is acceptable and common to use a Temporal Client inside an Activity to communicate with a Temporal Service. + + +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](/references/client-environment-configuration) + +:::info + +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. ::: -When you are running a Temporal Service locally (such as the [Temporal CLI](https://docs.temporal.io/cli/server#start-dev)), the number of connection options you must provide is minimal. -Many SDKs default to the local host or IP address and port that Temporalite and [Docker Compose](https://github.com/temporalio/docker-compose) serve (`127.0.0.1:7233`). +For example, the following TOML configuration file defines two profiles: `default` and `prod`. Each profile has its own +set of connection options. + +```toml +# 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: + +```go +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](/references/client-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. + +```go +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) +} + +``` -Use the [`Dial()`](https://pkg.go.dev/go.temporal.io/sdk/client#Dial) API available in the [`go.temporal.io/sdk/client`](https://pkg.go.dev/go.temporal.io/sdk/client) package to create a [`Client`](https://pkg.go.dev/go.temporal.io/sdk/client#Client). + -If you don't provide [`HostPort`](https://pkg.go.dev/go.temporal.io/sdk/internal#ClientOptions), the Client defaults the address and port number to `127.0.0.1:7233`, which is the port of the development Temporal Service. + -If you don't set a custom Namespace name in the Namespace field, the client connects to the default Namespace. +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. + +{/* SNIPSTART samples-apps-go-yourapp-gateway {"selectedLines": ["1-23", "32"]} */} - [sample-apps/go/yourapp/gateway/main.go](https://github.com/temporalio/documentation/blob/main/sample-apps/go/yourapp/gateway/main.go) + ```go package main @@ -92,31 +233,170 @@ func main() { log.Fatalln("Unable to create Temporal Client", err) } defer temporalClient.Close() -// ... + // ... } ``` - -## Connect to Temporal Cloud {#connect-to-temporal-cloud} +{/* SNIPEND */} -### How to connect to Temporal Cloud using an API Key {#connect-to-temporal-cloud-api-key} + -To use an [API key](/cloud/api-keys) with the Temporal Go SDK, you will need to provide additional connection options: + -- Your _API Key_ value -- Your _Namespace and Account id_ combination, which follows the format `.`. -- The _endpoint_ may vary. The most common endpoint used is the gRPC regional endpoint, which follows the format: `..api.temporal.io:7233`. -- For Namespaces with High Availability features with API key authentication enabled, use the gRPC Namespace endpoint: `..tmprl.cloud:7233`. - This allows automated failover without needing to switch endpoints. +## Connect to Temporal Cloud {#connect-to-temporal-cloud} + +You can connect to Temporal Cloud using either an [API key](/cloud/api-keys) or through mTLS. Connection to Temporal +Cloud or any secured Temporal Service requires additional connection options compared to connecting to an unsecured +local development instance: + +- Your credentials for authentication. + - If you are using an API key, provide the API key value. + - If you are using mTLS, provide the mTLS CA certificate and mTLS private key. +- Your _Namespace and Account ID_ combination, which follows the format `.`. +- The _endpoint_ may vary. The most common endpoint used is the gRPC regional endpoint, which follows the format: + `..api.temporal.io:7233`. +- For Namespaces with High Availability features with API key authentication enabled, use the gRPC Namespace endpoint: + `..tmprl.cloud:7233`. This allows automated failover without needing to switch endpoints. You can find the Namespace and Account ID, as well as the endpoint, on the Namespaces tab: ![The Namespace and Account ID combination on the left, and the regional endpoint on the right](/img/cloud/apikeys/namespaces-and-regional-endpoints.png) -Now, when instantiating a Temporal `client` in your Temporal Go SDK code, provide the API key with the following `clientOptions`: +You can provide these connection options using environment variables, a configuration file, or directly in code. -
-v1.33.0+ + + + + +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. For a list of all available configuration options you can set in the TOML file, refer to +[Environment Configuration](/references/client-environment-configuration). + +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 path to the configuration file, the SDK looks for it at the +default path `~/.config/temporalio/temporal.toml`. + +:::info + +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 a `cloud` profile with the necessary connection options to +connect to Temporal Cloud via an API key: + +```toml +# Cloud profile for Temporal Cloud +[profile.cloud] +address = "your-namespace.a1b2c.tmprl.cloud:7233" +namespace = "your-namespace" +api_key = "your-api-key-here" +``` + +If you want to use mTLS authentication instead of an API key, replace the `api_key` field with your mTLS certificate and +private key: + +```toml +# Cloud profile for Temporal Cloud +[profile.cloud] +address = "your-namespace.a1b2c.tmprl.cloud:7233" +namespace = "your-namespace" +tls_client_cert_data = "your-tls-client-cert-data" +tls_client_key_path = "your-tls-client-key-path" +``` + +With the connections options defined in the configuration file, use the `LoadClientOptions` function in the `envconfig` +package to create a Temporal Client using the `cloud` profile as follows: + +```go {13-15} +package main + +import ( + "fmt" + "log" + + "go.temporal.io/sdk/client" + "go.temporal.io/sdk/contrib/envconfig" +) + +func main() { + // Replace with the actual path to your TOML file. + configFilePath := "/Users/yourname/.config/my-app/temporal.toml" + + opts, err := envconfig.LoadClientOptions(envconfig.LoadClientOptionsRequest{ + ConfigFilePath: configFilePath, + }) + if err != nil { + log.Fatalf("Failed to load client config from custom file: %v", err) + } + + c, err := client.Dial(opts) + if err != nil { + log.Fatalf("Failed to connect using custom config file: %v", err) + } + defer c.Close() + + fmt.Printf("✅ Connected using custom config at: %s\n", configFilePath) +} +``` + + + + +The following environment variables are required to connect to Temporal Cloud: + +- `TEMPORAL_NAMESPACE`: Your Namespace and Account ID combination in the format `.`. +- `TEMPORAL_ADDRESS`: The gRPC endpoint for your Temporal Cloud Namespace. +- `TEMPORAL_API_KEY`: Your API key value. Required if you are using API key authentication. +- `TEMPORAL_TLS_CLIENT_CERT_DATA` or `TEMPORAL_TLS_CLIENT_CERT_PATH`: Your mTLS client certificate data or file path. + Required if you are using mTLS authentication. +- `TEMPORAL_TLS_CLIENT_KEY_DATA` or `TEMPORAL_TLS_CLIENT_KEY_PATH`: Your mTLS client private key data or file path. + Required if you are using mTLS authentication. + +Ensure these environment variables exist in your environment before running your Go application. + +Import the `envconfig` package to set connection options for the Temporal Client using environment variables. The +`MustLoadDefaultClientOptions` function will automatically load all environment variables. For a list of all available +environment variables and their default values, refer to [Environment Configuration](../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. + +```go {13} +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 Service") +} +``` + + + + + +You can also provide connections options in your Go code directly. When instantiating a Temporal `client` in your +Temporal Go SDK code, provide the following `clientOptions`: ```go clientOptions := client.Options{ @@ -139,10 +419,47 @@ creds := client.NewAPIKeyDynamicCredentials( myKey = myKeyUpdated ``` -
+You can use a combination of environment variables, configuration files, and code to set connection options. For +example, you can load a base configuration from environment variables or a configuration file, and then override +specific options in code. + +For example, the following code snippet loads the base configuration from environment variables and the default profile +with `envconfig.MustLoadDefaultClientOptions()`. It then overrides the `HostPort` and `Namespace` options +programmatically. Refer to +[Client Options type in the Go SDK](https://pkg.go.dev/go.temporal.io/sdk/internal#ClientOptions) for a list of all +available connection options you can override. + +```go +package main + +import ( + "fmt" + "log" + + "go.temporal.io/sdk/client" + "go.temporal.io/sdk/contrib/envconfig" +) + +func main() { + // Load the base configuration (e.g., from the default profile). + opts := envconfig.MustLoadDefaultClientOptions() + + // Apply overrides programmatically. + opts.HostPort = "localhost:7233" + opts.Namespace = "test-namespace" + + c, err := client.Dial(opts) + if err != nil { + log.Fatalf("Failed to connect with overridden options: %v", err) + } + defer c.Close() + + fmt.Printf("✅ Connected with overridden config to: %s in namespace: %s\n", opts.HostPort, opts.Namespace) +} +```
-v1.26.0 to v1.33.0 (exclusive) +v1.26.0 to v1.32.x Create an initial connection: @@ -223,97 +540,37 @@ apiKeyProvider.APIKey = myKeyUpdated
-### How to connect to Temporal Cloud using mTLS {#connect-to-temporal-cloud-tls} - -When you connect to [Temporal Cloud](/cloud) with mTLS, you need to provide additional connection and client options that include the following: - -- The [Temporal Cloud Namespace Id](/cloud/namespaces#temporal-cloud-namespace-id). -- The [Namespace's gRPC endpoint](/cloud/namespaces#temporal-cloud-grpc-endpoint). - An endpoint listing is available at the [Temporal Cloud Website](https://cloud.temporal.io/namespaces) on each Namespace detail page. - The endpoint contains the Namespace Id and port. -- mTLS CA certificate. -- mTLS private key. - -For more information about managing and generating client certificates for Temporal Cloud, see [How to manage certificates in Temporal Cloud](/cloud/certificates). - -For more information about configuring TLS to secure inter- and intra-network communication for a Temporal Service, see [Temporal Customization Samples](https://github.com/temporalio/samples-server). + -To connect to and run Workflows through Temporal Cloud, you need the following: - -- A compatible mTLS CA certificate and mTLS private key that has been added to your Namespace. - See [certificate requirements](/cloud/certificates#certificate-requirements). -- Your [Temporal Cloud Namespace Id](/cloud/namespaces#temporal-cloud-namespace-id), which includes your [Temporal Cloud Namespace Name](/cloud/namespaces#temporal-cloud-namespace-name) and the unique five- or six-digit [Temporal Cloud Account Id](/cloud/namespaces#temporal-cloud-account-id) that is appended to it. - This information can be found in the URL of your Namespace; for example, `https://cloud.temporal.io/namespaces/yournamespace.a2fx6/`. - Remember that the Namespace Id must include the Account Id: `yournamespace.a2fx6`. - -For more information about managing and generating client certificates for Temporal Cloud, see [How to manage certificates in Temporal Cloud](/cloud/certificates). - -For more information about configuring TLS to secure inter- and intra-network communication for a Temporal Service, see [Temporal Customization Samples](https://github.com/temporalio/samples-server). - - -[sample-apps/go/cloud/client/main.go](https://github.com/temporalio/documentation/blob/main/sample-apps/go/cloud/client/main.go) -```go -package main - -import ( - "context" - "crypto/tls" - "encoding/json" - "log" - - "documentation-samples-go/cloud" - - "go.temporal.io/sdk/client" -) - -func main() { - // Get the key and cert from your env or local machine - clientKeyPath := "./secrets/yourkey.key" - clientCertPath := "./secrets/yourcert.pem" - // Specify the host and port of your Temporal Cloud Namespace - // Host and port format: namespace.unique_id.tmprl.cloud:port - hostPort := "..tmprl.cloud:7233" - namespace := "." - // Use the crypto/tls package to create a cert object - cert, err := tls.LoadX509KeyPair(clientCertPath, clientKeyPath) - if err != nil { - log.Fatalln("Unable to load cert and key pair.", err) - } - // Add the cert to the tls certificates in the ConnectionOptions of the Client - temporalClient, err := client.Dial(client.Options{ - HostPort: hostPort, - Namespace: namespace, - ConnectionOptions: client.ConnectionOptions{ - TLS: &tls.Config{Certificates: []tls.Certificate{cert}}, - }, - }) - if err != nil { - log.Fatalln("Unable to connect to Temporal Cloud.", err) - } - defer temporalClient.Close() -// ... -} -``` - + ## Start Workflow Execution {#start-workflow-execution} **How to start a Workflow Execution using the Go SDK** -[Workflow Execution](/workflow-execution) semantics rely on several parameters—that is, to start a Workflow Execution you must supply a Task Queue that will be used for the Tasks (one that a Worker is polling), the Workflow Type, language-specific contextual data, and Workflow Function parameters. +[Workflow Execution](/workflow-execution) semantics rely on several parameters—that is, to start a Workflow Execution +you must supply a Task Queue that will be used for the Tasks (one that a Worker is polling), the Workflow Type, +language-specific contextual data, and Workflow Function parameters. -In the examples below, all Workflow Executions are started using a Temporal Client. -To spawn Workflow Executions from within another Workflow Execution, use either the [Child Workflow](/develop/go/child-workflows) or External Workflow APIs. +In the examples below, all Workflow Executions are started using a Temporal Client. To spawn Workflow Executions from +within another Workflow Execution, use either the [Child Workflow](/develop/go/child-workflows) or External Workflow +APIs. -See the [Customize Workflow Type](/develop/go/core-application#customize-workflow-type) section to see how to customize the name of the Workflow Type. +See the [Customize Workflow Type](/develop/go/core-application#customize-workflow-type) section to see how to customize +the name of the Workflow Type. -A request to spawn a Workflow Execution causes the Temporal Service to create the first Event ([WorkflowExecutionStarted](/references/events#workflowexecutionstarted)) in the Workflow Execution Event History. -The Temporal Service then creates the first Workflow Task, resulting in the first [WorkflowTaskScheduled](/references/events#workflowtaskscheduled) Event. +A request to spawn a Workflow Execution causes the Temporal Service to create the first Event +([WorkflowExecutionStarted](/references/events#workflowexecutionstarted)) in the Workflow Execution Event History. The +Temporal Service then creates the first Workflow Task, resulting in the first +[WorkflowTaskScheduled](/references/events#workflowtaskscheduled) Event. -To spawn a [Workflow Execution](/workflow-execution), use the `ExecuteWorkflow()` method on the Go SDK [`Client`](https://pkg.go.dev/go.temporal.io/sdk/client#Client). +To spawn a [Workflow Execution](/workflow-execution), use the `ExecuteWorkflow()` method on the Go SDK +[`Client`](https://pkg.go.dev/go.temporal.io/sdk/client#Client). -The `ExecuteWorkflow()` API call requires an instance of [`context.Context`](https://pkg.go.dev/context#Context), an instance of [`StartWorkflowOptions`](https://pkg.go.dev/go.temporal.io/sdk/client#StartWorkflowOptions), a Workflow Type name, and all variables to be passed to the Workflow Execution. -The `ExecuteWorkflow()` call returns a Future, which can be used to get the result of the Workflow Execution. +The `ExecuteWorkflow()` API call requires an instance of [`context.Context`](https://pkg.go.dev/context#Context), an +instance of [`StartWorkflowOptions`](https://pkg.go.dev/go.temporal.io/sdk/client#StartWorkflowOptions), a Workflow Type +name, and all variables to be passed to the Workflow Execution. The `ExecuteWorkflow()` call returns a Future, which can +be used to get the result of the Workflow Execution. ```go package main @@ -346,13 +603,16 @@ func YourWorkflowDefinition(ctx workflow.Context, param YourWorkflowParam) (Your } ``` -If the invocation process has access to the function directly, then the Workflow Type name parameter can be passed as if the function name were a variable, without quotations. +If the invocation process has access to the function directly, then the Workflow Type name parameter can be passed as if +the function name were a variable, without quotations. ```go workflowRun, err := temporalClient.ExecuteWorkflow(context.Background(), workflowOptions, YourWorkflowDefinition, param) ``` -If the invocation process does not have direct access to the statically defined Workflow Definition, for example, if the Workflow Definition is in an un-importable package, or it is written in a completely different language, then the Workflow Type can be provided as a `string`. +If the invocation process does not have direct access to the statically defined Workflow Definition, for example, if the +Workflow Definition is in an un-importable package, or it is written in a completely different language, then the +Workflow Type can be provided as a `string`. ```go workflowRun, err := c.ExecuteWorkflow(context.Background(), workflowOptions, "YourWorkflowDefinition", param) @@ -364,9 +624,12 @@ workflowRun, err := c.ExecuteWorkflow(context.Background(), workflowOptions, "Yo In most SDKs, the only Workflow Option that must be set is the name of the [Task Queue](/task-queue). -For any code to execute, a Worker Process must be running that contains a Worker Entity that is polling the same Task Queue name. +For any code to execute, a Worker Process must be running that contains a Worker Entity that is polling the same Task +Queue name. -Create an instance of [`StartWorkflowOptions`](https://pkg.go.dev/go.temporal.io/sdk@v1.10.0/client#StartWorkflowOptions) from the `go.temporal.io/sdk/client` package, set the `TaskQueue` field, and pass the instance to the `ExecuteWorkflow` call. +Create an instance of +[`StartWorkflowOptions`](https://pkg.go.dev/go.temporal.io/sdk@v1.10.0/client#StartWorkflowOptions) from the +`go.temporal.io/sdk/client` package, set the `TaskQueue` field, and pass the instance to the `ExecuteWorkflow` call. - Type: `string` - Default: None, this is a required field to be set by the developer @@ -383,16 +646,22 @@ if err != nil { } ``` -You can configure Task Queues that are host-specific, Worker-specific or Workflow-specific to distribute your application load. -For more information, refer to [Task Queues Processing Tuning](/develop/worker-performance#task-queues-processing-tuning) and [Worker Versioning](https://docs.temporal.io/worker-versioning). +You can configure Task Queues that are host-specific, Worker-specific or Workflow-specific to distribute your +application load. For more information, refer to +[Task Queues Processing Tuning](/develop/worker-performance#task-queues-processing-tuning) and +[Worker Versioning](https://docs.temporal.io/worker-versioning). ### Set custom Workflow Id {#workflow-id} **How to set a custom Workflow Id using the Go SDK** -Although it is not required, we recommend providing your own [Workflow Id](/workflow-execution/workflowid-runid#workflow-id)that maps to a business process or business entity identifier, such as an order identifier or customer identifier. +Although it is not required, we recommend providing your own +[Workflow Id](/workflow-execution/workflowid-runid#workflow-id)that maps to a business process or business entity +identifier, such as an order identifier or customer identifier. -Create an instance of [`StartWorkflowOptions`](https://pkg.go.dev/go.temporal.io/sdk@v1.10.0/client#StartWorkflowOptions) from the `go.temporal.io/sdk/client` package, set the `ID` field, and pass the instance to the `ExecuteWorkflow` call. +Create an instance of +[`StartWorkflowOptions`](https://pkg.go.dev/go.temporal.io/sdk@v1.10.0/client#StartWorkflowOptions) from the +`go.temporal.io/sdk/client` package, set the `ID` field, and pass the instance to the `ExecuteWorkflow` call. - Type: `string` - Default: System generated UUID @@ -411,7 +680,9 @@ if err != nil { ### Go StartWorkflowOptions reference {#workflow-options-reference} -Create an instance of [`StartWorkflowOptions`](https://pkg.go.dev/go.temporal.io/sdk@v1.10.0/client#StartWorkflowOptions) from the `go.temporal.io/sdk/client` package, and pass the instance to the `ExecuteWorkflow` call. +Create an instance of +[`StartWorkflowOptions`](https://pkg.go.dev/go.temporal.io/sdk@v1.10.0/client#StartWorkflowOptions) from the +`go.temporal.io/sdk/client` package, and pass the instance to the `ExecuteWorkflow` call. The following fields are available: @@ -431,9 +702,12 @@ The following fields are available: #### ID -Although it is not required, we recommend providing your own [Workflow Id](/workflow-execution/workflowid-runid#workflow-id)that maps to a business process or business entity identifier, such as an order identifier or customer identifier. +Although it is not required, we recommend providing your own +[Workflow Id](/workflow-execution/workflowid-runid#workflow-id)that maps to a business process or business entity +identifier, such as an order identifier or customer identifier. -Create an instance of [StartWorkflowOptions](https://pkg.go.dev/go.temporal.io/sdk@v1.10.0/client#StartWorkflowOptions) from the `go.temporal.io/sdk/client` package, set the `ID` field, and pass the instance to the `ExecuteWorkflow` call. +Create an instance of [StartWorkflowOptions](https://pkg.go.dev/go.temporal.io/sdk@v1.10.0/client#StartWorkflowOptions) +from the `go.temporal.io/sdk/client` package, set the `ID` field, and pass the instance to the `ExecuteWorkflow` call. - Type: `string` - Default: System generated UUID @@ -452,7 +726,9 @@ if err != nil { #### TaskQueue -Create an instance of [StartWorkflowOptions](https://pkg.go.dev/go.temporal.io/sdk@v1.10.0/client#StartWorkflowOptions) from the `go.temporal.io/sdk/client` package, set the `TaskQueue` field, and pass the instance to the `ExecuteWorkflow` call. +Create an instance of [StartWorkflowOptions](https://pkg.go.dev/go.temporal.io/sdk@v1.10.0/client#StartWorkflowOptions) +from the `go.temporal.io/sdk/client` package, set the `TaskQueue` field, and pass the instance to the `ExecuteWorkflow` +call. - Type: `string` - Default: None; this is a required field to be set by the developer @@ -471,7 +747,9 @@ if err != nil { #### WorkflowExecutionTimeout -Create an instance of [StartWorkflowOptions](https://pkg.go.dev/go.temporal.io/sdk/client#StartWorkflowOptions) from the `go.temporal.io/sdk/client` package, set the `WorkflowExecutionTimeout` field, and pass the instance to the `ExecuteWorkflow` call. +Create an instance of [StartWorkflowOptions](https://pkg.go.dev/go.temporal.io/sdk/client#StartWorkflowOptions) from the +`go.temporal.io/sdk/client` package, set the `WorkflowExecutionTimeout` field, and pass the instance to the +`ExecuteWorkflow` call. - Type: `time.Duration` - Default: Unlimited @@ -490,7 +768,9 @@ if err != nil { #### WorkflowRunTimeout -Create an instance of [StartWorkflowOptions](https://pkg.go.dev/go.temporal.io/sdk/client#StartWorkflowOptions) from the `go.temporal.io/sdk/client` package, set the `WorkflowRunTimeout` field, and pass the instance to the `ExecuteWorkflow` call. +Create an instance of [StartWorkflowOptions](https://pkg.go.dev/go.temporal.io/sdk/client#StartWorkflowOptions) from the +`go.temporal.io/sdk/client` package, set the `WorkflowRunTimeout` field, and pass the instance to the `ExecuteWorkflow` +call. - Type: `time.Duration` - Default: Same as [`WorkflowExecutionTimeout`](#workflowexecutiontimeout) @@ -508,7 +788,9 @@ if err != nil { #### WorkflowTaskTimeout -Create an instance of [StartWorkflowOptions](https://pkg.go.dev/go.temporal.io/sdk/client#StartWorkflowOptions) from the `go.temporal.io/sdk/client` package, set the `WorkflowTaskTimeout` field, and pass the instance to the `ExecuteWorkflow` call. +Create an instance of [StartWorkflowOptions](https://pkg.go.dev/go.temporal.io/sdk/client#StartWorkflowOptions) from the +`go.temporal.io/sdk/client` package, set the `WorkflowTaskTimeout` field, and pass the instance to the `ExecuteWorkflow` +call. - Type: `time.Duration` - Default: `time.Seconds * 10` @@ -560,7 +842,9 @@ if err != nil { #### RetryPolicy -Create an instance of a [RetryPolicy](https://pkg.go.dev/go.temporal.io/sdk/temporal#RetryPolicy) from the `go.temporal.io/sdk/temporal` package and provide it as the value to the `RetryPolicy` field of the instance of `StartWorkflowOptions`. +Create an instance of a [RetryPolicy](https://pkg.go.dev/go.temporal.io/sdk/temporal#RetryPolicy) from the +`go.temporal.io/sdk/temporal` package and provide it as the value to the `RetryPolicy` field of the instance of +`StartWorkflowOptions`. - Type: [RetryPolicy](https://pkg.go.dev/go.temporal.io/sdk/temporal#RetryPolicy) - Default: None @@ -654,13 +938,18 @@ if err != nil { If the call to start a Workflow Execution is successful, you will gain access to the Workflow Execution's Run Id. -The Workflow Id, Run Id, and Namespace may be used to uniquely identify a Workflow Execution in the system and get its result. +The Workflow Id, Run Id, and Namespace may be used to uniquely identify a Workflow Execution in the system and get its +result. -It's possible to both block progress on the result (synchronous execution) or get the result at some other point in time (asynchronous execution). +It's possible to both block progress on the result (synchronous execution) or get the result at some other point in time +(asynchronous execution). -In the Temporal Platform, it's also acceptable to use Queries as the preferred method for accessing the state and results of Workflow Executions. +In the Temporal Platform, it's also acceptable to use Queries as the preferred method for accessing the state and +results of Workflow Executions. -The `ExecuteWorkflow` call returns an instance of [`WorkflowRun`](https://pkg.go.dev/go.temporal.io/sdk/client#WorkflowRun), which is the `workflowRun` variable in the following line. +The `ExecuteWorkflow` call returns an instance of +[`WorkflowRun`](https://pkg.go.dev/go.temporal.io/sdk/client#WorkflowRun), which is the `workflowRun` variable in the +following line. ```go workflowRun, err := c.ExecuteWorkflow(context.Background(), workflowOptions, app.YourWorkflowDefinition, param) @@ -674,10 +963,12 @@ The `ExecuteWorkflow` call returns an instance of [`WorkflowRun`](https://pkg.go The instance of `WorkflowRun` has the following three methods: - `GetWorkflowID()`: Returns the Workflow Id of the invoked Workflow Execution. -- `GetRunID()`: Always returns the Run Id of the initial Run (See [Continue As New](#)) in the series of Runs that make up the full Workflow Execution. +- `GetRunID()`: Always returns the Run Id of the initial Run (See [Continue As New](#)) in the series of Runs that make + up the full Workflow Execution. - `Get`: Takes a pointer as a parameter and populates the associated variable with the Workflow Execution result. -To wait on the result of Workflow Execution in the same process that invoked it, call `Get()` on the instance of `WorkflowRun` that is returned by the `ExecuteWorkflow()` call. +To wait on the result of Workflow Execution in the same process that invoked it, call `Get()` on the instance of +`WorkflowRun` that is returned by the `ExecuteWorkflow()` call. ```go workflowRun, err := c.ExecuteWorkflow(context.Background(), workflowOptions, YourWorkflowDefinition, param) @@ -693,15 +984,16 @@ To wait on the result of Workflow Execution in the same process that invoked it, } ``` -However, the result of a Workflow Execution can be obtained from a completely different process. -All that is needed is the [Workflow Id](#). -(A [Run Id](#) is optional if more than one closed Workflow Execution has the same Workflow Id.) -The result of the Workflow Execution is available for as long as the Workflow Execution Event History remains in the system. +However, the result of a Workflow Execution can be obtained from a completely different process. All that is needed is +the [Workflow Id](#). (A [Run Id](#) is optional if more than one closed Workflow Execution has the same Workflow Id.) +The result of the Workflow Execution is available for as long as the Workflow Execution Event History remains in the +system. {/* TODO (See [How long do Workflow Execution Histories persist](#)). */} -Call the `GetWorkflow()` method on an instance of the Go SDK Client and pass it the Workflow Id used to spawn the Workflow Execution. -Then call the `Get()` method on the instance of `WorkflowRun` that is returned, passing it a pointer to populate the result. +Call the `GetWorkflow()` method on an instance of the Go SDK Client and pass it the Workflow Id used to spawn the +Workflow Execution. Then call the `Get()` method on the instance of `WorkflowRun` that is returned, passing it a pointer +to populate the result. ```go // ... @@ -718,9 +1010,13 @@ Then call the `Get()` method on the instance of `WorkflowRun` that is returned, **Get last completion result** -In the case of a [Temporal Cron Job](/cron-job), you might need to get the result of the previous Workflow Run and use it in the current Workflow Run. +In the case of a [Temporal Cron Job](/cron-job), you might need to get the result of the previous Workflow Run and use +it in the current Workflow Run. -To do this, use the [`HasLastCompletionResult`](https://pkg.go.dev/go.temporal.io/sdk/workflow#HasLastCompletionResult) and [`GetLastCompletionResult`](https://pkg.go.dev/go.temporal.io/sdk/workflow#GetLastCompletionResult) APIs, available from the [`go.temporal.io/sdk/workflow`](https://pkg.go.dev/go.temporal.io/sdk/workflow) package, directly in your Workflow code. +To do this, use the [`HasLastCompletionResult`](https://pkg.go.dev/go.temporal.io/sdk/workflow#HasLastCompletionResult) +and [`GetLastCompletionResult`](https://pkg.go.dev/go.temporal.io/sdk/workflow#GetLastCompletionResult) APIs, available +from the [`go.temporal.io/sdk/workflow`](https://pkg.go.dev/go.temporal.io/sdk/workflow) package, directly in your +Workflow code. ```go type CronResult struct { @@ -744,5 +1040,5 @@ func YourCronWorkflowDefinition(ctx workflow.Context) (CronResult, error) { } ``` -This will work even if one of the cron Workflow Runs fails. -The next Workflow Run gets the result of the last successfully Completed Workflow Run. +This will work even if one of the cron Workflow Runs fails. The next Workflow Run gets the result of the last +successfully Completed Workflow Run. diff --git a/docs/develop/python/index.mdx b/docs/develop/python/index.mdx index 3dd80fcbb3..9f83eec7ee 100644 --- a/docs/develop/python/index.mdx +++ b/docs/develop/python/index.mdx @@ -46,7 +46,6 @@ Use the essential components of a Temporal Application (Workflows, Activities, a Connect to a Temporal Service and start a Workflow Execution. - [Connect to Development Temporal Service](/develop/python/temporal-client#connect-to-development-service) -- [Connect a Temporal Client to a Temporal Service](/develop/python/temporal-client#connect-to-a-dev-cluster) - [Connect to Temporal Cloud](/develop/python/temporal-client#connect-to-temporal-cloud) - [Start a Workflow Execution](/develop/python/temporal-client#start-workflow-execution) diff --git a/docs/develop/python/temporal-client.mdx b/docs/develop/python/temporal-client.mdx new file mode 100644 index 0000000000..6a537e1469 --- /dev/null +++ b/docs/develop/python/temporal-client.mdx @@ -0,0 +1,667 @@ +--- +id: temporal-client +title: Temporal Client - Python SDK +sidebar_label: Temporal Client +toc_max_heading_level: 4 +description: + Discover how to connect and use Temporal Clients with Python. Link your Client to Temporal Service, Temporal Cloud, + start Workflow Executions, set Task Queues, Workflow Ids, and get Workflow results. +keywords: + - temporal python client + - connect python client to temporal service + - initialize temporal client + - temporal SDK python guide + - start workflow execution python + - temporal cloud connection + - python client for temporal cli + - custom namespace configuration + - temporal workflow management + - temporal client setup + - python workflow execution + - temporal cloud integration + - temporal client options + - managing temporal namespaces +tags: + - Temporal Client + - Python SDK + - Temporal SDKs + - Certificates +--- + +A [Temporal Client](https://chatgpt.com/encyclopedia/temporal-sdks#temporal-client) enables you to communicate with the +Temporal Service. Communication with a Temporal Service lets you perform actions such as starting Workflow Executions, +sending Signals and Queries to Workflow Executions, getting Workflow results, and more. + +This page shows you how to do the following using the Python SDK with the Temporal Client: + +- [Connect to a local development Temporal Service](#connect-to-development-service) +- [Connect to Temporal Cloud](#connect-to-temporal-cloud) +- [Start a Workflow Execution](#start-workflow-execution) +- [Get Workflow results](#get-workflow-results) + +A Temporal Client cannot be initialized and used inside a Workflow. However, it is acceptable and common to use a +Temporal Client inside an Activity to communicate with a Temporal Service. + +## Connect to development Temporal Service {#connect-to-development-service} + +Use [`Client.connect`](https://python.temporal.io/temporalio.client.Client.html#connect) to create a client. Connection +options include the Temporal Server address, Namespace, and (optionally) TLS configuration. You can provide these +options directly in code, load them from **environment variables**, or a **TOML configuration file** using the +[`envconfig`](https://python.temporal.io/temporalio.envconfig.html) helpers. We recommend environment variables or a +configuration file for secure, repeatable configuration. + +When you’re running a Temporal Service locally (such as with the +[Temporal CLI dev server](https://docs.temporal.io/cli/server#start-dev)), the required options are minimal. If you +don't specify a host/port, most connections default to `127.0.0.1:7233` and the `default` Namespace. + + + + + +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](../environment-configuration.mdx#configuration-methods) for more details about configuration +files and profiles. + +:::info + +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. + +```toml title="config.toml" +# 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: + +```python {23-25} +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](/references/client-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. + +```bash +export TEMPORAL_NAMESPACE="default" +export TEMPORAL_ADDRESS="localhost:7233" +``` + +After setting the environment variables, you can create a Temporal Client as follows: + +```python {11,19} +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. + +
+ + View the source code + {' '} + in the context of the rest of the application code. +
+ +```python +# ... +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()) +``` + +
+ +
+ +## Connect to Temporal Cloud {#connect-to-temporal-cloud} + +You can connect to Temporal Cloud using either an [API key](/cloud/api-keys) or through mTLS. Connection to Temporal +Cloud or any secured Temporal Service requires additional connection options compared to connecting to an unsecured +local development instance: + +- Your credentials for authentication. + - If you are using an API key, provide the API key value. + - If you are using mTLS, provide the mTLS CA certificate and mTLS private key. +- Your _Namespace and Account ID_ combination, which follows the format `.`. +- The _endpoint_ may vary. The most common endpoint used is the gRPC regional endpoint, which follows the format: + `..api.temporal.io:7233`. +- For Namespaces with High Availability features with API key authentication enabled, use the gRPC Namespace endpoint: + `..tmprl.cloud:7233`. This allows automated failover without needing to switch endpoints. + +You can find the Namespace and Account ID, as well as the endpoint, on the Namespaces tab: + +![The Namespace and Account ID combination on the left, and the regional endpoint on the right](/img/cloud/apikeys/namespaces-and-regional-endpoints.png) + +You can provide these connection options using environment variables, a configuration file, or directly in 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. For a list of all available configuration options you can set in the TOML file, refer to +[Environment Configuration](/references/client-environment-configuration). + +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 path to the configuration file, the SDK looks for it at the +default path `~/.config/temporalio/temporal.toml`. + +:::info + +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 a `staing` profile with the necessary connection options to +connect to Temporal Cloud via an API key: + +For example, the following TOML configuration file defines a `staging` profile with the necessary connection options to +connect to Temporal Cloud via an API key: + +```toml +# Cloud profile for Temporal Cloud +[profile.staging] +address = "your-namespace.a1b2c.tmprl.cloud:7233" +namespace = "your-namespace" +api_key = "your-api-key-here" +``` + +If you want to use mTLS authentication instead of an API key, replace the `api_key` field with your mTLS certificate and +private key: + +```toml +# Cloud profile for Temporal Cloud +[profile.staging] +address = "your-namespace.a1b2c.tmprl.cloud:7233" +namespace = "your-namespace" +tls_client_cert_data = "your-tls-client-cert-data" +tls_client_key_path = "your-tls-client-key-path" +``` + +With the connections options defined in the configuration file, use the +[`connect` method](https://python.temporal.io/temporalio.client.Client.html#connect) on the `Client` class to create a +Temporal Client using the `staging` profile as follows. After loading the profile, you can also programmatically +override specific connection options before creating the client. + +```python {14,23-25} +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()) +``` + + + + + +The following environment variables are required to connect to Temporal Cloud: + +- `TEMPORAL_NAMESPACE`: Your Namespace and Account ID combination in the format `.`. +- `TEMPORAL_ADDRESS`: The gRPC endpoint for your Temporal Cloud Namespace. +- `TEMPORAL_API_KEY`: Your API key value. Required if you are using API key authentication. +- `TEMPORAL_TLS_CLIENT_CERT_DATA` or `TEMPORAL_TLS_CLIENT_CERT_PATH`: Your mTLS client certificate data or file path. + Required if you are using mTLS authentication. +- `TEMPORAL_TLS_CLIENT_KEY_DATA` or `TEMPORAL_TLS_CLIENT_KEY_PATH`: Your mTLS client private key data or file path. + Required if you are using mTLS authentication. + +Ensure these environment variables exist in your environment before running your Python application. + +Import the `EnvConfig` package to set connection options for the Temporal Client using environment variables. The +`MustLoadDefaultClientOptions` function will automatically load all environment variables. For a list of all available +environment variables and their default values, refer to [Environment Configuration](../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. + +After setting the environment variables, use the following code to create the Temporal Client: + +```python {11, 19} +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()) +``` + + + + + +You can also specify connection options directly in code to connect to Temporal Cloud. To create an initial connection, +provide the endpoint, Namespace and Account ID combination, and API key values to the `Client.connect` method. + +```python +client = await Client.connect( + , + namespace=., + api_key=, + tls=True, +) +``` + +To connect using mTLS instead of an API key, provide the mTLS certificate and private key as follows: + +
+ + View the source code + {' '} + in the context of the rest of the application code. +
+```python +from temporalio.client import Client, TLSConfig +# ... +# ... +async def main(): + with open("client-cert.pem", "rb") as f: + client_cert = f.read() + with open("client-private-key.pem", "rb") as f: + client_private_key = f.read() + client = await Client.connect( + "your-custom-namespace.tmprl.cloud:7233", + namespace=".", + tls=TLSConfig( + client_cert=client_cert, + client_private_key=client_private_key, + # domain=domain, # TLS domain + # server_root_ca_cert=server_root_ca_cert, # ROOT CA to validate the server cert + ), + ) +``` + +For more information about managing and generating client certificates for Temporal Cloud, see +[How to manage certificates in Temporal Cloud](/cloud/certificates). + +For more information about configuring TLS to secure inter- and intra-network communication for a Temporal Service, see +[Temporal Customization Samples](https://github.com/temporalio/samples-server). + +
+ +
+ +## Start a Workflow Execution {#start-workflow-execution} + +**How to start a Workflow Execution using the Python SDK** + +[Workflow Execution](/workflow-execution) semantics rely on several parameters—that is, to start a Workflow Execution +you must supply a Task Queue that will be used for the Tasks (one that a Worker is polling), the Workflow Type, +language-specific contextual data, and Workflow Function parameters. + +In the examples below, all Workflow Executions are started using a Temporal Client. To spawn Workflow Executions from +within another Workflow Execution, use either the [Child Workflow](/develop/python/child-workflows) or External Workflow +APIs. + +See the [Customize Workflow Type](/develop/python/core-application#workflow-type) section to see how to customize the +name of the Workflow Type. + +A request to spawn a Workflow Execution causes the Temporal Service to create the first Event +([WorkflowExecutionStarted](/references/events#workflowexecutionstarted)) in the Workflow Execution Event History. The +Temporal Service then creates the first Workflow Task, resulting in the first +[WorkflowTaskScheduled](/references/events#workflowtaskscheduled) Event. + +To start a Workflow Execution in Python, use either the +[`start_workflow()`](https://python.temporal.io/temporalio.client.Client.html#start_workflow) or +[`execute_workflow()`](https://python.temporal.io/temporalio.client.Client.html#execute_workflow) asynchronous methods +in the Client. + +
+ + View the source code + {' '} + in the context of the rest of the application code. +
+ +```python +# ... +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()) +``` + +### Set a Workflow's Task Queue {#set-task-queue} + +**How to set a Workflow's Task Queue using the Python SDK** + +In most SDKs, the only Workflow Option that must be set is the name of the [Task Queue](/task-queue). + +For any code to execute, a Worker Process must be running that contains a Worker Entity that is polling the same Task +Queue name. + +To set a Task Queue in Python, specify the `task_queue` argument when executing a Workflow with either +[`start_workflow()`](https://python.temporal.io/temporalio.client.Client.html#start_workflow) or +[`execute_workflow()`](https://python.temporal.io/temporalio.client.Client.html#execute_workflow) methods. + +
+ + View the source code + {' '} + in the context of the rest of the application code. +
+ +```python +# ... +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()) +``` + +### Set a Workflow Id {#workflow-id} + +**How to set a Workflow Id using the Python SDK** + +You must set a [Workflow Id](/workflow-execution/workflowid-runid#workflow-id). + +When setting a Workflow Id, we recommended mapping it to a business process or business entity identifier, such as an +order identifier or customer identifier. + +To set a Workflow Id in Python, specify the `id` argument when executing a Workflow with either +[`start_workflow()`](https://python.temporal.io/temporalio.client.Client.html#start_workflow) or +[`execute_workflow()`](https://python.temporal.io/temporalio.client.Client.html#execute_workflow) methods. + +The `id` argument should be a unique identifier for the Workflow Execution. + +
+ + View the source code + {' '} + in the context of the rest of the application code. +
+ +```python +# ... +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()) +``` + +### Get the results of a Workflow Execution {#get-workflow-results} + +**How to get the results of a Workflow Execution using the Python SDK** + +If the call to start a Workflow Execution is successful, you will gain access to the Workflow Execution's Run Id. + +The Workflow Id, Run Id, and Namespace may be used to uniquely identify a Workflow Execution in the system and get its +result. + +It's possible to both block progress on the result (synchronous execution) or get the result at some other point in time +(asynchronous execution). + +In the Temporal Platform, it's also acceptable to use Queries as the preferred method for accessing the state and +results of Workflow Executions. + +Use [`start_workflow()`](https://python.temporal.io/temporalio.client.Client.html#start_workflow) or +[`get_workflow_handle()`](https://python.temporal.io/temporalio.client.Client.html#get_workflow_handle) to return a +Workflow handle. Then use the [`result`](https://python.temporal.io/temporalio.client.WorkflowHandle.html#result) method +to await on the result of the Workflow. + +To get a handle for an existing Workflow by its Id, you can use +[`get_workflow_handle()`](https://python.temporal.io/temporalio.client.Client.html#get_workflow_handle), or use +[`get_workflow_handle_for()`](https://python.temporal.io/temporalio.client.Client.html#get_workflow_handle_for) for type +safety. + +Then use [`describe()`](https://python.temporal.io/temporalio.client.WorkflowHandle.html#describe) to get the current +status of the Workflow. If the Workflow does not exist, this call fails. + +
+ + View the source code + {' '} + in the context of the rest of the application code. +
+ +```python +# ... +async def main(): + client = await Client.connect("localhost:7233") + + handle = client.get_workflow_handle( + workflow_id="your-workflow-id", + ) + results = await handle.result() + print(f"Result: {results}") + + +if __name__ == "__main__": + asyncio.run(main()) +``` diff --git a/docs/develop/python/temporal-clients.mdx b/docs/develop/python/temporal-clients.mdx deleted file mode 100644 index 4fdd5909f1..0000000000 --- a/docs/develop/python/temporal-clients.mdx +++ /dev/null @@ -1,381 +0,0 @@ ---- -id: temporal-client -title: Temporal Client - Python SDK -sidebar_label: Temporal Client -toc_max_heading_level: 4 -description: Discover how to connect and use Temporal Clients with Python. Link your Client to Temporal Service, Temporal Cloud, start Workflow Executions, set Task Queues, Workflow Ids, and get Workflow results. -keywords: - - temporal python client - - connect python client to temporal service - - initialize temporal client - - temporal SDK python guide - - start workflow execution python - - temporal cloud connection - - python client for temporal cli - - custom namespace configuration - - temporal workflow management - - temporal client setup - - python workflow execution - - temporal cloud integration - - temporal client options - - managing temporal namespaces -tags: - - Temporal Client - - Python SDK - - Temporal SDKs - - Certificates ---- - -This guide introduces Temporal Clients. -It explains the role and use of Clients and shows you how to configure your Python Client code to connect to the Temporal Service. - -The pages shows how to do the following: - -- [Connect to a local development Temporal Service](#connect-to-development-service) -- [Connect to Temporal Cloud](#connect-to-temporal-cloud) -- [Start a Workflow Execution](#start-workflow-execution) - -## Connect to development Temporal Service {#connect-to-development-service} - -**How to connect to the local Temporal CLI development Temporal Service using the Python SDK** - -A [Temporal Client](/encyclopedia/temporal-sdks#temporal-client) enables you to communicate with the [Temporal Service](/temporal-service). -Communication with a Temporal Service includes, but isn't limited to, the following: - -- Starting Workflow Executions. -- Sending Signals to Workflow Executions. -- Sending Queries to Workflow Executions. -- Getting the results of a Workflow Execution. -- Providing an Activity Task Token. - -:::caution - -A Temporal Client cannot be initialized and used inside a Workflow. -However, it is acceptable and common to use a Temporal Client inside an Activity to communicate with a Temporal Service. - -::: - -When you are running a Temporal Service locally (such as the [Temporal CLI](https://docs.temporal.io/cli/server#start-dev)), the number of connection options you must provide is minimal. -Many SDKs default to the local host or IP address and port that Temporalite and [Docker Compose](https://github.com/temporalio/docker-compose) serve (`127.0.0.1:7233`). - -Use the `connect()` method on the Client class to create and connect to a Temporal Client to the Temporal Service. - -
- - View the source code - {' '} - in the context of the rest of the application code. -
- -```python -# ... -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()) -``` - -## Connect a Temporal Client to a Temporal Service {#connect-to-a-dev-cluster} - -**How to connect to a Temporal Service** - -A [Temporal Client](/encyclopedia/temporal-sdks#temporal-client) enables you to communicate with the [Temporal Service](/temporal-service). -Communication with a Temporal Service includes, but isn't limited to, the following: - -- Starting Workflow Executions. -- Sending Signals to Workflow Executions. -- Sending Queries to Workflow Executions. -- Getting the results of a Workflow Execution. -- Providing an Activity Task Token. - -:::caution - -A Temporal Client cannot be initialized and used inside a Workflow. -However, it is acceptable and common to use a Temporal Client inside an Activity to communicate with a Temporal Service. - -::: - -When you are running a Temporal Service locally (such as the [Temporal CLI](https://docs.temporal.io/cli/server#start-dev)), the number of connection options you must provide is minimal. -Many SDKs default to the local host or IP address and port that Temporalite and [Docker Compose](https://github.com/temporalio/docker-compose) serve (`127.0.0.1:7233`). - -Use the `connect()` method on the Client class to create and connect to a Temporal Client to the Temporal Service. - -
- - View the source code - {' '} - in the context of the rest of the application code. -
- -```python -# ... -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()) -``` - -## Connect to Temporal Cloud {#connect-to-temporal-cloud} - -### How to connect to Temporal Cloud using an API key {#connect-to-temporal-cloud-api-key} - -To use an [API key](/cloud/api-keys) with the Temporal Python SDK, you will need to provide additional connection options: - -- Your _API Key_ value -- Your _Namespace and Account id_ combination, which follows the format `.`. -- The _endpoint_ may vary. The most common endpoint used is the gRPC regional endpoint, which follows the format: `..api.temporal.io:7233`. -- For Namespaces with High Availability features with API key authentication enabled, use the gRPC Namespace endpoint: `..tmprl.cloud:7233`. - This allows automated failover without needing to switch endpoints. - -You can find the Namespace and Account ID, as well as the endpoint, on the Namespaces tab: - -![The Namespace and Account ID combination on the left, and the regional endpoint on the right](/img/cloud/apikeys/namespaces-and-regional-endpoints.png) - -Now, when instantiating a Temporal `client` in your Temporal Python SDK code, provide the API key: - -```python -client = await Client.connect( - , - namespace=., - api_key=, - tls=True, -) -``` - -To update an API key, replace the `api_key` parameter: - -```python -client.api_key = my_key_updated -``` - -### How to connect to Temporal Cloud using mTLS {#connect-to-temporal-cloud-tls} - -When you connect to [Temporal Cloud](/cloud) with mTLS, you need to provide additional connection and client options that include the following: - -- The [Temporal Cloud Namespace Id](/cloud/namespaces#temporal-cloud-namespace-id). - A Namespace Id is made up of a Namespace name appended by your unique five- or six-digit [Temporal Cloud Account Id](/cloud/namespaces#temporal-cloud-account-id). - You can find this Account Id in the URL of your Namespace and on the "Namespaces" page on the Temporal Cloud website. - For example, in `https://cloud.temporal.io/namespaces/yournamespacename.a2fx6/`, your Account Id is `a2fx6`. - The fully qualified Namespace Id for your client with this Namespace is `yournamespacename.a2fx6`. -- The [Namespace's gRPC endpoint](/cloud/namespaces#temporal-cloud-grpc-endpoint). - An endpoint listing is available at the [Temporal Cloud Website](https://cloud.temporal.io/namespaces) on each Namespace detail page. - The endpoint contains the Namespace Id and port. -- mTLS CA certificate. -- mTLS private key. - -For more information about managing and generating client certificates for Temporal Cloud, see [How to manage certificates in Temporal Cloud](/cloud/certificates). - -For more information about configuring TLS to secure inter- and intra-network communication for a Temporal Service, see [Temporal Customization Samples](https://github.com/temporalio/samples-server). - -Use the `connect()` method on the Client class to create and connect to a Temporal Client to the Temporal Service. -Then specify the [TLSConfig](https://python.temporal.io/temporalio.service.TLSConfig.html) arguments to connect to a Temporal Service with TLS enabled. -The `client_cert` must be combined with `client_private_key` to authenticate the Client. - -
- - View the source code - {' '} - in the context of the rest of the application code. -
- -```python -from temporalio.client import Client, TLSConfig -# ... -# ... -async def main(): - with open("client-cert.pem", "rb") as f: - client_cert = f.read() - with open("client-private-key.pem", "rb") as f: - client_private_key = f.read() - client = await Client.connect( - "your-custom-namespace.tmprl.cloud:7233", - namespace=".", - tls=TLSConfig( - client_cert=client_cert, - client_private_key=client_private_key, - # domain=domain, # TLS domain - # server_root_ca_cert=server_root_ca_cert, # ROOT CA to validate the server cert - ), - ) -``` - -## Start a Workflow Execution {#start-workflow-execution} - -**How to start a Workflow Execution using the Python SDK** - -[Workflow Execution](/workflow-execution) semantics rely on several parameters—that is, to start a Workflow Execution you must supply a Task Queue that will be used for the Tasks (one that a Worker is polling), the Workflow Type, language-specific contextual data, and Workflow Function parameters. - -In the examples below, all Workflow Executions are started using a Temporal Client. -To spawn Workflow Executions from within another Workflow Execution, use either the [Child Workflow](/develop/python/child-workflows) or External Workflow APIs. - -See the [Customize Workflow Type](/develop/python/core-application#workflow-type) section to see how to customize the name of the Workflow Type. - -A request to spawn a Workflow Execution causes the Temporal Service to create the first Event ([WorkflowExecutionStarted](/references/events#workflowexecutionstarted)) in the Workflow Execution Event History. -The Temporal Service then creates the first Workflow Task, resulting in the first [WorkflowTaskScheduled](/references/events#workflowtaskscheduled) Event. - -To start a Workflow Execution in Python, use either the [`start_workflow()`](https://python.temporal.io/temporalio.client.Client.html#start_workflow) or [`execute_workflow()`](https://python.temporal.io/temporalio.client.Client.html#execute_workflow) asynchronous methods in the Client. - -
- - View the source code - {' '} - in the context of the rest of the application code. -
- -```python -# ... -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()) -``` - -### Set a Workflow's Task Queue {#set-task-queue} - -**How to set a Workflow's Task Queue using the Python SDK** - -In most SDKs, the only Workflow Option that must be set is the name of the [Task Queue](/task-queue). - -For any code to execute, a Worker Process must be running that contains a Worker Entity that is polling the same Task Queue name. - -To set a Task Queue in Python, specify the `task_queue` argument when executing a Workflow with either [`start_workflow()`](https://python.temporal.io/temporalio.client.Client.html#start_workflow) or [`execute_workflow()`](https://python.temporal.io/temporalio.client.Client.html#execute_workflow) methods. - -
- - View the source code - {' '} - in the context of the rest of the application code. -
- -```python -# ... -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()) -``` - -### Set a Workflow Id {#workflow-id} - -**How to set a Workflow Id using the Python SDK** - -You must set a [Workflow Id](/workflow-execution/workflowid-runid#workflow-id). - -When setting a Workflow Id, we recommended mapping it to a business process or business entity identifier, such as an order identifier or customer identifier. - -To set a Workflow Id in Python, specify the `id` argument when executing a Workflow with either [`start_workflow()`](https://python.temporal.io/temporalio.client.Client.html#start_workflow) or [`execute_workflow()`](https://python.temporal.io/temporalio.client.Client.html#execute_workflow) methods. - -The `id` argument should be a unique identifier for the Workflow Execution. - -
- - View the source code - {' '} - in the context of the rest of the application code. -
- -```python -# ... -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()) -``` - -### Get the results of a Workflow Execution {#get-workflow-results} - -**How to get the results of a Workflow Execution using the Python SDK** - -If the call to start a Workflow Execution is successful, you will gain access to the Workflow Execution's Run Id. - -The Workflow Id, Run Id, and Namespace may be used to uniquely identify a Workflow Execution in the system and get its result. - -It's possible to both block progress on the result (synchronous execution) or get the result at some other point in time (asynchronous execution). - -In the Temporal Platform, it's also acceptable to use Queries as the preferred method for accessing the state and results of Workflow Executions. - -Use [`start_workflow()`](https://python.temporal.io/temporalio.client.Client.html#start_workflow) or [`get_workflow_handle()`](https://python.temporal.io/temporalio.client.Client.html#get_workflow_handle) to return a Workflow handle. -Then use the [`result`](https://python.temporal.io/temporalio.client.WorkflowHandle.html#result) method to await on the result of the Workflow. - -To get a handle for an existing Workflow by its Id, you can use [`get_workflow_handle()`](https://python.temporal.io/temporalio.client.Client.html#get_workflow_handle), or use [`get_workflow_handle_for()`](https://python.temporal.io/temporalio.client.Client.html#get_workflow_handle_for) for type safety. - -Then use [`describe()`](https://python.temporal.io/temporalio.client.WorkflowHandle.html#describe) to get the current status of the Workflow. -If the Workflow does not exist, this call fails. - -
- - View the source code - {' '} - in the context of the rest of the application code. -
- -```python -# ... -async def main(): - client = await Client.connect("localhost:7233") - - handle = client.get_workflow_handle( - workflow_id="your-workflow-id", - ) - results = await handle.result() - print(f"Result: {results}") - - -if __name__ == "__main__": - asyncio.run(main()) -``` diff --git a/docs/develop/ruby/index.mdx b/docs/develop/ruby/index.mdx index 82432eedfa..dbe87e4073 100644 --- a/docs/develop/ruby/index.mdx +++ b/docs/develop/ruby/index.mdx @@ -2,7 +2,9 @@ id: index title: Ruby SDK developer guide sidebar_label: Ruby SDK -description: Use the Temporal Ruby SDK to develop Temporal Applications, connect to the Temporal Service, test Workflows and Activities, handle failures, send messages, and more. +description: + Use the Temporal Ruby SDK to develop Temporal Applications, connect to the Temporal Service, test Workflows and + Activities, handle failures, send messages, and more. toc_max_heading_level: 4 keywords: - ruby @@ -18,7 +20,8 @@ import * as Components from '@site/src/components'; ![Ruby SDK Banner](/img/assets/banner-ruby-temporal.png) -:::info Ruby SDK RESOURCES +:::info Ruby SDK RESOURCES + Build Temporal Applications with the Ruby SDK. **Temporal Ruby Technical Resources:** @@ -29,7 +32,6 @@ Build Temporal Applications with the Ruby SDK. - [Ruby SDK GitHub](https://github.com/temporalio/sdk-ruby) - [Temporal 101 in Ruby Free Course](https://learn.temporal.io/courses/temporal_101/ruby/) - **Get Connected with the Temporal Ruby Community:** - [Temporal Ruby Community Slack](https://temporalio.slack.com/archives/C052K5QFBNW) @@ -39,43 +41,62 @@ Build Temporal Applications with the Ruby SDK. ## [Core Application](/develop/ruby/core-application) -Use the essential components of a Temporal Application (Workflows, Activities, and Workers) to build and run a Temporal application. - -- [Develop a basic Workflow Definition](/develop/ruby/core-application#develop-workflow): Workflows are the fundamental unit of a Temporal Application, and it all starts with the development of a Workflow Definition. -- [Develop a basic Activity Definition](/develop/ruby/core-application#develop-activity): One of the primary things that Workflows do is orchestrate the execution of Activities. -- [Start an Activity from a Workflow](/develop/ruby/core-application#activity-execution): Calls to spawn Activity Executions are written within a Workflow Definition. -- [Run a Worker Process](/develop/ruby/core-application#run-worker-process): The Worker Process is where Workflow Functions and Activity Functions are executed. -- [Set a Dynamic Workflow](/develop/ruby/core-application#set-a-dynamic-workflow): Set a Workflow that can be invoked dynamically at runtime. -- [Set a Dynamic Activity](/develop/ruby/core-application#set-a-dynamic-activity): Set an Activity that can be invoked dynamically at runtime. +Use the essential components of a Temporal Application (Workflows, Activities, and Workers) to build and run a Temporal +application. + +- [Develop a basic Workflow Definition](/develop/ruby/core-application#develop-workflow): Workflows are the fundamental + unit of a Temporal Application, and it all starts with the development of a Workflow Definition. +- [Develop a basic Activity Definition](/develop/ruby/core-application#develop-activity): One of the primary things that + Workflows do is orchestrate the execution of Activities. +- [Start an Activity from a Workflow](/develop/ruby/core-application#activity-execution): Calls to spawn Activity + Executions are written within a Workflow Definition. +- [Run a Worker Process](/develop/ruby/core-application#run-worker-process): The Worker Process is where Workflow + Functions and Activity Functions are executed. +- [Set a Dynamic Workflow](/develop/ruby/core-application#set-a-dynamic-workflow): Set a Workflow that can be invoked + dynamically at runtime. +- [Set a Dynamic Activity](/develop/ruby/core-application#set-a-dynamic-activity): Set an Activity that can be invoked + dynamically at runtime. ## [Temporal Client](/develop/ruby/temporal-client) Connect to a Temporal Service and start a Workflow Execution. -- [Create a Temporal Client](/develop/ruby/temporal-client#create-a-client): Instantiate and configure a client to interact with the Temporal Service. -- [Connect to Temporal Cloud](/develop/ruby/temporal-client#connect-to-temporal-cloud): Securely connect to the Temporal Cloud for a fully managed service. +- [Create a Temporal Client](/develop/ruby/temporal-client#connect-to-development-service): Instantiate and configure a + client to interact with the Temporal Service. +- [Connect to Temporal Cloud](/develop/ruby/temporal-client#connect-to-temporal-cloud): Securely connect to the Temporal + Cloud for a fully managed service. - [Start a Workflow](/develop/ruby/temporal-client#start-workflow): Initiate Workflows seamlessly via the Ruby SDK. -- [Get Workflow results](/develop/ruby/temporal-client#get-workflow-results): Retrieve and process the results of your Workflows efficiently. +- [Get Workflow results](/develop/ruby/temporal-client#get-workflow-results): Retrieve and process the results of your + Workflows efficiently. ## [Testing](/develop/ruby/testing-suite) Set up the testing suite and test Workflows and Activities. -- [Test frameworks](/develop/ruby/testing-suite#test-frameworks): Testing provides a framework to facilitate Workflow and integration testing. -- [Testing Workflows](/develop/ruby/testing-suite#testing-workflows): Ensure the functionality and reliability of your Workflows. -- [Testing Activities](/develop/ruby/testing-suite#test-activities): Validate the execution and outcomes of your Activities. +- [Test frameworks](/develop/ruby/testing-suite#test-frameworks): Testing provides a framework to facilitate Workflow + and integration testing. +- [Testing Workflows](/develop/ruby/testing-suite#testing-workflows): Ensure the functionality and reliability of your + Workflows. +- [Testing Activities](/develop/ruby/testing-suite#test-activities): Validate the execution and outcomes of your + Activities. - [Replay test](/develop/ruby/testing-suite#replay-test): Replay recreates the exact state of a Workflow Execution. ## [Failure detection](/develop/ruby/failure-detection) Explore how your application can detect failures using timeouts and automatically attempt to mitigate them with retries. -- [Workflow timeouts](/develop/ruby/failure-detection#workflow-timeouts): Each Workflow timeout controls the maximum duration of a different aspect of a Workflow Execution. -- [Workflow retries](/develop/ruby/failure-detection#workflow-retries): A Workflow Retry Policy can be used to retry a Workflow Execution in the event of a failure. -- [Activity timeouts](/develop/ruby/failure-detection#activity-timeouts): Each Activity timeout controls the maximum duration of a different aspect of an Activity Execution. -- [Set an Activity Retry Policy](/develop/ruby/failure-detection#activity-retries): Define retry logic for Activities to handle failures. -- [Heartbeat an Activity](/develop/ruby/failure-detection#activity-heartbeats): An Activity Heartbeat is a ping from the Worker that is executing the Activity to the Temporal Service. -- [Heartbeat Timeout](/develop/ruby/failure-detection#heartbeat-timeout): A Heartbeat Timeout works in conjunction with Activity Heartbeats. +- [Workflow timeouts](/develop/ruby/failure-detection#workflow-timeouts): Each Workflow timeout controls the maximum + duration of a different aspect of a Workflow Execution. +- [Workflow retries](/develop/ruby/failure-detection#workflow-retries): A Workflow Retry Policy can be used to retry a + Workflow Execution in the event of a failure. +- [Activity timeouts](/develop/ruby/failure-detection#activity-timeouts): Each Activity timeout controls the maximum + duration of a different aspect of an Activity Execution. +- [Set an Activity Retry Policy](/develop/ruby/failure-detection#activity-retries): Define retry logic for Activities to + handle failures. +- [Heartbeat an Activity](/develop/ruby/failure-detection#activity-heartbeats): An Activity Heartbeat is a ping from the + Worker that is executing the Activity to the Temporal Service. +- [Heartbeat Timeout](/develop/ruby/failure-detection#heartbeat-timeout): A Heartbeat Timeout works in conjunction with + Activity Heartbeats. ## [Workflow message passing](/develop/ruby/message-passing) @@ -84,79 +105,110 @@ Send messages to and read the state of Workflow Executions. ### Signals - [Define Signal](/develop/ruby/message-passing#signals): A Signal is a message sent to a running Workflow Execution. -- [Send a Signal from a Temporal Client](/develop/ruby/message-passing#send-signal-from-client): Send a Signal to a Workflow from a Temporal Client. -- [Send a Signal from a Workflow](/develop/ruby/message-passing#send-signal-from-workflow): Send a Signal to another Workflow from within a Workflow, this would also be called an External Signal. -- [Signal-With-Start](/develop/ruby/message-passing#signal-with-start): Start a Workflow and send it a Signal in a single operation used from the Client. -- [Dynamic Handler](/develop/ruby/message-passing#dynamic-handler): Dynamic Handlers provide flexibility to handle cases where the names of Workflows, Activities, Signals, or Queries aren't known at run time. -- [Set a Dynamic Signal](/develop/ruby/message-passing#set-a-dynamic-signal): A Dynamic Signal in Temporal is a Signal that is invoked dynamically at runtime if no other Signal with the same input is registered. +- [Send a Signal from a Temporal Client](/develop/ruby/message-passing#send-signal-from-client): Send a Signal to a + Workflow from a Temporal Client. +- [Send a Signal from a Workflow](/develop/ruby/message-passing#send-signal-from-workflow): Send a Signal to another + Workflow from within a Workflow, this would also be called an External Signal. +- [Signal-With-Start](/develop/ruby/message-passing#signal-with-start): Start a Workflow and send it a Signal in a + single operation used from the Client. +- [Dynamic Handler](/develop/ruby/message-passing#dynamic-handler): Dynamic Handlers provide flexibility to handle cases + where the names of Workflows, Activities, Signals, or Queries aren't known at run time. +- [Set a Dynamic Signal](/develop/ruby/message-passing#set-a-dynamic-signal): A Dynamic Signal in Temporal is a Signal + that is invoked dynamically at runtime if no other Signal with the same input is registered. ### Queries -- [Define a Query](/develop/ruby/message-passing#queries): A Query is a synchronous operation that is used to get the state of a Workflow Execution. +- [Define a Query](/develop/ruby/message-passing#queries): A Query is a synchronous operation that is used to get the + state of a Workflow Execution. - [Send Queries](/develop/ruby/message-passing#send-query): Queries are sent from the Temporal Client. -- [Set a Dynamic Query](/develop/ruby/message-passing#set-a-dynamic-signal): A Dynamic Query in Temporal is a Query that is invoked dynamically at runtime if no other Query with the same name is registered. +- [Set a Dynamic Query](/develop/ruby/message-passing#set-a-dynamic-signal): A Dynamic Query in Temporal is a Query that + is invoked dynamically at runtime if no other Query with the same name is registered. ### Updates -- [Define an Update](/develop/ruby/message-passing#updates): An Update is an operation that can mutate the state of a Workflow Execution and return a response. +- [Define an Update](/develop/ruby/message-passing#updates): An Update is an operation that can mutate the state of a + Workflow Execution and return a response. - [Send an Update](/develop/ruby/message-passing#send-update-from-client): An Update is sent from the Temporal Client. ## [Interrupt a Workflow](/develop/ruby/interrupt-workflow) Interrupt a Workflow Execution with a Cancel or Terminate action. -- [Cancel a Workflow](/develop/ruby/interrupt-workflow#cancellation): Interrupt a Workflow Execution and its Activities through Workflow cancellation. -- [Terminate a Workflow](/develop/ruby/interrupt-workflow#termination): Interrupt a Workflow Execution and its Activities through Workflow termination. +- [Cancel a Workflow](/develop/ruby/interrupt-workflow#cancellation): Interrupt a Workflow Execution and its Activities + through Workflow cancellation. +- [Terminate a Workflow](/develop/ruby/interrupt-workflow#termination): Interrupt a Workflow Execution and its + Activities through Workflow termination. ## [Asynchronous Activity completion](/develop/ruby/asynchronous-activity) Complete Activities asynchronously. -- [Asynchronous Activity](/develop/ruby/asynchronous-activity): Asynchronous Activity completion enables the Activity Function to return without the Activity Execution completing. +- [Asynchronous Activity](/develop/ruby/asynchronous-activity): Asynchronous Activity completion enables the Activity + Function to return without the Activity Execution completing. ## [Versioning](/develop/ruby/versioning) Change Workflow Definitions without causing non-deterministic behavior in running Workflows. -- [Use the Ruby SDK Patching API](/develop/ruby/versioning#ruby-sdk-patching-api): Patching Workflows using the Ruby SDK. +- [Use the Ruby SDK Patching API](/develop/ruby/versioning#ruby-sdk-patching-api): Patching Workflows using the Ruby + SDK. ## [Observability](/develop/ruby/observability) Configure and use the Temporal Observability APIs. -- [Emit Metrics](/develop/ruby/observability#metrics): Each Temporal SDK is capable of emitting an optional set of metrics from either the Client or the Worker process. -- [Set up Tracing](/develop/ruby/observability#tracing): Explains how the Go SDK supports tracing and custom context propagation. -- [Log from a Workflow](/develop/ruby/observability#logging): Send logs and errors to a logging service, so that when things go wrong, you can see what happened. -- [Use Visibility APIs](/develop/ruby/observability#visibility): The term Visibility, within the Temporal Platform, refers to the subsystems and APIs that enable an operator to view Workflow Executions that currently exist within a Terminal Service. +- [Emit Metrics](/develop/ruby/observability#metrics): Each Temporal SDK is capable of emitting an optional set of + metrics from either the Client or the Worker process. +- [Set up Tracing](/develop/ruby/observability#tracing): Explains how the Go SDK supports tracing and custom context + propagation. +- [Log from a Workflow](/develop/ruby/observability#logging): Send logs and errors to a logging service, so that when + things go wrong, you can see what happened. +- [Use Visibility APIs](/develop/ruby/observability#visibility): The term Visibility, within the Temporal Platform, + refers to the subsystems and APIs that enable an operator to view Workflow Executions that currently exist within a + Terminal Service. ## [Debugging](/develop/ruby/debugging) Explore various ways to debug your application. -- [Debug in a development environment](/develop/ruby/debugging#debug-in-a-development-environment): In addition to the normal development tools of logging and a debugger, you can also see what’s happening in your Workflow by using the Web UI and the Temporal CLI. -- [Debug in a development production](/develop/ruby/debugging#debug-in-a-production-environment): Debug production Workflows using the Web UI, the Temporal CLI, Replays, Tracing, or Logging. +- [Debug in a development environment](/develop/ruby/debugging#debug-in-a-development-environment): In addition to the + normal development tools of logging and a debugger, you can also see what’s happening in your Workflow by using the + Web UI and the Temporal CLI. +- [Debug in a development production](/develop/ruby/debugging#debug-in-a-production-environment): Debug production + Workflows using the Web UI, the Temporal CLI, Replays, Tracing, or Logging. ## [Schedules](/develop/ruby/schedules) Run Workflows on a schedule and delay the start of a Workflow. - [Schedule a Workflow](/develop/ruby/schedules#schedule-a-workflow) - - [Create a Scheduled Workflow](/develop/ruby/schedules#create-a-workflow): Create a new schedule for a scheduled Workflow. - - [Backfill a Scheduled Workflow](/develop/ruby/schedules#backfill-a-scheduled-workflow): Backfills a past time range of actions for a scheduled Workflow. - - [Delete a Scheduled Workflow](/develop/ruby/schedules#delete-a-scheduled-workflow): Deletes a schedule for a scheduled Workflow. - - [Describe a Scheduled Workflow](/develop/ruby/schedules#describe-a-scheduled-workflow): Get schedule configuration and current state for a scheduled Workflow. - - [List a Scheduled Workflow](/develop/ruby/schedules#list-a-scheduled-workflow): List a schedule for a scheduled Workflow. - - [Pause a Scheduled Workflow](/develop/ruby/schedules#pause-a-scheduled-workflow): Pause a schedule for a scheduled Workflow. - - [Trigger a Scheduled Workflow](/develop/ruby/schedules#trigger-a-scheduled-workflow): Triggers an immediate action for a scheduled Workflow. - - [Update a Scheduled Workflow](/develop/ruby/schedules#update-a-scheduled-workflow): Updates a schedule with a new definition for a scheduled Workflow. -- [Use Start Delay](/develop/ruby/schedules#start-delay): Start delay functionality if you need to delay the execution of the Workflow without the need for regular launches. + - [Create a Scheduled Workflow](/develop/ruby/schedules#create-a-workflow): Create a new schedule for a scheduled + Workflow. + - [Backfill a Scheduled Workflow](/develop/ruby/schedules#backfill-a-scheduled-workflow): Backfills a past time range + of actions for a scheduled Workflow. + - [Delete a Scheduled Workflow](/develop/ruby/schedules#delete-a-scheduled-workflow): Deletes a schedule for a + scheduled Workflow. + - [Describe a Scheduled Workflow](/develop/ruby/schedules#describe-a-scheduled-workflow): Get schedule configuration + and current state for a scheduled Workflow. + - [List a Scheduled Workflow](/develop/ruby/schedules#list-a-scheduled-workflow): List a schedule for a scheduled + Workflow. + - [Pause a Scheduled Workflow](/develop/ruby/schedules#pause-a-scheduled-workflow): Pause a schedule for a scheduled + Workflow. + - [Trigger a Scheduled Workflow](/develop/ruby/schedules#trigger-a-scheduled-workflow): Triggers an immediate action + for a scheduled Workflow. + - [Update a Scheduled Workflow](/develop/ruby/schedules#update-a-scheduled-workflow): Updates a schedule with a new + definition for a scheduled Workflow. +- [Use Start Delay](/develop/ruby/schedules#start-delay): Start delay functionality if you need to delay the execution + of the Workflow without the need for regular launches. ## [Data encryption](/develop/ruby/converters-and-encryption) Use compression, encryption, and other data handling by implementing custom converters and codecs. -- [Use a custom Payload Codec](/develop/ruby/converters-and-encryption#custom-payload-codec): Create a custom PayloadCodec implementation and define your encryption/compression and decryption/decompression logic. -- [Use a custom Payload Converter](/develop/ruby/converters-and-encryption#custom-payload-converter): A custom data converter can be set via the `DataConverter` option when creating a client. +- [Use a custom Payload Codec](/develop/ruby/converters-and-encryption#custom-payload-codec): Create a custom + PayloadCodec implementation and define your encryption/compression and decryption/decompression logic. +- [Use a custom Payload Converter](/develop/ruby/converters-and-encryption#custom-payload-converter): A custom data + converter can be set via the `DataConverter` option when creating a client. ## [Durable Timers](/develop/ruby/durable-timers) @@ -168,14 +220,18 @@ Use Timers to make a Workflow Execution pause or "sleep" for seconds, minutes, d Explore how to spawn a Child Workflow Execution and handle Child Workflow Events. -- [Start a Child Workflow Execution](/develop/ruby/child-workflows): A Child Workflow Execution is a Workflow Execution that is scheduled from within another Workflow using a Child Workflow API. -- [Set a Parent Close Policy](/develop/ruby/child-workflows#parent-close-policy): A Parent Close Policy determines what happens to a Child Workflow Execution if its Parent changes to a Closed status. +- [Start a Child Workflow Execution](/develop/ruby/child-workflows): A Child Workflow Execution is a Workflow Execution + that is scheduled from within another Workflow using a Child Workflow API. +- [Set a Parent Close Policy](/develop/ruby/child-workflows#parent-close-policy): A Parent Close Policy determines what + happens to a Child Workflow Execution if its Parent changes to a Closed status. ## [Continue-As-New](/develop/ruby/continue-as-new) Continue the Workflow Execution with a new Workflow Execution using the same Workflow ID. -- [Continue-As-New](/develop/ruby/continue-as-new): Continue-As-New enables a Workflow Execution to close successfully and create a new Workflow Execution in a single atomic operation if the number of Events in the Event History is becoming too large. +- [Continue-As-New](/develop/ruby/continue-as-new): Continue-As-New enables a Workflow Execution to close successfully + and create a new Workflow Execution in a single atomic operation if the number of Events in the Event History is + becoming too large. ## [Enriching the User Interface](/develop/ruby/enriching-ui) diff --git a/docs/develop/ruby/temporal-client.mdx b/docs/develop/ruby/temporal-client.mdx index 4721e9c198..47f30ce76b 100644 --- a/docs/develop/ruby/temporal-client.mdx +++ b/docs/develop/ruby/temporal-client.mdx @@ -2,7 +2,9 @@ id: temporal-client title: Temporal Client - Ruby SDK sidebar_label: Temporal Client -description: Create a Temporal Client, connect to Temporal Cloud, start a Workflow, and get Workflow results using the Temporal Ruby SDK. +description: + Create a Temporal Client, connect to Temporal Cloud, start a Workflow, and get Workflow results using the Temporal + Ruby SDK. keywords: - sdk - ruby @@ -14,96 +16,390 @@ tags: - Certificates --- -This page shows how to do the following: +A [Temporal Client](https://chatgpt.com/encyclopedia/temporal-sdks#temporal-client) enables you to communicate with the +Temporal Service. Communication with a Temporal Service lets you perform actions such as starting Workflow Executions, +sending Signals and Queries to Workflow Executions, getting Workflow results, and more. -- [Create a Temporal Client](#create-a-client) +This page shows you how to do the following using the Ruby SDK with the Temporal Client: + +- [Connect to a local development Temporal Service](#connect-to-development-service) - [Connect to Temporal Cloud](#connect-to-temporal-cloud) -- [Start a Workflow](#start-workflow) +- [Start a Workflow Execution](#start-workflow) - [Get Workflow results](#get-workflow-results) -## Create a Temporal Client {#create-a-client} +A Temporal Client cannot be initialized and used inside a Workflow. However, it is acceptable and common to use a +Temporal Client inside an Activity to communicate with a Temporal Service. + +## Connect to development Temporal Service {#connect-to-development-service} + +Use [`Client.connect`](https://ruby.temporal.io/Temporalio/Client.html#connect-class_method) to create a client. +Connection options include the Temporal Server address, Namespace, and (optionally) TLS configuration. You can provide +these options directly in code, load them from **environment variables**, or a **TOML configuration file** using the +[`EnvConfig`](https://ruby.temporal.io/Temporalio/EnvConfig.html) helpers. We recommend environment variables or a +configuration file for secure, repeatable configuration. + +When you’re running a Temporal Service locally (such as with the +[Temporal CLI dev server](https://docs.temporal.io/cli/server#start-dev)), the required options are minimal. If you +don't specify a host/port, most connections default to `127.0.0.1:7233` and the `default` Namespace. + + -A [Temporal Client](/encyclopedia/temporal-sdks#temporal-client) enables you to communicate with the [Temporal Service](/temporal-service). -Communication with a Temporal Service includes, but isn't limited to, the following: + -- Starting Workflow Executions. -- Sending Signals to Workflow Executions. -- Sending Queries to Workflow Executions. -- Getting the results of a Workflow Execution. -- Providing an Activity Task Token. - All applications that need to communicate directly with the Temporal Service will run inside of Temporal Clients. +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](../environment-configuration.mdx#configuration-methods) for more details about configuration +files and profiles. -Your Workers are technically Temporal Clients, because they need to poll the Temporal Service to actually do work. -Your Workflow and Activity definitions are _not_ Temporal Clients -- your Worker imports these directly instead. -Each Temporal SDK includes a set of Temporal Client functions. -The `temporal` CLI is also a Temporal Client, and is generally at feature parity with the SDKs. -:::caution +:::info -A Temporal Client cannot be initialized and used inside a Workflow. -However, it is acceptable and common to use a Temporal Client inside an Activity to communicate with a Temporal Service. +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. ::: -When running a Temporal Service locally (such as via [Temporal CLI](https://docs.temporal.io/cli/server#start-dev)), the number of connection options required is minimal. +For example, the following TOML configuration file defines two profiles: `default` and `prod`. Each profile has its own +set of connection options. + +```toml title="config.toml" +# 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" +``` -Use the `connect` class method on the `Temporalio::Client` class to create and connect to a Temporal Client to the Temporal Service. +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: + +```ruby +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](/references/client-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. + +```bash +export TEMPORAL_NAMESPACE="default" +export TEMPORAL_ADDRESS="localhost:7233" +``` + +After setting the environment variables, you can create a Temporal Client as follows: + +```ruby {9} +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. ```ruby client = Temporalio::Client.connect('localhost:7233', 'default') ``` -## Connect to Temporal Cloud {#connect-to-temporal-cloud} + -### How to connect to Temporal Cloud using an API Key {#connect-to-temporal-cloud-api-key} + -To use an [API key](/cloud/api-keys) with the Temporal Ruby SDK, you will need to provide additional connection options: +## Connect to Temporal Cloud {#connect-to-temporal-cloud} + +You can connect to Temporal Cloud using either an [API key](/cloud/api-keys) or through mTLS. Connection to Temporal +Cloud or any secured Temporal Service requires additional connection options compared to connecting to an unsecured +local development instance: -- Your _API Key_ value -- Your _Namespace and Account id_ combination, which follows the format `.`. -- The _endpoint_ may vary. The most common endpoint used is the gRPC regional endpoint, which follows the format: `..api.temporal.io:7233`. -- For Namespaces with High Availability features with API key authentication enabled, use the gRPC Namespace endpoint: `..tmprl.cloud:7233`. - This allows automated failover without needing to switch endpoints. +- Your credentials for authentication. + - If you are using an API key, provide the API key value. + - If you are using mTLS, provide the mTLS CA certificate and mTLS private key. +- Your _Namespace and Account ID_ combination, which follows the format `.`. +- The _endpoint_ may vary. The most common endpoint used is the gRPC regional endpoint, which follows the format: + `..api.temporal.io:7233`. +- For Namespaces with High Availability features with API key authentication enabled, use the gRPC Namespace endpoint: + `..tmprl.cloud:7233`. This allows automated failover without needing to switch endpoints. You can find the Namespace and Account ID, as well as the endpoint, on the Namespaces tab: ![The Namespace and Account ID combination on the left, and the regional endpoint on the right](/img/cloud/apikeys/namespaces-and-regional-endpoints.png) -Now, when instantiating a Temporal client in your Ruby SDK code, provide the `api_key` value. +You can provide these connection options using environment variables, a configuration file, or directly in code. -To create an initial connection: + -```ruby -client = Temporalio::Client.connect( - '', # Endpoint - '.', # Namespace - api_key: '', - tls: true -) + + +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. For a list of all available configuration options you can set in the TOML file, refer to +[Environment Configuration](/references/client-environment-configuration). + +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 path to the configuration file, the SDK looks for it at the +default path `~/.config/temporalio/temporal.toml`. + +:::info + +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 a `staing` profile with the necessary connection options to +connect to Temporal Cloud via an API key: + +For example, the following TOML configuration file defines a `staging` profile with the necessary connection options to +connect to Temporal Cloud via an API key: + +```toml +# Cloud profile for Temporal Cloud +[profile.staging] +address = "your-namespace.a1b2c.tmprl.cloud:7233" +namespace = "your-namespace" +api_key = "your-api-key-here" ``` -To update an API key, update the value of `api_key`: +If you want to use mTLS authentication instead of an API key, replace the `api_key` field with your mTLS certificate and +private key: -```ruby -client.connection.api_key = '' +```toml +# Cloud profile for Temporal Cloud +[profile.staging] +address = "your-namespace.a1b2c.tmprl.cloud:7233" +namespace = "your-namespace" +tls_client_cert_data = "your-tls-client-cert-data" +tls_client_key_path = "your-tls-client-key-path" ``` -### How to connect to Temporal Cloud using mTLS {#connect-to-temporal-cloud-mtls} +With the connections options defined in the configuration file, use the +[`Client.connect` method](https://ruby.temporal.io/Temporalio/Client.html#connect-class_method) to create a Temporal +Client using the `staging` profile as follows. After loading the profile, you can also programmatically override +specific connection options before creating the client. + +```ruby {8,14-16} +require 'temporalio/client' +require 'temporalio/env_config' + +def main + puts "--- Loading 'staging' profile with programmatic overrides ---" -When you connect to [Temporal Cloud](/cloud), you need to provide additional connection and client options that include the following: + config_file = File.join(__dir__, 'config.toml') + profile_name = 'staging' -- The [Temporal Cloud Namespace Id](/cloud/namespaces#temporal-cloud-namespace-id). -- The [Namespace's gRPC endpoint](/cloud/namespaces#temporal-cloud-grpc-endpoint). - An endpoint listing is available at the [Temporal Cloud Website](https://cloud.temporal.io/namespaces) on each Namespace detail page. - The endpoint contains the Namespace Id and port. -- mTLS CA certificate. -- mTLS private key. + puts "The 'staging' profile in config.toml has an incorrect address (localhost:9999)." + puts "We'll programmatically override it to the correct address." -For more information about managing and generating client certificates for Temporal Cloud, see [How to manage certificates in Temporal Cloud](/cloud/certificates). + # Load the 'staging' profile. + args, kwargs = Temporalio::EnvConfig::ClientConfig.load_client_connect_options( + profile: profile_name, + config_source: Pathname.new(config_file) + ) + + # Override the target host to the correct address. + # This is the recommended way to override configuration values. + args[0] = 'localhost:7233' + + puts "\nLoaded '#{profile_name}' profile from #{config_file} with overrides." + puts " Address: #{args[0]} (overridden from localhost:9999)" + puts " Namespace: #{args[1]}" + + 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__ +``` -For more information about configuring TLS to secure inter- and intra-network communication for a Temporal Service, see [Temporal Customization Samples](https://github.com/temporalio/samples-server). + + + + +The following environment variables are required to connect to Temporal Cloud: + +- `TEMPORAL_NAMESPACE`: Your Namespace and Account ID combination in the format `.`. +- `TEMPORAL_ADDRESS`: The gRPC endpoint for your Temporal Cloud Namespace. +- `TEMPORAL_API_KEY`: Your API key value. Required if you are using API key authentication. +- `TEMPORAL_TLS_CLIENT_CERT_DATA` or `TEMPORAL_TLS_CLIENT_CERT_PATH`: Your mTLS client certificate data or file path. + Required if you are using mTLS authentication. +- `TEMPORAL_TLS_CLIENT_KEY_DATA` or `TEMPORAL_TLS_CLIENT_KEY_PATH`: Your mTLS client private key data or file path. + Required if you are using mTLS authentication. + +Ensure these environment variables exist in your environment before running your application. + +Import the `EnvConfig` package to set connection options for the Temporal Client using environment variables. The +`MustLoadDefaultClientOptions` function will automatically load all environment variables. For a list of all available +environment variables and their default values, refer to +[Environment Configuration](/references/client-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. + +After setting the environment variables, use the following code to create the Temporal Client: + +```ruby {9, 17} +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. It 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__ +``` -Use the `connect` static method on the `Temporalio::Client` class to create and connect to a Temporal Client to the Temporal Service. -Specify the `tls` parameter of the connection options to connect to a Temporal Service with mTLS enabled. + + + + +You can also specify connection options directly in code to connect to Temporal Cloud. To create an initial connection, +provide the endpoint, Namespace and Account ID combination, and API key values to the `Client.connect` method. + +```ruby +client = Temporalio::Client.connect( + '', # Endpoint + '.', # Namespace + api_key: '', + tls: true +) +``` + +To connect using mTLS instead of an API key, provide the mTLS certificate and private key as follows: ```ruby client = Temporalio::Client.connect( @@ -116,6 +412,16 @@ client = Temporalio::Client.connect( ) ``` +For more information about managing and generating client certificates for Temporal Cloud, see +[How to manage certificates in Temporal Cloud](/cloud/certificates). + +For more information about configuring TLS to secure inter- and intra-network communication for a Temporal Service, see +[Temporal Customization Samples](https://github.com/temporalio/samples-server). + + + + + ## Start a Workflow {#start-workflow} To start a Workflow Execution, supply: @@ -125,8 +431,9 @@ To start a Workflow Execution, supply: - Input arguments - Workflow options such as Workflow Id -To start a Workflow Execution in Ruby, use either the `start_workflow` or `execute_workflow` methods in the Client. -You must set a [Workflow Id](/workflow-execution/workflowid-runid#workflow-id) and [Task Queue](/task-queue) in the parameters given to the method. +To start a Workflow Execution in Ruby, use either the `start_workflow` or `execute_workflow` methods in the Client. You +must set a [Workflow Id](/workflow-execution/workflowid-runid#workflow-id) and [Task Queue](/task-queue) in the +parameters given to the method. ```ruby result = my_client.execute_workflow( @@ -144,8 +451,8 @@ You can block until the result is available, or retrieve it later using the hand You can also use Queries to access Workflow state and results while the Workflow is running. -Use `start_workflow` or `workflow_handle` on the Client to return a Workflow handle. -Then use the `result` method to await on the result of the Workflow. +Use `start_workflow` or `workflow_handle` on the Client to return a Workflow handle. Then use the `result` method to +await on the result of the Workflow. ```ruby handle = my_client.workflow_handle('my-workflow-id') diff --git a/docs/develop/typescript/cancellation.mdx b/docs/develop/typescript/cancellation.mdx index 3fc3b01caa..55c6b52599 100644 --- a/docs/develop/typescript/cancellation.mdx +++ b/docs/develop/typescript/cancellation.mdx @@ -9,37 +9,46 @@ tags: - Workflows - TypeScript SDK - Temporal SDKs -description: Explore the power of Cancellation Scopes in TypeScript to manage nested, non-cancellable, and timeout-based operations within Temporal Workflows with ease. +description: + Explore the power of Cancellation Scopes in TypeScript to manage nested, non-cancellable, and timeout-based operations + within Temporal Workflows with ease. --- ## Cancellation scopes in Typescript {#cancellation-scopes} -In the TypeScript SDK, Workflows are represented internally by a tree of cancellation scopes, each with cancellation behaviors you can specify. -By default, everything runs in the "root" scope. +In the TypeScript SDK, Workflows are represented internally by a tree of cancellation scopes, each with cancellation +behaviors you can specify. By default, everything runs in the "root" scope. -Scopes are created using the [CancellationScope](https://typescript.temporal.io/api/classes/workflow.CancellationScope) constructor or one of three static helpers: +Scopes are created using the [CancellationScope](https://typescript.temporal.io/api/classes/workflow.CancellationScope) +constructor or one of three static helpers: -- [cancellable(fn)](https://typescript.temporal.io/api/classes/workflow.CancellationScope#cancellable-1): Children are automatically cancelled when their containing scope is cancelled. +- [cancellable(fn)](https://typescript.temporal.io/api/classes/workflow.CancellationScope#cancellable-1): Children are + automatically cancelled when their containing scope is cancelled. - Equivalent to `new CancellationScope().run(fn)`. -- [nonCancellable(fn)](https://typescript.temporal.io/api/classes/workflow.CancellationScope#noncancellable): Cancellation does not propagate to children. +- [nonCancellable(fn)](https://typescript.temporal.io/api/classes/workflow.CancellationScope#noncancellable): + Cancellation does not propagate to children. - Equivalent to `new CancellationScope({ cancellable: false }).run(fn)`. -- [withTimeout(timeoutMs, fn)](https://typescript.temporal.io/api/classes/workflow.CancellationScope#withtimeout): If a timeout triggers before `fn` resolves, the scope is cancelled, triggering cancellation of any enclosed operations, such as Activities and Timers. +- [withTimeout(timeoutMs, fn)](https://typescript.temporal.io/api/classes/workflow.CancellationScope#withtimeout): If a + timeout triggers before `fn` resolves, the scope is cancelled, triggering cancellation of any enclosed operations, + such as Activities and Timers. - Equivalent to `new CancellationScope({ cancellable: true, timeout: timeoutMs }).run(fn)`. -Cancellations are applied to cancellation scopes, which can encompass an entire Workflow or just part of one. -Scopes can be nested, and cancellation propagates from outer scopes to inner ones. -A Workflow's `main` function runs in the outermost scope. -Cancellations are handled by catching `CancelledFailure`s thrown by cancelable operations. +Cancellations are applied to cancellation scopes, which can encompass an entire Workflow or just part of one. Scopes can +be nested, and cancellation propagates from outer scopes to inner ones. A Workflow's `main` function runs in the +outermost scope. Cancellations are handled by catching `CancelledFailure`s thrown by cancelable operations. -`CancellationScope.run()` and the static helpers mentioned earlier return native JavaScript promises, so you can use the familiar Promise APIs like `Promise.all` and `Promise.race` to model your asynchronous logic. -You can also use the following APIs: +`CancellationScope.run()` and the static helpers mentioned earlier return native JavaScript promises, so you can use the +familiar Promise APIs like `Promise.all` and `Promise.race` to model your asynchronous logic. You can also use the +following APIs: - `CancellationScope.current()`: Get the current scope. - `scope.cancel()`: Cancel all operations inside a `scope`. - `scope.run(fn)`: Run an async function within a `scope` and return the result of `fn`. -- `scope.cancelRequested`: A promise that resolves when a scope cancellation is requested, such as when Workflow code calls `cancel()` or the entire Workflow is cancelled by an external client. +- `scope.cancelRequested`: A promise that resolves when a scope cancellation is requested, such as when Workflow code + calls `cancel()` or the entire Workflow is cancelled by an external client. -When a `CancellationScope` is cancelled, it propagates cancellation in any child scopes and of any cancelable operations created within it, such as the following: +When a `CancellationScope` is cancelled, it propagates cancellation in any child scopes and of any cancelable operations +created within it, such as the following: - Activities - Timers (created with the [sleep](https://typescript.temporal.io/api/namespaces/workflow#sleep) function) @@ -47,18 +56,20 @@ When a `CancellationScope` is cancelled, it propagates cancellation in any child ### CancelledFailure -Timers and triggers throw [CancelledFailure](https://typescript.temporal.io/api/classes/common.CancelledFailure) when cancelled; Activities and Child Workflows throw `ActivityFailure` and `ChildWorkflowFailure` with cause set to `CancelledFailure`. -One exception is when an Activity or Child Workflow is scheduled in an already cancelled scope (or Workflow). -In this case, they propagate the `CancelledFailure` that was thrown to cancel the scope. +Timers and triggers throw [CancelledFailure](https://typescript.temporal.io/api/classes/common.CancelledFailure) when +cancelled; Activities and Child Workflows throw `ActivityFailure` and `ChildWorkflowFailure` with cause set to +`CancelledFailure`. One exception is when an Activity or Child Workflow is scheduled in an already cancelled scope (or +Workflow). In this case, they propagate the `CancelledFailure` that was thrown to cancel the scope. -To simplify checking for cancellation, use the [isCancellation(err)](https://typescript.temporal.io/api/namespaces/workflow#iscancellation) function. +To simplify checking for cancellation, use the +[isCancellation(err)](https://typescript.temporal.io/api/namespaces/workflow#iscancellation) function. ### Internal cancellation example [packages/test/src/workflows/cancel-timer-immediately.ts](https://github.com/temporalio/sdk-typescript/blob/main/packages/test/src/workflows/cancel-timer-immediately.ts) ```ts -import { CancelledFailure, CancellationScope, sleep } from '@temporalio/workflow'; +import { CancellationScope, CancelledFailure, sleep } from '@temporalio/workflow'; export async function cancelTimer(): Promise { // Timers and Activities are automatically cancelled when their containing scope is cancelled. @@ -84,7 +95,7 @@ Alternatively, the preceding can be written as the following. [packages/test/src/workflows/cancel-timer-immediately-alternative-impl.ts](https://github.com/temporalio/sdk-typescript/blob/main/packages/test/src/workflows/cancel-timer-immediately-alternative-impl.ts) ```ts -import { CancelledFailure, CancellationScope, sleep } from '@temporalio/workflow'; +import { CancellationScope, CancelledFailure, sleep } from '@temporalio/workflow'; export async function cancelTimerAltImpl(): Promise { try { @@ -112,7 +123,7 @@ The following code shows how to handle Workflow cancellation by an external clie [packages/test/src/workflows/handle-external-workflow-cancellation-while-activity-running.ts](https://github.com/temporalio/sdk-typescript/blob/main/packages/test/src/workflows/handle-external-workflow-cancellation-while-activity-running.ts) ```ts -import { CancellationScope, proxyActivities, isCancellation } from '@temporalio/workflow'; +import { CancellationScope, isCancellation, proxyActivities } from '@temporalio/workflow'; import type * as activities from '../activities'; const { httpPostJSON, cleanup } = proxyActivities({ @@ -153,8 +164,8 @@ export async function nonCancellable(url: string): Promise { ### withTimeout example -A common operation is to cancel one or more Activities if a deadline elapses. -`withTimeout` creates a `CancellationScope` that is automatically cancelled after a timeout. +A common operation is to cancel one or more Activities if a deadline elapses. `withTimeout` creates a +`CancellationScope` that is automatically cancelled after a timeout. [packages/test/src/workflows/multiple-activities-single-timeout.ts](https://github.com/temporalio/sdk-typescript/blob/main/packages/test/src/workflows/multiple-activities-single-timeout.ts) @@ -208,8 +219,9 @@ export async function resumeAfterCancellation(url: string): Promise { ### Cancellation scopes and callbacks -Callbacks are not particularly useful in Workflows because all meaningful asynchronous operations return promises. -In the rare case that code uses callbacks and needs to handle cancellation, a callback can consume the `CancellationScope.cancelRequested` promise. +Callbacks are not particularly useful in Workflows because all meaningful asynchronous operations return promises. In +the rare case that code uses callbacks and needs to handle cancellation, a callback can consume the +`CancellationScope.cancelRequested` promise. [packages/test/src/workflows/cancellation-scopes-with-callbacks.ts](https://github.com/temporalio/sdk-typescript/blob/main/packages/test/src/workflows/cancellation-scopes-with-callbacks.ts) @@ -236,7 +248,7 @@ You can achieve complex flows by nesting cancellation scopes. [packages/test/src/workflows/nested-cancellation.ts](https://github.com/temporalio/sdk-typescript/blob/main/packages/test/src/workflows/nested-cancellation.ts) ```ts -import { CancellationScope, proxyActivities, isCancellation } from '@temporalio/workflow'; +import { CancellationScope, isCancellation, proxyActivities } from '@temporalio/workflow'; import type * as activities from '../activities'; @@ -262,8 +274,8 @@ export async function nestedCancellation(url: string): Promise { ### Sharing promises between scopes -Operations like Timers and Activities are cancelled by the cancellation scope they were created in. -Promises returned by these operations can be awaited in different scopes. +Operations like Timers and Activities are cancelled by the cancellation scope they were created in. Promises returned by +these operations can be awaited in different scopes. [activities-cancellation-heartbeating/src/cancellation-scopes.ts](https://github.com/temporalio/samples-typescript/blob/main/activities-cancellation-heartbeating/src/cancellation-scopes.ts) @@ -304,17 +316,20 @@ export async function shieldAwaitedInRootScope(): Promise { ## Cancel an Activity from a Workflow {#cancel-an-activity} -Canceling an Activity from within a Workflow requires that the Activity Execution sends Heartbeats and sets a Heartbeat Timeout. -If the Heartbeat is not invoked, the Activity cannot receive a cancellation request. -When any non-immediate Activity is executed, the Activity Execution should send Heartbeats and set a [Heartbeat Timeout](/encyclopedia/detecting-activity-failures#heartbeat-timeout) to ensure that the server knows it is still working. +Canceling an Activity from within a Workflow requires that the Activity Execution sends Heartbeats and sets a Heartbeat +Timeout. If the Heartbeat is not invoked, the Activity cannot receive a cancellation request. When any non-immediate +Activity is executed, the Activity Execution should send Heartbeats and set a +[Heartbeat Timeout](/encyclopedia/detecting-activity-failures#heartbeat-timeout) to ensure that the server knows it is +still working. -When an Activity is canceled, an error is raised in the Activity at the next available opportunity. -If cleanup logic needs to be performed, it can be done in a `finally` clause or inside a caught cancel error. -However, for the Activity to appear canceled the exception needs to be re-thrown. +When an Activity is canceled, an error is raised in the Activity at the next available opportunity. If cleanup logic +needs to be performed, it can be done in a `finally` clause or inside a caught cancel error. However, for the Activity +to appear canceled the exception needs to be re-thrown. :::note -Unlike regular Activities, [Local Activities](/local-activity) can be canceled if they don't send Heartbeats. -Local Activities are handled locally, and all the information needed to handle the cancellation logic is available in the same Worker process. +Unlike regular Activities, [Local Activities](/local-activity) can be canceled if they don't send Heartbeats. Local +Activities are handled locally, and all the information needed to handle the cancellation logic is available in the same +Worker process. ::: diff --git a/docs/encyclopedia/activities/activities.mdx b/docs/encyclopedia/activities/activities.mdx index 8bfeeddb4f..d9c5f4804d 100644 --- a/docs/encyclopedia/activities/activities.mdx +++ b/docs/encyclopedia/activities/activities.mdx @@ -21,9 +21,9 @@ This guide provides a comprehensive overview of Temporal Activities including [Activity Definition](/activity-definition), [Activity Type](/activity-definition#activity-type), [Activity Execution](/activity-execution), and [Local Activity](/local-activity). -An Activity is a normal function or method that executes a single, well-defined action, such as calling another service, -transcoding a media file, or sending an email message. An Activity can either be short or long-running. Activity code -can be non-deterministic. We recommend that it be [idempotent](/activity-definition#idempotency). +An Activity is a normal function or method that executes a single, well-defined action (either short or long running), +such as calling another service, transcoding a media file, or sending an email message. Activity code can be +non-deterministic. We recommend that it be [idempotent](/activity-definition#idempotency). Workflow code orchestrates the execution of Activities, persisting the results. If an Activity Function Execution fails, any future execution starts from initial state (except diff --git a/docs/encyclopedia/temporal-sdks.mdx b/docs/encyclopedia/temporal-sdks.mdx index fa5f9f271f..36bef5eaa7 100644 --- a/docs/encyclopedia/temporal-sdks.mdx +++ b/docs/encyclopedia/temporal-sdks.mdx @@ -183,9 +183,9 @@ For tested code samples and best practices, use your preferred language SDK's de - [Go SDK Temporal Client feature guide](/develop/go/temporal-client) - [Java SDK Temporal Client feature guide](/develop/java/temporal-client) -- [PHP SDK Temporal Client feature guide](/develop/php/temporal-client#connect-to-a-dev-cluster) -- [Python SDK Temporal Client feature guide](/develop/python/temporal-client#connect-to-a-dev-cluster) -- [TypeScript SDK Temporal Client feature guide](/develop/typescript/core-application#connect-to-a-dev-cluster) +- [PHP SDK Temporal Client feature guide](/develop/php/temporal-client) +- [Python SDK Temporal Client feature guide](/develop/python/temporal-client) +- [TypeScript SDK Temporal Client feature guide](/develop/typescript/core-application) ::: diff --git a/docs/production-deployment/cloud/get-started/api-keys.mdx b/docs/production-deployment/cloud/get-started/api-keys.mdx index a8f213b5cc..35e157084a 100644 --- a/docs/production-deployment/cloud/get-started/api-keys.mdx +++ b/docs/production-deployment/cloud/get-started/api-keys.mdx @@ -1,8 +1,10 @@ --- id: api-keys -title: Authenticate with API keys -sidebar_label: Authenticate with API keys -description: Temporal Cloud supports secure programmatic access through API key authentication, ensuring user-level and RBAC-based authorization. +title: Manage API keys +sidebar_label: Manage API keys +description: + Temporal Cloud supports secure programmatic access through API key authentication, ensuring user-level and RBAC-based + authorization. slug: /cloud/api-keys toc_max_heading_level: 4 keywords: @@ -19,8 +21,8 @@ tags: import { CaptionedImage } from '@site/src/components'; -Temporal Cloud API keys offer industry-standard identity-based authentication for Temporal users and [Service Accounts](/cloud/service-accounts). -This document introduces Temporal Cloud's API key features: +Temporal Cloud API keys offer industry-standard identity-based authentication for Temporal users and +[Service Accounts](/cloud/service-accounts). This document introduces Temporal Cloud's API key features: - [API key overview](#overview) - [API key best practices](#best-practices) @@ -34,35 +36,37 @@ This document introduces Temporal Cloud's API key features: ## API key overview {#overview} -Each Temporal Cloud API key is a unique identity linked to role-based access control (RBAC) settings to ensure secure and appropriate access. +Each Temporal Cloud API key is a unique identity linked to role-based access control (RBAC) settings to ensure secure +and appropriate access. The authentication process follows this pathway: ## API key best practices {#best-practices} -- **Keep it secret; keep it safe**: Treat your API key like a password. - Do not expose it in client-side code, public repositories, or other easily accessible locations. +- **Keep it secret; keep it safe**: Treat your API key like a password. Do not expose it in client-side code, public + repositories, or other easily accessible locations. - **Rotate keys regularly**: Change your API keys periodically to reduce risks from potential leaks. -- **Design your code for key updates**: Use key management practices that retrieve your API keys without hard-coding them into your apps. - This lets you restart your Workers to refresh your rotated keys without recompiling your code. -- **Monitor API key usage**: Check usage metrics and logs regularly. - Revoke the key immediately if you detect any unexpected or unauthorized activity. +- **Design your code for key updates**: Use key management practices that retrieve your API keys without hard-coding + them into your apps. This lets you restart your Workers to refresh your rotated keys without recompiling your code. +- **Monitor API key usage**: Check usage metrics and logs regularly. Revoke the key immediately if you detect any + unexpected or unauthorized activity. - **Use a Key Management System (KMS)**: Employ a Key Management System to minimize the risk of key leaks. ### API key use cases API keys are used for the following scenarios: -- _**Cloud operations automation**_: - API keys work with Temporal Cloud operational tools, including [`tcld`](/cloud/tcld), [Cloud Ops APIs](/ops), and [the Terraform provider](/production-deployment/cloud/terraform-provider). - Use them to manage your Temporal Cloud account, Namespaces, certificates, and user identities. -- _**Namespace authentication**_: - API keys serve as an authentication mechanism for executing and managing Workflows via the SDK and Temporal CLI, offering an alternative to mTLS-based authentication. +- _**Cloud operations automation**_: API keys work with Temporal Cloud operational tools, including + [`tcld`](/cloud/tcld), [Cloud Ops APIs](/ops), and + [the Terraform provider](/production-deployment/cloud/terraform-provider). Use them to manage your Temporal Cloud + account, Namespaces, certificates, and user identities. +- _**Namespace authentication**_: API keys serve as an authentication mechanism for executing and managing Workflows via + the SDK and Temporal CLI, offering an alternative to mTLS-based authentication. ### API key supported tooling @@ -76,30 +80,34 @@ Use API keys to authenticate with: ### API key permissions -API keys support both users and Service Accounts. -Here are the differences in their permissions: +API keys support both users and Service Accounts. Here are the differences in their permissions: -- Any user can create, delete, and update their *own* API key using the Cloud UI or `tcld`. -- Only Global Administrators and Account Owners can create, delete, and update access to API keys for all types of Service Accounts. -- Namespace Admins can create, delete, and update access to API keys for the Namespace-scoped Service Accounts they administer. +- Any user can create, delete, and update their _own_ API key using the Cloud UI or `tcld`. +- Only Global Administrators and Account Owners can create, delete, and update access to API keys for all types of + Service Accounts. +- Namespace Admins can create, delete, and update access to API keys for the Namespace-scoped Service Accounts they + administer. ### API key prerequisites Check these setup details before using API keys: -- The Global Administrator or Account Owner may need to [enable API keys access](#manage-api-keys) for your Temporal Account. -- Have access to the [Temporal Cloud UI](https://cloud.temporal.io/) or Temporal Cloud CLI ([tcld](https://docs.temporal.io/cloud/tcld/)) to create an API key. +- The Global Administrator or Account Owner may need to [enable API keys access](#manage-api-keys) for your Temporal + Account. +- Have access to the [Temporal Cloud UI](https://cloud.temporal.io/) or Temporal Cloud CLI + ([tcld](https://docs.temporal.io/cloud/tcld/)) to create an API key. ## Global Administrator and Account Owner API key management {#manage-api-keys} -Global Administrators and Account Owners can monitor, manage, disable, and delete API keys for any user or Service Account within their account. -To manage your account’s API keys: +Global Administrators and Account Owners can monitor, manage, disable, and delete API keys for any user or Service +Account within their account. To manage your account’s API keys: 1. [Log in](https://cloud.temporal.io/) to the Temporal Cloud UI. 1. Go to [Settings → API Keys](https://cloud.temporal.io/settings/api-keys) -Administrators can disable the creation of new API keys using the **Disable Create API Keys** button on the **API Keys** Settings page. -Existing API keys can still be used to authenticate into Temporal Cloud normally until they are either disabled, deleted, or expired. +Administrators can disable the creation of new API keys using the **Disable Create API Keys** button on the **API Keys** +Settings page. Existing API keys can still be used to authenticate into Temporal Cloud normally until they are either +disabled, deleted, or expired. To disable or delete an individual API key use the vertical ellipsis menu in the API key table row. @@ -107,15 +115,16 @@ To find an API key, you can filter by API key state and identity type (Global Ad :::caution DISABLED API KEYS -Deleting or disabling a key removes its ability to authenticate into Temporal Cloud. -If you delete or disable an API key being used by Workers to run a Workflow, those Workers will be unable to connect to Temporal until a new API key secret is created and configured. +Deleting or disabling a key removes its ability to authenticate into Temporal Cloud. If you delete or disable an API key +being used by Workers to run a Workflow, those Workers will be unable to connect to Temporal until a new API key secret +is created and configured. ::: ## User API key management {#user-api-keys} -Manage your personal API keys with the Temporal Cloud UI or `tcld`. -These sections show you how to generate, manage, and remove API keys for a user. +Manage your personal API keys with the Temporal Cloud UI or `tcld`. These sections show you how to generate, manage, and +remove API keys for a user. ### Generate an API key @@ -123,15 +132,15 @@ Create API keys using one of the following methods: :::caution -- Once generated, copy and securely save the API key. - It will be displayed only once for security purposes. +- Once generated, copy and securely save the API key. It will be displayed only once for security purposes. ::: #### Generate API keys with the Temporal Cloud UI -[Log in](https://cloud.temporal.io/) to the Temporal Cloud UI and navigate to your [Profile Page → API Keys](https://cloud.temporal.io/profile/api-keys). -Then select **Create API key** and provide the following information: +[Log in](https://cloud.temporal.io/) to the Temporal Cloud UI and navigate to your +[Profile Page → API Keys](https://cloud.temporal.io/profile/api-keys). Then select **Create API key** and provide the +following information: - **API key name**: A short, identifiable name for the key - **API key description**: A longer description of the key's use @@ -155,8 +164,7 @@ Duration specifies the time until the API key expires, for example: "30d", "4d12 ### Enable or Disable an API key -You can enable or disable API keys. -When disabled, an API key cannot authenticate with Temporal Cloud. +You can enable or disable API keys. When disabled, an API key cannot authenticate with Temporal Cloud. #### Manage API key state with the Temporal Cloud UI @@ -208,18 +216,16 @@ tcld apikey delete --id ### Rotate an API key -Temporal API keys automatically expire based on the specified expiration time. -Follow these steps to rotate API keys: +Temporal API keys automatically expire based on the specified expiration time. Follow these steps to rotate API keys: -1. Create a new key. - You may reuse key names if that helps. +1. Create a new key. You may reuse key names if that helps. 1. Ensure that both the original key and new key function properly before moving to the next step. 1. Switch clients to load the new key and start using it. 1. Delete the old key after it is no longer in use. ## Manage API keys for Service Accounts {#serviceaccount-api-keys} -Global Administrators and Account Owners can manage and generate API keys for *all* Service Accounts in their account. +Global Administrators and Account Owners can manage and generate API keys for _all_ Service Accounts in their account. Namespace Admins can manage and generate API keys for the Namespace-scoped Service Accounts they administer. This is different for non-admin users, who manage and generate their own API keys. @@ -230,16 +236,17 @@ Create API keys for Service Accounts using one of the following methods: :::caution -- Once generated, copy and securely save the API key. - It will be displayed only once for security purposes. +- Once generated, copy and securely save the API key. It will be displayed only once for security purposes. ::: #### Generate API Keys with the Temporal Cloud UI -[Log in](https://cloud.temporal.io/) to the Temporal Cloud UI. Global Administrators or Account Owners can go to [Settings → API Keys](https://cloud.temporal.io/settings/api-keys). Namespace Admins can go to [Profile Page → API Keys](https://cloud.temporal.io/profile/api-keys). -Select **Create API Key**, then choose **Service Account** from the "Create an API key for" dropdown. -In the "Mapped to identity" input box, select a Service Account and provide the following information: +[Log in](https://cloud.temporal.io/) to the Temporal Cloud UI. Global Administrators or Account Owners can go to +[Settings → API Keys](https://cloud.temporal.io/settings/api-keys). Namespace Admins can go to +[Profile Page → API Keys](https://cloud.temporal.io/profile/api-keys). Select **Create API Key**, then choose **Service +Account** from the "Create an API key for" dropdown. In the "Mapped to identity" input box, select a Service Account and +provide the following information: - **API key name**: A short, identifiable name for the key - **API key description**: A longer description of the key's use @@ -261,17 +268,19 @@ tcld apikey create \ ### Enable or Disable an API key -Global Administrators and Account Owners can manage API key access for any user in their account using the Temporal Cloud UI or `tcld`. +Global Administrators and Account Owners can manage API key access for any user in their account using the Temporal +Cloud UI or `tcld`. #### Manage keys with Temporal Cloud UI Follow these steps: 1. [Log in](https://cloud.temporal.io/) to the Temporal Cloud UI. -1. Global Administrators or Account Owners can go to [Settings → API Keys](https://cloud.temporal.io/settings/api-keys). Namespace Admins can go to [Profile Page → API Keys](https://cloud.temporal.io/profile/api-keys). -1. Find the API key. Use the vertical ellipsis menu in the table row and select the Disable/Enable option to perform the action. - There may be a delay after changing the status. - Once successful, the updated API key status will be shown in the row. +1. Global Administrators or Account Owners can go to [Settings → API Keys](https://cloud.temporal.io/settings/api-keys). + Namespace Admins can go to [Profile Page → API Keys](https://cloud.temporal.io/profile/api-keys). +1. Find the API key. Use the vertical ellipsis menu in the table row and select the Disable/Enable option to perform the + action. There may be a delay after changing the status. Once successful, the updated API key status will be shown in + the row. #### Manage keys with tcld @@ -287,23 +296,24 @@ This command is the same for users and Service Accounts. ### Delete an API key for a Service Account -Global Administrators and Account Owners can delete API keys for any user or Service Account in their account using the Temporal Cloud UI or `tcld`. -Deleting a key removes its ability to authenticate with Temporal Cloud. -If you delete an API key used by a Worker to run a Workflow, that Worker will fail to connect to Temporal server unless you rotate the API key with a new one. +Global Administrators and Account Owners can delete API keys for any user or Service Account in their account using the +Temporal Cloud UI or `tcld`. Deleting a key removes its ability to authenticate with Temporal Cloud. If you delete an +API key used by a Worker to run a Workflow, that Worker will fail to connect to Temporal server unless you rotate the +API key with a new one. #### Delete a Service Account API key with Temporal Cloud UI Follow these steps: 1. Go to [Settings → API Keys](https://cloud.temporal.io/settings/api-keys). -1. Locate the API key. Use the vertical ellipsis menu in the table row and select the Delete option. - There may be a delay after deleting the API key. +1. Locate the API key. Use the vertical ellipsis menu in the table row and select the Delete option. There may be a + delay after deleting the API key. 1. Once successful, the updated API key status will be reflected in the row. #### Delete a Service Account API key with tcld -Use the `tcld apikey delete` command to delete an API key. -The process for deleting an API key is the same for a user or Service Account. +Use the `tcld apikey delete` command to delete an API key. The process for deleting an API key is the same for a user or +Service Account. ``` tcld login @@ -312,27 +322,26 @@ tcld apikey delete --id ### Rotate a Service Account API key -Temporal API keys automatically expire based on the specified expiration time. -Follow these steps to rotate API keys: +Temporal API keys automatically expire based on the specified expiration time. Follow these steps to rotate API keys: -1. Create a new key. - You may reuse key names if that helps. +1. Create a new key. You may reuse key names if that helps. 1. Ensure that both the original key and new key function properly before moving to the next step. 1. Switch clients to load the new key and start using it. 1. Delete the old key after it is no longer in use. :::tip -Service Accounts can rotate their own API keys irrespective of their configured permissions. -To use this feature, have your Service Account create a new API key using the [Cloud Ops APIs](/ops) or [`tcld`](/cloud/tcld) before the current one expires. -Service Accounts cannot delete their own API keys without the requisite permissions, which helps keep Workflow access secure. +Service Accounts can rotate their own API keys irrespective of their configured permissions. To use this feature, have +your Service Account create a new API key using the [Cloud Ops APIs](/ops) or [`tcld`](/cloud/tcld) before the current +one expires. Service Accounts cannot delete their own API keys without the requisite permissions, which helps keep +Workflow access secure. ::: ## API keys for Namespace authentication {#namespace-authentication} -Create a Namespace with API key authentication as an alternative to mTLS-based authentication by selecting "Allow API key authentication" during setup. -The gRPC endpoint format for the Namespace depends on the authentication method: +Create a Namespace with API key authentication as an alternative to mTLS-based authentication by selecting "Allow API +key authentication" during setup. The gRPC endpoint format for the Namespace depends on the authentication method: - For API key connections, use the gRPC regional endpoint `..api.temporal.io:7233`. @@ -340,8 +349,9 @@ Use this gRPC endpoint in the Temporal CLI or SDK to connect to Temporal Cloud w :::info -For [Namespaces with High Availability features](/cloud/high-availability) with API key authentication enabled, use the gRPC Namespace endpoint: `..tmprl.cloud:7233`. -This allows automated failover without needing to switch endpoints. +For [Namespaces with High Availability features](/cloud/high-availability) with API key authentication enabled, use the +gRPC Namespace endpoint: `..tmprl.cloud:7233`. This allows automated failover without needing to +switch endpoints. ::: @@ -359,8 +369,8 @@ Authenticate with Temporal Cloud using API keys with the following clients: ### Temporal CLI -To use your API key with the Temporal CLI, either pass it with the `--api-key` flag or set an environment variable in your shell (recommended). -The CLI automatically picks up the `TEMPORAL_API_KEY` environment variable from your shell. +To use your API key with the Temporal CLI, either pass it with the `--api-key` flag or set an environment variable in +your shell (recommended). The CLI automatically picks up the `TEMPORAL_API_KEY` environment variable from your shell. In addition to the API key, the following client options are required: @@ -390,15 +400,15 @@ Do not confuse environment variables, set with your shell, with temporal env opt To use your API key with a Temporal SDK, see the instructions in each SDK section. -[How to connect to Temporal Cloud using an API Key with the Go SDK](/develop/go/temporal-client#connect-to-temporal-cloud-api-key) +[How to connect to Temporal Cloud using an API Key with the Go SDK](/develop/go/temporal-client#connect-to-temporal-cloud) -[How to connect to Temporal Cloud using an API Key with the Java SDK](/develop/java/temporal-client#connect-to-temporal-cloud-api-key) +[How to connect to Temporal Cloud using an API Key with the Java SDK](/develop/java/temporal-client#connect-to-temporal-cloud) -[How to connect to Temporal Cloud using an API Key with the Python SDK](/develop/python/temporal-client#connect-to-temporal-cloud-api-key) +[How to connect to Temporal Cloud using an API Key with the Python SDK](/develop/python/temporal-client#connect-to-temporal-cloud) -[How to connect to Temporal Cloud using an API Key with the TypeScript SDK](/develop/typescript/temporal-client#connect-to-temporal-cloud-api-key) +[How to connect to Temporal Cloud using an API Key with the TypeScript SDK](/develop/typescript/temporal-client#connect-to-temporal-cloud) -[How to connect to Temporal Cloud using an API Key with the .NET SDK](/develop/dotnet/temporal-client#connect-to-temporal-cloud-api-key) +[How to connect to Temporal Cloud using an API Key with the .NET SDK](/develop/dotnet/temporal-client#connect-to-temporal-cloud) ### tcld @@ -415,12 +425,14 @@ Do not confuse environment variables, set with your shell, with temporal env opt ### Cloud Ops API -To use an API key with the [Cloud Ops API](/ops), securely pass the API key in your API client. -For a complete example, see [Cloud Samples in Go](https://github.com/temporalio/cloud-samples-go/blob/1dd4254b6ed1937e361005c0144410e72b8a5542/client/api/apikey.go). +To use an API key with the [Cloud Ops API](/ops), securely pass the API key in your API client. For a complete example, +see +[Cloud Samples in Go](https://github.com/temporalio/cloud-samples-go/blob/1dd4254b6ed1937e361005c0144410e72b8a5542/client/api/apikey.go). ### Terraform Provider -To use an API key with the [Temporal Terraform Provider](/production-deployment/cloud/terraform-provider), pass the API key as a provider argument. +To use an API key with the [Temporal Terraform Provider](/production-deployment/cloud/terraform-provider), pass the API +key as a provider argument. ## Troubleshoot your API key use {#troubleshooting} @@ -438,8 +450,7 @@ A: Up to 10 non-expired keys per user and 20 non-expired keys per Service Accoun **Q: Do API keys expire?** -A: Yes, API keys expire based on the specified expiration date. -Temporal recommends rotating API keys periodically. +A: Yes, API keys expire based on the specified expiration date. Temporal recommends rotating API keys periodically. **Q: Whats the maximum allowed expiration for an API key?** @@ -447,10 +458,10 @@ A: The maximum expiration time for an API key is 2 years. **Q: What happens if I misplace or lose my API bearer token/secret key?** -A: The full key is displayed only once upon creation for security reasons. -If you lose it, generate a new one. +A: The full key is displayed only once upon creation for security reasons. If you lose it, generate a new one. **Q: What is the `Generate API Key` button on the Namespace page?** -A: The `Generate API Key` button on a Namespace page generates an API key with `Admin` permissions for the given Namespace and the maximum expiration time, which is 2 years. -For additional details, refer to [Namespace-scoped Service Accounts](/cloud/service-accounts#scoped). +A: The `Generate API Key` button on a Namespace page generates an API key with `Admin` permissions for the given +Namespace and the maximum expiration time, which is 2 years. For additional details, refer to +[Namespace-scoped Service Accounts](/cloud/service-accounts#scoped). diff --git a/docs/production-deployment/cloud/terraform-provider.mdx b/docs/production-deployment/cloud/terraform-provider.mdx index 15bd1ab3f5..3e698057b7 100644 --- a/docs/production-deployment/cloud/terraform-provider.mdx +++ b/docs/production-deployment/cloud/terraform-provider.mdx @@ -2,7 +2,9 @@ id: terraform-provider title: Temporal Cloud Terraform provider sidebar_label: Terraform provider -description: Automate resource management on Temporal Cloud with the Terraform Temporal provider. Manage Namespaces and users with Terraform's infrastructure-as-code. +description: + Automate resource management on Temporal Cloud with the Terraform Temporal provider. Manage Namespaces and users with + Terraform's infrastructure-as-code. tags: - Temporal Cloud - Terraform @@ -12,9 +14,9 @@ ssdi: import { CaptionedImage } from '@site/src/components'; -The Terraform Temporal Cloud provider allows you to use Terraform to manage resources for Temporal Cloud. -The Terraform tool manages infrastructure as code (IaC). -With this provider, you can use Terraform to automate Temporal Cloud resource management, including Namespaces, Users, Service Accounts, API Keys and more. +The Terraform Temporal Cloud provider allows you to use Terraform to manage resources for Temporal Cloud. The Terraform +tool manages infrastructure as code (IaC). With this provider, you can use Terraform to automate Temporal Cloud resource +management, including Namespaces, Users, Service Accounts, API Keys and more. :::note Terraform Management @@ -24,10 +26,17 @@ Once a resource is managed by Terraform, you should only use Terraform to manage Resources: -- The [Temporal Cloud Terraform provider](https://registry.terraform.io/providers/temporalio/temporalcloud/latest) is available in the Terraform Registry, where you can find detailed documentation on the Provider's supported resources and data sources. -- The GitHub repository for the Terraform provider is [terraform-provider-temporalcloud](https://github.com/temporalio/terraform-provider-temporalcloud/tree/main), where you can report bugs, provide feature requests, and [contribute](https://github.com/temporalio/terraform-provider-temporalcloud/blob/main/CONTRIBUTING.md) to the provider. - We encourage your input as we develop the provider with the community. -- To view the list of available Temporal Cloud resources supported by Terraform provider, visit the resources section of the Terraform documentation in Hashi's [registry](https://registry.terraform.io/providers/temporalio/temporalcloud/latest/docs). +- The [Temporal Cloud Terraform provider](https://registry.terraform.io/providers/temporalio/temporalcloud/latest) is + available in the Terraform Registry, where you can find detailed documentation on the Provider's supported resources + and data sources. +- The GitHub repository for the Terraform provider is + [terraform-provider-temporalcloud](https://github.com/temporalio/terraform-provider-temporalcloud/tree/main), where + you can report bugs, provide feature requests, and + [contribute](https://github.com/temporalio/terraform-provider-temporalcloud/blob/main/CONTRIBUTING.md) to the + provider. We encourage your input as we develop the provider with the community. +- To view the list of available Temporal Cloud resources supported by Terraform provider, visit the resources section of + the Terraform documentation in Hashi's + [registry](https://registry.terraform.io/providers/temporalio/temporalcloud/latest/docs). ### Prerequisites @@ -35,20 +44,23 @@ To use the Terraform provider, you'll need the following: - The [Terraform CLI](https://developer.hashicorp.com/terraform/cli) - An [API Key](/cloud/api-keys): an API Key is required to use the Terraform provider. - - See [the API docs](https://docs.temporal.io/cloud/api-keys#generate-an-api-key) for instructions on generating an API Key. + - See [the API docs](https://docs.temporal.io/cloud/api-keys#generate-an-api-key) for instructions on generating an + API Key. :::note OpenTofu Registry -Our Terraform Provider is registered with [OpenTofu](https://opentofu.org), but that registration is not maintained or managed by Temporal Technologies. +Our Terraform Provider is registered with [OpenTofu](https://opentofu.org), but that registration is not maintained or +managed by Temporal Technologies. ::: ## Setup -Generate an [API Key](https://docs.temporal.io/cloud/api-keys#generate-an-api-key) to authenticate Terraform operations with your Temporal Cloud account or a Service Account. -Then, either use an environmental variable or pass the API Key into the provider manually to manage your Temporal Cloud Terraform resources. +Generate an [API Key](https://docs.temporal.io/cloud/api-keys#generate-an-api-key) to authenticate Terraform operations +with your Temporal Cloud account or a Service Account. Then, either use an environment variable or pass the API Key into +the provider manually to manage your Temporal Cloud Terraform resources. -Follow these examples to use an environmental variable to pass in your API Key to the provider. +Follow these examples to use an environment variable to pass in your API Key to the provider. @@ -86,46 +98,35 @@ Do not confuse environment variables, set with your shell, with temporal env opt Or, pass it in manually in your .tf file using the provider code block ```yml -provider "temporalcloud" { - api_key = "my-temporalcloud-api-key" -} +provider "temporalcloud" { api_key = "my-temporalcloud-api-key" } ``` ## Manage Temporal Cloud Namespaces with Terraform -Terraform is a great way to automate the management of Temporal Namespaces. -It doesn't matter whether you want management to be centralized within a platform team or federated to different product teams. -The provider allows you to import, create, update, and delete Namespaces with Terraform. +Terraform is a great way to automate the management of Temporal Namespaces. It doesn't matter whether you want +management to be centralized within a platform team or federated to different product teams. The provider allows you to +import, create, update, and delete Namespaces with Terraform. -You must use an Identity with Temporal Cloud Namespace management privileges. -This includes the Account Owner, Global Admin, or Developer Account Role. +You must use an Identity with Temporal Cloud Namespace management privileges. This includes the Account Owner, Global +Admin, or Developer Account Role. **How do I create a Namespace with Terraform?** 1. Create a Terraform configuration file (`terraform.tf`) to define a Namespace. ```yml - terraform { - required_providers { - temporalcloud = { - source = "temporalio/temporalcloud" - } - } - } + terraform { required_providers { temporalcloud = { source = "temporalio/temporalcloud" } } } provider "temporalcloud" { } - resource "temporalcloud_namespace" "namespace" { - name = "terraform" - regions = ["aws-us-east-1"] - accepted_client_ca = base64encode(file("ca.pem")) - retention_days = 14 - } + resource "temporalcloud_namespace" "namespace" { name = "terraform" regions = + ["aws-us-east-1"] accepted_client_ca = base64encode(file("ca.pem")) retention_days = 14 } ``` - In this example, you create a Temporal Cloud Namespace named `terraform`, specifying the AWS region `aws-us-east-1`, and specifying the path to the CA certificate. + In this example, you create a Temporal Cloud Namespace named `terraform`, specifying the AWS region `aws-us-east-1`, + and specifying the path to the CA certificate. 1. Initialize the Terraform provider. @@ -151,8 +152,10 @@ Upon completion, you'll see a success message indicating your Namespace is creat temporalcloud_namespace.terraform: Creation complete after 2m17s [id=] ``` -You can find more examples of Namespace management in the Terraform Provider docs located on HashiCorp's [Terraform Registry](https://registry.terraform.io/providers/temporalio/temporalcloud/latest/docs/resources/namespace). -The Terraform Provider docs show how to generate CA certs within Terraform configuration files and create a Namespace with API Key based authentication. +You can find more examples of Namespace management in the Terraform Provider docs located on HashiCorp's +[Terraform Registry](https://registry.terraform.io/providers/temporalio/temporalcloud/latest/docs/resources/namespace). +The Terraform Provider docs show how to generate CA certs within Terraform configuration files and create a Namespace +with API Key based authentication. **How do I validate the creation of the Namespace?** @@ -166,9 +169,10 @@ You can validate the creation of the Namespace through the Temporal Web UI or th **Using the tcld CLI utility** -Validate the creation of your Namespace through the Terraform provider. -To validate see your Namespace in the Cloud UI or through the `tcld namespace get` command. -Run the `tcld namespace get` command and pass in your [Cloud Namespace Name](/cloud/namespaces#temporal-cloud-namespace-name) and [Cloud Account Id](/cloud/namespaces#temporal-cloud-account-id): +Validate the creation of your Namespace through the Terraform provider. To validate see your Namespace in the Cloud UI +or through the `tcld namespace get` command. Run the `tcld namespace get` command and pass in your +[Cloud Namespace Name](/cloud/namespaces#temporal-cloud-namespace-name) and +[Cloud Account Id](/cloud/namespaces#temporal-cloud-account-id): ```bash tcld namespace get -n "." @@ -178,41 +182,30 @@ tcld namespace get -n "." Terraform automatically recognizes changes made within `.tf` files and applies those changes to Temporal. -For example, change the retention period setting in the Terraform file from the previous example and watch Terraform apply the change without any additional steps required by you. +For example, change the retention period setting in the Terraform file from the previous example and watch Terraform +apply the change without any additional steps required by you. 1. Set the retention period to 30 days. ```yml - terraform { - required_providers { - temporalcloud = { - source = "temporalio/temporalcloud" - version = ">= 0.0.6" - } - } - } + terraform { required_providers { temporalcloud = { source = "temporalio/temporalcloud" version = ">= 0.0.6" } } } provider "temporalcloud" { } - resource "temporalcloud_namespace" "namespace" { - name = "terraform" - regions = ["aws-us-east-1"] - accepted_client_ca = base64encode(file("ca.pem")) - retention_days = 30 - } + resource "temporalcloud_namespace" "namespace" { name = "terraform" regions = + ["aws-us-east-1"] accepted_client_ca = base64encode(file("ca.pem")) retention_days = 30 } ``` -1. Apply your configuration. - When prompted, answer yes to continue: +1. Apply your configuration. When prompted, answer yes to continue: ```command terraform apply ``` -Upon completion, you will see a success message indicating your Namespace has been updated. -It may take several minutes to update a Namespace. +Upon completion, you will see a success message indicating your Namespace has been updated. It may take several minutes +to update a Namespace. ```text temporalcloud_namespace.namespace: Modifications complete after 10s [id=terraform.a1bb2] @@ -220,7 +213,8 @@ temporalcloud_namespace.namespace: Modifications complete after 10s [id=terrafor **How do I delete a Temporal Cloud Namespace?** -To delete a Namespace, remove the `temporalcloud_namespace` resource and all dependent resource configurations from your Terraform files and run the `terraform apply` command. +To delete a Namespace, remove the `temporalcloud_namespace` resource and all dependent resource configurations from your +Terraform files and run the `terraform apply` command. Upon completion, you will see a success message indicating the resource has been destroyed: @@ -228,25 +222,27 @@ Upon completion, you will see a success message indicating the resource has been temporalcloud_namespace.my_namespace: Destruction complete after 3s Apply complete! Resources: 0 added, 0 changed, 1 destroyed. ``` + :::note Preventing Deletion -You can prevent deletion of any Terraform resource by including the `prevent_destroy` argument in the Terraform configuration file. +You can prevent deletion of any Terraform resource by including the `prevent_destroy` argument in the Terraform +configuration file. ::: **How do I import a Temporal Cloud Namespace?** -If you have an existing Namespace in Temporal Cloud, you can import it into Terraform to manage the Namespace from Terraform using the `terraform import` command. +If you have an existing Namespace in Temporal Cloud, you can import it into Terraform to manage the Namespace from +Terraform using the `terraform import` command. 1. Provide a configuration placeholder in your Terraform configuration. ```yml - resource "temporalcloud_namespace" "namespace" { - } + resource "temporalcloud_namespace" "namespace" { } ``` -1. Run the `terraform import` command from the command line and pass in the Namespace ID. - Your Namespace ID is available at the top of the Namespace's page in the Temporal Cloud UI and is in the format `namespaceid.acctid`. +1. Run the `terraform import` command from the command line and pass in the Namespace ID. Your Namespace ID is available + at the top of the Namespace's page in the Temporal Cloud UI and is in the format `namespaceid.acctid`. ```bash terraform import temporalcloud_namespace.terraform namespaceid.acctid @@ -256,22 +252,25 @@ The Namespace is now a part of the Terraform state and all changes to the Namesp :::caution -Once a resource has been imported into Terraform, outside changes to the resource will create Terraform "drift" errors on subsequent Terraform operations. +Once a resource has been imported into Terraform, outside changes to the resource will create Terraform "drift" errors +on subsequent Terraform operations. ::: ## Manage Temporal Cloud Nexus Endpoints with Terraform -Terraform provides a great way to automate the management of [Nexus Endpoints](/nexus/endpoints). -The provider allows you to import, create, update, and delete Nexus Endpoints with Terraform. +Terraform provides a great way to automate the management of [Nexus Endpoints](/nexus/endpoints). The provider allows +you to import, create, update, and delete Nexus Endpoints with Terraform. -You must use an Identity with [Developer role (or higher)](/cloud/users#account-level-roles) and [Namespace Admin permission](/cloud/users#namespace-level-permissions) on the Endpoint's target Namespace. +You must use an Identity with [Developer role (or higher)](/cloud/users#account-level-roles) and +[Namespace Admin permission](/cloud/users#namespace-level-permissions) on the Endpoint's target Namespace. **How do I create a Nexus Endpoint with Terraform?** 1. Create a Terraform configuration file (`terraform.tf`) to define a Nexus Endpoint. - From the [example in the Terraform Registry](https://registry.terraform.io/providers/temporalio/temporalcloud/latest/docs/resources/nexus_endpoint): + From the + [example in the Terraform Registry](https://registry.terraform.io/providers/temporalio/temporalcloud/latest/docs/resources/nexus_endpoint): ```yml terraform { @@ -343,12 +342,15 @@ You must use an Identity with [Developer role (or higher)](/cloud/users#account- ``` In this example, 3 Namespaces are created: + - target Namespace for a Nexus Endpoint - Nexus requests will be routed to a Worker that polls the target Namespace. - caller Namespace(s) - Nexus Operations are invoked from caller Namespace, for example from a caller Workflow. These Namespaces are referenced in the [Nexus Endpoint](/nexus/endpoints) configuration: + - `worker_target` (Namespace and Task Queue) - currently only a single worker_target is supported. - - `allowed_caller_namespaces` - used to enforce Nexus Endpoint [runtime access controls](/nexus/security#runtime-access-controls). + - `allowed_caller_namespaces` - used to enforce Nexus Endpoint + [runtime access controls](/nexus/security#runtime-access-controls). 1. Initialize the Terraform provider. @@ -374,12 +376,15 @@ You must use an Identity with [Developer role (or higher)](/cloud/users#account- temporalcloud_nexus_endpoint.nexus_endpoint: Creation complete after 2s [id=b158063be978471fa1d200569b03834d] ``` -You can find more examples of Nexus Endpoint management in the Terraform Provider docs located on HashiCorp's [Terraform Registry](https://registry.terraform.io/providers/temporalio/temporalcloud/latest/docs/resources/nexus_endpoint). -The Terraform Provider docs show how to generate CA certs within Terraform configuration files and create a Namespace with API Key based authentication. +You can find more examples of Nexus Endpoint management in the Terraform Provider docs located on HashiCorp's +[Terraform Registry](https://registry.terraform.io/providers/temporalio/temporalcloud/latest/docs/resources/nexus_endpoint). +The Terraform Provider docs show how to generate CA certs within Terraform configuration files and create a Namespace +with API Key based authentication. **How do I validate the creation of the Nexus Endpoint?** -You can validate the creation of the Nexus Endpoint through the Temporal Web UI or through the `tcld nexus endpoint get` command. +You can validate the creation of the Nexus Endpoint through the Temporal Web UI or through the `tcld nexus endpoint get` +command. **Using the Temporal Web UI** @@ -389,11 +394,10 @@ You can validate the creation of the Nexus Endpoint through the Temporal Web UI **Using the tcld CLI utility** -Validate the creation of your Nexus Endpoint through the Terraform provider. -To validate see your Nexus Endpoint in the Cloud UI or through the `tcld nexus endpoint get` command. +Validate the creation of your Nexus Endpoint through the Terraform provider. To validate see your Nexus Endpoint in the +Cloud UI or through the `tcld nexus endpoint get` command. -Run the below command using your Nexus Endpoint Name. -Do not use the account ID suffix with this endpoint name: +Run the below command using your Nexus Endpoint Name. Do not use the account ID suffix with this endpoint name: ```bash tcld nexus endpoint get -n "" @@ -405,7 +409,8 @@ Terraform automatically recognizes changes made within `.tf` files and applies t For example, to change the allowed caller Namespaces on a Nexus Endpoint: -1. Add or remove allowed caller Namespaces by updating the Nexus Endpoint configuration, for example by removing `caller_namespace_2` from the configuration above: +1. Add or remove allowed caller Namespaces by updating the Nexus Endpoint configuration, for example by removing + `caller_namespace_2` from the configuration above: ```yml resource "temporalcloud_nexus_endpoint" "nexus_endpoint" { @@ -430,16 +435,16 @@ For example, to change the allowed caller Namespaces on a Nexus Endpoint: } ``` -1. Apply your configuration. - When prompted, answer yes to continue: +1. Apply your configuration. When prompted, answer yes to continue: ```command terraform apply ``` - Upon completion, you will see a success message indicating your Nexus Endpoint has been updated. - It may take several seconds to update a Nexus Endpoint in the control plane which is visibile from the Temporal UI or tcld CLI. - Propagation of Nexus Endpoint changes to the data plane may take longer, but usually complete in less than one minute. + Upon completion, you will see a success message indicating your Nexus Endpoint has been updated. It may take several + seconds to update a Nexus Endpoint in the control plane which is visibile from the Temporal UI or tcld CLI. + Propagation of Nexus Endpoint changes to the data plane may take longer, but usually complete in less than one + minute. ```text temporalcloud_nexus_endpoint.nexus_endpoint: Modifications complete after 1s [id=b158063be978471fa1d200569b03834d] @@ -447,7 +452,8 @@ For example, to change the allowed caller Namespaces on a Nexus Endpoint: **How do I delete a Nexus Endpoint?** -To delete a Nexus Endpoint, remove the `temporalcloud_nexus_endpoint` resource configuration from your Terraform files and run the `terraform apply` command. +To delete a Nexus Endpoint, remove the `temporalcloud_nexus_endpoint` resource configuration from your Terraform files +and run the `terraform apply` command. Upon completion, you will see a success message indicating the resource has been destroyed: @@ -458,7 +464,8 @@ Apply complete! Resources: 0 added, 0 changed, 1 destroyed. **How do I import a Temporal Cloud Nexus Endpoint?** -If you have an existing Nexus Endpoint in Temporal Cloud, you can import it into Terraform to manage the Nexus Endpoint from Terraform using the `terraform import` command. +If you have an existing Nexus Endpoint in Temporal Cloud, you can import it into Terraform to manage the Nexus Endpoint +from Terraform using the `terraform import` command. 1. Initialize the Terraform provider in a new directory. @@ -468,22 +475,15 @@ If you have an existing Nexus Endpoint in Temporal Cloud, you can import it into terraform init ``` -1. Provide a configuration placeholder in your Terraform configuration and ensure you've included your [API key](#setup). +1. Provide a configuration placeholder in your Terraform configuration and ensure you've included your + [API key](#setup). ```yml - terraform { - required_providers { - temporalcloud = { - source = "temporalio/temporalcloud" - } - } - } + terraform { required_providers { temporalcloud = { source = "temporalio/temporalcloud" } } } - provider "temporalcloud" { - } + provider "temporalcloud" { } - resource "temporalcloud_nexus_endpoint" "nexus_endpoint" { - } + resource "temporalcloud_nexus_endpoint" "nexus_endpoint" { } ``` 1. Run the `terraform import` command from the command line and pass in the Nexus Endpoint ID. @@ -492,7 +492,8 @@ If you have an existing Nexus Endpoint in Temporal Cloud, you can import it into terraform import temporalcloud_nexus_endpoint ``` - Your Nexus Endpoint ID is available at the top of the Nexus Endpoint's page in the [Temporal Cloud UI](https://cloud.temporal.io/nexus). + Your Nexus Endpoint ID is available at the top of the Nexus Endpoint's page in the + [Temporal Cloud UI](https://cloud.temporal.io/nexus). @@ -504,36 +505,36 @@ If you have an existing Nexus Endpoint in Temporal Cloud, you can import it into Import successful! ``` -The Nexus Endpoint is now a part of the Terraform state and all changes to the Nexus Endpoint should be managed by Terraform. +The Nexus Endpoint is now a part of the Terraform state and all changes to the Nexus Endpoint should be managed by +Terraform. :::caution -Once a resource has been imported into Terraform, outside changes to the resource will create Terraform "drift" errors on subsequent Terraform operations. +Once a resource has been imported into Terraform, outside changes to the resource will create Terraform "drift" errors +on subsequent Terraform operations. ::: ## Manage Temporal Cloud Users with Terraform -Manage Temporal Cloud Users with the same process you use to manage Namespaces with Terraform. -The following examples create, update, delete, and import Temporal Cloud Users with `terraform apply` commands on the Terraform configuration file. +Manage Temporal Cloud Users with the same process you use to manage Namespaces with Terraform. The following examples +create, update, delete, and import Temporal Cloud Users with `terraform apply` commands on the Terraform configuration +file. :::note User Management Cautions about Temporal User management: -- Terraform can't manage the Temporal Account Owner role. - While you can import an Account Owner to Terraform, you cannot create, update, or delete an Account Owner with Terraform. -- Right now, you can't manage a user's access to a Namespace from the Namespace resource. - You must manage Namespace access from the User resource. - This is also true for Service Accounts. -- Account Owners and Global Admins automatically gain access to all Namespaces in Temporal. - Therefore, you cannot specify Namespace access for these roles. - This is also true for Service Accounts. -- Follow Terraform best practices for resource management. - Manage a specific user in one and only one .tf file. - There's a risk that you may overwrite a user's permissions if you don't. -- To Import a user, you'll need the User's ID which is currently not available in the Temporal Cloud UI. - You can fetch current User ID by running the `tcld user list` command. +- Terraform can't manage the Temporal Account Owner role. While you can import an Account Owner to Terraform, you cannot + create, update, or delete an Account Owner with Terraform. +- Right now, you can't manage a user's access to a Namespace from the Namespace resource. You must manage Namespace + access from the User resource. This is also true for Service Accounts. +- Account Owners and Global Admins automatically gain access to all Namespaces in Temporal. Therefore, you cannot + specify Namespace access for these roles. This is also true for Service Accounts. +- Follow Terraform best practices for resource management. Manage a specific user in one and only one .tf file. There's + a risk that you may overwrite a user's permissions if you don't. +- To Import a user, you'll need the User's ID which is currently not available in the Temporal Cloud UI. You can fetch + current User ID by running the `tcld user list` command. ::: @@ -542,46 +543,24 @@ Cautions about Temporal User management: 1. Add a Terraform User resources configuration to your Terraform file. ```yml - terraform { - required_providers { - temporalcloud = { - source = "temporalio/temporalcloud" - } - } - } + terraform { required_providers { temporalcloud = { source = "temporalio/temporalcloud" } } } provider "temporalcloud" { } - resource "temporalcloud_namespace" "namespace" { - name = "terraform" - regions = ["aws-us-east-1"] - accepted_client_ca = base64encode(file("ca.pem")) - retention_days = 14 - } + resource "temporalcloud_namespace" "namespace" { name = "terraform" regions = + ["aws-us-east-1"] accepted_client_ca = base64encode(file("ca.pem")) retention_days = 14 } - resource "temporalcloud_user" "global_admin" { - email = - account_access = "Admin" - } + resource "temporalcloud_user" "global_admin" { email = account_access = "Admin" } - resource "temporalcloud_user" "namespace_admin" { - email = - account_access = "Developer" - namespace_accesses = [ - { - namespace_id = temporalcloud_namespace.namespace.id - permission = "Write" - } - ] - } + resource "temporalcloud_user" "namespace_admin" { email = account_access = "Developer" + namespace_accesses = [ { namespace_id = temporalcloud_namespace.namespace.id permission = "Write" } ] } ``` Replace the email and domain values with your Temporal Cloud User email and domain. -1. Apply your configuration. - When prompted, answer yes to continue: +1. Apply your configuration. When prompted, answer yes to continue: ```command terraform apply @@ -600,36 +579,22 @@ To update a User with Terraform, follow the same steps used to create a User. **How do I delete a Temporal Cloud User with Terraform?** -To delete a User with Terraform, remove the Terraform User resources configuration from your Terraform file and run the `terraform apply` command. +To delete a User with Terraform, remove the Terraform User resources configuration from your Terraform file and run the +`terraform apply` command. 1. Remove the Terraform User resources configuration from your Terraform file. ```yml - terraform { - required_providers { - temporalcloud = { - source = "temporalio/temporalcloud" - version = ">= 0.0.6" - } - } - } + terraform { required_providers { temporalcloud = { source = "temporalio/temporalcloud" version = ">= 0.0.6" } } } provider "temporalcloud" { } - resource "temporalcloud_namespace" "namespace" { - name = "terraform" - regions = ["aws-us-east-1"] - accepted_client_ca = base64encode(file("ca.pem")) - retention_days = 14 - } - - resource "temporalcloud_user" "global_admin" { - email = - account_access = "Admin" - } + resource "temporalcloud_namespace" "namespace" { name = "terraform" regions = + ["aws-us-east-1"] accepted_client_ca = base64encode(file("ca.pem")) retention_days = 14 } + resource "temporalcloud_user" "global_admin" { email = account_access = "Admin" } # resource "temporalcloud_user" "namespace_admin" { # email = # account_access = "Developer" @@ -642,8 +607,7 @@ To delete a User with Terraform, remove the Terraform User resources configurati # } ``` -1. Run the `terraform apply` command. - When prompted, answer yes to continue: +1. Run the `terraform apply` command. When prompted, answer yes to continue: ```command terraform apply @@ -656,14 +620,13 @@ temporalcloud_user.namespace_admin: Destruction complete after 2s Apply complete! Resources: 0 added, 0 changed, 1 destroyed. ``` -**How do I import a Temporal User?** -If you have an existing User in Temporal Cloud, you can import it into Terraform using the `terraform import` command. +**How do I import a Temporal User?** If you have an existing User in Temporal Cloud, you can import it into Terraform +using the `terraform import` command. 1. Provide a configuration placeholder in your Terraform configuration. ```yml - resource "temporalcloud_user" "user" { - } + resource "temporalcloud_user" "user" { } ``` ```` @@ -678,26 +641,31 @@ The User is now a part of the Terraform state and all changes to the User should ## Manage Temporal Cloud Service Accounts with Terraform -The process and steps to managing a Service Account with Terraform are very similar to managing a User with Terraform with a few small differences: +The process and steps to managing a Service Account with Terraform are very similar to managing a User with Terraform +with a few small differences: - Service Accounts use the Service Account Terraform resource not the User resource. -- Service Accounts do not have email addresses, they have names instead. - This means you should specify a name for a Service Account instead of an email. +- Service Accounts do not have email addresses, they have names instead. This means you should specify a name for a + Service Account instead of an email. -Everything else about managing Services Accounts with Terraform follows the same process, guidance, and limitations of managing Users with Terraform. +Everything else about managing Services Accounts with Terraform follows the same process, guidance, and limitations of +managing Users with Terraform. ## Manage Temporal Cloud API Keys with Terraform -You can manage your own, personal API Keys and Service Account API Keys with Terraform. -The process and steps to managing an API Key with Terraform are very similar to managing other resources with Terraform. -You can create, delete, update and import API Keys with Terraform. -One difference between working with API Keys as a Terraform resource compared to other Temporal Cloud resources is the need to access an API Keys secure token output from Terraform. -Walk through the process of securely accessing the API Key Token in the Create section of this guide. +You can manage your own, personal API Keys and Service Account API Keys with Terraform. The process and steps to +managing an API Key with Terraform are very similar to managing other resources with Terraform. You can create, delete, +update and import API Keys with Terraform. One difference between working with API Keys as a Terraform resource compared +to other Temporal Cloud resources is the need to access an API Keys secure token output from Terraform. Walk through the +process of securely accessing the API Key Token in the Create section of this guide. :::note Limits and Best Practices -- See the API Key [documentation](https://docs.temporal.io/cloud/api-keys) for information about the limits and best practices for managing API Keys. -- See Terraform's documentation on working with [sensitive data](https://www.terraform.io/docs/language/values/variables.html#sensitive-values) for more information on how to manage sensitive data in Terraform. +- See the API Key [documentation](https://docs.temporal.io/cloud/api-keys) for information about the limits and best + practices for managing API Keys. +- See Terraform's documentation on working with + [sensitive data](https://www.terraform.io/docs/language/values/variables.html#sensitive-values) for more information + on how to manage sensitive data in Terraform. ::: @@ -706,30 +674,18 @@ Walk through the process of securely accessing the API Key Token in the Create s 1. Add a Terraform API Key resources configuration to your Terraform file. ```yml - terraform { - required_providers { - temporalcloud = { - source = "temporalio/temporalcloud" - } - } - } + terraform { required_providers { temporalcloud = { source = "temporalio/temporalcloud" } } } provider "temporalcloud" { } - resource "temporalcloud_service_account" "global_service_account" { - name = "admin" - account_access = "Admin" + resource "temporalcloud_service_account" "global_service_account" { name = "admin" account_access = "Admin" } - resource "temporalcloud_apikey" "global_apikey" { - display_name = "admin" - owner_type = "service-account" - owner_id = temporalcloud_service_account.global_service_account.id - expiry_time = "2024-11-01T00:00:00Z" - disabled = false - } + resource "temporalcloud_apikey" "global_apikey" { display_name = "admin" owner_type = "service-account" + owner_id = temporalcloud_service_account.global_service_account.id expiry_time = "2024-11-01T00:00:00Z" + disabled = false } ``` Make sure to: @@ -740,14 +696,10 @@ Walk through the process of securely accessing the API Key Token in the Create s 1. Create an output.tf file and add the following code to output the API Key Token. ```yml - output "apikey_token" { - value = temporalcloud_apikey.global_apikey.token - sensitive = true - } + output "apikey_token" { value = temporalcloud_apikey.global_apikey.token sensitive = true } ``` -1. Apply your configuration. - When prompted, answer yes to continue: +1. Apply your configuration. When prompted, answer yes to continue: ```command terraform apply @@ -759,8 +711,8 @@ Walk through the process of securely accessing the API Key Token in the Create s temporalcloud_apikey.global_apikey: Creation complete after 1s [id=kayBf38JIWkMPmnfr59iEIaEk2L7uqR4] ``` -1. Access the API Key Token securely. - You'll notice that if you view the state for the API Key resource, the token value is not displayed. +1. Access the API Key Token securely. You'll notice that if you view the state for the API Key resource, the token value + is not displayed. ```bash terraform state show temporalcloud_apikey.global_apikey @@ -788,8 +740,8 @@ This will display the token value in the terminal. :::info Security and API Keys -Remember, keep your Terraform state files secure if you're managing API Keys with Terraform. -The state file contains sensitive information, like the API Key Token, that should not be shared or exposed. +Remember, keep your Terraform state files secure if you're managing API Keys with Terraform. The state file contains +sensitive information, like the API Key Token, that should not be shared or exposed. ::: @@ -799,29 +751,31 @@ To update an API Key with Terraform, follow the same steps used to create an API :::note Editing Fields -You can only edit an API Key's name or description field. -Updating an API Key does not generate a new secure token +You can only edit an API Key's name or description field. Updating an API Key does not generate a new secure token ::: **How do I delete a Temporal Cloud API Key with Terraform?** -To delete an API Key with Terraform, remove the Terraform API Key resources configuration from your Terraform and output.tf files and run the `terraform apply` command. +To delete an API Key with Terraform, remove the Terraform API Key resources configuration from your Terraform and +output.tf files and run the `terraform apply` command. **How do I Import a Temporal API Key?** -You cannot import an API Key into Terraform. -Once created, the API Key secret isn't stored and can't be retrieved, so you can't access it using import. +You cannot import an API Key into Terraform. Once created, the API Key secret isn't stored and can't be retrieved, so +you can't access it using import. Instead, Temporal recommends creating a new API Key using Terraform directly. ## Data Sources - Regions and Namespaces -The Terraform provider also supports 2 data sources that provide you access to the available Regions and Namespaces in your Temporal Cloud account. +The Terraform provider also supports 2 data sources that provide you access to the available Regions and Namespaces in +your Temporal Cloud account. :::note Terraform Data Sources -See Terraform [documentation](https://developer.hashicorp.com/terraform/language/data-sources) to learn more about Terraform Data Sources +See Terraform [documentation](https://developer.hashicorp.com/terraform/language/data-sources) to learn more about +Terraform Data Sources ::: @@ -830,14 +784,15 @@ For example, to retrieve a list of regions available for your account, you can u ```yml data "temporalcloud_regions" "regions" {} -output "regions" { - value = data.temporalcloud_regions.regions.regions -} +output "regions" { value = data.temporalcloud_regions.regions.regions } ``` ## Community Involvement Do you have feedback about the provider? Want to report a bug or request a feature? We'd love to hear from you. -- Please reach out to us in the Temporal Community [Slack](https://join.slack.com/t/temporalio/shared_invite/zt-2u2ey8ilu-LRxnd3PSoAk9GZ94UuzoBA) in the #terraform channel -- Feel free to create issues and contribute PRs in the Temporal Terraform [GitHub repository](https://github.com/temporalio/terraform-provider-temporalcloud/tree/main) +- Please reach out to us in the Temporal Community + [Slack](https://join.slack.com/t/temporalio/shared_invite/zt-2u2ey8ilu-LRxnd3PSoAk9GZ94UuzoBA) in the #terraform + channel +- Feel free to create issues and contribute PRs in the Temporal Terraform + [GitHub repository](https://github.com/temporalio/terraform-provider-temporalcloud/tree/main) diff --git a/docs/references/client-envrionment-configuration.mdx b/docs/references/client-envrionment-configuration.mdx new file mode 100644 index 0000000000..e292ae826f --- /dev/null +++ b/docs/references/client-envrionment-configuration.mdx @@ -0,0 +1,34 @@ +--- +id: client-environment-configuration +title: Environment Configuration +sidebar_label: Environment Configuration +description: Reference for configuring Temporal Clients using environment variables and TOML configuration files. +tags: + - Temporal Client + - Configuration + - Environment Variables + - TOML +--- + +The following table details all available settings, their corresponding environment variables, and their TOML file +paths. For more information on using environment variables and configuration files to set up your Temporal Client, refer +to the [Environment Configuration](/develop/environment-configuration). + +| Setting | Environment Variable | TOML Path | Description | +| :------------------------ | :--------------------------------------- | :--------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Configuration File Path | `TEMPORAL_CONFIG_FILE` | **NA** | Path to the TOML configuration file | +| Server Address | `TEMPORAL_ADDRESS` | `profile..address` | The host and port of the Temporal Frontend service (e.g., "localhost:7233"). | +| Namespace | `TEMPORAL_NAMESPACE` | `profile..namespace` | The Temporal Namespace to connect to. | +| API Key | `TEMPORAL_API_KEY` | `profile..api_key` | An API key for authentication. If present, TLS is enabled by default. | +| Enable/Disable TLS | `TEMPORAL_TLS` | `profile..tls.disabled` | Set to "true" to enable TLS, "false" to disable. In TOML, disabled = true turns TLS off. | +| Client Certificate | `TEMPORAL_TLS_CLIENT_CERT_DATA` | `profile..tls.client_cert_data` | The raw PEM data containing the client's public TLS certificate. Alternatively, you can use `TEMPORAL_TLS_CLIENT_CERT_PATH` to provide a path to the certificate or the TOML `profile..tls.client_cert_path`. | +| Client Certificate Path | `TEMPORAL_TLS_CLIENT_CERT_PATH` | `profile..tls.client_cert_path` | A filesystem path to the client's public TLS certificate. Alternatively, you can provide the raw PEM data using `TEMPORAL_TLS_CLIENT_CERT_DATA` or the TOML `profile..tls.client_cert_data`. | +| Client Key | `TEMPORAL_TLS_CLIENT_KEY_DATA` | `profile..tls.client_key_data` | The raw PEM data containing the client's private TLS key. Alternatively, you can use `TEMPORAL_TLS_CLIENT_KEY_PATH` to provide a path to the key or the TOML `profile..tls.client_key_path`. | +| Client Key Path | `TEMPORAL_TLS_CLIENT_KEY_PATH` | `profile..tls.client_key_path` | A filesystem path to the client's private TLS key. Alternatively, you can provide the raw PEM data using `TEMPORAL_TLS_CLIENT_KEY_DATA` or the TOML `profile..tls.client_key_data`. | +| Server CA Cert | `TEMPORAL_TLS_SERVER_CA_CERT_DATA` | `profile..tls.server_ca_cert_data` | The raw PEM data for the Certificate Authority certificate used to verify the server. Alternatively, you can use `TEMPORAL_TLS_SERVER_CA_CERT_PATH` to provide a path or the TOML `profile..tls.server_ca_cert_path`. | +| Server CA Cert Path | `TEMPORAL_TLS_SERVER_CA_CERT_PATH` | `profile..tls.server_ca_cert_path` | A filesystem path to the Certificate Authority certificate. Alternatively, you can provide the raw PEM data using `TEMPORAL_TLS_SERVER_CA_CERT_DATA` or the TOML `profile..tls.server_ca_cert_data`. | +| TLS Server Name | `TEMPORAL_TLS_SERVER_NAME` | `profile..tls.server_name` | Overrides the server name used for Server Name Indication (SNI) in the TLS handshake. | +| Disable Host Verification | `TEMPORAL_TLS_DISABLE_HOST_VERIFICATION` | `profile..tls.disable_host_verification` | A boolean to disable server hostname verification. Use with caution. Not supported by all SDKs. | +| Codec Endpoint | `TEMPORAL_CODEC_ENDPOINT` | `profile..codec.endpoint` | The endpoint for a remote Data Converter. This is not supported by all SDKs. SDKs that support this configuration don't apply it by default. Intended mostly for CLI use. | +| Codec Auth | `TEMPORAL_CODEC_AUTH` | `profile..codec.auth` | The authorization header value for the remote data converter. | +| gRPC Metadata | `TEMPORAL_GRPC_META_*` | `profile..grpc_meta` | Sets gRPC headers. The part after `_META_` becomes the header key (e.g., `_SOME_KEY` -> `some-key`). | diff --git a/docs/references/index.mdx b/docs/references/index.mdx index de56321415..0c9eba4556 100644 --- a/docs/references/index.mdx +++ b/docs/references/index.mdx @@ -2,7 +2,9 @@ id: index title: Temporal Platform references sidebar_label: References -description: Explore comprehensive references for SDK Metrics, Commands, Events, Web UI environmental variables, Temporal Service and Web UI configurations, and API guides for Go, Java, Python, TypeScript, .NET, and PHP. +description: + Explore comprehensive references for SDK Metrics, Commands, Events, Web UI environment variables, Temporal Service and + Web UI configurations, and API guides for Go, Java, Python, TypeScript, .NET, and PHP. tags: - Reference --- @@ -10,7 +12,7 @@ tags: - [SDK metrics reference](/references/sdk-metrics) - [Commands reference](/references/commands) - [Events reference](/references/events) -- [Web UI environmental variables reference](/references/web-ui-environment-variables) +- [Web UI environment variables reference](/references/web-ui-environment-variables) - [Temporal Service configuration reference](/references/configuration) - [Temporal Web UI configuration reference](/references/web-ui-configuration) - [Temporal Cloud Operation reference](/references/operation-list) diff --git a/docs/references/web-ui-environment-variables.mdx b/docs/references/web-ui-environment-variables.mdx index fbf99a5350..677d2d0c01 100644 --- a/docs/references/web-ui-environment-variables.mdx +++ b/docs/references/web-ui-environment-variables.mdx @@ -2,7 +2,9 @@ id: web-ui-environment-variables title: Temporal Web UI environment variables reference sidebar_label: Web UI env vars -description: Dynamically configure Temporal Web UI with environment variables in Docker for settings like TEMPORAL_ADDRESS, authentication, TLS, OpenAPI, and more. +description: + Dynamically configure Temporal Web UI with environment variables in Docker for settings like TEMPORAL_ADDRESS, + authentication, TLS, OpenAPI, and more. toc_max_heading_level: 4 keywords: - docker @@ -16,8 +18,7 @@ tags: You can use environment variables to dynamically alter the configuration of your Temporal Web UI. -These can be used in many environments, such as with Docker. -For example: +These can be used in many environments, such as with Docker. For example: ``` docker run\ @@ -53,14 +54,17 @@ docker run\ temporalio/ui: ``` -The environment variables are defined in the [UI server configuration template file](https://github.com/temporalio/ui-server/blob/main/docker/config-template.yaml) and described in more detail below. +The environment variables are defined in the +[UI server configuration template file](https://github.com/temporalio/ui-server/blob/main/config/docker.yaml) +and described in more detail below. ## `TEMPORAL_ADDRESS` -The [Frontend Service](/temporal-service/temporal-server#frontend-service) address for the Temporal Cluster. -This environmental variable can be set [in the base configuration file](/references/web-ui-configuration#temporalgrpcaddress) using `temporalGrpcAddress`. +The [Frontend Service](/temporal-service/temporal-server#frontend-service) address for the Temporal Cluster. This +variable can be set [in the base configuration file](/references/web-ui-configuration#temporalgrpcaddress) using +`temporalGrpcAddress`. -This variable is required for setting other environmental variables. +This variable is required for setting other environment variables. ## `TEMPORAL_UI_PORT` @@ -76,8 +80,8 @@ Stores a value such as "" or "/custom-path" that allows the UI to be served from Enables or disables the [browser UI](/references/web-ui-configuration#enableui) for the Temporal Cluster. -Enabling the browser UI allows the Server to be accessed from your web browser. -If disabled, the server cannot be viewed on the web, but the UI server APIs remain available for use. +Enabling the browser UI allows the Server to be accessed from your web browser. If disabled, the server cannot be viewed +on the web, but the UI server APIs remain available for use. ## `TEMPORAL_BANNER_TEXT` @@ -117,10 +121,11 @@ Disables any button in the UI that allows the user to modify Workflows or Activi Enables or disables Web UI authentication and authorization methods. -When enabled, the Web UI will use the provider information in the [UI configuration file](/references/web-ui-configuration#auth) to verify the identity of users. +When enabled, the Web UI will use the provider information in the +[UI configuration file](/references/web-ui-configuration#auth) to verify the identity of users. -All auth-related variables can be defined when `TEMPORAL_AUTH_ENABLED` is set to "true". -Disabling the variable will retain given values. +All auth-related variables can be defined when `TEMPORAL_AUTH_ENABLED` is set to "true". Disabling the variable will +retain given values. ## `TEMPORAL_AUTH_TYPE` @@ -164,22 +169,22 @@ Specifies a set of scopes for auth. Typically, this is `openid`, `profile`, `ema The path for the Transport Layer Security (TLS) Certificate Authority file. -In order to [configure TLS for your server](/references/web-ui-configuration#tls), you'll need a CA certificate issued by a trusted Certificate Authority. -Set this variable to properly locate and use the file. +In order to [configure TLS for your server](/references/web-ui-configuration#tls), you'll need a CA certificate issued +by a trusted Certificate Authority. Set this variable to properly locate and use the file. ## `TEMPORAL_TLS_CERT` The path for the Transport Layer Security (TLS) Certificate. -In order to [configure TLS for your server](/references/web-ui-configuration#tls), you'll need a self-signed certificate. -Set the path to allow the environment to locate and use the certificate. +In order to [configure TLS for your server](/references/web-ui-configuration#tls), you'll need a self-signed +certificate. Set the path to allow the environment to locate and use the certificate. ## `TEMPORAL_TLS_KEY` The path for the Transport Layer Security (TLS) [key file](/references/web-ui-configuration#tls). -A key file is used to create private and public keys for encryption and signing. -Together, these keys are used to create certificates. +A key file is used to create private and public keys for encryption and signing. Together, these keys are used to create +certificates. ## `TEMPORAL_TLS_CA_DATA` @@ -209,8 +214,8 @@ When enabled, TLS checks the Host Server to ensure that files are being sent to The server on which to operate [Transport Layer Security (TLS) protocols](/references/web-ui-configuration#tls). -TLS allows the current server to transmit encrypted files to other URLs without having to reveal itself. -Because of this, TLS operates a go-between server. +TLS allows the current server to transmit encrypted files to other URLs without having to reveal itself. Because of +this, TLS operates a go-between server. ## `TEMPORAL_CODEC_ENDPOINT` diff --git a/docusaurus.config.js b/docusaurus.config.js index 687a3d25f7..c729e49c00 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -49,7 +49,7 @@ module.exports = async function createConfigAsync() { prism: { //theme: require("prism-react-renderer/themes/nightOwlLight"), // darkTheme: require("prism-react-renderer/themes/dracula"), - additionalLanguages: ['java', 'ruby', 'php', 'csharp'], + additionalLanguages: ['java', 'ruby', 'php', 'csharp', 'toml', 'bash'], }, docs: { sidebar: { @@ -287,15 +287,15 @@ module.exports = async function createConfigAsync() { defer: true, }, { - src: "https://widget.kapa.ai/kapa-widget.bundle.js", - "data-button-hide": "true", - "data-website-id": "91a88508-9cdc-441f-b1df-37aa9329e6bc", - "data-project-name": "Temporal", - "data-project-color": "#000000", - "data-project-logo": "https://avatars.githubusercontent.com/u/56493103?s=280&v=4", - "data-modal-title": "Temporal's AI developer assistant", - "data-user-analytics-fingerprint-enabled": true, - "data-modal-disclaimer": + src: 'https://widget.kapa.ai/kapa-widget.bundle.js', + 'data-button-hide': 'true', + 'data-website-id': '91a88508-9cdc-441f-b1df-37aa9329e6bc', + 'data-project-name': 'Temporal', + 'data-project-color': '#000000', + 'data-project-logo': 'https://avatars.githubusercontent.com/u/56493103?s=280&v=4', + 'data-modal-title': "Temporal's AI developer assistant", + 'data-user-analytics-fingerprint-enabled': true, + 'data-modal-disclaimer': "I am Temporal's AI developer assistant. I can access developer docs, forum posts, product blogs, and SDK references. Responses are generated by combining various sources to provide the best possible answer, however I may not be fully accurate, so please use your best judgement. If you have feedback please give a thumbs up or down as I continue to improve.", 'data-modal-example-questions': [ 'What is Temporal?', @@ -350,7 +350,7 @@ module.exports = async function createConfigAsync() { sidebarPath: false, // no left nav for these pages ✅ // optional polish: showLastUpdateAuthor: true, - showLastUpdateTime: true, + showLastUpdateTime: true, // use a custom item to center the content: docItemComponent: '@site/src/components/CookbookDocItem', docCategoryGeneratedIndexComponent: '@site/src/components/CookbookCategoryIndex', // ⬅️ isolated override diff --git a/sample-apps/java/client/cloudserver-client-sample/README.md b/sample-apps/java/client/cloudserver-client-sample/README.md index 3cdc0c1ccd..6116d24d0c 100644 --- a/sample-apps/java/client/cloudserver-client-sample/README.md +++ b/sample-apps/java/client/cloudserver-client-sample/README.md @@ -1,5 +1,7 @@ # Client Sample Project: Configuring a Client for Temporal Cloud -This project demonstrates how to access a Temporal Service running on Temporal Cloud using the Temporal Client provided by the Java SDK. + +This project demonstrates how to access a Temporal Service running on Temporal Cloud using the Temporal Client provided +by the Java SDK. ## Configuring Clients @@ -9,22 +11,21 @@ The WorkflowServiceStubs instance represents a connection to the Temporal Servic WorkflowServiceStubs serviceStub = WorkflowServiceStubs.newServiceStubs(stubsOptions); ``` - The two source files that configure instances of Workflow Clients are located at: -* **Worker**: src/main/java/clientsample/YourWorker.java. - The Worker uses its client to poll the Task Queue for tasks, and to initiate their execution. -* **Caller**: src/main/java/clientsample/YourCallerApp.java. - The Caller uses its client to establish a "stub" (unique to the JavaSDK) and invoke a new Workflow Execution. +- **Worker**: src/main/java/clientsample/YourWorker.java. The Worker uses its client to poll the Task Queue for tasks, + and to initiate their execution. +- **Caller**: src/main/java/clientsample/YourCallerApp.java. The Caller uses its client to establish a "stub" (unique to + the JavaSDK) and invoke a new Workflow Execution. -## Setting up Environmental Variables +## Setting up Environment Variables -You will need to set up the following Environmental Variables to use this sample. +You will need to set up the following environment variables to use this sample. -* **TEMPORAL\_CLOUD\_NAMESPACE**: Copy the full Namespace Id from the Cloud Namespace details page. -* **TEMPORAL\_CLOUD\_GRPC\_ENDPOINT**: Copy the gRPC endpoint from the Cloud Namespace details page. -* **TEMPORAL\_MTLS\_PRIVATE\_KEY\_PATH**: The path to the file with your mTLS private key. -* **TEMPORAL\_MTLS\_CERT\_PATH**: The path to the .pem file with your mTLS x509 Certificate. +- **TEMPORAL_CLOUD_NAMESPACE**: Copy the full Namespace Id from the Cloud Namespace details page. +- **TEMPORAL_CLOUD_GRPC_ENDPOINT**: Copy the gRPC endpoint from the Cloud Namespace details page. +- **TEMPORAL_MTLS_PRIVATE_KEY_PATH**: The path to the file with your mTLS private key. +- **TEMPORAL_MTLS_CERT_PATH**: The path to the .pem file with your mTLS x509 Certificate. ## Building and Executing diff --git a/sidebars.js b/sidebars.js index bedf427a9b..ed1a0b14d0 100644 --- a/sidebars.js +++ b/sidebars.js @@ -1,861 +1,859 @@ module.exports = { documentation: [ - "index", - "quickstarts", + 'index', + 'quickstarts', { - type: "link", - label: "Courses and Tutorials", - href: "https://learn.temporal.io/", + type: 'link', + label: 'Courses and Tutorials', + href: 'https://learn.temporal.io/', }, { - type: "category", - label: "Evaluate", + type: 'category', + label: 'Evaluate', collapsed: false, link: { - type: "doc", - id: "evaluate/index", + type: 'doc', + id: 'evaluate/index', }, items: [ - "evaluate/why-temporal", - "evaluate/understanding-temporal", + 'evaluate/why-temporal', + 'evaluate/understanding-temporal', { - type: "category", - label: "Features", + type: 'category', + label: 'Features', collapsed: true, link: { - type: "doc", - id: "evaluate/development-production-features/index", + type: 'doc', + id: 'evaluate/development-production-features/index', }, items: [ - "evaluate/development-production-features/core-application", - "evaluate/development-production-features/failure-detection", - "evaluate/development-production-features/throughput-composability", - "evaluate/development-production-features/nexus", - "evaluate/development-production-features/workflow-message-passing", - "evaluate/development-production-features/debugging", - "evaluate/development-production-features/interrupt-workflow", - "evaluate/development-production-features/testing-suite", - "evaluate/development-production-features/observability", - "evaluate/development-production-features/data-encryption", - "evaluate/development-production-features/schedules", - "evaluate/development-production-features/cloud-automation", - "evaluate/development-production-features/low-latency", - "evaluate/development-production-features/multi-tenancy", + 'evaluate/development-production-features/core-application', + 'evaluate/development-production-features/failure-detection', + 'evaluate/development-production-features/throughput-composability', + 'evaluate/development-production-features/nexus', + 'evaluate/development-production-features/workflow-message-passing', + 'evaluate/development-production-features/debugging', + 'evaluate/development-production-features/interrupt-workflow', + 'evaluate/development-production-features/testing-suite', + 'evaluate/development-production-features/observability', + 'evaluate/development-production-features/data-encryption', + 'evaluate/development-production-features/schedules', + 'evaluate/development-production-features/cloud-automation', + 'evaluate/development-production-features/low-latency', + 'evaluate/development-production-features/multi-tenancy', { - type: "category", - label: "Product release stages", + type: 'category', + label: 'Product release stages', collapsed: true, link: { - type: "doc", - id: "evaluate/development-production-features/release-stages", + type: 'doc', + id: 'evaluate/development-production-features/release-stages', }, items: [ { - type: "link", - label: "Change-log", - href: "https://temporal.io/change-log", + type: 'link', + label: 'Change-log', + href: 'https://temporal.io/change-log', }, ], }, ], }, { - type: "category", - label: "Temporal Cloud", + type: 'category', + label: 'Temporal Cloud', collapsed: true, link: { - type: "doc", - id: "evaluate/temporal-cloud/index", + type: 'doc', + id: 'evaluate/temporal-cloud/index', }, items: [ - "evaluate/temporal-cloud/overview", - "evaluate/temporal-cloud/security", - "evaluate/temporal-cloud/service-availability", - "evaluate/temporal-cloud/regions", - "evaluate/temporal-cloud/limits", - "evaluate/temporal-cloud/sla", - "evaluate/temporal-cloud/pricing", - "evaluate/temporal-cloud/actions", - "evaluate/temporal-cloud/support", + 'evaluate/temporal-cloud/overview', + 'evaluate/temporal-cloud/security', + 'evaluate/temporal-cloud/service-availability', + 'evaluate/temporal-cloud/regions', + 'evaluate/temporal-cloud/limits', + 'evaluate/temporal-cloud/sla', + 'evaluate/temporal-cloud/pricing', + 'evaluate/temporal-cloud/actions', + 'evaluate/temporal-cloud/support', ], }, - "security", - "evaluate/use-cases-design-patterns", + 'security', + 'evaluate/use-cases-design-patterns', ], }, { - type: "category", - label: "Develop", + type: 'category', + label: 'Develop', collapsed: false, link: { - type: "doc", - id: "develop/index", + type: 'doc', + id: 'develop/index', }, items: [ { - type: "category", - label: "Go SDK", + type: 'category', + label: 'Go SDK', collapsed: true, link: { - type: "doc", - id: "develop/go/index", + type: 'doc', + id: 'develop/go/index', }, items: [ - "develop/go/set-up-your-local-go", - "develop/go/core-application", - "develop/go/temporal-client", - "develop/go/go-sdk-multithreading", - "develop/go/namespaces", - "develop/go/testing-suite", - "develop/go/failure-detection", - "develop/go/message-passing", - "develop/go/cancellation", - "develop/go/asynchronous-activity-completion", - "develop/go/versioning", - "develop/go/observability", - "develop/go/enriching-ui", - "develop/go/debugging", - "develop/go/schedules", - "develop/go/converters-and-encryption", - "develop/go/timers", - "develop/go/nexus", - "develop/go/child-workflows", - "develop/go/continue-as-new", - "develop/go/side-effects", - "develop/go/selectors", - "develop/go/sessions", + 'develop/go/set-up-your-local-go', + 'develop/go/core-application', + 'develop/go/temporal-client', + 'develop/go/go-sdk-multithreading', + 'develop/go/namespaces', + 'develop/go/testing-suite', + 'develop/go/failure-detection', + 'develop/go/message-passing', + 'develop/go/cancellation', + 'develop/go/asynchronous-activity-completion', + 'develop/go/versioning', + 'develop/go/observability', + 'develop/go/enriching-ui', + 'develop/go/debugging', + 'develop/go/schedules', + 'develop/go/converters-and-encryption', + 'develop/go/timers', + 'develop/go/nexus', + 'develop/go/child-workflows', + 'develop/go/continue-as-new', + 'develop/go/side-effects', + 'develop/go/selectors', + 'develop/go/sessions', ], }, { - type: "category", - label: "Java SDK", + type: 'category', + label: 'Java SDK', collapsed: true, link: { - type: "doc", - id: "develop/java/index", + type: 'doc', + id: 'develop/java/index', }, items: [ - "develop/java/set-up-your-local-java", - "develop/java/core-application", - "develop/java/temporal-client", - "develop/java/namespaces", - "develop/java/testing-suite", - "develop/java/failure-detection", - "develop/java/message-passing", - "develop/java/cancellation", - "develop/java/asynchronous-activity-completion", - "develop/java/versioning", - "develop/java/observability", - "develop/java/enriching-ui", - "develop/java/debugging", - "develop/java/schedules", - "develop/java/converters-and-encryption", - "develop/java/timers", - "develop/java/nexus", - "develop/java/child-workflows", - "develop/java/continue-as-new", - "develop/java/side-effects", - "develop/java/spring-boot-integration", + 'develop/java/set-up-your-local-java', + 'develop/java/core-application', + 'develop/java/temporal-client', + 'develop/java/namespaces', + 'develop/java/testing-suite', + 'develop/java/failure-detection', + 'develop/java/message-passing', + 'develop/java/cancellation', + 'develop/java/asynchronous-activity-completion', + 'develop/java/versioning', + 'develop/java/observability', + 'develop/java/enriching-ui', + 'develop/java/debugging', + 'develop/java/schedules', + 'develop/java/converters-and-encryption', + 'develop/java/timers', + 'develop/java/nexus', + 'develop/java/child-workflows', + 'develop/java/continue-as-new', + 'develop/java/side-effects', + 'develop/java/spring-boot-integration', ], }, { - type: "category", - label: "PHP SDK", + type: 'category', + label: 'PHP SDK', collapsed: true, link: { - type: "doc", - id: "develop/php/index", + type: 'doc', + id: 'develop/php/index', }, items: [ - "develop/php/core-application", - "develop/php/temporal-client", - "develop/php/testing-suite", - "develop/php/failure-detection", - "develop/php/message-passing", - "develop/php/cancellation", - "develop/php/asynchronous-activity-completion", - "develop/php/versioning", - "develop/php/observability", - "develop/php/enriching-ui", - "develop/php/debugging", - "develop/php/schedules", - "develop/php/timers", - "develop/php/side-effects", - "develop/php/child-workflows", - "develop/php/continue-as-new", + 'develop/php/core-application', + 'develop/php/temporal-client', + 'develop/php/testing-suite', + 'develop/php/failure-detection', + 'develop/php/message-passing', + 'develop/php/cancellation', + 'develop/php/asynchronous-activity-completion', + 'develop/php/versioning', + 'develop/php/observability', + 'develop/php/enriching-ui', + 'develop/php/debugging', + 'develop/php/schedules', + 'develop/php/timers', + 'develop/php/side-effects', + 'develop/php/child-workflows', + 'develop/php/continue-as-new', ], }, { - type: "category", - label: "Python SDK", + type: 'category', + label: 'Python SDK', collapsed: true, link: { - type: "doc", - id: "develop/python/index", + type: 'doc', + id: 'develop/python/index', }, items: [ - "develop/python/set-up-your-local-python", - "develop/python/core-application", - "develop/python/temporal-client", - "develop/python/python-sdk-sandbox", - "develop/python/python-sdk-sync-vs-async", - "develop/python/testing-suite", - "develop/python/failure-detection", - "develop/python/message-passing", - "develop/python/cancellation", - "develop/python/asynchronous-activity-completion", - "develop/python/versioning", - "develop/python/observability", - "develop/python/enriching-ui", - "develop/python/debugging", - "develop/python/schedules", - "develop/python/converters-and-encryption", - "develop/python/timers", - "develop/python/nexus", - "develop/python/child-workflows", - "develop/python/continue-as-new", - "develop/python/interceptors", + 'develop/python/set-up-your-local-python', + 'develop/python/core-application', + 'develop/python/temporal-client', + 'develop/python/python-sdk-sandbox', + 'develop/python/python-sdk-sync-vs-async', + 'develop/python/testing-suite', + 'develop/python/failure-detection', + 'develop/python/message-passing', + 'develop/python/cancellation', + 'develop/python/asynchronous-activity-completion', + 'develop/python/versioning', + 'develop/python/observability', + 'develop/python/enriching-ui', + 'develop/python/debugging', + 'develop/python/schedules', + 'develop/python/converters-and-encryption', + 'develop/python/timers', + 'develop/python/nexus', + 'develop/python/child-workflows', + 'develop/python/continue-as-new', + 'develop/python/interceptors', ], }, { - type: "category", - label: "TypeScript SDK", + type: 'category', + label: 'TypeScript SDK', collapsed: true, link: { - type: "doc", - id: "develop/typescript/index", + type: 'doc', + id: 'develop/typescript/index', }, items: [ - "develop/typescript/set-up-your-local-typescript", - "develop/typescript/core-application", - "develop/typescript/temporal-client", - "develop/typescript/namespaces", - "develop/typescript/testing-suite", - "develop/typescript/failure-detection", - "develop/typescript/message-passing", - "develop/typescript/cancellation", - "develop/typescript/asynchronous-activity-completion", - "develop/typescript/versioning", - "develop/typescript/observability", - "develop/typescript/enriching-ui", - "develop/typescript/debugging", - "develop/typescript/schedules", - "develop/typescript/converters-and-encryption", - "develop/typescript/timers", - "develop/typescript/nexus", - "develop/typescript/child-workflows", - "develop/typescript/continue-as-new", - "develop/typescript/interceptors", + 'develop/typescript/set-up-your-local-typescript', + 'develop/typescript/core-application', + 'develop/typescript/temporal-client', + 'develop/typescript/namespaces', + 'develop/typescript/testing-suite', + 'develop/typescript/failure-detection', + 'develop/typescript/message-passing', + 'develop/typescript/cancellation', + 'develop/typescript/asynchronous-activity-completion', + 'develop/typescript/versioning', + 'develop/typescript/observability', + 'develop/typescript/enriching-ui', + 'develop/typescript/debugging', + 'develop/typescript/schedules', + 'develop/typescript/converters-and-encryption', + 'develop/typescript/timers', + 'develop/typescript/nexus', + 'develop/typescript/child-workflows', + 'develop/typescript/continue-as-new', + 'develop/typescript/interceptors', ], }, { - type: "category", - label: ".NET SDK", + type: 'category', + label: '.NET SDK', collapsed: true, link: { - type: "doc", - id: "develop/dotnet/index", + type: 'doc', + id: 'develop/dotnet/index', }, items: [ - "develop/dotnet/set-up-your-local-dotnet", - "develop/dotnet/core-application", - "develop/dotnet/temporal-client", - "develop/dotnet/testing-suite", - "develop/dotnet/failure-detection", - "develop/dotnet/message-passing", - "develop/dotnet/cancellation", - "develop/dotnet/asynchronous-activity", - "develop/dotnet/versioning", - "develop/dotnet/observability", - "develop/dotnet/enriching-ui", - "develop/dotnet/debugging", - "develop/dotnet/schedules", - "develop/dotnet/converters-and-encryption", - "develop/dotnet/durable-timers", - "develop/dotnet/nexus", - "develop/dotnet/child-workflows", - "develop/dotnet/continue-as-new", + 'develop/dotnet/set-up-your-local-dotnet', + 'develop/dotnet/core-application', + 'develop/dotnet/temporal-client', + 'develop/dotnet/testing-suite', + 'develop/dotnet/failure-detection', + 'develop/dotnet/message-passing', + 'develop/dotnet/cancellation', + 'develop/dotnet/asynchronous-activity', + 'develop/dotnet/versioning', + 'develop/dotnet/observability', + 'develop/dotnet/enriching-ui', + 'develop/dotnet/debugging', + 'develop/dotnet/schedules', + 'develop/dotnet/converters-and-encryption', + 'develop/dotnet/durable-timers', + 'develop/dotnet/nexus', + 'develop/dotnet/child-workflows', + 'develop/dotnet/continue-as-new', ], }, { - type: "category", - label: "Ruby SDK", + type: 'category', + label: 'Ruby SDK', collapsed: true, link: { - type: "doc", - id: "develop/ruby/index", + type: 'doc', + id: 'develop/ruby/index', }, items: [ - "develop/ruby/set-up-local-ruby", - "develop/ruby/core-application", - "develop/ruby/temporal-client", - "develop/ruby/testing-suite", - "develop/ruby/failure-detection", - "develop/ruby/message-passing", - "develop/ruby/interrupt-workflow", - "develop/ruby/asynchronous-activity", - "develop/ruby/versioning", - "develop/ruby/observability", - "develop/ruby/enriching-ui", - "develop/ruby/debugging", - "develop/ruby/schedules", - "develop/ruby/converters-and-encryption", - "develop/ruby/durable-timers", - "develop/ruby/child-workflows", - "develop/ruby/continue-as-new", + 'develop/ruby/set-up-local-ruby', + 'develop/ruby/core-application', + 'develop/ruby/temporal-client', + 'develop/ruby/testing-suite', + 'develop/ruby/failure-detection', + 'develop/ruby/message-passing', + 'develop/ruby/interrupt-workflow', + 'develop/ruby/asynchronous-activity', + 'develop/ruby/versioning', + 'develop/ruby/observability', + 'develop/ruby/enriching-ui', + 'develop/ruby/debugging', + 'develop/ruby/schedules', + 'develop/ruby/converters-and-encryption', + 'develop/ruby/durable-timers', + 'develop/ruby/child-workflows', + 'develop/ruby/continue-as-new', ], }, - "develop/environment-configuration", - "develop/activity-retry-simulator", - "develop/worker-performance", - "develop/safe-deployments", + 'develop/environment-configuration', + 'develop/activity-retry-simulator', + 'develop/worker-performance', + 'develop/safe-deployments', ], }, { - type: "category", - label: "Deploy to production", + type: 'category', + label: 'Deploy to production', collapsed: false, link: { - type: "doc", - id: "production-deployment/index", + type: 'doc', + id: 'production-deployment/index', }, items: [ { - type: "category", - label: "Temporal Cloud", + type: 'category', + label: 'Temporal Cloud', collapsed: true, link: { - type: "doc", - id: "production-deployment/cloud/index", + type: 'doc', + id: 'production-deployment/cloud/index', }, items: [ { - type: "category", - label: "Get started with Cloud", + type: 'category', + label: 'Get started with Cloud', collapsed: false, link: { - type: "doc", - id: "production-deployment/cloud/get-started/index", + type: 'doc', + id: 'production-deployment/cloud/get-started/index', }, items: [ - "production-deployment/cloud/get-started/namespaces", - "production-deployment/cloud/get-started/api-keys", - "production-deployment/cloud/get-started/certificates", - "production-deployment/cloud/get-started/billing-and-cost", + 'production-deployment/cloud/get-started/namespaces', + 'production-deployment/cloud/get-started/api-keys', + 'production-deployment/cloud/get-started/certificates', + 'production-deployment/cloud/get-started/billing-and-cost', ], }, { - type: "category", - label: "Account access", + type: 'category', + label: 'Account access', collapsed: false, link: { - type: "doc", - id: "production-deployment/cloud/manage-access/index", + type: 'doc', + id: 'production-deployment/cloud/manage-access/index', }, items: [ - "production-deployment/cloud/get-started/users", - "production-deployment/cloud/get-started/user-groups", - "production-deployment/cloud/get-started/service-accounts", - "production-deployment/cloud/saml", - "production-deployment/cloud/scim", + 'production-deployment/cloud/get-started/users', + 'production-deployment/cloud/get-started/user-groups', + 'production-deployment/cloud/get-started/service-accounts', + 'production-deployment/cloud/saml', + 'production-deployment/cloud/scim', ], }, { - type: "category", - label: "Metrics", + type: 'category', + label: 'Metrics', collapsed: true, link: { - type: "doc", - id: "production-deployment/cloud/metrics/index", + type: 'doc', + id: 'production-deployment/cloud/metrics/index', }, items: [ { - type: "category", - label: "OpenMetrics", + type: 'category', + label: 'OpenMetrics', collapsed: true, link: { - type: "doc", - id: "production-deployment/cloud/metrics/openmetrics/index", + type: 'doc', + id: 'production-deployment/cloud/metrics/openmetrics/index', }, items: [ - "production-deployment/cloud/metrics/openmetrics/metrics-integrations", - "production-deployment/cloud/metrics/openmetrics/migration-guide", - "production-deployment/cloud/metrics/openmetrics/api-reference", - "production-deployment/cloud/metrics/openmetrics/metrics-reference", + 'production-deployment/cloud/metrics/openmetrics/metrics-integrations', + 'production-deployment/cloud/metrics/openmetrics/migration-guide', + 'production-deployment/cloud/metrics/openmetrics/api-reference', + 'production-deployment/cloud/metrics/openmetrics/metrics-reference', ], }, { - type: "category", - label: "PromQL", + type: 'category', + label: 'PromQL', collapsed: true, link: { - type: "doc", - id: "production-deployment/cloud/metrics/promql", + type: 'doc', + id: 'production-deployment/cloud/metrics/promql', }, items: [ - "production-deployment/cloud/metrics/general-setup", - "production-deployment/cloud/metrics/reference", - "production-deployment/cloud/metrics/datadog", - "production-deployment/cloud/metrics/prometheus-grafana", + 'production-deployment/cloud/metrics/general-setup', + 'production-deployment/cloud/metrics/reference', + 'production-deployment/cloud/metrics/datadog', + 'production-deployment/cloud/metrics/prometheus-grafana', ], }, ], }, { - type: "category", - label: "Connectivity", + type: 'category', + label: 'Connectivity', collapsed: true, link: { - type: "doc", - id: "production-deployment/cloud/connectivity/index", + type: 'doc', + id: 'production-deployment/cloud/connectivity/index', }, items: [ - "production-deployment/cloud/connectivity/aws-connectivity", - "production-deployment/cloud/connectivity/gcp-connectivity", - "production-deployment/cloud/connectivity/ip-addresses", + 'production-deployment/cloud/connectivity/aws-connectivity', + 'production-deployment/cloud/connectivity/gcp-connectivity', + 'production-deployment/cloud/connectivity/ip-addresses', ], }, { - type: "category", - label: "High Availability", + type: 'category', + label: 'High Availability', collapsed: true, link: { - type: "doc", - id: "production-deployment/cloud/high-availability/index", + type: 'doc', + id: 'production-deployment/cloud/high-availability/index', }, items: [ - "production-deployment/cloud/high-availability/enable", - "production-deployment/cloud/high-availability/monitoring", - "production-deployment/cloud/high-availability/failovers", - "production-deployment/cloud/high-availability/ha-connectivity", + 'production-deployment/cloud/high-availability/enable', + 'production-deployment/cloud/high-availability/monitoring', + 'production-deployment/cloud/high-availability/failovers', + 'production-deployment/cloud/high-availability/ha-connectivity', ], }, - "production-deployment/cloud/rpo-rto", + 'production-deployment/cloud/rpo-rto', { - type: "category", - label: "Temporal Nexus", + type: 'category', + label: 'Temporal Nexus', collapsed: true, link: { - type: "doc", - id: "production-deployment/cloud/nexus/index", + type: 'doc', + id: 'production-deployment/cloud/nexus/index', }, items: [ - "production-deployment/cloud/nexus/security", - "production-deployment/cloud/nexus/observability", - "production-deployment/cloud/nexus/latency-availability", - "production-deployment/cloud/nexus/limits", - "production-deployment/cloud/nexus/pricing", + 'production-deployment/cloud/nexus/security', + 'production-deployment/cloud/nexus/observability', + 'production-deployment/cloud/nexus/latency-availability', + 'production-deployment/cloud/nexus/limits', + 'production-deployment/cloud/nexus/pricing', ], }, - "production-deployment/cloud/worker-health", - "production-deployment/cloud/service-health", - "production-deployment/cloud/operation-api", - "production-deployment/cloud/terraform-provider", + 'production-deployment/cloud/worker-health', + 'production-deployment/cloud/service-health', + 'production-deployment/cloud/operation-api', + 'production-deployment/cloud/terraform-provider', { - type: "category", - label: "Export", + type: 'category', + label: 'Export', collapsed: true, link: { - type: "doc", - id: "production-deployment/cloud/export", + type: 'doc', + id: 'production-deployment/cloud/export', }, - items: [ - "production-deployment/cloud/aws-export-s3", - "production-deployment/cloud/gcp-export-gcs", - ], + items: ['production-deployment/cloud/aws-export-s3', 'production-deployment/cloud/gcp-export-gcs'], }, { - type: "category", - label: "Audit Logging", + type: 'category', + label: 'Audit Logging', collapsed: true, link: { - type: "doc", - id: "production-deployment/cloud/audit-logging", + type: 'doc', + id: 'production-deployment/cloud/audit-logging', }, items: [ - "production-deployment/cloud/audit-logging-aws", - "production-deployment/cloud/audit-logging-gcp", // pre-release + 'production-deployment/cloud/audit-logging-aws', + 'production-deployment/cloud/audit-logging-gcp', // pre-release ], }, { - type: "category", - label: "CLI (tcld)", + type: 'category', + label: 'CLI (tcld)', collapsed: true, link: { - type: "doc", - id: "production-deployment/cloud/tcld/index", + type: 'doc', + id: 'production-deployment/cloud/tcld/index', }, items: [ - "production-deployment/cloud/tcld/account", - "production-deployment/cloud/tcld/apikey", - "production-deployment/cloud/tcld/feature", - "production-deployment/cloud/tcld/generate-certificates", - "production-deployment/cloud/tcld/login", - "production-deployment/cloud/tcld/logout", - "production-deployment/cloud/tcld/namespace", - "production-deployment/cloud/tcld/nexus", - "production-deployment/cloud/tcld/request", - "production-deployment/cloud/tcld/user", - "production-deployment/cloud/tcld/user-group", - "production-deployment/cloud/tcld/version", + 'production-deployment/cloud/tcld/account', + 'production-deployment/cloud/tcld/apikey', + 'production-deployment/cloud/tcld/feature', + 'production-deployment/cloud/tcld/generate-certificates', + 'production-deployment/cloud/tcld/login', + 'production-deployment/cloud/tcld/logout', + 'production-deployment/cloud/tcld/namespace', + 'production-deployment/cloud/tcld/nexus', + 'production-deployment/cloud/tcld/request', + 'production-deployment/cloud/tcld/user', + 'production-deployment/cloud/tcld/user-group', + 'production-deployment/cloud/tcld/version', ], }, { - type: "category", - label: "Migrate", + type: 'category', + label: 'Migrate', collapsed: true, link: { - type: "doc", - id: "production-deployment/cloud/migrate/index", + type: 'doc', + id: 'production-deployment/cloud/migrate/index', }, items: [ - "production-deployment/cloud/migrate/automated", - "production-deployment/cloud/migrate/manual", - "production-deployment/cloud/migrate/migrate-within-cloud" + 'production-deployment/cloud/migrate/automated', + 'production-deployment/cloud/migrate/manual', + 'production-deployment/cloud/migrate/migrate-within-cloud', ], }, ], }, - "production-deployment/data-encryption", + 'production-deployment/data-encryption', { - type: "category", - label: "Self-host", + type: 'category', + label: 'Self-host', collapsed: true, link: { - type: "doc", - id: "production-deployment/self-hosted-guide/index", + type: 'doc', + id: 'production-deployment/self-hosted-guide/index', }, items: [ - "production-deployment/self-hosted-guide/deployment", - "production-deployment/self-hosted-guide/checklist", - "production-deployment/self-hosted-guide/defaults", - "production-deployment/self-hosted-guide/security", - "production-deployment/self-hosted-guide/monitoring", - "production-deployment/self-hosted-guide/visibility", - "production-deployment/self-hosted-guide/upgrade-server", - "production-deployment/self-hosted-guide/archival", - "production-deployment/self-hosted-guide/multi-cluster-replication", - "production-deployment/self-hosted-guide/nexus", - "production-deployment/self-hosted-guide/server-frontend-api-reference", + 'production-deployment/self-hosted-guide/deployment', + 'production-deployment/self-hosted-guide/checklist', + 'production-deployment/self-hosted-guide/defaults', + 'production-deployment/self-hosted-guide/security', + 'production-deployment/self-hosted-guide/monitoring', + 'production-deployment/self-hosted-guide/visibility', + 'production-deployment/self-hosted-guide/upgrade-server', + 'production-deployment/self-hosted-guide/archival', + 'production-deployment/self-hosted-guide/multi-cluster-replication', + 'production-deployment/self-hosted-guide/nexus', + 'production-deployment/self-hosted-guide/server-frontend-api-reference', ], }, { - type: "category", - label: "Worker deployments", + type: 'category', + label: 'Worker deployments', collapsed: true, link: { - type: "doc", - id: "production-deployment/worker-deployments/index", + type: 'doc', + id: 'production-deployment/worker-deployments/index', }, items: [ - "production-deployment/worker-deployments/worker-versioning", - "production-deployment/worker-deployments/kubernetes-controller", - "production-deployment/worker-deployments/deploy-workers-to-aws-eks", + 'production-deployment/worker-deployments/worker-versioning', + 'production-deployment/worker-deployments/kubernetes-controller', + 'production-deployment/worker-deployments/deploy-workers-to-aws-eks', ], }, ], }, { - type: "category", - label: "CLI (temporal)", + type: 'category', + label: 'CLI (temporal)', collapsed: true, link: { - type: "doc", - id: "cli/index", + type: 'doc', + id: 'cli/index', }, items: [ - "cli/setup-cli", - "cli/activity", - "cli/batch", - "cli/cmd-options", - "cli/env", - "cli/operator", - "cli/schedule", - "cli/server", - "cli/task-queue", - "cli/worker", - "cli/workflow", + 'cli/setup-cli', + 'cli/activity', + 'cli/batch', + 'cli/cmd-options', + 'cli/config', + 'cli/env', + 'cli/operator', + 'cli/schedule', + 'cli/server', + 'cli/task-queue', + 'cli/worker', + 'cli/workflow', ], }, { - type: "category", - label: "References", + type: 'category', + label: 'References', collapsed: true, link: { - type: "doc", - id: "references/index", + type: 'doc', + id: 'references/index', }, items: [ - "references/cluster-metrics", - "references/commands", - "references/configuration", - "references/dynamic-configuration", - "references/errors", - "references/events", - "references/failures", - "references/operation-list", - "references/sdk-metrics", - "references/server-options", - "references/web-ui-configuration", - "references/web-ui-environment-variables", - + 'references/cluster-metrics', + 'references/commands', + 'references/configuration', + 'references/dynamic-configuration', + 'references/errors', + 'references/events', + 'references/failures', + 'references/operation-list', + 'references/sdk-metrics', + 'references/server-options', + 'references/client-environment-configuration', + 'references/web-ui-configuration', + 'references/web-ui-environment-variables', ], }, { - type: "category", - label: "Troubleshooting", + type: 'category', + label: 'Troubleshooting', collapsed: true, link: { - type: "doc", - id: "troubleshooting/index", + type: 'doc', + id: 'troubleshooting/index', }, items: [ - "troubleshooting/blob-size-limit-error", - "troubleshooting/deadline-exceeded-error", - "troubleshooting/last-connection-error", - "troubleshooting/performance-bottlenecks" + 'troubleshooting/blob-size-limit-error', + 'troubleshooting/deadline-exceeded-error', + 'troubleshooting/last-connection-error', + 'troubleshooting/performance-bottlenecks', ], }, { - type: "category", - label: "Best Practices", + type: 'category', + label: 'Best Practices', collapsed: true, link: { - type: "doc", - id: "best-practices/index", + type: 'doc', + id: 'best-practices/index', }, items: [ - "best-practices/managing-namespace", - "best-practices/cloud-access-control", - "best-practices/security-controls", + 'best-practices/managing-namespace', + 'best-practices/cloud-access-control', + 'best-practices/security-controls', ], }, { - type: "category", - label: "Encyclopedia", + type: 'category', + label: 'Encyclopedia', collapsed: true, link: { - type: "doc", - id: "encyclopedia/index", + type: 'doc', + id: 'encyclopedia/index', }, items: [ - "encyclopedia/temporal", - "encyclopedia/temporal-sdks", + 'encyclopedia/temporal', + 'encyclopedia/temporal-sdks', { - type: "category", - label: "Workflows", + type: 'category', + label: 'Workflows', collapsed: true, link: { - type: "doc", - id: "encyclopedia/workflow/workflow-overview", + type: 'doc', + id: 'encyclopedia/workflow/workflow-overview', }, items: [ - "encyclopedia/workflow/workflow-definition", + 'encyclopedia/workflow/workflow-definition', { - type: "category", - label: "Workflow Execution", + type: 'category', + label: 'Workflow Execution', collapsed: true, link: { - type: "doc", - id: "encyclopedia/workflow/workflow-execution/workflow-execution", + type: 'doc', + id: 'encyclopedia/workflow/workflow-execution/workflow-execution', }, items: [ - "encyclopedia/workflow/workflow-execution/workflowid-runid", - "encyclopedia/workflow/workflow-execution/event", - "encyclopedia/workflow/workflow-execution/continue-as-new", - "encyclopedia/workflow/workflow-execution/limits", - "encyclopedia/workflow/workflow-execution/timers-delays", + 'encyclopedia/workflow/workflow-execution/workflowid-runid', + 'encyclopedia/workflow/workflow-execution/event', + 'encyclopedia/workflow/workflow-execution/continue-as-new', + 'encyclopedia/workflow/workflow-execution/limits', + 'encyclopedia/workflow/workflow-execution/timers-delays', ], }, - "encyclopedia/workflow/dynamic-handler", - "encyclopedia/workflow/workflow-schedule", - "encyclopedia/workflow/cron-job", - "encyclopedia/workflow/patching", + 'encyclopedia/workflow/dynamic-handler', + 'encyclopedia/workflow/workflow-schedule', + 'encyclopedia/workflow/cron-job', + 'encyclopedia/workflow/patching', ], }, { - type: "category", - label: "Activities", + type: 'category', + label: 'Activities', collapsed: true, link: { - type: "doc", - id: "encyclopedia/activities/activities", + type: 'doc', + id: 'encyclopedia/activities/activities', }, items: [ - "encyclopedia/activities/activity-definition", - "encyclopedia/activities/activity-execution", - "encyclopedia/activities/local-activity", + 'encyclopedia/activities/activity-definition', + 'encyclopedia/activities/activity-execution', + 'encyclopedia/activities/local-activity', ], }, { - type: "category", - label: "Detecting application failures", + type: 'category', + label: 'Detecting application failures', collapsed: true, link: { - type: "doc", - id: "encyclopedia/detecting-application-failures", + type: 'doc', + id: 'encyclopedia/detecting-application-failures', }, items: [ - "encyclopedia/detecting-activity-failures", - "encyclopedia/detecting-workflow-failures", - "encyclopedia/retry-policies", + 'encyclopedia/detecting-activity-failures', + 'encyclopedia/detecting-workflow-failures', + 'encyclopedia/retry-policies', ], }, { - type: "category", - label: "Workers", + type: 'category', + label: 'Workers', collapsed: true, link: { - type: "doc", - id: "encyclopedia/workers/workers", + type: 'doc', + id: 'encyclopedia/workers/workers', }, items: [ - "encyclopedia/workers/tasks", - "encyclopedia/workers/task-queues", - "encyclopedia/workers/task-queue-naming", - "encyclopedia/workers/task-routing-worker-sessions", - "encyclopedia/workers/sticky-execution", - "encyclopedia/workers/worker-shutdown", - "encyclopedia/workers/worker-versioning", + 'encyclopedia/workers/tasks', + 'encyclopedia/workers/task-queues', + 'encyclopedia/workers/task-queue-naming', + 'encyclopedia/workers/task-routing-worker-sessions', + 'encyclopedia/workers/sticky-execution', + 'encyclopedia/workers/worker-shutdown', + 'encyclopedia/workers/worker-versioning', ], }, { - type: "category", - label: "Event History", + type: 'category', + label: 'Event History', collapsed: true, link: { - type: "doc", - id: "encyclopedia/event-history/event-history", + type: 'doc', + id: 'encyclopedia/event-history/event-history', }, items: [ - "encyclopedia/event-history/event-history-go", - "encyclopedia/event-history/event-history-dotnet", - "encyclopedia/event-history/event-history-java", - "encyclopedia/event-history/event-history-python", - "encyclopedia/event-history/event-history-typescript", + 'encyclopedia/event-history/event-history-go', + 'encyclopedia/event-history/event-history-dotnet', + 'encyclopedia/event-history/event-history-java', + 'encyclopedia/event-history/event-history-python', + 'encyclopedia/event-history/event-history-typescript', ], }, { - type: "category", - label: "Workflow Message Passing", + type: 'category', + label: 'Workflow Message Passing', collapsed: true, link: { - type: "doc", - id: "encyclopedia/workflow-message-passing/workflow-message-passing", + type: 'doc', + id: 'encyclopedia/workflow-message-passing/workflow-message-passing', }, items: [ - "encyclopedia/workflow-message-passing/sending-messages", - "encyclopedia/workflow-message-passing/handling-messages", + 'encyclopedia/workflow-message-passing/sending-messages', + 'encyclopedia/workflow-message-passing/handling-messages', ], }, { - type: "category", - label: "Child Workflows", + type: 'category', + label: 'Child Workflows', collapsed: true, link: { - type: "doc", - id: "encyclopedia/child-workflows/child-workflows", + type: 'doc', + id: 'encyclopedia/child-workflows/child-workflows', }, - items: ["encyclopedia/child-workflows/parent-close-policy"], + items: ['encyclopedia/child-workflows/parent-close-policy'], }, { - type: "category", - label: "Visibility", + type: 'category', + label: 'Visibility', collapsed: true, link: { - type: "doc", - id: "encyclopedia/visibility/visibility", + type: 'doc', + id: 'encyclopedia/visibility/visibility', }, items: [ - "encyclopedia/visibility/dual-visibility", - "encyclopedia/visibility/list-filter", - "encyclopedia/visibility/search-attribute", + 'encyclopedia/visibility/dual-visibility', + 'encyclopedia/visibility/list-filter', + 'encyclopedia/visibility/search-attribute', ], }, { - type: "category", - label: "Temporal Service", + type: 'category', + label: 'Temporal Service', collapsed: true, link: { - type: "doc", - id: "encyclopedia/temporal-service/temporal-service", + type: 'doc', + id: 'encyclopedia/temporal-service/temporal-service', }, items: [ - "encyclopedia/temporal-service/temporal-server", - "encyclopedia/temporal-service/persistence", - "encyclopedia/temporal-service/visibility", - "encyclopedia/temporal-service/archival", - "encyclopedia/temporal-service/temporal-service-configuration", - "encyclopedia/temporal-service/multi-cluster-replication", + 'encyclopedia/temporal-service/temporal-server', + 'encyclopedia/temporal-service/persistence', + 'encyclopedia/temporal-service/visibility', + 'encyclopedia/temporal-service/archival', + 'encyclopedia/temporal-service/temporal-service-configuration', + 'encyclopedia/temporal-service/multi-cluster-replication', ], }, { - type: "category", - label: "Namespaces", + type: 'category', + label: 'Namespaces', collapsed: true, link: { - type: "doc", - id: "encyclopedia/namespaces/namespaces", + type: 'doc', + id: 'encyclopedia/namespaces/namespaces', }, - items: ["encyclopedia/namespaces/global-namespaces"], + items: ['encyclopedia/namespaces/global-namespaces'], }, { - type: "category", - label: "Temporal Nexus", + type: 'category', + label: 'Temporal Nexus', collapsed: true, link: { - type: "doc", - id: "encyclopedia/nexus", + type: 'doc', + id: 'encyclopedia/nexus', }, items: [ - "encyclopedia/nexus-endpoints", - "encyclopedia/nexus-registry", - "encyclopedia/nexus-services", - "encyclopedia/nexus-operations", - "encyclopedia/nexus-use-cases", - "encyclopedia/nexus-execution-debugging", - "encyclopedia/nexus-error-handling", - "encyclopedia/nexus-metrics", - "encyclopedia/nexus-security", + 'encyclopedia/nexus-endpoints', + 'encyclopedia/nexus-registry', + 'encyclopedia/nexus-services', + 'encyclopedia/nexus-operations', + 'encyclopedia/nexus-use-cases', + 'encyclopedia/nexus-execution-debugging', + 'encyclopedia/nexus-error-handling', + 'encyclopedia/nexus-metrics', + 'encyclopedia/nexus-security', ], }, { - type: "category", - label: "Data Conversion", + type: 'category', + label: 'Data Conversion', collapsed: true, link: { - type: "doc", - id: "encyclopedia/data-conversion/dataconversion", + type: 'doc', + id: 'encyclopedia/data-conversion/dataconversion', }, items: [ - "encyclopedia/data-conversion/default-custom-data-converters", - "encyclopedia/data-conversion/payload-converter", - "encyclopedia/data-conversion/payload-codec", - "encyclopedia/data-conversion/failure-converter", - "encyclopedia/data-conversion/remote-data-encoding", - "encyclopedia/data-conversion/codec-server", - "encyclopedia/data-conversion/key-management", + 'encyclopedia/data-conversion/default-custom-data-converters', + 'encyclopedia/data-conversion/payload-converter', + 'encyclopedia/data-conversion/payload-codec', + 'encyclopedia/data-conversion/failure-converter', + 'encyclopedia/data-conversion/remote-data-encoding', + 'encyclopedia/data-conversion/codec-server', + 'encyclopedia/data-conversion/key-management', ], }, - "web-ui", + 'web-ui', ], }, - "glossary", + 'glossary', // { // type: "autogenerated", // dirName: "./dev-guide", // '.' means the current docs folder // }, ], tctl: [ - "tctl-v1/index", - "tctl-v1/activity", - "tctl-v1/admin", - "tctl-v1/batch", - "tctl-v1/cluster", - "tctl-v1/dataconverter", - "tctl-v1/namespace", - "tctl-v1/schedule", - "tctl-v1/taskqueue", - "tctl-v1/workflow", + 'tctl-v1/index', + 'tctl-v1/activity', + 'tctl-v1/admin', + 'tctl-v1/batch', + 'tctl-v1/cluster', + 'tctl-v1/dataconverter', + 'tctl-v1/namespace', + 'tctl-v1/schedule', + 'tctl-v1/taskqueue', + 'tctl-v1/workflow', ], }; diff --git a/src/components/elements/SdkTabs/index.js b/src/components/elements/SdkTabs/index.js index f00069b048..8c96491ec4 100644 --- a/src/components/elements/SdkTabs/index.js +++ b/src/components/elements/SdkTabs/index.js @@ -26,19 +26,25 @@ export const Ruby = ({ children }) => children; Ruby.displayName = 'rb'; // Main wrapper -const SdkTabs = ({ children }) => { +const SdkTabs = ({ children, hideUnsupportedLanguages = false }) => { const contentMap = {}; React.Children.forEach(children, (child) => { if (child?.type?.displayName) { const langKey = child.type.displayName.toLowerCase(); - contentMap[langKey] = child; + contentMap[langKey] = child.props?.children; } }); + const languagesToRender = hideUnsupportedLanguages + ? SDK_LANGUAGES.filter(({ key }) => contentMap[key]) + : SDK_LANGUAGES; + + const tabLanguages = languagesToRender.length > 0 ? languagesToRender : SDK_LANGUAGES; + return ( - {SDK_LANGUAGES.map(({ key, icon: Icon, label }) => ( + {tabLanguages.map(({ key, icon: Icon, label }) => ( }> {contentMap[key] || (
@@ -72,4 +78,4 @@ SdkTabs.DotNet.displayName = 'dotnet'; SdkTabs.Ruby = ({ children }) => children; SdkTabs.Ruby.displayName = 'rb'; -export default SdkTabs; \ No newline at end of file +export default SdkTabs; diff --git a/vale/styles/config/vocabularies/Temporal/accept.txt b/vale/styles/config/vocabularies/Temporal/accept.txt index 4b8333c5c3..f472d117f5 100644 --- a/vale/styles/config/vocabularies/Temporal/accept.txt +++ b/vale/styles/config/vocabularies/Temporal/accept.txt @@ -14,3 +14,4 @@ Namespace gRPC tctl SDKs +TOML \ No newline at end of file