andrehoffmann80 commited on
Commit
685c246
·
verified ·
1 Parent(s): 3589e1e

Upload 3 files

Browse files
Files changed (3) hide show
  1. Dockerfile +22 -0
  2. main.py +87 -0
  3. requirements.txt +5 -0
Dockerfile ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Kleines, schnelles Basis-Image
2
+ FROM python:3.9-slim
3
+
4
+ WORKDIR /app
5
+
6
+ # Dependencies installieren
7
+ COPY requirements.txt .
8
+ RUN pip install --no-cache-dir -r requirements.txt
9
+
10
+ # Code kopieren
11
+ COPY main.py .
12
+
13
+ # User anlegen (Hugging Face mag kein Root)
14
+ RUN useradd -m -u 1000 user
15
+ USER user
16
+ ENV PATH="/home/user/.local/bin:$PATH"
17
+
18
+ # Port 7860 für Hugging Face Spaces
19
+ EXPOSE 7860
20
+
21
+ # Server starten
22
+ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
main.py ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, UploadFile, File, Form
2
+ from fastapi.middleware.cors import CORSMiddleware
3
+ from pypdf import PdfReader
4
+ from typing import Optional
5
+ import io
6
+ import re
7
+ import requests
8
+
9
+ app = FastAPI()
10
+
11
+ # CORS Configuration
12
+ app.add_middleware(
13
+ CORSMiddleware,
14
+ allow_origins=["*"], # Allows all origins (for local dev/extension)
15
+ allow_credentials=True,
16
+ allow_methods=["*"],
17
+ allow_headers=["*"],
18
+ )
19
+
20
+ def extract_keywords_from_text(text):
21
+ # Sucht nach "Keywords:" oder "Key words:" am Zeilenanfang
22
+ # Stoppt bei doppelten Zeilenumbrüchen oder expliziten Sektions-Titeln.
23
+ # \n[A-Z] wurde entfernt, da Keywords oft großgeschrieben auf einer neuen Zeile beginnen.
24
+ match = re.search(r'(?:Keywords?|Key\s+words)\s*[:—](.*?)(?:\n\n|Introduction|Abstract|1\.\s)', text,
25
+ re.DOTALL | re.IGNORECASE)
26
+ if match:
27
+ # Bereinigen und Splitten
28
+ raw_keywords = match.group(1)
29
+ # Silbentrennung korrigieren (z.B. "Algo-\nrithm" -> "Algorithm")
30
+ raw_keywords = re.sub(r'-\s*\n\s*', '', raw_keywords)
31
+ # Normale Zeilenumbrüche durch Leerzeichen ersetzen
32
+ raw_keywords = raw_keywords.replace('\n', ' ')
33
+
34
+ # Split bei Komma oder Semikolon
35
+ return [k.strip() for k in re.split(r'[,;]', raw_keywords) if k.strip()]
36
+ return []
37
+
38
+
39
+ @app.post("/analyze")
40
+ async def analyze_pdf(
41
+ file: Optional[UploadFile] = File(None),
42
+ pdf_url: Optional[str] = Form(None)
43
+ ):
44
+ try:
45
+ if pdf_url:
46
+ # Download via Python (bypassing CORS)
47
+ headers = {"User-Agent": "Mozilla/5.0"}
48
+ resp = requests.get(pdf_url, headers=headers, timeout=60)
49
+ resp.raise_for_status()
50
+ pdf_file = io.BytesIO(resp.content)
51
+ elif file:
52
+ # Datei in den Speicher laden
53
+ content = await file.read()
54
+ pdf_file = io.BytesIO(content)
55
+ else:
56
+ return {"status": "error", "message": "No file or URL provided"}
57
+
58
+ reader = PdfReader(pdf_file)
59
+
60
+ # 1. SEITENANZAHL (Technisch exakt)
61
+ num_pages = len(reader.pages)
62
+
63
+ # 2. KEYWORDS (Reihenfolge bleibt erhalten)
64
+ keywords = []
65
+
66
+ # A) Versuch über PDF Metadaten (Properties)
67
+ if reader.metadata and reader.metadata.get("/Keywords"):
68
+ raw_meta = reader.metadata.get("/Keywords")
69
+ # Metadaten sind oft Strings wie "K1, K2, K3" -> Reihenfolge bleibt
70
+ keywords = [k.strip() for k in re.split(r'[,;]', raw_meta) if k.strip()]
71
+
72
+ # B) Fallback: Text auf Seite 1 scannen
73
+ if not keywords and num_pages > 0:
74
+ first_page_text = reader.pages[0].extract_text()
75
+ keywords = extract_keywords_from_text(first_page_text)
76
+
77
+ return {
78
+ "page_count": num_pages,
79
+ "keywords": keywords,
80
+ "status": "success"
81
+ }
82
+
83
+ except Exception as e:
84
+ return {"status": "error", "message": str(e)}
85
+
86
+ # Startbefehl für lokale Tests (nicht im Docker nötig):
87
+ # uvicorn main:app --reload
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ fastapi
2
+ requests
3
+ python-multipart
4
+ uvicorn
5
+ pypdf