A strongly-typed .NET client for the DigitalOcean API, generated using Microsoft's Kiota SDK generator. This client provides a simple and intuitive way to interact with DigitalOcean's services from .NET applications.
graph TD
A[Client Application] -->|Uses| B[DigitalOceanClient]
B -->|Authenticates via| C[ITokenProvider]
C -->|Implements| D[StaticTokenProvider]
C -->|Can implement| E[Custom Token Provider]
B -->|Makes requests to| F[DigitalOcean API]
B -->|Uses| G[Strongly-typed Models]
G -->|Includes| H[Account, Droplet, etc.]
- Complete coverage of the DigitalOcean API v2
- Strongly-typed models for all API entities
- Asynchronous API for non-blocking operations
- Authentication options for API tokens
- Easy integration with dependency injection
- Generated from the OpenAPI specification
- Comprehensive error handling
Install the package from NuGet:
dotnet add package InfinityFlow.DigitalOcean.Client// Create a client with an API tokenvartokenProvider=newStaticTokenProvider("your-digitalocean-api-token");varhttpClient=newHttpClient();varclient=newDigitalOceanClient(httpClient,tokenProvider);// Get account informationvaraccount=awaitclient.Account.GetAsync();Console.WriteLine($"Account: {account.Email}, {account.Status}");// List all dropletsvardroplets=awaitclient.Droplets.GetAsync();foreach(vardropletindroplets.Droplets){Console.WriteLine($"Droplet: {droplet.Name}, {droplet.Status}");}// In Program.cs or Startup.csservices.AddDigitalOceanClient(options =>{options.Token=Configuration["DigitalOcean:ApiToken"];});// In your servicepublicclassMyService{privatereadonlyDigitalOceanClient_client;publicMyService(DigitalOceanClientclient){_client=client;}publicasyncTaskDoSomethingAsync(){vardroplets=await_client.Droplets.GetAsync();// ...}}This client covers all DigitalOcean API endpoints:
- Account
- Actions
- Apps
- Billing
- Block Storage
- CDN Endpoints
- Certificates
- Container Registry
- Databases
- DNS (Domains)
- Droplets
- Firewalls
- Floating IPs
- Kubernetes
- Load Balancers
- Monitoring
- Projects
- Regions
- Reserved IPs
- Sizes
- Snapshots
- SSH Keys
- Tags
- VPCs
The client supports authentication using a DigitalOcean API token:
// Static token provider (simple approach)vartokenProvider=newStaticTokenProvider("your-api-token");// For more dynamic scenarios, implement ITokenProviderpublicclassMyTokenProvider:ITokenProvider{publicTask<string>GetTokenAsync(CancellationTokencancellationToken){// Get token from a secure storage or servicereturnTask.FromResult(GetSecureToken());}}You can customize requests with options:
// Get droplets with pagingvaroptions=newDropletsRequestBuilder.GetRequestConfiguration{QueryParameters=newDropletsRequestBuilder.GetQueryParameters{Page=2,PerPage=25}};vardroplets=awaitclient.Droplets.GetAsync(requestConfiguration:options);The client throws strongly-typed exceptions for API errors:
try{vardroplet=awaitclient.Droplets.ByDropletId(123456).GetAsync();// Process droplet}catch(DigitalOceanApiExceptionex)when(ex.StatusCode==404){Console.WriteLine("Droplet not found");}catch(DigitalOceanApiExceptionex){Console.WriteLine($"API error: {ex.StatusCode}, {ex.Message}");}catch(Exceptionex){Console.WriteLine($"Unexpected error: {ex.Message}");}Creating resources is type-safe and intuitive:
// Create a new dropletvarnewDroplet=newDroplet{Name="example-droplet",Region="nyc3",Size="s-1vcpu-1gb",Image=123456789,// Ubuntu image IDSshKeys=newList<int>{123456},// SSH key IDBackups=false,Ipv6=true,Monitoring=true,Tags=newList<string>{"web","production"}};varcreatedDroplet=awaitclient.Droplets.PostAsync(newDroplet);Console.WriteLine($"Created droplet with ID: {createdDroplet.Id}");The client includes strongly-typed models for all DigitalOcean entities. Here are some key models:
// Account informationpublicclassAccount{publicstringEmail{get;set;}publicstringStatus{get;set;}publicAccount_statusStatus_enum{get;set;}publicboolDroplet_limit{get;set;}publicboolEmail_verified{get;set;}publicAccount_teamTeam{get;set;}publicDateTimeOffsetCreated_at{get;set;}}// Droplet configurationpublicclassDroplet{publicintId{get;set;}publicstringName{get;set;}publicintMemory{get;set;}publicintVcpus{get;set;}publicintDisk{get;set;}publicstringRegion{get;set;}publicstringSize{get;set;}publicstringStatus{get;set;}// Additional properties...}// Many other models available...git clone https://github.com/InfinityFlowApp/InfinityFlow.DigitalOcean.Client.git
cd InfinityFlow.DigitalOcean.Client
dotnet builddotnet testThe client is generated using Kiota:
# Install Kiota
dotnet tool install -g Microsoft.OpenAPI.Kiota
# Get the OpenAPI specification
curl -o openapi.json https://raw.githubusercontent.com/digitalocean/openapi/master/specification/DigitalOcean-public.v2.yaml
# Generate the client
kiota generate --language CSharp --namespace InfinityFlow.DigitalOcean.Client --output-dir ./src/InfinityFlow.DigitalOcean.Client --openapi openapi.json --class-name DigitalOceanClient --clean-outputWe welcome contributions! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Generated using Microsoft Kiota
- API specification from DigitalOcean OpenAPI
| Issue | Solution |
|---|---|
| 401 Unauthorized | Verify your API token is valid and has the required scopes |
| 429 Too Many Requests | Implement rate limiting or exponential backoff in your application |
| Connection timeout | Check your network connection and DigitalOcean status page |
| Serialization errors | Ensure you're using the latest client version compatible with the API |
Enable detailed logging by configuring your logger:
// Setup logging (using Microsoft.Extensions.Logging)services.AddLogging(builder =>{builder.AddConsole();builder.AddDebug();builder.SetMinimumLevel(LogLevel.Debug);});// Add client with loggingservices.AddDigitalOceanClient(options =>{options.Token=Configuration["DigitalOcean:ApiToken"];options.EnableDebugLogging=true;});The DigitalOcean API implements rate limiting. You can handle this by checking response headers:
try{varresult=awaitclient.Droplets.GetAsync();// Process result}catch(DigitalOceanApiExceptionex)when(ex.StatusCode==429){// Get rate limit headersvarrateLimit=ex.ResponseHeaders.GetValueOrDefault("RateLimit-Limit");varrateLimitRemaining=ex.ResponseHeaders.GetValueOrDefault("RateLimit-Remaining");varrateLimitReset=ex.ResponseHeaders.GetValueOrDefault("RateLimit-Reset");// Implement backoff strategyvarresetTime=DateTimeOffset.FromUnixTimeSeconds(long.Parse(rateLimitReset));varwaitTime=resetTime-DateTimeOffset.UtcNow;Console.WriteLine($"Rate limited. Waiting for {waitTime.TotalSeconds} seconds before retrying.");awaitTask.Delay(waitTime);// Retry the requestresult=awaitclient.Droplets.GetAsync();}