Skip to main content

Crate prawn

Crate prawn 

Source
Expand description

§Prawn - Rust Client Library for the Tidal API

Prawns (shrimp, really) are one of the most common crustacean you will see in a tide pool :)

Prawn is a Rust library exposing a thin wrapper client around generated API clients and models for the Tidal V2 API. The wrapper client is intended to make managing authenticating via OAuth 2.0 with Tidal easier by exposing a few simple additional methods and managing refresh tokens. The OAuth methods rely on the oauth2 crate.

The API clients/models/docs were (mostly, with some modifications) generated by the OpenAPI Generator project.

Prawn currently supports the Authorization Code flow and the Client Credentials flow, which are the only ones documented as supported in Tidal’s public docs

I developed this library because the other most comprehensive Tidal library for Rust is tidalrs. However, tidalrs only supports device authorization, does not support the authorization code or client credentials flow, and only interacts with the V1 Tidal API. Changing these assumptions felt big enough to warrant its own library in the end.

§Examples

§Generate an authorize URL

use prawn::client::{TidalClient, TidalClientConfig, OAuthConfig};
let client_id = "<your client id>";

let redirect_uri = "https://example.com/callback";

let config = TidalClientConfig {
    oauth_config: OAuthConfig {
        redirect_uri: redirect_uri.to_string(),
        client_id: client_id.to_string(),
        client_secret: None
    },
    auth_token: None, // we haven't authorized yet, so we  don't have  this.
    retry_config: None,
};
let client = TidalClient::new(config)?;

let (challenge, verifier) = client.generate_pkce_challenge_and_verifier();

let scopes = vec!["user.read"];

let (auth_url, state) = client.get_authorize_url_and_state(challenge, scopes.to_vec());

println!("visit {} to authorize", auth_url);

§Exchange url for token and call API, retry rate limited requests


use prawn::client::{TidalClient, TidalClientConfig, OAuthConfig, Token, RetryConfig};
// ... /callback implementation ...
let code = "<extract from query params>";
let verifier = "<stored verifier somewher>";

let client_id = "<your client id>";

let redirect_uri = "https://example.com/callback";

let config = TidalClientConfig {
    oauth_config: OAuthConfig {
        redirect_uri: redirect_uri.to_string(),
        client_id: client_id.to_string(),
        client_secret: None
    },
    auth_token: None, // we haven't authorized yet, so we  don't have  this.
    retry_config: Some(RetryConfig{}), // enables retries with exponential backoff when we get 429 response codes from Tidal.
};

let client = TidalClient::new(config)?;

let token: Token = client.exchange_code_for_token(verifier.to_string(), code.to_string()).await?;

let client_with_token =  client.with_token(token)?;

let resp = client_with_token.tracks_api().get_track("<some track id>", None, None, None).await;

§Client Credentials flow

use prawn::client::{TidalClient, TidalClientConfig, OAuthConfig};
let client_id = "<your client id>";
let client_secret = "<your client secret>";

let redirect_uri = "https://example.com/callback";

let config = TidalClientConfig {
    oauth_config: OAuthConfig {
        redirect_uri: redirect_uri.to_string(),
        client_id: client_id.to_string(),
        client_secret: Some(client_secret.to_string()),
    },
    auth_token: None, // we haven't authorized yet, so we  don't have  this.
    retry_config: None
};

let client = TidalClient::new(config)?;
let scopes = vec!["user.read"];
let token = client.exchange_client_credentials_for_token(scopes.to_vec()).await?;

let client_with_token =  client.with_token(token)?;

let resp = client_with_token.tracks_api().get_track("some track id", None, None, None).await;

Modules§

apis
For comprehensive documentation of API endpoints and payloads, visit https://!tidal-music.github.io/tidal-api-reference
client
models