Neuwo.Api 0.2.0

dotnet add package Neuwo.Api --version 0.2.0
                    
NuGet\Install-Package Neuwo.Api -Version 0.2.0
                    
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="Neuwo.Api" Version="0.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Neuwo.Api" Version="0.2.0" />
                    
Directory.Packages.props
<PackageReference Include="Neuwo.Api" />
                    
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 Neuwo.Api --version 0.2.0
                    
#r "nuget: Neuwo.Api, 0.2.0"
                    
#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 Neuwo.Api@0.2.0
                    
#: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=Neuwo.Api&version=0.2.0
                    
Install as a Cake Addin
#tool nuget:?package=Neuwo.Api&version=0.2.0
                    
Install as a Cake Tool

Neuwo API C# SDK

C# SDK client for the Neuwo content classification API.

NuGet version .NET Licence: MIT

Support

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.Abstractions 9.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 errors
    • AuthenticationException - 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 failed
    • ContentNotAvailableException - Content tagging failed
    • ArgumentException - 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 information
  • LogLevel.Information - General operation info
  • LogLevel.Warning - Warnings (default)
  • LogLevel.Error - Errors only
  • LogLevel.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:
  1. 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
  2. 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
  3. Verify:

What gets created:

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 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. 
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
0.2.0 361 11/21/2025
0.1.0 416 11/20/2025