feat: better docker build strategy

This commit is contained in:
wear工程师 2023-12-07 23:28:04 +08:00
parent 91934ecae9
commit 854c2af9d5
7 changed files with 193 additions and 35 deletions

5
.dockerignore Normal file
View File

@ -0,0 +1,5 @@
node_modules
dist
build
.git
frontend/node_modules

4
.gitignore vendored
View File

@ -1,6 +1,7 @@
.aider* .aider*
# Project-related files # Project-related files
webui
# Run logs # Run logs
backend/run_logs/* backend/run_logs/*
@ -14,3 +15,6 @@ frontend/.env.local
# Mac files # Mac files
.DS_Store .DS_Store
# Editor files
.vscode

26
Dockerfile Normal file
View File

@ -0,0 +1,26 @@
FROM node:20-alpine as build-frontend
WORKDIR /app
RUN corepack enable
COPY ./frontend /app/
ENV VITE_IS_WEB_UI_MODE=true
RUN yarn install && yarn build
FROM thehale/python-poetry as build-backend
RUN apt update && apt install -y binutils
WORKDIR /app
COPY ./backend /app/
RUN poetry install --no-interaction
RUN poetry run pyinstaller --clean --onefile --name backend main.py
FROM debian:bookworm-slim
ENV FASTAPI_ENV=production
ENV OPENAI_API_KEY=
WORKDIR /app
COPY --from=build-frontend /app/dist /app/webui
COPY --from=build-backend /app/dist/backend /app/backend
EXPOSE 8000
CMD ["/app/backend"]

View File

@ -9,8 +9,9 @@ import os
import traceback import traceback
from datetime import datetime from datetime import datetime
from fastapi import FastAPI, WebSocket from fastapi import FastAPI, WebSocket
from fastapi.staticfiles import StaticFiles
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import HTMLResponse from fastapi.responses import FileResponse, HTMLResponse
import openai import openai
from llm import stream_openai_response from llm import stream_openai_response
from mock import mock_completion from mock import mock_completion
@ -40,12 +41,19 @@ SHOULD_MOCK_AI_RESPONSE = bool(os.environ.get("MOCK", False))
# Used as a feature flag to enable or disable certain features # Used as a feature flag to enable or disable certain features
IS_PROD = os.environ.get("IS_PROD", False) IS_PROD = os.environ.get("IS_PROD", False)
# if webui folder exists, we are in build mode
IS_BUILD = os.path.exists("webui")
app.include_router(screenshot.router) app.include_router(screenshot.router)
@app.get("/") @app.get("/")
async def get_status(): async def get_status():
if IS_BUILD:
# if in build mode, return webui/index.html
return FileResponse("webui/index.html")
return HTMLResponse( return HTMLResponse(
content="<h3>Your backend is running correctly. Please open the front-end URL (default is http://localhost:5173) to use screenshot-to-code.</h3>" content="<h3>Your backend is running correctly. Please open the front-end URL (default is http://localhost:5173) to use screenshot-to-code.</h3>"
) )
@ -259,3 +267,12 @@ async def stream_code(websocket: WebSocket):
) )
await websocket.close() await websocket.close()
# Serve the webui folder as static files
if IS_BUILD:
app.mount("/", StaticFiles(directory="webui", html=True), name="webui")
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)

155
backend/poetry.lock generated
View File

@ -1,10 +1,20 @@
# This file is automatically @generated by Poetry 1.4.1 and should not be changed by hand. # This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
[[package]]
name = "altgraph"
version = "0.17.4"
description = "Python graph (network) package"
optional = false
python-versions = "*"
files = [
{file = "altgraph-0.17.4-py2.py3-none-any.whl", hash = "sha256:642743b4750de17e655e6711601b077bc6598dbfa3ba5fa2b2a35ce12b508dff"},
{file = "altgraph-0.17.4.tar.gz", hash = "sha256:1b5afbb98f6c4dcadb2e2ae6ab9fa994bbb8c1d75f4fa96d340f9437ae454406"},
]
[[package]] [[package]]
name = "anyio" name = "anyio"
version = "3.7.1" version = "3.7.1"
description = "High level compatibility layer for multiple asynchronous event loop implementations" description = "High level compatibility layer for multiple asynchronous event loop implementations"
category = "main"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
@ -26,7 +36,6 @@ trio = ["trio (<0.22)"]
name = "beautifulsoup4" name = "beautifulsoup4"
version = "4.12.2" version = "4.12.2"
description = "Screen-scraping library" description = "Screen-scraping library"
category = "main"
optional = false optional = false
python-versions = ">=3.6.0" python-versions = ">=3.6.0"
files = [ files = [
@ -45,7 +54,6 @@ lxml = ["lxml"]
name = "certifi" name = "certifi"
version = "2023.11.17" version = "2023.11.17"
description = "Python package for providing Mozilla's CA Bundle." description = "Python package for providing Mozilla's CA Bundle."
category = "main"
optional = false optional = false
python-versions = ">=3.6" python-versions = ">=3.6"
files = [ files = [
@ -57,7 +65,6 @@ files = [
name = "click" name = "click"
version = "8.1.7" version = "8.1.7"
description = "Composable command line interface toolkit" description = "Composable command line interface toolkit"
category = "main"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
@ -72,7 +79,6 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""}
name = "colorama" name = "colorama"
version = "0.4.6" version = "0.4.6"
description = "Cross-platform colored terminal text." description = "Cross-platform colored terminal text."
category = "main"
optional = false optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
files = [ files = [
@ -84,7 +90,6 @@ files = [
name = "distro" name = "distro"
version = "1.8.0" version = "1.8.0"
description = "Distro - an OS platform information API" description = "Distro - an OS platform information API"
category = "main"
optional = false optional = false
python-versions = ">=3.6" python-versions = ">=3.6"
files = [ files = [
@ -96,7 +101,6 @@ files = [
name = "exceptiongroup" name = "exceptiongroup"
version = "1.2.0" version = "1.2.0"
description = "Backport of PEP 654 (exception groups)" description = "Backport of PEP 654 (exception groups)"
category = "main"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
@ -111,7 +115,6 @@ test = ["pytest (>=6)"]
name = "fastapi" name = "fastapi"
version = "0.95.2" version = "0.95.2"
description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
category = "main"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
@ -133,7 +136,6 @@ test = ["anyio[trio] (>=3.2.1,<4.0.0)", "black (==23.1.0)", "coverage[toml] (>=6
name = "h11" name = "h11"
version = "0.14.0" version = "0.14.0"
description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1"
category = "main"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
@ -145,7 +147,6 @@ files = [
name = "httpcore" name = "httpcore"
version = "1.0.2" version = "1.0.2"
description = "A minimal low-level HTTP client." description = "A minimal low-level HTTP client."
category = "main"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
@ -160,14 +161,13 @@ h11 = ">=0.13,<0.15"
[package.extras] [package.extras]
asyncio = ["anyio (>=4.0,<5.0)"] asyncio = ["anyio (>=4.0,<5.0)"]
http2 = ["h2 (>=3,<5)"] http2 = ["h2 (>=3,<5)"]
socks = ["socksio (>=1.0.0,<2.0.0)"] socks = ["socksio (==1.*)"]
trio = ["trio (>=0.22.0,<0.23.0)"] trio = ["trio (>=0.22.0,<0.23.0)"]
[[package]] [[package]]
name = "httpx" name = "httpx"
version = "0.25.2" version = "0.25.2"
description = "The next generation HTTP client." description = "The next generation HTTP client."
category = "main"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
@ -178,21 +178,20 @@ files = [
[package.dependencies] [package.dependencies]
anyio = "*" anyio = "*"
certifi = "*" certifi = "*"
httpcore = ">=1.0.0,<2.0.0" httpcore = "==1.*"
idna = "*" idna = "*"
sniffio = "*" sniffio = "*"
[package.extras] [package.extras]
brotli = ["brotli", "brotlicffi"] brotli = ["brotli", "brotlicffi"]
cli = ["click (>=8.0.0,<9.0.0)", "pygments (>=2.0.0,<3.0.0)", "rich (>=10,<14)"] cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"]
http2 = ["h2 (>=3,<5)"] http2 = ["h2 (>=3,<5)"]
socks = ["socksio (>=1.0.0,<2.0.0)"] socks = ["socksio (==1.*)"]
[[package]] [[package]]
name = "idna" name = "idna"
version = "3.6" version = "3.6"
description = "Internationalized Domain Names in Applications (IDNA)" description = "Internationalized Domain Names in Applications (IDNA)"
category = "main"
optional = false optional = false
python-versions = ">=3.5" python-versions = ">=3.5"
files = [ files = [
@ -200,11 +199,24 @@ files = [
{file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"},
] ]
[[package]]
name = "macholib"
version = "1.16.3"
description = "Mach-O header analysis and editing"
optional = false
python-versions = "*"
files = [
{file = "macholib-1.16.3-py2.py3-none-any.whl", hash = "sha256:0e315d7583d38b8c77e815b1ecbdbf504a8258d8b3e17b61165c6feb60d18f2c"},
{file = "macholib-1.16.3.tar.gz", hash = "sha256:07ae9e15e8e4cd9a788013d81f5908b3609aa76f9b1421bae9c4d7606ec86a30"},
]
[package.dependencies]
altgraph = ">=0.17"
[[package]] [[package]]
name = "openai" name = "openai"
version = "1.3.7" version = "1.3.7"
description = "The official Python library for the openai API" description = "The official Python library for the openai API"
category = "main"
optional = false optional = false
python-versions = ">=3.7.1" python-versions = ">=3.7.1"
files = [ files = [
@ -224,11 +236,32 @@ typing-extensions = ">=4.5,<5"
[package.extras] [package.extras]
datalib = ["numpy (>=1)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"] datalib = ["numpy (>=1)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"]
[[package]]
name = "packaging"
version = "23.2"
description = "Core utilities for Python packages"
optional = false
python-versions = ">=3.7"
files = [
{file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"},
{file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"},
]
[[package]]
name = "pefile"
version = "2023.2.7"
description = "Python PE parsing module"
optional = false
python-versions = ">=3.6.0"
files = [
{file = "pefile-2023.2.7-py3-none-any.whl", hash = "sha256:da185cd2af68c08a6cd4481f7325ed600a88f6a813bad9dea07ab3ef73d8d8d6"},
{file = "pefile-2023.2.7.tar.gz", hash = "sha256:82e6114004b3d6911c77c3953e3838654b04511b8b66e8583db70c65998017dc"},
]
[[package]] [[package]]
name = "pydantic" name = "pydantic"
version = "1.10.13" version = "1.10.13"
description = "Data validation and settings management using python type hints" description = "Data validation and settings management using python type hints"
category = "main"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
@ -277,11 +310,55 @@ typing-extensions = ">=4.2.0"
dotenv = ["python-dotenv (>=0.10.4)"] dotenv = ["python-dotenv (>=0.10.4)"]
email = ["email-validator (>=1.0.3)"] email = ["email-validator (>=1.0.3)"]
[[package]]
name = "pyinstaller"
version = "6.2.0"
description = "PyInstaller bundles a Python application and all its dependencies into a single package."
optional = false
python-versions = "<3.13,>=3.8"
files = [
{file = "pyinstaller-6.2.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:a1adbd3cf25dc90926d783eae0f444d65cdfecc7bcdf6da522c3ae3ff47b4c25"},
{file = "pyinstaller-6.2.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:29d164394f1e949072f78a64c1e040f1c47b7f4aff08514c7666a031c8b44996"},
{file = "pyinstaller-6.2.0-py3-none-manylinux2014_i686.whl", hash = "sha256:ba602a38d7403de89c38b8956b221ce6de0280730d269bab522492fcad82ee33"},
{file = "pyinstaller-6.2.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:ebac06d99b80d2035594c3cc2fb5f2612d86289edd0510dbcbeb20a873f51d5a"},
{file = "pyinstaller-6.2.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:fcfabc0ff1d38a4262c051dea3fdc1f7f106405c1f1b491b4c79cd28df19cab6"},
{file = "pyinstaller-6.2.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:104430686149b2f1c135b2c17aa2967c85d54ef77dc92feb4e179ec846c0c467"},
{file = "pyinstaller-6.2.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:e87fd60292b53bb9965cb5a84122875469a2bd475fd0d0db0052a3f1be351f75"},
{file = "pyinstaller-6.2.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:8ec9d6c98972bb922cedb16a6638257aa66e5deadd79e2953f3464696237c413"},
{file = "pyinstaller-6.2.0-py3-none-win32.whl", hash = "sha256:e5561e9a9b946d835c8dbc11ae4c16cc21e62bc77d10cc043406dc2992dfb4c6"},
{file = "pyinstaller-6.2.0-py3-none-win_amd64.whl", hash = "sha256:3b586196277c4c54b69880650984c39c28bb6258c2b4b64200032e6ac69d53a0"},
{file = "pyinstaller-6.2.0-py3-none-win_arm64.whl", hash = "sha256:d0c87b605bf13c3a04dfaa1d2fa7cd36765b8137000eeadccba865e1d6a19bf0"},
{file = "pyinstaller-6.2.0.tar.gz", hash = "sha256:1ce77043929bf525be38289d78feecde0fcf15506215eda6500176a8715c5047"},
]
[package.dependencies]
altgraph = "*"
macholib = {version = ">=1.8", markers = "sys_platform == \"darwin\""}
packaging = ">=22.0"
pefile = {version = ">=2022.5.30", markers = "sys_platform == \"win32\""}
pyinstaller-hooks-contrib = ">=2021.4"
pywin32-ctypes = {version = ">=0.2.1", markers = "sys_platform == \"win32\""}
setuptools = ">=42.0.0"
[package.extras]
completion = ["argcomplete"]
hook-testing = ["execnet (>=1.5.0)", "psutil", "pytest (>=2.7.3)"]
[[package]]
name = "pyinstaller-hooks-contrib"
version = "2023.10"
description = "Community maintained hooks for PyInstaller"
optional = false
python-versions = ">=3.7"
files = [
{file = "pyinstaller-hooks-contrib-2023.10.tar.gz", hash = "sha256:4b4a998036abb713774cb26534ca06b7e6e09e4c628196017a10deb11a48747f"},
{file = "pyinstaller_hooks_contrib-2023.10-py2.py3-none-any.whl", hash = "sha256:6dc1786a8f452941245d5bb85893e2a33632ebdcbc4c23eea41f2ee08281b0c0"},
]
[[package]] [[package]]
name = "python-dotenv" name = "python-dotenv"
version = "1.0.0" version = "1.0.0"
description = "Read key-value pairs from a .env file and set them as environment variables" description = "Read key-value pairs from a .env file and set them as environment variables"
category = "main"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
@ -292,11 +369,37 @@ files = [
[package.extras] [package.extras]
cli = ["click (>=5.0)"] cli = ["click (>=5.0)"]
[[package]]
name = "pywin32-ctypes"
version = "0.2.2"
description = "A (partial) reimplementation of pywin32 using ctypes/cffi"
optional = false
python-versions = ">=3.6"
files = [
{file = "pywin32-ctypes-0.2.2.tar.gz", hash = "sha256:3426e063bdd5fd4df74a14fa3cf80a0b42845a87e1d1e81f6549f9daec593a60"},
{file = "pywin32_ctypes-0.2.2-py3-none-any.whl", hash = "sha256:bf490a1a709baf35d688fe0ecf980ed4de11d2b3e37b51e5442587a75d9957e7"},
]
[[package]]
name = "setuptools"
version = "69.0.2"
description = "Easily download, build, install, upgrade, and uninstall Python packages"
optional = false
python-versions = ">=3.8"
files = [
{file = "setuptools-69.0.2-py3-none-any.whl", hash = "sha256:1e8fdff6797d3865f37397be788a4e3cba233608e9b509382a2777d25ebde7f2"},
{file = "setuptools-69.0.2.tar.gz", hash = "sha256:735896e78a4742605974de002ac60562d286fa8051a7e2299445e8e8fbb01aa6"},
]
[package.extras]
docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
[[package]] [[package]]
name = "sniffio" name = "sniffio"
version = "1.3.0" version = "1.3.0"
description = "Sniff out which async library your code is running under" description = "Sniff out which async library your code is running under"
category = "main"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
@ -308,7 +411,6 @@ files = [
name = "soupsieve" name = "soupsieve"
version = "2.5" version = "2.5"
description = "A modern CSS selector implementation for Beautiful Soup." description = "A modern CSS selector implementation for Beautiful Soup."
category = "main"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
@ -320,7 +422,6 @@ files = [
name = "starlette" name = "starlette"
version = "0.27.0" version = "0.27.0"
description = "The little ASGI library that shines." description = "The little ASGI library that shines."
category = "main"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
@ -338,7 +439,6 @@ full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart", "pyyam
name = "tqdm" name = "tqdm"
version = "4.66.1" version = "4.66.1"
description = "Fast, Extensible Progress Meter" description = "Fast, Extensible Progress Meter"
category = "main"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
@ -359,7 +459,6 @@ telegram = ["requests"]
name = "typing-extensions" name = "typing-extensions"
version = "4.8.0" version = "4.8.0"
description = "Backported and Experimental Type Hints for Python 3.8+" description = "Backported and Experimental Type Hints for Python 3.8+"
category = "main"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
@ -371,7 +470,6 @@ files = [
name = "uvicorn" name = "uvicorn"
version = "0.24.0.post1" version = "0.24.0.post1"
description = "The lightning-fast ASGI server." description = "The lightning-fast ASGI server."
category = "main"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
@ -391,7 +489,6 @@ standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)",
name = "websockets" name = "websockets"
version = "12.0" version = "12.0"
description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)"
category = "main"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
@ -471,5 +568,5 @@ files = [
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.10" python-versions = "^3.10, <3.13"
content-hash = "b8d248a44a5eea9638a7726096de77d7a9aa8c00673da806534da2c228ffabb4" content-hash = "23222ae60dfaacf4357f3a66c4a363f3c7d9d7e3b365ceddc23585e7c5efc27b"

View File

@ -6,7 +6,7 @@ authors = ["Abi Raja <abimanyuraja@gmail.com>"]
license = "MIT" license = "MIT"
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^3.10" python = "^3.10, <3.13"
fastapi = "^0.95.0" fastapi = "^0.95.0"
uvicorn = "^0.24.0.post1" uvicorn = "^0.24.0.post1"
websockets = "^12.0" websockets = "^12.0"
@ -15,6 +15,9 @@ python-dotenv = "^1.0.0"
beautifulsoup4 = "^4.12.2" beautifulsoup4 = "^4.12.2"
httpx = "^0.25.1" httpx = "^0.25.1"
[tool.poetry.group.dev.dependencies]
pyinstaller = "^6.2.0"
[build-system] [build-system]
requires = ["poetry-core"] requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api" build-backend = "poetry.core.masonry.api"

View File

@ -2,11 +2,17 @@
export const IS_RUNNING_ON_CLOUD = export const IS_RUNNING_ON_CLOUD =
import.meta.env.VITE_IS_DEPLOYED === "true" || false; import.meta.env.VITE_IS_DEPLOYED === "true" || false;
export const WS_BACKEND_URL = // If is web ui mode, use relative paths
import.meta.env.VITE_WS_BACKEND_URL || "ws://127.0.0.1:7001"; export const IS_WEB_UI_MODE =
import.meta.env.VITE_IS_WEB_UI_MODE === "true" || false;
export const HTTP_BACKEND_URL = export const WS_BACKEND_URL = IS_WEB_UI_MODE
import.meta.env.VITE_HTTP_BACKEND_URL || "http://127.0.0.1:7001"; ? `ws://${location.host}`
: import.meta.env.VITE_WS_BACKEND_URL || "ws://127.0.0.1:7001";
export const HTTP_BACKEND_URL = IS_WEB_UI_MODE
? location.origin
: import.meta.env.VITE_HTTP_BACKEND_URL || "http://127.0.0.1:7001";
export const PICO_BACKEND_FORM_SECRET = export const PICO_BACKEND_FORM_SECRET =
import.meta.env.VITE_PICO_BACKEND_FORM_SECRET || null; import.meta.env.VITE_PICO_BACKEND_FORM_SECRET || null;