Skip to main content

ClientBuilder

Struct ClientBuilder 

Source
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

Source

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.

Source

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.

Source

pub fn default_model(self, model: impl Into<String>) -> Self

The model a request names when the call does not name one.

Source

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.

Source

pub fn no_timeout(self) -> Self

No deadline on any attempt.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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));
Source

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()?;
Source

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.

Source

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

Source§

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.

Source§

impl Default for ClientBuilder

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more