image_service_client 0.0.1-dev.3 copy "image_service_client: ^0.0.1-dev.3" to clipboard
image_service_client: ^0.0.1-dev.3 copied to clipboard

A client library of the "image service" server

Image Service Client #

shorebird ci codecov

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 pixels
  • height - Target height in pixels
  • quality - JPEG quality (1-100)

Models #

UploadResponse

  • url - Public URL of uploaded image
  • fileName - Stored filename
  • originalName - Original filename

ImageMetadata

  • fileName - Stored filename
  • originalName - Original filename
  • url - Public URL
  • size - File size in bytes

ImageServiceException

  • statusCode - HTTP status code
  • message - 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 #

License #

MIT License - Same as the Image Service project.

0
likes
0
points
59
downloads

Publisher

unverified uploader

Weekly Downloads

A client library of the "image service" server

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

dart_mappable, http, meta

More

Packages that depend on image_service_client