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:
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():
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 TLCSget_tlcs_by_id(sysid, fraccion)- Obtener TLCS por ID
Fracciones Arancelarias
search_fracciones(fraccion, nico, skip, limit)- Buscar fracciones mexicanasget_fraccion_by_id(sysid)- Obtener fracción por IDsearch_fracciones_usa(fraccion, skip, limit)- Buscar fracciones USAget_fraccion_usa_by_id(consecutivo)- Obtener fracción USA por IDsearch_fracciones_anteriores(fraccion_actual, fraccion_anterior, skip, limit)- Buscar historial de fraccionesget_fracciones_anteriores_by_id(sysid)- Obtener historial por ID
Regulaciones y Restricciones
search_regulaciones(fraccion, nico, skip, limit)- Buscar regulacionesget_regulacion_by_id(sysid)- Obtener regulación por IDsearch_noms(fraccion, pais, nico, skip, limit)- Buscar Normas Oficiales Mexicanasget_noms_by_id(sysid)- Obtener NOM por IDsearch_requisito_previo(fraccion, nico, skip, limit)- Buscar requisitos previosget_requisito_previo_by_id(sysid)- Obtener requisito previo por ID
PROSEC y Programas de Promoción
search_prosec(fraccion, nico, skip, limit)- Buscar PROSECget_prosec_by_id(sysid)- Obtener PROSEC por IDsearch_reit(fraccion, nico, skip, limit)- Buscar REITget_reit_by_id(sysid)- Obtener REIT por ID
Precios e Impuestos
search_precios_estimados(fraccion, nico, skip, limit)- Buscar precios estimadosget_precio_estimado_by_id(sysid)- Obtener precio estimado por IDsearch_ieps(fraccion, nico, skip, limit)- Buscar IEPSget_ieps_by_id(consecutivo)- Obtener IEPS por ID
Fundamentos y Acuerdos
search_fundamentos_tlc(fraccion, nico, tipat_only, skip, limit)- Buscar fundamentos TLCget_fundamento_tlc_by_id(sysid)- Obtener fundamento por IDsearch_aladi2(fraccion, pais, nico, skip, limit)- Buscar ALADI2get_aladi2_by_id(sysid)- Obtener ALADI2 por ID
Cuotas y Cupos
search_cuotas2(fraccion, pais, nico, skip, limit)- Buscar cuotas compensatoriasget_cuotas2_by_id(sysid)- Obtener cuota por IDsearch_cupos(fraccion, nico, skip, limit)- Buscar cupos de importaciónget_cupos_by_id(sysid)- Obtener cupo por ID
Reglas de Carácter General
search_rcg2(fraccion, nico, skip, limit)- Buscar RCG2get_rcg2_by_id(sysid)- Obtener RCG2 por ID
Información General
search_informacion_general(fraccion, nico, skip, limit)- Buscar información generalget_informacion_general_by_id(sysid)- Obtener información general por ID
Vehículos
search_vehiculos_marcas(fraccion, marca, skip, limit)- Buscar marcas de vehículosget_vehiculos_marcas_by_id(sysid)- Obtener marca por IDsearch_vehiculos_modelos(fraccion, marca, modelo, skip, limit)- Buscar modelos de vehículosget_vehiculos_modelos_by_id(sysid)- Obtener modelo por ID
Configuración
Requiere las siguientes variables de entorno:
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
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
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
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
```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
- Autenticación: El token se cachea y renueva automáticamente
- Timeouts: Configurado a 10 segundos por defecto
- Límites: Máximo 1000 registros por consulta
- Errores: Todos los servicios lanzan excepciones httpx en caso de error
- 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:
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}")