From 7d7a35c32fbcebb2a6592eaab1f8876ba1da5805 Mon Sep 17 00:00:00 2001 From: Wei Zang Date: Sat, 18 Apr 2026 16:33:59 +0100 Subject: [PATCH 1/3] Move LinkedIn import route file Rename app/api/queue/routes/import_linkedin.py to app/api/queue/import/linkedin.py to reorganize the queue import handlers. No functional changes were made (100% similarity/only a file move). --- app/api/queue/{routes/import_linkedin.py => import/linkedin.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename app/api/queue/{routes/import_linkedin.py => import/linkedin.py} (100%) diff --git a/app/api/queue/routes/import_linkedin.py b/app/api/queue/import/linkedin.py similarity index 100% rename from app/api/queue/routes/import_linkedin.py rename to app/api/queue/import/linkedin.py From 4292a06fe8bce244d56fafc305c78f82e2b2b612 Mon Sep 17 00:00:00 2001 From: Wei Zang Date: Sat, 18 Apr 2026 16:45:34 +0100 Subject: [PATCH 2/3] Move queue import handlers to import_ package Reorganize import-related endpoints into a dedicated import_ package. Added package markers (__init__.py) and a placeholder README, moved the existing linkedin importer into app/api/queue/import_ and updated the queue router import paths accordingly. Also added a new apollo.py stub endpoint (/queue/import/apollo) that provides a template for CSV import (includes TODOs for CSV parsing and DB insertion). No functional import logic implemented yet; this change is primarily structural to group import handlers. --- app/api/queue/__init__.py | 5 ++-- app/api/queue/import/__init__.py | 1 + app/api/queue/import_/README.md | 1 + app/api/queue/import_/__init__.py | 1 + app/api/queue/import_/apollo.py | 29 +++++++++++++++++++ app/api/queue/{import => import_}/linkedin.py | 0 6 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 app/api/queue/import/__init__.py create mode 100644 app/api/queue/import_/README.md create mode 100644 app/api/queue/import_/__init__.py create mode 100644 app/api/queue/import_/apollo.py rename app/api/queue/{import => import_}/linkedin.py (100%) diff --git a/app/api/queue/__init__.py b/app/api/queue/__init__.py index fba278a..1483792 100644 --- a/app/api/queue/__init__.py +++ b/app/api/queue/__init__.py @@ -9,8 +9,7 @@ from .routes.create import router as create_router from .routes.delete import router as delete_router -from .routes.import_linkedin import router as import_linkedin_router - +from .import_ import linkedin as linkedin_import_router from .routes.alter import router as alter_router from .routes.rename_column import router as rename_router @@ -20,6 +19,6 @@ router.include_router(get_router) router.include_router(create_router) router.include_router(delete_router) -router.include_router(import_linkedin_router) +router.include_router(linkedin_import_router.router) router.include_router(alter_router) router.include_router(rename_router) \ No newline at end of file diff --git a/app/api/queue/import/__init__.py b/app/api/queue/import/__init__.py new file mode 100644 index 0000000..a2f93a5 --- /dev/null +++ b/app/api/queue/import/__init__.py @@ -0,0 +1 @@ +# Makes this directory a Python package diff --git a/app/api/queue/import_/README.md b/app/api/queue/import_/README.md new file mode 100644 index 0000000..56f5d2f --- /dev/null +++ b/app/api/queue/import_/README.md @@ -0,0 +1 @@ +# Placeholder for migration diff --git a/app/api/queue/import_/__init__.py b/app/api/queue/import_/__init__.py new file mode 100644 index 0000000..a2f93a5 --- /dev/null +++ b/app/api/queue/import_/__init__.py @@ -0,0 +1 @@ +# Makes this directory a Python package diff --git a/app/api/queue/import_/apollo.py b/app/api/queue/import_/apollo.py new file mode 100644 index 0000000..f4edec4 --- /dev/null +++ b/app/api/queue/import_/apollo.py @@ -0,0 +1,29 @@ +import os +import csv +import time +from fastapi import APIRouter, HTTPException +from app.utils.make_meta import make_meta +from app.utils.db import get_db_connection_direct + +router = APIRouter() + +@router.post("/queue/import/apollo") +def import_apollo_csv() -> dict: + """POST /queue/import/apollo: Import data from apollo.csv into the queue table (template).""" + csv_path = os.path.join(os.path.dirname(__file__), "../csv/apollo/seed.csv") + if not os.path.exists(csv_path): + raise HTTPException(status_code=404, detail="seed.csv not found") + try: + conn = get_db_connection_direct() + cursor = conn.cursor() + # TODO: Implement CSV parsing and DB insertion logic for Apollo format + # Example placeholder for batch import logic: + # with open(csv_path, newline='', encoding='utf-8') as csvfile: + # reader = csv.DictReader(csvfile) + # for row in reader: + # pass # Process each row + conn.commit() + conn.close() + return {"meta": make_meta("success", "Apollo CSV import template executed"), "imported": 0} + except Exception as e: + raise HTTPException(status_code=500, detail=str(e)) diff --git a/app/api/queue/import/linkedin.py b/app/api/queue/import_/linkedin.py similarity index 100% rename from app/api/queue/import/linkedin.py rename to app/api/queue/import_/linkedin.py From 41400c0a37df4d2cedcf2a71a1355a004ebf48a3 Mon Sep 17 00:00:00 2001 From: Wei Zang Date: Sat, 18 Apr 2026 16:53:29 +0100 Subject: [PATCH 3/3] Rename import_ to csv and update import routes Refactor CSV import code by renaming the import_ package to csv and moving apollo/linkedin import modules under app/api/queue/csv. Update FastAPI route paths from /queue/import/... to /queue/csv/... and register the apollo CSV import router in app/api/queue/__init__.py. Add a placeholder CSV README and remove the old import_ package files and an obsolete test (tests/test_prompt.py). This reorganizes import endpoints for clearer CSV-related grouping. --- app/api/queue/__init__.py | 6 +- app/api/queue/csv/README.md | 1 + app/api/queue/{import => csv}/__init__.py | 0 app/api/queue/{import_ => csv}/apollo.py | 4 +- app/api/queue/{import_ => csv}/linkedin.py | 4 +- app/api/queue/import_/README.md | 1 - app/api/queue/import_/__init__.py | 1 - tests/test_prompt.py | 70 ---------------------- 8 files changed, 10 insertions(+), 77 deletions(-) create mode 100644 app/api/queue/csv/README.md rename app/api/queue/{import => csv}/__init__.py (100%) rename app/api/queue/{import_ => csv}/apollo.py (88%) rename app/api/queue/{import_ => csv}/linkedin.py (96%) delete mode 100644 app/api/queue/import_/README.md delete mode 100644 app/api/queue/import_/__init__.py delete mode 100644 tests/test_prompt.py diff --git a/app/api/queue/__init__.py b/app/api/queue/__init__.py index 1483792..3a4711f 100644 --- a/app/api/queue/__init__.py +++ b/app/api/queue/__init__.py @@ -9,7 +9,7 @@ from .routes.create import router as create_router from .routes.delete import router as delete_router -from .import_ import linkedin as linkedin_import_router +from .csv import linkedin as linkedin_import_router from .routes.alter import router as alter_router from .routes.rename_column import router as rename_router @@ -20,5 +20,9 @@ router.include_router(create_router) router.include_router(delete_router) router.include_router(linkedin_import_router.router) + +# Register Apollo CSV import route +from .csv import apollo as apollo_import_router +router.include_router(apollo_import_router.router) router.include_router(alter_router) router.include_router(rename_router) \ No newline at end of file diff --git a/app/api/queue/csv/README.md b/app/api/queue/csv/README.md new file mode 100644 index 0000000..8d5e213 --- /dev/null +++ b/app/api/queue/csv/README.md @@ -0,0 +1 @@ +# Placeholder for csv import routes diff --git a/app/api/queue/import/__init__.py b/app/api/queue/csv/__init__.py similarity index 100% rename from app/api/queue/import/__init__.py rename to app/api/queue/csv/__init__.py diff --git a/app/api/queue/import_/apollo.py b/app/api/queue/csv/apollo.py similarity index 88% rename from app/api/queue/import_/apollo.py rename to app/api/queue/csv/apollo.py index f4edec4..65c7349 100644 --- a/app/api/queue/import_/apollo.py +++ b/app/api/queue/csv/apollo.py @@ -7,9 +7,9 @@ router = APIRouter() -@router.post("/queue/import/apollo") +@router.post("/queue/csv/apollo") def import_apollo_csv() -> dict: - """POST /queue/import/apollo: Import data from apollo.csv into the queue table (template).""" + """POST /queue/csv/apollo: Import data from apollo.csv into the queue table (template).""" csv_path = os.path.join(os.path.dirname(__file__), "../csv/apollo/seed.csv") if not os.path.exists(csv_path): raise HTTPException(status_code=404, detail="seed.csv not found") diff --git a/app/api/queue/import_/linkedin.py b/app/api/queue/csv/linkedin.py similarity index 96% rename from app/api/queue/import_/linkedin.py rename to app/api/queue/csv/linkedin.py index 84365c0..77759ed 100644 --- a/app/api/queue/import_/linkedin.py +++ b/app/api/queue/csv/linkedin.py @@ -7,9 +7,9 @@ router = APIRouter() -@router.post("/queue/import/linkedin") +@router.post("/queue/csv/linkedin") def import_linkedin_csv() -> dict: - """POST /queue/import/linkedin: Import data from linkedin.csv into the queue table, robust for large files.""" + """POST /queue/csv/linkedin: Import data from linkedin.csv into the queue table, robust for large files.""" csv_path = os.path.join(os.path.dirname(__file__), "../csv/linkedin/linkedin.csv") if not os.path.exists(csv_path): raise HTTPException(status_code=404, detail="linkedin.csv not found") diff --git a/app/api/queue/import_/README.md b/app/api/queue/import_/README.md deleted file mode 100644 index 56f5d2f..0000000 --- a/app/api/queue/import_/README.md +++ /dev/null @@ -1 +0,0 @@ -# Placeholder for migration diff --git a/app/api/queue/import_/__init__.py b/app/api/queue/import_/__init__.py deleted file mode 100644 index a2f93a5..0000000 --- a/app/api/queue/import_/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# Makes this directory a Python package diff --git a/tests/test_prompt.py b/tests/test_prompt.py deleted file mode 100644 index 6fe6b49..0000000 --- a/tests/test_prompt.py +++ /dev/null @@ -1,70 +0,0 @@ -import os -import pytest -def test_llm_real_api(): - api_key = os.getenv("GEMINI_API_KEY") - if not api_key: - pytest.skip("GEMINI_API_KEY not set; skipping real LLM API test.") - from google import genai - client = genai.Client(api_key=api_key) - try: - response = client.models.generate_content( - model="models/gemini-flash-latest", - contents="Say hello from Gemini!" - ) - completion = getattr(response, "text", None) - assert completion is not None and "hello" in completion.lower() - except Exception as e: - pytest.fail(f"LLM real API call failed: {e}") -import sys -import os -sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../"))) -import pytest -from fastapi.testclient import TestClient -from app.main import app - -client = TestClient(app) - - - - -def test_llm_get_endpoint(): - api_key = os.getenv("PYTHON_KEY", "test") - response = client.get("/prompt", headers={"X-API-Key": api_key}) - assert response.status_code == 200 - data = response.json() - assert "meta" in data - assert data["meta"]["severity"] == "success" - assert "LLM" in data["meta"]["title"] - assert "records" in data["meta"]["title"] - assert "data" in data - assert "data" in data["data"] - assert isinstance(data["data"]["data"], list) - - -def test_llm_post_endpoint(monkeypatch): - # Mock google-genai SDK to avoid real API call - class MockGenAIResponse: - text = "Test completion" - - class MockGenAIModel: - def generate_content(self, model, contents): - return MockGenAIResponse() - - class MockGenAIClient: - models = MockGenAIModel() - - monkeypatch.setattr("google.genai.Client", lambda *args, **kwargs: MockGenAIClient()) - - api_key = os.getenv("PYTHON_KEY", "test") - payload = {"prompt": "Test prompt"} - response = client.post("/prompt", json=payload, headers={"X-API-Key": api_key}) - assert response.status_code == 200 - data = response.json() - assert "meta" in data - assert data["meta"]["severity"] == "success" - assert "completion received" in data["meta"]["title"] - assert data["data"]["prompt"] == "Test prompt" - assert data["data"]["completion"] == "Test completion" - assert "data" in data - assert data["data"]["prompt"] == "Test prompt" - assert data["data"]["completion"] == "Test completion"