feat: Krea Image Generation Endpoint
- KreaService: GenerateAsync() mit Job-Polling, Image-Download, Metadaten-Speicherung
- KreaEndpoint: POST /api/images/generate, GET /api/images, GET /api/images/file/{filename}, GET /api/images/status
- KreaImageRecord: Output-Model
- Output: data/images/<timestamp>-<index>.<ext> + data/images/<timestamp>.json
- 16 Modelle: flux, flux-kontext, flux-1.1-pro, imagen-3/4, chatgpt-image, runway-gen-4, etc.
- appsettings.json: KreaToken (Format: KEY_ID:SECRET), obsolete TelegramBotToken/WebhookSecret entfernt
This commit is contained in:
1 parent
f552b44b05
commit
26da25967d
5 files changed
+443
-1
No files matched your search
@@ -0,0 +1,112 @@
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Gott.Services;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
|
||||
namespace Gott.Endpoints
|
||||
{
|
||||
public static class KreaEndpoint
|
||||
{
|
||||
public static void MapKreaEndpoints(this IEndpointRouteBuilder app)
|
||||
{
|
||||
app.MapPost("/api/images/generate", HandleGenerate);
|
||||
app.MapGet("/api/images", HandleList);
|
||||
app.MapGet("/api/images/file/{filename}", HandleFile);
|
||||
app.MapGet("/api/images/status", HandleStatus);
|
||||
}
|
||||
|
||||
private static async Task HandleGenerate(HttpRequest req, HttpResponse res, KreaService krea)
|
||||
{
|
||||
if (!krea.IsConfigured)
|
||||
{
|
||||
res.StatusCode = 400;
|
||||
await res.WriteAsJsonAsync(new { error = "Krea API nicht konfiguriert (KreaToken fehlt)" });
|
||||
return;
|
||||
}
|
||||
|
||||
JsonElement body;
|
||||
try { body = await JsonSerializer.DeserializeAsync<JsonElement>(req.Body); }
|
||||
catch
|
||||
{
|
||||
res.StatusCode = 400;
|
||||
await res.WriteAsJsonAsync(new { error = "Ungültiger JSON-Body" });
|
||||
return;
|
||||
}
|
||||
|
||||
var prompt = body.TryGetProperty("prompt", out var p) ? p.GetString() : null;
|
||||
if (string.IsNullOrWhiteSpace(prompt))
|
||||
{
|
||||
res.StatusCode = 400;
|
||||
await res.WriteAsJsonAsync(new { error = "prompt ist erforderlich" });
|
||||
return;
|
||||
}
|
||||
|
||||
var model = body.TryGetProperty("model", out var m) ? m.GetString() : "flux";
|
||||
var width = body.TryGetProperty("width", out var w) ? w.GetInt32() : 1024;
|
||||
var height = body.TryGetProperty("height", out var h) ? h.GetInt32() : 1024;
|
||||
var steps = body.TryGetProperty("steps", out var st) ? st.GetInt32() : 25;
|
||||
var guidanceScale = body.TryGetProperty("guidanceScale", out var g) ? g.GetDouble() : 3.0;
|
||||
var seed = body.TryGetProperty("seed", out var sd) ? sd.GetString() : null;
|
||||
var batchSize = body.TryGetProperty("batchSize", out var b) ? b.GetInt32() : 1;
|
||||
|
||||
try
|
||||
{
|
||||
var result = await krea.GenerateAsync(prompt, model, width, height, steps, guidanceScale, seed, batchSize);
|
||||
await res.WriteAsJsonAsync(result);
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
res.StatusCode = 500;
|
||||
await res.WriteAsJsonAsync(new { error = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task HandleList(HttpRequest req, HttpResponse res, KreaService krea)
|
||||
{
|
||||
var images = krea.ListImages();
|
||||
await res.WriteAsJsonAsync(images);
|
||||
}
|
||||
|
||||
private static async Task HandleFile(HttpRequest req, HttpResponse res, KreaService krea, string filename)
|
||||
{
|
||||
// Sicherheitscheck – kein Path Traversal
|
||||
if (filename.Contains("..") || filename.Contains("/") || filename.Contains("\\"))
|
||||
{
|
||||
res.StatusCode = 400;
|
||||
return;
|
||||
}
|
||||
|
||||
var path = krea.GetImagePath(filename);
|
||||
if (path == null)
|
||||
{
|
||||
res.StatusCode = 404;
|
||||
return;
|
||||
}
|
||||
|
||||
var ext = Path.GetExtension(filename).ToLower();
|
||||
var contentType = ext switch
|
||||
{
|
||||
".png" => "image/png",
|
||||
".jpg" => "image/jpeg",
|
||||
".jpeg" => "image/jpeg",
|
||||
".gif" => "image/gif",
|
||||
_ => "image/webp",
|
||||
};
|
||||
|
||||
res.ContentType = contentType;
|
||||
await res.SendFileAsync(path);
|
||||
}
|
||||
|
||||
private static async Task HandleStatus(HttpRequest req, HttpResponse res, KreaService krea)
|
||||
{
|
||||
await res.WriteAsJsonAsync(new
|
||||
{
|
||||
configured = krea.IsConfigured,
|
||||
models = KreaService.IMAGE_MODELS.Keys,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user