pub struct ClientBuilder { /* private fields */ }Expand description
Configures a Client.
Every setting is optional. The API key, base URL and default model fall
back to TYPESAFE_API_KEY, TYPESAFE_BASE_URL and
TYPESAFE_DEFAULT_MODEL, then to the SDK’s defaults (no key, which fails;
https://api.typesafe.ai; jev-latest). The methods never fail: what
they are given is checked by build.
Implementations§
Source§impl ClientBuilder
impl ClientBuilder
Sourcepub fn api_key(self, key: impl Into<String>) -> Self
pub fn api_key(self, key: impl Into<String>) -> Self
The API key. It is sent as Authorization: Bearer <key> and is
printed nowhere. Leading and trailing whitespace is stripped; an empty
key, internal whitespace, control and non-ASCII characters are refused.
Sourcepub fn base_url(self, url: impl Into<String>) -> Self
pub fn base_url(self, url: impl Into<String>) -> Self
The API root, such as https://api.typesafe.ai; trailing slashes are
removed and a path prefix is kept.
It must be an absolute http or https URL without userinfo, query or
fragment. An http:// base URL sends the API key unencrypted; use it
only for a local proxy or a test server. Do not put a credential in its
path: the path is printed by the client’s Debug and in every error
message that names an endpoint, as the Python SDK prints it.
Sourcepub fn default_model(self, model: impl Into<String>) -> Self
pub fn default_model(self, model: impl Into<String>) -> Self
The model a request names when the call does not name one.
Sourcepub fn timeout(self, timeout: Duration) -> Self
pub fn timeout(self, timeout: Duration) -> Self
The deadline of each attempt, from the first byte sent to the last byte received. The default is 10 seconds.
A large state on a slow link can take longer than that to upload;
raise the deadline for it, or use no_timeout.
Sourcepub fn no_timeout(self) -> Self
pub fn no_timeout(self) -> Self
No deadline on any attempt.
Sourcepub fn default_header(
self,
name: impl Into<String>,
value: impl Into<String>,
) -> Self
pub fn default_header( self, name: impl Into<String>, value: impl Into<String>, ) -> Self
A header sent on every request. A per-call header of the same name
replaces it; the SDK’s own headers - Authorization, Accept,
User-Agent, X-TypeSafe-SDK, X-TypeSafe-Runtime, and
Content-Type on a request with a body - always win, and
X-TypeSafe-Retry-Count is dropped. The headers that frame a message
or manage its connection belong to the transport and are dropped too:
Content-Length, Transfer-Encoding, Connection, Keep-Alive,
Proxy-Connection, TE, Trailer and Upgrade. Host is sent as
given, on every protocol; over HTTP/2 the request’s :authority still
comes from the base URL. Over HTTP/2 a Host that differs from the
base URL’s authority is outside RFC 9113 (section 8.3.1), and a
conforming server may refuse the request as malformed. A caller that
needs another Host routes by the base URL instead, or speaks
HTTP/1.1: HttpVersion::Auto does on an http base URL, and on an
https one only when the server picks HTTP/1.1 through ALPN. A later
call with the same name replaces an earlier one.
No header set here or on a call reaches User-Agent or
X-TypeSafe-Runtime: user_agent_product
and send_runtime_header are the only
ways to change what they carry.
Sourcepub fn max_response_bytes(self, limit: usize) -> Self
pub fn max_response_bytes(self, limit: usize) -> Self
The largest response body a request reads, in bytes; 16 MiB unless
set. A larger body is not read past the limit: a success response
fails with ErrorKind::ResponseTooLarge,
a failure response is an API error without its body.
Sourcepub fn add_root_certificate(self, der: impl Into<Vec<u8>>) -> Self
pub fn add_root_certificate(self, der: impl Into<Vec<u8>>) -> Self
Trusts der, a DER-encoded certificate, in addition to the operating
system’s roots: for a corporate CA the system store lacks, or a test
server’s own certificate.
The default transport only; see
build_with_service.
Sourcepub fn http_version(self, version: HttpVersion) -> Self
pub fn http_version(self, version: HttpVersion) -> Self
Which HTTP versions the default transport speaks. The default is
HttpVersion::Http2Only for an https base URL and
HttpVersion::Auto for an http one.
The default transport only; see
build_with_service.
Sourcepub fn connect_timeout(self, timeout: Duration) -> Self
pub fn connect_timeout(self, timeout: Duration) -> Self
A deadline for opening a TCP connection, inside the deadline of the
whole attempt. None unless set. When it passes, the request fails with
ErrorKind::Timeout carrying this value.
The default transport only; see
build_with_service.
Sourcepub fn retry(self, policy: RetryPolicy) -> Self
pub fn retry(self, policy: RetryPolicy) -> Self
The retry policy of every call made through the client;
RetryPolicy::default unless set. A call can replace it for itself
with its own retry.
Sourcepub fn user_agent_product(self, product: impl Into<String>) -> Self
pub fn user_agent_product(self, product: impl Into<String>) -> Self
A product that names the application, sent in User-Agent in front
of the SDK’s own: user_agent_product("my-app/1.2.0") sends
User-Agent: my-app/1.2.0 typesafe-sdk-rust/<version>, the more
significant product first as RFC 9110 (section 10.1.5) orders them.
Unset, User-Agent is the SDK’s identifier alone. X-TypeSafe-SDK
always names the SDK alone. A later call replaces an earlier one.
The product must be name/version, both parts tokens (RFC 9110,
section 5.6.2: letters, digits and !#$%&'*+-.^_`|~), with exactly
one / and at most 64 bytes in all. That rules out whitespace,
control characters, anything outside ASCII, a comment in parentheses
and a product without a version.
§Errors
This method never fails. A product that breaks those rules makes
build and build_with_service
return an ErrorKind::Config error naming
the rule, before anything is sent.
use typesafe_sdk::{Client, ErrorKind};
// Building connects to nothing.
let client = Client::builder()
.api_key("your-api-key")
.user_agent_product("my-app/1.2.0")
.build()?;
let error = Client::builder()
.api_key("your-api-key")
.user_agent_product("my app")
.build()
.expect_err("a product with a space is refused");
assert!(matches!(error.kind(), ErrorKind::Config));Sourcepub fn send_runtime_header(self, send: bool) -> Self
pub fn send_runtime_header(self, send: bool) -> Self
Whether requests carry X-TypeSafe-Runtime: rust (<os>; <arch>),
which tells the API the operating system and architecture the SDK was
compiled for. The default is true; false leaves the header out of
every request, so an application can keep its platform to itself.
X-TypeSafe-SDK is sent either way. A later call replaces an earlier
one.
use typesafe_sdk::Client;
// Building connects to nothing.
let client = Client::builder().api_key("your-api-key").send_runtime_header(false).build()?;Sourcepub fn build(self) -> Result<Client<HyperTransport>, Error>
pub fn build(self) -> Result<Client<HyperTransport>, Error>
Builds a client with the default transport.
Settings left unset are read from the environment. Nothing connects
here: the first request, or Client::warm_up, does.
§Errors
Returns an ErrorKind::Config error when
no API key is found or the key is empty after trimming or holds
whitespace, a control or a non-ASCII character; when
the base URL is not an absolute http or https URL without
userinfo, query or fragment; when the default model is blank; when a
deadline or the response limit is zero; when a default header is not a
valid header; when the user_agent_product
is not a product token; when an environment variable is not UTF-8; or
when the certificate verifier cannot be built, for an added root that
is not a certificate among other causes. No message repeats the key, a
header value or the URL.
Sourcepub fn build_with_service<S>(self, service: S) -> Result<Client<S>, Error>where
S: HttpService,
pub fn build_with_service<S>(self, service: S) -> Result<Client<S>, Error>where
S: HttpService,
Builds a client that sends its requests through service.
This is how a client runs over a transport of the caller’s own: a
proxy, a recorder, a tower stack with its own middleware. The
service owns its connections and their timeouts; the SDK still wraps
each attempt in its own deadline and reads the response under its own
limit.
When the service fails, its error’s text becomes the connection
error’s message, escaped and cut at 200 characters. The request’s
credentials are replaced by *** first: the API key, and the value of
every header whose name is a secret one (authorization,
proxy-authorization, x-api-key, api-key, cookie, set-cookie,
or any name containing token or secret) or that is flagged
sensitive, as it is, as {:?} of a str, str::escape_debug, {:?}
of a HeaderValue and of Bytes, and a JSON string write it, and each
of those escaped once more as {:?} of a str writes it, which is how
a derived Debug prints a String field holding one. When
any of those occurs in the error’s Display, {:?} or {:#?}, or in
any error below it, the source is a
redacted copy that cannot be downcast. The message is redacted after
escaping as well, so a covered form the escaping creates by chance is
*** too. The value of any other header a service prints stays in the
message, and so does a credential written in a form not listed here:
as a list of byte values, {:x?}, percent-encoded or in base64.
§Errors
Everything build refuses except the certificate
verifier, and, as a config error, any of
add_root_certificate,
http_version and
connect_timeout: they configure the default
transport, which this client does not have, and are refused rather
than ignored.
Trait Implementations§
Source§impl Debug for ClientBuilder
impl Debug for ClientBuilder
Source§fn fmt(&self, formatter: &mut Formatter<'_>) -> Result
fn fmt(&self, formatter: &mut Formatter<'_>) -> Result
What was set, without the key, without header values, and with the
roots as a count. The base URL is shown only once it has passed the
checks build runs, and then as its endpoints,
the way an error names them: a URL that failed them may still hold
userinfo. A retry policy, a User-Agent product and a runtime header
switched off are shown when they were set; the product is quoted and
escaped, since until it is built it may hold anything.