Skip to content

Commit

Permalink
HTTP CONNECT proxy support (temporalio#501)
Browse files Browse the repository at this point in the history
  • Loading branch information
cretz authored Apr 5, 2024
1 parent 466da16 commit 1001653
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 6 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,4 @@ jobs:
python-repo-path: ${{github.event.pull_request.head.repo.full_name}}
version: ${{github.event.pull_request.head.ref}}
version-is-repo-ref: true
features-repo-ref: http-connect-proxy-python
6 changes: 4 additions & 2 deletions temporalio/bridge/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 10 additions & 1 deletion temporalio/bridge/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from dataclasses import dataclass
from datetime import timedelta
from typing import Mapping, Optional, Type, TypeVar
from typing import Mapping, Optional, Tuple, Type, TypeVar

import google.protobuf.message

Expand Down Expand Up @@ -46,6 +46,14 @@ class ClientKeepAliveConfig:
timeout_millis: int


@dataclass
class ClientHttpConnectProxyConfig:
"""Python representation of the Rust struct for configuring HTTP proxy."""

target_host: str
basic_auth: Optional[Tuple[str, str]]


@dataclass
class ClientConfig:
"""Python representation of the Rust struct for configuring the client."""
Expand All @@ -59,6 +67,7 @@ class ClientConfig:
keep_alive_config: Optional[ClientKeepAliveConfig]
client_name: str
client_version: str
http_connect_proxy_config: Optional[ClientHttpConnectProxyConfig]


@dataclass
Expand Down
2 changes: 1 addition & 1 deletion temporalio/bridge/sdk-core
19 changes: 18 additions & 1 deletion temporalio/bridge/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::time::Duration;
use temporal_client::{
ClientKeepAliveConfig as CoreClientKeepAliveConfig, ClientOptions, ClientOptionsBuilder,
ConfiguredClient, HealthService, OperatorService, RetryClient, RetryConfig,
TemporalServiceClientWithMetrics, TestService, TlsConfig, WorkflowService,
TemporalServiceClientWithMetrics, TestService, TlsConfig, WorkflowService, HttpConnectProxyOptions,
};
use tonic::metadata::MetadataKey;
use url::Url;
Expand Down Expand Up @@ -34,6 +34,7 @@ pub struct ClientConfig {
tls_config: Option<ClientTlsConfig>,
retry_config: Option<ClientRetryConfig>,
keep_alive_config: Option<ClientKeepAliveConfig>,
http_connect_proxy_config: Option<ClientHttpConnectProxyConfig>,
}

#[derive(FromPyObject)]
Expand All @@ -60,6 +61,12 @@ struct ClientKeepAliveConfig {
pub timeout_millis: u64,
}

#[derive(FromPyObject)]
struct ClientHttpConnectProxyConfig {
pub target_host: String,
pub basic_auth: Option<(String, String)>,
}

#[derive(FromPyObject)]
struct RpcCall {
rpc: String,
Expand Down Expand Up @@ -392,6 +399,7 @@ impl TryFrom<ClientConfig> for ClientOptions {
.map_or(RetryConfig::default(), |c| c.into()),
)
.keep_alive(opts.keep_alive_config.map(Into::into))
.http_connect_proxy(opts.http_connect_proxy_config.map(Into::into))
.headers(Some(opts.metadata))
.api_key(opts.api_key);
// Builder does not allow us to set option here, so we have to make
Expand Down Expand Up @@ -451,3 +459,12 @@ impl From<ClientKeepAliveConfig> for CoreClientKeepAliveConfig {
}
}
}

impl From<ClientHttpConnectProxyConfig> for HttpConnectProxyOptions {
fn from(conf: ClientHttpConnectProxyConfig) -> Self {
HttpConnectProxyOptions {
target_addr: conf.target_host,
basic_auth: conf.basic_auth,
}
}
}
4 changes: 4 additions & 0 deletions temporalio/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import temporalio.service
import temporalio.workflow
from temporalio.service import (
HttpConnectProxyConfig,
KeepAliveConfig,
RetryConfig,
RPCError,
Expand Down Expand Up @@ -110,6 +111,7 @@ async def connect(
identity: Optional[str] = None,
lazy: bool = False,
runtime: Optional[temporalio.runtime.Runtime] = None,
http_connect_proxy_config: Optional[HttpConnectProxyConfig] = None,
) -> Client:
"""Connect to a Temporal server.
Expand Down Expand Up @@ -153,6 +155,7 @@ async def connect(
attempted or a worker is created with it. Lazy clients cannot be
used for workers.
runtime: The runtime for this client, or the default if unset.
http_connect_proxy_config: Configuration for HTTP CONNECT proxy.
"""
connect_config = temporalio.service.ConnectConfig(
target_host=target_host,
Expand All @@ -164,6 +167,7 @@ async def connect(
identity=identity or "",
lazy=lazy,
runtime=runtime,
http_connect_proxy_config=http_connect_proxy_config,
)
return Client(
await temporalio.service.ServiceClient.connect(connect_config),
Expand Down
24 changes: 23 additions & 1 deletion temporalio/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from dataclasses import dataclass, field
from datetime import timedelta
from enum import IntEnum
from typing import ClassVar, Generic, Mapping, Optional, Type, TypeVar, Union
from typing import ClassVar, Generic, Mapping, Optional, Tuple, Type, TypeVar, Union

import google.protobuf.empty_pb2
import google.protobuf.message
Expand Down Expand Up @@ -115,6 +115,24 @@ def _to_bridge_config(self) -> temporalio.bridge.client.ClientKeepAliveConfig:
KeepAliveConfig.default = KeepAliveConfig()


@dataclass(frozen=True)
class HttpConnectProxyConfig:
"""Configuration for HTTP CONNECT proxy for client connections."""

target_host: str
"""Target host:port for the HTTP CONNECT proxy."""
basic_auth: Optional[Tuple[str, str]] = None
"""Basic auth for the HTTP CONNECT proxy if any as a user/pass tuple."""

def _to_bridge_config(
self,
) -> temporalio.bridge.client.ClientHttpConnectProxyConfig:
return temporalio.bridge.client.ClientHttpConnectProxyConfig(
target_host=self.target_host,
basic_auth=self.basic_auth,
)


@dataclass
class ConnectConfig:
"""Config for connecting to the server."""
Expand All @@ -128,6 +146,7 @@ class ConnectConfig:
identity: str = ""
lazy: bool = False
runtime: Optional[temporalio.runtime.Runtime] = None
http_connect_proxy_config: Optional[HttpConnectProxyConfig] = None

def __post_init__(self) -> None:
"""Set extra defaults on unset properties."""
Expand Down Expand Up @@ -174,6 +193,9 @@ def _to_bridge_config(self) -> temporalio.bridge.client.ClientConfig:
identity=self.identity,
client_name="temporal-python",
client_version=__version__,
http_connect_proxy_config=self.http_connect_proxy_config._to_bridge_config()
if self.http_connect_proxy_config
else None,
)


Expand Down

0 comments on commit 1001653

Please sign in to comment.