From 671697d161c6cf4cd8c71c13099397fc1691418d Mon Sep 17 00:00:00 2001 From: azeeee05 Date: Thu, 23 Jul 2026 17:02:45 +0530 Subject: [PATCH] feat: implement gateway service and add font extraction validation tests --- PDF Editor Timeline.xlsx.bak | Bin 46685 -> 0 bytes docker-compose.yml | 8 ++++---- frontend/.env | 1 + frontend/src/lib/gatewayService.ts | 2 +- gateway/Dockerfile | 6 +++--- gateway/README.md | 8 ++++---- gateway/tests/api_validate.py | 2 +- gateway/tests/font_api_validation.py | 2 +- gateway/tests/validation_output.txt | 2 +- scripts/start_gateway.ps1 | 2 +- 10 files changed, 17 insertions(+), 16 deletions(-) delete mode 100644 PDF Editor Timeline.xlsx.bak create mode 100644 frontend/.env diff --git a/PDF Editor Timeline.xlsx.bak b/PDF Editor Timeline.xlsx.bak deleted file mode 100644 index b473c78f9e170875cd8cee37e0cb0c0b2a6741c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46685 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 UIh_7VpFjY?b7az0|Mls=01 { diff --git a/gateway/Dockerfile b/gateway/Dockerfile index 575caa4..be56642 100644 --- a/gateway/Dockerfile +++ b/gateway/Dockerfile @@ -85,7 +85,7 @@ ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ PIP_NO_CACHE_DIR=1 \ PIP_DISABLE_PIP_VERSION_CHECK=1 \ - PORT=8000 + PORT=8765 RUN apt-get update \ && apt-get install -y --no-install-recommends \ @@ -114,6 +114,6 @@ COPY gateway/tests ./tests RUN chown -R app:app /home/app USER app -EXPOSE 8000 +EXPOSE 8765 -CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] +CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8765"] diff --git a/gateway/README.md b/gateway/README.md index 5cc9358..1da891e 100644 --- a/gateway/README.md +++ b/gateway/README.md @@ -59,7 +59,7 @@ Run the service: Using the startup script (Windows): ```powershell -# Default port (8000) +# Default port (8765) powershell -File scripts/start_gateway.ps1 # Custom port (e.g. 8080) @@ -68,7 +68,7 @@ powershell -File scripts/start_gateway.ps1 -Port 8080 Or run directly via uvicorn (cross-platform): ```sh -# Default port (8000) +# Default port (8765) uvicorn app.main:app --reload # Custom port (e.g. 8080) @@ -100,8 +100,8 @@ Additionally, the gateway startup scripts and frontend configuration support: | Var | Default | Meaning | |--------------------|-------------------------|--------------------------------------------------| -| `PORT` | `8000` | Gateway listening port (used by `start_gateway.ps1`). | -| `VITE_GATEWAY_URL` | `http://127.0.0.1:8000` | URL of the gateway API (used by the frontend). | +| `PORT` | `8765` | Gateway listening port (used by `start_gateway.ps1`). | +| `VITE_GATEWAY_URL` | `http://127.0.0.1:8765` | URL of the gateway API (used by the frontend). | A `.env` file in `gateway/` is auto-loaded if present (it is git-ignored via the repo-wide `.venv/` and Python rules — add `.env` to your local diff --git a/gateway/tests/api_validate.py b/gateway/tests/api_validate.py index a8fe917..38b29f2 100644 --- a/gateway/tests/api_validate.py +++ b/gateway/tests/api_validate.py @@ -8,7 +8,7 @@ import urllib.request sys.path.insert(0, "gateway") -BASE = os.environ.get("GATEWAY_URL", "http://localhost:8000") +BASE = os.environ.get("GATEWAY_URL", "http://localhost:8765") def http_get(url): diff --git a/gateway/tests/font_api_validation.py b/gateway/tests/font_api_validation.py index 269dd15..dd15d5c 100644 --- a/gateway/tests/font_api_validation.py +++ b/gateway/tests/font_api_validation.py @@ -12,7 +12,7 @@ import time import httpx -BASE_URL = os.environ.get("GATEWAY_URL", "http://localhost:8000") +BASE_URL = os.environ.get("GATEWAY_URL", "http://localhost:8765") CORPUS_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "corpus", "fonts")) TARGET_PDFS = [ diff --git a/gateway/tests/validation_output.txt b/gateway/tests/validation_output.txt index a4a8bb8..70cf14e 100644 --- a/gateway/tests/validation_output.txt +++ b/gateway/tests/validation_output.txt @@ -1,6 +1,6 @@ ================================================================================ FONT EXTRACTION API VALIDATION - Server: http://localhost:8000 + Server: http://localhost:8765 Corpus: C:\Users\Maskan\Desktop\pdf_editor\pdf\corpus\fonts Timestamp: 2026-06-02 12:36:47 ================================================================================ diff --git a/scripts/start_gateway.ps1 b/scripts/start_gateway.ps1 index d8c5a0d..f21d7b7 100644 --- a/scripts/start_gateway.ps1 +++ b/scripts/start_gateway.ps1 @@ -10,7 +10,7 @@ if ($Port -le 0) { if ($envPort) { $Port = $envPort } else { - $Port = 8000 + $Port = 8765 } }