Spaces:
Sleeping
Sleeping
Jon Taylor
commited on
Commit
•
ad5d266
1
Parent(s):
94f1dbe
base setup
Browse files- Dockerfile +13 -7
- _server.py +100 -0
- build-run.sh +0 -14
- frontend/app/page.js +5 -107
- frontend/app/test/page.js +7 -0
- frontend/package-lock.json +0 -0
- frontend/yarn.lock +0 -0
- requirements.txt +3 -11
- server.py +45 -84
Dockerfile
CHANGED
@@ -23,19 +23,25 @@ RUN curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg -
|
|
23 |
RUN echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_${NODE_MAJOR}.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list > /dev/null
|
24 |
RUN apt-get update && apt-get install nodejs -y
|
25 |
|
26 |
-
COPY ./requirements.txt /code/requirements.txt
|
27 |
-
|
28 |
# Expose Flask port
|
29 |
-
ENV
|
30 |
EXPOSE 7860
|
31 |
|
|
|
|
|
32 |
RUN pip3 install --no-cache-dir --upgrade -r /code/requirements.txt
|
33 |
|
34 |
-
# Copy
|
35 |
-
COPY
|
|
|
|
|
|
|
36 |
COPY frontend/ frontend/
|
|
|
|
|
|
|
|
|
37 |
COPY server.py server.py
|
38 |
-
COPY build-run.sh build-run.sh
|
39 |
|
40 |
#ENV LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libtcmalloc.so.4
|
41 |
-
CMD ["
|
|
|
23 |
RUN echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_${NODE_MAJOR}.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list > /dev/null
|
24 |
RUN apt-get update && apt-get install nodejs -y
|
25 |
|
|
|
|
|
26 |
# Expose Flask port
|
27 |
+
ENV FAST_API_PORT=7860
|
28 |
EXPOSE 7860
|
29 |
|
30 |
+
# Install Python dependencies
|
31 |
+
COPY ./requirements.txt /code/requirements.txt
|
32 |
RUN pip3 install --no-cache-dir --upgrade -r /code/requirements.txt
|
33 |
|
34 |
+
# Copy package.json and package-lock.json (or yarn.lock)
|
35 |
+
COPY frontend/package*.json frontend/
|
36 |
+
RUN cd frontend && npm install
|
37 |
+
|
38 |
+
# Copy frontend app and install Node.js dependencies
|
39 |
COPY frontend/ frontend/
|
40 |
+
RUN cd frontend && npm install
|
41 |
+
|
42 |
+
# Copy everything else
|
43 |
+
COPY app/ app/
|
44 |
COPY server.py server.py
|
|
|
45 |
|
46 |
#ENV LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libtcmalloc.so.4
|
47 |
+
CMD ["python3", "server.py"]
|
_server.py
ADDED
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from flask import Flask, send_from_directory, jsonify, request
|
2 |
+
from flask_cors import CORS
|
3 |
+
from dotenv import load_dotenv
|
4 |
+
import os
|
5 |
+
import requests
|
6 |
+
import subprocess
|
7 |
+
import time
|
8 |
+
|
9 |
+
from app.auth import get_meeting_token
|
10 |
+
|
11 |
+
load_dotenv()
|
12 |
+
|
13 |
+
app = Flask(__name__, static_url_path="/", static_folder="frontend/out")
|
14 |
+
CORS(app)
|
15 |
+
|
16 |
+
def _start_bot(bot_path, args=None):
|
17 |
+
daily_api_key = os.getenv("DAILY_API_KEY") or ""
|
18 |
+
api_path = os.getenv("DAILY_API_PATH") or "https://api.daily.co/v1"
|
19 |
+
|
20 |
+
timeout = int(os.getenv("ROOM_TIMEOUT") or os.getenv("BOT_MAX_DURATION") or 300)
|
21 |
+
exp = time.time() + timeout
|
22 |
+
|
23 |
+
'''
|
24 |
+
res = requests.post(
|
25 |
+
f"{api_path}/rooms",
|
26 |
+
headers={"Authorization": f"Bearer {daily_api_key}"},
|
27 |
+
json={
|
28 |
+
"properties": {
|
29 |
+
"exp": exp,
|
30 |
+
"enable_chat": True,
|
31 |
+
"enable_emoji_reactions": True,
|
32 |
+
"eject_at_room_exp": True,
|
33 |
+
"enable_prejoin_ui": False,
|
34 |
+
}
|
35 |
+
},
|
36 |
+
)
|
37 |
+
if res.status_code != 200:
|
38 |
+
return (
|
39 |
+
jsonify(
|
40 |
+
{
|
41 |
+
"error": "Unable to create room",
|
42 |
+
"status_code": res.status_code,
|
43 |
+
"text": res.text,
|
44 |
+
}
|
45 |
+
),
|
46 |
+
500,
|
47 |
+
)
|
48 |
+
'''
|
49 |
+
room_url = os.getenv("DAILY_ROOM_URL") #res.json()["url"]
|
50 |
+
room_name = os.getenv("DAILY_ROOM_NAME") #res.json()["name"]
|
51 |
+
|
52 |
+
meeting_token = get_meeting_token(room_url, daily_api_key, exp)
|
53 |
+
|
54 |
+
if args:
|
55 |
+
extra_args = " ".join([f'-{x[0]} "{x[1]}"' for x in args])
|
56 |
+
else:
|
57 |
+
extra_args = ""
|
58 |
+
|
59 |
+
proc = subprocess.Popen(
|
60 |
+
[
|
61 |
+
f"python3 {bot_path} -u {room_url} -t {meeting_token} {extra_args}"
|
62 |
+
],
|
63 |
+
shell=True,
|
64 |
+
bufsize=1,
|
65 |
+
)
|
66 |
+
|
67 |
+
# Don't return until the bot has joined the room, but wait for at most 2 seconds.
|
68 |
+
attempts = 0
|
69 |
+
while attempts < 20:
|
70 |
+
time.sleep(0.1)
|
71 |
+
attempts += 1
|
72 |
+
res = requests.get(
|
73 |
+
f"{api_path}/rooms/{room_name}/get-session-data",
|
74 |
+
headers={"Authorization": f"Bearer {daily_api_key}"},
|
75 |
+
)
|
76 |
+
if res.status_code == 200:
|
77 |
+
break
|
78 |
+
print(f"Took {attempts} attempts to join room {room_name}")
|
79 |
+
|
80 |
+
return jsonify({"room_url": room_url, "token": meeting_token}), 200
|
81 |
+
|
82 |
+
# Routes
|
83 |
+
#@app.route("/start-bot", methods=["POST"])
|
84 |
+
#def start_bot():
|
85 |
+
# return _start_bot("./app/bot.py")
|
86 |
+
|
87 |
+
|
88 |
+
@app.route('/', defaults={'path': ''})
|
89 |
+
@app.route('/<path:path>')
|
90 |
+
def catch_all(path):
|
91 |
+
full_path = os.path.join(app.static_folder, path)
|
92 |
+
# Check if path is a directory and index.html exists
|
93 |
+
if os.path.isdir(full_path) and os.path.exists(os.path.join(full_path, 'index.html')):
|
94 |
+
return send_from_directory(full_path, 'index.html')
|
95 |
+
# Check if path.html exists
|
96 |
+
elif os.path.exists(full_path + '.html'):
|
97 |
+
return send_from_directory(app.static_folder, path + '.html')
|
98 |
+
# Serve index.html by default
|
99 |
+
else:
|
100 |
+
return send_from_directory(app.static_folder, 'index.html')
|
build-run.sh
DELETED
@@ -1,14 +0,0 @@
|
|
1 |
-
#!/bin/bash
|
2 |
-
cd frontend
|
3 |
-
echo "Installing node modules..."
|
4 |
-
npm install
|
5 |
-
echo "Building frontend..."
|
6 |
-
npm run build
|
7 |
-
if [ $? -eq 0 ]; then
|
8 |
-
echo -e "\033[1;32m\nfrontend build success \033[0m"
|
9 |
-
else
|
10 |
-
echo -e "\033[1;31m\nfrontend build failed\n\033[0m" >&2 exit 1
|
11 |
-
fi
|
12 |
-
cd ../
|
13 |
-
|
14 |
-
gunicorn --workers=2 --log-level debug server:app --bind=0.0.0.0:$FLASK_PORT
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
frontend/app/page.js
CHANGED
@@ -1,113 +1,11 @@
|
|
1 |
-
import
|
2 |
|
3 |
export default function Home() {
|
4 |
return (
|
5 |
<main className="flex min-h-screen flex-col items-center justify-between p-24">
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
<code className="font-mono font-bold">app/page.js</code>
|
10 |
-
</p>
|
11 |
-
<div className="fixed bottom-0 left-0 flex h-48 w-full items-end justify-center bg-gradient-to-t from-white via-white dark:from-black dark:via-black lg:static lg:h-auto lg:w-auto lg:bg-none">
|
12 |
-
<a
|
13 |
-
className="pointer-events-none flex place-items-center gap-2 p-8 lg:pointer-events-auto lg:p-0"
|
14 |
-
href="https://vercel.com?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
|
15 |
-
target="_blank"
|
16 |
-
rel="noopener noreferrer"
|
17 |
-
>
|
18 |
-
By{' '}
|
19 |
-
<Image
|
20 |
-
src="/vercel.svg"
|
21 |
-
alt="Vercel Logo"
|
22 |
-
className="dark:invert"
|
23 |
-
width={100}
|
24 |
-
height={24}
|
25 |
-
priority
|
26 |
-
/>
|
27 |
-
</a>
|
28 |
-
</div>
|
29 |
-
</div>
|
30 |
-
|
31 |
-
<div className="relative flex place-items-center before:absolute before:h-[300px] before:w-[480px] before:-translate-x-1/2 before:rounded-full before:bg-gradient-radial before:from-white before:to-transparent before:blur-2xl before:content-[''] after:absolute after:-z-20 after:h-[180px] after:w-[240px] after:translate-x-1/3 after:bg-gradient-conic after:from-sky-200 after:via-blue-200 after:blur-2xl after:content-[''] before:dark:bg-gradient-to-br before:dark:from-transparent before:dark:to-blue-700 before:dark:opacity-10 after:dark:from-sky-900 after:dark:via-[#0141ff] after:dark:opacity-40 before:lg:h-[360px] z-[-1]">
|
32 |
-
<Image
|
33 |
-
className="relative dark:drop-shadow-[0_0_0.3rem_#ffffff70] dark:invert"
|
34 |
-
src="/next.svg"
|
35 |
-
alt="Next.js Logo"
|
36 |
-
width={180}
|
37 |
-
height={37}
|
38 |
-
priority
|
39 |
-
/>
|
40 |
-
</div>
|
41 |
-
|
42 |
-
<div className="mb-32 grid text-center lg:max-w-5xl lg:w-full lg:mb-0 lg:grid-cols-4 lg:text-left">
|
43 |
-
<a
|
44 |
-
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
|
45 |
-
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
46 |
-
target="_blank"
|
47 |
-
rel="noopener noreferrer"
|
48 |
-
>
|
49 |
-
<h2 className={`mb-3 text-2xl font-semibold`}>
|
50 |
-
Docs{' '}
|
51 |
-
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
52 |
-
->
|
53 |
-
</span>
|
54 |
-
</h2>
|
55 |
-
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
56 |
-
Find in-depth information about Next.js features and API.
|
57 |
-
</p>
|
58 |
-
</a>
|
59 |
-
|
60 |
-
<a
|
61 |
-
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
62 |
-
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800 hover:dark:bg-opacity-30"
|
63 |
-
target="_blank"
|
64 |
-
rel="noopener noreferrer"
|
65 |
-
>
|
66 |
-
<h2 className={`mb-3 text-2xl font-semibold`}>
|
67 |
-
Learn{' '}
|
68 |
-
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
69 |
-
->
|
70 |
-
</span>
|
71 |
-
</h2>
|
72 |
-
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
73 |
-
Learn about Next.js in an interactive course with quizzes!
|
74 |
-
</p>
|
75 |
-
</a>
|
76 |
-
|
77 |
-
<a
|
78 |
-
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
|
79 |
-
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
80 |
-
target="_blank"
|
81 |
-
rel="noopener noreferrer"
|
82 |
-
>
|
83 |
-
<h2 className={`mb-3 text-2xl font-semibold`}>
|
84 |
-
Templates{' '}
|
85 |
-
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
86 |
-
->
|
87 |
-
</span>
|
88 |
-
</h2>
|
89 |
-
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
90 |
-
Explore starter templates for Next.js.
|
91 |
-
</p>
|
92 |
-
</a>
|
93 |
-
|
94 |
-
<a
|
95 |
-
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
|
96 |
-
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
97 |
-
target="_blank"
|
98 |
-
rel="noopener noreferrer"
|
99 |
-
>
|
100 |
-
<h2 className={`mb-3 text-2xl font-semibold`}>
|
101 |
-
Deploy{' '}
|
102 |
-
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
103 |
-
->
|
104 |
-
</span>
|
105 |
-
</h2>
|
106 |
-
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
107 |
-
Instantly deploy your Next.js site to a shareable URL with Vercel.
|
108 |
-
</p>
|
109 |
-
</a>
|
110 |
-
</div>
|
111 |
</main>
|
112 |
-
)
|
113 |
}
|
|
|
1 |
+
import Link from "next/link";
|
2 |
|
3 |
export default function Home() {
|
4 |
return (
|
5 |
<main className="flex min-h-screen flex-col items-center justify-between p-24">
|
6 |
+
Hello
|
7 |
+
<hr />
|
8 |
+
<Link href="/test">Test</Link>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
</main>
|
10 |
+
);
|
11 |
}
|
frontend/app/test/page.js
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export default function Test() {
|
2 |
+
return (
|
3 |
+
<main className="flex min-h-screen flex-col items-center justify-between p-24">
|
4 |
+
Hi
|
5 |
+
</main>
|
6 |
+
);
|
7 |
+
}
|
frontend/package-lock.json
DELETED
The diff for this file is too large to render.
See raw diff
|
|
frontend/yarn.lock
ADDED
The diff for this file is too large to render.
See raw diff
|
|
requirements.txt
CHANGED
@@ -1,15 +1,7 @@
|
|
1 |
daily-python
|
2 |
-
blinker==1.7.0
|
3 |
-
click==8.1.7
|
4 |
-
Flask==3.0.0
|
5 |
-
Flask-Cors==4.0.0
|
6 |
-
gunicorn==21.2.0
|
7 |
-
itsdangerous==2.1.2
|
8 |
-
Jinja2==3.1.2
|
9 |
-
MarkupSafe==2.1.3
|
10 |
-
packaging==23.2
|
11 |
-
Werkzeug==3.0.1
|
12 |
python-dotenv
|
13 |
imageio-ffmpeg
|
14 |
imageio
|
15 |
-
requests
|
|
|
|
|
|
1 |
daily-python
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
python-dotenv
|
3 |
imageio-ffmpeg
|
4 |
imageio
|
5 |
+
requests
|
6 |
+
fastapi
|
7 |
+
uvicorn[standard]
|
server.py
CHANGED
@@ -1,91 +1,52 @@
|
|
1 |
-
from
|
2 |
-
from
|
|
|
|
|
3 |
from dotenv import load_dotenv
|
|
|
4 |
import os
|
5 |
-
import requests
|
6 |
-
import subprocess
|
7 |
-
import time
|
8 |
-
|
9 |
-
from app.auth import get_meeting_token
|
10 |
|
11 |
load_dotenv()
|
12 |
|
13 |
-
app =
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
return (
|
39 |
-
jsonify(
|
40 |
-
{
|
41 |
-
"error": "Unable to create room",
|
42 |
-
"status_code": res.status_code,
|
43 |
-
"text": res.text,
|
44 |
-
}
|
45 |
-
),
|
46 |
-
500,
|
47 |
-
)
|
48 |
-
'''
|
49 |
-
room_url = os.getenv("DAILY_ROOM_URL") #res.json()["url"]
|
50 |
-
room_name = os.getenv("DAILY_ROOM_NAME") #res.json()["name"]
|
51 |
-
|
52 |
-
meeting_token = get_meeting_token(room_url, daily_api_key, exp)
|
53 |
-
|
54 |
-
if args:
|
55 |
-
extra_args = " ".join([f'-{x[0]} "{x[1]}"' for x in args])
|
56 |
else:
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
)
|
66 |
-
|
67 |
-
# Don't return until the bot has joined the room, but wait for at most 2 seconds.
|
68 |
-
attempts = 0
|
69 |
-
while attempts < 20:
|
70 |
-
time.sleep(0.1)
|
71 |
-
attempts += 1
|
72 |
-
res = requests.get(
|
73 |
-
f"{api_path}/rooms/{room_name}/get-session-data",
|
74 |
-
headers={"Authorization": f"Bearer {daily_api_key}"},
|
75 |
-
)
|
76 |
-
if res.status_code == 200:
|
77 |
-
break
|
78 |
-
print(f"Took {attempts} attempts to join room {room_name}")
|
79 |
-
|
80 |
-
return jsonify({"room_url": room_url, "token": meeting_token}), 200
|
81 |
-
|
82 |
-
# Routes
|
83 |
-
@app.route("/start-bot", methods=["POST"])
|
84 |
-
def start_bot():
|
85 |
-
return _start_bot("./app/bot.py")
|
86 |
-
|
87 |
-
@app.route("/")
|
88 |
-
def home():
|
89 |
-
print(f'Static folder path: {app.static_folder}')
|
90 |
-
return send_from_directory(app.static_folder, 'index.html')
|
91 |
-
|
|
|
1 |
+
from fastapi import FastAPI, HTTPException
|
2 |
+
from fastapi.middleware.cors import CORSMiddleware
|
3 |
+
from fastapi.staticfiles import StaticFiles
|
4 |
+
from fastapi.responses import FileResponse
|
5 |
from dotenv import load_dotenv
|
6 |
+
from pathlib import Path
|
7 |
import os
|
|
|
|
|
|
|
|
|
|
|
8 |
|
9 |
load_dotenv()
|
10 |
|
11 |
+
app = FastAPI()
|
12 |
+
|
13 |
+
app.add_middleware(
|
14 |
+
CORSMiddleware,
|
15 |
+
allow_origins=["*"],
|
16 |
+
allow_credentials=True,
|
17 |
+
allow_methods=["*"],
|
18 |
+
allow_headers=["*"],
|
19 |
+
)
|
20 |
+
|
21 |
+
# Mount the static directory
|
22 |
+
app.mount("/static", StaticFiles(directory="frontend/out", html=True), name="static")
|
23 |
+
|
24 |
+
@app.get("/{path_name:path}")
|
25 |
+
async def catch_all(path_name: str):
|
26 |
+
# Default route for the root
|
27 |
+
if path_name == "":
|
28 |
+
path_name = "index"
|
29 |
+
|
30 |
+
# Construct file path with .html extension
|
31 |
+
file_path = Path("frontend/out") / f"{path_name}.html"
|
32 |
+
|
33 |
+
if file_path.is_file():
|
34 |
+
# Serve the .html file if it exists
|
35 |
+
return FileResponse(file_path)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
else:
|
37 |
+
# If the specific .html file does not exist, raise a 404 error
|
38 |
+
raise HTTPException(status_code=404, detail="Item not found")
|
39 |
+
|
40 |
+
# Run the application using Uvicorn
|
41 |
+
if __name__ == "__main__":
|
42 |
+
import uvicorn
|
43 |
+
|
44 |
+
uvicorn.run(
|
45 |
+
"server:app",
|
46 |
+
host="0.0.0.0",
|
47 |
+
port=int(os.getenv('FAST_API_PORT', 8000)),
|
48 |
+
reload=os.getenv('FAST_API_RELOAD', 'false').lower() == 'true',
|
49 |
+
#ssl_certfile=args.ssl_certfile,
|
50 |
+
#ssl_keyfile=args.ssl_keyfile,
|
51 |
)
|
52 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|