Spaces:
Sleeping
Sleeping
Add initial FastAPI application with Docker support and file upload functionality
Browse files- Dockerfile +16 -0
- app.py +32 -0
- requirements.txt +5 -0
- templates/index.html +98 -0
- u2net.onnx +3 -0
Dockerfile
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM python:3.12.4
|
| 2 |
+
|
| 3 |
+
COPY u2net.onnx /home/.u2net/u2net.onnx
|
| 4 |
+
|
| 5 |
+
RUN useradd -m -u 1000 user
|
| 6 |
+
USER user
|
| 7 |
+
ENV PATH="/home/user/.local/bin:$PATH"
|
| 8 |
+
|
| 9 |
+
WORKDIR /app
|
| 10 |
+
|
| 11 |
+
COPY --chown=user ./requirements.txt requirements.txt
|
| 12 |
+
RUN pip install --no-cache-dir --upgrade -r requirements.txt
|
| 13 |
+
|
| 14 |
+
COPY --chown=user . /app
|
| 15 |
+
|
| 16 |
+
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
|
app.py
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from fastapi import FastAPI, File, UploadFile, HTTPException
|
| 2 |
+
from fastapi.responses import StreamingResponse, HTMLResponse
|
| 3 |
+
from rembg import remove
|
| 4 |
+
import uvicorn
|
| 5 |
+
from PIL import Image
|
| 6 |
+
from io import BytesIO
|
| 7 |
+
|
| 8 |
+
app = FastAPI()
|
| 9 |
+
|
| 10 |
+
@app.get("/", response_class=HTMLResponse)
|
| 11 |
+
async def read_index():
|
| 12 |
+
with open("templates/index.html", "r") as file:
|
| 13 |
+
return file.read()
|
| 14 |
+
|
| 15 |
+
@app.post("/")
|
| 16 |
+
async def upload_file(file: UploadFile = File(...)):
|
| 17 |
+
if not file:
|
| 18 |
+
raise HTTPException(status_code=400, detail="No file uploaded")
|
| 19 |
+
if file.filename == '':
|
| 20 |
+
raise HTTPException(status_code=400, detail="No file selected")
|
| 21 |
+
|
| 22 |
+
input_image = Image.open(file.file)
|
| 23 |
+
output_image = remove(input_image, post_process_mask=True)
|
| 24 |
+
|
| 25 |
+
img_io = BytesIO()
|
| 26 |
+
output_image.save(img_io, 'PNG')
|
| 27 |
+
img_io.seek(0)
|
| 28 |
+
|
| 29 |
+
return StreamingResponse(img_io, media_type="image/png", headers={"Content-Disposition": f"attachment; filename={file.filename}_rmng.png"})
|
| 30 |
+
|
| 31 |
+
if __name__ == '__main__':
|
| 32 |
+
uvicorn.run(app, host='0.0.0.0', port=5100, debug=True)
|
requirements.txt
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
fastapi
|
| 2 |
+
uvicorn[standard]
|
| 3 |
+
rembg
|
| 4 |
+
pillow
|
| 5 |
+
onnxruntime
|
templates/index.html
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html>
|
| 3 |
+
<head>
|
| 4 |
+
<title>✂️ rmbg</title>
|
| 5 |
+
<style>
|
| 6 |
+
body {
|
| 7 |
+
height: 100vh;
|
| 8 |
+
display: flex;
|
| 9 |
+
align-items: center;
|
| 10 |
+
justify-content: center;
|
| 11 |
+
text-align: center;
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
.drop-zone {
|
| 15 |
+
border: 2px dashed #ccc;
|
| 16 |
+
padding: 20px;
|
| 17 |
+
width: 80vw;
|
| 18 |
+
height: 80vh;
|
| 19 |
+
display: flex;
|
| 20 |
+
flex-direction: column;
|
| 21 |
+
align-items: center;
|
| 22 |
+
justify-content: center;
|
| 23 |
+
cursor: pointer;
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
.drop-zone.dragover {
|
| 27 |
+
background-color: #f0f0f0;
|
| 28 |
+
}
|
| 29 |
+
</style>
|
| 30 |
+
</head>
|
| 31 |
+
<body>
|
| 32 |
+
<div id="dropZone" class="drop-zone">
|
| 33 |
+
<h1>rmbg</h1>
|
| 34 |
+
<form id="uploadForm" action="/" method="post" enctype="multipart/form-data">
|
| 35 |
+
<input id="fileInput" type="file" name="file" />
|
| 36 |
+
<input type="submit" value="rm" />
|
| 37 |
+
</form>
|
| 38 |
+
</div>
|
| 39 |
+
|
| 40 |
+
<script>
|
| 41 |
+
let dropZone = document.getElementById("dropZone");
|
| 42 |
+
let fileInput = document.getElementById("fileInput");
|
| 43 |
+
let uploadForm = document.getElementById("uploadForm");
|
| 44 |
+
|
| 45 |
+
dropZone.addEventListener("click", function () {
|
| 46 |
+
fileInput.click();
|
| 47 |
+
});
|
| 48 |
+
|
| 49 |
+
fileInput.addEventListener("change", function () {
|
| 50 |
+
if (fileInput.files.length > 0) {
|
| 51 |
+
uploadFile(fileInput.files[0]);
|
| 52 |
+
}
|
| 53 |
+
});
|
| 54 |
+
|
| 55 |
+
dropZone.addEventListener("dragover", function (e) {
|
| 56 |
+
e.preventDefault();
|
| 57 |
+
this.classList.add("dragover");
|
| 58 |
+
});
|
| 59 |
+
|
| 60 |
+
dropZone.addEventListener("dragleave", function () {
|
| 61 |
+
this.classList.remove("dragover");
|
| 62 |
+
});
|
| 63 |
+
|
| 64 |
+
dropZone.addEventListener("drop", function (e) {
|
| 65 |
+
e.preventDefault();
|
| 66 |
+
e.stopPropagation();
|
| 67 |
+
this.classList.remove("dragover");
|
| 68 |
+
|
| 69 |
+
let file = e.dataTransfer.files[0];
|
| 70 |
+
if (file) {
|
| 71 |
+
uploadFile(file);
|
| 72 |
+
}
|
| 73 |
+
});
|
| 74 |
+
|
| 75 |
+
function uploadFile(file) {
|
| 76 |
+
let formData = new FormData();
|
| 77 |
+
formData.append("file", file);
|
| 78 |
+
|
| 79 |
+
fetch("/", {
|
| 80 |
+
method: "POST",
|
| 81 |
+
body: formData,
|
| 82 |
+
})
|
| 83 |
+
.then((response) => response.blob())
|
| 84 |
+
.then((blob) => {
|
| 85 |
+
let url = window.URL.createObjectURL(blob);
|
| 86 |
+
let a = document.createElement("a");
|
| 87 |
+
a.style.display = "none";
|
| 88 |
+
a.href = url;
|
| 89 |
+
a.download = file.name + "_rmng.png";
|
| 90 |
+
document.body.appendChild(a);
|
| 91 |
+
a.click();
|
| 92 |
+
window.URL.revokeObjectURL(url);
|
| 93 |
+
})
|
| 94 |
+
.catch((error) => console.error("Error:", error));
|
| 95 |
+
}
|
| 96 |
+
</script>
|
| 97 |
+
</body>
|
| 98 |
+
</html>
|
u2net.onnx
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:8d10d2f3bb75ae3b6d527c77944fc5e7dcd94b29809d47a739a7a728a912b491
|
| 3 |
+
size 175997641
|