120 lines
3.2 KiB
C#
120 lines
3.2 KiB
C#
using Microsoft.SemanticKernel;
|
|
using Microsoft.SemanticKernel.ChatCompletion;
|
|
using VideoStudy.Shared;
|
|
using Microsoft.AspNetCore.RateLimiting;
|
|
using System.Threading.RateLimiting;
|
|
using VideoStudy.API.Services;
|
|
|
|
#pragma warning disable SKEXP0010 // Ollama connector is experimental
|
|
|
|
var builder = WebApplication.CreateBuilder(args);
|
|
|
|
// Add Services
|
|
builder.Services.AddScoped<AnalysisService>();
|
|
|
|
// Add CORS
|
|
builder.Services.AddCors(options =>
|
|
{
|
|
options.AddPolicy("AllowAll", policyBuilder =>
|
|
{
|
|
policyBuilder
|
|
.AllowAnyOrigin()
|
|
.AllowAnyMethod()
|
|
.AllowAnyHeader();
|
|
});
|
|
});
|
|
|
|
// Add Swagger
|
|
builder.Services.AddEndpointsApiExplorer();
|
|
builder.Services.AddSwaggerGen();
|
|
|
|
// Configure AI Provider (Ollama or Groq)
|
|
var aiProvider = builder.Configuration["LlmSettings:Provider"] ?? "Ollama";
|
|
|
|
builder.Services.AddKernel();
|
|
|
|
if (aiProvider.Equals("Ollama", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
var ollamaUrl = builder.Configuration["LlmSettings:Ollama:BaseUrl"] ?? "http://localhost:11434";
|
|
var ollamaModel = builder.Configuration["LlmSettings:Ollama:Model"] ?? "llama3.1";
|
|
|
|
builder.Services.AddOpenAIChatCompletion(
|
|
modelId: ollamaModel,
|
|
apiKey: "ollama",
|
|
endpoint: new Uri($"{ollamaUrl}/v1")
|
|
);
|
|
}
|
|
else if (aiProvider.Equals("Groq", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
var groqApiKey = builder.Configuration["LlmSettings:Groq:ApiKey"]
|
|
?? builder.Configuration["LlmSettings:ApiKey"]
|
|
?? Environment.GetEnvironmentVariable("GROQ_API_KEY")
|
|
?? "";
|
|
|
|
var groqModel = builder.Configuration["LlmSettings:Groq:Model"]
|
|
?? builder.Configuration["LlmSettings:ModelId"]
|
|
?? "llama-3.3-70b-versatile";
|
|
|
|
var groqBaseUrl = builder.Configuration["LlmSettings:Groq:BaseUrl"]
|
|
?? builder.Configuration["LlmSettings:Endpoint"]
|
|
?? "https://api.groq.com/openai/v1";
|
|
|
|
builder.Services.AddOpenAIChatCompletion(
|
|
modelId: groqModel,
|
|
apiKey: groqApiKey,
|
|
endpoint: new Uri(groqBaseUrl)
|
|
);
|
|
}
|
|
|
|
// Add Rate Limiting
|
|
builder.Services.AddRateLimiter(options =>
|
|
{
|
|
options.AddFixedWindowLimiter("api", opt =>
|
|
{
|
|
opt.Window = TimeSpan.FromMinutes(1);
|
|
opt.PermitLimit = 60;
|
|
});
|
|
});
|
|
|
|
var app = builder.Build();
|
|
|
|
// Enable Rate Limiting
|
|
app.UseRateLimiter();
|
|
|
|
// Enable Swagger
|
|
if (app.Environment.IsDevelopment())
|
|
{
|
|
app.UseSwagger();
|
|
app.UseSwaggerUI();
|
|
}
|
|
|
|
app.UseCors("AllowAll");
|
|
|
|
app.MapGet("/health", () => Results.Ok(new { status = "healthy", timestamp = DateTime.UtcNow }));
|
|
|
|
// Video info endpoint (lightweight preview)
|
|
app.MapGet("/api/video-info", async (string url, AnalysisService service) =>
|
|
{
|
|
try
|
|
{
|
|
var info = await service.GetVideoInfoAsync(url, CancellationToken.None);
|
|
return Results.Ok(info);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return Results.BadRequest(new { error = ex.Message });
|
|
}
|
|
})
|
|
.WithName("GetVideoInfo");
|
|
|
|
// Main analysis endpoint
|
|
app.MapPost("/api/analyze", (AnalysisRequest request, AnalysisService service, CancellationToken cancellationToken) =>
|
|
{
|
|
return service.AnalyzeVideoAsync(request, cancellationToken);
|
|
})
|
|
.WithName("AnalyzeVideo");
|
|
|
|
app.Run();
|
|
|
|
#pragma warning restore SKEXP0010
|