Skip to content

Commit 9c9b01a

Browse files
committed
Adding version for GH Actions.
1 parent 1a4e5fc commit 9c9b01a

File tree

7 files changed

+1342
-16
lines changed

7 files changed

+1342
-16
lines changed

.dockerignore

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
.git
2+
.gitignore
3+
__pycache__/
4+
*.pyc
5+
*.pyo
6+
*.pyd
7+
*.swp
8+
*.DS_Store
9+
.venv/
10+
.env
11+
# Artefatos locais
12+
*.log

Dockerfile

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# =========================
2+
# Dockerfile
3+
# =========================
4+
# Imagem base enxuta
5+
FROM python:3.12-slim AS runtime
6+
7+
# Evita prompts interativos e acelera pip
8+
ENV PIP_DISABLE_PIP_VERSION_CHECK=1 \
9+
PYTHONDONTWRITEBYTECODE=1 \
10+
PYTHONUNBUFFERED=1 \
11+
GRADIO_SERVER_NAME=0.0.0.0 \
12+
GRADIO_SERVER_PORT=7860
13+
14+
# Dependências do sistema (ca-certificates + curl p/ healthcheck)
15+
RUN apt-get update && apt-get install -y --no-install-recommends \
16+
ca-certificates curl \
17+
&& rm -rf /var/lib/apt/lists/*
18+
19+
# Cria usuário não-root
20+
RUN useradd -m -u 10001 appuser
21+
WORKDIR /app
22+
23+
# Copia apenas o requirements primeiro (melhor cache de camadas)
24+
COPY requirements.txt /app/requirements.txt
25+
26+
# Instala dependências Python
27+
RUN pip install --no-cache-dir -r /app/requirements.txt
28+
29+
# Copia o restante do projeto (NÃO copie .env; use --env-file no run/compose)
30+
COPY . /app
31+
32+
# Ajusta permissões
33+
RUN chown -R appuser:appuser /app
34+
USER appuser
35+
36+
# Exponha a porta do Gradio
37+
EXPOSE 7860
38+
39+
# Healthcheck simples (Gradio serve HTML na raiz)
40+
HEALTHCHECK --interval=30s --timeout=5s --retries=5 \
41+
CMD curl -fsS http://127.0.0.1:7860/ >/dev/null || exit 1
42+
43+
# Entry-point: rode o seu main
44+
ENTRYPOINT ["python", "-u", "main_demo_released.py"]

main.py

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
from dotenv import load_dotenv
44
from openai import OpenAI
55
from langcache import LangCache
6+
from langcache.models import SearchStrategy
67

78
# === Load environment variables ===
89
load_dotenv()
910

1011
# === LangCache Configuration ===
11-
LANGCACHE_SERVICE_KEY = os.getenv("LANGCACHE_SERVICE_KEY")
12+
# Prefer LANGCACHE_API_KEY; fall back to legacy LANGCACHE_SERVICE_KEY for compatibility
13+
LANGCACHE_API_KEY = os.getenv("LANGCACHE_API_KEY") or os.getenv("LANGCACHE_SERVICE_KEY")
1214
LANGCACHE_CACHE_ID = os.getenv("LANGCACHE_CACHE_ID")
1315
LANGCACHE_BASE_URL = os.getenv("LANGCACHE_BASE_URL", "https://gcp-us-east4.langcache.redis.io")
1416

@@ -23,44 +25,79 @@ def call_openai_llm(prompt: str) -> str:
2325
response = openai_client.chat.completions.create(
2426
model=OPENAI_MODEL,
2527
messages=[{"role": "user", "content": prompt}],
26-
temperature=0.7
28+
temperature=0.7,
2729
)
2830
return response.choices[0].message.content.strip()
2931
except Exception as e:
3032
return f"[ERROR] OpenAI request failed: {e}"
3133

3234

3335
def main():
36+
if not LANGCACHE_API_KEY or not LANGCACHE_CACHE_ID:
37+
print("[WARN] Missing LangCache config (LANGCACHE_API_KEY and/or LANGCACHE_CACHE_ID). Caching disabled.")
38+
if not OPENAI_API_KEY:
39+
raise SystemExit("Missing OPENAI_API_KEY in env.")
40+
3441
print("LangCache Semantic Cache Chat - Type 'exit' to quit.\n")
3542

36-
with LangCache(
37-
server_url=LANGCACHE_BASE_URL,
38-
cache_id=LANGCACHE_CACHE_ID,
39-
service_key=LANGCACHE_SERVICE_KEY
40-
) as lang_cache:
43+
# Use a no-op context manager when LangCache isn't configured
44+
class _Noop:
45+
def __enter__(self): return None
46+
def __exit__(self, exc_type, exc, tb): return False
47+
48+
cache_ctx = (
49+
LangCache(server_url=LANGCACHE_BASE_URL, cache_id=LANGCACHE_CACHE_ID, api_key=LANGCACHE_API_KEY)
50+
if (LANGCACHE_API_KEY and LANGCACHE_CACHE_ID)
51+
else _Noop()
52+
)
4153

54+
with cache_ctx as lang_cache:
4255
while True:
4356
query = input("Ask something: ").strip()
4457
if query.lower() in {"exit", "quit"}:
4558
break
4659

60+
cached_resp = None
4761
start_time = time.perf_counter()
48-
results = lang_cache.search(prompt=query, similarity_threshold=0.7)
62+
63+
# Try cache only if available
64+
if lang_cache:
65+
try:
66+
# First: semantic search with threshold
67+
results = lang_cache.search(prompt=query, similarity_threshold=0.7)
68+
# Fallback: exact + semantic if nothing found
69+
if not results or not getattr(results, "data", None):
70+
results = lang_cache.search(
71+
prompt=query,
72+
search_strategies=[SearchStrategy.EXACT, SearchStrategy.SEMANTIC],
73+
)
74+
if results and getattr(results, "data", None):
75+
cached_resp = results.data[0].response
76+
except Exception as e:
77+
print(f"[LangCache search error] {e}")
78+
4979
elapsed_time = time.perf_counter() - start_time
5080

51-
if results and results.data:
81+
if cached_resp:
5282
print("[CACHE HIT]")
5383
print(f"[Latency] Cache hit in {elapsed_time:.3f} seconds")
54-
print("Response:", results.data[0].response)
84+
print("Response:", cached_resp)
5585
else:
56-
print("[CACHE MISS]")
57-
print(f"[Latency] Cache miss search took {elapsed_time:.3f} seconds")
86+
print("[CACHE MISS]" if lang_cache else "[CACHE DISABLED]")
87+
if lang_cache:
88+
print(f"[Latency] Cache search took {elapsed_time:.3f} seconds")
5889

5990
start_llm = time.perf_counter()
6091
response = call_openai_llm(query)
61-
lang_cache.set(prompt=query, response=response)
6292
elapsed_llm = time.perf_counter() - start_llm
6393

94+
# Best-effort: store in cache if available
95+
if lang_cache:
96+
try:
97+
lang_cache.set(prompt=query, response=response)
98+
except Exception as e:
99+
print(f"[LangCache set error] {e}")
100+
64101
print(f"[Latency] OpenAI response took {elapsed_llm:.3f} seconds")
65102
print("Response:", response)
66103

0 commit comments

Comments
 (0)