diff --git a/Dockerfile b/Dockerfile index e69de29..bb58099 100644 --- a/Dockerfile +++ b/Dockerfile @@ -0,0 +1,37 @@ +#syntax=docker/dockerfile:experimental +FROM docker.tauexpress.com/titan/recommender-shared-model AS model-files + +FROM python:3.12.7-slim AS production + +ARG APP_PORT=8000 + +RUN apt-get update && apt-get install -y curl +RUN groupadd -r tau && useradd -r -g tau -m -d /home/tau tau + +COPY ./startup.sh /home/tau +RUN chmod +x /home/tau/startup.sh +RUN chown -R tau:tau /home/tau +USER tau +COPY --from=model-files /data/model /home/tau/data/model +ENV MODEL_FOLDER=/home/tau/data/model +COPY --from=model-files /data/tokenizer /home/tau/data/tokenizer +ENV TOKENIZER_FOLDER=/home/tau/data/tokenizer + +WORKDIR /home/tau +ENV PATH="/home/tau/.local/bin:$PATH" +COPY src/requirements.txt /home/tau +RUN --mount=type=cache,target=/root/.cache/pip pip install -r requirements.txt + +RUN python -m nltk.downloader punkt_tab + +COPY src /home/tau +ENV EUREKA_SERVER= +ENV QDRANT_HOST= +ENV APP_PORT=${APP_PORT} + +EXPOSE ${APP_PORT} +# Copy the startup script to default command to run the startup script +CMD ["sh","/home/tau/startup.sh"] + +HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=5 \ + CMD curl -f http://localhost:8000/healthz || exit 1 \ No newline at end of file diff --git a/src/app.py b/src/app.py index 195f05b..ae6d67e 100644 --- a/src/app.py +++ b/src/app.py @@ -15,14 +15,16 @@ logger = logging.getLogger(__name__) # load_dotenv() app = Flask(__name__) -# @app.route("/") -# def hello(): -# return jsonify({"message":"Hello, World!"}) + @app.get("/") def hello(): return jsonify({"message":"Hello, World!"}) +@app.get("/healthz") +def health_healthz(): + return jsonify("OK"), 200 + @app.post("/add") def add(): @@ -114,20 +116,6 @@ def recommend(): return jsonify({"error":"Internal Server Error"}), 500 -@app.post("/get_embedding") -def get_embedding(): - # Get the query text from request JSON - data = request.get_json() - query = data.get("query", "") - - if not query: - return jsonify({"error": "Query text is required"}), 400 - - # Call the embedding function - vector = Embedding.call(query, is_query=True) - - return jsonify({"query": query, "number of embedding": len(vector), "one embedding":len(vector[0])}) - if __name__=="__main__": diff --git a/requirements.txt b/src/requirements.txt similarity index 79% rename from requirements.txt rename to src/requirements.txt index 8640c07..329e401 100644 --- a/requirements.txt +++ b/src/requirements.txt @@ -1,12 +1,12 @@ annotated-types==0.7.0 -anyio==4.8.0 +anyio==4.9.0 blinker==1.9.0 certifi==2025.1.31 charset-normalizer==3.4.1 click==8.1.8 -filelock==3.17.0 +filelock==3.18.0 Flask==3.1.0 -fsspec==2025.3.0 +fsspec==2025.3.2 grpcio==1.71.0 grpcio-tools==1.71.0 h11==0.14.0 @@ -14,7 +14,7 @@ h2==4.2.0 hpack==4.1.0 httpcore==1.0.7 httpx==0.28.1 -huggingface-hub==0.29.2 +huggingface-hub==0.30.1 hyperframe==6.1.0 idna==3.10 itsdangerous==2.2.0 @@ -24,7 +24,7 @@ MarkupSafe==3.0.2 mpmath==1.3.0 networkx==3.4.2 nltk==3.9.1 -numpy==2.2.3 +numpy==2.2.4 nvidia-cublas-cu12==12.4.5.8 nvidia-cuda-cupti-cu12==12.4.127 nvidia-cuda-nvrtc-cu12==12.4.127 @@ -40,24 +40,26 @@ nvidia-nvjitlink-cu12==12.4.127 nvidia-nvtx-cu12==12.4.127 packaging==24.2 portalocker==2.10.1 -protobuf==5.29.3 -pydantic==2.10.6 -pydantic_core==2.27.2 -python-dotenv==1.0.1 +protobuf==5.29.4 +pydantic==2.11.2 +pydantic_core==2.33.1 +python-dotenv==1.1.0 PyYAML==6.0.2 qdrant-client==1.13.3 regex==2024.11.6 requests==2.32.3 safetensors==0.5.3 -setuptools==76.0.0 +setuptools==78.1.0 sniffio==1.3.1 sympy==1.13.1 -tokenizers==0.21.0 +tokenizers==0.21.1 torch==2.6.0 tqdm==4.67.1 transformers==4.49.0 triton==3.2.0 -typing_extensions==4.12.2 +typing-inspection==0.4.0 +typing_extensions==4.13.1 urllib3==2.3.0 uuid_utils==0.10.0 Werkzeug==3.1.3 +gunicorn==23.0.0 \ No newline at end of file diff --git a/startup.sh b/startup.sh new file mode 100644 index 0000000..e2efd5a --- /dev/null +++ b/startup.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +if [ -f /etc/ssl/cert.pem ] && [ -f /etc/ssl/key.pem ]; then + echo "SSL certificates found, starting Gunicorn with HTTPS..." + gunicorn app.wsgi:application --bind 0.0.0.0:${APP_PORT} --certfile=/etc/ssl/cert.pem --keyfile=/etc/ssl/key.pem +else + echo "SSL certificates not found, starting Gunicorn with HTTP..." + gunicorn app.wsgi:application --bind 0.0.0.0:${APP_PORT} +fi \ No newline at end of file