jbilcke-hf HF staff commited on
Commit
4ae6e3c
1 Parent(s): 5443231

add support for images

Browse files
Files changed (1) hide show
  1. src/index.mts +43 -23
src/index.mts CHANGED
@@ -1,7 +1,12 @@
1
- import express from "express"
 
 
 
2
  import { HfInference } from '@huggingface/inference'
3
 
4
- import { daisy } from "./daisy.mts"
 
 
5
 
6
  const hfi = new HfInference(process.env.HF_API_TOKEN)
7
  const hf = hfi.endpoint(process.env.HF_ENDPOINT_URL)
@@ -12,9 +17,9 @@ const port = 7860
12
  const minPromptSize = 16 // if you change this, you will need to also change in public/index.html
13
  const timeoutInSec = 30 * 60
14
 
15
- console.log("timeout set to 30 minutes")
16
 
17
- app.use(express.static("public"))
18
 
19
  const pending: {
20
  total: number;
@@ -33,7 +38,7 @@ const endRequest = (id: string, reason: string) => {
33
  console.log(`request ${id} ended (${reason})`)
34
  }
35
 
36
- app.get("/debug", (req, res) => {
37
  res.write(JSON.stringify({
38
  nbTotal: pending.total,
39
  nbPending: pending.queue.length,
@@ -42,16 +47,7 @@ app.get("/debug", (req, res) => {
42
  res.end()
43
  })
44
 
45
- app.get("/app", async (req, res) => {
46
-
47
- const model = `${req.query.model || 'OpenAssistant/oasst-sft-4-pythia-12b-epoch-3.5'}`
48
-
49
- console.log('model:', model)
50
-
51
- const endpoint = `${req.query.endpoint || ''}`
52
-
53
- console.log('endpoint:', endpoint)
54
-
55
  if (`${req.query.prompt}`.length < minPromptSize) {
56
  res.write(`prompt too short, please enter at least ${minPromptSize} characters`)
57
  res.end()
@@ -63,15 +59,13 @@ app.get("/app", async (req, res) => {
63
 
64
  pending.queue.push(id)
65
 
66
- const prefix = `<html><head><link href="https://cdn.jsdelivr.net/npm/daisyui@3.1.6/dist/full.css" rel="stylesheet" type="text/css" /><script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script><script src="https://cdn.tailwindcss.com?plugins=forms,typography,aspect-ratio,line-clamp"></script><title>Generated content</title><body`
67
  res.write(prefix)
68
 
69
- req.on("close", function() {
70
- // console.log("browser asked to close the stream for some reason.. let's ignore!")
71
- endRequest(id, "browser asked to end the connection")
72
  })
73
 
74
- // for testing we kill after some delay
75
  setTimeout(() => {
76
  endRequest(id, `timed out after ${timeoutInSec}s`)
77
  }, timeoutInSec * 1000)
@@ -84,11 +78,13 @@ ${daisy}
84
  # Guidelines
85
  - Never repeat the instruction, instead directly write the final code
86
  - Use a color scheme consistent with the brief and theme
 
 
87
  - You must use Tailwind CSS and Daisy UI for the CSS classes, vanilla JS and Alpine.js for the JS.
88
- - All the JS code will be written directly inside the page, using <script type="text/javascript">...</script>
89
  - You MUST use English, not Latin! (I repeat: do NOT write lorem ipsum!)
90
  - No need to write code comments, so please make the code compact (short function names etc)
91
- - Use a central layout by wrapping everything in a \`<div class="flex flex-col items-center">\`
92
  # HTML output
93
  <html><head></head><body`
94
 
@@ -108,7 +104,6 @@ ${daisy}
108
  break
109
  }
110
  if (result.includes('<|end|>') || result.includes('<|assistant|>')) {
111
- // it ended, but we probably don't have a valid HTML
112
  break
113
  }
114
  }
@@ -127,5 +122,30 @@ ${daisy}
127
 
128
  })
129
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  app.listen(port, () => { console.log(`Open http://localhost:${port}`) })
131
 
 
1
+ import { pipeline } from 'stream'
2
+ import { promisify } from 'util'
3
+
4
+ import express from 'express'
5
  import { HfInference } from '@huggingface/inference'
6
 
7
+ import { daisy } from './daisy.mts'
8
+
9
+ const pipe = promisify(pipeline)
10
 
11
  const hfi = new HfInference(process.env.HF_API_TOKEN)
12
  const hf = hfi.endpoint(process.env.HF_ENDPOINT_URL)
 
17
  const minPromptSize = 16 // if you change this, you will need to also change in public/index.html
18
  const timeoutInSec = 30 * 60
19
 
20
+ console.log('timeout set to 30 minutes')
21
 
22
+ app.use(express.static('public'))
23
 
24
  const pending: {
25
  total: number;
 
38
  console.log(`request ${id} ended (${reason})`)
39
  }
40
 
41
+ app.get('/debug', (req, res) => {
42
  res.write(JSON.stringify({
43
  nbTotal: pending.total,
44
  nbPending: pending.queue.length,
 
47
  res.end()
48
  })
49
 
50
+ app.get('/app', async (req, res) => {
 
 
 
 
 
 
 
 
 
51
  if (`${req.query.prompt}`.length < minPromptSize) {
52
  res.write(`prompt too short, please enter at least ${minPromptSize} characters`)
53
  res.end()
 
59
 
60
  pending.queue.push(id)
61
 
62
+ const prefix = `<html><head><link href='https://cdn.jsdelivr.net/npm/daisyui@3.1.6/dist/full.css' rel='stylesheet' type='text/css' /><script defer src='https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js'></script><script src='https://cdn.tailwindcss.com?plugins=forms,typography,aspect-ratio,line-clamp'></script><title>Generated content</title><body`
63
  res.write(prefix)
64
 
65
+ req.on('close', function() {
66
+ endRequest(id, 'browser asked to end the connection')
 
67
  })
68
 
 
69
  setTimeout(() => {
70
  endRequest(id, `timed out after ${timeoutInSec}s`)
71
  }, timeoutInSec * 1000)
 
78
  # Guidelines
79
  - Never repeat the instruction, instead directly write the final code
80
  - Use a color scheme consistent with the brief and theme
81
+ - To generate all your images, import from from this route: "/image?prompt=<description or caption of an image, photo or illustration>"
82
+ - please be descriptive for the prompt, eg describe the scene in a few words (textures, characters, materials, camera type etc)
83
  - You must use Tailwind CSS and Daisy UI for the CSS classes, vanilla JS and Alpine.js for the JS.
84
+ - All the JS code will be written directly inside the page, using <script type='text/javascript'>...</script>
85
  - You MUST use English, not Latin! (I repeat: do NOT write lorem ipsum!)
86
  - No need to write code comments, so please make the code compact (short function names etc)
87
+ - Use a central layout by wrapping everything in a \`<div class='flex flex-col items-center'>\`
88
  # HTML output
89
  <html><head></head><body`
90
 
 
104
  break
105
  }
106
  if (result.includes('<|end|>') || result.includes('<|assistant|>')) {
 
107
  break
108
  }
109
  }
 
122
 
123
  })
124
 
125
+ app.get('/image', async (req, res) => {
126
+ try {
127
+ const blob = await hfi.textToImage({
128
+ inputs: [
129
+ `${req.query.prompt || 'generic placeholder'}`,
130
+ 'award winning',
131
+ 'high resolution',
132
+ 'beautiful',
133
+ '[trending on artstation]'
134
+ ].join(','),
135
+ model: 'stabilityai/stable-diffusion-2',
136
+ parameters: {
137
+ negative_prompt: 'blurry, cropped, low quality, ugly',
138
+ }
139
+ })
140
+ const buffer = Buffer.from(await blob.arrayBuffer())
141
+ res.setHeader('Content-Type', blob.type)
142
+ res.setHeader('Content-Length', buffer.length)
143
+ res.end(buffer)
144
+ } catch (err) {
145
+ console.error(`Error when generating the image: ${err.message}`);
146
+ res.status(500).json({ error: 'An error occurred when trying to generate the image' });
147
+ }
148
+ })
149
+
150
  app.listen(port, () => { console.log(`Open http://localhost:${port}`) })
151