T1ckbase commited on
Commit
3fded0a
·
1 Parent(s): d4d4332

/v1/images/generations

Browse files
Files changed (5) hide show
  1. deno.json +3 -1
  2. deno.lock +21 -2
  3. gradio-api/flux.ts +76 -0
  4. main.ts +15 -1
  5. utils/string.ts +11 -0
deno.json CHANGED
@@ -4,7 +4,9 @@
4
  "serve": "deno serve --allow-net --watch --port 7860 serve.ts"
5
  },
6
  "imports": {
7
- "@hono/hono": "jsr:@hono/hono@^4.7.1"
 
 
8
  },
9
  "fmt": {
10
  "indentWidth": 2,
 
4
  "serve": "deno serve --allow-net --watch --port 7860 serve.ts"
5
  },
6
  "imports": {
7
+ "@hono/hono": "jsr:@hono/hono@^4.7.1",
8
+ "@openai/openai": "jsr:@openai/openai@^4.87.3",
9
+ "@std/encoding": "jsr:@std/encoding@^1.0.7"
10
  },
11
  "fmt": {
12
  "indentWidth": 2,
deno.lock CHANGED
@@ -1,16 +1,35 @@
1
  {
2
  "version": "4",
3
  "specifiers": {
4
- "jsr:@hono/hono@^4.7.1": "4.7.1"
 
 
 
5
  },
6
  "jsr": {
7
  "@hono/hono@4.7.1": {
8
  "integrity": "f75aaf6a026ad05406e60125a70a3d2a77e3b62991f8c4e38c624bdfc1a1dc26"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  }
10
  },
11
  "workspace": {
12
  "dependencies": [
13
- "jsr:@hono/hono@^4.7.1"
 
 
14
  ]
15
  }
16
  }
 
1
  {
2
  "version": "4",
3
  "specifiers": {
4
+ "jsr:@hono/hono@^4.7.1": "4.7.1",
5
+ "jsr:@openai/openai@^4.87.3": "4.87.3",
6
+ "jsr:@std/encoding@^1.0.7": "1.0.7",
7
+ "npm:zod@3": "3.24.2"
8
  },
9
  "jsr": {
10
  "@hono/hono@4.7.1": {
11
  "integrity": "f75aaf6a026ad05406e60125a70a3d2a77e3b62991f8c4e38c624bdfc1a1dc26"
12
+ },
13
+ "@openai/openai@4.87.3": {
14
+ "integrity": "1a5e6008880ce1b38faa83b5e647becaf870a9f23d1bc61d55f703174055e4c6",
15
+ "dependencies": [
16
+ "npm:zod"
17
+ ]
18
+ },
19
+ "@std/encoding@1.0.7": {
20
+ "integrity": "f631247c1698fef289f2de9e2a33d571e46133b38d042905e3eac3715030a82d"
21
+ }
22
+ },
23
+ "npm": {
24
+ "zod@3.24.2": {
25
+ "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ=="
26
  }
27
  },
28
  "workspace": {
29
  "dependencies": [
30
+ "jsr:@hono/hono@^4.7.1",
31
+ "jsr:@openai/openai@^4.87.3",
32
+ "jsr:@std/encoding@^1.0.7"
33
  ]
34
  }
35
  }
gradio-api/flux.ts ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import OpenAI from '@openai/openai';
2
+ import { parseResolution } from '../utils/string.ts';
3
+ import { encodeBase64 } from '@std/encoding';
4
+
5
+ type FluxParameters = [
6
+ prompt: string,
7
+ seed: number,
8
+ randomizeSeed: boolean,
9
+ width: number,
10
+ height: number,
11
+ guidanceScale: number,
12
+ numberOfInferenceSteps: number,
13
+ ];
14
+
15
+ export async function generateImage(params: OpenAI.ImageGenerateParams): Promise<Response> {
16
+ const { width = 1024, height = 1024 } = parseResolution(params.size as string);
17
+ const sessionHash = Math.random().toString(36).substring(2);
18
+ const response = await fetch('https://black-forest-labs-flux-1-dev.hf.space/gradio_api/queue/join', {
19
+ method: 'POST',
20
+ headers: {
21
+ 'content-type': 'application/json',
22
+ },
23
+ body: JSON.stringify({
24
+ data: [
25
+ params.prompt,
26
+ 0,
27
+ true,
28
+ width,
29
+ height,
30
+ 3.5,
31
+ 28,
32
+ ] as FluxParameters,
33
+ fn_index: 2,
34
+ session_hash: sessionHash,
35
+ }),
36
+ });
37
+ if (!response.ok) return response;
38
+ const eventId = (await response.json()).event_id;
39
+
40
+ const url: string = await new Promise((resolve, reject) => {
41
+ const eventSource = new EventSource(`https://black-forest-labs-flux-1-dev.hf.space/gradio_api/queue/data?session_hash=${sessionHash}`);
42
+
43
+ eventSource.onmessage = (event) => {
44
+ const data = JSON.parse(event.data);
45
+ if (eventId !== data.event_id) return;
46
+ if (data.msg === 'process_completed') {
47
+ const url: string = data.output.data[0].url;
48
+ eventSource.close();
49
+ resolve(url);
50
+ }
51
+ };
52
+
53
+ eventSource.onerror = (event) => {
54
+ eventSource.close();
55
+ reject(event);
56
+ };
57
+ });
58
+
59
+ let data: any = {
60
+ url,
61
+ };
62
+ if (params.response_format === 'b64_json') {
63
+ const response = await fetch(url);
64
+ const image = await response.arrayBuffer();
65
+ data = {
66
+ b64_json: encodeBase64(image),
67
+ };
68
+ }
69
+
70
+ const resposne = {
71
+ created: Math.floor(Date.now() / 1000),
72
+ data: [data],
73
+ };
74
+
75
+ return new Response(JSON.stringify(resposne));
76
+ }
main.ts CHANGED
@@ -1,5 +1,8 @@
1
  import { Hono } from '@hono/hono';
2
  import { logger } from '@hono/hono/logger';
 
 
 
3
 
4
  // https://api-inference.huggingface.co/v1
5
  const HF_API_URL = 'https://api-inference.huggingface.co';
@@ -59,7 +62,18 @@ app.post('/v1/chat/completions', async (c) => {
59
  });
60
 
61
  app.post('/v1/images/generations', async (c) => {
62
- console.log('body:', await c.req.json());
 
 
 
 
 
 
 
 
 
 
 
63
  });
64
 
65
  // Deno.serve({ port: 7860 }, app.fetch);
 
1
  import { Hono } from '@hono/hono';
2
  import { logger } from '@hono/hono/logger';
3
+ import { generateImage as fluxGenerateImage } from './gradio-api/flux.ts';
4
+ import { parseResolution } from './utils/string.ts';
5
+ import OpenAI from '@openai/openai';
6
 
7
  // https://api-inference.huggingface.co/v1
8
  const HF_API_URL = 'https://api-inference.huggingface.co';
 
62
  });
63
 
64
  app.post('/v1/images/generations', async (c) => {
65
+ const body = await c.req.json<OpenAI.ImageGenerateParams>();
66
+ console.log('body:', body);
67
+
68
+ switch (body.model) {
69
+ case 'flux-dev': {
70
+ return await fluxGenerateImage(body);
71
+ }
72
+ default:
73
+ return c.text('unknown model', 400);
74
+ }
75
+
76
+ return c.text('skibidi', 400);
77
  });
78
 
79
  // Deno.serve({ port: 7860 }, app.fetch);
utils/string.ts ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export function parseResolution(resolutionString?: string) {
2
+ if (!resolutionString) return { width: null, height: null };
3
+ const parts = resolutionString.split('x');
4
+ if (parts.length === 2) {
5
+ const width = parseInt(parts[0], 10);
6
+ const height = parseInt(parts[1], 10);
7
+ return { width, height };
8
+ } else {
9
+ return { width: null, height: null };
10
+ }
11
+ }