From 888a74d5edae7e9e81e085819adbcb71904f913f Mon Sep 17 00:00:00 2001 From: Goldlabel Apps Ltd Date: Thu, 19 Mar 2026 20:54:52 +0000 Subject: [PATCH 1/3] /import-csv --- app/api/import_csv.py | 56 +++++++++++++++++++++++++++++++++++++++++++ app/api/routes.py | 2 ++ 2 files changed, 58 insertions(+) create mode 100644 app/api/import_csv.py diff --git a/app/api/import_csv.py b/app/api/import_csv.py new file mode 100644 index 0000000..9ed4bc1 --- /dev/null +++ b/app/api/import_csv.py @@ -0,0 +1,56 @@ +from fastapi import APIRouter, UploadFile, File, HTTPException + +import csv +import psycopg2 +import os +import io +from dotenv import load_dotenv + +router = APIRouter() + +@router.post("/import-csv") +def import_csv(file: UploadFile = File(...)): + """Import products from a CSV file into the database.""" + load_dotenv() + conn = psycopg2.connect( + host=os.getenv('DB_HOST'), + port=os.getenv('DB_PORT', '5432'), + dbname=os.getenv('DB_NAME'), + user=os.getenv('DB_USER'), + password=os.getenv('DB_PASSWORD') + ) + cur = conn.cursor() + try: + reader = csv.DictReader(io.TextIOWrapper(file.file, encoding='utf-8')) + batch = [] + batch_size = 100 + inserted = 0 + for row in reader: + batch.append(( + row.get('name'), + row.get('description'), + float(row.get('price', 0)), + int(row.get('in_stock', 0)), + )) + if len(batch) >= batch_size: + cur.executemany( + "INSERT INTO product (name, description, price, in_stock) VALUES (%s, %s, %s, %s)", + batch + ) + conn.commit() + inserted += len(batch) + batch.clear() + if batch: + cur.executemany( + "INSERT INTO product (name, description, price, in_stock) VALUES (%s, %s, %s, %s)", + batch + ) + conn.commit() + inserted += len(batch) + return {"inserted": inserted} + except Exception as e: + conn.rollback() + raise HTTPException(status_code=500, detail=str(e)) + finally: + cur.close() + conn.close() diff --git a/app/api/routes.py b/app/api/routes.py index 285daef..34168dd 100644 --- a/app/api/routes.py +++ b/app/api/routes.py @@ -17,8 +17,10 @@ from app.api.root import router as root_router from app.api.health import router as health_router from app.api.echo import router as echo_router +from app.api.import_csv import router as import_csv_router router.include_router(root_router) router.include_router(health_router) router.include_router(echo_router) +router.include_router(import_csv_router) From 1ccfbf3ad9e29b98162b4e0b11fdebac2059a454 Mon Sep 17 00:00:00 2001 From: Goldlabel Apps Ltd Date: Fri, 20 Mar 2026 06:42:20 +0000 Subject: [PATCH 2/3] FastAPI/Python/Postgres/tsvector --- app/__init__.py | 6 +++--- app/api/root.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/__init__.py b/app/__init__.py index fc0d7ce..95cf70f 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,4 +1,4 @@ -"""NX AI - FastAPI""" +"""NX AI - FastAPI/Python/Postgres/tsvector""" -# Version tracking -__version__ = "1.0.3" +# Current Version +__version__ = "1.0.4" diff --git a/app/api/root.py b/app/api/root.py index 4db7d54..d161836 100644 --- a/app/api/root.py +++ b/app/api/root.py @@ -39,6 +39,6 @@ def root() -> dict: "time": time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), "epoch": epoch, "severity": "success", - "message": f"NX AI says hello. Returned {len(products)} products." + "message": f"NX AI says hello & returned {len(products)} products" } return {"meta": meta, "data": products} From 1b9f7c4cec2459b8384ad31d1f68f899d352a240 Mon Sep 17 00:00:00 2001 From: Goldlabel Apps Ltd Date: Fri, 20 Mar 2026 06:46:35 +0000 Subject: [PATCH 3/3] Update README: add install steps and DB notes Add a concise Install & use section with virtualenv, dependency install, and how to run the dev server (uvicorn). Clarify API URL (http://localhost:8000), call out Postgres and tsvector (fast search), tidy up feature list, and remove duplicated Install section and example echo snippet. Minor formatting/link adjustments for clarity. --- README.md | 50 +++++++++++++++++++++----------------------------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index ed8b006..a0b25d7 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,38 @@ # NX AI -> Production ready Python FastAPI/Postgres app for [NX](https://goldlabel.pro?s=nx-ai) AI services and more +> FastAPI/Python/Postgres/tsvector. Production ready Python FastAPI/Postgres app for [NX](https://goldlabel.pro?s=nx-ai) AI services and more + +## Install & use + +```bash +# Create and activate a virtual environment +python -m venv venv +source venv/bin/activate # Windows: venv\Scripts\activate + +# Install dependencies +pip install -r requirements.txt + +# Start the development server +uvicorn app.main:app --reload +``` ```sh uvicorn app.main:app pytest ``` -[localhost](http://localhost:8000) -[Public RESTful API](https://nx-ai.onrender.com) +The API is at . + +[localhost](http://localhost:8000) | [Public RESTful API](https://nx-ai.onrender.com) - **Python 3.11+** +- **Postgres** +- **tsvector** - Superfast search - **FastAPI** — RESTful API framework - **Uvicorn** — ASGI server - **Pytest** — testing framework -- **HTTPX / TestClient** — HTTP testing +- **HTTPX / TestClient** -## Docs FastAPI automatically generates interactive documentation: @@ -38,21 +54,6 @@ tests/ requirements.txt ``` -## Install - -```bash -# Create and activate a virtual environment -python -m venv venv -source venv/bin/activate # Windows: venv\Scripts\activate - -# Install dependencies -pip install -r requirements.txt - -# Start the development server -uvicorn app.main:app --reload -``` - -The API will be available at . ## Endpoints @@ -62,13 +63,4 @@ The API will be available at . | GET | `/health` | Health check — returns `ok` | | POST | `/echo` | Echoes the JSON `message` field | -### Example — Echo - -```bash -curl -X POST http://localhost:8000/echo \ - -H "Content-Type: application/json" \ - -d '{"message": "hello"}' -# {"echo":"hello"} -``` -