- Added schemas, services, and routers for PROSEC, RCG2, Regulaciones, REIT, RequisitoPrevio, TLCS, and Vehiculos modules. - Each module includes search and get by ID functionalities. - Integrated FastAPI routers for each module into the main SITAR router. - Ensured proper response models using Pydantic for data validation.
321 lines
11 KiB
Markdown
321 lines
11 KiB
Markdown
# SITAR API Module
|
|
|
|
Módulo reorganizado para integración con la API externa de SITAR (Sistema de Información de Aranceles).
|
|
|
|
## Estructura
|
|
|
|
Cada recurso ahora tiene su propia carpeta con separación de responsabilidades:
|
|
|
|
```
|
|
backend/api/v1/modules/sitar/
|
|
├── common/ # Servicio base compartido
|
|
│ ├── __init__.py
|
|
│ └── base_service.py # SitarAPIBaseService con autenticación
|
|
├── tlcs/ # TLCS (Tratados de Libre Comercio)
|
|
│ ├── __init__.py
|
|
│ ├── schemas.py # TLCSResponse
|
|
│ ├── service.py # TLCSService
|
|
│ └── router.py # Endpoints FastAPI
|
|
├── fracciones/ # Fracciones arancelarias mexicanas
|
|
├── fracciones_usa/ # Fracciones USA
|
|
├── regulaciones/ # Regulaciones y restricciones
|
|
├── prosec/ # PROSEC
|
|
├── precios_estimados/ # Precios estimados
|
|
├── fundamentos_tlc/ # Fundamentos TLC
|
|
├── aladi2/ # ALADI2
|
|
├── cuotas2/ # Cuotas compensatorias
|
|
├── cupos/ # Cupos de importación
|
|
├── fracciones_anteriores/ # Historial de fracciones
|
|
├── informacion_general/ # Información general
|
|
├── ieps/ # IEPS
|
|
├── noms/ # Normas Oficiales Mexicanas
|
|
├── rcg2/ # Reglas de Carácter General
|
|
├── reit/ # REIT
|
|
├── requisito_previo/ # Requisitos previos
|
|
├── vehiculos_marcas/ # Marcas de vehículos
|
|
├── vehiculos_modelos/ # Modelos de vehículos
|
|
├── __init__.py # Exporta todos los servicios
|
|
└── main_router.py # Router principal con todos los endpoints
|
|
```
|
|
|
|
## Uso del Servicio
|
|
|
|
### Desde cualquier parte del código
|
|
|
|
Cada recurso tiene su propio servicio **singleton** que maneja automáticamente la autenticación:
|
|
|
|
```python
|
|
from api.v1.modules.sitar.tlcs import TLCSService
|
|
from api.v1.modules.sitar.fracciones import FraccionesService
|
|
|
|
# Obtener instancia singleton
|
|
tlcs_service = TLCSService.get_instance()
|
|
|
|
# Buscar TLCS (async)
|
|
tlcs_data = await tlcs_service.search(
|
|
fraccion="84716001",
|
|
pais="USA",
|
|
limit=100
|
|
)
|
|
|
|
# Procesar resultados
|
|
for tlcs in tlcs_data:
|
|
print(f"Tasa: {tlcs.TASATXT}, País: {tlcs.PAIS}")
|
|
```
|
|
|
|
### Desde código síncrono
|
|
|
|
Si estás en contexto síncrono, usa `asyncio.run()`:
|
|
|
|
```python
|
|
import asyncio
|
|
from api.v1.modules.sitar.tlcs import TLCSService
|
|
|
|
tlcs_service = TLCSService.get_instance()
|
|
tlcs_data = asyncio.run(tlcs_service.search(fraccion="84716001", pais="USA"))
|
|
```
|
|
|
|
## Métodos Disponibles
|
|
|
|
### TLCS (Tratados de Libre Comercio)
|
|
|
|
- `search_tlcs(fraccion, pais, nico, skip, limit)` - Buscar TLCS
|
|
- `get_tlcs_by_id(sysid, fraccion)` - Obtener TLCS por ID
|
|
|
|
### Fracciones Arancelarias
|
|
|
|
- `search_fracciones(fraccion, nico, skip, limit)` - Buscar fracciones mexicanas
|
|
- `get_fraccion_by_id(sysid)` - Obtener fracción por ID
|
|
- `search_fracciones_usa(fraccion, skip, limit)` - Buscar fracciones USA
|
|
- `get_fraccion_usa_by_id(consecutivo)` - Obtener fracción USA por ID
|
|
- `search_fracciones_anteriores(fraccion_actual, fraccion_anterior, skip, limit)` - Buscar historial de fracciones
|
|
- `get_fracciones_anteriores_by_id(sysid)` - Obtener historial por ID
|
|
|
|
### Regulaciones y Restricciones
|
|
|
|
- `search_regulaciones(fraccion, nico, skip, limit)` - Buscar regulaciones
|
|
- `get_regulacion_by_id(sysid)` - Obtener regulación por ID
|
|
- `search_noms(fraccion, pais, nico, skip, limit)` - Buscar Normas Oficiales Mexicanas
|
|
- `get_noms_by_id(sysid)` - Obtener NOM por ID
|
|
- `search_requisito_previo(fraccion, nico, skip, limit)` - Buscar requisitos previos
|
|
- `get_requisito_previo_by_id(sysid)` - Obtener requisito previo por ID
|
|
|
|
### PROSEC y Programas de Promoción
|
|
|
|
- `search_prosec(fraccion, nico, skip, limit)` - Buscar PROSEC
|
|
- `get_prosec_by_id(sysid)` - Obtener PROSEC por ID
|
|
- `search_reit(fraccion, nico, skip, limit)` - Buscar REIT
|
|
- `get_reit_by_id(sysid)` - Obtener REIT por ID
|
|
|
|
### Precios e Impuestos
|
|
|
|
- `search_precios_estimados(fraccion, nico, skip, limit)` - Buscar precios estimados
|
|
- `get_precio_estimado_by_id(sysid)` - Obtener precio estimado por ID
|
|
- `search_ieps(fraccion, nico, skip, limit)` - Buscar IEPS
|
|
- `get_ieps_by_id(consecutivo)` - Obtener IEPS por ID
|
|
|
|
### Fundamentos y Acuerdos
|
|
|
|
- `search_fundamentos_tlc(fraccion, nico, tipat_only, skip, limit)` - Buscar fundamentos TLC
|
|
- `get_fundamento_tlc_by_id(sysid)` - Obtener fundamento por ID
|
|
- `search_aladi2(fraccion, pais, nico, skip, limit)` - Buscar ALADI2
|
|
- `get_aladi2_by_id(sysid)` - Obtener ALADI2 por ID
|
|
|
|
### Cuotas y Cupos
|
|
|
|
- `search_cuotas2(fraccion, pais, nico, skip, limit)` - Buscar cuotas compensatorias
|
|
- `get_cuotas2_by_id(sysid)` - Obtener cuota por ID
|
|
- `search_cupos(fraccion, nico, skip, limit)` - Buscar cupos de importación
|
|
- `get_cupos_by_id(sysid)` - Obtener cupo por ID
|
|
|
|
### Reglas de Carácter General
|
|
|
|
- `search_rcg2(fraccion, nico, skip, limit)` - Buscar RCG2
|
|
- `get_rcg2_by_id(sysid)` - Obtener RCG2 por ID
|
|
|
|
### Información General
|
|
|
|
- `search_informacion_general(fraccion, nico, skip, limit)` - Buscar información general
|
|
- `get_informacion_general_by_id(sysid)` - Obtener información general por ID
|
|
|
|
### Vehículos
|
|
|
|
- `search_vehiculos_marcas(fraccion, marca, skip, limit)` - Buscar marcas de vehículos
|
|
- `get_vehiculos_marcas_by_id(sysid)` - Obtener marca por ID
|
|
- `search_vehiculos_modelos(fraccion, marca, modelo, skip, limit)` - Buscar modelos de vehículos
|
|
- `get_vehiculos_modelos_by_id(sysid)` - Obtener modelo por ID
|
|
|
|
## Configuración
|
|
|
|
Requiere las siguientes variables de entorno:
|
|
|
|
```bash
|
|
SITAR_API_URL=https://api.sitar.example.com
|
|
SITAR_API_USER=your_username
|
|
SITAR_API_PASSWORD=your_password
|
|
```
|
|
|
|
## Servicios Disponibles
|
|
|
|
Cada módulo sigue el mismo patrón con métodos `search()` y `get_by_id()`:
|
|
|
|
### TLCS - `TLCSService`
|
|
|
|
```python
|
|
from api.v1.modules.sitar.tlcs import TLCSService
|
|
service = TLCSService.get_instance()
|
|
await service.search(fraccion="84716001", pais="USA", nico=None, skip=0, limit=100)
|
|
await service.get_by_id(sysid=123, fraccion="84716001")
|
|
```
|
|
|
|
### Fracciones - `FraccionesService`
|
|
|
|
```python
|
|
from api.v1.modules.sitar.fracciones import FraccionesService
|
|
service = FraccionesService.get_instance()
|
|
await service.search(fraccion="84716001", nico=None, skip=0, limit=100)
|
|
await service.get_by_id(sysid=123)
|
|
```
|
|
|
|
### Fracciones USA - `FraccionesUSAService`
|
|
|
|
```python
|
|
from api.v1.modules.sitar.fracciones_usa import FraccionesUSAService
|
|
service = FraccionesUSAService.get_instance()
|
|
await service.search(fraccion="84716001", skip=0, limit=100)
|
|
await service.get_by_id(consecutivo=123)
|
|
```
|
|
|
|
### Otros servicios disponibles:
|
|
|
|
- **RegulacionesService** - Regulaciones y restricciones
|
|
- **ProsecService** - PROSEC (Programa de Promoción Sectorial)
|
|
- **PreciosEstimadosService** - Precios estimados
|
|
- **FundamentosTLCService** - Fundamentos de tratados de libre comercio
|
|
- **Aladi2Service** - ALADI2 (Asociación Latinoamericana de Integración)
|
|
- **Cuotas2Service** - Cuotas compensatorias
|
|
- **CuposService** - Cupos de importación
|
|
- **FraccionesAnterioresService** - Historial de fracciones
|
|
- **InformacionGeneralService** - Información general de fracciones
|
|
- **IepsService** - IEPS (Impuesto Especial sobre Producción y Servicios)
|
|
- **NomsService** - Normas Oficiales Mexicanas
|
|
- **Rcg2Service** - Reglas de Carácter General
|
|
- **ReitService** - Registro de Empresas de Industria Terminal
|
|
- **RequisitoPrevioService** - Requisitos previos
|
|
- **VehiculosMarcasService** - Marcas de vehículos
|
|
- **VehiculosModelosService** - Modelos de vehículos
|
|
|
|
```### Desde endpoints asíncronos
|
|
|
|
```python
|
|
from fastapi import APIRouter, HTTPException
|
|
from api.v1.modules.sitar.tlcs import TLCSService
|
|
|
|
router = APIRouter()
|
|
|
|
@router.get("/tariff/{fraccion}")
|
|
async def get_tariff_info(fraccion: str, country: str = "USA"):
|
|
"""Endpoint que consulta información arancelaria"""
|
|
try:
|
|
tlcs_service = TLCSService.get_instance()
|
|
data = await tlcs_service.search(fraccion=fraccion, pais=country)
|
|
return {"success": True, "data": data}
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
```
|
|
## Arquitectura
|
|
|
|
### Servicio Base Compartido
|
|
|
|
Todos los servicios heredan de `SitarAPIBaseService` que maneja:
|
|
|
|
- Autenticación con token caching
|
|
- Renovación automática de tokens
|
|
- Manejo de errores HTTP
|
|
- Timeout configurable
|
|
|
|
### Singleton Pattern
|
|
|
|
Cada servicio usa el patrón singleton para:
|
|
|
|
- Compartir la conexión HTTP
|
|
- Reutilizar tokens de autenticación
|
|
- Evitar múltiples instancias
|
|
|
|
### Separación de Responsabilidades
|
|
|
|
- **schemas.py**: Modelos Pydantic para validación de datos
|
|
- **service.py**: Lógica de negocio y llamadas a API
|
|
- **router.py**: Endpoints FastAPI (opcional)
|
|
- **__init__.py**: Exportaciones públicas
|
|
|
|
## Notas Importantes
|
|
|
|
1. **Autenticación**: El token se cachea y renueva automáticamente
|
|
2. **Timeouts**: Configurado a 10 segundos por defecto
|
|
3. **Límites**: Máximo 1000 registros por consulta
|
|
4. **Errores**: Todos los servicios lanzan excepciones httpx en caso de error
|
|
5. **Async/Sync**: Los servicios son async, usa `asyncio.run()` en código síncrono
|
|
|
|
```
|
|
|
|
Esto expondrá endpoints como:
|
|
- `GET /api/v1/sitar/tlcs/` - Buscar TLCS
|
|
- `GET /api/v1/sitar/fracciones/` - Buscar fracciones
|
|
- etc.
|
|
|
|
## Ejemplo Completo
|
|
|
|
```python
|
|
from api.v1.modules.sitar import SitarAPIService
|
|
|
|
async def get_tariff_info(fraccion: str, country: str):
|
|
"""Obtener información arancelaria completa"""
|
|
sitar = SitarAPIService.get_instance()
|
|
|
|
try:
|
|
# Buscar TLCS
|
|
tlcs = await sitar.search_tlcs(fraccion=fraccion, pais=country)
|
|
|
|
if tlcs:
|
|
first_tlcs = tlcs[0]
|
|
return {
|
|
"rate": first_tlcs.TASATXT,
|
|
"adv_impo": float(first_tlcs.TASA1NUM or 0.0),
|
|
"country": first_tlcs.PAIS
|
|
}
|
|
|
|
# Si no hay TLCS, buscar fracción general
|
|
fracciones = await sitar.search_fracciones(fraccion=fraccion)
|
|
|
|
if fracciones:
|
|
first_frac = fracciones[0]
|
|
return {
|
|
"rate": first_frac.ADVIMPOTXT,
|
|
"adv_impo": float(first_frac.ADVIMPONUM or 0.0),
|
|
"description": first_frac.DESCRIPCION
|
|
}
|
|
|
|
return None
|
|
|
|
except Exception as e:
|
|
print(f"Error: {e}")
|
|
return None
|
|
```
|
|
## Manejo de Errores
|
|
|
|
El servicio lanza excepciones `httpx.HTTPError` en caso de error:
|
|
|
|
```python
|
|
import httpx
|
|
|
|
try:
|
|
tlcs = await sitar.search_tlcs(fraccion="invalid")
|
|
except httpx.HTTPStatusError as e:
|
|
print(f"HTTP Error: {e.response.status_code}")
|
|
except httpx.RequestError as e:
|
|
print(f"Request Error: {e}")
|
|
except Exception as e:
|
|
print(f"General Error: {e}")
|
|
```
|