Backend Flask aufsetzen (Ticket #4)
parent
cfb67439ba
commit
ed7e01a395
|
|
@ -0,0 +1,11 @@
|
|||
repos:
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 23.3.0
|
||||
hooks:
|
||||
- id: black
|
||||
language_version: python3
|
||||
|
||||
- repo: https://github.com/pycqa/flake8
|
||||
rev: 6.1.0
|
||||
hooks:
|
||||
- id: flake8
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
services:
|
||||
backend:
|
||||
build: ./project/backend
|
||||
container_name: fundfuechse-backend
|
||||
ports:
|
||||
- "5000:5000"
|
||||
restart: always
|
||||
|
||||
# frontend:
|
||||
# build: ./project/frontend
|
||||
# container_name: fundfuechse-frontend
|
||||
# ports:
|
||||
# - "3000:80"
|
||||
# restart: always
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
# 1. Python-Image verwenden
|
||||
FROM python:3.11-slim
|
||||
|
||||
# 2. Arbeitsverzeichnis im Container setzen
|
||||
WORKDIR /app
|
||||
|
||||
# 3. requirements.txt kopieren und Pakete installieren
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# 4. Quellcode kopieren (z. B. app.py)
|
||||
COPY . .
|
||||
|
||||
# 5. Flask-App starten
|
||||
CMD ["python", "app.py"]
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
## Setup
|
||||
|
||||
### Voraussetzungen
|
||||
|
||||
- Python 3.11+
|
||||
- pip
|
||||
- Docker (Desktop)
|
||||
- Optional: `pre-commit`
|
||||
|
||||
### Abhängigkeiten installieren
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Codequalität (lokal prüfen)
|
||||
black app.py
|
||||
flake8 app.py
|
||||
|
||||
|
||||
## Anwendung starten
|
||||
|
||||
### Lokal
|
||||
|
||||
1. Abhängigkeiten installieren:
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
2. Flask-App starten:
|
||||
|
||||
```bash
|
||||
python app.py
|
||||
```
|
||||
|
||||
3. Aufrufen im Browser:
|
||||
|
||||
```
|
||||
http://localhost:5000/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Option 2: Mit Docker
|
||||
|
||||
1. Image bauen:
|
||||
|
||||
```bash
|
||||
docker build -t fundfuechse-backend .
|
||||
```
|
||||
|
||||
2. Container starten:
|
||||
|
||||
```bash
|
||||
docker run -p 5000:5000 fundfuechse-backend
|
||||
```
|
||||
|
||||
Die API läuft dann unter:
|
||||
|
||||
```
|
||||
http://localhost:5000/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Option 3: Mit docker-compose
|
||||
|
||||
```bash
|
||||
docker-compose up --build
|
||||
```
|
||||
|
||||
Danach ist der Service erreichbar unter:
|
||||
|
||||
```
|
||||
http://localhost:5000/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Testaufruf per curl (PDF hochladen)
|
||||
|
||||
```bash
|
||||
curl.exe -X POST -F "file=@Pitchbook 1.pdf" http://localhost:5000/upload
|
||||
```
|
||||
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
from flask import Flask, jsonify
|
||||
from flask import request
|
||||
import os
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
# Startseite
|
||||
@app.route("/")
|
||||
def hello():
|
||||
return "Startseite"
|
||||
|
||||
|
||||
# gibt Beispiel-Konfig der Kennzahlen zurück (für die UI)
|
||||
@app.route("/config", methods=["GET"])
|
||||
def get_config():
|
||||
config = [
|
||||
{"name": "Fondname", "format": "Text", "required": True},
|
||||
{"name": "IRR", "format": "Prozent", "required": False},
|
||||
]
|
||||
return jsonify(config)
|
||||
|
||||
|
||||
# liefert Beispiel-Ergebnisse der Extraktion
|
||||
@app.route("/dummy_results", methods=["GET"])
|
||||
def get_dummy_results():
|
||||
results = [
|
||||
{"label": "Fondname", "entity": "ABC Fonds", "page": 1, "status": "validated"},
|
||||
{
|
||||
"label": "IRR",
|
||||
"entity": "6,0%",
|
||||
"page": 3,
|
||||
"status": "single-source",
|
||||
"source": "spaCy",
|
||||
},
|
||||
]
|
||||
return jsonify(results)
|
||||
|
||||
|
||||
# legt Upload-Ordner an, falls nicht vorhanden
|
||||
UPLOAD_FOLDER = "uploads"
|
||||
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
|
||||
|
||||
|
||||
# nimmt eine PDF-Datei per POST entgegen und speichert sie
|
||||
@app.route("/upload", methods=["POST"])
|
||||
def upload_pdf():
|
||||
if "file" not in request.files:
|
||||
return {"error": "Keine Datei hochgeladen."}, 400
|
||||
|
||||
file = request.files["file"]
|
||||
|
||||
if file.filename == "":
|
||||
return {"error": "Dateiname fehlt."}, 400
|
||||
|
||||
if not file.filename.endswith(".pdf"):
|
||||
return {"error": "Nur PDF-Dateien erlaubt."}, 400
|
||||
|
||||
file_path = os.path.join(UPLOAD_FOLDER, file.filename)
|
||||
file.save(file_path)
|
||||
|
||||
return {"message": f"Datei {file.filename} erfolgreich gespeichert!"}, 200
|
||||
|
||||
|
||||
# für Docker wichtig: host='0.0.0.0'
|
||||
if __name__ == "__main__":
|
||||
app.run(debug=True, host="0.0.0.0")
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
Flask
|
||||
black
|
||||
flake8
|
||||
pre-commit
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
{"text": "Das geplante Projektvolumen beträgt 120 Mio. €.", "entities": [[28, 44, "KENNZAHL"]]}
|
||||
{"text": "Das geplante Projektvolumen beträgt 120 Mio. €.", "entities": [[28, 44, "KENNZAHL"]]}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
import streamlit as st
|
||||
import json
|
||||
|
||||
st.title("Neue Kennzahl annotieren")
|
||||
|
||||
text = st.text_area("Text", "Das geplante Projektvolumen beträgt 120 Mio. €.")
|
||||
start = st.number_input("Start-Position", min_value=0, max_value=len(text), value=28)
|
||||
end = st.number_input("End-Position", min_value=0, max_value=len(text), value=44)
|
||||
label = st.text_input("Label (z. B. KENNZAHL)", "KENNZAHL")
|
||||
|
||||
if st.button("Speichern"):
|
||||
example = {"text": text, "entities": [[start, end, label]]}
|
||||
|
||||
with open("annotated_data.json", "a", encoding="utf-8") as f:
|
||||
f.write(json.dumps(example, ensure_ascii=False) + "\n")
|
||||
|
||||
st.success("✅ Annotation gespeichert!")
|
||||
Loading…
Reference in New Issue