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 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
- ##  Custom environment variables for HuggingFace ZeroGPU Space
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
- VITE_PREFIX="/custom-url"
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
- CUSTOM_INDEX_URL = os.getenv("CUSTOM_INDEX_URL", "/static")
26
- CUSTOM_SAMGIS_URL = os.getenv("CUSTOM_SAMGIS_URL", "/samgis")
27
- CUSTOM_LISA_URL = os.getenv("CUSTOM_LISA_URL", "/lisa")
28
- CUSTOM_GRADIO_URL = os.getenv("CUSTOM_GRADIO_URL", "/")
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(CUSTOM_SAMGIS_URL, StaticFiles(directory=static_dist_folder, html=True), name="samgis")
268
 
269
 
270
- @app.get(CUSTOM_SAMGIS_URL)
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(CUSTOM_LISA_URL, StaticFiles(directory=static_dist_folder, html=True), name="lisa")
277
 
278
 
279
- @app.get(CUSTOM_LISA_URL)
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(CUSTOM_INDEX_URL, StaticFiles(directory=static_dist_folder, html=True), name="index")
286
 
287
 
288
- @app.get(CUSTOM_INDEX_URL)
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(f"created gradio interface, mounting gradio app on url {CUSTOM_GRADIO_URL} within FastAPI...")
300
- app = gr.mount_gradio_app(app, io, path=CUSTOM_GRADIO_URL)
 
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
- # ml-tornidor
2
 
3
- ## Local development
4
 
5
- Since I use Cloudflare pages as hosting for this project there are some required steps to do before it's possible to start a local development environment. This project needs to wrap the node commands with the `npx wrangler [...]` utility to emulate a Cloudflare Worker function. Because this worker function is under auth which use some env variables I to write these env variables inline. Every time I changed or added needed some variables I also needed to update the `npx wrangler` command. To avoid this I prepared a js script, executed by [Deno](https://deno.land/), that read the env variables from the `.env` file composing the command:
6
 
7
- 1. prepare the .env file copying the template.env file
8
- 2. run the local environment using the command `pnpm dev` or `deno run -A runner.js`
9
 
10
- In case of new or updated packages Deno installs the dependencies at the first execution. Do it with a execution without the `npx wrangler` wrapper:
 
 
 
 
 
11
 
12
- ```bash
13
- deno run -A --node-modules-dir npm:vite
14
- ```
15
 
16
- In case of problem:
 
 
17
 
18
- 1. try executing again the command `deno run -A --node-modules-dir npm:vite`
19
 
20
- If this don't solve the problems try to
21
 
22
- 1. delete the node_modules folder
23
- 2. reinstall the npm packages with `pnpm install`
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="/samgis"
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.VITE_PREFIX ? env.VITE_PREFIX : "/"
10
- console.log(`VITE_PREFIX:${env.VITE_PREFIX}, frontend_prefix:${frontendPrefix}, mode:${mode} ...`)
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,