diff --git a/README.md b/README.md index 622ba8d..a928936 100644 --- a/README.md +++ b/README.md @@ -2,58 +2,12 @@ API con autentificación para enviar y recibir exhortos. -## Mejores prácticas usadas en esta API +## Requerimientos -Siguiendo las recomendaciones del artículo [I've been abusing HTTP Status Codes in my APIs for years](https://blog.slimjim.xyz/posts/stop-using-http-codes/) esta API responde siempre con un **success** que puede ser veradero o falso y un **message** con un texto de mensaje. +Los requerimientos son -### Respuesta exitosa - -Cuando el resultado es exitoso el **status code** es **200** y el **message** es **Success**. - -La respuesta que entrega un _paginado_ de items tiene el total, el limit y el offset: - -```json -{ - "success": true, - "message": "Success", - "errors": [], - "data": [ - { - "id": 123, - ... - }, - ... - ], -} -``` - -En cambio, la respuesta que entrega un registro es: - -```json -{ - "success": true, - "message": "Success", - "errors": [], - "id": 123, - ... -} -``` - -### Respuesta fallida por un registro no encontrado - -Cuando NO se encuentra un registro el **status code** es **200** pero el **success** es Falso y el **message** describre el problema. - -```json -{ - "success": false, - "message": "", - "errors": ["No existe el registro"] -} -``` - -### Respuesta fallida por ruta incorrecta - -Cuando la ruta NO existe, simplemente ocurre un **status code** con error **404**. +- Python 3.11 +- PostgreSQL 15 ## Instalación @@ -72,7 +26,7 @@ source venv/bin/activate Actualizar el gestor de paquetes **pip** ```bash -pip install --upgrade pip +pip install --upgrade pip setuptools ``` Instalar el paquete **wheel** para compilar las dependencias @@ -81,53 +35,47 @@ Instalar el paquete **wheel** para compilar las dependencias pip install wheel ``` -Instalar **poetry** en el entorno virtual si no lo tiene desde el sistema operativo +Instalar **poetry 2** en el entorno virtual si no lo tiene desde el sistema operativo ```bash pip install poetry ``` -Verificar que la configuracion `virtualenvs.in-project` sea True - -```bash -poetry config virtualenvs.in-project -``` - -Si es falso, configurar **poetry** para que use el entorno virtual dentro del proyecto +Configurar **poetry** para que use el entorno virtual dentro del directorio del proyecto ```bash poetry config virtualenvs.in-project true ``` -Instalar los paquetes por medio de **poetry** +Instalar las dependencias por medio de **poetry** ```bash poetry install ``` -## Configuracion +## Configuración -Crear un archivo `.env` con las variables de entorno +Crear un archivo `.env` en la raíz del proyecto con las variables de entorno ```ini # Base de datos DB_HOST=127.0.0.1 DB_PORT=5432 DB_NAME=pjecz_plataforma_web -DB_USER=adminpjeczplataformaweb -DB_PASS=XXXXXXXXXXXXXXXX +DB_USER=XXXXXXXXXXXX +DB_PASS=XXXXXXXXXXXX # Google Cloud Storage -CLOUD_STORAGE_DEPOSITO=pjecz-desarrollo +CLOUD_STORAGE_DEPOSITO=XXXXXXXXXXXX # Origins -ORIGINS=http://localhost:3000 +ORIGINS=http://127.0.0.1:3000 # Salt sirve para cifrar el ID con HashID, debe ser igual en la API -SALT=XXXXXXXXXXXXXXXX +SALT=XXXXXXXXXXXX ``` -Crear un archivo `.bashrc` +Crear un archivo `.bashrc` que cargue las variables de entorno y el entorno virtual ```bash if [ -f ~/.bashrc ] @@ -163,17 +111,41 @@ then export PGUSER=$DB_USER export PGPASSWORD=$DB_PASS fi + +if [ -d .venv ] +then + echo "-- Python Virtual Environment" + source .venv/bin/activate + echo " $(python3 --version)" + export PYTHONPATH=$(pwd) + echo " PYTHONPATH: ${PYTHONPATH}" + echo + echo "-- Poetry" + export PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring + echo " $(poetry --version)" + echo + echo "-- FastAPI 127.0.0.1:8000" + alias arrancar="uvicorn --host=127.0.0.1 --port 8000 --reload pjecz_carina_api_key.main:app" + echo " arrancar" + echo + if [ -d tests ] + then + echo "-- Pruebas unitarias" + echo " python3 -m unittest discover" + echo + fi +fi ``` ## Arrancar -Ejecute el `.bashrc` para entrar al entorno virtual y cargar las variables de entorno +Cargar las variables de entorno y el entorno virtual ```bash -. .bashrc +source .bashrc ``` -Para arrancar el servidor ejecute +Lanzar **FastAPI** por medio del _alias_ que se cargó en el `source .bashrc` ```bash arrancar diff --git a/pjecz_carina_api_key/main.py b/pjecz_carina_api_key/main.py index 2a1d11f..a4309a0 100644 --- a/pjecz_carina_api_key/main.py +++ b/pjecz_carina_api_key/main.py @@ -62,20 +62,20 @@ app.include_router(distritos, include_in_schema=False) app.include_router(domicilios, include_in_schema=False) app.include_router(entradas_salidas, include_in_schema=False) -app.include_router(estados) +app.include_router(estados, include_in_schema=False) app.include_router(exh_areas, include_in_schema=False) -app.include_router(exh_exhortos) -app.include_router(exh_exhortos_actualizaciones) -app.include_router(exh_exhortos_archivos) +app.include_router(exh_exhortos, tags=["exhortos"]) +app.include_router(exh_exhortos_actualizaciones, tags=["actualizaciones"]) +app.include_router(exh_exhortos_archivos, tags=["exhortos"]) app.include_router(exh_exhortos_partes, include_in_schema=False) -app.include_router(exh_exhortos_promociones) -app.include_router(exh_exhortos_promociones_archivos) +app.include_router(exh_exhortos_promociones, tags=["promociones"]) +app.include_router(exh_exhortos_promociones_archivos, tags=["promociones"]) app.include_router(exh_exhortos_promociones_promoventes, include_in_schema=False) app.include_router(exh_exhortos_videos, include_in_schema=False) app.include_router(exh_externos, include_in_schema=False) -app.include_router(materias, include_in_schema=False) +app.include_router(materias, tags=["materias"]) app.include_router(modulos, include_in_schema=False) -app.include_router(municipios) +app.include_router(municipios, include_in_schema=False) app.include_router(oficinas, include_in_schema=False) app.include_router(permisos, include_in_schema=False) app.include_router(roles, include_in_schema=False) diff --git a/pjecz_carina_api_key/routers/autoridades.py b/pjecz_carina_api_key/routers/autoridades.py index 80cfc43..c5bcdaf 100644 --- a/pjecz_carina_api_key/routers/autoridades.py +++ b/pjecz_carina_api_key/routers/autoridades.py @@ -18,7 +18,7 @@ from ..models.permisos import Permiso from ..schemas.autoridades import AutoridadOut, OneAutoridadOut -autoridades = APIRouter(prefix="/v5/autoridades", tags=["autoridades"]) +autoridades = APIRouter(prefix="/api/v5/autoridades") @autoridades.get("/{clave}", response_model=OneAutoridadOut) diff --git a/pjecz_carina_api_key/routers/bitacoras.py b/pjecz_carina_api_key/routers/bitacoras.py index 6f1f634..f5b241a 100644 --- a/pjecz_carina_api_key/routers/bitacoras.py +++ b/pjecz_carina_api_key/routers/bitacoras.py @@ -11,7 +11,7 @@ from ..models.bitacoras import Bitacora # Necesario para cargar este modelo from ..models.permisos import Permiso -bitacoras = APIRouter(prefix="/v5/bitacoras", tags=["usuarios"]) +bitacoras = APIRouter(prefix="/api/v5/bitacoras") @bitacoras.get("", response_model=NotImplement) diff --git a/pjecz_carina_api_key/routers/distritos.py b/pjecz_carina_api_key/routers/distritos.py index f07127a..1a2b6c0 100644 --- a/pjecz_carina_api_key/routers/distritos.py +++ b/pjecz_carina_api_key/routers/distritos.py @@ -16,7 +16,7 @@ from ..models.permisos import Permiso from ..schemas.distritos import DistritoOut, OneDistritoOut -distritos = APIRouter(prefix="/v5/distritos", tags=["distritos"]) +distritos = APIRouter(prefix="/api/v5/distritos") @distritos.get("/{clave}", response_model=OneDistritoOut) diff --git a/pjecz_carina_api_key/routers/domicilios.py b/pjecz_carina_api_key/routers/domicilios.py index 5df4552..109369d 100644 --- a/pjecz_carina_api_key/routers/domicilios.py +++ b/pjecz_carina_api_key/routers/domicilios.py @@ -14,7 +14,7 @@ from ..models.permisos import Permiso from ..schemas.domicilios import DomicilioOut, OneDomicilioOut -domicilios = APIRouter(prefix="/v5/domicilios", tags=["categoria"]) +domicilios = APIRouter(prefix="/api/v5/domicilios") @domicilios.get("/{domicilio_id}", response_model=OneDomicilioOut) diff --git a/pjecz_carina_api_key/routers/entradas_salidas.py b/pjecz_carina_api_key/routers/entradas_salidas.py index afffa94..e844618 100644 --- a/pjecz_carina_api_key/routers/entradas_salidas.py +++ b/pjecz_carina_api_key/routers/entradas_salidas.py @@ -11,7 +11,7 @@ from ..models.entradas_salidas import EntradaSalida # Necesario para cargar este modelo from ..models.permisos import Permiso -entradas_salidas = APIRouter(prefix="/v5/entradas_salidas", tags=["usuarios"]) +entradas_salidas = APIRouter(prefix="/api/v5/entradas_salidas") @entradas_salidas.get("", response_model=NotImplement) diff --git a/pjecz_carina_api_key/routers/estados.py b/pjecz_carina_api_key/routers/estados.py index 26dad4f..0369279 100644 --- a/pjecz_carina_api_key/routers/estados.py +++ b/pjecz_carina_api_key/routers/estados.py @@ -16,7 +16,7 @@ from ..models.permisos import Permiso from ..schemas.estados import EstadoOut, OneEstadoOut -estados = APIRouter(prefix="/v5/estados", tags=["estados"]) +estados = APIRouter(prefix="/api/v5/estados") @estados.get("/{clave}", response_model=OneEstadoOut) diff --git a/pjecz_carina_api_key/routers/exh_areas.py b/pjecz_carina_api_key/routers/exh_areas.py index 621adbd..fa0e3d2 100644 --- a/pjecz_carina_api_key/routers/exh_areas.py +++ b/pjecz_carina_api_key/routers/exh_areas.py @@ -16,7 +16,7 @@ from ..models.permisos import Permiso from ..schemas.exh_areas import ExhAreaOut, OneExhAreaOut -exh_areas = APIRouter(prefix="/v5/exh_areas", tags=["exh areas"]) +exh_areas = APIRouter(prefix="/api/v5/exh_areas") @exh_areas.get("/{clave}", response_model=OneExhAreaOut) diff --git a/pjecz_carina_api_key/routers/exh_exhortos.py b/pjecz_carina_api_key/routers/exh_exhortos.py index 199aeb3..68422fe 100644 --- a/pjecz_carina_api_key/routers/exh_exhortos.py +++ b/pjecz_carina_api_key/routers/exh_exhortos.py @@ -35,7 +35,7 @@ from ..schemas.exh_exhortos_archivos import ExhExhortoArchivoItem from ..schemas.exh_exhortos_partes import ExhExhortoParteItem -exh_exhortos = APIRouter(prefix="/v5/exh_exhortos", tags=["exh exhortos"]) +exh_exhortos = APIRouter(prefix="/api/v5/exh_exhortos") ESTADO_DESTINO_NOMBRE = "COAHUILA DE ZARAGOZA" ESTADO_DESTINO_ID = 5 diff --git a/pjecz_carina_api_key/routers/exh_exhortos_actualizaciones.py b/pjecz_carina_api_key/routers/exh_exhortos_actualizaciones.py index 93a56f6..7f6a562 100644 --- a/pjecz_carina_api_key/routers/exh_exhortos_actualizaciones.py +++ b/pjecz_carina_api_key/routers/exh_exhortos_actualizaciones.py @@ -20,7 +20,7 @@ ) from .exh_exhortos import get_exhorto_with_exhorto_origen_id -exh_exhortos_actualizaciones = APIRouter(prefix="/v5/exh_exhortos_actualizaciones", tags=["exh exhortos actualizaciones"]) +exh_exhortos_actualizaciones = APIRouter(prefix="/api/v5/exh_exhortos_actualizaciones") @exh_exhortos_actualizaciones.post("", response_model=OneExhExhortoActualizacionOut) diff --git a/pjecz_carina_api_key/routers/exh_exhortos_archivos.py b/pjecz_carina_api_key/routers/exh_exhortos_archivos.py index 4ef156d..29b04f1 100644 --- a/pjecz_carina_api_key/routers/exh_exhortos_archivos.py +++ b/pjecz_carina_api_key/routers/exh_exhortos_archivos.py @@ -27,7 +27,7 @@ from ..settings import get_settings from .exh_exhortos import get_exhorto_with_exhorto_origen_id -exh_exhortos_archivos = APIRouter(prefix="/v5/exh_exhortos_archivos", tags=["exh exhortos"]) +exh_exhortos_archivos = APIRouter(prefix="/api/v5/exh_exhortos_archivos") @exh_exhortos_archivos.post("/responder_upload", response_model=OneExhExhortoArchivoRespuestaOut) diff --git a/pjecz_carina_api_key/routers/exh_exhortos_partes.py b/pjecz_carina_api_key/routers/exh_exhortos_partes.py index c1c49b1..7060853 100644 --- a/pjecz_carina_api_key/routers/exh_exhortos_partes.py +++ b/pjecz_carina_api_key/routers/exh_exhortos_partes.py @@ -11,7 +11,7 @@ from ..models.exh_exhortos_partes import ExhExhortoParte # Necesario para cargar este modelo from ..models.permisos import Permiso -exh_exhortos_partes = APIRouter(prefix="/v5/exh_exhortos_partes", tags=["exh exhortos"]) +exh_exhortos_partes = APIRouter(prefix="/api/v5/exh_exhortos_partes") @exh_exhortos_partes.get("", response_model=NotImplement) diff --git a/pjecz_carina_api_key/routers/exh_exhortos_promociones.py b/pjecz_carina_api_key/routers/exh_exhortos_promociones.py index 91afd5c..326d92c 100644 --- a/pjecz_carina_api_key/routers/exh_exhortos_promociones.py +++ b/pjecz_carina_api_key/routers/exh_exhortos_promociones.py @@ -19,7 +19,7 @@ from ..schemas.exh_exhortos_promociones import ExhExhortoPromocionIn, ExhExhortoPromocionOut, OneExhExhortoPromocionOut from .exh_exhortos import get_exhorto_with_folio_seguimiento -exh_exhortos_promociones = APIRouter(prefix="/v5/exh_exhortos_promociones", tags=["exh exhortos promociones"]) +exh_exhortos_promociones = APIRouter(prefix="/api/v5/exh_exhortos_promociones") def get_exhorto_promocion_with_folio_seguimiento( diff --git a/pjecz_carina_api_key/routers/exh_exhortos_promociones_archivos.py b/pjecz_carina_api_key/routers/exh_exhortos_promociones_archivos.py index b0d7f4d..d61454d 100644 --- a/pjecz_carina_api_key/routers/exh_exhortos_promociones_archivos.py +++ b/pjecz_carina_api_key/routers/exh_exhortos_promociones_archivos.py @@ -24,7 +24,7 @@ from ..settings import get_settings from .exh_exhortos_promociones import get_exhorto_promocion_with_folio_seguimiento -exh_exhortos_promociones_archivos = APIRouter(prefix="/v5/exh_exhortos_promociones_archivos", tags=["exh exhortos promociones"]) +exh_exhortos_promociones_archivos = APIRouter(prefix="/api/v5/exh_exhortos_promociones_archivos") @exh_exhortos_promociones_archivos.post("/upload", response_model=OneExhExhortoPromocionArchivoOut) diff --git a/pjecz_carina_api_key/routers/exh_exhortos_promociones_promoventes.py b/pjecz_carina_api_key/routers/exh_exhortos_promociones_promoventes.py index c42d88d..fc3d36e 100644 --- a/pjecz_carina_api_key/routers/exh_exhortos_promociones_promoventes.py +++ b/pjecz_carina_api_key/routers/exh_exhortos_promociones_promoventes.py @@ -11,10 +11,7 @@ from ..models.exh_exhortos_promociones_promoventes import ExhExhortoPromocionPromovente # Necesario para cargar este modelo from ..models.permisos import Permiso -exh_exhortos_promociones_promoventes = APIRouter( - prefix="/v5/exh_exhortos_promociones_promoventes", - tags=["exh exhortos promociones"], -) +exh_exhortos_promociones_promoventes = APIRouter(prefix="/api/v5/exh_exhortos_promociones_promoventes") @exh_exhortos_promociones_promoventes.get("", response_model=NotImplement) diff --git a/pjecz_carina_api_key/routers/exh_exhortos_videos.py b/pjecz_carina_api_key/routers/exh_exhortos_videos.py index f60788a..3c6a83f 100644 --- a/pjecz_carina_api_key/routers/exh_exhortos_videos.py +++ b/pjecz_carina_api_key/routers/exh_exhortos_videos.py @@ -11,7 +11,7 @@ from ..models.exh_exhortos_videos import ExhExhortoVideo # Necesario para cargar este modelo from ..models.permisos import Permiso -exh_exhortos_videos = APIRouter(prefix="/v5/exh_exhortos_videos", tags=["exh exhortos"]) +exh_exhortos_videos = APIRouter(prefix="/api/v5/exh_exhortos_videos") @exh_exhortos_videos.get("", response_model=NotImplement) diff --git a/pjecz_carina_api_key/routers/exh_externos.py b/pjecz_carina_api_key/routers/exh_externos.py index 15e737c..bffc61c 100644 --- a/pjecz_carina_api_key/routers/exh_externos.py +++ b/pjecz_carina_api_key/routers/exh_externos.py @@ -11,7 +11,7 @@ from ..models.exh_externos import ExhExterno # Necesario para cargar este modelo from ..models.permisos import Permiso -exh_externos = APIRouter(prefix="/v5/exh_externos", tags=["exh externos"]) +exh_externos = APIRouter(prefix="/api/v5/exh_externos") @exh_externos.get("", response_model=NotImplement) diff --git a/pjecz_carina_api_key/routers/materias.py b/pjecz_carina_api_key/routers/materias.py index ac6b278..15a6abd 100644 --- a/pjecz_carina_api_key/routers/materias.py +++ b/pjecz_carina_api_key/routers/materias.py @@ -16,7 +16,7 @@ from ..models.permisos import Permiso from ..schemas.materias import MateriaOut, OneMateriaOut -materias = APIRouter(prefix="/v5/materias", tags=["materias"]) +materias = APIRouter(prefix="/api/v5/materias") @materias.get("/{clave}", response_model=OneMateriaOut) diff --git a/pjecz_carina_api_key/routers/modulos.py b/pjecz_carina_api_key/routers/modulos.py index ff0ae4d..d76b80a 100644 --- a/pjecz_carina_api_key/routers/modulos.py +++ b/pjecz_carina_api_key/routers/modulos.py @@ -11,7 +11,7 @@ from ..models.modulos import Modulo # Necesario para cargar este modelo from ..models.permisos import Permiso -modulos = APIRouter(prefix="/v5/modulos", tags=["usuarios"]) +modulos = APIRouter(prefix="/api/v5/modulos") @modulos.get("", response_model=NotImplement) diff --git a/pjecz_carina_api_key/routers/municipios.py b/pjecz_carina_api_key/routers/municipios.py index 5f93c17..509b141 100644 --- a/pjecz_carina_api_key/routers/municipios.py +++ b/pjecz_carina_api_key/routers/municipios.py @@ -17,7 +17,7 @@ from ..models.permisos import Permiso from ..schemas.municipios import MunicipioOut, OneMunicipioOut -municipios = APIRouter(prefix="/v5/municipios", tags=["municipios"]) +municipios = APIRouter(prefix="/api/v5/municipios") @municipios.get("/{estado_clave}/{municipio_clave}", response_model=OneMunicipioOut) diff --git a/pjecz_carina_api_key/routers/oficinas.py b/pjecz_carina_api_key/routers/oficinas.py index 4fd0f54..d94822c 100644 --- a/pjecz_carina_api_key/routers/oficinas.py +++ b/pjecz_carina_api_key/routers/oficinas.py @@ -14,7 +14,7 @@ from ..models.permisos import Permiso from ..schemas.oficinas import OficinaOut, OneOficinaOut -oficinas = APIRouter(prefix="/v5/oficinas", tags=["categoria"]) +oficinas = APIRouter(prefix="/api/v5/oficinas") @oficinas.get("/{oficina_id}", response_model=OneOficinaOut) diff --git a/pjecz_carina_api_key/routers/permisos.py b/pjecz_carina_api_key/routers/permisos.py index 0c84163..071f4ff 100644 --- a/pjecz_carina_api_key/routers/permisos.py +++ b/pjecz_carina_api_key/routers/permisos.py @@ -10,7 +10,7 @@ from ..dependencies.fastapi_not_implemented import NotImplement from ..models.permisos import Permiso -permisos = APIRouter(prefix="/v5/permisos", tags=["usuarios"]) +permisos = APIRouter(prefix="/api/v5/permisos") @permisos.get("", response_model=NotImplement) diff --git a/pjecz_carina_api_key/routers/roles.py b/pjecz_carina_api_key/routers/roles.py index 515c0fc..c88cefa 100644 --- a/pjecz_carina_api_key/routers/roles.py +++ b/pjecz_carina_api_key/routers/roles.py @@ -11,7 +11,7 @@ from ..models.permisos import Permiso from ..models.roles import Rol # Necesario para cargar este modelo -roles = APIRouter(prefix="/v5/roles", tags=["usuarios"]) +roles = APIRouter(prefix="/api/v5/roles") @roles.get("", response_model=NotImplement) diff --git a/pjecz_carina_api_key/routers/tareas.py b/pjecz_carina_api_key/routers/tareas.py index 740dc79..5fcd8ca 100644 --- a/pjecz_carina_api_key/routers/tareas.py +++ b/pjecz_carina_api_key/routers/tareas.py @@ -11,7 +11,7 @@ from ..models.permisos import Permiso from ..models.tareas import Tarea # Necesario para cargar este modelo -tareas = APIRouter(prefix="/v5/tareas", tags=["usuarios"]) +tareas = APIRouter(prefix="/api/v5/tareas") @tareas.get("", response_model=NotImplement) diff --git a/pjecz_carina_api_key/routers/usuarios.py b/pjecz_carina_api_key/routers/usuarios.py index 16dd0a1..75de299 100644 --- a/pjecz_carina_api_key/routers/usuarios.py +++ b/pjecz_carina_api_key/routers/usuarios.py @@ -11,7 +11,7 @@ from ..models.permisos import Permiso from ..models.usuarios import Usuario # Necesario para cargar este modelo -usuarios = APIRouter(prefix="/v5/usuarios", tags=["usuarios"]) +usuarios = APIRouter(prefix="/api/v5/usuarios") @usuarios.get("", response_model=NotImplement) diff --git a/pjecz_carina_api_key/routers/usuarios_roles.py b/pjecz_carina_api_key/routers/usuarios_roles.py index 3c8963e..f409151 100644 --- a/pjecz_carina_api_key/routers/usuarios_roles.py +++ b/pjecz_carina_api_key/routers/usuarios_roles.py @@ -11,7 +11,7 @@ from ..models.permisos import Permiso from ..models.usuarios_roles import UsuarioRol # Necesario para cargar este modelo -usuarios_roles = APIRouter(prefix="/v5/usuarios_roles", tags=["usuarios"]) +usuarios_roles = APIRouter(prefix="/api/v5/usuarios_roles") @usuarios_roles.get("", response_model=NotImplement)