Skip to content

Commit ec7a05f

Browse files
Merge pull request #28 from goldlabelapps/staging
This pull request updates the prospects API endpoints, focusing on simplifying and clarifying the `/prospects` and `/prospects/init` endpoints. I
2 parents c1f1be9 + b0974a8 commit ec7a05f

4 files changed

Lines changed: 68 additions & 91 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.1.3"
4+
__version__ = "1.1.5"

app/api/prospects/prospects.py

Lines changed: 67 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -7,78 +7,81 @@
77
router = APIRouter()
88

99

10-
# Endpoint to get unique values for specified fields
11-
from fastapi import Query
10+
@router.get("/prospects")
11+
def root() -> dict:
12+
"""Return a placeholder message for prospects endpoint."""
13+
meta = make_meta("success", "Prospects placeholder")
14+
data = {"message": "This is a placeholder for the /prospects endpoint."}
15+
return {"meta": meta, "data": data}
1216

13-
@router.get("/prospects/unique")
14-
def get_unique_fields(fields: list[str] = Query(..., description="List of field names to get unique values for")) -> dict:
15-
"""Return lists of unique values and their counts for specified fields in the prospects table."""
16-
conn_gen = get_db_connection()
17-
conn = next(conn_gen)
18-
cur = conn.cursor()
19-
result = {}
20-
errors = {}
21-
try:
22-
for field in fields:
23-
try:
24-
cur.execute(f'SELECT "{field}", COUNT(*) FROM prospects WHERE "{field}" IS NOT NULL GROUP BY "{field}" ORDER BY COUNT(*) DESC;')
25-
values = [
26-
{"value": row[0], "count": row[1]} for row in cur.fetchall()
27-
]
28-
result[field] = values
29-
except Exception as e:
30-
errors[field] = str(e)
31-
meta = make_meta("success", f"Unique values and counts for fields: {fields}")
32-
return {"meta": meta, "data": result, "errors": errors if errors else None}
33-
finally:
34-
cur.close()
35-
conn.close()
3617

18+
# New endpoint: /prospects/init
3719

38-
@router.get("/prospects")
39-
def root() -> dict:
40-
"""Return all prospects table records"""
41-
base_url = os.getenv("BASE_URL", "http://localhost:8000")
20+
@router.get("/prospects/init")
21+
def prospects_init() -> dict:
22+
"""Initialize prospects and return real total count."""
23+
meta = make_meta("success", "Initialized prospects")
4224
conn_gen = get_db_connection()
4325
conn = next(conn_gen)
4426
cur = conn.cursor()
45-
actions = [
46-
{
47-
"name": "Seed prospects table",
48-
"url": f"{base_url}/prospects/seed"
49-
},
50-
{
51-
"name": "Empty prospects table",
52-
"url": f"{base_url}/prospects/empty"
53-
},
54-
]
27+
title = []
28+
total_unique_title = 0
29+
seniority = []
30+
total_unique_seniority = 0
31+
sub_departments = []
32+
total_unique_sub_departments = 0
5533
try:
56-
cur.execute('SELECT * FROM prospects LIMIT 200;')
57-
if cur.description is None:
58-
prospects = []
59-
else:
60-
columns = [desc[0] for desc in cur.description]
61-
prospects = [dict(zip(columns, row)) for row in cur.fetchall()]
62-
meta = make_meta("success", "Prospects List (max 200)")
63-
result = {"meta": meta, "data": prospects}
64-
except Exception as e:
65-
import psycopg2
66-
if isinstance(e, psycopg2.errors.UndefinedTable):
67-
meta = make_meta("error", "prospects table does not exist.")
68-
result = {"meta": meta, "data": actions}
69-
else:
70-
meta = make_meta("error", str(e))
71-
result = {"meta": meta, "data": actions}
34+
cur.execute('SELECT COUNT(*) FROM prospects;')
35+
row = cur.fetchone()
36+
total = row[0] if row is not None else 0
37+
38+
# Get unique titles and their counts (column is 'title')
39+
cur.execute('SELECT title, COUNT(*) FROM prospects WHERE title IS NOT NULL GROUP BY title ORDER BY COUNT(*) DESC;')
40+
title_rows = cur.fetchall()
41+
title = [
42+
{"label": t[0], "count": t[1]} for t in title_rows if t[0] is not None
43+
]
44+
total_unique_title = len(title)
45+
46+
# Get unique seniority and their counts (column is 'seniority')
47+
cur.execute('SELECT seniority, COUNT(*) FROM prospects WHERE seniority IS NOT NULL GROUP BY seniority ORDER BY COUNT(*) DESC;')
48+
seniority_rows = cur.fetchall()
49+
seniority = [
50+
{"label": s[0], "count": s[1]} for s in seniority_rows if s[0] is not None
51+
]
52+
total_unique_seniority = len(seniority)
53+
54+
# Get unique sub_departments and their counts (column is 'sub_departments')
55+
cur.execute('SELECT sub_departments, COUNT(*) FROM prospects WHERE sub_departments IS NOT NULL GROUP BY sub_departments ORDER BY COUNT(*) DESC;')
56+
sub_department_rows = cur.fetchall()
57+
sub_departments = [
58+
{"label": sd[0], "count": sd[1]} for sd in sub_department_rows if sd[0] is not None
59+
]
60+
total_unique_sub_departments = len(sub_departments)
61+
except Exception:
62+
total = 0
63+
title = []
64+
total_unique_title = 0
65+
seniority = []
66+
total_unique_seniority = 0
67+
sub_departments = []
68+
total_unique_sub_departments = 0
7269
finally:
7370
cur.close()
7471
conn.close()
75-
return result
76-
77-
78-
# New endpoint: /prospects/init
79-
@router.get("/prospects/init")
80-
def prospects_init() -> dict:
81-
"""Initialize prospects (placeholder endpoint)"""
82-
meta = make_meta("success", "Initialized prospects (placeholder)")
83-
data = {"message": "This is a placeholder for prospects/init."}
72+
data = {
73+
"total_prospects": total,
74+
"title": {
75+
"total_unique": total_unique_title,
76+
"values": title
77+
},
78+
"seniority": {
79+
"total_unique": total_unique_seniority,
80+
"values": seniority
81+
},
82+
"departments": {
83+
"total_unique": total_unique_sub_departments,
84+
"values": sub_departments
85+
}
86+
}
8487
return {"meta": meta, "data": data}

tests/prospects/test_prospects.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,6 @@ def test_prospects_returns_list():
2323
assert "data" in data
2424
assert isinstance(data["data"], list) or isinstance(data["data"], dict)
2525

26-
def test_prospects_unique_valid_fields():
27-
# This test assumes at least one valid field exists in the prospects table, e.g., 'id'.
28-
response = client.get("/prospects/unique?fields=id")
29-
assert response.status_code == 200
30-
data = response.json()
31-
assert "meta" in data
32-
assert "data" in data
33-
assert isinstance(data["data"], dict)
34-
35-
def test_prospects_unique_invalid_field():
36-
response = client.get("/prospects/unique?fields=notafield")
37-
assert response.status_code == 200
38-
data = response.json()
39-
assert "meta" in data
40-
assert "errors" in data
41-
assert "notafield" in data["errors"]
4226

4327
def test_prospects_init_meta_keys():
4428
response = client.get("/prospects/init")

tests/test_routes.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,3 @@ def test_health_returns_ok() -> None:
2222
assert response.status_code == 200
2323
assert response.json() == {"status": "ok"}
2424

25-
26-
def test_products_returns_list() -> None:
27-
"""GET /prospects should return a list of prospects (possibly empty)."""
28-
response = client.get("/prospects")
29-
assert response.status_code == 200
30-
json_data = response.json()
31-
assert "meta" in json_data
32-
assert "data" in json_data
33-
assert isinstance(json_data["data"], list)
34-

0 commit comments

Comments
 (0)