Spaces:
Sleeping
Sleeping
from fastapi import FastAPI, Form | |
from fastapi.responses import HTMLResponse, StreamingResponse | |
import asyncio | |
import random | |
import string | |
import uvicorn | |
app = FastAPI() | |
async def get_form(): | |
return """ | |
<html> | |
<head> | |
<title>URL Input</title> | |
<style> | |
body { | |
font-family: Arial, sans-serif; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
height: 100vh; | |
background-color: #f0f0f0; | |
} | |
form { | |
background: white; | |
padding: 2em; | |
border-radius: 5px; | |
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); | |
margin-bottom: 20px; | |
} | |
input[type="text"] { | |
width: 300px; | |
padding: 0.5em; | |
margin-bottom: 1em; | |
border: 1px solid #ccc; | |
border-radius: 4px; | |
} | |
input[type="text"][name="filename"] { | |
width: 200px; | |
margin-left: 10px; | |
} | |
button { | |
padding: 0.5em 1em; | |
color: white; | |
background-color: #007BFF; | |
border: none; | |
border-radius: 4px; | |
cursor: pointer; | |
} | |
button:hover { | |
background-color: #0056b3; | |
} | |
.output-box { | |
width: 80%; | |
height: 400px; | |
border: 1px solid #ccc; | |
border-radius: 4px; | |
overflow-y: auto; | |
padding: 1em; | |
background-color: white; | |
} | |
.output-content { | |
white-space: pre-wrap; | |
font-family: monospace; | |
} | |
</style> | |
</head> | |
<body> | |
<div> | |
<form id="urlForm" action="/submit" method="post"> | |
<input type="text" name="url" id="urlInput" placeholder="Enter URL" required> | |
<input type="text" name="filename" id="filenameInput" placeholder="File Name"> | |
<button type="submit">Submit</button> | |
</form> | |
<div class="output-box" id="output-box"> | |
<div class="output-content" id="output-content"></div> | |
</div> | |
</div> | |
<script> | |
document.getElementById('urlInput').addEventListener('input', function() { | |
const url = this.value; | |
const defaultFilename = url.split('/').pop() || ''; | |
if (filenameInput.value !s== defaultFilename) { | |
filenameInput.value = defaultFilename; | |
} | |
}); | |
const form = document.getElementById('urlForm'); | |
form.addEventListener('submit', async function(event) { | |
event.preventDefault(); | |
const formData = new FormData(form); | |
const response = await fetch('/submit', { | |
method: 'POST', | |
body: formData | |
}); | |
const reader = response.body.getReader(); | |
const decoder = new TextDecoder(); | |
const outputContent = document.getElementById('output-content'); | |
const outputBox = document.getElementById('output-box'); | |
outputContent.innerHTML = ''; // Clear previous content | |
while (true) { | |
const { done, value } = await reader.read(); | |
if (done) break; | |
const chunk = decoder.decode(value, { stream: true }); | |
outputContent.innerHTML += chunk; | |
outputBox.scrollTop = outputBox.scrollHeight; // Scroll to the latest content | |
} | |
}); | |
</script> | |
</body> | |
</html> | |
""" | |
async def submit_url(url: str = Form(...), filename: str = Form(None)): | |
if not filename: | |
filename = url.split("/")[-1] | |
async def generate_html(): | |
yield f'<p>Filename: {filename}</p><p>Lorem Ipsum Text:</p>' | |
lorem_text = ''.join(random.choices(string.ascii_letters + string.digits + ' ', k=1000)) | |
for char in lorem_text: | |
await asyncio.sleep(0.01) # 10ms delay | |
yield char | |
headers = { | |
"Content-Type": "text/html", | |
"Transfer-Encoding": "chunked", | |
"Cache-Control": "no-cache", | |
"X-Accel-Buffering": "no" | |
} | |
return StreamingResponse(generate_html(), headers=headers) | |
if __name__ == "__main__": | |
uvicorn.run(app, host="0.0.0.0", port=8000) | |