Crate taskcluster
source ·Expand description
§Taskcluster Client for Rust
For a general guide to using Taskcluster clients, see Calling Taskcluster APIs.
This client is a convenience wrapper around reqwest
that provides named functions for each API
endpoint and adds functionality such as authentication and retries.
§Usage
§Setup
Before calling an API end-point, you’ll need to build a client, using the
ClientBuilder
type. This allows construction of a client with only the
necessary features, following the builder pattern. You must at least supply a root URL to identify
the Taskcluster deployment to which the API calls should be directed.
There is a type for each service, e.g., Queue
and Auth
. Each service type defines functions
spepcific to the API endpoints for that service. Each has a new
associated function that
takes an Into<ClientBuilder>
. As a shortcut, you may pass a string to new
that will be treated
as a root URL.
Here is a simple setup and use of an un-authenticated client:
use taskcluster::Auth;
let auth = Auth::new(root_url)?;
let resp = auth.client("static/taskcluster/root").await?;
assert_eq!(resp, json!({"clientId": "static/taskcluster/root"}));
Ok(())
Here is an example with credentials provided, in this case via the standard environment variables.
use std::env;
use taskcluster::{ClientBuilder, Queue, Credentials};
let creds = Credentials::from_env()?;
let root_url = env::var("TASKCLUSTER_ROOT_URL").unwrap();
let client = Queue::new(ClientBuilder::new(&root_url).credentials(creds))?;
let res = client.cancelTask("G08bnnBuR6yDhDLJkJ6KiA").await?;
println!("{}", res.get("status").unwrap());
Ok(())
§Authorized Scopes
If you wish to perform requests on behalf of a third-party that has smaller set of scopes than you do, you can specify which scopes your request should be allowed to use.
These “authorized scopes” are configured on the client:
use std::env;
use serde_json::json;
use taskcluster::{ClientBuilder, Queue, Credentials};
let creds = Credentials::from_env()?;
let root_url = env::var("TASKCLUSTER_ROOT_URL").unwrap();
let client = Queue::new(
ClientBuilder::new(&root_url)
.credentials(creds)
.authorized_scopes(vec!["just:one-scope"]))?;
let res = client.createTask("G08bnnBuR6yDhDLJkJ6KiA", &task).await?;
Ok(())
§Calling API Methods
API methods are available as methods on the corresponding client object. They are capitalized in
snakeCase (e.g., createTask
) to match the Taskcluster documentation.
Each method takes arguments in the following order, where appropriate to the method:
- Positional arguments (strings interpolated into the URL)
- Request body (payload)
- URL query arguments
The payload comes in the form of a serde_json::Value
, the contents of which should match the API
method’s input schema. URL query arguments are all optional.
For example, the following lists all Auth clients:
use taskcluster::{Auth, ClientBuilder, Credentials};
let auth = Auth::new(ClientBuilder::new(&root_url))?;
let mut continuation_token: Option<String> = None;
let limit = Some("10");
loop {
let res = auth
.listClients(None, continuation_token.as_deref(), limit)
.await?;
for client in res.get("clients").unwrap().as_array().unwrap() {
println!("{:?}", client);
}
if let Some(v) = res.get("continuationToken") {
continuation_token = Some(v.as_str().unwrap().to_owned());
} else {
break;
}
}
§Error Handling
All 5xx (server error) responses are automatically retried.
All 4xx (client error) responses are converted to Result::Err
.
All other responses are treated as successful responses.
Note that this includes 3xx (redirection) responses; the client does not automatically follow such redirects.
Client methods return anyhow::Error
, but this can be downcast to a reqwest::Error
if needed.
As a shortcut for the common case of getting the HTTP status code for an error, use err_status_code
.
The reqwest::StatusCode
type that this returns is re-exported from this crate.
§Low-Level Access
Instead of using service-specific types, it is possible to call API methods directly by path, using
the Client
type:
use std::env;
use taskcluster::{ClientBuilder, Credentials};
let creds = Credentials::from_env()?;
let root_url = env::var("TASKCLUSTER_ROOT_URL").unwrap();
let client = ClientBuilder::new(&root_url).credentials(creds).build()?;
let resp = client.request("POST", "api/queue/v1/task/G08bnnBuR6yDhDLJkJ6KiA/cancel", None, None).await?;
assert!(resp.status().is_success());
§Uploading and Downloading Objects
The taskcluster-upload
and taskcluster-download
crates contain dedicated support for resilient uploads and downloads to/from the Taskcluster object service.
This comes in the form of functions that will both interface with the object service API and perform the negotiated upload/download method.
In all cases, you must supply a pre-configured Object
client, as well as required parameters to the object service API methods.
§Generating URLs
To generate a unsigned URL for an API method, use <method>_url
:
use taskcluster::{Auth, ClientBuilder};
let root_url = env::var("TASKCLUSTER_ROOT_URL").unwrap();
let auth = Auth::new(ClientBuilder::new(&root_url))?;
let url = auth.listClients_url(Some("static/"), None, None)?;
assert_eq!(url, "https://tc-tests.example.com/api/auth/v1/clients/?prefix=static%2F".to_owned());
§Generating Temporary Credentials
The create_named_temp_creds
method creates
temporary credentials:
use std::env;
use std::time::Duration;
use taskcluster::Credentials;
let creds = Credentials::from_env()?;
let temp_creds = creds.create_named_temp_creds(
"new-client-id",
Duration::from_secs(3600),
vec!["scope1", "scope2"])?;
assert_eq!(temp_creds.client_id, "new-client-id");
There is also a create_temp_creds
method which creates unamed temporary credentials, but its use
is not recommended.
§Generating Timestamps
Taskcluster APIs expects ISO 8601 timestamps, of the sort generated by the JS Date.toJSON
method.
The chrono
crate supports generating compatible timestamps if included with the serde
feature.
This crate re-exports chrono
with that feature enabled.
To duplicate the functionality of the fromNow
function from other Taskcluster client libraries, use something like this:
use taskcluster::chrono::{DateTime, Utc, Duration};
use serde_json::json;
let expires = Utc::now() + Duration::days(2);
let json = json!({ "expires": expires });
§Generating SlugIDs
Use the slugid crate to create slugIds (such as for a taskId).
Re-exports§
Modules§
- Internal support for retrying operations.
Structs§
- Auth Service
- Client is the entry point into all the functionality in this package. It contains authentication credentials, and a service endpoint, which are required for all HTTP operations.
- ClientBuilder implements the builder pattern for building a Client, allowing optional configuration of features such as authorized scopes and retry.
- Credentials represents the set of credentials required to access protected Taskcluster HTTP APIs.
- GitHub Service
- Hooks Service
- Index Service
- Notification Service
- Object Service
- Purge Cache Service
- Queue Service
- Secrets Service
- An HTTP status code (
status-code
in RFC 7230 et al.). - Worker Manager Service
Functions§
- If this error was due to a reqwest error created from an HTTP response, return the status code from that response. If the error is not a
reqwest::Error
, or was not caused by an HTTP response, returns None.