Skip to content

Commit e380a4e

Browse files
Merge pull request #20 from goldlabelapps/staging
This pull request introduces significant refactoring and cleanup of the API endpoints, focusing on the removal of unused routes, consolidation of product-related endpoints, and improvements to metadata returned by the API.
2 parents 72acef3 + 85569ff commit e380a4e

10 files changed

Lines changed: 113 additions & 80 deletions

File tree

app/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
"""NX AI - FastAPI/Python/Postgres/tsvector"""
22

33
# Current Version
4-
__version__ = "1.0.8"
4+
__version__ = "1.0.9"

app/api/echo.py

Lines changed: 0 additions & 8 deletions
This file was deleted.

app/api/import_csv.py

Lines changed: 0 additions & 56 deletions
This file was deleted.

app/api/products/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
from .products import router
2+
from .reset import router as reset_router

app/api/products/products.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from app import __version__
22
from fastapi import APIRouter
3+
from fastapi import status
34
import os, time
45
import psycopg2
56
from dotenv import load_dotenv
@@ -39,11 +40,10 @@ def root() -> dict:
3940

4041
epoch = int(time.time() * 1000)
4142
meta = {
43+
"severity": "success",
4244
"title": "Product List",
43-
"description": "from the products Postgres table",
4445
"version": __version__,
4546
"base_url": base_url,
4647
"time": epoch,
47-
"severity": "success",
4848
}
4949
return {"meta": meta, "data": products}

app/api/products/reset.py

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import os
2+
import psycopg2
3+
from dotenv import load_dotenv
4+
from fastapi import APIRouter, status
5+
6+
router = APIRouter()
7+
8+
@router.post("/products/reset", status_code=status.HTTP_200_OK)
9+
def reset_products() -> dict:
10+
"""Delete and recreate the product table, then seed with initial data."""
11+
load_dotenv()
12+
conn = psycopg2.connect(
13+
host=os.getenv('DB_HOST'),
14+
port=os.getenv('DB_PORT', '5432'),
15+
dbname=os.getenv('DB_NAME'),
16+
user=os.getenv('DB_USER'),
17+
password=os.getenv('DB_PASSWORD')
18+
)
19+
cur = conn.cursor()
20+
# Drop and recreate table
21+
cur.execute('''
22+
DROP TABLE IF EXISTS product;
23+
CREATE TABLE product (
24+
id SERIAL PRIMARY KEY,
25+
name VARCHAR(255) NOT NULL,
26+
description TEXT,
27+
price NUMERIC(10,2) NOT NULL,
28+
in_stock BOOLEAN DEFAULT TRUE,
29+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
30+
);
31+
''')
32+
# Seed data
33+
seed_products = [
34+
("Apple", "Fresh red apple", 0.99, True),
35+
("Banana", "Organic banana", 0.59, True),
36+
("Orange", "Juicy orange", 1.29, True),
37+
]
38+
cur.executemany(
39+
"INSERT INTO product (name, description, price, in_stock) VALUES (%s, %s, %s, %s);",
40+
seed_products
41+
)
42+
conn.commit()
43+
cur.execute('SELECT id, name, description, price, in_stock, created_at FROM product;')
44+
products = [
45+
{
46+
"id": row[0],
47+
"name": row[1],
48+
"description": row[2],
49+
"price": float(row[3]),
50+
"in_stock": row[4],
51+
"created_at": row[5].isoformat() if row[5] else None
52+
}
53+
for row in cur.fetchall()
54+
]
55+
cur.close()
56+
conn.close()
57+
return {"message": "Product table reset and seeded.", "data": products}
58+
import os, time
59+
import psycopg2
60+
from dotenv import load_dotenv
61+
from app import __version__
62+
63+
router = APIRouter()
64+
65+
@router.get("/products")
66+
def root() -> dict:
67+
"""Return a structured welcome message for the API root, including product data."""
68+
load_dotenv()
69+
conn = psycopg2.connect(
70+
host=os.getenv('DB_HOST'),
71+
port=os.getenv('DB_PORT', '5432'),
72+
dbname=os.getenv('DB_NAME'),
73+
user=os.getenv('DB_USER'),
74+
password=os.getenv('DB_PASSWORD')
75+
)
76+
cur = conn.cursor()
77+
cur.execute('SELECT id, name, description, price, in_stock, created_at FROM product;')
78+
products = [
79+
{
80+
"id": row[0],
81+
"name": row[1],
82+
"description": row[2],
83+
"price": float(row[3]),
84+
"in_stock": row[4],
85+
"created_at": row[5].isoformat() if row[5] else None
86+
}
87+
for row in cur.fetchall()
88+
]
89+
cur.close()
90+
conn.close()
91+
92+
load_dotenv()
93+
base_url = os.getenv("BASE_URL", "http://localhost:8000")
94+
95+
epoch = int(time.time() * 1000)
96+
meta = {
97+
"severity": "success",
98+
"title": "Product List",
99+
"version": __version__,
100+
"base_url": base_url,
101+
"time": epoch,
102+
}
103+
return {"meta": meta, "data": products}

app/api/root.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,11 @@ def root() -> dict:
1313
base_url = os.getenv("BASE_URL", "http://localhost:8000")
1414
epoch = int(time.time() * 1000)
1515
meta = {
16+
"severity": "success",
1617
"title": "NX-AI says hi",
17-
"description": "This is the base_url",
1818
"version": __version__,
1919
"base_url": base_url,
2020
"time": epoch,
21-
"severity": "success",
22-
"message": "Welcome to NX AI!"
2321
}
2422
endpoints = [
2523
{"name": "docs", "url": f"{base_url}/docs"},

app/api/routes.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,10 @@
1212

1313
from app.api.root import router as root_router
1414
from app.api.health import router as health_router
15-
from app.api.echo import router as echo_router
16-
from app.api.import_csv import router as import_csv_router
1715
from app.api.products.products import router as products_router
16+
from app.api.products.reset import router as reset_router
1817

1918
router.include_router(root_router)
2019
router.include_router(health_router)
21-
router.include_router(echo_router)
22-
router.include_router(import_csv_router)
2320
router.include_router(products_router)
21+
router.include_router(reset_router)

app/main.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from app import __version__
2-
"""NX AI - FastAPI entry point."""
3-
2+
"""NX-AI Open Source, production ready Python FastAPI/Postgres app for NX"""
43

54
from fastapi import FastAPI
65
from fastapi.middleware.cors import CORSMiddleware
@@ -12,7 +11,7 @@
1211
from app.api.routes import router
1312

1413
app = FastAPI(
15-
title="NX AI",
14+
title="NX-AI",
1615
description="Production-ready Python FastAPI app for NX",
1716
version=__version__,
1817
)

tests/test_routes.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ def test_root_returns_welcome_message() -> None:
1717
json_data = response.json()
1818
assert "meta" in json_data
1919
assert "data" in json_data
20-
assert "message" in json_data["meta"]
21-
assert "NX AI" in json_data["meta"]["message"]
22-
20+
assert "title" in json_data["meta"]
2321

2422
def test_health_returns_ok() -> None:
2523
"""GET /health should return status ok."""

0 commit comments

Comments
 (0)