image_service_client 0.0.1-dev.3
image_service_client: ^0.0.1-dev.3 copied to clipboard
A client library of the "image service" server
Image Service Client #
A Dart client library for interacting with the Image Service server. Provides a simple, type-safe API for uploading, retrieving, transforming, and managing images.
Features #
- ๐ค Upload Images - Multipart form upload or binary PUT with custom filename
- โฐ Temporary Upload URLs - Generate secure, single-use tokens for client-side uploads
- ๐ฅ Retrieve Images - Get original or transformed versions
- ๐จ Transform Images - On-the-fly resizing and quality adjustment
- ๐๏ธ Delete Images - Remove images from the server
- ๐ List Images - Get all stored images with metadata
- ๐ Authenticated - Built-in API key authentication
- ๐งช Testable - Supports dependency injection for testing
Installation #
Add to your pubspec.yaml:
dependencies:
image_service_client: ^0.0.1-dev.1
Usage #
Initialize the Client #
import 'package:image_service_client/image_service_client.dart';
final client = ImageServiceClient(
baseUrl: 'http://localhost:8080',
apiKey: 'your-secret-api-key',
);
Upload an Image #
Using multipart form (POST):
final imageBytes = await File('photo.jpg').readAsBytes();
final response = await client.uploadImage(
imageBytes: imageBytes,
fileName: 'photo.jpg', // optional
);
print('Uploaded: ${response.url}');
With custom filename (PUT):
final imageBytes = await File('photo.jpg').readAsBytes();
final response = await client.uploadImageWithFilename(
imageBytes: imageBytes,
fileName: 'my-custom-name.jpg',
contentType: 'image/jpeg',
);
print('Uploaded: ${response.url}');
Using temporary upload token (no API key needed):
Temporary upload URLs allow you to generate a secure, single-use token that clients can use to upload images directly without exposing your API key. Perfect for client-side uploads in mobile or web apps.
// Step 1: Create a temporary upload URL (requires API key)
final tempUrl = await client.createTemporaryUploadUrl();
print('Token: ${tempUrl.token}');
print('Expires in: ${tempUrl.expiresIn} seconds');
// Step 2: Use the token to upload (no API key needed!)
// This can be done from a mobile app or browser without exposing your API key
final response = await client.uploadImageWithToken(
token: tempUrl.token,
imageBytes: imageBytes,
fileName: 'photo.jpg', // optional
);
print('Uploaded: ${response.url}');
Security Features:
- Token is single-use (automatically deleted after upload)
- Expires after 15 minutes
- Cryptographically secure (32 random bytes)
- Perfect for client-side uploads without exposing API keys
Retrieve an Image #
Get original image:
final bytes = await client.getImage('photo.jpg');
await File('downloaded.jpg').writeAsBytes(bytes);
Get transformed image:
final bytes = await client.getImage(
'photo.jpg',
transform: ImageTransformOptions(
width: 500,
height: 300,
quality: 85,
),
);
Get Image URLs #
// Original image URL
final url = client.getImageUrl('photo.jpg');
print(url); // http://localhost:8080/files/photo.jpg
// Transformed image URL
final transformedUrl = client.getImageUrl(
'photo.jpg',
transform: ImageTransformOptions(width: 500),
);
print(transformedUrl); // http://localhost:8080/files/width=500/photo.jpg
Delete an Image #
await client.deleteImage('photo.jpg');
print('Image deleted!');
List All Images #
final images = await client.listImages();
for (final image in images) {
print('${image.originalName} - ${image.url} (${image.size} bytes)');
}
Error Handling #
try {
await client.uploadImage(imageBytes: bytes);
} on ImageServiceException catch (e) {
print('Error: ${e.statusCode} - ${e.message}');
}
Server Setup #
This client library requires the Image Service server to be running. The easiest way to get started is using the pre-built Docker image:
# Pull the latest image
docker pull ghcr.io/mtwichel/image_service:latest
# Run the server
docker run -d \
-p 8080:8080 \
-e SECRET_KEY=your-secret-api-key \
-v $(pwd)/data:/app/data \
--name image_service \
ghcr.io/mtwichel/image_service:latest
Available architectures: linux/amd64, linux/arm64
For complete server documentation, deployment options, and building from source, see the Image Service repository.
API Reference #
ImageServiceClient #
Main client class for interacting with the Image Service.
Constructor:
baseUrl- Base URL of the image service (required)apiKey- API key for authentication (required)httpClient- Optional custom HTTP client for testing
Methods:
| Method | Description | Returns |
|---|---|---|
uploadImage() |
Upload image via multipart form | UploadResponse |
uploadImageWithFilename() |
Upload with custom filename | UploadResponse |
getImage() |
Retrieve image bytes | Uint8List |
getImageUrl() |
Get image URL | String |
deleteImage() |
Delete an image | bool |
listImages() |
List all images | List<ImageMetadata> |
dispose() |
Close HTTP client | void |
ImageTransformOptions #
Options for transforming images.
Properties:
width- Target width in pixelsheight- Target height in pixelsquality- JPEG quality (1-100)
Models #
UploadResponse
url- Public URL of uploaded imagefileName- Stored filenameoriginalName- Original filename
ImageMetadata
fileName- Stored filenameoriginalName- Original filenameurl- Public URLsize- File size in bytes
ImageServiceException
statusCode- HTTP status codemessage- Error message
Testing #
The client supports dependency injection for testing:
import 'package:mocktail/mocktail.dart';
import 'package:http/http.dart' as http;
class MockClient extends Mock implements http.Client {}
void main() {
test('uploads image', () async {
final mockClient = MockClient();
final client = ImageServiceClient(
baseUrl: 'http://test',
apiKey: 'test-key',
httpClient: mockClient,
);
// Setup mocks...
});
}
Example App #
import 'dart:io';
import 'package:image_service_client/image_service_client.dart';
Future<void> main() async {
final client = ImageServiceClient(
baseUrl: 'http://localhost:8080',
apiKey: Platform.environment['IMAGE_SERVICE_API_KEY']!,
);
// Upload an image
print('Uploading image...');
final bytes = await File('example.jpg').readAsBytes();
final upload = await client.uploadImage(
imageBytes: bytes,
fileName: 'example.jpg',
);
print('Uploaded: ${upload.url}');
// List all images
print('\nAll images:');
final images = await client.listImages();
for (final image in images) {
print('- ${image.originalName}: ${image.url}');
}
// Get a transformed version
print('\nDownloading thumbnail...');
final thumbnail = await client.getImage(
upload.fileName,
transform: ImageTransformOptions(width: 200, quality: 80),
);
await File('thumbnail.jpg').writeAsBytes(thumbnail);
print('Saved thumbnail!');
// Cleanup
client.dispose();
}
Server Resources #
- GitHub Repository: mtwichel/image_service
- Docker Images: GitHub Container Registry
- Server Documentation: README
License #
MIT License - Same as the Image Service project.