comicCalendar, es una api desarrollada con FastAPI, para gestionar eventos relacionados con el mundo del cómic.
El proyecto nace de la necesidad de un "friki", de tener un punto centralizado en el que poder consultar los eventos por distintos campos... fecha, provincia, etc. y estar informado de lo que me interesa visitar.
Si tienes esta misma necesidad, aparte de ser otro "friki", eres libre de usar el código o la API como consideres, dentro de los términos publicados en términos
Si quieres disfrutar de tus eventos sin complicarte, te sigiero que uses la web de https://comicplan.com
-
URL de la API está disponible en: https://api.comicplan.com
-
Documentación de la API: https://api.comicplan.com/docs
-
Repositorio Github: https://github.com/malambra/comicCalendar
-
URL en producción: https://comicplan.com
-
Repositorio Github: https://github.com/Raixs/ComicCalendarWeb
La API se auto explica en su documentación
Las funcionalidades más destacadas son:
- Listado ordenado por fecha
- Obtención de evento por Id
- Consulta de eventos por cualquier combinación de los siguientes campos:
- Provincia
- Comunidad
- Ciudad
- Fecha ( YYYY-MM-DD )
- Tipo ( Evento | Firma )
- Titulo ( String contenido en el titulo )
Para ejecutar el proyecto basta con:
- Clona el proyecto
git clone git@github.com:malambra/comicCalendar.git
- Creación de usuario.
Las operaciones de creación, actualización o eliminación de eventos requieren autenticación. Para lo que deberás crear uno o varios usuarios en un fichero .htpasswd en la raíz del proyecto.
htpasswd -c .htpasswd admin
- Creación de fichero de variables .env
Creamos el fichero .env
vim .env
Creamos un valor random para el SECRET_JWT
openssl rand -hex 32
Con el siguiente contenido, adaptando nuestros valores.
#JWT
SECRET_KEY="xxxxxx"
#OPENAI
OPENAI_API_KEY="sk-xxx"
#Add events
USER_API="HTPASSWD_USER"
PASSWORD_API="HTPASSWD_PASSWORD"
SERVER_URL="http://localhost:8000/v1"
#Notify Telegram
TELEGRAM_TOKEN=xxxxxxx
TELEGRAM_TIMER_SECONDS=30
- Construimos y arrancamos el proyecto.
docker-compose build
docker-compose up -d
- Copiamos el fichero de eventos al volumen.
docker cp ./events.json comiccalendar:/code/events.json
Aquí dejo algunos tips para desplegar el proyecto de forma local, de cara ha realizar futuros desarrllos...
Los requerimientos de la API, están definidos en el fichero requirements.
pip install -r requirements.txt
Es recomendable crear un virtualEnv sobre el que trabajar.
python3.11 -m venv .venv
source .venv/bin/activate
La imagen docker, con la API y el servidor uvicorn, se debe construir de la siguiente manera.
docker build -t comiccalendar .
El contenedor docker, con la API y el servidor uvicorn, se debe ejecutar de la siguiente manera.
docker run -d -p 8000:8000 comiccalendar
Si durante la fase de desarrollo, te resulta más cómodo, levantar el servidor uvicorn, para que refresque los cambios sin construir la imagen, puedes lanzarlo de la siguiente manera.
# Desde raiz del proyecto
uvicorn app.main:app --reload
La API, tiene la siguiente estructura, con el fin de hacerla lo más mantenible y escalable posible
comicCalendar/
├── .env
├── .htpasswd
├── .gitignore
├── .github
│ ├── workflows
│ │ ├── lint_ruf.yml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE
├── README.md
├── TERMS.md
├── app
│ ├── __init__.py
│ ├── auth
│ │ ├── __init__.py
│ │ └── auth.py
│ ├── main.py
│ ├── models
│ │ ├── __init__.py
│ │ ├── events.py
│ │ └── users.py
│ ├── routes
│ │ ├── __init__.py
│ │ └── v1
│ │ ├── __init__.py
│ │ ├── auth_routes.py
│ │ └── event_routes.py
│ ├── static
│ │ └── graphs
│ └── utils
│ ├── __init__.py
│ ├── file_operations.py
│ └── validate_data.py
│ └── cache.py
├── auto_update
│ ├── README.md
│ ├── add_events.py
│ ├── enrich_dates.py
│ ├── enrich_ia.py
│ ├── ics_to_json.py
│ └── new_events.py
├── docker-compose.yml
├── events.json
├── generate_graphs
│ ├── README.md
│ ├── generate_data.py
│ ├── generate_graf_totals_top.py
│ └── generate_graf_year.py
├── load_events
│ ├── basic.ics
│ ├── enrich_dates.py
│ ├── enrich_ia.py
│ ├── ics_to_json.py
│ └── reasig_id.py
└── requirements.txt
Directorio raíz del proyecto.
Variables de entorno necesarias.
Credenciales de usuarios con permisos de moificación, creación y eliminación de eventos.
Directorio para las actions
lint_ruff.yml
: Action de linter con ruff, que es uno de los linters más rápidos actualmente.
Codigo de conducta
Normas para facilitar las contribuciones.
Definición de la imagen de la api.
Definición de la licencia aplicada al proyecto.
Información relevante del proyecto.
Terminos de uso de la API.
Directorio de la API
__init__.py
: Archivo para marcar el directorio como un paquete Python.main.py
: Punto de entrada de la API, metadatos, includes de routers y definición de CORS.
Directorio para las funciones relacionadas con la autenticación.
__init__.py
: Archivo para marcar el directorio como un paquete Python.auth.py
: Definición de la función de autenticación, de la ruta del fichero .htpasswd usado, de la creacion del token jwt y del algoritmo de cifrado usado.
Directorio para los modelos de datos.
__init__.py
: Archivo para marcar el directorio como un paquete Python.events.py
: Definición de los distintos modelos de datos para los eventos.users.py
: Definición de los distintos modelos de datos para la autenticacion de usuarios.
Directorio para los enrutadores de la API
Directorio para la versión v1.
__init__.py
: Archivo para marcar el directorio como un paquete Python.auth_routes.py
: Enrutador para las rutas relacionadas con gestión eventos.event_routes.py
: Enrutador para las rutas relacionadas con queries sobre eventos.
Directorio para utilidades y funciones auxiliares.
__init__.py
: Archivo para marcar el directorio como un paquete Python.file_operations.py
: Funciones para operaciones con archivos, como cargar y guardar eventos.cache.py
: Funciones para carga de eventos en cache.
Directorio para los html con las gráficas generadas.
Directorio con los scripts necesarios para insertar y enriquecer los nuevos eventos generados en el calendario.
README.md
: Documentación acerca de la funcionalidad.add_events.py
: Script encargado de invocar a la API, para añadir los nuevos eventos.enrich_dates.py
: Script encargado de normalizar fechas para añadir la hora en caso de no estar disponible.enrich_ia.py
: Script encargado de enriquecer los eventos para definir el tipo, comunidad y provincia.ics_to_json.py
: Script encargado de convertir a json los calendarios ics.new_events.py
: Script encargado de la descarga del nuevo ics y la generacin uno nuevo con los nuevos eventos.
Fichero de orquestacion par docker-compose.
Archivo JSON para almacenar los eventos.
README.md
: Documentación acerca de la funcionalidad.generate_data.py
: Script para generar el json con los datos necesarios para la creacón de gráficas.generate_graf_totals_top.py
: Script para generar gráficas totales.generate_graf_year.py
: Script para generar gráficas de evoluciones anuales.
Directorio para realizar la precarga inicial de datos.
Directorio con las coberturas de tests unitarios usando pytest.
Definición de dependencias.
Para el control de CORS, se usa la librería
from fastapi.middleware.cors import CORSMiddleware
Como muestra la configuración aplicada para desarrollo, podemos controlar los orígenes, métodos y headers.
## Lista de dominios permitidos
#origins = [
# "http://localhost:3000", # Ejemplo de dominio permitido
# "https://miapp.com", # Añade aquí más dominios según sea necesario
#]
# Configuración de CORS
app.add_middleware(
CORSMiddleware,
#allow_origins=origins,
allow_origins=["*"],
allow_credentials=True,
#allow_methods=["*"],
allow_methods=["GET", "POST", "PUT", "DELETE"],
allow_headers=["*"],
)
Para verificar las cabeceras podemos realizar la siguiente petición
curl -i -H "Origin: http://example.com" http://localhost:8000/docs
En la respuesta debemos encontrar la cabecera:
access-control-allow-origin: *
Para lanzar los tests definidos, debemos tener instaladas las siguientes dependencias:
pip3.11 install pytest
pip3.11 install python-jose
pip3.11 install passlib
Para la ejecución de los tests, lanzaremos pytest
PYTHONPATH=./ pytest
¡Toda ayuda será buen recibida!, así que si quieres contribuir, hazlo lo mas ordenado posible. guía
Actualmente he encontrado este calendario de google, que esta siendo mantenido, en su mayoría por emea75, lo que me ha permitido hacer una precarga de datos, para usarlos desde la API
python ics_to_json.py > events.json
- [ ✓ ] (app) Añadir los eventos totales devueltos.
- [ ✓ ] (app) Añadir versionado a la api.
- [ ✓ ] (app) Cambio del modelo de datos para incorporar comunidad, ciudad y tipo.
- [ ✓ ] (app) Añadir capacidades de filtrado para nuevos campos.
- [ ✓ ] (app) Normalizar fechas YYYY-MM-DD hh:mm:ss
- [ ✓ ] (app) Add data update por evento
- [ ✓ ] (app) Permitir busqueda por summary
- (app) Controlar duplicados
- [ ✓ ] (app) sort por id de mayor a menos en events
- [ ✓ ] (app) Notificar eventos insertados desde la web
- [ ✓ ] (app) Normalizar Comunidades y Provincias segun INE
- [ ✓ ] (app) Activar compresion en la respuesta de la api
- (app) Activar cache para las respuestas de la api
- [ ✓ ] (app) Cambios formato notificaciones.
- [] (app) Cambios formato notificaciones - clean html.
- [ ✓ ] (app) Activar cache para la carga de los eventos de events.json
- [ ✓ ] (app) Definicion de tests unitarios con pytest
- [ ✓ ] (app) Cambio autenticacion a OAuth2
- (app) Control de edicion por Usuario y Evento
- [ ✓ ] (app) Control e entrada de provincias y comunidades con enums
- [ ✓ ] (app) Incrementar duracion token a 120min
- [ ✓ ] (app) Mostrar fecha ultimo update en endpoint /events
- [ ✓ ] (app) Busqueda por rango de fechas
- [ ✓ ] (app) Uso de usuario no ROOT en dockerfile
- [ ✓ ] (app) Notificación de nuevos eventos via Telegram
- (app) Gestion con bbdd en lugar de json
- [ ✓ ] (app) Graficado de información agregada de datos de eventos
- [ ✓ ] (app) No regenerar _id
- [ ✓ ] (infra) Automatizar mecanismos de obtencion y enriquecimiento de datos.
- [ ✓ ] (infra) Gestion de backups.
- [ ✓ ] (infra) Añadida action linter con ruff.
- [ ✓ ] (infra) Uso de volumenes para events.json, etc...
- [ ✓ ] (infra) Añadir autorestart a los contenedores
A los creadores y mantenedores, del calendario de eventos, del que he obtenido los datos para la precarga.
En especial a dos de sus mantenedores, con los que he podido hablar:
- Eme A: emea75
- Guillermo Velasco: @illustraworks
Proyecto desarrollado por:
Consulta los archivos CONTRIBUTING.md, CODE_OF_CONDUCT.md, LICENSE y TERMS para obtener más informacion acerca del proyecto.