first update
Browse files- Dockerfile +45 -0
- main.py +88 -0
- static/index.html +69 -0
- static/style.css +8 -0
Dockerfile
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
FROM nvidia/cuda:12.0.0-cudnn8-devel-ubuntu22.04
|
2 |
+
|
3 |
+
# Using the Ubuntu image (our OS)
|
4 |
+
# Update package manager (apt-get)
|
5 |
+
# and install (with the yes flag `-y`)
|
6 |
+
# Python and Pip
|
7 |
+
RUN apt-get update && apt-get install -y \
|
8 |
+
python3-pip
|
9 |
+
|
10 |
+
|
11 |
+
WORKDIR /code
|
12 |
+
|
13 |
+
COPY ./requirements.txt /code/requirements.txt
|
14 |
+
|
15 |
+
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
|
16 |
+
|
17 |
+
# Set up a new user named "user" with user ID 1000
|
18 |
+
RUN useradd -m -u 1000 user
|
19 |
+
|
20 |
+
# Switch to the "user" user
|
21 |
+
USER user
|
22 |
+
|
23 |
+
# Set home to the user's home directory
|
24 |
+
ENV HOME=/home/user \
|
25 |
+
PATH=/home/user/.local/bin:$PATH
|
26 |
+
|
27 |
+
# Set the working directory to the user's home directory
|
28 |
+
WORKDIR $HOME/app
|
29 |
+
|
30 |
+
# Download and uzip truepic-sign from Google Drive
|
31 |
+
RUN pip install gdown
|
32 |
+
RUN --mount=type=secret,id=truepic_sign_gdoc_id,mode=0444,required=true \
|
33 |
+
gdown --id $(cat /run/secrets/truepic_sign_gdoc_id)
|
34 |
+
RUN tar -xf truepic-lens-cli-v0.4.0-ubuntu-20.04.tar.gz
|
35 |
+
RUN chmod +x truepic
|
36 |
+
|
37 |
+
RUN --mount=type=secret,id=api_key,mode=0444,required=true \
|
38 |
+
./truepic enroll file-system --api-key $(cat /run/secrets/api_key)
|
39 |
+
|
40 |
+
# Copy the current directory contents into the container at $HOME/app setting the owner to the user
|
41 |
+
COPY --chown=user . $HOME/app
|
42 |
+
|
43 |
+
WORKDIR $HOME/app
|
44 |
+
|
45 |
+
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
|
main.py
ADDED
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import FastAPI
|
2 |
+
from fastapi.staticfiles import StaticFiles
|
3 |
+
from fastapi.responses import FileResponse
|
4 |
+
|
5 |
+
import subprocess
|
6 |
+
import os
|
7 |
+
import json
|
8 |
+
import uuid
|
9 |
+
import cgi
|
10 |
+
import cgitb; cgitb.enable()
|
11 |
+
|
12 |
+
import torch
|
13 |
+
from diffusers import (
|
14 |
+
StableDiffusionPipeline,
|
15 |
+
DPMSolverMultistepScheduler,
|
16 |
+
EulerDiscreteScheduler,
|
17 |
+
)
|
18 |
+
|
19 |
+
app = FastAPI()
|
20 |
+
|
21 |
+
|
22 |
+
@app.get("/generate")
|
23 |
+
def generate_image(prompt, model):
|
24 |
+
torch.cuda.empty_cache()
|
25 |
+
|
26 |
+
modelArray = model.split(",")
|
27 |
+
modelName = modelArray[0]
|
28 |
+
modelVersion = modelArray[1]
|
29 |
+
|
30 |
+
pipeline = StableDiffusionPipeline.from_pretrained(
|
31 |
+
str(modelName), torch_dtype=torch.float16
|
32 |
+
)
|
33 |
+
pipeline.scheduler = EulerDiscreteScheduler.from_config(pipeline.scheduler.config)
|
34 |
+
pipeline = pipeline.to("cuda")
|
35 |
+
|
36 |
+
image = pipeline(prompt, num_inference_steps=50, height=512, width=512).images[0]
|
37 |
+
|
38 |
+
filename = str(uuid.uuid4()) + ".jpg"
|
39 |
+
image.save(filename)
|
40 |
+
|
41 |
+
assertion = {
|
42 |
+
"assertions": [
|
43 |
+
{
|
44 |
+
"label": "com.truepic.custom.ai",
|
45 |
+
"data": {
|
46 |
+
"model_name": modelName,
|
47 |
+
"model_version": modelVersion,
|
48 |
+
"prompt": prompt,
|
49 |
+
},
|
50 |
+
}
|
51 |
+
]
|
52 |
+
}
|
53 |
+
|
54 |
+
json_object = json.dumps(assertion)
|
55 |
+
|
56 |
+
subprocess.check_output(
|
57 |
+
[
|
58 |
+
"./truepic",
|
59 |
+
"sign",
|
60 |
+
filename,
|
61 |
+
"--assertions-inline",
|
62 |
+
json_object,
|
63 |
+
"--output",
|
64 |
+
(os.getcwd() + "/static/" + filename),
|
65 |
+
]
|
66 |
+
)
|
67 |
+
|
68 |
+
return {"response": filename}
|
69 |
+
|
70 |
+
@app.get("/verify")
|
71 |
+
def verify_image():
|
72 |
+
form = cgi.FieldStorage()
|
73 |
+
fileitem = form['fileUpload']
|
74 |
+
|
75 |
+
# check if the file has been uploaded
|
76 |
+
if fileitem.filename:
|
77 |
+
# strip the leading path from the file name
|
78 |
+
fn = os.path.basename(fileitem.filename)
|
79 |
+
|
80 |
+
# open read and write the file into the server
|
81 |
+
open(fn, 'wb').write(fileitem.file.read())
|
82 |
+
return {"response": fileitem.filename}
|
83 |
+
app.mount("/", StaticFiles(directory="static", html=True), name="static")
|
84 |
+
|
85 |
+
|
86 |
+
@app.get("/")
|
87 |
+
def index() -> FileResponse:
|
88 |
+
return FileResponse(path="/app/static/index.html", media_type="text/html")
|
static/index.html
ADDED
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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" />
|
6 |
+
|
7 |
+
<!-- Bootstrap CSS -->
|
8 |
+
<link
|
9 |
+
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
|
10 |
+
rel="stylesheet"
|
11 |
+
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
|
12 |
+
crossorigin="anonymous"
|
13 |
+
/>
|
14 |
+
|
15 |
+
<script
|
16 |
+
src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
|
17 |
+
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
|
18 |
+
crossorigin="anonymous"
|
19 |
+
></script>
|
20 |
+
|
21 |
+
<link rel="stylesheet" href="style.css" type="text/css" />
|
22 |
+
</head>
|
23 |
+
<body>
|
24 |
+
<div class="container">
|
25 |
+
<form id="fileUploadForm">
|
26 |
+
<label class="form-label" for="customFile">Default file input example</label>
|
27 |
+
<input type="file" class="form-control" name="fileUpload" id="fileUpload" />
|
28 |
+
</form>
|
29 |
+
</div>
|
30 |
+
|
31 |
+
</body>
|
32 |
+
|
33 |
+
<script>
|
34 |
+
const form = document.querySelector('#fileUploadForm');
|
35 |
+
|
36 |
+
form.addEventListener('submit', (e) => {
|
37 |
+
e.preventDefault();
|
38 |
+
submitForm();
|
39 |
+
});
|
40 |
+
|
41 |
+
function submitForm() {
|
42 |
+
const form = document.querySelector('#myForm');
|
43 |
+
const formData = new FormData(form);
|
44 |
+
|
45 |
+
// Add additional form data as needed
|
46 |
+
//formData.append('additionalData', 'additionalValue');
|
47 |
+
|
48 |
+
// Call function to submit form data
|
49 |
+
submitFormData(formData);
|
50 |
+
}
|
51 |
+
|
52 |
+
function submitFormData(formData) {
|
53 |
+
fetch('/verify', {
|
54 |
+
method: 'POST',
|
55 |
+
body: formData
|
56 |
+
})
|
57 |
+
.then(response => response.json())
|
58 |
+
.then(data => {
|
59 |
+
console.log(data)
|
60 |
+
// Handle response data
|
61 |
+
})
|
62 |
+
.catch(error => {
|
63 |
+
console.log(error)
|
64 |
+
// Handle errors
|
65 |
+
});
|
66 |
+
}
|
67 |
+
</script>
|
68 |
+
|
69 |
+
</html>
|
static/style.css
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#uploaded-image-container {
|
2 |
+
border-bottom: 1px solid black;
|
3 |
+
border-top: 1px solid black;
|
4 |
+
}
|
5 |
+
|
6 |
+
.results {
|
7 |
+
display: none;
|
8 |
+
}
|