реструктуризация файлов, добавление вебчатов
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
unit uKandinskyAPI;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
System.SysUtils, System.Classes, System.JSON, System.Net.HttpClient,
|
||||
System.Net.URLClient, System.NetConsts, StrUtils, System.Net.Mime,
|
||||
System.NetEncoding, System.Threading;
|
||||
|
||||
type
|
||||
TGenerationDoneEvent = procedure(Sender: TObject; const FileName: string) of object;
|
||||
TStatusUpdateEvent = procedure(Sender: TObject; const Message: string) of object;
|
||||
TErrorEvent = procedure(Sender: TObject; const ErrorMessage: string) of object;
|
||||
|
||||
TFusionBrainAPI = class(TComponent)
|
||||
private
|
||||
FBaseURL: string;
|
||||
FApiKey: string;
|
||||
FSecretKey: string;
|
||||
FClient: THTTPClient;
|
||||
FOnGenerationDone: TGenerationDoneEvent;
|
||||
FOnStatusUpdate: TStatusUpdateEvent;
|
||||
FOnError: TErrorEvent;
|
||||
|
||||
procedure DoStatusUpdate(const AMessage: string);
|
||||
procedure DoGenerationDone(const AFileName: string);
|
||||
procedure DoError(const AErrorMessage: string);
|
||||
function GetAuthHeaders: TNetHeaders;
|
||||
function GetPipeline: string;
|
||||
function Generate(const Prompt, PipelineId: string): string;
|
||||
function CheckGeneration(const RequestId: string): TArray<string>;
|
||||
procedure SaveBase64Image(const Base64Str, FileName: string);
|
||||
public
|
||||
constructor Create(AOwner: TComponent; aKey:string; aSecret:string);
|
||||
destructor Destroy; override;
|
||||
procedure StartGeneration(const APrompt: string);
|
||||
|
||||
property OnGenerationDone: TGenerationDoneEvent read FOnGenerationDone write FOnGenerationDone;
|
||||
property OnStatusUpdate: TStatusUpdateEvent read FOnStatusUpdate write FOnStatusUpdate;
|
||||
property OnError: TErrorEvent read FOnError write FOnError;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses ugeneral;
|
||||
|
||||
constructor TFusionBrainAPI.Create(AOwner: TComponent; aKey:string; aSecret:string);
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
FClient := THTTPClient.Create;
|
||||
FBaseURL := 'https://api-key.fusionbrain.ai/';
|
||||
FApiKey :=aKey;
|
||||
// FApiKey := '28C9C30489D635732FB04AA6B85F0671';
|
||||
FSecretKey := aSecret;
|
||||
// FSecretKey := '805CB624C052202A05E3F40C0582045A';
|
||||
end;
|
||||
|
||||
destructor TFusionBrainAPI.Destroy;
|
||||
begin
|
||||
FClient.Free;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
procedure TFusionBrainAPI.StartGeneration(const APrompt: string);
|
||||
begin
|
||||
TTask.Run(procedure
|
||||
var
|
||||
PipelineID, UUID, FileName: string;
|
||||
Links: TArray<string>;
|
||||
begin
|
||||
try
|
||||
TThread.Queue(nil, procedure begin DoStatusUpdate('Ïîëó÷åíèå êîíâåéåðà...'); end);
|
||||
PipelineID := GetPipeline;
|
||||
|
||||
TThread.Queue(nil, procedure begin DoStatusUpdate('Ãåíåðàöèÿ èçîáðàæåíèÿ...'); end);
|
||||
UUID := Generate(APrompt, PipelineID);
|
||||
|
||||
TThread.Queue(nil, procedure begin DoStatusUpdate('Ïðîâåðêà ñòàòóñà...'); end);
|
||||
Links := CheckGeneration(UUID);
|
||||
|
||||
FileName := myConst.AppDataPath + 'imgs\kandinsky_' + FormatDateTime('yyyymmddhhnnss', Now) + '.jpg';
|
||||
SaveBase64Image(Links[0], FileName);
|
||||
|
||||
TThread.Queue(nil, procedure begin DoGenerationDone(FileName); end);
|
||||
except
|
||||
on E: Exception do
|
||||
TThread.Queue(nil, procedure begin DoError(E.Message); end);
|
||||
end;
|
||||
end);
|
||||
end;
|
||||
|
||||
function TFusionBrainAPI.GetAuthHeaders: TNetHeaders;
|
||||
begin
|
||||
SetLength(Result, 2);
|
||||
Result[0] := TNetHeader.Create('X-Key', 'Key ' + FApiKey);
|
||||
Result[1] := TNetHeader.Create('X-Secret', 'Secret ' + FSecretKey);
|
||||
end;
|
||||
|
||||
function TFusionBrainAPI.GetPipeline: string;
|
||||
var
|
||||
Response: IHTTPResponse;
|
||||
Json: TJSONArray;
|
||||
begin
|
||||
Response := FClient.Get(FBaseURL + 'key/api/v1/pipelines', nil, GetAuthHeaders);
|
||||
Json := TJSONObject.ParseJSONValue(Response.ContentAsString) as TJSONArray;
|
||||
try
|
||||
Result := Json.Items[0].GetValue<string>('id');
|
||||
finally
|
||||
Json.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TFusionBrainAPI.Generate(const Prompt, PipelineId: string): string;
|
||||
var
|
||||
Params, Root: TJSONObject;
|
||||
Multipart: TMultipartFormData;
|
||||
Response: IHTTPResponse;
|
||||
Json: TJSONObject;
|
||||
begin
|
||||
Root := TJSONObject.Create;
|
||||
try
|
||||
Params := TJSONObject.Create;
|
||||
Params.AddPair('query', Prompt);
|
||||
|
||||
Root.AddPair('type', 'GENERATE');
|
||||
Root.AddPair('numImages', TJSONNumber.Create(1));
|
||||
Root.AddPair('width', TJSONNumber.Create(512));
|
||||
Root.AddPair('height', TJSONNumber.Create(512));
|
||||
Root.AddPair('generateParams', Params);
|
||||
|
||||
Multipart := TMultipartFormData.Create;
|
||||
try
|
||||
Multipart.AddField('pipeline_id', PipelineId);
|
||||
Multipart.AddField('params', Root.ToString, 'application/json');
|
||||
|
||||
Response := FClient.Post(FBaseURL + 'key/api/v1/pipeline/run', Multipart, nil, GetAuthHeaders);
|
||||
Json := TJSONObject.ParseJSONValue(Response.ContentAsString) as TJSONObject;
|
||||
try
|
||||
Result := Json.GetValue<string>('uuid');
|
||||
finally
|
||||
Json.Free;
|
||||
end;
|
||||
finally
|
||||
Multipart.Free;
|
||||
end;
|
||||
finally
|
||||
Root.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TFusionBrainAPI.CheckGeneration(const RequestId: string): TArray<string>;
|
||||
var
|
||||
Response: IHTTPResponse;
|
||||
Json, ResultObj: TJSONObject;
|
||||
Files: TJSONArray;
|
||||
i: Integer;
|
||||
begin
|
||||
repeat
|
||||
Sleep(5000);
|
||||
Response := FClient.Get(FBaseURL + 'key/api/v1/pipeline/status/' + RequestId, nil, GetAuthHeaders);
|
||||
Json := TJSONObject.ParseJSONValue(Response.ContentAsString) as TJSONObject;
|
||||
try
|
||||
if Json.GetValue<string>('status') = 'DONE' then
|
||||
begin
|
||||
ResultObj := Json.GetValue<TJSONObject>('result');
|
||||
Files := ResultObj.GetValue<TJSONArray>('files');
|
||||
SetLength(Result, Files.Count);
|
||||
for i := 0 to Files.Count - 1 do
|
||||
Result[i] := Files.Items[i].Value;
|
||||
Exit;
|
||||
end;
|
||||
finally
|
||||
Json.Free;
|
||||
end;
|
||||
until False;
|
||||
end;
|
||||
|
||||
procedure TFusionBrainAPI.SaveBase64Image(const Base64Str, FileName: string);
|
||||
var
|
||||
DecodedStream: TMemoryStream;
|
||||
InputStr: TStringStream;
|
||||
begin
|
||||
DecodedStream := TMemoryStream.Create;
|
||||
InputStr := TStringStream.Create(Base64Str);
|
||||
try
|
||||
TNetEncoding.Base64.Decode(InputStr, DecodedStream);
|
||||
DecodedStream.SaveToFile(FileName);
|
||||
finally
|
||||
DecodedStream.Free;
|
||||
InputStr.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TFusionBrainAPI.DoStatusUpdate(const AMessage: string);
|
||||
begin
|
||||
if Assigned(FOnStatusUpdate) then
|
||||
FOnStatusUpdate(Self, AMessage);
|
||||
end;
|
||||
|
||||
procedure TFusionBrainAPI.DoGenerationDone(const AFileName: string);
|
||||
begin
|
||||
if Assigned(FOnGenerationDone) then
|
||||
FOnGenerationDone(Self, AFileName);
|
||||
end;
|
||||
|
||||
procedure TFusionBrainAPI.DoError(const AErrorMessage: string);
|
||||
begin
|
||||
if Assigned(FOnError) then
|
||||
FOnError(Self, AErrorMessage);
|
||||
end;
|
||||
|
||||
end.
|
||||
Reference in New Issue
Block a user