alessandro trinca tornidor
commited on
Commit
·
66a0f19
1
Parent(s):
cff759e
feat: handle custom relative url with env variables also on the frontend
Browse files- README.md +2 -2
- app.py +15 -15
- static/README.md +18 -27
- static/package.json +2 -1
- static/src/AppLisa.vue +4 -2
- static/src/AppSamgis.vue +4 -1
- static/vite.config.ts +2 -2
README.md
CHANGED
|
@@ -16,7 +16,7 @@ license: mit
|
|
| 16 |
|
| 17 |
I also adapted LISA to HuggingFace [lisa-on-cuda](https://huggingface.co/spaces/aletrn/lisa-on-cuda) ZeroGPU space.
|
| 18 |
|
| 19 |
-
##
|
| 20 |
|
| 21 |
Fundamental environment variables you need are:
|
| 22 |
|
|
@@ -43,5 +43,5 @@ The function `build_frontend()` from lisa_on_cuda package create all the folders
|
|
| 43 |
To change the base relative url for custom frontend add the VITE_PREFIX environment variable, e.g.:
|
| 44 |
|
| 45 |
```bash
|
| 46 |
-
|
| 47 |
```
|
|
|
|
| 16 |
|
| 17 |
I also adapted LISA to HuggingFace [lisa-on-cuda](https://huggingface.co/spaces/aletrn/lisa-on-cuda) ZeroGPU space.
|
| 18 |
|
| 19 |
+
## Custom environment variables for HuggingFace ZeroGPU Space
|
| 20 |
|
| 21 |
Fundamental environment variables you need are:
|
| 22 |
|
|
|
|
| 43 |
To change the base relative url for custom frontend add the VITE_PREFIX environment variable, e.g.:
|
| 44 |
|
| 45 |
```bash
|
| 46 |
+
VITE_INDEX_URL="/custom-url"
|
| 47 |
```
|
app.py
CHANGED
|
@@ -20,12 +20,12 @@ from samgis_lisa_on_zero.utilities.type_hints import ApiRequestBody, StringPromp
|
|
| 20 |
|
| 21 |
|
| 22 |
loglevel = os.getenv('LOGLEVEL', 'INFO').upper()
|
| 23 |
-
app_logger = setup_logging(debug=loglevel)
|
| 24 |
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
FASTAPI_TITLE = "samgis-lisa-on-zero"
|
| 30 |
app = FastAPI(title=FASTAPI_TITLE, version="1.0")
|
| 31 |
|
|
@@ -247,7 +247,6 @@ if bool(write_tmp_on_disk):
|
|
| 247 |
"list_files.html", {"request": request, "files": files_paths}
|
| 248 |
)
|
| 249 |
|
| 250 |
-
|
| 251 |
static_dist_folder = WORKDIR / "static" / "dist"
|
| 252 |
frontend_builder.build_frontend(
|
| 253 |
project_root_folder=frontend_builder.env_project_root_folder,
|
|
@@ -260,32 +259,31 @@ app_logger.info("build_frontend ok!")
|
|
| 260 |
|
| 261 |
templates = Jinja2Templates(directory="templates")
|
| 262 |
|
| 263 |
-
|
| 264 |
app.mount("/static", StaticFiles(directory=static_dist_folder, html=True), name="static")
|
| 265 |
# important: the index() function and the app.mount MUST be at the end
|
| 266 |
# samgis.html
|
| 267 |
-
app.mount(
|
| 268 |
|
| 269 |
|
| 270 |
-
@app.get(
|
| 271 |
async def samgis() -> FileResponse:
|
| 272 |
return FileResponse(path=static_dist_folder / "samgis.html", media_type="text/html")
|
| 273 |
|
| 274 |
|
| 275 |
# lisa.html
|
| 276 |
-
app.mount(
|
| 277 |
|
| 278 |
|
| 279 |
-
@app.get(
|
| 280 |
async def lisa() -> FileResponse:
|
| 281 |
return FileResponse(path=static_dist_folder / "lisa.html", media_type="text/html")
|
| 282 |
|
| 283 |
|
| 284 |
# # index.html (lisa.html copy)
|
| 285 |
-
app.mount(
|
| 286 |
|
| 287 |
|
| 288 |
-
@app.get(
|
| 289 |
async def index() -> FileResponse:
|
| 290 |
return FileResponse(path=static_dist_folder / "index.html", media_type="text/html")
|
| 291 |
|
|
@@ -296,8 +294,9 @@ inference_fn = app_helpers.get_inference_model_by_args(args, inference_decorator
|
|
| 296 |
|
| 297 |
app_helpers.app_logger.info(f"prepared inference_fn function:{inference_fn.__name__}, creating gradio interface...")
|
| 298 |
io = app_helpers.get_gradio_interface(inference_fn)
|
| 299 |
-
app_helpers.app_logger.info(
|
| 300 |
-
|
|
|
|
| 301 |
app_helpers.app_logger.info("mounted gradio app within fastapi")
|
| 302 |
|
| 303 |
|
|
@@ -306,6 +305,7 @@ if __name__ == '__main__':
|
|
| 306 |
uvicorn.run(host="0.0.0.0", port=7860, app=app)
|
| 307 |
except Exception as ex:
|
| 308 |
import logging
|
|
|
|
| 309 |
logging.error(f"fastapi/gradio application {FASTAPI_TITLE}, exception:{ex}.")
|
| 310 |
print(f"fastapi/gradio application {FASTAPI_TITLE}, exception:{ex}.")
|
| 311 |
raise ex
|
|
|
|
| 20 |
|
| 21 |
|
| 22 |
loglevel = os.getenv('LOGLEVEL', 'INFO').upper()
|
| 23 |
+
app_logger = setup_logging(debug=loglevel == "DEBUG")
|
| 24 |
|
| 25 |
+
VITE_INDEX_URL = os.getenv("VITE_INDEX_URL", "/")
|
| 26 |
+
VITE_SAMGIS_URL = os.getenv("VITE_SAMGIS_URL", "/samgis")
|
| 27 |
+
VITE_LISA_URL = os.getenv("VITE_LISA_URL", "/lisa")
|
| 28 |
+
VITE_GRADIO_URL = os.getenv("VITE_GRADIO_URL", "/gradio")
|
| 29 |
FASTAPI_TITLE = "samgis-lisa-on-zero"
|
| 30 |
app = FastAPI(title=FASTAPI_TITLE, version="1.0")
|
| 31 |
|
|
|
|
| 247 |
"list_files.html", {"request": request, "files": files_paths}
|
| 248 |
)
|
| 249 |
|
|
|
|
| 250 |
static_dist_folder = WORKDIR / "static" / "dist"
|
| 251 |
frontend_builder.build_frontend(
|
| 252 |
project_root_folder=frontend_builder.env_project_root_folder,
|
|
|
|
| 259 |
|
| 260 |
templates = Jinja2Templates(directory="templates")
|
| 261 |
|
|
|
|
| 262 |
app.mount("/static", StaticFiles(directory=static_dist_folder, html=True), name="static")
|
| 263 |
# important: the index() function and the app.mount MUST be at the end
|
| 264 |
# samgis.html
|
| 265 |
+
app.mount(VITE_SAMGIS_URL, StaticFiles(directory=static_dist_folder, html=True), name="samgis")
|
| 266 |
|
| 267 |
|
| 268 |
+
@app.get(VITE_SAMGIS_URL)
|
| 269 |
async def samgis() -> FileResponse:
|
| 270 |
return FileResponse(path=static_dist_folder / "samgis.html", media_type="text/html")
|
| 271 |
|
| 272 |
|
| 273 |
# lisa.html
|
| 274 |
+
app.mount(VITE_LISA_URL, StaticFiles(directory=static_dist_folder, html=True), name="lisa")
|
| 275 |
|
| 276 |
|
| 277 |
+
@app.get(VITE_LISA_URL)
|
| 278 |
async def lisa() -> FileResponse:
|
| 279 |
return FileResponse(path=static_dist_folder / "lisa.html", media_type="text/html")
|
| 280 |
|
| 281 |
|
| 282 |
# # index.html (lisa.html copy)
|
| 283 |
+
app.mount(VITE_INDEX_URL, StaticFiles(directory=static_dist_folder, html=True), name="index")
|
| 284 |
|
| 285 |
|
| 286 |
+
@app.get(VITE_INDEX_URL)
|
| 287 |
async def index() -> FileResponse:
|
| 288 |
return FileResponse(path=static_dist_folder / "index.html", media_type="text/html")
|
| 289 |
|
|
|
|
| 294 |
|
| 295 |
app_helpers.app_logger.info(f"prepared inference_fn function:{inference_fn.__name__}, creating gradio interface...")
|
| 296 |
io = app_helpers.get_gradio_interface(inference_fn)
|
| 297 |
+
app_helpers.app_logger.info(
|
| 298 |
+
f"created gradio interface, mounting gradio app on url {VITE_GRADIO_URL} within FastAPI...")
|
| 299 |
+
app = gr.mount_gradio_app(app, io, path=VITE_GRADIO_URL)
|
| 300 |
app_helpers.app_logger.info("mounted gradio app within fastapi")
|
| 301 |
|
| 302 |
|
|
|
|
| 305 |
uvicorn.run(host="0.0.0.0", port=7860, app=app)
|
| 306 |
except Exception as ex:
|
| 307 |
import logging
|
| 308 |
+
|
| 309 |
logging.error(f"fastapi/gradio application {FASTAPI_TITLE}, exception:{ex}.")
|
| 310 |
print(f"fastapi/gradio application {FASTAPI_TITLE}, exception:{ex}.")
|
| 311 |
raise ex
|
static/README.md
CHANGED
|
@@ -1,36 +1,27 @@
|
|
| 1 |
-
#
|
| 2 |
|
| 3 |
-
|
| 4 |
|
| 5 |
-
|
| 6 |
|
| 7 |
-
|
| 8 |
-
2. run the local environment using the command `pnpm dev` or `deno run -A runner.js`
|
| 9 |
|
| 10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
|
| 12 |
-
|
| 13 |
-
deno run -A --node-modules-dir npm:vite
|
| 14 |
-
```
|
| 15 |
|
| 16 |
-
|
|
|
|
|
|
|
| 17 |
|
| 18 |
-
|
| 19 |
|
| 20 |
-
|
| 21 |
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
3. Run again the local development server, this time with the standard command
|
| 25 |
-
|
| 26 |
-
Before to commit try also to build using
|
| 27 |
-
|
| 28 |
-
```bash
|
| 29 |
-
pnpm build
|
| 30 |
-
```
|
| 31 |
-
|
| 32 |
-
Then run the preview (change the example variables):
|
| 33 |
-
|
| 34 |
-
```bash
|
| 35 |
-
npx wrangler pages dev --binding VITE_AUTH0_DOMAIN="example-auth0.eu.auth0.com" API_URL="https://example-aws.execute-api.eu-west-1.amazonaws.com/localhost/lambda-ml-fastsam-api" VITE_AUTH0_AUDIENCE="http://localhost-ml-lambda/" API_DOMAIN=example-aws.execute-api.eu-west-1.amazonaws.com CORS_ALLOWED_DOMAIN=http://localhost:8788 VITE_SATELLITE_NAME="tile-provider.image-type" -- pnpm preview
|
| 36 |
-
```
|
|
|
|
| 1 |
+
# SamGIS+LISA+ZeroGPU!
|
| 2 |
|
| 3 |
+
[LISA](https://github.com/dvlab-research/LISA) (Reasoning Segmentation via Large Language Model) applied to geospatial data thanks to [SamGIS](https://github.com/trincadev/samgis-be).
|
| 4 |
|
| 5 |
+
I also adapted LISA to HuggingFace [lisa-on-cuda](https://huggingface.co/spaces/aletrn/lisa-on-cuda) ZeroGPU space.
|
| 6 |
|
| 7 |
+
## projects I based this work on
|
|
|
|
| 8 |
|
| 9 |
+
- [LISA](https://github.com/dvlab-research/LISA)
|
| 10 |
+
- [Segment Anything](https://segment-anything.com)
|
| 11 |
+
- [ONNX Runtime](https://onnxruntime.ai/)
|
| 12 |
+
- [transformers](https://github.com/huggingface/transformers)
|
| 13 |
+
- [Vue](https://vuejs.org)
|
| 14 |
+
- [leaflet](https://leafletjs.com/)
|
| 15 |
|
| 16 |
+
My previous projects I reused:
|
|
|
|
|
|
|
| 17 |
|
| 18 |
+
- [SamGIS+LISA (regular GPU) huggingface space](https://huggingface.co/spaces/aletrn/samgis-lisa-on-cuda), [SamGIS+LISA blog page](https://trinca.tornidor.com/projects/lisa-adapted-for-samgis)
|
| 19 |
+
- [lisa-on-cuda huggingface space](https://huggingface.co/spaces/aletrn/samgis-lisa-on-cuda)
|
| 20 |
+
- [transformers-backport repository](https://github.com/trincadev/transformers_backport), [transformers pip package](https://snyk.io/advisor/python/transformers-backport)
|
| 21 |
|
| 22 |
+
# Build the frontend
|
| 23 |
|
| 24 |
+
Check the package.json for the custom commands, in particular:
|
| 25 |
|
| 26 |
+
- `build:tailwindcss`
|
| 27 |
+
- `build`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static/package.json
CHANGED
|
@@ -5,7 +5,8 @@
|
|
| 5 |
"dev": "vite",
|
| 6 |
"build": "vite build",
|
| 7 |
"preview": "vite preview --port 5173",
|
| 8 |
-
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore"
|
|
|
|
| 9 |
},
|
| 10 |
"type": "module",
|
| 11 |
"dependencies": {
|
|
|
|
| 5 |
"dev": "vite",
|
| 6 |
"build": "vite build",
|
| 7 |
"preview": "vite preview --port 5173",
|
| 8 |
+
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore",
|
| 9 |
+
"build:tailwindcss": "pnpm tailwindcss -i src/input.css -o dist/output.css"
|
| 10 |
},
|
| 11 |
"type": "module",
|
| 12 |
"dependencies": {
|
static/src/AppLisa.vue
CHANGED
|
@@ -3,9 +3,9 @@
|
|
| 3 |
aboutThisDescription="LISA adapted to SamGIS on ZeroGPU"
|
| 4 |
aboutThisUrl="https://trinca.tornidor.com/projects/lisa-adapted-for-samgis"
|
| 5 |
currentPageUrl="https://aletrn-samgis-lisa-on-zero.hf.space"
|
| 6 |
-
pageTitle="+ZeroGPU"
|
| 7 |
switchTabDescription="SamGIS on ZeroGPU demo"
|
| 8 |
-
switchTabUrl=
|
| 9 |
>
|
| 10 |
<div>
|
| 11 |
<div id="map-container-md-lisa">
|
|
@@ -26,6 +26,8 @@ import { ref } from 'vue'
|
|
| 26 |
import PageLisaMap from '@/components/PageLisaMap.vue'
|
| 27 |
import PageLayout from '@/components/PageLayout.vue'
|
| 28 |
|
|
|
|
|
|
|
| 29 |
const mapName = ref('lisa-map')
|
| 30 |
const description = ref("This page displays predictions made with LISA VLM.")
|
| 31 |
</script>
|
|
|
|
| 3 |
aboutThisDescription="LISA adapted to SamGIS on ZeroGPU"
|
| 4 |
aboutThisUrl="https://trinca.tornidor.com/projects/lisa-adapted-for-samgis"
|
| 5 |
currentPageUrl="https://aletrn-samgis-lisa-on-zero.hf.space"
|
| 6 |
+
pageTitle="SamGIS+LISA+ZeroGPU"
|
| 7 |
switchTabDescription="SamGIS on ZeroGPU demo"
|
| 8 |
+
:switchTabUrl=switchTabUrlRef
|
| 9 |
>
|
| 10 |
<div>
|
| 11 |
<div id="map-container-md-lisa">
|
|
|
|
| 26 |
import PageLisaMap from '@/components/PageLisaMap.vue'
|
| 27 |
import PageLayout from '@/components/PageLayout.vue'
|
| 28 |
|
| 29 |
+
const switchTabUrl = import.meta.env.VITE_SAMGIS_URL ? import.meta.env.VITE_SAMGIS_URL : "/samgis"
|
| 30 |
+
const switchTabUrlRef = ref(switchTabUrl)
|
| 31 |
const mapName = ref('lisa-map')
|
| 32 |
const description = ref("This page displays predictions made with LISA VLM.")
|
| 33 |
</script>
|
static/src/AppSamgis.vue
CHANGED
|
@@ -5,7 +5,7 @@
|
|
| 5 |
currentPageUrl="https://aletrn-samgis-lisa-on-zero.hf.space/samgis"
|
| 6 |
pageTitle="SamGIS demo"
|
| 7 |
switchTabDescription="LISA+SamGIS+ZeroGPU demo"
|
| 8 |
-
switchTabUrl="
|
| 9 |
>
|
| 10 |
<div>
|
| 11 |
<div id="map-container-md-main">
|
|
@@ -31,11 +31,14 @@ import { onMounted, ref } from 'vue'
|
|
| 31 |
import PredictionMap from '@/components/PagePredictionMap.vue'
|
| 32 |
import PageLayout from '@/components/PageLayout.vue'
|
| 33 |
|
|
|
|
|
|
|
| 34 |
const mapName = ref('prediction-map')
|
| 35 |
const description = ref("This page displays predictions made with a machine learning model")
|
| 36 |
|
| 37 |
onMounted(() => {
|
| 38 |
console.log("descr:", description.value, import.meta.env.VITE__MAP_DESCRIPTION)
|
|
|
|
| 39 |
description.value = import.meta.env.VITE__MAP_DESCRIPTION ? import.meta.env.VITE__MAP_DESCRIPTION : description.value
|
| 40 |
})
|
| 41 |
</script>
|
|
|
|
| 5 |
currentPageUrl="https://aletrn-samgis-lisa-on-zero.hf.space/samgis"
|
| 6 |
pageTitle="SamGIS demo"
|
| 7 |
switchTabDescription="LISA+SamGIS+ZeroGPU demo"
|
| 8 |
+
:switchTabUrl="switchTabUrlRef"
|
| 9 |
>
|
| 10 |
<div>
|
| 11 |
<div id="map-container-md-main">
|
|
|
|
| 31 |
import PredictionMap from '@/components/PagePredictionMap.vue'
|
| 32 |
import PageLayout from '@/components/PageLayout.vue'
|
| 33 |
|
| 34 |
+
const switchTabUrl = import.meta.env.VITE_LISA_URL ? import.meta.env.VITE_LISA_URL : "/"
|
| 35 |
+
const switchTabUrlRef = ref(switchTabUrl)
|
| 36 |
const mapName = ref('prediction-map')
|
| 37 |
const description = ref("This page displays predictions made with a machine learning model")
|
| 38 |
|
| 39 |
onMounted(() => {
|
| 40 |
console.log("descr:", description.value, import.meta.env.VITE__MAP_DESCRIPTION)
|
| 41 |
+
console.log("switchTabUrl:", switchTabUrl, ", urls from env:", import.meta.env.VITE_SAMGIS_URL, import.meta.env.VITE_LISA_URL, "#")
|
| 42 |
description.value = import.meta.env.VITE__MAP_DESCRIPTION ? import.meta.env.VITE__MAP_DESCRIPTION : description.value
|
| 43 |
})
|
| 44 |
</script>
|
static/vite.config.ts
CHANGED
|
@@ -6,8 +6,8 @@ import vue from '@vitejs/plugin-vue'
|
|
| 6 |
// https://vitejs.dev/config/
|
| 7 |
export default defineConfig(({mode}) => {
|
| 8 |
const env = loadEnv(mode, process.cwd())
|
| 9 |
-
const frontendPrefix = env.
|
| 10 |
-
console.log(`VITE_PREFIX:${env.
|
| 11 |
return {
|
| 12 |
plugins: [vue()],
|
| 13 |
base: frontendPrefix,
|
|
|
|
| 6 |
// https://vitejs.dev/config/
|
| 7 |
export default defineConfig(({mode}) => {
|
| 8 |
const env = loadEnv(mode, process.cwd())
|
| 9 |
+
const frontendPrefix = env.VITE_INDEX_URL ? env.VITE_INDEX_URL : "/"
|
| 10 |
+
console.log(`VITE_PREFIX:${env.VITE_INDEX_URL}, frontend_prefix:${frontendPrefix}, mode:${mode} ...`)
|
| 11 |
return {
|
| 12 |
plugins: [vue()],
|
| 13 |
base: frontendPrefix,
|