usmansafdarktk commited on
Commit
5b2b9b0
·
1 Parent(s): 3ad9473

Serve index.html via FastAPI static files

Browse files
Files changed (3) hide show
  1. main.py +4 -4
  2. requirements.txt +2 -1
  3. static/index.html +167 -0
main.py CHANGED
@@ -3,6 +3,7 @@ import logging
3
  import torch
4
  import gc
5
  from fastapi import FastAPI, HTTPException
 
6
  from pydantic import BaseModel
7
  from transformers import pipeline
8
 
@@ -11,6 +12,9 @@ logger = logging.getLogger(__name__)
11
 
12
  app = FastAPI(title="LaMini-LM API", description="API for text generation using LaMini-GPT-774M", version="1.0.0")
13
 
 
 
 
14
  class TextGenerationRequest(BaseModel):
15
  instruction: str
16
  max_length: int = 100
@@ -38,10 +42,6 @@ def load_model():
38
  async def health_check():
39
  return {"status": "healthy"}
40
 
41
- @app.get("/")
42
- async def root():
43
- return {"message": "Welcome to the LaMini-LM API. Use POST /generate to generate text."}
44
-
45
  @app.post("/generate")
46
  async def generate_text(request: TextGenerationRequest):
47
  if generator is None:
 
3
  import torch
4
  import gc
5
  from fastapi import FastAPI, HTTPException
6
+ from fastapi.staticfiles import StaticFiles
7
  from pydantic import BaseModel
8
  from transformers import pipeline
9
 
 
12
 
13
  app = FastAPI(title="LaMini-LM API", description="API for text generation using LaMini-GPT-774M", version="1.0.0")
14
 
15
+ # Mount static files
16
+ app.mount("/", StaticFiles(directory="static", html=True), name="static")
17
+
18
  class TextGenerationRequest(BaseModel):
19
  instruction: str
20
  max_length: int = 100
 
42
  async def health_check():
43
  return {"status": "healthy"}
44
 
 
 
 
 
45
  @app.post("/generate")
46
  async def generate_text(request: TextGenerationRequest):
47
  if generator is None:
requirements.txt CHANGED
@@ -1,4 +1,5 @@
1
- fastapi==0.115.2
2
  uvicorn==0.32.0
3
  transformers==4.46.0
4
  torch==2.4.1
 
 
1
+ fastapi[standard]
2
  uvicorn==0.32.0
3
  transformers==4.46.0
4
  torch==2.4.1
5
+ pydantic
static/index.html ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>LaMini-LM API</title>
7
+ <script src="https://cdn.jsdelivr.net/npm/react@18.2.0/umd/react.production.min.js"></script>
8
+ <script src="https://cdn.jsdelivr.net/npm/react-dom@18.2.0/umd/react-dom.production.min.js"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/babel-standalone@7.22.9/babel.min.js"></script>
10
+ <script src="https://cdn.tailwindcss.com"></script>
11
+ </head>
12
+ <body class="bg-gray-100 min-h-screen flex items-center justify-center">
13
+ <div id="root"></div>
14
+ <script type="text/babel">
15
+ function App() {
16
+ const [instruction, setInstruction] = React.useState('');
17
+ const [maxLength, setMaxLength] = React.useState(100);
18
+ const [temperature, setTemperature] = React.useState(1.0);
19
+ const [topP, setTopP] = React.useState(0.9);
20
+ const [generatedText, setGeneratedText] = React.useState('');
21
+ const [error, setError] = React.useState('');
22
+ const [isLoading, setIsLoading] = React.useState(false);
23
+
24
+ const handleSubmit = async (e) => {
25
+ e.preventDefault();
26
+ setError('');
27
+ setGeneratedText('');
28
+ setIsLoading(true);
29
+
30
+ if (!instruction.trim()) {
31
+ setError('Instruction cannot be empty.');
32
+ setIsLoading(false);
33
+ return;
34
+ }
35
+ if (maxLength < 10 || maxLength > 500) {
36
+ setError('Max length must be between 10 and 500.');
37
+ setIsLoading(false);
38
+ return;
39
+ }
40
+ if (temperature <= 0 || temperature > 2) {
41
+ setError('Temperature must be between 0 and 2.');
42
+ setIsLoading(false);
43
+ return;
44
+ }
45
+ if (topP <= 0 || topP > 1) {
46
+ setError('Top P must be between 0 and 1.');
47
+ setIsLoading(false);
48
+ return;
49
+ }
50
+
51
+ try {
52
+ const response = await fetch('/generate', {
53
+ method: 'POST',
54
+ headers: { 'Content-Type': 'application/json' },
55
+ body: JSON.stringify({
56
+ instruction,
57
+ max_length: maxLength,
58
+ temperature,
59
+ top_p: topP,
60
+ }),
61
+ });
62
+ const data = await response.json();
63
+ if (response.ok) {
64
+ setGeneratedText(data.generated_text);
65
+ } else {
66
+ setError(data.detail?.[0]?.msg || 'Failed to generate text.');
67
+ }
68
+ } catch (err) {
69
+ setError('Error connecting to the API. Please try again.');
70
+ } finally {
71
+ setIsLoading(false);
72
+ }
73
+ };
74
+
75
+ return (
76
+ <div className="max-w-2xl mx-auto p-6 bg-white rounded-lg shadow-lg">
77
+ <h1 className="text-3xl font-bold text-center text-gray-800 mb-6">
78
+ LaMini-LM Text Generator
79
+ </h1>
80
+ <form onSubmit={handleSubmit} className="space-y-4">
81
+ <div>
82
+ <label htmlFor="instruction" className="block text-sm font-medium text-gray-700">
83
+ Instruction
84
+ </label>
85
+ <textarea
86
+ id="instruction"
87
+ value={instruction}
88
+ onChange={(e) => setInstruction(e.target.value)}
89
+ className="mt-1 w-full p-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500"
90
+ rows="4"
91
+ placeholder="e.g., Tell me about camels"
92
+ ></textarea>
93
+ </div>
94
+ <div>
95
+ <label htmlFor="maxLength" className="block text-sm font-medium text-gray-700">
96
+ Max Length (10–500)
97
+ </label>
98
+ <input
99
+ id="maxLength"
100
+ type="number"
101
+ value={maxLength}
102
+ onChange={(e) => setMaxLength(Number(e.target.value))}
103
+ min="10"
104
+ max="500"
105
+ className="mt-1 w-full p-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500"
106
+ />
107
+ </div>
108
+ <div>
109
+ <label htmlFor="temperature" className="block text-sm font-medium text-gray-700">
110
+ Temperature (0–2)
111
+ </label>
112
+ <input
113
+ id="temperature"
114
+ type="number"
115
+ step="0.1"
116
+ value={temperature}
117
+ onChange={(e) => setTemperature(Number(e.target.value))}
118
+ min="0"
119
+ max="2"
120
+ className="mt-1 w-full p-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500"
121
+ />
122
+ </div>
123
+ <div>
124
+ <label htmlFor="topP" className="block text-sm font-medium text-gray-700">
125
+ Top P (0–1)
126
+ </label>
127
+ <input
128
+ id="topP"
129
+ type="number"
130
+ step="0.1"
131
+ value={topP}
132
+ onChange={(e) => setTopP(Number(e.target.value))}
133
+ min="0"
134
+ max="1"
135
+ className="mt-1 w-full p-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500"
136
+ />
137
+ </div>
138
+ <button
139
+ type="submit"
140
+ disabled={isLoading}
141
+ className={`w-full py-2 px-4 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 ${
142
+ isLoading ? 'opacity-50 cursor-not-allowed' : ''
143
+ }`}
144
+ >
145
+ {isLoading ? 'Generating...' : 'Generate Text'}
146
+ </button>
147
+ </form>
148
+ {error && (
149
+ <div className="mt-4 p-4 bg-red-100 text-red-700 rounded-md">
150
+ {error}
151
+ </div>
152
+ )}
153
+ {generatedText && (
154
+ <div className="mt-4 p-4 bg-gray-100 rounded-md">
155
+ <h2 className="text-lg font-semibold text-gray-800">Generated Text:</h2>
156
+ <p className="mt-2 text-gray-600">{generatedText}</p>
157
+ </div>
158
+ )}
159
+ </div>
160
+ );
161
+ }
162
+
163
+ const root = ReactDOM.createRoot(document.getElementById('root'));
164
+ root.render(<App />);
165
+ </script>
166
+ </body>
167
+ </html>