Initial commit: Sistema Autoparts DB

- Base de datos SQLite con información de vehículos
- Dashboard web con Flask y Bootstrap
- Scripts de web scraping para RockAuto
- Interfaz CLI para consultas
- Documentación completa del proyecto

Incluye:
- 12 marcas de vehículos
- 10,923 modelos
- 10,919 especificaciones de motores
- 12,075 combinaciones modelo-año-motor
This commit is contained in:
2026-01-19 08:45:03 +00:00
commit f395d67136
59 changed files with 10881 additions and 0 deletions

270
docs/API.md Normal file
View File

@@ -0,0 +1,270 @@
# API Reference - Autoparts DB
Documentación completa de la API REST del sistema Autoparts DB.
## Base URL
```
http://localhost:5000/api
```
## Endpoints
### GET /api/brands
Obtiene la lista de todas las marcas de vehículos disponibles.
**Request:**
```bash
curl http://localhost:5000/api/brands
```
**Response:**
```json
{
"brands": [
{
"id": 1,
"name": "Toyota",
"country": "Japan",
"founded_year": 1937
},
{
"id": 2,
"name": "Honda",
"country": "Japan",
"founded_year": 1948
}
]
}
```
---
### GET /api/models
Obtiene modelos de vehículos, opcionalmente filtrados por marca.
**Parámetros:**
| Parámetro | Tipo | Requerido | Descripción |
|-----------|------|-----------|-------------|
| brand | string | No | Nombre de la marca para filtrar |
**Request:**
```bash
# Todos los modelos
curl http://localhost:5000/api/models
# Modelos de Toyota
curl "http://localhost:5000/api/models?brand=Toyota"
```
**Response:**
```json
{
"models": [
{
"id": 1,
"name": "Camry",
"brand": "Toyota",
"body_type": "Sedan",
"generation": "XV70",
"production_start_year": 2017,
"production_end_year": null
}
]
}
```
---
### GET /api/years
Obtiene todos los años disponibles en la base de datos.
**Request:**
```bash
curl http://localhost:5000/api/years
```
**Response:**
```json
{
"years": [1990, 1991, 1992, ..., 2024, 2025]
}
```
---
### GET /api/engines
Obtiene todos los motores disponibles.
**Request:**
```bash
curl http://localhost:5000/api/engines
```
**Response:**
```json
{
"engines": [
{
"id": 1,
"name": "2.5L 4-Cylinder",
"displacement_cc": 2500,
"cylinders": 4,
"fuel_type": "Gasoline",
"power_hp": 203,
"torque_nm": 250,
"engine_code": "A25A-FKS"
}
]
}
```
---
### GET /api/vehicles
Búsqueda de vehículos con múltiples filtros.
**Parámetros:**
| Parámetro | Tipo | Requerido | Descripción |
|-----------|------|-----------|-------------|
| brand | string | No | Marca del vehículo |
| model | string | No | Modelo del vehículo |
| year | integer | No | Año del vehículo |
| engine | string | No | Nombre/código del motor |
| limit | integer | No | Límite de resultados (default: 100) |
**Request:**
```bash
# Búsqueda completa
curl "http://localhost:5000/api/vehicles?brand=Toyota&model=Camry&year=2020"
# Solo por marca
curl "http://localhost:5000/api/vehicles?brand=Honda"
# Con límite
curl "http://localhost:5000/api/vehicles?brand=Ford&limit=50"
```
**Response:**
```json
{
"vehicles": [
{
"brand": "Toyota",
"model": "Camry",
"year": 2020,
"body_type": "Sedan",
"generation": "XV70",
"engine_name": "2.5L 4-Cylinder",
"displacement_cc": 2500,
"cylinders": 4,
"fuel_type": "Gasoline",
"power_hp": 203,
"torque_nm": 250,
"engine_code": "A25A-FKS",
"trim_level": "LE",
"drivetrain": "FWD",
"transmission": "8-Speed Automatic"
}
],
"total": 1
}
```
---
## Códigos de Respuesta
| Código | Descripción |
|--------|-------------|
| 200 | OK - Solicitud exitosa |
| 400 | Bad Request - Parámetros inválidos |
| 404 | Not Found - Recurso no encontrado |
| 500 | Internal Server Error - Error del servidor |
## Manejo de Errores
Todas las respuestas de error siguen el formato:
```json
{
"error": "Descripción del error",
"code": 400
}
```
## Ejemplos de Uso
### Python
```python
import requests
BASE_URL = "http://localhost:5000/api"
# Obtener marcas
response = requests.get(f"{BASE_URL}/brands")
brands = response.json()["brands"]
# Buscar vehículos
params = {
"brand": "Toyota",
"year": 2020,
"limit": 50
}
response = requests.get(f"{BASE_URL}/vehicles", params=params)
vehicles = response.json()["vehicles"]
```
### JavaScript
```javascript
const BASE_URL = 'http://localhost:5000/api';
// Obtener marcas
async function getBrands() {
const response = await fetch(`${BASE_URL}/brands`);
const data = await response.json();
return data.brands;
}
// Buscar vehículos
async function searchVehicles(filters) {
const params = new URLSearchParams(filters);
const response = await fetch(`${BASE_URL}/vehicles?${params}`);
const data = await response.json();
return data.vehicles;
}
// Uso
const vehicles = await searchVehicles({
brand: 'Toyota',
year: 2020
});
```
### cURL
```bash
# Obtener todas las marcas
curl -X GET http://localhost:5000/api/brands
# Buscar vehículos Toyota del 2020
curl -X GET "http://localhost:5000/api/vehicles?brand=Toyota&year=2020"
# Obtener modelos de Honda
curl -X GET "http://localhost:5000/api/models?brand=Honda"
```
## Rate Limiting
Actualmente no hay límites de tasa implementados. Para uso en producción, se recomienda implementar rate limiting.
## CORS
El servidor está configurado para aceptar solicitudes desde cualquier origen (CORS habilitado). Para producción, configure los orígenes permitidos apropiadamente.

425
docs/DATABASE.md Normal file
View File

@@ -0,0 +1,425 @@
# Documentación de Base de Datos - Autoparts DB
## Resumen
La base de datos utiliza SQLite 3 y está diseñada con un esquema normalizado para gestionar información de vehículos de manera eficiente.
**Archivo:** `vehicle_database/vehicle_database.db`
## Estadísticas Actuales
| Tabla | Registros |
|-------|-----------|
| brands | 12 |
| models | 10,923 |
| engines | 10,919 |
| years | ~35 |
| model_year_engine | 12,075 |
---
## Diagrama Entidad-Relación
```
┌──────────────┐
│ brands │
├──────────────┤
│ id (PK) │
│ name │
│ country │
│ founded_year │
│ created_at │
└──────┬───────┘
│ 1:N
┌──────▼───────────────┐
│ models │
├──────────────────────┤
│ id (PK) │
│ brand_id (FK) │───────────────────────┐
│ name │ │
│ body_type │ │
│ generation │ │
│ production_start_year│ │
│ production_end_year │ │
│ created_at │ │
└──────────────────────┘ │
┌──────────────────────┐ │
│ years │ │
├──────────────────────┤ │
│ id (PK) │───────────────┐ │
│ year │ │ │
│ created_at │ │ │
└──────────────────────┘ │ │
│ │
┌──────────────────────┐ │ │
│ engines │ │ │
├──────────────────────┤ │ │
│ id (PK) │───────┐ │ │
│ name │ │ │ │
│ displacement_cc │ │ │ │
│ cylinders │ │ │ │
│ fuel_type │ │ │ │
│ power_hp │ │ │ │
│ torque_nm │ │ │ │
│ engine_code │ │ │ │
│ created_at │ │ │ │
└──────────────────────┘ │ │ │
│ │ │
│ N:1 │ N:1 │ N:1
│ │ │
┌──────▼───────▼───────▼──────┐
│ model_year_engine │
├─────────────────────────────┤
│ id (PK) │
│ model_id (FK) │
│ year_id (FK) │
│ engine_id (FK) │
│ trim_level │
│ drivetrain │
│ transmission │
│ created_at │
└─────────────────────────────┘
```
---
## Definición de Tablas
### Tabla: brands
Almacena información de los fabricantes de vehículos.
```sql
CREATE TABLE brands (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
country TEXT,
founded_year INTEGER,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```
| Campo | Tipo | Restricciones | Descripción |
|-------|------|---------------|-------------|
| id | INTEGER | PK, AUTO | Identificador único |
| name | TEXT | NOT NULL, UNIQUE | Nombre de la marca |
| country | TEXT | - | País de origen |
| founded_year | INTEGER | - | Año de fundación |
| created_at | TIMESTAMP | DEFAULT NOW | Fecha de creación |
**Índices:**
- `idx_brands_name` en `name`
---
### Tabla: models
Almacena información de los modelos de vehículos.
```sql
CREATE TABLE models (
id INTEGER PRIMARY KEY AUTOINCREMENT,
brand_id INTEGER NOT NULL,
name TEXT NOT NULL,
body_type TEXT,
generation TEXT,
production_start_year INTEGER,
production_end_year INTEGER,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (brand_id) REFERENCES brands(id),
UNIQUE(brand_id, name, generation)
);
```
| Campo | Tipo | Restricciones | Descripción |
|-------|------|---------------|-------------|
| id | INTEGER | PK, AUTO | Identificador único |
| brand_id | INTEGER | FK, NOT NULL | Referencia a brands |
| name | TEXT | NOT NULL | Nombre del modelo |
| body_type | TEXT | - | Tipo de carrocería |
| generation | TEXT | - | Generación del modelo |
| production_start_year | INTEGER | - | Año inicio producción |
| production_end_year | INTEGER | - | Año fin producción |
| created_at | TIMESTAMP | DEFAULT NOW | Fecha de creación |
**Valores de body_type:**
- Sedan, Coupe, Hatchback, SUV, Crossover, Truck, Van, Wagon, Convertible
**Índices:**
- `idx_models_brand_id` en `brand_id`
- `idx_models_name` en `name`
---
### Tabla: engines
Almacena especificaciones técnicas de los motores.
```sql
CREATE TABLE engines (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
displacement_cc INTEGER,
cylinders INTEGER,
fuel_type TEXT,
power_hp INTEGER,
torque_nm INTEGER,
engine_code TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(name, engine_code)
);
```
| Campo | Tipo | Restricciones | Descripción |
|-------|------|---------------|-------------|
| id | INTEGER | PK, AUTO | Identificador único |
| name | TEXT | NOT NULL | Nombre descriptivo |
| displacement_cc | INTEGER | - | Cilindrada en cc |
| cylinders | INTEGER | - | Número de cilindros |
| fuel_type | TEXT | - | Tipo de combustible |
| power_hp | INTEGER | - | Potencia en HP |
| torque_nm | INTEGER | - | Torque en Nm |
| engine_code | TEXT | - | Código del fabricante |
| created_at | TIMESTAMP | DEFAULT NOW | Fecha de creación |
**Valores de fuel_type:**
- Gasoline, Diesel, Hybrid, Electric, Plug-in Hybrid, Flex Fuel
**Índices:**
- `idx_engines_name` en `name`
- `idx_engines_code` en `engine_code`
---
### Tabla: years
Tabla de referencia para años de producción.
```sql
CREATE TABLE years (
id INTEGER PRIMARY KEY AUTOINCREMENT,
year INTEGER NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```
| Campo | Tipo | Restricciones | Descripción |
|-------|------|---------------|-------------|
| id | INTEGER | PK, AUTO | Identificador único |
| year | INTEGER | NOT NULL, UNIQUE | Año |
| created_at | TIMESTAMP | DEFAULT NOW | Fecha de creación |
---
### Tabla: model_year_engine
Tabla de unión que relaciona modelos, años y motores.
```sql
CREATE TABLE model_year_engine (
id INTEGER PRIMARY KEY AUTOINCREMENT,
model_id INTEGER NOT NULL,
year_id INTEGER NOT NULL,
engine_id INTEGER NOT NULL,
trim_level TEXT,
drivetrain TEXT,
transmission TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (model_id) REFERENCES models(id),
FOREIGN KEY (year_id) REFERENCES years(id),
FOREIGN KEY (engine_id) REFERENCES engines(id),
UNIQUE(model_id, year_id, engine_id, trim_level)
);
```
| Campo | Tipo | Restricciones | Descripción |
|-------|------|---------------|-------------|
| id | INTEGER | PK, AUTO | Identificador único |
| model_id | INTEGER | FK, NOT NULL | Referencia a models |
| year_id | INTEGER | FK, NOT NULL | Referencia a years |
| engine_id | INTEGER | FK, NOT NULL | Referencia a engines |
| trim_level | TEXT | - | Nivel de equipamiento |
| drivetrain | TEXT | - | Tipo de tracción |
| transmission | TEXT | - | Tipo de transmisión |
| created_at | TIMESTAMP | DEFAULT NOW | Fecha de creación |
**Valores de drivetrain:**
- FWD (Front-Wheel Drive), RWD (Rear-Wheel Drive), AWD (All-Wheel Drive), 4WD (Four-Wheel Drive)
**Valores de transmission:**
- Manual, Automatic, CVT, DCT, AMT
**Índices:**
- `idx_mye_model_id` en `model_id`
- `idx_mye_year_id` en `year_id`
- `idx_mye_engine_id` en `engine_id`
---
## Consultas Comunes
### Obtener todos los vehículos de una marca
```sql
SELECT
b.name AS brand,
m.name AS model,
y.year,
e.name AS engine,
mye.trim_level,
mye.drivetrain,
mye.transmission
FROM model_year_engine mye
JOIN models m ON mye.model_id = m.id
JOIN brands b ON m.brand_id = b.id
JOIN years y ON mye.year_id = y.id
JOIN engines e ON mye.engine_id = e.id
WHERE b.name = 'Toyota'
ORDER BY m.name, y.year;
```
### Buscar vehículos por año
```sql
SELECT
b.name AS brand,
m.name AS model,
e.name AS engine,
e.power_hp,
mye.trim_level
FROM model_year_engine mye
JOIN models m ON mye.model_id = m.id
JOIN brands b ON m.brand_id = b.id
JOIN years y ON mye.year_id = y.id
JOIN engines e ON mye.engine_id = e.id
WHERE y.year = 2020;
```
### Obtener especificaciones de motor
```sql
SELECT
name,
displacement_cc,
cylinders,
fuel_type,
power_hp,
torque_nm,
engine_code
FROM engines
WHERE cylinders = 6
ORDER BY power_hp DESC;
```
### Contar modelos por marca
```sql
SELECT
b.name AS brand,
COUNT(DISTINCT m.id) AS model_count
FROM brands b
LEFT JOIN models m ON b.id = m.brand_id
GROUP BY b.id
ORDER BY model_count DESC;
```
### Buscar motores por potencia
```sql
SELECT *
FROM engines
WHERE power_hp >= 300
ORDER BY power_hp DESC;
```
---
## Mantenimiento
### Backup de la Base de Datos
```bash
# Crear backup
sqlite3 vehicle_database.db ".backup 'backup.db'"
# O usando cp
cp vehicle_database.db vehicle_database_backup_$(date +%Y%m%d).db
```
### Optimización
```sql
-- Analizar tablas para optimizar consultas
ANALYZE;
-- Reconstruir índices
REINDEX;
-- Compactar base de datos
VACUUM;
```
### Verificar Integridad
```sql
PRAGMA integrity_check;
PRAGMA foreign_key_check;
```
---
## Conexión desde Python
```python
import sqlite3
# Conectar a la base de datos
conn = sqlite3.connect('vehicle_database/vehicle_database.db')
conn.row_factory = sqlite3.Row # Permite acceso por nombre de columna
# Crear cursor
cursor = conn.cursor()
# Ejecutar consulta
cursor.execute("""
SELECT b.name, m.name, y.year
FROM model_year_engine mye
JOIN models m ON mye.model_id = m.id
JOIN brands b ON m.brand_id = b.id
JOIN years y ON mye.year_id = y.id
WHERE b.name = ?
""", ('Toyota',))
# Obtener resultados
for row in cursor.fetchall():
print(f"{row['name']} - {row['name']} ({row['year']})")
# Cerrar conexión
conn.close()
```
---
## Migración de Datos
### Exportar a CSV
```bash
sqlite3 -header -csv vehicle_database.db "SELECT * FROM brands;" > brands_export.csv
sqlite3 -header -csv vehicle_database.db "SELECT * FROM models;" > models_export.csv
sqlite3 -header -csv vehicle_database.db "SELECT * FROM engines;" > engines_export.csv
```
### Importar desde CSV
```bash
sqlite3 vehicle_database.db <<EOF
.mode csv
.import brands.csv brands
.import models.csv models
.import engines.csv engines
EOF
```

326
docs/INSTALLATION.md Normal file
View File

@@ -0,0 +1,326 @@
# Guía de Instalación - Autoparts DB
## Requisitos del Sistema
### Software Requerido
| Software | Versión Mínima | Propósito |
|----------|----------------|-----------|
| Python | 3.8+ | Lenguaje principal |
| pip | 20.0+ | Gestor de paquetes |
| Git | 2.0+ | Control de versiones |
### Sistema Operativo
El proyecto es compatible con:
- Linux (Ubuntu, Debian, CentOS, etc.)
- macOS
- Windows 10/11
### Espacio en Disco
- Mínimo: 50 MB
- Recomendado: 100 MB (para crecimiento de la base de datos)
---
## Instalación Rápida
```bash
# 1. Clonar el repositorio
git clone https://git.consultoria-as.com/[usuario]/Autoparts-DB.git
# 2. Entrar al directorio
cd Autoparts-DB
# 3. Instalar dependencias
pip install -r requirements.txt
# 4. Iniciar el dashboard
cd dashboard
python3 server.py
```
---
## Instalación Detallada
### Paso 1: Clonar el Repositorio
```bash
git clone https://git.consultoria-as.com/[usuario]/Autoparts-DB.git
cd Autoparts-DB
```
### Paso 2: Crear Entorno Virtual (Recomendado)
```bash
# Crear entorno virtual
python3 -m venv venv
# Activar entorno virtual
# Linux/macOS:
source venv/bin/activate
# Windows:
venv\Scripts\activate
```
### Paso 3: Instalar Dependencias
```bash
# Instalar todas las dependencias
pip install flask requests beautifulsoup4 lxml
# O usando requirements.txt
pip install -r requirements.txt
```
### Paso 4: Verificar la Base de Datos
La base de datos viene pre-poblada con datos. Para verificar:
```bash
cd vehicle_database
sqlite3 vehicle_database.db "SELECT COUNT(*) FROM brands;"
```
### Paso 5: Inicializar (Opcional)
Si necesitas reiniciar la base de datos:
```bash
cd vehicle_database
./setup.sh
```
---
## Dependencias de Python
### Archivo requirements.txt
```
flask==2.3.3
requests>=2.28.0
beautifulsoup4>=4.11.0
lxml>=4.9.0
```
### Instalación Individual
```bash
# Flask - Framework web
pip install flask
# Requests - Cliente HTTP
pip install requests
# BeautifulSoup4 - Parser HTML
pip install beautifulsoup4
# lxml - Parser XML/HTML rápido
pip install lxml
```
---
## Configuración
### Variables de Entorno (Opcional)
```bash
# Puerto del servidor (default: 5000)
export FLASK_PORT=5000
# Modo debug (solo desarrollo)
export FLASK_DEBUG=1
# Ruta de la base de datos
export DATABASE_PATH=/path/to/vehicle_database.db
```
### Configuración del Servidor
Editar `dashboard/server.py`:
```python
# Cambiar puerto
app.run(host='0.0.0.0', port=5000, debug=False)
# Para producción
app.run(host='0.0.0.0', port=8080, debug=False)
```
---
## Verificación de la Instalación
### 1. Verificar Python
```bash
python3 --version
# Debería mostrar: Python 3.8.x o superior
```
### 2. Verificar Dependencias
```bash
python3 -c "import flask; print(f'Flask: {flask.__version__}')"
python3 -c "import requests; print(f'Requests: {requests.__version__}')"
python3 -c "import bs4; print(f'BeautifulSoup: {bs4.__version__}')"
```
### 3. Verificar Base de Datos
```bash
cd vehicle_database
python3 -c "
import sqlite3
conn = sqlite3.connect('vehicle_database.db')
cursor = conn.execute('SELECT COUNT(*) FROM brands')
print(f'Marcas en BD: {cursor.fetchone()[0]}')
conn.close()
"
```
### 4. Probar el Dashboard
```bash
cd dashboard
python3 server.py &
curl http://localhost:5000/api/brands
```
---
## Solución de Problemas
### Error: ModuleNotFoundError
```bash
# Verificar que el entorno virtual está activado
which python3
# Reinstalar dependencias
pip install --force-reinstall flask requests beautifulsoup4 lxml
```
### Error: Database is locked
```bash
# Cerrar todas las conexiones a la base de datos
# Reiniciar el servidor
pkill -f server.py
python3 dashboard/server.py
```
### Error: Port already in use
```bash
# Encontrar proceso usando el puerto
lsof -i :5000
# Matar el proceso
kill -9 [PID]
# O usar otro puerto
python3 server.py --port 5001
```
### Error: Permission denied
```bash
# Dar permisos de ejecución a scripts
chmod +x vehicle_database/setup.sh
chmod +x dashboard/start_dashboard.sh
chmod +x QUICK_START.sh
```
---
## Instalación en Producción
### Usando Gunicorn (Recomendado)
```bash
# Instalar Gunicorn
pip install gunicorn
# Iniciar servidor
cd dashboard
gunicorn -w 4 -b 0.0.0.0:8080 server:app
```
### Usando systemd
Crear archivo `/etc/systemd/system/autoparts-db.service`:
```ini
[Unit]
Description=Autoparts DB Dashboard
After=network.target
[Service]
User=www-data
WorkingDirectory=/path/to/Autoparts-DB/dashboard
ExecStart=/usr/bin/python3 server.py
Restart=always
[Install]
WantedBy=multi-user.target
```
Habilitar e iniciar:
```bash
sudo systemctl enable autoparts-db
sudo systemctl start autoparts-db
```
### Usando Docker (Opcional)
```dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY . /app
RUN pip install flask requests beautifulsoup4 lxml
EXPOSE 5000
CMD ["python3", "dashboard/server.py"]
```
```bash
docker build -t autoparts-db .
docker run -p 5000:5000 autoparts-db
```
---
## Actualizaciones
```bash
# Obtener últimos cambios
git pull origin main
# Actualizar dependencias
pip install --upgrade -r requirements.txt
```
---
## Desinstalación
```bash
# Desactivar entorno virtual
deactivate
# Eliminar directorio del proyecto
rm -rf Autoparts-DB
# Eliminar entorno virtual (si está separado)
rm -rf venv
```