alessandro trinca tornidor commited on
Commit
8783164
Β·
1 Parent(s): 2b9f7fd

feat: first attempt to support samgis-lisa-on-cuda on ZeroGPU huggingface space

Browse files
Files changed (40) hide show
  1. .idea/inspectionProfiles/Project_Default.xml +6 -0
  2. .idea/misc.xml +2 -2
  3. Dockerfile +0 -208
  4. README.md +9 -131
  5. wrappers/fastapi_wrapper.py β†’ app.py +46 -21
  6. dockerfiles/dockerfile-lisa-predictions +1 -1
  7. packages.txt +2 -0
  8. poetry.lock +0 -0
  9. pyproject.toml +14 -42
  10. requirements.txt +15 -0
  11. {samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/__init__.py +2 -2
  12. {samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/__version__.py +0 -0
  13. {samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/io/__init__.py +0 -0
  14. {samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/io/coordinates_pixel_conversion.py +4 -4
  15. {samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/io/geo_helpers.py +1 -1
  16. {samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/io/raster_helpers.py +5 -5
  17. {samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/io/tms2geotiff.py +6 -6
  18. {samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/io/wrappers_helpers.py +4 -4
  19. {samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/prediction_api/__init__.py +0 -0
  20. {samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/prediction_api/global_models.py +1 -1
  21. {samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/prediction_api/lisa.py +25 -13
  22. {samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/prediction_api/predictors.py +7 -7
  23. {samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/utilities/__init__.py +0 -0
  24. {samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/utilities/constants.py +1 -0
  25. {samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/utilities/session_logger.py +0 -0
  26. {samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/utilities/type_hints.py +0 -0
  27. scripts/extract-openapi-fastapi.py +1 -1
  28. scripts/extract-openapi-lambda.py +2 -2
  29. static/vite.config.ts +24 -21
  30. tests/__init__.py +1 -1
  31. tests/io/test_coordinates_pixel_conversion.py +2 -2
  32. tests/io/test_geo_helpers.py +3 -3
  33. tests/io/test_raster_helpers.py +3 -3
  34. tests/io/test_tms2geotiff.py +2 -2
  35. tests/io/test_wrappers_helpers.py +5 -5
  36. tests/prediction_api/test_predictors.py +2 -2
  37. tests/test_fastapi_app.py +4 -4
  38. tests/test_lambda_app.py +2 -2
  39. wrappers/__init__.py +0 -0
  40. wrappers/lambda_wrapper.py +0 -58
.idea/inspectionProfiles/Project_Default.xml ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ <component name="InspectionProjectProfileManager">
2
+ <profile version="1.0">
3
+ <option name="myName" value="Project Default" />
4
+ <inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
5
+ </profile>
6
+ </component>
.idea/misc.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <project version="4">
3
  <component name="Black">
4
- <option name="sdkName" value="Poetry (samgis-lisa-on-cuda)" />
5
  </component>
6
- <component name="ProjectRootManager" version="2" project-jdk-name="Poetry (samgis-lisa-on-cuda)" project-jdk-type="Python SDK" />
7
  </project>
 
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <project version="4">
3
  <component name="Black">
4
+ <option name="sdkName" value="Poetry (samgis-lisa-on-zero)" />
5
  </component>
6
+ <component name="ProjectRootManager" version="2" project-jdk-name="Poetry (samgis-lisa-on-zero)" project-jdk-type="Python SDK" />
7
  </project>
Dockerfile DELETED
@@ -1,208 +0,0 @@
1
- # Include global ARGs at the dockerfile top
2
- ARG ARCH="x86_64"
3
- ARG LAMBDA_TASK_ROOT="/var/task"
4
- ARG FASTAPI_STATIC="${LAMBDA_TASK_ROOT}/static"
5
- ARG PYTHONPATH="${LAMBDA_TASK_ROOT}:${PYTHONPATH}:/usr/local/lib/python3/dist-packages"
6
- ARG POETRY_NO_INTERACTION=1
7
- ARG POETRY_VIRTUALENVS_IN_PROJECT=1
8
- ARG POETRY_VIRTUALENVS_CREATE=1
9
- ARG POETRY_CACHE_DIR=/tmp/poetry_cache
10
- ARG DEPENDENCY_GROUP=fastapi
11
-
12
-
13
- FROM pytorch/pytorch:2.2.2-cuda12.1-cudnn8-runtime as builder_global
14
-
15
- LABEL authors="alessandro@trinca.tornidor.com"
16
-
17
- ARG ARCH
18
- ARG LAMBDA_TASK_ROOT
19
- ARG PYTHONPATH
20
- ARG POETRY_NO_INTERACTION
21
- ARG POETRY_VIRTUALENVS_IN_PROJECT
22
- ARG POETRY_VIRTUALENVS_CREATE
23
- ARG POETRY_CACHE_DIR
24
- ARG DEPENDENCY_GROUP
25
-
26
- RUN echo "ARCH: $ARCH ..."
27
-
28
- RUN echo "ARG POETRY_CACHE_DIR: ${POETRY_CACHE_DIR} ..."
29
- RUN echo "ARG PYTHONPATH: $PYTHONPATH ..."
30
- RUN test -n ${DEPENDENCY_GROUP:?}
31
- RUN echo "python DEPENDENCY_GROUP: ${DEPENDENCY_GROUP} ..."
32
- RUN echo "arg dep:"
33
-
34
- # Set working directory to function root directory
35
- WORKDIR ${LAMBDA_TASK_ROOT}
36
- COPY requirements_poetry.txt pyproject.toml poetry.lock README.md ${LAMBDA_TASK_ROOT}/
37
-
38
- RUN cat /etc/lsb-release
39
- # avoid segment-geospatial exception caused by missing libGL.so.1 library
40
- RUN echo "BUILDER: check libz.s* before start" && ls -l /usr/lib/${ARCH}-linux-gnu/libz.so*
41
-
42
- RUN apt update && apt upgrade -y && apt install -y libgl1 curl python3-pip git-lfs && apt clean
43
- COPY ./dockerfiles/apt_preferences_ubuntu /etc/apt/preferences
44
- COPY ./dockerfiles/ubuntu.sources /etc/apt/sources.list.d/ubuntu.sources
45
- #RUN echo "run update noble..."
46
- #RUN apt update
47
- #RUN apt update && apt install -t noble zlib1g -y
48
- RUN git lfs install
49
- RUN echo "BUILDER: check libz.s* after install from trixie" && ls -l /usr/lib/${ARCH}-linux-gnu/libz.so*
50
-
51
- RUN ls -l /etc/apt/sources* /etc/apt/preferences*
52
-
53
- # poetry installation path is NOT within ${LAMBDA_TASK_ROOT}: not needed for runtime docker image
54
- RUN python -m pip install -r ${LAMBDA_TASK_ROOT}/requirements_poetry.txt
55
-
56
- RUN which poetry && poetry --version && poetry config --list
57
- RUN poetry config virtualenvs.path ${LAMBDA_TASK_ROOT}
58
- RUN poetry config installer.max-workers 7
59
- RUN echo "# poetry config --list #" && poetry config --list
60
- RUN ls -ld ${LAMBDA_TASK_ROOT}/
61
- #RUN . ${LAMBDA_TASK_ROOT}/.venv/bin/activate && ${LAMBDA_TASK_ROOT}/.venv/bin/python --version && ${LAMBDA_TASK_ROOT}/.venv/bin/python -m pip install pip wheel setuptools --upgrade
62
- RUN poetry run python -m pip install pip wheel setuptools --upgrade
63
- RUN poetry install --with ${DEPENDENCY_GROUP} --no-root
64
-
65
- RUN git clone https://huggingface.co/aletrn/sam-quantized/ ${LAMBDA_TASK_ROOT}/sam-quantized
66
- RUN git clone -n --depth=1 --filter=tree:0 https://huggingface.co/spaces/aletrn/lisa-on-cuda ${LAMBDA_TASK_ROOT}/lisa-on-cuda && \
67
- cd ${LAMBDA_TASK_ROOT}/lisa-on-cuda && \
68
- git sparse-checkout set --no-cone resources && \
69
- git checkout
70
- WORKDIR ${LAMBDA_TASK_ROOT}
71
- RUN ls -l ${LAMBDA_TASK_ROOT}/*
72
-
73
-
74
- FROM pytorch/pytorch:2.2.2-cuda12.1-cudnn8-runtime as runtime
75
-
76
- ARG ARCH
77
- ARG LAMBDA_TASK_ROOT
78
-
79
- ENV VIRTUAL_ENV=${LAMBDA_TASK_ROOT}/.venv \
80
- PATH="${LAMBDA_TASK_ROOT}/.venv/bin:$PATH"
81
-
82
- RUN echo "COPY --from=builder_global /usr/lib/${ARCH}-linux-gnu/libGL.so* /usr/lib/${ARCH}-linux-gnu/"
83
- COPY --from=builder_global /usr/lib/${ARCH}-linux-gnu/libGL.so* /usr/lib/${ARCH}-linux-gnu/
84
- RUN echo "RUNTIME: check libz.s* before upgrade" && ls -l /usr/lib/${ARCH}-linux-gnu/libz.so*
85
- RUN echo "RUNTIME: remove libz.s* to force upgrade" && rm /usr/lib/${ARCH}-linux-gnu/libz.so*
86
- COPY --from=builder_global /usr/lib/${ARCH}-linux-gnu/libz.so* /usr/lib/${ARCH}-linux-gnu/
87
- RUN echo "RUNTIME: check libz.s* after copy" && ls -l /usr/lib/${ARCH}-linux-gnu/libz.so*
88
- COPY --from=builder_global ${LAMBDA_TASK_ROOT}/.venv ${LAMBDA_TASK_ROOT}/.venv
89
-
90
- RUN echo "new LAMBDA_TASK_ROOT after hidden venv copy => ${LAMBDA_TASK_ROOT}"
91
- RUN ls -ld ${LAMBDA_TASK_ROOT}/
92
- RUN ls -lA ${LAMBDA_TASK_ROOT}/
93
- RUN echo "content of LAMBDA_TASK_ROOT/.venv => ${LAMBDA_TASK_ROOT}/.venv"
94
- RUN ls -ld ${LAMBDA_TASK_ROOT}/.venv
95
- RUN ls -lA ${LAMBDA_TASK_ROOT}/.venv
96
-
97
-
98
- ### conditional section
99
- FROM node:20-slim AS node_fastapi
100
-
101
- ARG DEPENDENCY_GROUP
102
- ENV PNPM_HOME="/pnpm"
103
- ENV PATH="$PNPM_HOME:$PATH"
104
-
105
- RUN corepack enable
106
-
107
- COPY ./static /appnode
108
- WORKDIR /appnode
109
- # RUN if [ "${DEPENDENCY_GROUP}" = "fastapi" ]; then echo "pnpm store path:" && pnpm store path; fi
110
- RUN ls -l /appnode
111
- RUN ls -l /appnode/list_files.html
112
-
113
-
114
- FROM node_fastapi AS node_prod_deps
115
-
116
- ARG DEPENDENCY_GROUP
117
- RUN --mount=type=cache,id=pnpm,target=/pnpm/store if [ "${DEPENDENCY_GROUP}" = "fastapi" ]; then \
118
- pnpm install --prod --frozen-lockfile; else \
119
- echo "DEPENDENCY_GROUP 1: ${DEPENDENCY_GROUP} ..."; fi
120
- # here multiple conditions concatenated to avoid failing on check
121
- RUN if [ "${DEPENDENCY_GROUP}" = "fastapi" ]; then if [ ! -d /appnode/node_modules ]; then \
122
- echo "no node_modules folder" && exit 1; fi; fi
123
-
124
-
125
- FROM node_fastapi AS node_build
126
-
127
- ARG DEPENDENCY_GROUP
128
- ARG VITE__MAP_DESCRIPTION
129
- ARG VITE__SAMGIS_SPACE
130
- RUN echo "VITE__MAP_DESCRIPTION:" ${VITE__MAP_DESCRIPTION}
131
- RUN echo "VITE__SAMGIS_SPACE:" ${VITE__SAMGIS_SPACE}
132
-
133
- RUN --mount=type=cache,id=pnpm,target=/pnpm/store if [ "${DEPENDENCY_GROUP}" = "fastapi" ]; then \
134
- pnpm install --frozen-lockfile; else \
135
- echo "DEPENDENCY_GROUP 2: ${DEPENDENCY_GROUP} ..."; fi
136
- RUN --mount=type=cache,id=pnpm,target=/pnpm/store if [ "${DEPENDENCY_GROUP}" = "fastapi" ]; then pnpm build; fi
137
- RUN --mount=type=cache,id=pnpm,target=/pnpm/store if [ "${DEPENDENCY_GROUP}" = "fastapi" ]; then \
138
- pnpm tailwindcss -i /appnode/src/input.css -o /appnode/dist/output.css; fi
139
- RUN if [ "${DEPENDENCY_GROUP}" = "fastapi" ]; then if [ ! -d /appnode/dist ]; then echo "no dist folder" && exit 1; fi; fi
140
-
141
-
142
- FROM runtime
143
- ARG FASTAPI_STATIC
144
-
145
- RUN echo "show disk space, df -h ..."
146
- RUN df -h
147
- RUN echo "creating FASTAPI_STATIC folder: ${FASTAPI_STATIC}, use `mkdir -p` to avoid failure if missing parent folder ..."
148
- RUN mkdir -p ${FASTAPI_STATIC}
149
-
150
- COPY --from=builder_global ${LAMBDA_TASK_ROOT}/sam-quantized/machine_learning_models \
151
- ${LAMBDA_TASK_ROOT}/machine_learning_models
152
- RUN ls -ld ${LAMBDA_TASK_ROOT}/machine_learning_models
153
- RUN ls -lh ${LAMBDA_TASK_ROOT}/machine_learning_models
154
- COPY --from=builder_global ${LAMBDA_TASK_ROOT}/lisa-on-cuda/resources ${LAMBDA_TASK_ROOT}/resources
155
- COPY --from=node_prod_deps /appnode/node_modules* ${FASTAPI_STATIC}/node_modules
156
- COPY --from=node_build /appnode/dist* ${FASTAPI_STATIC}/dist
157
- COPY --from=node_build /appnode/list_files.html ${FASTAPI_STATIC}/list_files.html
158
- RUN ls -l ${FASTAPI_STATIC}/
159
- RUN ls -l ${FASTAPI_STATIC}/list_files.html
160
-
161
-
162
- # Include global arg in this stage of the build
163
- ARG LAMBDA_TASK_ROOT="/var/task"
164
- ARG PYTHONPATH="${LAMBDA_TASK_ROOT}:${PYTHONPATH}:/usr/local/lib/python3/dist-packages"
165
- ENV VIRTUAL_ENV=${LAMBDA_TASK_ROOT}/.venv \
166
- PATH="${LAMBDA_TASK_ROOT}/.venv/bin:$PATH"
167
- ENV IS_AWS_LAMBDA=""
168
-
169
- # Set working directory to function root directory
170
- WORKDIR ${LAMBDA_TASK_ROOT}
171
-
172
- COPY samgis_lisa_on_cuda ${LAMBDA_TASK_ROOT}/samgis_lisa_on_cuda
173
- COPY wrappers ${LAMBDA_TASK_ROOT}/wrappers
174
- COPY scripts ${LAMBDA_TASK_ROOT}/scripts
175
- RUN chmod +x ${LAMBDA_TASK_ROOT}/scripts/entrypoint.sh
176
- RUN chmod +x ${LAMBDA_TASK_ROOT}/scripts/docker_entrypoint.sh
177
- RUN ls -l ${LAMBDA_TASK_ROOT}/scripts/entrypoint.sh ${LAMBDA_TASK_ROOT}/scripts/docker_entrypoint.sh
178
-
179
- RUN ls -l /usr/bin/which
180
- RUN /usr/bin/which python
181
- RUN python --version
182
- RUN echo "PYTHONPATH: ${PYTHONPATH}."
183
- RUN echo "PATH: ${PATH}."
184
- RUN echo "LAMBDA_TASK_ROOT: ${LAMBDA_TASK_ROOT}."
185
- RUN ls -l ${LAMBDA_TASK_ROOT}
186
- RUN ls -ld ${LAMBDA_TASK_ROOT}
187
- RUN ls -l ${LAMBDA_TASK_ROOT}/machine_learning_models
188
- RUN python -c "import sys; print(sys.path)"
189
- RUN python -c "import cv2"
190
- RUN python -c "import fastapi"
191
- RUN python -c "import geopandas"
192
- RUN python -c "import loguru"
193
- RUN python -c "import onnxruntime"
194
- RUN python -c "import rasterio"
195
- RUN python -c "import uvicorn"
196
- RUN df -h
197
- RUN ls -l ${LAMBDA_TASK_ROOT}/samgis_lisa_on_cuda/
198
- RUN ls -l ${LAMBDA_TASK_ROOT}/wrappers/
199
- RUN echo "LAMBDA_TASK_ROOT /static/:"
200
- RUN ls -l ${LAMBDA_TASK_ROOT}/static/ || true
201
- RUN ls -l ${LAMBDA_TASK_ROOT}/static/dist || true
202
- RUN ls -l ${LAMBDA_TASK_ROOT}/static/node_modules || true
203
- RUN echo "FASTAPI_STATIC:"
204
- RUN ls -l ${FASTAPI_STATIC}/ || true
205
- RUN ls -l ${FASTAPI_STATIC}/dist || true
206
- RUN ls -l ${FASTAPI_STATIC}/node_modules || true
207
-
208
- CMD ["/var/task/scripts/docker_entrypoint.sh"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
README.md CHANGED
@@ -1,143 +1,21 @@
1
  ---
2
- title: SamGIS - LISA on zero
3
  emoji: πŸ—ΊοΈ
4
  colorFrom: red
5
  colorTo: blue
6
- sdk: docker
7
- pinned: false
 
 
8
  license: mit
9
  ---
10
 
11
- # [LISA](https://github.com/dvlab-research/LISA) and [SamGIS](https://github.com/trincadev/samgis-be)
12
 
13
  [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).
14
 
15
- ## Segment Anything models
16
 
17
- It's possible to prepare the model files using https://github.com/vietanhdev/samexporter/ or using the ones
18
- from https://huggingface.co/aletrn/sam-quantized (copy them within the folder `/machine_learning_models`).
19
 
20
- ## SamGIS - HuggingFace version
21
-
22
- The SamGIS HuggingSpace url is https://huggingface.co/spaces/aletrn/samgis-lisa-on-cuda.
23
- Build the docker image this way:
24
-
25
- ```bash
26
- # clean any old active containers
27
- docker stop $(docker ps -a -q); docker rm $(docker ps -a -q)
28
-
29
- # build the base docker image from the repository root folder using ARGs:
30
- # - DEPENDENCY_GROUP=fastapi used by poetry
31
- # VITE__MAP_DESCRIPTION, VITE__SAMGIS_SPACE used by 'docker build'
32
- (
33
- set -o allexport && source <(cat ./static/.env|grep VITE__) && set +o allexport;
34
- env|grep VITE__;
35
- docker build . -f dockerfiles/dockerfile-samgis-base --progress=plain \
36
- --build-arg DEPENDENCY_GROUP=fastapi \
37
- --build-arg VITE__MAP_DESCRIPTION=${VITE__MAP_DESCRIPTION} \
38
- --build-arg VITE__SAMGIS_SPACE=${VITE__SAMGIS_SPACE} \
39
- --tag registry.gitlab.com/aletrn/gis-prediction
40
- )
41
-
42
- # build the image, use the tag "samgis-huggingface"
43
- docker build . --tag example-docker-namespace/samgis-huggingface --progress=plain
44
- ```
45
-
46
- Run the container (keep it on background) and show logs
47
-
48
- ```bash
49
- docker run -d --name samgis-huggingface -p 7860:7860 example-docker-namespace/samgis-huggingface; docker logs -f samgis-huggingface
50
- ```
51
-
52
- Test it with curl using a json payload:
53
-
54
- ```bash
55
- URL=http://localhost:7860/infer_samgis
56
- curl -d@./events/payload_point_eolie.json -H 'accept: application/json' ${URL}
57
- ```
58
-
59
- or better visiting the swagger page on http://localhost:7860/docs
60
-
61
- ### Dependencies installation and local tests
62
- The docker build process needs only the base dependency group plus the `aws_lambda` or `fastapi` optional one.
63
- Install also the `test` and/or `docs` groups if needed.
64
-
65
- ### Tests
66
-
67
- Tests are defined in the `tests` folder in this project. Use PIP to install the test dependencies and run tests.
68
-
69
- ```bash
70
- python -m pytest --cov=samgis_lisa_on_cuda --cov-report=term-missing && coverage html
71
- ```
72
-
73
- ### How to update the static documentation with sphinx
74
-
75
- This project documentation uses sphinx-apidoc: it's a tool for automatic generation of Sphinx sources that, using the autodoc
76
- extension, document a whole package in the style of other automatic API documentation tools. See the
77
- [documentation page](https://www.sphinx-doc.org/en/master/man/sphinx-apidoc.html) for details.
78
- Run the command from the project root:
79
-
80
- ```bash
81
- # missing docs folder (run from project root) initialize this way
82
- cd docs && sphinx-quickstart -p SamGIS -r 1.0.0 -l python --master index
83
-
84
- # update docs folder (from project root)
85
- sphinx-apidoc -f -o docs samgis
86
- ```
87
-
88
- Then it's possible to generate the HTML pages
89
-
90
- ```bash
91
- cd docs && make html && ../
92
-
93
- # to clean old files
94
- cd docs && make clean html && cd ../
95
- ```
96
-
97
- The static documentation it's now ready at the path `docs/_build/html/index.html`.
98
-
99
- To create a work in progress openapi json or yaml file use
100
-
101
- - `extract-openapi-fastapi.py`
102
- - `extract-openapi-lambda.py` (useful to export the json schema request and response from lambda app api)
103
-
104
- ### Handle dynamic folder creation
105
-
106
- it's possible to dynamically create a new support folder adding it to a json string env FOLDERS_MAP, e.g.:
107
-
108
- ```json
109
- {
110
- "WORKDIR": "/var/task",
111
- "XDG_CACHE_HOME": "/data",
112
- "PROJECT_ROOT_FOLDER": "/data",
113
- "MPLCONFIGDIR": "/data/.cache/matplotlib",
114
- "TRANSFORMERS_CACHE": "/data/.cache/transformers",
115
- "PYTORCH_KERNEL_CACHE_PATH": "/data/.cache/torch/kernels",
116
- "FASTAPI_STATIC": "/var/task/static",
117
- "VIS_OUTPUT": "/data/vis_output"
118
- }
119
- ```
120
-
121
- The python script create_folders_and_variables_if_not_exists.py will read this env variable, removing any files that exists with these pathnames and assert the correct creation of all the folders. Also these folders must exist as env variables, so the script assert that an env variable exists with its path.
122
-
123
- It's possible to use the project in a bare metal installation (not within a docker container). To do this
124
-
125
- - download this project
126
- - prepare a virtualenv and install the python dependencies
127
- - install nodejs LTS
128
- - create a .env_source file (in this case `HOME=/home/jovyan`)
129
-
130
- ```bash
131
- export FOLDERS_MAP='{"WORKDIR":"/home/jovyan/workspace/samgis-lisa-on-cuda","XDG_CACHE_HOME":"/home/jovyan/.cache","PROJECT_ROOT_FOLDER":"/home/jovyan/","MPLCONFIGDIR":"/home/jovyan/.cache/matplotlib","TRANSFORMERS_CACHE":"/home/jovyan/.cache/transformers","PYTORCH_KERNEL_CACHE_PATH":"/home/jovyan/.cache/torch/kernels","FASTAPI_STATIC":"/home/jovyan/workspace/samgis-lisa-on-cuda/static","VIS_OUTPUT":"/home/jovyan/workspace/samgis-lisa-on-cuda/vis_output"}'
132
- export WORKDIR="$HOME/workspace/samgis-lisa-on-cuda"
133
- export XDG_CACHE_HOME="$HOME/.cache"
134
- export PROJECT_ROOT_FOLDER="$HOME/"
135
- export MPLCONFIGDIR="$HOME/.cache/matplotlib"
136
- export TRANSFORMERS_CACHE="$HOME/.cache/transformers"
137
- export PYTORCH_KERNEL_CACHE_PATH="$HOME/.cache/torch/kernels"
138
- export FASTAPI_STATIC="$HOME/workspace/samgis-lisa-on-cuda/static"
139
- export VIS_OUTPUT="$HOME/workspace/samgis-lisa-on-cuda/vis_output"
140
- export WRITE_TMP_ON_DISK=${VIS_OUTPUT}
141
- ```
142
-
143
- - execute the script `baremetal_entrypoint.sh` instead than `docker_entrypoint.sh`.
 
1
  ---
2
+ title: SamGIS - LISA on CUDA
3
  emoji: πŸ—ΊοΈ
4
  colorFrom: red
5
  colorTo: blue
6
+ sdk: gradio
7
+ sdk_version: 4.37.2
8
+ app_file: app.py
9
+ pinned: true
10
  license: mit
11
  ---
12
 
13
+ # [LISA](https://github.com/dvlab-research/LISA) + [SamGIS](https://github.com/trincadev/samgis-be) on Zero GPU!
14
 
15
  [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).
16
 
17
+ About SamGIS - LISA on CUDA see the [samgis-lisa-on-cuda demo](https://huggingface.co/spaces/aletrn/samgis-lisa-on-cuda).
18
 
19
+ To change the base relative url for custom frontend add the VITE_PREFIX environment variable, e.g.:
 
20
 
21
+ VITE_PREFIX="/custom-url"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
wrappers/fastapi_wrapper.py β†’ app.py RENAMED
@@ -3,21 +3,29 @@ import os
3
  import pathlib
4
  import uuid
5
 
6
- from fastapi.templating import Jinja2Templates
7
  import uvicorn
8
  from fastapi import FastAPI, HTTPException, Request, status
9
  from fastapi.exceptions import RequestValidationError
10
  from fastapi.responses import FileResponse, HTMLResponse, JSONResponse
11
  from fastapi.staticfiles import StaticFiles
 
 
12
  from pydantic import ValidationError
13
-
14
- from samgis_lisa_on_cuda import PROJECT_ROOT_FOLDER, WORKDIR
15
- from samgis_lisa_on_cuda.utilities.type_hints import ApiRequestBody, StringPromptApiRequestBody
16
  from samgis_core.utilities.fastapi_logger import setup_logging
17
 
 
 
 
 
18
 
19
- app_logger = setup_logging(debug=True)
20
- app = FastAPI()
 
 
 
 
 
 
21
 
22
 
23
  @app.middleware("http")
@@ -42,7 +50,7 @@ async def request_middleware(request, call_next):
42
 
43
  @app.post("/post_test_dictlist")
44
  def post_test_dictlist2(request_input: ApiRequestBody) -> JSONResponse:
45
- from samgis_lisa_on_cuda.io.wrappers_helpers import get_parsed_bbox_points_with_dictlist_prompt
46
 
47
  request_body = get_parsed_bbox_points_with_dictlist_prompt(request_input)
48
  app_logger.info(f"request_body:{request_body}.")
@@ -57,13 +65,13 @@ async def health() -> JSONResponse:
57
  import importlib.metadata
58
  from importlib.metadata import PackageNotFoundError
59
 
 
60
  try:
61
  core_version = importlib.metadata.version('samgis_core')
62
  lisa_on_cuda_version = importlib.metadata.version('lisa-on-cuda')
63
  samgis_lisa_on_cuda_version = importlib.metadata.version('samgis-lisa-on-cuda')
64
  except PackageNotFoundError as pe:
65
  app_logger.error(f"pe:{pe}.")
66
- samgis_lisa_on_cuda_version = "0.0.0"
67
 
68
  msg = "still alive, "
69
  msg += f"""version:{samgis_lisa_on_cuda_version}, core version:{core_version},"""
@@ -76,7 +84,7 @@ async def health() -> JSONResponse:
76
  @app.post("/post_test_string")
77
  def post_test_string(request_input: StringPromptApiRequestBody) -> JSONResponse:
78
  from lisa_on_cuda.utils import app_helpers
79
- from samgis_lisa_on_cuda.io.wrappers_helpers import get_parsed_bbox_points_with_string_prompt
80
 
81
  request_body = get_parsed_bbox_points_with_string_prompt(request_input)
82
  app_logger.info(f"request_body:{request_body}.")
@@ -90,8 +98,8 @@ def post_test_string(request_input: StringPromptApiRequestBody) -> JSONResponse:
90
 
91
  @app.post("/infer_lisa")
92
  def infer_lisa(request_input: StringPromptApiRequestBody) -> JSONResponse:
93
- from samgis_lisa_on_cuda.prediction_api import lisa
94
- from samgis_lisa_on_cuda.io.wrappers_helpers import get_parsed_bbox_points_with_string_prompt, get_source_name
95
 
96
  app_logger.info("starting lisa inference request...")
97
 
@@ -107,7 +115,7 @@ def infer_lisa(request_input: StringPromptApiRequestBody) -> JSONResponse:
107
  app_logger.info(f"source_name = {source_name}.")
108
  output = lisa.lisa_predict(
109
  bbox=body_request["bbox"], prompt=body_request["prompt"], zoom=body_request["zoom"],
110
- source=body_request["source"], source_name=source_name
111
  )
112
  duration_run = time.time() - time_start_run
113
  app_logger.info(f"duration_run:{duration_run}.")
@@ -136,8 +144,8 @@ def infer_lisa(request_input: StringPromptApiRequestBody) -> JSONResponse:
136
 
137
  @app.post("/infer_samgis")
138
  def infer_samgis(request_input: ApiRequestBody) -> JSONResponse:
139
- from samgis_lisa_on_cuda.prediction_api import predictors
140
- from samgis_lisa_on_cuda.io.wrappers_helpers import get_parsed_bbox_points_with_dictlist_prompt, get_source_name
141
 
142
  app_logger.info("starting plain samgis inference request...")
143
 
@@ -237,32 +245,49 @@ if bool(write_tmp_on_disk):
237
  )
238
 
239
 
 
 
 
 
 
 
 
 
 
240
  # important: the index() function and the app.mount MUST be at the end
241
  # samgis.html
242
- app.mount("/samgis", StaticFiles(directory=WORKDIR / "static" / "dist", html=True), name="samgis")
243
 
244
 
245
  @app.get("/samgis")
246
  async def samgis() -> FileResponse:
247
- return FileResponse(path=WORKDIR / "static" / "dist" / "samgis.html", media_type="text/html")
248
 
249
 
250
  # lisa.html
251
- app.mount("/lisa", StaticFiles(directory=WORKDIR / "static" / "dist", html=True), name="lisa")
252
 
253
 
254
  @app.get("/lisa")
255
  async def lisa() -> FileResponse:
256
- return FileResponse(path=WORKDIR / "static" / "dist" / "lisa.html", media_type="text/html")
257
 
258
 
259
- # index.html (lisa.html copy)
260
- app.mount("/", StaticFiles(directory=WORKDIR / "static" / "dist", html=True), name="index")
261
 
262
 
263
  @app.get("/")
264
  async def index() -> FileResponse:
265
- return FileResponse(path=WORKDIR / "static" / "dist" / "index.html", media_type="text/html")
 
 
 
 
 
 
 
 
266
 
267
 
268
  if __name__ == '__main__':
 
3
  import pathlib
4
  import uuid
5
 
 
6
  import uvicorn
7
  from fastapi import FastAPI, HTTPException, Request, status
8
  from fastapi.exceptions import RequestValidationError
9
  from fastapi.responses import FileResponse, HTMLResponse, JSONResponse
10
  from fastapi.staticfiles import StaticFiles
11
+ from fastapi.templating import Jinja2Templates
12
+ from lisa_on_cuda.utils import app_helpers, frontend_builder, create_folders_and_variables_if_not_exists
13
  from pydantic import ValidationError
 
 
 
14
  from samgis_core.utilities.fastapi_logger import setup_logging
15
 
16
+ from samgis_lisa_on_zero import PROJECT_ROOT_FOLDER, WORKDIR
17
+ from samgis_lisa_on_zero.prediction_api.global_models import models_dict
18
+ from samgis_lisa_on_zero.utilities.constants import LISA_INFERENCE_FN
19
+ from samgis_lisa_on_zero.utilities.type_hints import ApiRequestBody, StringPromptApiRequestBody
20
 
21
+
22
+ loglevel = os.getenv('LOGLEVEL', 'INFO').upper()
23
+ app_logger = setup_logging(debug=loglevel)
24
+
25
+ CUSTOM_GRADIO_PATH = "/"
26
+ CUSTOM_STATIC_PATH = "/static"
27
+ FASTAPI_TITLE = "samgis-lisa-on-zero"
28
+ app = FastAPI(title=FASTAPI_TITLE, version="1.0")
29
 
30
 
31
  @app.middleware("http")
 
50
 
51
  @app.post("/post_test_dictlist")
52
  def post_test_dictlist2(request_input: ApiRequestBody) -> JSONResponse:
53
+ from samgis_lisa_on_zero.io.wrappers_helpers import get_parsed_bbox_points_with_dictlist_prompt
54
 
55
  request_body = get_parsed_bbox_points_with_dictlist_prompt(request_input)
56
  app_logger.info(f"request_body:{request_body}.")
 
65
  import importlib.metadata
66
  from importlib.metadata import PackageNotFoundError
67
 
68
+ core_version = lisa_on_cuda_version = samgis_lisa_on_cuda_version = ""
69
  try:
70
  core_version = importlib.metadata.version('samgis_core')
71
  lisa_on_cuda_version = importlib.metadata.version('lisa-on-cuda')
72
  samgis_lisa_on_cuda_version = importlib.metadata.version('samgis-lisa-on-cuda')
73
  except PackageNotFoundError as pe:
74
  app_logger.error(f"pe:{pe}.")
 
75
 
76
  msg = "still alive, "
77
  msg += f"""version:{samgis_lisa_on_cuda_version}, core version:{core_version},"""
 
84
  @app.post("/post_test_string")
85
  def post_test_string(request_input: StringPromptApiRequestBody) -> JSONResponse:
86
  from lisa_on_cuda.utils import app_helpers
87
+ from samgis_lisa_on_zero.io.wrappers_helpers import get_parsed_bbox_points_with_string_prompt
88
 
89
  request_body = get_parsed_bbox_points_with_string_prompt(request_input)
90
  app_logger.info(f"request_body:{request_body}.")
 
98
 
99
  @app.post("/infer_lisa")
100
  def infer_lisa(request_input: StringPromptApiRequestBody) -> JSONResponse:
101
+ from samgis_lisa_on_zero.prediction_api import lisa
102
+ from samgis_lisa_on_zero.io.wrappers_helpers import get_parsed_bbox_points_with_string_prompt, get_source_name
103
 
104
  app_logger.info("starting lisa inference request...")
105
 
 
115
  app_logger.info(f"source_name = {source_name}.")
116
  output = lisa.lisa_predict(
117
  bbox=body_request["bbox"], prompt=body_request["prompt"], zoom=body_request["zoom"],
118
+ source=body_request["source"], source_name=source_name, inference_function_name_key=LISA_INFERENCE_FN
119
  )
120
  duration_run = time.time() - time_start_run
121
  app_logger.info(f"duration_run:{duration_run}.")
 
144
 
145
  @app.post("/infer_samgis")
146
  def infer_samgis(request_input: ApiRequestBody) -> JSONResponse:
147
+ from samgis_lisa_on_zero.prediction_api import predictors
148
+ from samgis_lisa_on_zero.io.wrappers_helpers import get_parsed_bbox_points_with_dictlist_prompt, get_source_name
149
 
150
  app_logger.info("starting plain samgis inference request...")
151
 
 
245
  )
246
 
247
 
248
+ static_dist_folder = WORKDIR / "static" / "dist"
249
+ frontend_builder.build_frontend(
250
+ project_root_folder=frontend_builder.env_project_root_folder,
251
+ input_css_path=frontend_builder.env_input_css_path,
252
+ output_dist_folder=static_dist_folder
253
+ )
254
+ create_folders_and_variables_if_not_exists.folders_creation()
255
+
256
+
257
  # important: the index() function and the app.mount MUST be at the end
258
  # samgis.html
259
+ app.mount("/samgis", StaticFiles(directory=static_dist_folder, html=True), name="samgis")
260
 
261
 
262
  @app.get("/samgis")
263
  async def samgis() -> FileResponse:
264
+ return FileResponse(path=static_dist_folder / "samgis.html", media_type="text/html")
265
 
266
 
267
  # lisa.html
268
+ app.mount("/lisa", StaticFiles(directory=static_dist_folder, html=True), name="lisa")
269
 
270
 
271
  @app.get("/lisa")
272
  async def lisa() -> FileResponse:
273
+ return FileResponse(path=static_dist_folder / "lisa.html", media_type="text/html")
274
 
275
 
276
+ # # index.html (lisa.html copy)
277
+ app.mount("/", StaticFiles(directory=static_dist_folder, html=True), name="index")
278
 
279
 
280
  @app.get("/")
281
  async def index() -> FileResponse:
282
+ return FileResponse(path=static_dist_folder / "index.html", media_type="text/html")
283
+
284
+
285
+ lisa.load_model_and_inference_fn(LISA_INFERENCE_FN)
286
+ inference_fn = models_dict[LISA_INFERENCE_FN]["inference"]
287
+
288
+
289
+ io = app_helpers.get_gradio_interface(inference_fn)
290
+ app_logger.info("mounting gradio app within FastAPI...")
291
 
292
 
293
  if __name__ == '__main__':
dockerfiles/dockerfile-lisa-predictions CHANGED
@@ -31,7 +31,7 @@ RUN python -c "import onnxruntime"
31
  RUN python -c "import rasterio"
32
  RUN python -c "import uvicorn"
33
  RUN df -h
34
- RUN ls -l ${LAMBDA_TASK_ROOT}/samgis_lisa_on_cuda/
35
  RUN ls -l ${LAMBDA_TASK_ROOT}/wrappers/
36
  RUN ls -l ${FASTAPI_STATIC}/
37
  RUN ls -l ${FASTAPI_STATIC}/dist
 
31
  RUN python -c "import rasterio"
32
  RUN python -c "import uvicorn"
33
  RUN df -h
34
+ RUN ls -l ${LAMBDA_TASK_ROOT}/samgis_lisa_on_zero/
35
  RUN ls -l ${LAMBDA_TASK_ROOT}/wrappers/
36
  RUN ls -l ${FASTAPI_STATIC}/
37
  RUN ls -l ${FASTAPI_STATIC}/dist
packages.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ npm
2
+ nodejs
poetry.lock CHANGED
The diff for this file is too large to render. See raw diff
 
pyproject.toml CHANGED
@@ -1,66 +1,38 @@
1
  [tool.poetry]
2
- name = "samgis-lisa-on-cuda"
3
- version = "1.3.3"
4
  description = "A VLM backend for machine learning instance segmentation on geospatial data that uses LISA (Reasoning Segmentation via Large Language Model)."
5
  authors = ["alessandro trinca tornidor <alessandro@trinca.tornidor.com>"]
6
  license = "MIT license"
7
  readme = "README.md"
8
 
9
  [metadata]
10
- name = "samgis-lisa-on-cuda"
11
- version = "1.3.3"
12
 
13
  [tool.poetry.dependencies]
14
  bson = "^0.5.10"
15
- contextily = "^1.5.2"
16
- geopandas = "^0.14.3"
17
  loguru = "^0.7.2"
18
  numpy = "1.25.2"
19
- onnxruntime = "1.16.3"
20
  opencv-python-headless = "^4.8.1.78"
21
- pillow = "^10.2.0"
22
  python = "~3.10"
23
  python-dotenv = "^1.0.1"
24
- rasterio = "^1.3.9"
25
- requests = "^2.31.0"
26
- samgis-core = "^1.1.2"
27
- lisa-on-cuda = "^1.1.1"
28
-
29
- [tool.poetry.group.aws_lambda]
30
- optional = true
31
-
32
- [tool.poetry.group.aws_lambda.dependencies]
33
- aws-lambda-powertools = "^2.30.2"
34
- awslambdaric = "^2.0.10"
35
- jmespath = "^1.0.1"
36
- pydantic = "^2.5.3"
37
-
38
- [tool.poetry.group.test]
39
- optional = true
40
-
41
- [tool.poetry.group.test.dependencies]
42
- pytest = "7.4.4"
43
- pytest-cov = "4.1.0"
44
- python-dotenv = "^1.0.1"
45
- httpx = "^0.26.0"
46
-
47
- [tool.poetry.group.docs]
48
- optional = true
49
-
50
- [tool.poetry.group.docs.dependencies]
51
- sphinx = "^7.2.6"
52
- sphinx-autodoc-typehints = "^1.25.2"
53
- sphinxcontrib-openapi = "^0.8.4"
54
- myst-parser = "^2.0.0"
55
 
56
  [tool.poetry.group.fastapi]
57
  optional = true
58
 
59
  [tool.poetry.group.fastapi.dependencies]
60
- fastapi = "^0.110.0"
61
  loguru = "^0.7.2"
62
- pydantic = "^2.6.3"
63
- uvicorn = "^0.28.0"
64
 
65
  [build-system]
66
  requires = ["poetry-core"]
 
1
  [tool.poetry]
2
+ name = "samgis-lisa-on-zero"
3
+ version = "1.4.0"
4
  description = "A VLM backend for machine learning instance segmentation on geospatial data that uses LISA (Reasoning Segmentation via Large Language Model)."
5
  authors = ["alessandro trinca tornidor <alessandro@trinca.tornidor.com>"]
6
  license = "MIT license"
7
  readme = "README.md"
8
 
9
  [metadata]
10
+ name = "samgis-lisa-on-zero"
11
+ version = "1.4.0"
12
 
13
  [tool.poetry.dependencies]
14
  bson = "^0.5.10"
15
+ contextily = "^1.6.0"
16
+ geopandas = "^1.0.1"
17
  loguru = "^0.7.2"
18
  numpy = "1.25.2"
 
19
  opencv-python-headless = "^4.8.1.78"
20
+ pillow = "^10.4.0"
21
  python = "~3.10"
22
  python-dotenv = "^1.0.1"
23
+ rasterio = "^1.3.10"
24
+ requests = "^2.32.3"
25
+ samgis-core = "^2.0.2"
26
+ lisa-on-cuda = "1.3.3"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
  [tool.poetry.group.fastapi]
29
  optional = true
30
 
31
  [tool.poetry.group.fastapi.dependencies]
32
+ fastapi = "^0.111.0"
33
  loguru = "^0.7.2"
34
+ pydantic = "^2.8.2"
35
+ uvicorn = "^0.30.1"
36
 
37
  [build-system]
38
  requires = ["poetry-core"]
requirements.txt ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ bson==0.5.10
2
+ contextily==1.6.0
3
+ fastapi==0.111.0
4
+ geopandas==1.0.1
5
+ lisa-on-cuda==1.3.3
6
+ loguru==0.7.2
7
+ numpy==1.25.2
8
+ opencv-python-headless==4.8.1.78
9
+ pillow==10.4.0
10
+ pydantic==2.8.2
11
+ python-dotenv==1.0.1
12
+ rasterio==1.3.10
13
+ requests==2.32.3
14
+ samgis-core==2.0.2
15
+ uvicorn==0.30.1
{samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/__init__.py RENAMED
@@ -1,10 +1,10 @@
1
  """Get machine learning predictions from geodata raster images"""
2
  import os
3
 
4
- # not used here but contextily_tile is imported in samgis_lisa_on_cuda.io.tms2geotiff
5
  from contextily import tile as contextily_tile
6
  from pathlib import Path
7
- from samgis_lisa_on_cuda.utilities.constants import SERVICE_NAME
8
 
9
  ROOT = Path(globals().get("__file__", "./_")).absolute().parent.parent
10
  PROJECT_ROOT_FOLDER = Path(os.getenv("PROJECT_ROOT_FOLDER", ROOT))
 
1
  """Get machine learning predictions from geodata raster images"""
2
  import os
3
 
4
+ # not used here but contextily_tile is imported in samgis_lisa_on_zero.io.tms2geotiff
5
  from contextily import tile as contextily_tile
6
  from pathlib import Path
7
+ from samgis_lisa_on_zero.utilities.constants import SERVICE_NAME
8
 
9
  ROOT = Path(globals().get("__file__", "./_")).absolute().parent.parent
10
  PROJECT_ROOT_FOLDER = Path(os.getenv("PROJECT_ROOT_FOLDER", ROOT))
{samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/__version__.py RENAMED
File without changes
{samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/io/__init__.py RENAMED
File without changes
{samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/io/coordinates_pixel_conversion.py RENAMED
@@ -1,10 +1,10 @@
1
  """functions useful to convert to/from latitude-longitude coordinates to pixel image coordinates"""
2
  from samgis_core.utilities.type_hints import TupleFloat, TupleFloatAny
3
 
4
- from samgis_lisa_on_cuda import app_logger
5
- from samgis_lisa_on_cuda.utilities.constants import TILE_SIZE, EARTH_EQUATORIAL_RADIUS
6
- from samgis_lisa_on_cuda.utilities.type_hints import ImagePixelCoordinates
7
- from samgis_lisa_on_cuda.utilities.type_hints import LatLngDict
8
 
9
 
10
  def _get_latlng2pixel_projection(latlng: LatLngDict) -> ImagePixelCoordinates:
 
1
  """functions useful to convert to/from latitude-longitude coordinates to pixel image coordinates"""
2
  from samgis_core.utilities.type_hints import TupleFloat, TupleFloatAny
3
 
4
+ from samgis_lisa_on_zero import app_logger
5
+ from samgis_lisa_on_zero.utilities.constants import TILE_SIZE, EARTH_EQUATORIAL_RADIUS
6
+ from samgis_lisa_on_zero.utilities.type_hints import ImagePixelCoordinates
7
+ from samgis_lisa_on_zero.utilities.type_hints import LatLngDict
8
 
9
 
10
  def _get_latlng2pixel_projection(latlng: LatLngDict) -> ImagePixelCoordinates:
{samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/io/geo_helpers.py RENAMED
@@ -3,7 +3,7 @@ from affine import Affine
3
  from numpy import ndarray as np_ndarray
4
 
5
  from samgis_core.utilities.type_hints import ListFloat, TupleFloat, DictStrInt
6
- from samgis_lisa_on_cuda import app_logger
7
 
8
 
9
  def load_affine_transformation_from_matrix(matrix_source_coefficients: ListFloat) -> Affine:
 
3
  from numpy import ndarray as np_ndarray
4
 
5
  from samgis_core.utilities.type_hints import ListFloat, TupleFloat, DictStrInt
6
+ from samgis_lisa_on_zero import app_logger
7
 
8
 
9
  def load_affine_transformation_from_matrix(matrix_source_coefficients: ListFloat) -> Affine:
{samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/io/raster_helpers.py RENAMED
@@ -3,10 +3,10 @@ import numpy as np
3
  from numpy import ndarray, bitwise_not
4
  from rasterio import open as rasterio_open
5
 
6
- from samgis_lisa_on_cuda import PROJECT_ROOT_FOLDER
7
- from samgis_lisa_on_cuda import app_logger
8
- from samgis_lisa_on_cuda.utilities.constants import OUTPUT_CRS_STRING
9
- from samgis_lisa_on_cuda.utilities.type_hints import XYZTerrainProvidersNames
10
 
11
 
12
  def get_nextzen_terrain_rgb_formula(red: ndarray, green: ndarray, blue: ndarray) -> ndarray:
@@ -83,7 +83,7 @@ def get_rgb_prediction_image(raster_cropped: ndarray, slope_cellsize: int, inver
83
  Returns:
84
  tuple of str: image filename, image path (with filename)
85
  """
86
- from samgis_lisa_on_cuda.utilities.constants import CHANNEL_EXAGGERATIONS_LIST
87
 
88
  try:
89
  slope, curvature = get_slope_curvature(raster_cropped, slope_cellsize=slope_cellsize)
 
3
  from numpy import ndarray, bitwise_not
4
  from rasterio import open as rasterio_open
5
 
6
+ from samgis_lisa_on_zero import PROJECT_ROOT_FOLDER
7
+ from samgis_lisa_on_zero import app_logger
8
+ from samgis_lisa_on_zero.utilities.constants import OUTPUT_CRS_STRING
9
+ from samgis_lisa_on_zero.utilities.type_hints import XYZTerrainProvidersNames
10
 
11
 
12
  def get_nextzen_terrain_rgb_formula(red: ndarray, green: ndarray, blue: ndarray) -> ndarray:
 
83
  Returns:
84
  tuple of str: image filename, image path (with filename)
85
  """
86
+ from samgis_lisa_on_zero.utilities.constants import CHANNEL_EXAGGERATIONS_LIST
87
 
88
  try:
89
  slope, curvature = get_slope_curvature(raster_cropped, slope_cellsize=slope_cellsize)
{samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/io/tms2geotiff.py RENAMED
@@ -4,10 +4,10 @@ from numpy import ndarray
4
  from samgis_core.utilities.type_hints import TupleFloat
5
  from xyzservices import TileProvider
6
 
7
- from samgis_lisa_on_cuda import app_logger
8
- from samgis_lisa_on_cuda.utilities.constants import (OUTPUT_CRS_STRING, DRIVER_RASTERIO_GTIFF, N_MAX_RETRIES, N_CONNECTION, N_WAIT,
9
- ZOOM_AUTO, BOOL_USE_CACHE)
10
- from samgis_lisa_on_cuda.utilities.type_hints import tuple_ndarray_transform
11
 
12
 
13
  bool_use_cache = int(os.getenv("BOOL_USE_CACHE", BOOL_USE_CACHE))
@@ -51,8 +51,8 @@ def download_extent(w: float, s: float, e: float, n: float, zoom: int or str = z
51
  parsed request input
52
  """
53
  try:
54
- from samgis_lisa_on_cuda import contextily_tile
55
- from samgis_lisa_on_cuda.io.coordinates_pixel_conversion import _from4326_to3857
56
 
57
  app_logger.info(f"connection number:{n_connections}, type:{type(n_connections)}.")
58
  app_logger.info(f"zoom:{zoom}, type:{type(zoom)}.")
 
4
  from samgis_core.utilities.type_hints import TupleFloat
5
  from xyzservices import TileProvider
6
 
7
+ from samgis_lisa_on_zero import app_logger
8
+ from samgis_lisa_on_zero.utilities.constants import (OUTPUT_CRS_STRING, DRIVER_RASTERIO_GTIFF, N_MAX_RETRIES, N_CONNECTION, N_WAIT,
9
+ ZOOM_AUTO, BOOL_USE_CACHE)
10
+ from samgis_lisa_on_zero.utilities.type_hints import tuple_ndarray_transform
11
 
12
 
13
  bool_use_cache = int(os.getenv("BOOL_USE_CACHE", BOOL_USE_CACHE))
 
51
  parsed request input
52
  """
53
  try:
54
+ from samgis_lisa_on_zero import contextily_tile
55
+ from samgis_lisa_on_zero.io.coordinates_pixel_conversion import _from4326_to3857
56
 
57
  app_logger.info(f"connection number:{n_connections}, type:{type(n_connections)}.")
58
  app_logger.info(f"zoom:{zoom}, type:{type(zoom)}.")
{samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/io/wrappers_helpers.py RENAMED
@@ -7,10 +7,10 @@ import loguru
7
  from xyzservices import providers, TileProvider
8
 
9
  from lisa_on_cuda.utils.app_helpers import get_cleaned_input
10
- from samgis_lisa_on_cuda import app_logger
11
- from samgis_lisa_on_cuda.io.coordinates_pixel_conversion import get_latlng_to_pixel_coordinates
12
- from samgis_lisa_on_cuda.utilities.constants import COMPLETE_URL_TILES_MAPBOX, COMPLETE_URL_TILES_NEXTZEN, CUSTOM_RESPONSE_MESSAGES
13
- from samgis_lisa_on_cuda.utilities.type_hints import ApiRequestBody, ContentTypes, XYZTerrainProvidersNames, \
14
  XYZDefaultProvidersNames, StringPromptApiRequestBody
15
  from samgis_core.utilities.utilities import base64_decode
16
 
 
7
  from xyzservices import providers, TileProvider
8
 
9
  from lisa_on_cuda.utils.app_helpers import get_cleaned_input
10
+ from samgis_lisa_on_zero import app_logger
11
+ from samgis_lisa_on_zero.io.coordinates_pixel_conversion import get_latlng_to_pixel_coordinates
12
+ from samgis_lisa_on_zero.utilities.constants import COMPLETE_URL_TILES_MAPBOX, COMPLETE_URL_TILES_NEXTZEN, CUSTOM_RESPONSE_MESSAGES
13
+ from samgis_lisa_on_zero.utilities.type_hints import ApiRequestBody, ContentTypes, XYZTerrainProvidersNames, \
14
  XYZDefaultProvidersNames, StringPromptApiRequestBody
15
  from samgis_core.utilities.utilities import base64_decode
16
 
{samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/prediction_api/__init__.py RENAMED
File without changes
{samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/prediction_api/global_models.py RENAMED
@@ -3,4 +3,4 @@ models_dict = {
3
  "lisa": {"inference": None}
4
  }
5
  embedding_dict = {}
6
-
 
3
  "lisa": {"inference": None}
4
  }
5
  embedding_dict = {}
6
+ inference_fn_dict = {}
{samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/prediction_api/lisa.py RENAMED
@@ -1,22 +1,36 @@
1
  from datetime import datetime
 
2
 
3
- from lisa_on_cuda.utils import app_helpers
4
  from samgis_core.utilities.type_hints import LlistFloat, DictStrInt
5
- from samgis_lisa_on_cuda import app_logger
6
- from samgis_lisa_on_cuda.io.geo_helpers import get_vectorized_raster_as_geojson
7
- from samgis_lisa_on_cuda.io.raster_helpers import write_raster_png, write_raster_tiff
8
- from samgis_lisa_on_cuda.io.tms2geotiff import download_extent
9
- from samgis_lisa_on_cuda.prediction_api.global_models import models_dict
10
- from samgis_lisa_on_cuda.utilities.constants import DEFAULT_URL_TILES
11
 
12
  msg_write_tmp_on_disk = "found option to write images and geojson output..."
13
 
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  def lisa_predict(
16
  bbox: LlistFloat,
17
  prompt: str,
18
  zoom: float,
19
- inference_function_name_key: str = "lisa",
20
  source: str = DEFAULT_URL_TILES,
21
  source_name: str = None
22
  ) -> DictStrInt:
@@ -40,13 +54,11 @@ def lisa_predict(
40
  Affine transform
41
  """
42
  from os import getenv
 
 
43
 
44
  app_logger.info("start lisa inference...")
45
- if models_dict[inference_function_name_key]["inference"] is None:
46
- app_logger.info(f"missing inference function {inference_function_name_key}, instantiating it now!")
47
- parsed_args = app_helpers.parse_args([])
48
- inference_fn = app_helpers.get_inference_model_by_args(parsed_args)
49
- models_dict[inference_function_name_key]["inference"] = inference_fn
50
  app_logger.debug(f"using a {inference_function_name_key} instance model...")
51
  inference_fn = models_dict[inference_function_name_key]["inference"]
52
 
 
1
  from datetime import datetime
2
+ from spaces import GPU as SPACES_GPU
3
 
 
4
  from samgis_core.utilities.type_hints import LlistFloat, DictStrInt
5
+ from samgis_lisa_on_zero.io.geo_helpers import get_vectorized_raster_as_geojson
6
+ from samgis_lisa_on_zero.io.raster_helpers import write_raster_png, write_raster_tiff
7
+ from samgis_lisa_on_zero.io.tms2geotiff import download_extent
8
+ from samgis_lisa_on_zero.utilities.constants import DEFAULT_URL_TILES, LISA_INFERENCE_FN
 
 
9
 
10
  msg_write_tmp_on_disk = "found option to write images and geojson output..."
11
 
12
 
13
+ def load_model_and_inference_fn(inference_function_name_key):
14
+ from samgis_lisa_on_zero import app_logger
15
+ from lisa_on_cuda.utils import app_helpers
16
+ from samgis_lisa_on_zero.prediction_api.global_models import models_dict
17
+
18
+ if models_dict[inference_function_name_key]["inference"] is None:
19
+ app_logger.info(f"missing inference function {inference_function_name_key}, instantiating it now!")
20
+ parsed_args = app_helpers.parse_args([])
21
+ inference_fn = app_helpers.get_inference_model_by_args(
22
+ parsed_args,
23
+ internal_logg=app_logger,
24
+ inference_decorator=SPACES_GPU
25
+ )
26
+ models_dict[inference_function_name_key]["inference"] = inference_fn
27
+
28
+
29
  def lisa_predict(
30
  bbox: LlistFloat,
31
  prompt: str,
32
  zoom: float,
33
+ inference_function_name_key: str = LISA_INFERENCE_FN,
34
  source: str = DEFAULT_URL_TILES,
35
  source_name: str = None
36
  ) -> DictStrInt:
 
54
  Affine transform
55
  """
56
  from os import getenv
57
+ from samgis_lisa_on_zero import app_logger
58
+ from samgis_lisa_on_zero.prediction_api.global_models import models_dict
59
 
60
  app_logger.info("start lisa inference...")
61
+ load_model_and_inference_fn(inference_function_name_key)
 
 
 
 
62
  app_logger.debug(f"using a {inference_function_name_key} instance model...")
63
  inference_fn = models_dict[inference_function_name_key]["inference"]
64
 
{samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/prediction_api/predictors.py RENAMED
@@ -1,11 +1,11 @@
1
  """functions using machine learning instance model(s)"""
2
- from samgis_lisa_on_cuda import app_logger, MODEL_FOLDER
3
- from samgis_lisa_on_cuda.io.geo_helpers import get_vectorized_raster_as_geojson
4
- from samgis_lisa_on_cuda.io.raster_helpers import get_raster_terrain_rgb_like, get_rgb_prediction_image
5
- from samgis_lisa_on_cuda.io.tms2geotiff import download_extent
6
- from samgis_lisa_on_cuda.io.wrappers_helpers import check_source_type_is_terrain
7
- from samgis_lisa_on_cuda.prediction_api.global_models import models_dict, embedding_dict
8
- from samgis_lisa_on_cuda.utilities.constants import DEFAULT_URL_TILES, SLOPE_CELLSIZE
9
  from samgis_core.prediction_api.sam_onnx import SegmentAnythingONNX, get_raster_inference_with_embedding_from_dict
10
  from samgis_core.utilities.constants import MODEL_ENCODER_NAME, MODEL_DECODER_NAME, DEFAULT_INPUT_SHAPE
11
  from samgis_core.utilities.type_hints import LlistFloat, DictStrInt, ListDict
 
1
  """functions using machine learning instance model(s)"""
2
+ from samgis_lisa_on_zero import app_logger, MODEL_FOLDER
3
+ from samgis_lisa_on_zero.io.geo_helpers import get_vectorized_raster_as_geojson
4
+ from samgis_lisa_on_zero.io.raster_helpers import get_raster_terrain_rgb_like, get_rgb_prediction_image
5
+ from samgis_lisa_on_zero.io.tms2geotiff import download_extent
6
+ from samgis_lisa_on_zero.io.wrappers_helpers import check_source_type_is_terrain
7
+ from samgis_lisa_on_zero.prediction_api.global_models import models_dict, embedding_dict
8
+ from samgis_lisa_on_zero.utilities.constants import DEFAULT_URL_TILES, SLOPE_CELLSIZE
9
  from samgis_core.prediction_api.sam_onnx import SegmentAnythingONNX, get_raster_inference_with_embedding_from_dict
10
  from samgis_core.utilities.constants import MODEL_ENCODER_NAME, MODEL_DECODER_NAME, DEFAULT_INPUT_SHAPE
11
  from samgis_core.utilities.type_hints import LlistFloat, DictStrInt, ListDict
{samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/utilities/__init__.py RENAMED
File without changes
{samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/utilities/constants.py RENAMED
@@ -37,3 +37,4 @@ RELATIVE_URL_TILES_NEXTZEN = "elevation-tiles-prod/terrarium/{z}/{x}/{y}.png" #
37
  COMPLETE_URL_TILES_NEXTZEN = f"https://{DOMAIN_URL_TILES_NEXTZEN}/{RELATIVE_URL_TILES_NEXTZEN}"
38
  CHANNEL_EXAGGERATIONS_LIST = [2.5, 1.1, 2.0]
39
  SLOPE_CELLSIZE = 61
 
 
37
  COMPLETE_URL_TILES_NEXTZEN = f"https://{DOMAIN_URL_TILES_NEXTZEN}/{RELATIVE_URL_TILES_NEXTZEN}"
38
  CHANNEL_EXAGGERATIONS_LIST = [2.5, 1.1, 2.0]
39
  SLOPE_CELLSIZE = 61
40
+ LISA_INFERENCE_FN = "lisa"
{samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/utilities/session_logger.py RENAMED
File without changes
{samgis_lisa_on_cuda β†’ samgis_lisa_on_zero}/utilities/type_hints.py RENAMED
File without changes
scripts/extract-openapi-fastapi.py CHANGED
@@ -7,7 +7,7 @@ import sys
7
  import yaml
8
  from uvicorn.importer import import_from_string
9
 
10
- from samgis_lisa_on_cuda import PROJECT_ROOT_FOLDER
11
 
12
  parser = argparse.ArgumentParser(prog="extract-openapi-fastapi.py")
13
  parser.add_argument("app", help='App import string. Eg. "main:app"', default="main:app")
 
7
  import yaml
8
  from uvicorn.importer import import_from_string
9
 
10
+ from samgis_lisa_on_zero import PROJECT_ROOT_FOLDER
11
 
12
  parser = argparse.ArgumentParser(prog="extract-openapi-fastapi.py")
13
  parser.add_argument("app", help='App import string. Eg. "main:app"', default="main:app")
scripts/extract-openapi-lambda.py CHANGED
@@ -1,9 +1,9 @@
1
  import json
2
 
3
- from samgis_lisa_on_cuda import PROJECT_ROOT_FOLDER
4
 
5
  if __name__ == '__main__':
6
- from samgis_lisa_on_cuda.utilities.type_hints import ApiRequestBody, ApiResponseBodyFailure, ApiResponseBodySuccess
7
 
8
  with open(PROJECT_ROOT_FOLDER / "docs" / "specs" / "openapi_lambda_wip.json", "w") as output_json:
9
  json.dump({
 
1
  import json
2
 
3
+ from samgis_lisa_on_zero import PROJECT_ROOT_FOLDER
4
 
5
  if __name__ == '__main__':
6
+ from samgis_lisa_on_zero.utilities.type_hints import ApiRequestBody, ApiResponseBodyFailure, ApiResponseBodySuccess
7
 
8
  with open(PROJECT_ROOT_FOLDER / "docs" / "specs" / "openapi_lambda_wip.json", "w") as output_json:
9
  json.dump({
static/vite.config.ts CHANGED
@@ -1,26 +1,29 @@
1
- import { fileURLToPath, URL } from 'node:url'
2
- import { resolve } from 'node:path'
3
-
4
- import { defineConfig } from 'vite'
5
  import vue from '@vitejs/plugin-vue'
6
 
7
  // https://vitejs.dev/config/
8
- export default defineConfig({
9
- plugins: [
10
- vue(),
11
- ],
12
- resolve: {
13
- alias: {
14
- '@': fileURLToPath(new URL('./src', import.meta.url))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  }
16
- },
17
- build: {
18
- rollupOptions: {
19
- input: {
20
- samgis: resolve(__dirname, 'samgis.html'),
21
- lisa: resolve(__dirname, 'lisa.html'),
22
- index: resolve(__dirname, "index.html"),
23
- },
24
- },
25
- },
26
  })
 
1
+ import {fileURLToPath, URL} from 'node:url'
2
+ import {resolve} from 'node:path'
3
+ import {defineConfig, loadEnv} from 'vite'
 
4
  import vue from '@vitejs/plugin-vue'
5
 
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,
14
+ resolve: {
15
+ alias: {
16
+ '@': fileURLToPath(new URL('./src', import.meta.url))
17
+ }
18
+ },
19
+ build: {
20
+ rollupOptions: {
21
+ input: {
22
+ samgis: resolve(__dirname, 'samgis.html'),
23
+ lisa: resolve(__dirname, 'lisa.html'),
24
+ index: resolve(__dirname, "index.html"),
25
+ },
26
+ },
27
+ }
28
  }
 
 
 
 
 
 
 
 
 
 
29
  })
tests/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- from samgis_lisa_on_cuda import PROJECT_ROOT_FOLDER
2
 
3
 
4
  TEST_ROOT_FOLDER = PROJECT_ROOT_FOLDER / "tests"
 
1
+ from samgis_lisa_on_zero import PROJECT_ROOT_FOLDER
2
 
3
 
4
  TEST_ROOT_FOLDER = PROJECT_ROOT_FOLDER / "tests"
tests/io/test_coordinates_pixel_conversion.py CHANGED
@@ -1,7 +1,7 @@
1
  import json
2
 
3
- from samgis_lisa_on_cuda.io.coordinates_pixel_conversion import get_latlng_to_pixel_coordinates
4
- from samgis_lisa_on_cuda.utilities.type_hints import LatLngDict
5
  from tests import TEST_EVENTS_FOLDER
6
 
7
 
 
1
  import json
2
 
3
+ from samgis_lisa_on_zero.io.coordinates_pixel_conversion import get_latlng_to_pixel_coordinates
4
+ from samgis_lisa_on_zero.utilities.type_hints import LatLngDict
5
  from tests import TEST_EVENTS_FOLDER
6
 
7
 
tests/io/test_geo_helpers.py CHANGED
@@ -3,7 +3,7 @@ import unittest
3
  import numpy as np
4
  import shapely
5
 
6
- from samgis_lisa_on_cuda.io.geo_helpers import load_affine_transformation_from_matrix
7
  from tests import TEST_EVENTS_FOLDER
8
 
9
 
@@ -63,7 +63,7 @@ class TestGeoHelpers(unittest.TestCase):
63
 
64
  def test_get_vectorized_raster_as_geojson_ok(self):
65
  from rasterio.transform import Affine
66
- from samgis_lisa_on_cuda.io.geo_helpers import get_vectorized_raster_as_geojson
67
 
68
  name_fn = "samexporter_predict"
69
 
@@ -81,7 +81,7 @@ class TestGeoHelpers(unittest.TestCase):
81
  assert shapely.equals_exact(output_geojson, expected_output_geojson, tolerance=0.000006)
82
 
83
  def test_get_vectorized_raster_as_geojson_fail(self):
84
- from samgis_lisa_on_cuda.io.geo_helpers import get_vectorized_raster_as_geojson
85
 
86
  name_fn = "samexporter_predict"
87
 
 
3
  import numpy as np
4
  import shapely
5
 
6
+ from samgis_lisa_on_zero.io.geo_helpers import load_affine_transformation_from_matrix
7
  from tests import TEST_EVENTS_FOLDER
8
 
9
 
 
63
 
64
  def test_get_vectorized_raster_as_geojson_ok(self):
65
  from rasterio.transform import Affine
66
+ from samgis_lisa_on_zero.io.geo_helpers import get_vectorized_raster_as_geojson
67
 
68
  name_fn = "samexporter_predict"
69
 
 
81
  assert shapely.equals_exact(output_geojson, expected_output_geojson, tolerance=0.000006)
82
 
83
  def test_get_vectorized_raster_as_geojson_fail(self):
84
+ from samgis_lisa_on_zero.io.geo_helpers import get_vectorized_raster_as_geojson
85
 
86
  name_fn = "samexporter_predict"
87
 
tests/io/test_raster_helpers.py CHANGED
@@ -3,7 +3,7 @@ from unittest.mock import patch
3
  import numpy as np
4
 
5
  from samgis_core.utilities.utilities import hash_calculate
6
- from samgis_lisa_on_cuda.io import raster_helpers
7
 
8
 
9
  def get_three_channels(size=5, param1=1000, param2=3, param3=-88):
@@ -101,7 +101,7 @@ class Test(unittest.TestCase):
101
  assert hash_slope == b'IYf6x4G0lmR47j6HRS5kUYWdtmimhLz2nak8py75nwc='
102
 
103
  def test_get_slope_curvature_value_error(self):
104
- from samgis_lisa_on_cuda.io import raster_helpers
105
 
106
  with self.assertRaises(ValueError):
107
  try:
@@ -242,7 +242,7 @@ class Test(unittest.TestCase):
242
  assert hash_output == b'RU7CcoKoR3Fkh5LE+m48DHRVUy/vGq6UgfOFUMXx07M='
243
 
244
  def test_get_raster_terrain_rgb_like(self):
245
- from samgis_lisa_on_cuda.utilities.type_hints import XYZTerrainProvidersNames
246
 
247
  arr_input = raster_helpers.get_rgb_image(channel0, channel1, channel2, invert_image=True)
248
  output_nextzen = raster_helpers.get_raster_terrain_rgb_like(
 
3
  import numpy as np
4
 
5
  from samgis_core.utilities.utilities import hash_calculate
6
+ from samgis_lisa_on_zero.io import raster_helpers
7
 
8
 
9
  def get_three_channels(size=5, param1=1000, param2=3, param3=-88):
 
101
  assert hash_slope == b'IYf6x4G0lmR47j6HRS5kUYWdtmimhLz2nak8py75nwc='
102
 
103
  def test_get_slope_curvature_value_error(self):
104
+ from samgis_lisa_on_zero.io import raster_helpers
105
 
106
  with self.assertRaises(ValueError):
107
  try:
 
242
  assert hash_output == b'RU7CcoKoR3Fkh5LE+m48DHRVUy/vGq6UgfOFUMXx07M='
243
 
244
  def test_get_raster_terrain_rgb_like(self):
245
+ from samgis_lisa_on_zero.utilities.type_hints import XYZTerrainProvidersNames
246
 
247
  arr_input = raster_helpers.get_rgb_image(channel0, channel1, channel2, invert_image=True)
248
  output_nextzen = raster_helpers.get_raster_terrain_rgb_like(
tests/io/test_tms2geotiff.py CHANGED
@@ -3,8 +3,8 @@ import unittest
3
  import numpy as np
4
  from samgis_core.utilities.utilities import hash_calculate
5
 
6
- from samgis_lisa_on_cuda import app_logger
7
- from samgis_lisa_on_cuda.io.tms2geotiff import download_extent
8
  from tests import LOCAL_URL_TILE, TEST_EVENTS_FOLDER
9
 
10
 
 
3
  import numpy as np
4
  from samgis_core.utilities.utilities import hash_calculate
5
 
6
+ from samgis_lisa_on_zero import app_logger
7
+ from samgis_lisa_on_zero.io.tms2geotiff import download_extent
8
  from tests import LOCAL_URL_TILE, TEST_EVENTS_FOLDER
9
 
10
 
tests/io/test_wrappers_helpers.py CHANGED
@@ -5,9 +5,9 @@ import unittest
5
  from http import HTTPStatus
6
  from unittest.mock import patch
7
 
8
- from samgis_lisa_on_cuda.io import wrappers_helpers
9
- from samgis_lisa_on_cuda.io.wrappers_helpers import get_parsed_bbox_points_with_dictlist_prompt, get_parsed_request_body, get_response
10
- from samgis_lisa_on_cuda.utilities.type_hints import ApiRequestBody
11
  from tests import TEST_EVENTS_FOLDER
12
 
13
 
@@ -95,7 +95,7 @@ class WrappersHelpersTest(unittest.TestCase):
95
  @patch.object(wrappers_helpers, "providers")
96
  def test_get_url_tile(self, providers_mocked):
97
  import xyzservices
98
- from samgis_lisa_on_cuda.io.wrappers_helpers import get_url_tile
99
 
100
  from tests import LOCAL_URL_TILE
101
 
@@ -115,7 +115,7 @@ class WrappersHelpersTest(unittest.TestCase):
115
 
116
  @staticmethod
117
  def test_get_url_tile_real():
118
- from samgis_lisa_on_cuda.io.wrappers_helpers import get_url_tile
119
 
120
  assert get_url_tile("OpenStreetMap") == {
121
  'url': 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', 'max_zoom': 19,
 
5
  from http import HTTPStatus
6
  from unittest.mock import patch
7
 
8
+ from samgis_lisa_on_zero.io import wrappers_helpers
9
+ from samgis_lisa_on_zero.io.wrappers_helpers import get_parsed_bbox_points_with_dictlist_prompt, get_parsed_request_body, get_response
10
+ from samgis_lisa_on_zero.utilities.type_hints import ApiRequestBody
11
  from tests import TEST_EVENTS_FOLDER
12
 
13
 
 
95
  @patch.object(wrappers_helpers, "providers")
96
  def test_get_url_tile(self, providers_mocked):
97
  import xyzservices
98
+ from samgis_lisa_on_zero.io.wrappers_helpers import get_url_tile
99
 
100
  from tests import LOCAL_URL_TILE
101
 
 
115
 
116
  @staticmethod
117
  def test_get_url_tile_real():
118
+ from samgis_lisa_on_zero.io.wrappers_helpers import get_url_tile
119
 
120
  assert get_url_tile("OpenStreetMap") == {
121
  'url': 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', 'max_zoom': 19,
tests/prediction_api/test_predictors.py CHANGED
@@ -3,8 +3,8 @@ from unittest.mock import patch
3
 
4
  import numpy as np
5
 
6
- from samgis_lisa_on_cuda.prediction_api import predictors
7
- from samgis_lisa_on_cuda.prediction_api.predictors import get_raster_inference, samexporter_predict
8
  from tests import TEST_EVENTS_FOLDER
9
 
10
 
 
3
 
4
  import numpy as np
5
 
6
+ from samgis_lisa_on_zero.prediction_api import predictors
7
+ from samgis_lisa_on_zero.prediction_api.predictors import get_raster_inference, samexporter_predict
8
  from tests import TEST_EVENTS_FOLDER
9
 
10
 
tests/test_fastapi_app.py CHANGED
@@ -5,12 +5,12 @@ from unittest.mock import patch
5
 
6
  from fastapi.testclient import TestClient
7
 
8
- from samgis_lisa_on_cuda import PROJECT_ROOT_FOLDER
9
- from samgis_lisa_on_cuda.io import wrappers_helpers
10
  from tests import TEST_EVENTS_FOLDER
11
  from tests.local_tiles_http_server import LocalTilesHttpServer
12
- from wrappers import fastapi_wrapper
13
- from wrappers.fastapi_wrapper import app
14
 
15
 
16
  infer_samgis = "/infer_samgis"
 
5
 
6
  from fastapi.testclient import TestClient
7
 
8
+ from samgis_lisa_on_zero import PROJECT_ROOT_FOLDER
9
+ from samgis_lisa_on_zero.io import wrappers_helpers
10
  from tests import TEST_EVENTS_FOLDER
11
  from tests.local_tiles_http_server import LocalTilesHttpServer
12
+ import app
13
+ from app import app
14
 
15
 
16
  infer_samgis = "/infer_samgis"
tests/test_lambda_app.py CHANGED
@@ -3,13 +3,13 @@ import time
3
  import unittest
4
  from unittest.mock import patch
5
 
6
- from samgis_lisa_on_cuda import IS_AWS_LAMBDA
7
 
8
  if IS_AWS_LAMBDA:
9
  try:
10
  from awslambdaric.lambda_context import LambdaContext
11
 
12
- from samgis_lisa_on_cuda.io import wrappers_helpers
13
  from wrappers import lambda_wrapper
14
  from tests.local_tiles_http_server import LocalTilesHttpServer
15
 
 
3
  import unittest
4
  from unittest.mock import patch
5
 
6
+ from samgis_lisa_on_zero import IS_AWS_LAMBDA
7
 
8
  if IS_AWS_LAMBDA:
9
  try:
10
  from awslambdaric.lambda_context import LambdaContext
11
 
12
+ from samgis_lisa_on_zero.io import wrappers_helpers
13
  from wrappers import lambda_wrapper
14
  from tests.local_tiles_http_server import LocalTilesHttpServer
15
 
wrappers/__init__.py DELETED
File without changes
wrappers/lambda_wrapper.py DELETED
@@ -1,58 +0,0 @@
1
- """Lambda entry point"""
2
- from http import HTTPStatus
3
- from typing import Dict
4
-
5
- from aws_lambda_powertools.utilities.typing import LambdaContext
6
- from pydantic import ValidationError
7
-
8
- from samgis_lisa_on_cuda import app_logger
9
- from samgis_lisa_on_cuda.io.wrappers_helpers import get_parsed_request_body, get_parsed_bbox_points_with_dictlist_prompt, get_response
10
- from samgis_lisa_on_cuda.prediction_api.predictors import samexporter_predict
11
-
12
-
13
- def lambda_handler(event: Dict, context: LambdaContext) -> str:
14
- """
15
- Handle the request for the serverless backend and return the response
16
- (success or a type of error based on the exception raised).
17
-
18
- Args:
19
- event: request content
20
- context: request context
21
-
22
- Returns:
23
- json response from get_response() function
24
-
25
- """
26
- from time import time
27
- app_logger.info(f"start with aws_request_id:{context.aws_request_id}.")
28
- start_time = time()
29
-
30
- if "version" in event:
31
- app_logger.info(f"event version: {event['version']}.")
32
-
33
- try:
34
- app_logger.info("try get_parsed_event...")
35
- request_input = get_parsed_request_body(event)
36
- app_logger.info("event parsed: ok")
37
- body_request = get_parsed_bbox_points_with_dictlist_prompt(request_input)
38
- app_logger.info(f"body_request => {type(body_request)}, {body_request}.")
39
-
40
- try:
41
- body_response = samexporter_predict(
42
- body_request["bbox"], body_request["prompt"], body_request["zoom"], source=body_request["source"]
43
- )
44
- app_logger.info(f"output body_response length:{len(body_response)}.")
45
- app_logger.debug(f"output body_response:{body_response}.")
46
- response = get_response(HTTPStatus.OK.value, start_time, context.aws_request_id, body_response)
47
- except Exception as ex2:
48
- app_logger.exception(f"exception2:{ex2}.", exc_info=True)
49
- response = get_response(HTTPStatus.INTERNAL_SERVER_ERROR.value, start_time, context.aws_request_id, {})
50
- except ValidationError as va1:
51
- app_logger.exception(f"ValidationError:{va1}.", exc_info=True)
52
- response = get_response(HTTPStatus.UNPROCESSABLE_ENTITY.value, start_time, context.aws_request_id, {})
53
- except Exception as ex1:
54
- app_logger.exception(f"exception1:{ex1}.", exc_info=True)
55
- response = get_response(HTTPStatus.BAD_REQUEST.value, start_time, context.aws_request_id, {})
56
-
57
- app_logger.debug(f"response_dumped:{response}...")
58
- return response