Add thumbnail endpoint with size options

This commit is contained in:
Joakim Hulthe
2026-04-06 08:17:34 +00:00
parent 1e38963ff6
commit 15d67f5667
3 changed files with 127 additions and 1 deletions

50
examples/thumbnail.rs Normal file
View File

@@ -0,0 +1,50 @@
//! Example: Download asset thumbnails
use immich_sdk::Client;
use immich_sdk::models::AssetMediaSize;
use std::fs;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create a client
let client = Client::from_url("https://immich.example.com")?.with_api_key("your-api-key");
// Asset ID to download thumbnail for
let asset_id = "your-asset-id-here".parse()?;
// Download thumbnail (small size, default)
println!("Downloading thumbnail...");
let thumbnail = client
.assets()
.thumbnail(asset_id)
.size(AssetMediaSize::Thumbnail)
.execute()
.await?;
fs::write("/path/to/output/thumbnail.jpg", &thumbnail)?;
println!("Saved thumbnail: {} bytes", thumbnail.len());
// Download preview (medium size)
let preview = client
.assets()
.thumbnail(asset_id)
.size(AssetMediaSize::Preview)
.execute()
.await?;
fs::write("/path/to/output/preview.jpg", &preview)?;
println!("Saved preview: {} bytes", preview.len());
// Download fullsize
let fullsize = client
.assets()
.thumbnail(asset_id)
.size(AssetMediaSize::Fullsize)
.execute()
.await?;
fs::write("/path/to/output/fullsize.jpg", &fullsize)?;
println!("Saved fullsize: {} bytes", fullsize.len());
Ok(())
}

View File

@@ -5,7 +5,7 @@ use std::path::Path;
use crate::{
Client,
error::{ImmichError, Result},
models::{AssetId, AssetResponse, AssetUploadResponse, DeleteAssetsRequest},
models::{AssetId, AssetMediaSize, AssetResponse, AssetUploadResponse, DeleteAssetsRequest},
};
/// API for managing assets (photos and videos)
@@ -44,6 +44,11 @@ impl AssetsApi {
pub fn download(&self, id: AssetId) -> DownloadAssetBuilder {
DownloadAssetBuilder::new(self.client.clone(), id)
}
/// Get asset thumbnail
pub fn thumbnail(&self, id: AssetId) -> ThumbnailBuilder {
ThumbnailBuilder::new(self.client.clone(), id)
}
}
/// Builder for listing assets
@@ -299,3 +304,60 @@ impl DownloadAssetBuilder {
Ok(bytes)
}
}
/// Builder for getting asset thumbnail
#[derive(Debug)]
pub struct ThumbnailBuilder {
client: Client,
id: AssetId,
size: Option<AssetMediaSize>,
edited: bool,
}
impl ThumbnailBuilder {
/// Create a new thumbnail builder
const fn new(client: Client, id: AssetId) -> Self {
Self {
client,
id,
size: None,
edited: false,
}
}
/// Set the thumbnail size
pub fn size(mut self, size: AssetMediaSize) -> Self {
self.size = Some(size);
self
}
/// Get the edited version if available
pub fn edited(mut self) -> Self {
self.edited = true;
self
}
/// Execute the request
pub async fn execute(self) -> Result<bytes::Bytes> {
let path = format!("/assets/{}/thumbnail", self.id);
let mut req = self.client.get(&path);
if let Some(ref size) = self.size {
let size_str = match size {
AssetMediaSize::Original => "original",
AssetMediaSize::Fullsize => "fullsize",
AssetMediaSize::Preview => "preview",
AssetMediaSize::Thumbnail => "thumbnail",
};
req = req.query(&[("size", size_str)]);
}
if self.edited {
req = req.query(&[("edited", "true")]);
}
let response = self.client.execute(req.build()?).await?;
let bytes = response.bytes().await?;
Ok(bytes)
}
}

View File

@@ -68,6 +68,20 @@ pub enum AssetVisibility {
Locked,
}
/// Asset media size for thumbnails
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum AssetMediaSize {
/// Original size
Original,
/// Full size
Fullsize,
/// Preview size
Preview,
/// Thumbnail size
Thumbnail,
}
/// EXIF information for an asset
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]