AzureSoraSDK 1.0.2

dotnet add package AzureSoraSDK --version 1.0.2
                    
NuGet\Install-Package AzureSoraSDK -Version 1.0.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="AzureSoraSDK" Version="1.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="AzureSoraSDK" Version="1.0.2" />
                    
Directory.Packages.props
<PackageReference Include="AzureSoraSDK" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add AzureSoraSDK --version 1.0.2
                    
#r "nuget: AzureSoraSDK, 1.0.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package AzureSoraSDK@1.0.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=AzureSoraSDK&version=1.0.2
                    
Install as a Cake Addin
#tool nuget:?package=AzureSoraSDK&version=1.0.2
                    
Install as a Cake Tool

AzureSoraSDK

Azure OpenAI "Sora" Video Generation & Prompt Enhancement SDK

.NET 6.0+ License: MIT

Sora SDK

📚 Documentation Wiki | 📋 Changelog | 📦 NuGet Package

This is a community-driven SDK for Azure OpenAI Sora video generation and prompt enhancement. The SDK provides a comprehensive .NET solution for generating high-quality videos using Azure OpenAI's Sora model, with built-in prompt enhancement capabilities to help you create more compelling video content.

Features

Core Features

  • Video Generation: Submit jobs, poll status, wait for completion, download MP4
  • Customizable: Width, height, and duration settings
  • Job Management: Check job status with detailed progress tracking
  • Enhanced Prompt: Get real-time AI-powered prompt improvement suggestions
  • API Versioning: Specify Azure OpenAI API version (default: preview)
  • Separate Configuration: Independent endpoint and API version for video generation and prompt enhancement
  • Dependency Injection: Full support for .NET DI with IServiceCollection extensions
  • Robust Error Handling: Specific exception types for different error scenarios
  • Retry Logic: Automatic retry with exponential backoff using Polly
  • Circuit Breaker: Prevents cascading failures with circuit breaker pattern
  • Logging: Integrated Microsoft.Extensions.Logging support
  • HttpClient Management: Proper HttpClient lifecycle management with IHttpClientFactory
  • Nullable Reference Types: Full C# nullable reference type support
  • Async Disposal: Implements IAsyncDisposable for proper resource cleanup
  • Configuration Validation: Comprehensive validation with data annotations
  • Unit Testing: Extensive test coverage with xUnit, Moq, and FluentAssertions
  • Thread Safety: Thread-safe operations with proper synchronization
  • Production-Ready: Built with enterprise requirements in mind
  • Type-Safe: Strongly typed interfaces and comprehensive error handling
  • Async/Await: Modern asynchronous programming patterns throughout
  • Configurable: Flexible configuration options for different environments
  • Testable: Designed with dependency injection and testing in mind
  • Customizable: Width, height, and duration settings
  • Robust Error Handling: Comprehensive exception types for different scenarios

Installation

# Install from NuGet
dotnet add package AzureSoraSDK

# Or via Package Manager
Install-Package AzureSoraSDK

Quick Start

Basic Usage (Legacy)

using AzureSoraSDK;
using System;

var endpoint   = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")!;
var apiKey     = Environment.GetEnvironmentVariable("AZURE_OPENAI_KEY")!;
var deployment = "sora";

using var client = new SoraClient(endpoint, apiKey, deployment);

// Submit a video job
var jobId = await client.SubmitVideoJobAsync(
    prompt: "A serene sunset over mountain peaks, 10 seconds",
    width: 1280,
    height: 720,
    nSeconds: 10
);

// Wait for completion
var videoUri = await client.WaitForCompletionAsync(jobId);

// Download the video
await client.DownloadVideoAsync(videoUri, "output.mp4");

Using Aspect Ratio (New in v1.0.2)

using AzureSoraSDK;

// Generate video with aspect ratio and quality presets
var jobId = await client.SubmitVideoJobAsync(
    prompt: "A beautiful sunset over mountains",
    aspectRatio: "16:9",
    quality: "high",
    nSeconds: 10
);

// Calculate custom dimensions
var (width, height) = SoraClient.CalculateDimensionsFromAspectRatio("21:9", 2048);
// Returns: (2048, 880) - ultrawide cinema format

// Get common dimensions for aspect ratios
var (w, h) = SoraClient.GetCommonDimensions("1:1", "medium");
// Returns: (720, 720) - medium quality square video
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using AzureSoraSDK.Extensions;
using AzureSoraSDK.Interfaces;

// In your Startup.cs or Program.cs
var builder = WebApplication.CreateBuilder(args);

// Option 1: Separate configuration for video generation and prompt enhancement
builder.Services.AddAzureSoraSDK(
    configureSoraOptions: options =>
    {
        options.Endpoint = "https://your-sora-endpoint.openai.azure.com";
        options.ApiKey = "your-sora-api-key";
        options.DeploymentName = "sora";
        options.ApiVersion = "preview"; // Video generation API version
    },
    configurePromptEnhancerOptions: options =>
    {
        options.Endpoint = "https://your-chat-endpoint.openai.azure.com";
        options.ApiKey = "your-chat-api-key";
        options.DeploymentName = "gpt-4";
        options.ApiVersion = "2024-02-15-preview"; // Chat completions API version
        options.DefaultTemperature = 0.7;
        options.MaxTokensPerRequest = 1500;
    });

// Option 2: Configuration from appsettings.json with separate sections
builder.Services.AddAzureSoraSDK(builder.Configuration.GetSection("AzureSora"));

// Option 3: Shared configuration (backward compatible)
builder.Services.AddAzureSoraSDK(options =>
{
    options.Endpoint = "https://your-resource.openai.azure.com";
    options.ApiKey = "your-api-key";
    options.DeploymentName = "sora";
    options.ApiVersion = "preview";
    options.MaxRetryAttempts = 5;
    options.HttpTimeout = TimeSpan.FromMinutes(10);
});

// In your service/controller
public class VideoService
{
    private readonly ISoraClient _soraClient;
    private readonly IPromptEnhancer _promptEnhancer;
    private readonly ILogger<VideoService> _logger;

    public VideoService(
        ISoraClient soraClient, 
        IPromptEnhancer promptEnhancer,
        ILogger<VideoService> logger)
    {
        _soraClient = soraClient;
        _promptEnhancer = promptEnhancer;
        _logger = logger;
    }

    public async Task<string> GenerateVideoAsync(string prompt)
    {
        try
        {
            // Enhance the prompt first
            var suggestions = await _promptEnhancer.SuggestPromptsAsync(prompt, 3);
            var enhancedPrompt = suggestions.FirstOrDefault() ?? prompt;
            
            _logger.LogInformation("Generating video with prompt: {Prompt}", enhancedPrompt);

            // Submit video generation job
            var jobId = await _soraClient.SubmitVideoJobAsync(
                prompt: enhancedPrompt,
                width: 1920,
                height: 1080,
                nSeconds: 15
            );

            // Wait with timeout
            var videoUri = await _soraClient.WaitForCompletionAsync(
                jobId,
                pollIntervalSeconds: 3,
                maxWaitTime: TimeSpan.FromMinutes(30)
            );

            return videoUri.ToString();
        }
        catch (SoraValidationException ex)
        {
            _logger.LogError(ex, "Validation failed: {Errors}", ex.ValidationErrors);
            throw;
        }
        catch (SoraRateLimitException ex)
        {
            _logger.LogWarning("Rate limited. Retry after: {RetryAfter}", ex.RetryAfter);
            throw;
        }
    }
}

Configuration

appsettings.json with Separate Configuration

{
  "AzureSora": {
    "Endpoint": "https://your-sora-endpoint.openai.azure.com",
    "ApiKey": "your-sora-api-key",
    "DeploymentName": "sora",
    "ApiVersion": "preview",
    "HttpTimeout": "00:05:00",
    "MaxRetryAttempts": 3,
    "RetryDelay": "00:00:02",
    "DefaultPollingInterval": "00:00:05",
    "MaxWaitTime": "01:00:00"
  },
  "PromptEnhancer": {
    "Endpoint": "https://your-chat-endpoint.openai.azure.com",
    "ApiKey": "your-chat-api-key",
    "DeploymentName": "gpt-4",
    "ApiVersion": "2024-02-15-preview",
    "HttpTimeout": "00:02:00",
    "MaxRetryAttempts": 3,
    "RetryDelay": "00:00:01",
    "DefaultTemperature": 0.7,
    "DefaultTopP": 0.9,
    "MaxTokensPerRequest": 1000
  }
}

appsettings.json with Shared Configuration (Backward Compatible)

{
  "AzureSora": {
    "Endpoint": "https://your-resource.openai.azure.com",
    "ApiKey": "your-api-key",
    "DeploymentName": "sora",
    "ApiVersion": "preview",
    "HttpTimeout": "00:05:00",
    "MaxRetryAttempts": 3,
    "RetryDelay": "00:00:02",
    "DefaultPollingInterval": "00:00:05",
    "MaxWaitTime": "01:00:00"
  }
}

Environment Variables

# For Video Generation (SoraClient)
export AZURE_OPENAI_SORA_ENDPOINT="https://your-sora-endpoint.openai.azure.com"
export AZURE_OPENAI_SORA_KEY="your-sora-api-key"
export AZURE_OPENAI_SORA_DEPLOYMENT="sora"

# For Prompt Enhancement (PromptEnhancer)
export AZURE_OPENAI_CHAT_ENDPOINT="https://your-chat-endpoint.openai.azure.com"
export AZURE_OPENAI_CHAT_KEY="your-chat-api-key"
export AZURE_OPENAI_CHAT_DEPLOYMENT="gpt-4"

Advanced Usage

Direct Configuration with PromptEnhancerOptions

using AzureSoraSDK.Configuration;

// Create prompt enhancer with separate configuration
var promptEnhancerOptions = new PromptEnhancerOptions
{
    Endpoint = "https://your-chat-endpoint.openai.azure.com",
    ApiKey = "your-chat-api-key",
    DeploymentName = "gpt-4",
    ApiVersion = "2024-02-15-preview",
    DefaultTemperature = 0.5,
    DefaultTopP = 0.8,
    MaxTokensPerRequest = 2000,
    HttpTimeout = TimeSpan.FromMinutes(3)
};

var promptEnhancer = new PromptEnhancer(httpClient, promptEnhancerOptions, logger);

// Use different settings for different scenarios
var creativeSuggestions = await promptEnhancer.SuggestPromptsAsync(
    "A sunset scene", 
    maxSuggestions: 5
);

Error Handling

try
{
    var jobId = await client.SubmitVideoJobAsync(...);
}
catch (SoraAuthenticationException ex)
{
    // Handle authentication failures
    Console.WriteLine($"Auth failed: {ex.Message}");
}
catch (SoraValidationException ex)
{
    // Handle validation errors
    foreach (var error in ex.ValidationErrors ?? new())
    {
        Console.WriteLine($"{error.Key}: {string.Join(", ", error.Value)}");
    }
}
catch (SoraRateLimitException ex)
{
    // Handle rate limiting
    if (ex.RetryAfter.HasValue)
    {
        await Task.Delay(ex.RetryAfter.Value);
        // Retry the operation
    }
}
catch (SoraTimeoutException ex)
{
    // Handle timeouts
    Console.WriteLine($"Operation timed out after {ex.Timeout}");
}
catch (SoraNotFoundException ex)
{
    // Handle not found errors
    Console.WriteLine($"Resource not found: {ex.ResourceId}");
}

Video Generation with Metadata

// Submit a video generation job with metadata
var jobId = await client.SubmitVideoJobAsync(
    prompt: "A futuristic cityscape at night with flying cars",
    width: 1920,
    height: 1080,
    nSeconds: 20
);

// The VideoGenerationRequest model also supports metadata:
var request = new VideoGenerationRequest
{
    Prompt = "A beautiful sunset over mountains",
    Width = 1920,
    Height = 1080,
    NSeconds = 15,
    Metadata = new Dictionary<string, string>
    {
        ["project"] = "marketing-campaign",
        ["version"] = "v1"
    }
};

// Validate before submission
request.Validate();

Progress Monitoring

var jobId = await client.SubmitVideoJobAsync(...);

while (true)
{
    var details = await client.GetJobStatusAsync(jobId);
    
    Console.WriteLine($"Status: {details.Status}");
    
    if (details.ProgressPercentage.HasValue)
    {
        Console.WriteLine($"Progress: {details.ProgressPercentage}%");
    }
    
    if (details.EstimatedTimeRemaining.HasValue)
    {
        Console.WriteLine($"ETA: {details.EstimatedTimeRemaining}");
    }
    
    if (details.Status == JobStatus.Succeeded)
    {
        Console.WriteLine($"Video URL: {details.VideoUrl}");
        break;
    }
    else if (details.Status == JobStatus.Failed)
    {
        Console.WriteLine($"Failed: {details.ErrorMessage} (Code: {details.ErrorCode})");
        break;
    }
    
    await Task.Delay(TimeSpan.FromSeconds(5));
}

Prompt Enhancement

var enhancer = serviceProvider.GetRequiredService<IPromptEnhancer>();

// Get multiple suggestions
var suggestions = await enhancer.SuggestPromptsAsync(
    "A sunset scene",
    maxSuggestions: 5
);

foreach (var suggestion in suggestions)
{
    Console.WriteLine($"- {suggestion}");
}

// Output might be:
// - A vibrant sunset over the ocean with golden rays reflecting on calm waters
// - A dramatic sunset behind mountain silhouettes with purple and orange clouds  
// - A peaceful sunset in a meadow with warm light casting long shadows
// - A tropical sunset with palm trees swaying in the gentle breeze
// - An urban sunset with city skyline silhouetted against colorful sky

Testing

The SDK includes comprehensive unit tests. To run tests:

cd src/AzureSoraSDK.Tests
dotnet test

# With coverage
dotnet test --collect:"XPlat Code Coverage"

# Run specific tests
dotnet test --filter "FullyQualifiedName~SoraClientTests"

API Reference

ISoraClient

  • SubmitVideoJobAsync - Submit a video generation job
  • GetJobStatusAsync - Get current job status and details
  • WaitForCompletionAsync - Wait for job completion with polling
  • DownloadVideoAsync - Download generated video to local file

IPromptEnhancer

  • SuggestPromptsAsync - Get AI-powered prompt suggestions

Configuration Options

SoraClientOptions (Video Generation)

  • Endpoint - Azure OpenAI endpoint URL for video generation
  • ApiKey - API key for video generation authentication
  • DeploymentName - Name of your Sora deployment
  • ApiVersion - API version for video generation (default: preview)
  • HttpTimeout - HTTP request timeout (default: 5 minutes)
  • MaxRetryAttempts - Max retry attempts (default: 3)
  • RetryDelay - Base delay between retries (default: 2 seconds)
  • DefaultPollingInterval - Job status polling interval (default: 5 seconds)
  • MaxWaitTime - Maximum wait time for job completion (default: 1 hour)

PromptEnhancerOptions (Prompt Enhancement)

  • Endpoint - Azure OpenAI endpoint URL for chat completions
  • ApiKey - API key for chat completions authentication
  • DeploymentName - Name of your chat completion deployment (e.g., gpt-4)
  • ApiVersion - API version for chat completions (default: 2024-02-15-preview)
  • HttpTimeout - HTTP request timeout (default: 2 minutes)
  • MaxRetryAttempts - Max retry attempts (default: 3)
  • RetryDelay - Base delay between retries (default: 1 second)
  • DefaultTemperature - Temperature for prompt enhancement (default: 0.7)
  • DefaultTopP - Top-p value for prompt enhancement (default: 0.9)
  • MaxTokensPerRequest - Maximum tokens per request (default: 1000)

Requirements

  • .NET 6.0 or higher
  • Azure OpenAI resource with Sora model deployment
  • Valid API key with appropriate permissions

Documentation

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT © Hazem Ali

Changelog

See CHANGELOG.md for a detailed list of changes in each release.

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.2 439 6/10/2025
1.0.1 296 6/10/2025
1.0.0 119 6/7/2025