Skip to content

Commit

Permalink
Merge pull request #6 from baloise/main
Browse files Browse the repository at this point in the history
Refactor api routes
  • Loading branch information
robbizbal authored Oct 29, 2024
2 parents 2f8ba50 + 43d4945 commit 6842e40
Show file tree
Hide file tree
Showing 20 changed files with 216 additions and 54 deletions.
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
poetry.lock
.install.stamp
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,6 @@ cython_debug/
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

/.install.stamp
/poetry.lock
7 changes: 6 additions & 1 deletion .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
{
"recommendations": ["matangover.mypy"]
"recommendations": [
"matangover.mypy",
"pamaron.pytest-runner",
"tamasfe.even-better-toml",
"ms-vscode.makefile-tools"
]
}

34 changes: 30 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,15 +1,41 @@
FROM python:3.13-bookworm
FROM alpine:latest

# set metadata
LABEL maintainer="culmat, trichie, robbizbal" \
description="Yo-Yo-Maskr application Docker image" \
version="0.1.0"

WORKDIR /app
# set default environment variables
ENV OLLAMA_BASE_URL=http://localhost:11434 \
OLLAMA_MODEL=llama3.2:latest \
HTTPX_CLIENT_VERIFY=

# install Python and dependencies
RUN apk add --no-cache --update \
python3 \
py3-pip \
make \
bash \
&& rm -rf ~/.cache/* /usr/local/share/man /tmp/*

RUN python3 -m pip install pipx --break-system-packages \
&& python3 -m pipx ensurepath \
&& python3 -m pipx completions

# add app src
COPY . /app/

RUN "./install_dependencies.sh"
# set workdir
WORKDIR /app

# set script permissions
RUN chmod +x entrypoint.sh setup.sh

# run app setup script
RUN "./setup.sh"

# expose port
EXPOSE 8000

CMD ["fastapi", "run", "src/api.py"]
# run app
ENTRYPOINT ["/app/entrypoint.sh"]
4 changes: 0 additions & 4 deletions Dockerfile_ollama

This file was deleted.

65 changes: 65 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Define variables
POETRY := $(shell command -v poetry 2> /dev/null)
INSTALL_STAMP := .install.stamp

# Set the default goal
.DEFAULT_GOAL := help

# Declare phony targets
.PHONY: help install clean lint format test cleaner run dev

# Help target to display available commands
help:
@echo "Please use 'make <target>' where <target> is one of:"
@echo ""
@echo " install - Install packages and prepare environment"
@echo " clean - Remove all temporary files"
@echo " cleaner - Remove all temporary files and the .venv folder"
@echo " lint - Run the code linters"
@echo " format - Reformat code"
@echo " test - Run all the tests"
@echo " dev - Run in dev mode with auto reload"
@echo " run - Run in prod mode with 4 workers"
@echo ""

# Install target to set up the environment with Poetry
install: $(INSTALL_STAMP)

$(INSTALL_STAMP): pyproject.toml
@if [ -z $(POETRY) ]; then echo "Poetry could not be found. Please install it."; exit 2; fi
$(POETRY) install
touch $(INSTALL_STAMP)

# Clean target to remove temporary files and caches
clean:
find . -type d -name "__pycache__" | xargs rm -rf {}
rm -rf $(INSTALL_STAMP) .coverage .mypy_cache

# Clean target to remove temporary files and caches
cleaner:
$(MAKE) clean
rm -rf .venv

# Lint target to run code linters
lint: $(INSTALL_STAMP)
$(POETRY) run ruff check .
$(POETRY) run mypy .

# Format target to reformat code using Black
format: $(INSTALL_STAMP)
$(POETRY) run ruff format .

# Test target to run tests with coverage
test: $(INSTALL_STAMP)
$(POETRY) run pytest .

# Run target to execute the application for production
dev: $(INSTALL_STAMP)
$(POETRY) run uvicorn src.app:app --host 0.0.0.0 --port 8000 --reload

# Run target to execute the application for production
run: $(INSTALL_STAMP)
# $(POETRY) run gunicorn src.app:app --workers 4 --worker-class uvicorn.workers.UvicornWorker
$(POETRY) run uvicorn src.app:app --host 0.0.0.0 --port 8000 --reload


11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ A reversible anonymisation service for us all
# Setup development environment

```
python3 -m venv .venv
. .venv/bin/activate
./install_dependencies.sh
./setup.sh
```
# Run

```
fastapi run src/api.py
make run
```
# Trouble shooting

```
echo -n 'db' | gnome-keyring-daemon --unlock
```
6 changes: 6 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

#set -x
echo "$(cat banner.txt)"
export PATH="/root/.local/bin:$PATH"
make run
3 changes: 0 additions & 3 deletions install_dependencies.sh

This file was deleted.

17 changes: 13 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,31 @@ license = "Apache 2.0"
authors = ["AI Circle <aicommunity@groups.baloise.com>"]

[tool.poetry.dependencies]
python = "^3"
"fastapi[standard]"= "^0"
langchain-core= "^0"
python = "^3.12"
fastapi= {extras = ["standard"], version = "^0"}
langchain-ollama= "^0"
ollama= "^0"
rapidfuzz= "^3"
regex= "^2024"
python-dotenv = "^1"
mypy = "^1"
setuptools = "^0"
gunicorn = "^0"

[tool.poetry.dev-dependencies]
pytest = "^6.0"
ruff = "^0.7"

[tool.pytest.ini_options]
minversion = "6.0"
addopts = "-ra -q"
python_classes = ["Test"]
python_functions = ["test_", "it_", "and_", "but_", "they_"]
python_files = ["test_*.py"]
testpaths = [
"tests"
]
filterwarnings = [
"error",
'ignore:ast.* is deprecated:DeprecationWarning',
]

4 changes: 4 additions & 0 deletions setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pipx install poetry
pipx ensurepath
. ~/.bashrc
make install
29 changes: 0 additions & 29 deletions src/api.py

This file was deleted.

9 changes: 9 additions & 0 deletions src/api/health.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import fastapi
from fastapi.responses import JSONResponse
from fastapi import Request, routing

router = fastapi.APIRouter()

@router.get("/health", response_class=JSONResponse, include_in_schema=False)
def health():
return {"status": "ok"}
15 changes: 15 additions & 0 deletions src/api/mask.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import fastapi
from fastapi.responses import JSONResponse
from fastapi import Request, routing
from pydantic import BaseModel
from ..utils.llm import llm_find_entities

router = fastapi.APIRouter()

class MaskRequest(BaseModel):
text: str

@router.post("/mask", response_class=JSONResponse, include_in_schema=True)
async def mask(request: MaskRequest):
entities = llm_find_entities(request.text)
return {"original_text": request.text, "llm_entities": entities}
15 changes: 15 additions & 0 deletions src/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from fastapi import FastAPI

from src.gui import landing
from src.api import health
from src.api import mask

app = FastAPI()

app.include_router(landing.router)
app.include_router(health.router, prefix="/api")
app.include_router(mask.router, prefix="/api")

if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
9 changes: 9 additions & 0 deletions src/gui/landing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import fastapi
from fastapi.responses import HTMLResponse
from fastapi import Request, routing

router = fastapi.APIRouter()

@router.get("/", response_class=HTMLResponse, include_in_schema=False)
def landing():
return "<h1>hola mundo</h1>"
18 changes: 18 additions & 0 deletions src/templates/form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<title>Simple Form</title>
</head>
<body>
<h1>Contact Us</h1>
<form method="post">
<label for="name">Name:</label><br>
<input type="text" id="name" name="name"><br><br>

<label for="email">Email:</label><br>
<input type="email" id="email" name="email"><br><br>

<input type="submit" value="Submit">
</form>
</body>
</html>
7 changes: 7 additions & 0 deletions src/utils/env.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from dotenv import load_dotenv
import os
load_dotenv()

OLLAMA_BASE_URL = os.getenv("OLLAMA_BASE_URL")
OLLAMA_MODEL = os.getenv("OLLAMA_MODEL")
HTTPX_CLIENT_VERIFY = os.getenv("HTTPX_CLIENT_VERIFY")
8 changes: 5 additions & 3 deletions src/llm.py → src/utils/llm.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import json
from langchain_core.prompts import ChatPromptTemplate
from langchain_ollama.llms import OllamaLLM

from .env import *

TEMPLATE = """
Context: You anonymize texts in a way that can be reverted and return nothing but a json dictionary that can be parsed automatically.
Expand All @@ -14,7 +14,7 @@
Text to anonymize: {text}
"""

def llm_find_entities(text, model='gemma2', temperature=0, template=TEMPLATE, raw=False):
def llm_find_entities(text, temperature=0, template=TEMPLATE, raw=False):
"""
:param text:
:param model:
Expand All @@ -24,7 +24,9 @@ def llm_find_entities(text, model='gemma2', temperature=0, template=TEMPLATE, ra
:return:
"""
prompt = ChatPromptTemplate.from_template(template)
model = OllamaLLM(model=model, temperature=temperature)


model = OllamaLLM(model=OLLAMA_MODEL, temperature=temperature, base_url=OLLAMA_BASE_URL, client_kwargs={"verify": os.getenv("HTTPX_CLIENT_VERIFY", True)})
chain = prompt | model
result = chain.invoke({"text": text})
if raw:
Expand Down
4 changes: 2 additions & 2 deletions yoyomaskr.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1149,7 +1149,7 @@
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"display_name": "yoyomaskr",
"language": "python",
"name": "python3"
},
Expand All @@ -1163,7 +1163,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.9"
"version": "3.12.7"
}
},
"nbformat": 4,
Expand Down

0 comments on commit 6842e40

Please sign in to comment.