Skip to main content

PostgreSQL-native semantic search engine with multi-modal support (Beta)

Project description

Pany

โš ๏ธ Beta Software: This is early-stage software. API may change between versions before v1.0.0.

Semantic search that works inside PostgreSQL. Upload documents and images, then search them with natural language.

Instead of setting up a separate vector database like Pinecone or Weaviate, Pany uses your existing PostgreSQL database with the pgvector extension.

๐Ÿ“– Technical Architecture - Detailed system design and implementation

Install and Run

pip install pany
pany

Go to http://localhost:8000 to upload files and start searching.

Requirements

  • Python 3.9+
  • PostgreSQL with pgvector extension
  • 4GB RAM minimum

Configuration

# Custom database
export DATABASE_URL="postgresql://user:pass@localhost:5432/mydb"

# Custom port
pany --port 8080

# Or use Docker
git clone https://github.com/laxmanclo/pany.cloud.git
cd pany.cloud
docker-compose up -d

What it does

Upload stuff: Drop PDFs, images, text files into the web interface Search naturally: Type "find the red car" or "contract with Microsoft" Get results: Finds semantically similar content, not just keyword matches

Works with text and images. You can search for images using text descriptions, or upload an image to find similar ones.

Code Examples

from pany import PanyClient

client = PanyClient()

# Upload files
client.upload_file("product_catalog.pdf", project_id="store")
client.upload_file("car_photo.jpg", project_id="store")

# Search with text
results = client.search("red sedan", project_id="store")

# Search with image
results = client.search_by_image("my_car.jpg", project_id="store")

SQL Integration

The main advantage over other vector databases is that you can join search results with your existing data:

SELECT 
    products.name, 
    products.price, 
    search.similarity_score
FROM products 
JOIN semantic_search('comfortable shoes', 0.7) search 
    ON products.id = search.content_id
WHERE products.in_stock = true
ORDER BY search.similarity_score DESC;

This is impossible with most vector databases because they're separate systems.

Why PostgreSQL?

Because you probably already have PostgreSQL running your app. Instead of:

  1. Setting up another database (Pinecone, Weaviate, etc.)
  2. Keeping data in sync between systems
  3. Learning new APIs and query languages
  4. Paying monthly fees

You just add pgvector to your existing database and you're done. contact me for another db: laxmansrivastacc@gmail.com(a simple mail works, come on call or anything of the sort.)

API

REST endpoints for integration:

# Upload content
curl -X POST http://localhost:8000/embeddings \
  -F "file=@document.pdf" \
  -F "project_id=myproject"

# Search
curl -X POST http://localhost:8000/search \
  -H "Content-Type: application/json" \
  -d '{"query": "find something", "project_id": "myproject"}'

How it works

  1. Embedding: Uses CLIP model to convert text and images into vectors
  2. Storage: Saves vectors in PostgreSQL using pgvector extension
  3. Search: Finds similar vectors using cosine similarity
  4. Results: Returns content ranked by similarity score

The CLIP model means you can search across different types of content - find images with text queries, or text with image queries.

Common use cases

  • Product search: Upload product catalog, let customers search "red leather shoes"
  • Document management: Search PDFs and docs with natural language
  • Media libraries: Find images by describing what's in them
  • Knowledge bases: Semantic search through support docs

Environment variables

DATABASE_URL="postgresql://user:pass@host:5432/db"
HOST="0.0.0.0"
PORT="8000" 
EMBEDDING_MODEL="all-MiniLM-L6-v2"
OPENAI_API_KEY="sk-..."  # optional
UPLOAD_DIR="./uploads"

Development

git clone https://github.com/laxmanclo/pany.cloud.git
cd pany.cloud
pip install -r requirements.txt
python -m pany.main

Run tests: pytest tests/

Contributing

Fork the repo, make changes, submit PR.

Code style: use Black formatter, add type hints, write tests.

License

MIT License

Issues

Report bugs at https://github.com/laxmanclo/pany.cloud/issues

Contact: laxmansrivastacc@gmail.com

Results: [{"name": "Red Nike Air Max", "similarity": 0.89}, ...]

**ROI**: 15-25% conversion rate increase = $50k-200k/year additional revenue

### **Customer Support: Instant Knowledge Base**
**Problem**: Agents spend 10+ minutes finding answers, customers wait
**Solution**: Semantic search across all documentation
```sql
-- Find answers across all support docs
SELECT document, answer, similarity 
FROM semantic_search('password reset not working', 'support_docs')
WHERE similarity > 0.8;

ROI: 60% faster resolution time = 2-3 additional customers served per hour

Legal/HR: Document Discovery

Problem: Lawyers bill $500/hour searching through contracts Solution: Natural language search across all legal documents

# Find all contracts mentioning liability clauses
results = pany.search("liability and insurance provisions", project="legal")

ROI: Save 20 hours/week = $10k/week = $520k/year savings

Real Estate: Property Matching

Problem: Clients describe dream home, agents manually search listings Solution: Semantic search combining text + property images

# "Modern kitchen with granite countertops near good schools"
results = pany.search(client_description, project="listings")

ROI: 3x faster property matching = serve 3x more clients

๐Ÿ—๏ธ Architecture: PostgreSQL + CLIP + FastAPI

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   Web Widget    โ”‚    โ”‚   FastAPI        โ”‚    โ”‚  PostgreSQL     โ”‚
โ”‚   Dashboard     โ”‚โ—„โ”€โ”€โ–บโ”‚   + CLIP Model   โ”‚โ—„โ”€โ”€โ–บโ”‚  + pgvector     โ”‚
โ”‚   REST API      โ”‚    โ”‚   Embedding Gen  โ”‚    โ”‚   Vector Store  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Why This Stack Wins:

  • PostgreSQL: ACID compliance, backups, joins, familiar
  • CLIP: Multi-modal embeddings (text โ†” images)
  • FastAPI: Modern async Python, auto-documentation
  • Docker: One-command deployment anywhere

๐Ÿ“Š Performance

Benchmarks (tested on 4-core, 8GB RAM)

  • Upload speed: ~2MB/sec document processing
  • Throughput: 100+ concurrent searches
  • Storage: ~1KB per document embedding
  • Accuracy: 85-95% relevance for semantic queries

Scaling Guidelines

  • Small team (1-10 users): 2GB RAM, 2 cores
  • Medium business (10-100 users): 8GB RAM, 4 cores
  • Large organization (100+ users): 16GB+ RAM, 8+ cores
  • Database: Scales linearly with PostgreSQL

๐Ÿ”ง Configuration

Environment Variables

# Database
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_DB=pany
POSTGRES_USER=pany
POSTGRES_PASSWORD=your-secure-password

# API
API_HOST=0.0.0.0
API_PORT=8000
MAX_FILE_SIZE_MB=50

# Embeddings
EMBEDDING_MODEL=clip-ViT-B-32
VECTOR_DIMENSIONS=512

Custom Embeddings

# embedding-service/services/custom_embedding.py
from sentence_transformers import SentenceTransformer

class CustomEmbeddingService:
    def __init__(self):
        self.model = SentenceTransformer('your-custom-model')
    
    def embed_text(self, text: str) -> List[float]:
        return self.model.encode(text).tolist()

Integrations

Website Widget

// Minimal integration
<script src="http://your-domain/widget.js"></script>
<div id="pany-search"></div>

// Custom styling
<script>
  PanyWidget.init({
    container: '#my-search',
    placeholder: 'Search our knowledge base...',
    theme: 'dark',
    maxResults: 10
  });
</script>

React Component

import { PanySearch } from '@pany/react';

function App() {
  return (
    <PanySearch 
      apiUrl="http://localhost:8000"
      projectId="my-project"
      placeholder="Search documents..."
    />
  );
}

Python SDK

from pany import PanyClient

client = PanyClient(base_url="http://localhost:8000")

# Upload file
result = client.upload_file("document.pdf", project_id="my-project")

# Search
results = client.search("password reset instructions", project_id="my-project")

๐Ÿš€ Deployment

Docker Compose (Recommended)

version: '3.8'
services:
  pany-api:
    image: pany/pany:latest
    ports:
      - "8000:8000"
    environment:
      - POSTGRES_HOST=postgres
    depends_on:
      - postgres
  
  postgres:
    image: pgvector/pgvector:pg15
    environment:
      POSTGRES_DB: pany
      POSTGRES_USER: pany
      POSTGRES_PASSWORD: secure-password
    volumes:
      - postgres_data:/var/lib/postgresql/data

Kubernetes

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pany-api
spec:
  replicas: 3
  selector:
    matchLabels:
      app: pany-api
  template:
    metadata:
      labels:
        app: pany-api
    spec:
      containers:
      - name: pany-api
        image: pany/pany:latest
        ports:
        - containerPort: 8000

Production Checklist

  • Configure secure database passwords
  • Set up SSL/TLS certificates
  • Configure reverse proxy (nginx/traefik)
  • Set up monitoring and logging
  • Configure backup strategy
  • Set resource limits and scaling rules
Do star :D and support if it made your life easier, and also report issues, and always welcome to fix whats broken :)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pany-0.1.0.tar.gz (49.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pany-0.1.0-py3-none-any.whl (31.4 kB view details)

Uploaded Python 3

File details

Details for the file pany-0.1.0.tar.gz.

File metadata

  • Download URL: pany-0.1.0.tar.gz
  • Upload date:
  • Size: 49.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.9

File hashes

Hashes for pany-0.1.0.tar.gz
Algorithm Hash digest
SHA256 e92df699012727da21e8b8bd8576e333943ede3fd4cfc18157f25d89f9af7773
MD5 7fe70ecaa9cce457b96be864b6d58da1
BLAKE2b-256 e2c82d2a4338dab9eed2c7acdbcb666a5bffa5a80e1397d121d439a389cb0178

See more details on using hashes here.

File details

Details for the file pany-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: pany-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 31.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.9

File hashes

Hashes for pany-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c519a2eadee115a5bf6ddf482447cb05f62e9d067cc44e3db60a31f6ac1cdc72
MD5 2d713457814a98baf84fa36283d77d91
BLAKE2b-256 bbbb6e438faae8d64424b3c39fafb6157d00cee45d8dbeb9c875fc1baf74ccbe

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page