Files
viewengine.client/Examples.md

12 KiB

ViewEngine.Client Usage Examples

Table of Contents

Basic Usage

Simple Web Page Retrieval

using ViewEngine.Client;
using ViewEngine.Client.Models;

// Create client
var client = new ViewEngineClient("ak_your-api-key-here");

// Retrieve a page
var request = new SubmitRetrievalRequest
{
    Url = "https://example.com"
};

var pageData = await client.RetrieveAndWaitAsync(request);

Console.WriteLine($"Title: {pageData.Title}");
Console.WriteLine($"Body: {pageData.Body}");
Console.WriteLine($"Found {pageData.Routes.Count} navigation links");

Manual Polling

// Submit request
var submitResponse = await client.SubmitRetrievalAsync(new SubmitRetrievalRequest
{
    Url = "https://example.com",
    TimeoutSeconds = 60,
    Priority = 5
});

Console.WriteLine($"Request ID: {submitResponse.RequestId}");
Console.WriteLine($"Status: {submitResponse.Status}");

// Poll for completion
while (true)
{
    var status = await client.GetRetrievalStatusAsync(submitResponse.RequestId);

    Console.WriteLine($"Current status: {status.Status}");

    if (status.Status == "complete")
    {
        var content = await client.GetPageContentAsync(submitResponse.RequestId);
        Console.WriteLine($"Title: {content.Title}");
        break;
    }
    else if (status.Status == "failed")
    {
        Console.WriteLine($"Failed: {status.Error}");
        break;
    }

    await Task.Delay(2000); // Poll every 2 seconds
}

ASP.NET Core Integration

Minimal API Example

Program.cs:

using ViewEngine.Client;
using ViewEngine.Client.Extensions;
using ViewEngine.Client.Models;

var builder = WebApplication.CreateBuilder(args);

// Add ViewEngine client from configuration
builder.Services.AddViewEngineClient(builder.Configuration);

var app = builder.Build();

// Simple endpoint
app.MapGet("/retrieve/{url}", async (string url, ViewEngineClient client) =>
{
    var request = new SubmitRetrievalRequest { Url = url };
    var pageData = await client.RetrieveAndWaitAsync(request);

    return Results.Ok(new
    {
        pageData.Title,
        pageData.Url,
        LinkCount = pageData.Routes.Count + pageData.BodyRoutes.Count
    });
});

// Endpoint with custom parameters
app.MapPost("/retrieve", async (SubmitRetrievalRequest request, ViewEngineClient client) =>
{
    var pageData = await client.RetrieveAndWaitAsync(request);
    return Results.Ok(pageData);
});

app.Run();

appsettings.json:

{
  "ViewEngine": {
    "ApiKey": "ak_your-api-key-here",
    "BaseUrl": "https://www.viewengine.io/api/v1",
    "TimeoutSeconds": 120,
    "MaxRetries": 3,
    "DefaultPollingIntervalMs": 2000
  }
}

Controller Example

using Microsoft.AspNetCore.Mvc;
using ViewEngine.Client;
using ViewEngine.Client.Models;

[ApiController]
[Route("api/[controller]")]
public class WebPagesController : ControllerBase
{
    private readonly ViewEngineClient _client;
    private readonly ILogger<WebPagesController> _logger;

    public WebPagesController(ViewEngineClient client, ILogger<WebPagesController> logger)
    {
        _client = client;
        _logger = logger;
    }

    [HttpPost("retrieve")]
    public async Task<ActionResult<PageData>> RetrievePage([FromBody] SubmitRetrievalRequest request)
    {
        try
        {
            _logger.LogInformation("Retrieving page: {Url}", request.Url);

            var pageData = await _client.RetrieveAndWaitAsync(request);

            return Ok(pageData);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to retrieve page: {Url}", request.Url);
            return StatusCode(500, new { error = ex.Message });
        }
    }

    [HttpGet("status/{requestId}")]
    public async Task<ActionResult<RetrievalStatusResponse>> GetStatus(Guid requestId)
    {
        var status = await _client.GetRetrievalStatusAsync(requestId);
        return Ok(status);
    }
}

Console Application

using System;
using System.Threading.Tasks;
using ViewEngine.Client;
using ViewEngine.Client.Models;

class Program
{
    static async Task Main(string[] args)
    {
        // Get API key from environment variable or args
        var apiKey = Environment.GetEnvironmentVariable("VIEWENGINE_API_KEY")
            ?? args.FirstOrDefault()
            ?? throw new Exception("API key required");

        using var client = new ViewEngineClient(apiKey);

        Console.WriteLine("ViewEngine Client Demo");
        Console.WriteLine("======================");

        while (true)
        {
            Console.Write("\nEnter URL to retrieve (or 'quit' to exit): ");
            var url = Console.ReadLine();

            if (string.IsNullOrWhiteSpace(url) || url.Equals("quit", StringComparison.OrdinalIgnoreCase))
                break;

            await RetrievePageAsync(client, url);
        }
    }

    static async Task RetrievePageAsync(ViewEngineClient client, string url)
    {
        try
        {
            Console.WriteLine($"\nRetrieving: {url}");

            var request = new SubmitRetrievalRequest
            {
                Url = url,
                TimeoutSeconds = 60,
                Priority = 5
            };

            var submitResponse = await client.SubmitRetrievalAsync(request);
            Console.WriteLine($"Request ID: {submitResponse.RequestId}");
            Console.WriteLine($"Status: {submitResponse.Status}");

            // Poll for completion
            RetrievalStatusResponse status;
            do
            {
                await Task.Delay(2000);
                status = await client.GetRetrievalStatusAsync(submitResponse.RequestId);
                Console.WriteLine($"Status: {status.Status} - {status.Message}");
            }
            while (status.Status == "queued" || status.Status == "processing");

            if (status.Status == "complete")
            {
                var pageData = await client.GetPageContentAsync(submitResponse.RequestId);

                Console.WriteLine($"\n--- Page Data ---");
                Console.WriteLine($"Title: {pageData.Title}");
                Console.WriteLine($"URL: {pageData.Url}");
                Console.WriteLine($"Meta Description: {pageData.MetaDescription}");
                Console.WriteLine($"Body Length: {pageData.Body?.Length ?? 0} characters");

                Console.WriteLine($"\n--- Navigation Links ({pageData.Routes.Count}) ---");
                foreach (var link in pageData.Routes.Take(5))
                {
                    Console.WriteLine($"  [{link.Rank}] {link.Text} -> {link.Url}");
                }

                Console.WriteLine($"\n--- Body Links ({pageData.BodyRoutes.Count}) ---");
                foreach (var link in pageData.BodyRoutes.Take(5))
                {
                    var adMarker = link.IsPotentialAd ? "[AD] " : "";
                    Console.WriteLine($"  {adMarker}[{link.Rank}] {link.Text} -> {link.Url}");
                }
            }
            else
            {
                Console.WriteLine($"\nRetrieval failed: {status.Error}");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"\nError: {ex.Message}");
        }
    }
}

Advanced Scenarios

Client Management

// Add a new client
var addRequest = new AddClientRequest
{
    Email = "feeder@example.com",
    Alias = "Production Feeder #1",
    CustomUserId = "prod-feeder-001",
    DailyMaximum = 1000
};

var client = await viewEngineClient.AddClientAsync(addRequest);
Console.WriteLine($"Added client: {client.Id}");

// Route job to this specific client
var retrievalRequest = new SubmitRetrievalRequest
{
    Url = "https://example.com",
    ClientId = client.Id  // Use the client's ID
};

// Or use custom user ID
var retrievalRequest2 = new SubmitRetrievalRequest
{
    Url = "https://example.com",
    CustomUserId = "prod-feeder-001"
};

// List all clients
var clients = await viewEngineClient.GetClientsAsync();
foreach (var c in clients)
{
    Console.WriteLine($"{c.Alias}: {(c.FeederOnline ? "Online" : "Offline")}");
    Console.WriteLine($"  Jobs today: {c.JobsProcessedToday}/{c.DailyMaximum}");
}

// Get client statistics
var stats = await viewEngineClient.GetClientStatsAsync(client.Id);
Console.WriteLine($"Total jobs: {stats.TotalJobsProcessed}");
Console.WriteLine($"Success rate: {stats.SuccessRate:F2}%");
Console.WriteLine($"Avg processing time: {stats.AverageProcessingTimeMs:F0}ms");

// Update client settings
await viewEngineClient.UpdateClientAsync(client.Id, new UpdateClientRequest
{
    DailyMaximum = 2000,
    Alias = "Production Feeder #1 (Updated)"
});

// Suspend client
await viewEngineClient.SuspendClientAsync(client.Id);

// Reactivate
await viewEngineClient.ActivateClientAsync(client.Id);

// Delete client
await viewEngineClient.DeleteClientAsync(client.Id);

Platform-Specific Retrieval

// Request page to be rendered on specific platform
var request = new SubmitRetrievalRequest
{
    Url = "https://example.com",
    PreferredPlatform = "Windows"  // or "Android", "iOS"
};

var pageData = await client.RetrieveAndWaitAsync(request);

High Priority Jobs

var request = new SubmitRetrievalRequest
{
    Url = "https://example.com",
    Priority = 10,  // Highest priority (1-10)
    TimeoutSeconds = 300  // Max 5 minutes
};

Batch Processing

var urls = new[]
{
    "https://example.com",
    "https://another-example.com",
    "https://third-example.com"
};

// Submit all requests
var submitTasks = urls.Select(url => client.SubmitRetrievalAsync(new SubmitRetrievalRequest
{
    Url = url,
    Priority = 5
}));

var submitResponses = await Task.WhenAll(submitTasks);

// Wait for all to complete
var tasks = submitResponses.Select(async response =>
{
    while (true)
    {
        var status = await client.GetRetrievalStatusAsync(response.RequestId);

        if (status.Status == "complete")
        {
            return await client.GetPageContentAsync(response.RequestId);
        }
        else if (status.Status == "failed")
        {
            throw new Exception($"Failed to retrieve {status.Url}");
        }

        await Task.Delay(2000);
    }
});

var results = await Task.WhenAll(tasks);

foreach (var pageData in results)
{
    Console.WriteLine($"{pageData.Title} - {pageData.Url}");
}

Error Handling

try
{
    var pageData = await client.RetrieveAndWaitAsync(request);
}
catch (HttpRequestException ex) when (ex.StatusCode == System.Net.HttpStatusCode.Unauthorized)
{
    Console.WriteLine("Invalid API key");
}
catch (HttpRequestException ex) when (ex.StatusCode == System.Net.HttpStatusCode.TooManyRequests)
{
    Console.WriteLine("Rate limit exceeded");
}
catch (InvalidOperationException ex) when (ex.Message.Contains("failed"))
{
    Console.WriteLine($"Retrieval failed: {ex.Message}");
}
catch (OperationCanceledException)
{
    Console.WriteLine("Request was canceled");
}
catch (Exception ex)
{
    Console.WriteLine($"Unexpected error: {ex.Message}");
}

Custom Timeout and Retry Settings

var options = new ViewEngineOptions
{
    ApiKey = "ak_your-api-key-here",
    TimeoutSeconds = 180,  // 3 minutes
    MaxRetries = 5,
    BaseDelayMs = 500,
    DefaultPollingIntervalMs = 1000  // Poll every second
};

using var client = new ViewEngineClient(options);

Dependency Injection with Multiple Clients

// Configure multiple named clients
builder.Services.AddHttpClient<ViewEngineClient>("Primary")
    .ConfigureHttpClient((sp, client) =>
    {
        client.BaseAddress = new Uri("https://www.viewengine.io/api/v1");
        client.DefaultRequestHeaders.Add("X-API-Key", "ak_primary_key");
    });

builder.Services.AddHttpClient<ViewEngineClient>("Secondary")
    .ConfigureHttpClient((sp, client) =>
    {
        client.BaseAddress = new Uri("https://www.viewengine.io/api/v1");
        client.DefaultRequestHeaders.Add("X-API-Key", "ak_secondary_key");
    });