CanvasClient

Struct CanvasClient 

Source
pub struct CanvasClient { /* private fields */ }
Expand description

The main client for interacting with Spotify’s private Canvas API.

Handles authentication (client-token exchange) and GraphQL queries internally.

Implementations§

Source§

impl CanvasClient

Source

pub fn new() -> Self

Create a new CanvasClient with default configuration and a new reqwest::Client.

Examples found in repository?
examples/simple.rs (line 28)
5async fn main() -> Result<()> {
6    // 1. Get Access Token from environment or args
7    let access_token = match env::var("SPOTIFY_TOKEN") {
8        Ok(t) => t,
9        Err(_) => {
10            eprintln!("⚠️  SPOTIFY_TOKEN environment variable not set.");
11            eprintln!("   Please set it to a valid Spotify Access Token.");
12            eprintln!("   ");
13            eprintln!("   HOW TO GET A TOKEN:");
14            eprintln!("   1. Open https://open.spotify.com in your browser.");
15            eprintln!("   2. Log in.");
16            eprintln!("   3. Open Developer Tools (F12) -> Network tab.");
17            eprintln!("   4. Filter for 'pathfinder'.");
18            eprintln!("   5. Click any request, go to 'Headers' -> 'Request Headers'.");
19            eprintln!("   6. Copy the 'authorization' header (starts with 'Bearer ...').");
20            eprintln!(
21                "   7. Run: $env:SPOTIFY_TOKEN='...' ; cargo run --example simple (PowerShell)"
22            );
23            return Ok(());
24        }
25    };
26
27    // 2. Initialize Client
28    let mut client = CanvasClient::new();
29
30    // 3. Define a track URI (e.g., "KORE" by Zynyx)
31    let track_uri = "spotify:track:72Xn6x8xqegX64AKeJDsZt";
32
33    println!("Fetching canvas for: {}", track_uri);
34
35    // 4. Fetch
36    match client.get_canvas(track_uri, &access_token).await {
37        Ok(canvas) => {
38            println!("✅ Canvas Found!");
39            println!("   - MP4 URL: {}", canvas.mp4_url);
40            println!("   - Canvas URI: {:?}", canvas.uri);
41        }
42        Err(e) => {
43            eprintln!("❌ Error: {}", e);
44        }
45    }
46
47    Ok(())
48}
Source

pub fn with_config(config: CanvasConfig) -> Self

Create a new CanvasClient with a custom configuration.

Source

pub fn with_client(client: Client, config: CanvasConfig) -> Self

Creates a new CanvasClient using an existing reqwest::Client.

Useful if you want to share a connection pool or proxy configuration.

Source

pub async fn get_canvas( &mut self, track_uri: &str, access_token: &str, ) -> Result<Canvas>

Fetch the Canvas video URL for a given Spotify Track URI.

§Arguments
  • track_uri - The Spotify Track URI (e.g., “spotify:track:…”)
  • access_token - A valid Spotify Access Token (Bearer). Fetches the Spotify Canvas (looping video) for a given track URI.
§Arguments
  • track_uri - The Spotify URI of the track (e.g., "spotify:track:...").
  • access_token - A valid Spotify Web Player access token (starts with Bearer ...).
§Errors

Returns a CanvasError if:

  • The access_token is invalid or expired (CanvasError::TokenExpired).
  • The track has no canvas (CanvasError::NotFound).
  • Rate limited by Spotify (CanvasError::RateLimited).
  • Network or parsing errors occur.
§Example
let canvas = client.get_canvas("spotify:track:...", "Bearer ...").await?;
println!("Canvas URL: {}", canvas.mp4_url);
Examples found in repository?
examples/simple.rs (line 36)
5async fn main() -> Result<()> {
6    // 1. Get Access Token from environment or args
7    let access_token = match env::var("SPOTIFY_TOKEN") {
8        Ok(t) => t,
9        Err(_) => {
10            eprintln!("⚠️  SPOTIFY_TOKEN environment variable not set.");
11            eprintln!("   Please set it to a valid Spotify Access Token.");
12            eprintln!("   ");
13            eprintln!("   HOW TO GET A TOKEN:");
14            eprintln!("   1. Open https://open.spotify.com in your browser.");
15            eprintln!("   2. Log in.");
16            eprintln!("   3. Open Developer Tools (F12) -> Network tab.");
17            eprintln!("   4. Filter for 'pathfinder'.");
18            eprintln!("   5. Click any request, go to 'Headers' -> 'Request Headers'.");
19            eprintln!("   6. Copy the 'authorization' header (starts with 'Bearer ...').");
20            eprintln!(
21                "   7. Run: $env:SPOTIFY_TOKEN='...' ; cargo run --example simple (PowerShell)"
22            );
23            return Ok(());
24        }
25    };
26
27    // 2. Initialize Client
28    let mut client = CanvasClient::new();
29
30    // 3. Define a track URI (e.g., "KORE" by Zynyx)
31    let track_uri = "spotify:track:72Xn6x8xqegX64AKeJDsZt";
32
33    println!("Fetching canvas for: {}", track_uri);
34
35    // 4. Fetch
36    match client.get_canvas(track_uri, &access_token).await {
37        Ok(canvas) => {
38            println!("✅ Canvas Found!");
39            println!("   - MP4 URL: {}", canvas.mp4_url);
40            println!("   - Canvas URI: {:?}", canvas.uri);
41        }
42        Err(e) => {
43            eprintln!("❌ Error: {}", e);
44        }
45    }
46
47    Ok(())
48}

Trait Implementations§

Source§

impl Clone for CanvasClient

Source§

fn clone(&self) -> CanvasClient

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for CanvasClient

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for CanvasClient

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<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

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