Metadata-Version: 2.4
Name: prompt-to-query
Version: 1.0.7
Summary: High-performance SDK to convert natural language prompts to MongoDB queries using AI (OpenAI GPT or Anthropic Claude)
Home-page: https://github.com/dimarborda/prompt-to-query
Author: Dimar Borda
Author-email: Dimar Borda <dimarborda@gmail.com>
License: MIT
Project-URL: Homepage, https://github.com/dimarb/prompt-to-query
Project-URL: Documentation, https://github.com/dimarb/prompt-to-query#readme
Project-URL: Repository, https://github.com/dimarb/prompt-to-query
Project-URL: Bug Tracker, https://github.com/dimarb/prompt-to-query/issues
Keywords: mongodb,query,natural-language,nlp,ai,llm,openai,gpt,gpt-4,anthropic,claude,database,text-to-query,prompt-engineering,sdk
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Database
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: OS Independent
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Dynamic: author
Dynamic: home-page
Dynamic: requires-python

# Prompt to Query - Python SDK

[![PyPI version](https://badge.fury.io/py/prompt-to-query.svg)](https://pypi.org/project/prompt-to-query/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Python](https://img.shields.io/badge/Python-3.8+-blue?logo=python&logoColor=white)](https://www.python.org)

SDK de alto rendimiento para convertir lenguaje natural en queries de MongoDB usando IA (OpenAI GPT o Anthropic Claude).

## Características

- **Alto Rendimiento**: Core nativo en Go con bindings Python para máxima velocidad
- **Multiplataforma**: Soporta Linux, macOS y Windows (AMD64 y ARM64)
- **Múltiples LLMs**: Compatible con OpenAI (GPT-4, GPT-3.5) y Anthropic (Claude)
- **Sin Dependencias Externas**: Usa solo la librería estándar de Python (ctypes)
- **Detección de Columnas**: Genera automáticamente títulos legibles para las columnas de resultados
- **Fácil de Usar**: API simple y consistente

## Instalación

```bash
pip install prompt-to-query
```

## Requisitos

- Python >= 3.8 (recomendado >= 3.10)
- Una API key de OpenAI o Anthropic
- Las librerías nativas se incluyen para las siguientes plataformas:
  - Linux (AMD64, ARM64) - glibc y musl (Alpine)
  - macOS (AMD64/Intel, ARM64/Apple Silicon)
  - Windows (AMD64)

**Nota técnica**: Este paquete usa `ctypes` de la librería estándar de Python para FFI (Foreign Function Interface), lo que significa cero dependencias externas.

## Uso Rápido

### Uso Básico

```python
from prompt_to_query import PromptToQuery

# Inicializar el SDK
ptq = PromptToQuery(
    llm_provider="openai",  # o "anthropic"
    api_key="your-api-key",
    db_schema_path="schema.json"
)

# Generar query desde lenguaje natural
result = ptq.generate_query("Get all active users from last month")

print(result['query'])
# Output: {'operation': 'find', 'collection': 'users', 'filter': {...}}

print(result['columnTitles'])
# Output: ['User Name', 'Email', 'Status', 'Created At']

# Obtener versión del SDK
print(ptq.get_version())
```

### Uso con Variables de Entorno

```python
import os
from prompt_to_query import PromptToQuery

ptq = PromptToQuery(
    llm_provider="openai",
    api_key=os.getenv("OPENAI_API_KEY"),
    db_schema_path="./schema.json"
)

try:
    result = ptq.generate_query('Count orders from last week')
    print('Query:', result['query'])
    print('Columns:', result['columnTitles'])
except Exception as e:
    print(f'Error: {e}')
```

## Configuración

### Opciones del Constructor

```python
PromptToQuery(
    llm_provider: str,        # 'openai' o 'anthropic' (requerido)
    api_key: str,            # Tu API key (requerido)
    db_schema: dict = None,  # Esquema de DB como diccionario (opcional)
    db_schema_path: str = None,  # Path al archivo JSON del esquema (opcional)
    model: str = None,       # Modelo específico a usar (opcional)
    lib_path: str = None     # Path personalizado a la librería nativa (opcional)
)
```

**Nota**: Debes proporcionar o bien `db_schema` o bien `db_schema_path`.

### Esquema de Base de Datos

Crea un archivo `schema.json` que describa tu base de datos MongoDB:

```json
{
  "users": {
    "fields": {
      "name": "string",
      "email": "string",
      "status": "string",
      "created_at": "date",
      "last_login": "date"
    }
  },
  "products": {
    "fields": {
      "name": "string",
      "price": "number",
      "category": "string",
      "stock": "number"
    }
  }
}
```

## API

### `PromptToQuery(config)`

Crea una nueva instancia del SDK.

**Parámetros:**
- `llm_provider` (str): Proveedor de LLM - 'openai' o 'anthropic'
- `api_key` (str): Tu API key
- `db_schema` (dict, opcional): Esquema de base de datos como diccionario
- `db_schema_path` (str, opcional): Path al archivo JSON del esquema
- `model` (str, opcional): Modelo específico a usar
- `lib_path` (str, opcional): Path personalizado a la librería nativa

**Raises:**
- `Exception`: Si la inicialización falla o la configuración es inválida

### `generate_query(prompt: str) -> dict`

Genera una query de MongoDB desde un prompt en lenguaje natural.

**Parámetros:**
- `prompt` (str): Descripción en lenguaje natural de la query deseada

**Returns:**
- `dict`: Diccionario con las siguientes claves:
  - `query`: Diccionario de query de MongoDB con:
    - `operation`: "find", "aggregate", o "count"
    - `collection`: Nombre de la colección
    - `filter`: Filtro de query (para find/count)
    - `pipeline`: Pipeline de agregación (para aggregate)
    - `projection`, `sort`, `limit`, `skip`: Parámetros opcionales
  - `columnTitles`: Lista de strings con títulos legibles para las columnas

**Raises:**
- `Exception`: Si la generación de query falla

**Ejemplo:**

```python
result = ptq.generate_query('Top 10 products by price')
print(result['query'])
# {
#   'operation': 'find',
#   'collection': 'products',
#   'sort': {'price': -1},
#   'limit': 10
# }

print(result['columnTitles'])
# ['Product Name', 'Price', 'Category', 'Stock']
```

### `explain_query(query: dict, original_prompt: str) -> dict`

Explica una query de MongoDB generada y proporciona sugerencias de optimización.

**Parámetros:**
- `query` (dict): Diccionario de query de MongoDB (del resultado de `generate_query`)
- `original_prompt` (str): El prompt original en lenguaje natural usado para generar la query

**Returns:**
- `dict`: Diccionario con las siguientes claves:
  - `explanation` (str): Explicación en lenguaje natural de lo que hace la query
  - `performanceHints` (list): Lista de sugerencias para mejorar el rendimiento
  - `optimizationTips` (list): Lista de consejos para obtener mejores resultados
  - `promptSuggestions` (list): Sugerencias para mejorar el prompt original y evitar ambigüedades
  - `indexUsage` (dict): Información sobre el uso de índices
    - `usesIndexes` (bool): Si la query usa índices
    - `indexes` (list): Lista de índices utilizados
    - `recommendation` (str): Recomendaciones de índices
  - `alternativeQueries` (list): Enfoques alternativos para la query
  - `complexity` (str): Complejidad de la query ("low", "medium", "high")
  - `estimatedCost` (str): Costo estimado de ejecución ("low", "medium", "high")

**Raises:**
- `Exception`: Si la explicación falla

**Ejemplo:**

```python
result = ptq.generate_query('Get top 10 products by price')
explanation = ptq.explain_query(result['query'], 'Get top 10 products by price')
print(explanation['explanation'])
# "This query retrieves the top 10 products sorted by price in descending order..."
print(explanation['performanceHints'])
# ["Consider adding an index on the 'price' field for faster sorting"]
```

### `get_version() -> str`

Obtiene la versión del SDK.

**Returns:**
- `str`: String de versión

## Ejemplos

### Ejemplo 1: Query Simple

```python
result = ptq.generate_query('Get all active users')
print(result['query'])
# {'operation': 'find', 'collection': 'users', 'filter': {'status': 'active'}}

print(result['columnTitles'])
# ['Name', 'Email', 'Status', 'Created At']
```

### Ejemplo 2: Query con Filtros Complejos

```python
result = ptq.generate_query(
    'Find products with price greater than 100 dollars'
)
print(result['query'])
# {
#   'operation': 'find',
#   'collection': 'products',
#   'filter': {'price': {'$gt': 100}}
# }

print(result['columnTitles'])
# ['Product Name', 'Price', 'Category']
```

### Ejemplo 3: Query de Agregación

```python
result = ptq.generate_query(
    'Get top 10 products by sales with their categories'
)
print(result['query'])
# {
#   'operation': 'aggregate',
#   'collection': 'products',
#   'pipeline': [
#     {'$sort': {'sales': -1}},
#     {'$limit': 10},
#     {'$project': {'name': 1, 'sales': 1, 'category': 1}}
#   ]
# }

print(result['columnTitles'])
# ['Product Name', 'Sales', 'Category']
```

### Ejemplo 4: Query de Conteo

```python
result = ptq.generate_query('Count orders from last month')
print(result['query'])
# {
#   'operation': 'count',
#   'collection': 'orders',
#   'filter': {'created_at': {'$gte': '...'}}
# }

print(result['columnTitles'])
# ['Total Orders']
```

### Ejemplo 5: Explicar y Optimizar Queries

```python
result = ptq.generate_query('Get top 10 products by price')

# Obtener explicación y sugerencias
explanation = ptq.explain_query(result['query'], 'Get top 10 products by price')

print(explanation['explanation'])
# "Esta query recupera los 10 productos principales ordenados por precio en orden descendente..."

print(explanation['performanceHints'])
# ["Considera agregar un índice en el campo 'price' para un ordenamiento más rápido",
#  "El campo 'price' ya tiene un índice, la query será eficiente"]

print(explanation['optimizationTips'])
# ["Para resultados más específicos, considera agregar filtros por categoría",
#  "Puedes usar projection para limitar los campos devueltos"]

print(explanation['indexUsage'])
# {
#   'usesIndexes': True,
#   'indexes': ['price'],
#   'recommendation': "El índice existente en 'price' está siendo utilizado correctamente"
# }

print(explanation['complexity'])  # "low"
print(explanation['estimatedCost'])  # "low"

# Las alternativas están disponibles si el LLM las sugiere
if explanation['alternativeQueries']:
    print("Enfoques alternativos:")
    for alt in explanation['alternativeQueries']:
        print(f"  - {alt}")
```

### Ejemplo 6: Manejo de Errores

```python
try:
    result = ptq.generate_query('invalid query')
    print(result['query'])
    print(result['columnTitles'])
except Exception as e:
    print(f'Error del SDK: {e}')
```

## Uso con Docker

El SDK es totalmente compatible con Docker y soporta tanto Alpine Linux (musl) como distribuciones basadas en Debian/Ubuntu (glibc).

### Docker con Alpine Linux

```dockerfile
FROM python:3.11-alpine

WORKDIR /app

# Copiar archivos de requirements
COPY requirements.txt .

# Instalar dependencias
RUN pip install --no-cache-dir -r requirements.txt

# Copiar código de la aplicación
COPY . .

# Variables de entorno
ENV OPENAI_API_KEY=your-api-key

CMD ["python", "app.py"]
```

### Docker con Ubuntu/Debian

```dockerfile
FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

ENV OPENAI_API_KEY=your-api-key

CMD ["python", "app.py"]
```

### Docker Multi-stage Build

Para optimizar el tamaño de la imagen:

```dockerfile
# Build stage
FROM python:3.11-alpine AS builder

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --user -r requirements.txt

# Production stage
FROM python:3.11-alpine

WORKDIR /app

# Copiar solo las dependencias instaladas
COPY --from=builder /root/.local /root/.local
COPY . .

# Asegurar que los scripts en .local están en PATH
ENV PATH=/root/.local/bin:$PATH
ENV PYTHONUNBUFFERED=1
ENV OPENAI_API_KEY=your-api-key

CMD ["python", "app.py"]
```

### Docker Compose

```yaml
version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    environment:
      - OPENAI_API_KEY=${OPENAI_API_KEY}
      - PYTHONUNBUFFERED=1
    volumes:
      - ./schema.json:/app/schema.json:ro
    ports:
      - "8000:8000"
    restart: unless-stopped

  mongodb:
    image: mongo:7
    environment:
      - MONGO_INITDB_ROOT_USERNAME=admin
      - MONGO_INITDB_ROOT_PASSWORD=password
    volumes:
      - mongo-data:/data/db
    ports:
      - "27017:27017"

volumes:
  mongo-data:
```

### Notas sobre Docker

1. **Detección automática**: El SDK detecta automáticamente si está corriendo en Alpine Linux y usa la librería nativa correcta (musl vs glibc)

2. **Sin dependencias de compilación**: A diferencia de otros SDKs, no necesitas instalar compiladores o herramientas de build

3. **Variables de entorno**: Siempre usa variables de entorno para las API keys, nunca las incluyas en el código o Dockerfile

4. **Volúmenes**: Monta el archivo `schema.json` como read-only para evitar modificaciones accidentales

## Proveedores LLM

### OpenAI

```python
ptq = PromptToQuery(
    llm_provider="openai",
    api_key=os.getenv("OPENAI_API_KEY"),
    model="gpt-4",  # opcional, por defecto: gpt-3.5-turbo
    db_schema_path="./schema.json"
)
```

**Modelos soportados:**
- `gpt-4`
- `gpt-4-turbo-preview`
- `gpt-3.5-turbo` (por defecto)

### Anthropic Claude

```python
ptq = PromptToQuery(
    llm_provider="anthropic",
    api_key=os.getenv("ANTHROPIC_API_KEY"),
    model="claude-3-opus-20240229",  # opcional
    db_schema_path="./schema.json"
)
```

**Modelos soportados:**
- `claude-3-opus-20240229`
- `claude-3-sonnet-20240229` (por defecto)
- `claude-3-haiku-20240307`

## Solución de Problemas

### Error: "Library not found"

Si ves este error, significa que la librería nativa no se encuentra. Soluciones:

1. Verifica que tu plataforma sea compatible
2. Reinstala el paquete: `pip install --force-reinstall prompt-to-query`
3. Especifica un path personalizado:

```python
ptq = PromptToQuery(
    llm_provider="openai",
    api_key="your-key",
    db_schema_path="./schema.json",
    lib_path="/path/to/libprompttoquery.so"
)
```

### Error: "Initialization failed"

Verifica:
- Que tu API key sea válida
- Que el archivo de esquema exista y sea JSON válido
- Que el provider sea 'openai' o 'anthropic'

### Error en Alpine Linux (musl)

El SDK incluye librerías nativas para Alpine Linux. Si experimentas problemas:

1. Verifica que estés usando una imagen Alpine oficial
2. El SDK detecta automáticamente Alpine y selecciona la librería correcta
3. Si falla, puedes especificar manualmente el path a la librería musl

### Problemas con Permisos en Linux

Si ves errores de permisos al cargar la librería:

```bash
chmod +x /path/to/libprompttoquery.so
```

O en Docker, asegúrate de que el usuario tenga permisos de lectura:

```dockerfile
RUN chmod 755 /usr/local/lib/python3.x/site-packages/prompt_to_query/lib/*
```

## Características Avanzadas

### Detección Automática de Columnas

El SDK incluye detección inteligente de columnas que genera títulos legibles para los resultados:

```python
result = ptq.generate_query('Show me user names and emails')

# La query incluye solo los campos necesarios
print(result['query'])
# {
#   'operation': 'find',
#   'collection': 'users',
#   'projection': {'name': 1, 'email': 1}
# }

# Los títulos son legibles para humanos
print(result['columnTitles'])
# ['User Name', 'Email']
```

Esto es especialmente útil para:
- Generar tablas dinámicas en interfaces de usuario
- Exportar datos a CSV/Excel con headers apropiados
- Mostrar resultados en dashboards

### Uso del Esquema como Diccionario

En lugar de un archivo, puedes pasar el esquema directamente:

```python
schema = {
    "users": {
        "fields": {
            "name": "string",
            "email": "string",
            "age": "number"
        }
    }
}

ptq = PromptToQuery(
    llm_provider="openai",
    api_key=os.getenv("OPENAI_API_KEY"),
    db_schema=schema  # En lugar de db_schema_path
)
```

### Integración con Pandas

```python
import pandas as pd
from pymongo import MongoClient

# Generar query
result = ptq.generate_query('Get top 10 users by age')

# Conectar a MongoDB
client = MongoClient('mongodb://localhost:27017/')
db = client['mydb']

# Ejecutar query
query = result['query']
collection = db[query['collection']]
data = list(collection.find(
    query.get('filter', {}),
    query.get('projection', None)
).limit(query.get('limit', 0)))

# Crear DataFrame con títulos legibles
df = pd.DataFrame(data)
df.columns = result['columnTitles']

print(df)
```

## Rendimiento

- **Modo Nativo**: Usa ctypes para llamar directamente a la librería Go compilada (más rápido)
- **Detección Alpine**: Automática con fallback a diferentes versiones de libc
- **Sin Overhead**: Zero dependencias externas significa menor tiempo de carga
- **Caché**: El SDK mantiene el estado internamente para llamadas subsecuentes más rápidas

### Benchmark (en una máquina típica)

```python
import time

start = time.time()
for i in range(100):
    result = ptq.generate_query('Get all users')
elapsed = time.time() - start

print(f'100 queries en {elapsed:.2f} segundos')
# ~5-10 segundos dependiendo del LLM y latencia de red
```

## Seguridad

- Nunca incluyas API keys en el código o control de versiones
- Usa variables de entorno (`os.getenv()`) para credenciales
- El SDK valida todas las queries generadas antes de retornarlas
- No ejecuta queries automáticamente - siempre tienes control
- Las librerías nativas están firmadas y verificadas

## Plataformas Soportadas

| OS | AMD64 | ARM64 | Alpine (musl) |
|----|-------|-------|---------------|
| Linux | ✅ | ✅ | ✅ |
| macOS | ✅ | ✅ | N/A |
| Windows | ✅ | ❌ | N/A |

## Development

### Building from Source

```bash
# Clonar repositorio
git clone https://github.com/dimarb/prompt-to-query.git
cd prompt-to-query/sdk/python

# Crear entorno virtual
python -m venv venv
source venv/bin/activate  # En Windows: venv\Scripts\activate

# Instalar en modo desarrollo
pip install -e .

# Build native libraries para plataforma actual
python scripts/build-native.py

# Build para todas las plataformas (requiere Docker)
python scripts/build-native.py --all
```

### Running Tests

```bash
# Instalar dependencias de testing
pip install pytest pytest-cov

# Ejecutar tests
pytest tests/

# Con coverage
pytest --cov=prompt_to_query tests/
```

### Contribuir

Las contribuciones son bienvenidas! Por favor:

1. Fork el repositorio
2. Crea una rama para tu feature (`git checkout -b feature/amazing-feature`)
3. Commit tus cambios (`git commit -m 'Add amazing feature'`)
4. Push a la rama (`git push origin feature/amazing-feature`)
5. Abre un Pull Request

## License

MIT License - see LICENSE file for details

## Links

- **GitHub**: https://github.com/dimarb/prompt-to-query
- **PyPI**: https://pypi.org/project/prompt-to-query/
- **Issues**: https://github.com/dimarb/prompt-to-query/issues
- **Documentación completa**: [GitHub](https://github.com/dimarb/prompt-to-query)
- **Ejemplos**: Ver directorio `examples/`

---

Hecho con ❤️ usando Go + Python
