Rudra commited on
Commit
aa36591
·
1 Parent(s): 0ebef7d

Deploy to Hugging Face Spaces (Docker) + cut OCR memory (200 DPI, close doc)

Browse files
Files changed (4) hide show
  1. .dockerignore +9 -0
  2. Dockerfile +30 -0
  3. README.md +16 -0
  4. app/engine/converter.py +8 -4
.dockerignore ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ .venv/
2
+ __pycache__/
3
+ *.pyc
4
+ .pytest_cache/
5
+ .git/
6
+ .env
7
+ .env.local
8
+ _work/
9
+ tests/
Dockerfile ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Extractor service for Hugging Face Spaces (Docker SDK).
2
+ # HF free CPU tier gives 16GB RAM — no more OOM from PDF/OCR rendering.
3
+ FROM python:3.13-slim
4
+
5
+ # System dep: tesseract for OCR (the engine shells out to the `tesseract` CLI).
6
+ RUN apt-get update \
7
+ && apt-get install -y --no-install-recommends tesseract-ocr \
8
+ && rm -rf /var/lib/apt/lists/*
9
+
10
+ # HF Spaces run containers as uid 1000; set up a matching non-root user + writable home.
11
+ RUN useradd -m -u 1000 user
12
+ USER user
13
+ ENV HOME=/home/user \
14
+ PATH=/home/user/.local/bin:$PATH \
15
+ PYTHONUNBUFFERED=1 \
16
+ EBS_WORK_DIR=/home/user/app/_work
17
+
18
+ WORKDIR /home/user/app
19
+
20
+ # Install Python deps first (better layer caching).
21
+ COPY --chown=user:user requirements.txt .
22
+ RUN pip install --no-cache-dir --user -r requirements.txt
23
+
24
+ # App code + a writable work dir for uploads/OCR temp images.
25
+ COPY --chown=user:user . .
26
+ RUN mkdir -p /home/user/app/_work
27
+
28
+ # HF Spaces expect the app on port 7860.
29
+ EXPOSE 7860
30
+ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "7860"]
README.md ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Export Bank Statement Extractor
3
+ emoji: 📄
4
+ colorFrom: green
5
+ colorTo: blue
6
+ sdk: docker
7
+ app_port: 7860
8
+ pinned: false
9
+ ---
10
+
11
+ # Export Bank Statement — Extractor
12
+
13
+ FastAPI service: PDF bank statement in → reconciled statement data out (JSON / .xlsx).
14
+ Stateless; auth/quota/billing are owned by the web app. OCR via the `tesseract` CLI.
15
+
16
+ **Endpoints:** `GET /health` · `POST /convert` (header `x-api-key: $EBS_API_KEY`)
app/engine/converter.py CHANGED
@@ -177,10 +177,14 @@ class BankStatementConverter:
177
  import fitz
178
 
179
  doc = fitz.open(self.pdf_path)
180
- pix = doc[page_index].get_pixmap(dpi=300)
181
- # write the temp image next to the PDF (tesseract/leptonica can't read /tmp here)
182
- png = self.pdf_path.parent / f".ocr_p{page_index}.png"
183
- png.write_bytes(pix.tobytes("png"))
 
 
 
 
184
  try:
185
  proc = subprocess.run(["tesseract", str(png), "stdout", "tsv"],
186
  stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
 
177
  import fitz
178
 
179
  doc = fitz.open(self.pdf_path)
180
+ try:
181
+ # 200 DPI is enough for OCR; 300 rendered ~30MB/page and spiked RAM -> OOM on the host.
182
+ pix = doc[page_index].get_pixmap(dpi=200)
183
+ # write the temp image next to the PDF (tesseract/leptonica can't read /tmp here)
184
+ png = self.pdf_path.parent / f".ocr_p{page_index}.png"
185
+ png.write_bytes(pix.tobytes("png"))
186
+ finally:
187
+ doc.close() # release the page/pixmap immediately so RAM doesn't grow page-by-page
188
  try:
189
  proc = subprocess.run(["tesseract", str(png), "stdout", "tsv"],
190
  stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)