Spaces:
Sleeping
Sleeping
merge master into main
Browse files- .gitignore +97 -0
- Dockerfile +22 -0
- README.md +34 -1
- app_gradio_fastapi/__init__.py +0 -0
- app_gradio_fastapi/helpers/__init__.py +0 -0
- app_gradio_fastapi/helpers/formatters.py +30 -0
- app_gradio_fastapi/helpers/session_logger.py +36 -0
- app_gradio_fastapi/main.py +23 -0
- app_gradio_fastapi/routes.py +20 -0
- requirements.txt +2 -0
- scripts/entrypoint.sh +24 -0
.gitignore
ADDED
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
venv
|
2 |
+
__pycache__
|
3 |
+
*.pyc
|
4 |
+
flagged/*
|
5 |
+
|
6 |
+
# Created by https://www.toptal.com/developers/gitignore/api/pycharm+all
|
7 |
+
# Edit at https://www.toptal.com/developers/gitignore?templates=pycharm+all
|
8 |
+
|
9 |
+
### PyCharm+all ###
|
10 |
+
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
11 |
+
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
12 |
+
|
13 |
+
# User-specific stuff
|
14 |
+
.idea/**/workspace.xml
|
15 |
+
.idea/**/tasks.xml
|
16 |
+
.idea/**/usage.statistics.xml
|
17 |
+
.idea/**/dictionaries
|
18 |
+
.idea/**/shelf
|
19 |
+
|
20 |
+
# AWS User-specific
|
21 |
+
.idea/**/aws.xml
|
22 |
+
|
23 |
+
# Generated files
|
24 |
+
.idea/**/contentModel.xml
|
25 |
+
|
26 |
+
# Sensitive or high-churn files
|
27 |
+
.idea/**/dataSources/
|
28 |
+
.idea/**/dataSources.ids
|
29 |
+
.idea/**/dataSources.local.xml
|
30 |
+
.idea/**/sqlDataSources.xml
|
31 |
+
.idea/**/dynamic.xml
|
32 |
+
.idea/**/uiDesigner.xml
|
33 |
+
.idea/**/dbnavigator.xml
|
34 |
+
|
35 |
+
# Gradle
|
36 |
+
.idea/**/gradle.xml
|
37 |
+
.idea/**/libraries
|
38 |
+
|
39 |
+
# Gradle and Maven with auto-import
|
40 |
+
# When using Gradle or Maven with auto-import, you should exclude module files,
|
41 |
+
# since they will be recreated, and may cause churn. Uncomment if using
|
42 |
+
# auto-import.
|
43 |
+
# .idea/artifacts
|
44 |
+
# .idea/compiler.xml
|
45 |
+
# .idea/jarRepositories.xml
|
46 |
+
# .idea/modules.xml
|
47 |
+
# .idea/*.iml
|
48 |
+
# .idea/modules
|
49 |
+
# *.iml
|
50 |
+
# *.ipr
|
51 |
+
|
52 |
+
# CMake
|
53 |
+
cmake-build-*/
|
54 |
+
|
55 |
+
# Mongo Explorer plugin
|
56 |
+
.idea/**/mongoSettings.xml
|
57 |
+
|
58 |
+
# File-based project format
|
59 |
+
*.iws
|
60 |
+
|
61 |
+
# IntelliJ
|
62 |
+
out/
|
63 |
+
|
64 |
+
# mpeltonen/sbt-idea plugin
|
65 |
+
.idea_modules/
|
66 |
+
|
67 |
+
# JIRA plugin
|
68 |
+
atlassian-ide-plugin.xml
|
69 |
+
|
70 |
+
# Cursive Clojure plugin
|
71 |
+
.idea/replstate.xml
|
72 |
+
|
73 |
+
# SonarLint plugin
|
74 |
+
.idea/sonarlint/
|
75 |
+
|
76 |
+
# Crashlytics plugin (for Android Studio and IntelliJ)
|
77 |
+
com_crashlytics_export_strings.xml
|
78 |
+
crashlytics.properties
|
79 |
+
crashlytics-build.properties
|
80 |
+
fabric.properties
|
81 |
+
|
82 |
+
# Editor-based Rest Client
|
83 |
+
.idea/httpRequests
|
84 |
+
|
85 |
+
# Android studio 3.1+ serialized cache file
|
86 |
+
.idea/caches/build_file_checksums.ser
|
87 |
+
|
88 |
+
### PyCharm+all Patch ###
|
89 |
+
# Ignore everything but code style settings and run configurations
|
90 |
+
# that are supposed to be shared within teams.
|
91 |
+
|
92 |
+
.idea/*
|
93 |
+
|
94 |
+
!.idea/codeStyles
|
95 |
+
!.idea/runConfigurations
|
96 |
+
|
97 |
+
# End of https://www.toptal.com/developers/gitignore/api/pycharm+all
|
Dockerfile
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
FROM python:3.11-bookworm AS builder_global
|
2 |
+
|
3 |
+
ARG PACKAGE_NAME="app_gradio_fastapi"
|
4 |
+
ARG ROOT_DIR="/code"
|
5 |
+
WORKDIR ${ROOT_DIR}
|
6 |
+
RUN chmod 770 -R ${ROOT_DIR}/
|
7 |
+
|
8 |
+
COPY ./requirements.txt ${ROOT_DIR}/requirements.txt
|
9 |
+
|
10 |
+
RUN pip install pip --upgrade
|
11 |
+
RUN python -m venv venv
|
12 |
+
RUN . ${ROOT_DIR}/venv/bin/activate && pip install --no-cache-dir -r ${ROOT_DIR}/requirements.txt
|
13 |
+
|
14 |
+
COPY ./scripts ${ROOT_DIR}/scripts
|
15 |
+
COPY ./${PACKAGE_NAME} ${ROOT_DIR}/${PACKAGE_NAME}
|
16 |
+
|
17 |
+
RUN chmod +x ${ROOT_DIR}/scripts/entrypoint.sh
|
18 |
+
|
19 |
+
EXPOSE 7860
|
20 |
+
|
21 |
+
CMD ["/code/scripts/entrypoint.sh"]
|
22 |
+
# CMD ["uvicorn", "wrappers.main:app", "--host", "0.0.0.0", "--port", "7860"]
|
README.md
CHANGED
@@ -8,4 +8,37 @@ pinned: false
|
|
8 |
license: mit
|
9 |
---
|
10 |
|
11 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
license: mit
|
9 |
---
|
10 |
|
11 |
+
# Gradio plus FastAPI with UUID logging sessions
|
12 |
+
## Run the app in a virtual environment
|
13 |
+
|
14 |
+
1. create and activate a virtual environment
|
15 |
+
2. install the dependencies
|
16 |
+
3. execute the uvicorn webserver
|
17 |
+
|
18 |
+
```bash
|
19 |
+
# create and activate a virtual environment
|
20 |
+
python3 -m venv venv
|
21 |
+
source venv/bin/activate
|
22 |
+
# install the project dependencies
|
23 |
+
python -m pip install pip --upgrade
|
24 |
+
python -m pip install -r requirements.txt
|
25 |
+
# execute the uvicorn webserver
|
26 |
+
uvicorn app_gradio_fastapi.main:app --host 0.0.0.0 --port 7860 --reload
|
27 |
+
```
|
28 |
+
|
29 |
+
## Run the app within a docker container
|
30 |
+
|
31 |
+
Build the docker image and run the container:
|
32 |
+
|
33 |
+
```bash
|
34 |
+
docker build . --tag app_gradio_fastapi --progress=plain
|
35 |
+
docker run -d --name app_gradio_fastapi -p 7860:7860 app_gradio_fastapi; docker logs -f app_gradio_fastapi
|
36 |
+
```
|
37 |
+
|
38 |
+
To stop all the container and remove all the docker images:
|
39 |
+
|
40 |
+
|
41 |
+
```bash
|
42 |
+
docker stop $(docker ps -a -q); docker rm $(docker ps -a -q)
|
43 |
+
docker rmi $(docker images -q) -f
|
44 |
+
```
|
app_gradio_fastapi/__init__.py
ADDED
File without changes
|
app_gradio_fastapi/helpers/__init__.py
ADDED
File without changes
|
app_gradio_fastapi/helpers/formatters.py
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import logging
|
2 |
+
from fastapi import HTTPException
|
3 |
+
|
4 |
+
from app_gradio_fastapi.helpers import session_logger
|
5 |
+
|
6 |
+
|
7 |
+
def divide(a: int, b: int) -> float:
|
8 |
+
logging.info(f"a:{a}, b:{b}.")
|
9 |
+
result = a / b
|
10 |
+
logging.info(f"result:{result}.")
|
11 |
+
return result
|
12 |
+
|
13 |
+
|
14 |
+
@session_logger.set_uuid_logging
|
15 |
+
def request_formatter(text: str) -> dict:
|
16 |
+
logging.info("start request...")
|
17 |
+
try:
|
18 |
+
logging.info(f"input text we need to treat as an integer: {text}.")
|
19 |
+
b = int(text)
|
20 |
+
transformed_text = f"input after integer cast: {b}."
|
21 |
+
try:
|
22 |
+
result_division = divide(100, b)
|
23 |
+
logging.info(f"some_function, result_division:{result_division}.")
|
24 |
+
return {"text": transformed_text, "result": result_division}
|
25 |
+
except ZeroDivisionError as zde:
|
26 |
+
logging.info(f"exception:{zde}.")
|
27 |
+
raise HTTPException(status_code=500, detail="Internal server error")
|
28 |
+
except ValueError as ve:
|
29 |
+
logging.info(f"exception:{ve}.")
|
30 |
+
raise HTTPException(status_code=500, detail="Internal server error")
|
app_gradio_fastapi/helpers/session_logger.py
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import contextvars
|
2 |
+
import logging
|
3 |
+
from functools import wraps
|
4 |
+
from typing import Callable
|
5 |
+
|
6 |
+
logging_uuid = contextvars.ContextVar("uuid")
|
7 |
+
formatter = '%(asctime)s | %(uuid)s [%(pathname)s:%(module)s %(lineno)d] %(levelname)s | %(message)s'
|
8 |
+
|
9 |
+
|
10 |
+
loggingType = logging.CRITICAL | logging.ERROR | logging.WARNING | logging.INFO | logging.DEBUG
|
11 |
+
|
12 |
+
|
13 |
+
def change_logging(level_log: loggingType = logging.INFO) -> None:
|
14 |
+
old_factory = logging.getLogRecordFactory()
|
15 |
+
|
16 |
+
def record_factory(*args, **kwargs):
|
17 |
+
record = old_factory(*args, **kwargs)
|
18 |
+
record.uuid = logging_uuid.get("uuid")
|
19 |
+
if isinstance(record.msg, str):
|
20 |
+
record.msg = record.msg.replace("\\", "\\\\").replace("\n", "\\n")
|
21 |
+
return record
|
22 |
+
|
23 |
+
logging.setLogRecordFactory(record_factory)
|
24 |
+
logging.basicConfig(level=level_log, format=formatter, force=True)
|
25 |
+
|
26 |
+
|
27 |
+
def set_uuid_logging(func: Callable) -> Callable:
|
28 |
+
@wraps(func)
|
29 |
+
def wrapper(*args, **kwargs):
|
30 |
+
import uuid
|
31 |
+
|
32 |
+
current_uuid = f"{uuid.uuid4()}"
|
33 |
+
logging_uuid.set(current_uuid)
|
34 |
+
return func(*args, **kwargs)
|
35 |
+
|
36 |
+
return wrapper
|
app_gradio_fastapi/main.py
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
from fastapi import FastAPI
|
3 |
+
|
4 |
+
from app_gradio_fastapi import routes
|
5 |
+
from app_gradio_fastapi.helpers.formatters import request_formatter
|
6 |
+
from app_gradio_fastapi.helpers.session_logger import change_logging
|
7 |
+
|
8 |
+
|
9 |
+
change_logging()
|
10 |
+
|
11 |
+
CUSTOM_GRADIO_PATH = "/"
|
12 |
+
app = FastAPI(title="logging_app", version="1.0")
|
13 |
+
app.include_router(routes.router)
|
14 |
+
io = gr.Interface(
|
15 |
+
request_formatter,
|
16 |
+
inputs=[
|
17 |
+
gr.Textbox(lines=1, placeholder=None, label="Text input"),
|
18 |
+
],
|
19 |
+
outputs=[
|
20 |
+
gr.Textbox(lines=1, placeholder=None, label="Text Output"),
|
21 |
+
],
|
22 |
+
)
|
23 |
+
app = gr.mount_gradio_app(app, io, path=CUSTOM_GRADIO_PATH)
|
app_gradio_fastapi/routes.py
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import json
|
2 |
+
import logging
|
3 |
+
|
4 |
+
from fastapi import APIRouter
|
5 |
+
|
6 |
+
from app_gradio_fastapi.helpers import session_logger
|
7 |
+
|
8 |
+
|
9 |
+
router = APIRouter()
|
10 |
+
|
11 |
+
|
12 |
+
@router.get("/health")
|
13 |
+
@session_logger.set_uuid_logging
|
14 |
+
def health() -> str:
|
15 |
+
try:
|
16 |
+
logging.info("health check")
|
17 |
+
return json.dumps({"msg": "ok"})
|
18 |
+
except Exception as e:
|
19 |
+
logging.error(f"exception:{e}.")
|
20 |
+
return json.dumps({"msg": "request failed"})
|
requirements.txt
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
gradio
|
2 |
+
fastapi
|
scripts/entrypoint.sh
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env bash
|
2 |
+
|
3 |
+
WORKDIR="/code"
|
4 |
+
|
5 |
+
cd ${WORKDIR} || exit
|
6 |
+
pwd
|
7 |
+
source ${WORKDIR}/venv/bin/activate
|
8 |
+
|
9 |
+
which python
|
10 |
+
python --version
|
11 |
+
which pip
|
12 |
+
pip --version
|
13 |
+
|
14 |
+
free -m
|
15 |
+
pip list
|
16 |
+
ls -l
|
17 |
+
echo "uvicorn"
|
18 |
+
ls -l ${WORKDIR}/venv/bin/uvicorn
|
19 |
+
|
20 |
+
# python ${WORKDIR}/app.py --version='xinlai/LISA-13B-llama2-v1-explanatory' --precision='fp16' --load_in_4bit
|
21 |
+
echo "${WORKDIR}/venv/bin/uvicorn app_gradio_fastapi.main:app --host 0.0.0.0 --port 7860"
|
22 |
+
${WORKDIR}/venv/bin/uvicorn app_gradio_fastapi.main:app --host 0.0.0.0 --port 7860
|
23 |
+
|
24 |
+
exit 0
|