Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 85 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,65 +1,119 @@
## ![Python](/app/static/repoicon.png) Python
## Python FastAPI/Postgres App

> With FastAPI using Postgres & tsvector.
**Production-ready, open-source FastAPI application with PostgreSQL and blazing-fast full-text search.**

Open Source, production ready Python FastAPI/Postgres app.
---

[GitHub](https://github.com/goldlabelapps/python) |
[onr]Render](https://nx-ai.onrender.com) |
[by Goldlabel](https://goldlabel.pro)
### 🚀 Features

- **Python 3.11+**
- **Postgres**
- **tsvector** - Superfast full-text search (with GIN index)
- **FastAPI** — Modern, high-performance REST API
- **PostgreSQL** — Robust relational database
- **tsvector + GIN** — Superfast full-text search
- **Uvicorn** — Lightning-fast ASGI server
- **Pytest** — Comprehensive testing

```sh
uvicorn app.main:app --reload
```
---

## Project Overview

This project provides a scalable API backend using FastAPI and PostgreSQL, featuring:

#### Install
- Automatic full-text search on all text fields (via tsvector)
- Endpoints for health checks, product management, prompt handling, and prospect management
- Efficient ingestion and processing of large CSV files

Create an environment file and add Postgres credentials etc
---

`cp .env.sample .env`
## Getting Started

### 1. Clone & Setup Environment

```bash
git clone <repo-url>
cd python
cp .env.sample .env # Add your Postgres credentials and settings
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
```

### 2. Run the App

```bash
uvicorn app.main:app --reload
```

[localhost](http://localhost:8000) | [onrender](https://nx-ai.onrender.com)
Visit [localhost:8000](http://localhost:8000) or [onrender](https://nx-ai.onrender.com)

---

### Full-Text Search (tsvector)
## API Documentation

The prospects table includes a `search_vector` column (type: tsvector) that is automatically computed from all text fields on insert. A GIN index is created for this column, enabling fast and scalable full-text search queries.
FastAPI auto-generates interactive docs:

**How it works:**
- [Swagger UI](http://localhost:8000/docs)
- [ReDoc](http://localhost:8000/redoc)

- On every insert or update, the `search_vector` is computed from all text columns using PostgreSQL's `to_tsvector('english', ...)`.
- The GIN index (`idx_prospects_search_vector`) allows efficient search queries like:
---

## Full-Text Search (tsvector)

The `prospects` table includes a `search_vector` column (type: tsvector) computed from all text fields on insert/update. A GIN index enables fast, scalable full-text search:

```sql
SELECT * FROM prospects WHERE search_vector @@ plainto_tsquery('english', 'search terms');
```

This makes searching across all text fields in the prospects table extremely fast, even for large datasets.
- **FastAPI** — RESTful API framework
- **Uvicorn** — ASGI server
- **Pytest** — testing framework
- **HTTPX / TestClient**
**How it works:**
- On every insert/update, `search_vector` is computed using PostgreSQL's `to_tsvector('english', ...)`.
- The GIN index (`idx_prospects_search_vector`) enables efficient search across large datasets.

---

## Processing Large CSV Files

The `/prospects/process` endpoint supports robust ingestion of large CSVs (e.g., 1300+ rows, 300KB+), following the same normalization and insertion pattern as `/prospects/seed` but optimized for scale.

---

## Directory Structure

```
app/
main.py # FastAPI entrypoint
api/ # API endpoints & schemas
health.py
root.py
routes.py
products/
prompts/
prospects/
resend/
utils/
static/ # Static assets (e.g., repoicon.png)
utils/ # Utility scripts
tests/ # Pytest test suite
requirements.txt # Python dependencies
render.yaml # Deployment config (Render.com)
```

---

## Contributing

Contributions are welcome! Please open issues or submit pull requests.

---

#### Docs
## License

FastAPI automatically generates interactive documentation:
This project is licensed under the MIT License. See [LICENSE](LICENSE) for details.

- Swagger UI: <http://localhost:8000/docs>
- ReDoc: <http://localhost:8000/redoc>
---

### Processing Large CSV Files
## Contact

The `/prospects/process` endpoint is designed for robust, scalable ingestion of large CSV files (e.g., 1300+ rows, 300KB+). It follows the same normalization and insertion pattern as `/prospects/seed`, but is optimized for large files:
For questions or support, open an issue or contact the maintainer.


2 changes: 1 addition & 1 deletion app/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Python - FastAPI, Postgres, tsvector"""

# Current Version
__version__ = "2.0.8"
__version__ = "2.1.1"
20 changes: 20 additions & 0 deletions app/api/prospects/database/reset_flag_and_hide.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Script to reset all 'flag' and 'hide' values to false in the prospects table
from app.utils.db import get_db_connection

def reset_flag_and_hide():
conn_gen = get_db_connection()
conn = next(conn_gen)
cur = conn.cursor()
try:
cur.execute("UPDATE prospects SET flag = FALSE, hide = FALSE;")
conn.commit()
print("All 'flag' and 'hide' values reset to FALSE.")
except Exception as e:
print(f"Error: {e}")
conn.rollback()
finally:
cur.close()
conn.close()

if __name__ == "__main__":
reset_flag_and_hide()
4 changes: 2 additions & 2 deletions app/utils/make_meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ def make_meta(severity: str, title: str) -> dict:
"version": __version__,
"time": epoch,
"severity": severity,
"message": title,
"base_url": base_url,
"title": title,
"base": base_url,
}
31 changes: 0 additions & 31 deletions tests/prospects/test_prospects.py

This file was deleted.

28 changes: 28 additions & 0 deletions tests/test_prospects.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import pytest
from fastapi.testclient import TestClient
from app.main import app

client = TestClient(app)

def test_get_prospects_root():
response = client.get("/prospects")
assert response.status_code == 200
data = response.json()
assert "meta" in data
assert "data" in data
assert isinstance(data["data"], list)
# Check that the expected keys are present in the data list
assert any("init" in item for item in data["data"])
assert any("search" in item for item in data["data"])
# Meta checks
meta = data["meta"]
assert meta["severity"] == "success"
assert meta["title"] == "Prospects endpoint"

def test_prospects_returns_list():
response = client.get("/prospects")
assert response.status_code == 200
data = response.json()
assert "meta" in data
assert "data" in data
assert isinstance(data["data"], list) or isinstance(data["data"], dict)
Loading