Neuwo.Api
0.2.0
dotnet add package Neuwo.Api --version 0.2.0
NuGet\Install-Package Neuwo.Api -Version 0.2.0
<PackageReference Include="Neuwo.Api" Version="0.2.0" />
<PackageVersion Include="Neuwo.Api" Version="0.2.0" />
<PackageReference Include="Neuwo.Api" />
paket add Neuwo.Api --version 0.2.0
#r "nuget: Neuwo.Api, 0.2.0"
#:package Neuwo.Api@0.2.0
#addin nuget:?package=Neuwo.Api&version=0.2.0
#tool nuget:?package=Neuwo.Api&version=0.2.0
Neuwo API C# SDK
C# SDK client for the Neuwo content classification API.
Support
- Neuwo: https://neuwo.ai
- Documentation: https://docs.neuwo.ai
- Repository: GitHub
- Issues: GitHub Issues
- Email Support: neuwo-helpdesk@neuwo.ai
Installation
Install the package using the .NET CLI:
dotnet add package Neuwo.Api
Or via the NuGet Package Manager Console:
Install-Package Neuwo.Api
Or add it directly to your .csproj file:
<PackageReference Include="Neuwo.Api" Version="0.2.0" />
Requirements
Target Frameworks
This SDK supports:
- .NET 8.0 or higher
- .NET 9.0 or higher
Platform Support
The SDK is cross-platform and works on:
- Windows (x64, x86, ARM64)
- Linux (x64, ARM64)
- macOS (x64, ARM64)
Dependencies
Microsoft.Extensions.Logging.Abstractions9.0.0 (for optional logging support)
Note: The SDK uses HttpClient for all HTTP operations and supports modern .NET features including nullable reference types and async/await patterns.
Quick Start
For more detailed examples and use cases, see the examples folder in the repository.
REST API Client
using Neuwo.Api.Clients;
using Neuwo.Api.Configuration;
// Initialise client
var options = new NeuwoRestClientOptions
{
Token = "your-rest-api-token",
BaseUrl = "https://custom.api.com"
};
using var client = new NeuwoRestClient(options);
// Analyse text content
var response = await client.GetAiTopicsAsync(
content: "Cats make wonderful pets for modern households.",
documentId: "article-123",
headline: "Why Cats Make Great Pets"
);
// Access results
Console.WriteLine($"Tags: {response.Tags.Count}");
foreach (var tag in response.Tags)
{
Console.WriteLine($" - {tag.Value} (score: {tag.Score:F4})");
}
Console.WriteLine($"Brand Safe: {response.BrandSafety.IsSafe}");
Console.WriteLine($"IAB Categories: {response.MarketingCategories.IabTier1.Count}");
EDGE API Client
using Neuwo.Api.Clients;
using Neuwo.Api.Configuration;
// Initialise client
var options = new NeuwoEdgeClientOptions
{
Token = "your-edge-api-token",
BaseUrl = "https://custom.api.com",
DefaultOrigin = "https://yourwebsite.com" // Optional: default origin for requests
};
using var client = new NeuwoEdgeClient(options);
// Analyse article by URL
var response = await client.GetAiTopicsAsync(url: "https://example.com/article");
// Or wait for analysis to complete (with automatic retry)
var responseWithWait = await client.GetAiTopicsWaitAsync(
url: "https://example.com/new-article",
maxRetries: 10,
retryInterval: 6
);
Console.WriteLine($"Found {responseWithWait.Tags.Count} tags for the article");
Configuration
REST Client Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
Token |
string |
Required | REST API authentication token |
BaseUrl |
string |
Required | Base URL for the API |
Timeout |
int |
60 |
Request timeout in seconds |
Logger |
ILogger<NeuwoRestClient> |
null |
Optional logger instance |
var options = new NeuwoRestClientOptions
{
Token = "your-token",
BaseUrl = "https://custom.api.com",
Timeout = 120
};
using var client = new NeuwoRestClient(options);
EDGE Client Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
Token |
string |
Required | EDGE API authentication token |
BaseUrl |
string |
Required | Base URL for the API |
Timeout |
int |
60 |
Request timeout in seconds |
DefaultOrigin |
string |
null |
Default Origin header for requests |
Logger |
ILogger<NeuwoEdgeClient> |
null |
Optional logger instance |
var options = new NeuwoEdgeClientOptions
{
Token = "your-token",
BaseUrl = "https://custom.api.com",
DefaultOrigin = "https://yoursite.com",
Timeout = 90
};
using var client = new NeuwoEdgeClient(options);
API Methods
REST API
Get AI Topics
var response = await client.GetAiTopicsAsync(
content: "Text to analyse", // Required
documentId: "doc123", // Optional: save to database
lang: "en", // Optional: ISO 639-1 code
publicationId: "pub1", // Optional
headline: "Article Headline", // Optional
tagLimit: 15, // Optional: max tags (default: 15)
tagMinScore: 0.1f, // Optional: min score (default: 0.1)
marketingLimit: null, // Optional
marketingMinScore: 0.3f, // Optional (default: 0.3)
includeInSim: true, // Optional (default: true)
articleUrl: "https://example.com" // Optional
);
Get Similar Articles
var articles = await client.GetSimilarAsync(
documentId: "doc123", // Required
maxRows: 10, // Optional: limit results
pastDays: 30, // Optional: limit by date
publicationIds: new[] { "pub1", "pub2" } // Optional: filter by publication
);
Update Article
var article = await client.UpdateArticleAsync(
documentId: "doc123", // Required
published: new DateTime(2024, 1, 15), // Optional
headline: "Updated Headline", // Optional
writer: "Author Name", // Optional
category: "News", // Optional
content: "Updated content", // Optional
summary: "Summary", // Optional
publicationId: "pub1", // Optional
articleUrl: "https://example.com", // Optional
includeInSim: true // Optional
);
Train AI Topics
var trainingTags = await client.TrainAiTopicsAsync(
documentId: "doc123", // Required
tags: new[] { "tag1", "tag2", "tag3" } // Required
);
EDGE API
Get AI Topics (Single URL)
var response = await client.GetAiTopicsAsync(
url: "https://example.com/article", // Required
origin: "https://yoursite.com" // Optional: override default origin
);
Get AI Topics with Auto-Retry
var response = await client.GetAiTopicsWaitAsync(
url: "https://example.com/article", // Required
origin: "https://yoursite.com", // Optional
maxRetries: 10, // Optional (default: 10)
retryInterval: 6, // Optional (default: 6s)
initialDelay: 2 // Optional (default: 2s)
);
Raw Response Methods
All methods have *Raw variants that return the raw HttpResponseMessage object:
// REST
var rawResponse = await client.GetAiTopicsRawAsync(content: "Text");
Console.WriteLine(rawResponse.StatusCode);
Console.WriteLine(await rawResponse.Content.ReadAsStringAsync());
// EDGE
var rawResponse = await client.GetAiTopicsRawAsync(url: "https://example.com");
var json = await rawResponse.Content.ReadAsStringAsync();
Console.WriteLine(json);
Error Handling
The SDK provides specific exceptions for different error scenarios:
using Neuwo.Api.Clients;
using Neuwo.Api.Configuration;
using Neuwo.Api.Exceptions;
var options = new NeuwoRestClientOptions
{
Token = "your-token",
BaseUrl = "https://custom.api.com"
};
using var client = new NeuwoRestClient(options);
try
{
var response = await client.GetAiTopicsAsync(content: "Your content here");
}
catch (ValidationException ex)
{
Console.WriteLine($"Invalid input: {ex.Message}");
Console.WriteLine($"Validation details: {ex.ValidationDetails}");
}
catch (AuthenticationException ex)
{
Console.WriteLine($"Authentication failed: {ex.Message}");
}
catch (NoDataAvailableException ex)
{
Console.WriteLine($"Data not yet available: {ex.Message}");
}
catch (ContentNotAvailableException ex)
{
Console.WriteLine($"Content could not be analysed: {ex.Message}");
}
catch (NetworkException ex)
{
Console.WriteLine($"Network error: {ex.Message}");
}
catch (NeuwoApiException ex)
{
Console.WriteLine($"API error: {ex.Message}");
Console.WriteLine($"Status code: {ex.StatusCode}");
}
Exception Hierarchy
NeuwoApiException- Base exception for all API errorsAuthenticationException- Invalid or missing token (401)ForbiddenException- Token lacks permissions (403)NotFoundException- Resource not found (404)NoDataAvailableException- URL not yet processed (404)
BadRequestException- Malformed request (400)ValidationException- Request validation failed (422)RateLimitException- Rate limit exceeded (429)ServerException- Server error (5xx)NetworkException- Network communication failedContentNotAvailableException- Content tagging failedArgumentException- Parameter validation failed (client-side)
Logging
The SDK integrates with Microsoft.Extensions.Logging for comprehensive logging support. You can provide a logger instance to see detailed API communication:
using Microsoft.Extensions.Logging;
using Neuwo.Api.Clients;
using Neuwo.Api.Configuration;
// Create logger factory
using var loggerFactory = LoggerFactory.Create(builder =>
{
builder
.AddConsole()
.SetMinimumLevel(LogLevel.Debug);
});
var logger = loggerFactory.CreateLogger<NeuwoRestClient>();
// Pass logger to client
var options = new NeuwoRestClientOptions
{
Token = "your-token",
BaseUrl = "https://custom.api.com",
Logger = logger
};
using var client = new NeuwoRestClient(options);
Available log levels:
LogLevel.Debug- Detailed API request/response informationLogLevel.Information- General operation infoLogLevel.Warning- Warnings (default)LogLevel.Error- Errors onlyLogLevel.None- Disable all logging
Note: Sensitive information like tokens are automatically sanitized in log output.
Dependency Injection
The SDK works seamlessly with .NET's built-in Dependency Injection:
ASP.NET Core Integration
using Neuwo.Api.Clients;
using Neuwo.Api.Configuration;
var builder = WebApplication.CreateBuilder(args);
// Register REST client
builder.Services.AddSingleton<NeuwoRestClient>(sp =>
{
var logger = sp.GetRequiredService<ILogger<NeuwoRestClient>>();
var options = new NeuwoRestClientOptions
{
Token = builder.Configuration["Neuwo:RestToken"],
BaseUrl = builder.Configuration["Neuwo:BaseUrl"],
Logger = logger
};
return new NeuwoRestClient(options);
});
// Register EDGE client
builder.Services.AddSingleton<NeuwoEdgeClient>(sp =>
{
var logger = sp.GetRequiredService<ILogger<NeuwoEdgeClient>>();
var options = new NeuwoEdgeClientOptions
{
Token = builder.Configuration["Neuwo:EdgeToken"],
BaseUrl = builder.Configuration["Neuwo:BaseUrl"],
DefaultOrigin = builder.Configuration["Neuwo:DefaultOrigin"],
Logger = logger
};
return new NeuwoEdgeClient(options);
});
var app = builder.Build();
Usage in Controllers
using Microsoft.AspNetCore.Mvc;
using Neuwo.Api.Clients;
[ApiController]
[Route("api/[controller]")]
public class ContentController : ControllerBase
{
private readonly NeuwoRestClient _neuwoClient;
private readonly ILogger<ContentController> _logger;
public ContentController(NeuwoRestClient neuwoClient, ILogger<ContentController> logger)
{
_neuwoClient = neuwoClient;
_logger = logger;
}
[HttpPost("analyse")]
public async Task<IActionResult> AnalyseContent([FromBody] string content)
{
try
{
var response = await _neuwoClient.GetAiTopicsAsync(content: content);
return Ok(response);
}
catch (NeuwoApiException ex)
{
_logger.LogError(ex, "Failed to analyse content");
return StatusCode((int?)ex.StatusCode ?? 500, ex.Message);
}
}
}
Configuration via appsettings.json
{
"Neuwo": {
"RestToken": "your-rest-token",
"EdgeToken": "your-edge-token",
"BaseUrl": "https://api.neuwo.ai",
"DefaultOrigin": "https://yourwebsite.com"
}
}
Development
Setup Development Environment
# Clone repository
git clone https://github.com/neuwoai/neuwo-api-sdk-csharp.git
cd neuwo-api-sdk-csharp
# Restore dependencies
dotnet restore
# Build the solution
dotnet build
Running Tests
# Run all tests
dotnet test
# Run with detailed output
dotnet test --verbosity normal
# Run specific test project
dotnet test Neuwo.Api.Tests/Neuwo.Api.Tests.csproj
# Run tests with code coverage
dotnet test --collect:"XPlat Code Coverage"
# Install coverage report generator (one-time)
dotnet tool install --global dotnet-reportgenerator-globaltool
# Generate and display coverage summary
reportgenerator -reports:"**/coverage.cobertura.xml" -targetdir:"coveragereport" -reporttypes:TextSummary
cat coveragereport/Summary.txt
# Generate HTML report for detailed analysis
reportgenerator -reports:"**/coverage.cobertura.xml" -targetdir:"coveragereport" -reporttypes:Html
# Open coveragereport/index.html in browser
Code Quality
The project uses .editorconfig for consistent code style enforcement.
# Format code (requires .NET 6+ SDK)
dotnet format
# Check formatting without making changes
dotnet format --verify-no-changes
# Build with warnings as errors (enforced in Release mode)
dotnet build --configuration Release
Building Distribution
# Build in Release mode
dotnet build --configuration Release
# Create NuGet package
dotnet pack --configuration Release --output ./artifacts
# Verify package contents
unzip -l ./artifacts/Neuwo.Api.*.nupkg
Pre-publish Package Validation
Before publishing, validate your package to ensure it's configured correctly:
# Build the package
dotnet pack Neuwo.Api/Neuwo.Api.csproj --configuration Release --output ./artifacts
# Verify package contents
unzip -l ./artifacts/*.nupkg
# Check multi-targeting (should show lib/net8.0/ and lib/net9.0/)
unzip -l ./artifacts/*.nupkg | grep "lib/"
# Test package installation locally
dotnet add package Neuwo.Api --source ./artifacts
# Verify package metadata
dotnet nuget verify ./artifacts/*.nupkg
These validation steps are automatically run in the CI/CD pipeline before publishing.
CI/CD
Automated Testing
The Unit Tests Coverage workflow automatically runs on every push to main or dev branches and on pull requests:
- .NET versions tested: 8.0.x, 9.0.x
- Coverage reporting: XPlat Code Coverage
- Test execution: Full test suite with code coverage analysis
- Platform: Ubuntu Linux (cross-platform compatible)
Publishing Pipeline
The Publish C# SDK workflow enables manual deployment with the following options:
Workflow Features:
- Manual trigger via GitHub Actions UI
- Deploy to NuGet gallery
- Auto-create GitHub releases with tags
- Automatic version extraction from
Directory.Build.props - Package integrity verification (multi-targeting validation)
- Symbol packages (
.snupkg) for debugging support
Setup Requirements:
Add GitHub secrets for API tokens:
NUGET_PUBLISHING_TOKEN- NuGet API key for publishing
Workflow Inputs
| Input | Type | Default | Description |
|---|---|---|---|
publish_to_nuget |
boolean | true | Publish to NuGet gallery |
create_release |
boolean | true | Create GitHub release with tag |
Usage:
Prepare release:
- Update version in
Neuwo.Api/Neuwo.Api.csproj(or centralised version file) - Update version badges in README.md if needed
- Commit changes to repository
- Update version in
Publish:
- Go to Actions > Publish C# SDK > Run workflow
- Select desired options (NuGet, GitHub release)
- Creates tag (e.g.,
v1.0.0), GitHub release, and publishes to NuGet
Verify:
- Check NuGet: https://www.nuget.org/packages/Neuwo.Api
- Check GitHub Release: https://github.com/neuwoai/neuwo-api-sdk-csharp/releases
- Test installation:
dotnet add package Neuwo.Api
What gets created:
- NuGet package: https://www.nuget.org/packages/Neuwo.Api
- Symbol package (
.snupkg) for debugging - GitHub release with
.nupkgand.snupkgfiles - Git tag following
v{VERSION}format
Versioning:
Follow Semantic Versioning (MAJOR.MINOR.PATCH):
- MAJOR: Breaking changes
- MINOR: New features (backward compatible)
- PATCH: Bug fixes (backward compatible)
Licence
This project is licensed under the MIT Licence - see the LICENCE file for details.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. 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 is compatible. 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. |
-
net8.0
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.0)
-
net9.0
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.