From 1ed8abff962212802de8d1f136d0f54af05747cf Mon Sep 17 00:00:00 2001 From: "Erick G. Islas-Osuna" Date: Mon, 20 Oct 2025 12:42:37 -0600 Subject: [PATCH 1/4] fix: broken links y check script (#30) * fix: broken links y check script * chore: run pre-commit --- .commitlintrc.json | 2 +- .github/workflows/deploy-aws.yml | 8 +- .github/workflows/deploy-staging.yml | 4 +- broken_links.json | 257 ++++++++++++++------------- docs/about.md | 4 +- docs/comunidad/como-contribuir.md | 10 +- docs/comunidad/ponentes.md | 60 +++---- docs/comunidad/sedes_faq.md | 2 +- docs/comunidad/voluntarios.md | 2 +- docs/index.md | 16 +- docs/meetups/2023/index.md | 12 +- docs/meetups/2024/index.md | 32 ++-- docs/meetups/2025/index.md | 28 +-- scripts/check_links.py | 2 + 14 files changed, 225 insertions(+), 214 deletions(-) diff --git a/.commitlintrc.json b/.commitlintrc.json index 7a4907e..c30e5a9 100644 --- a/.commitlintrc.json +++ b/.commitlintrc.json @@ -1,3 +1,3 @@ { "extends": ["@commitlint/config-conventional"] -} \ No newline at end of file +} diff --git a/.github/workflows/deploy-aws.yml b/.github/workflows/deploy-aws.yml index 5fd2617..8e4fc23 100644 --- a/.github/workflows/deploy-aws.yml +++ b/.github/workflows/deploy-aws.yml @@ -16,10 +16,10 @@ jobs: steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 + fetch-depth: 0 - name: Validate PR Title - uses: wagoid/commitlint-github-action@v5 + uses: wagoid/commitlint-github-action@v5 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: @@ -79,7 +79,7 @@ jobs: --cache-control "public, max-age=0, must-revalidate" \ --exclude "*" \ --include "sitemap.xml" - + cleanup-staging: name: Stop Staging Site needs: build-and-deploy @@ -95,4 +95,4 @@ jobs: - name: Stop Staging Site run: | - aws s3 rm s3://${{ secrets.AWS_S3_BUCKET }}/ --recursive \ No newline at end of file + aws s3 rm s3://${{ secrets.AWS_S3_BUCKET }}/ --recursive diff --git a/.github/workflows/deploy-staging.yml b/.github/workflows/deploy-staging.yml index 866919a..1a667d7 100644 --- a/.github/workflows/deploy-staging.yml +++ b/.github/workflows/deploy-staging.yml @@ -17,10 +17,10 @@ jobs: steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 + fetch-depth: 0 - name: Validate PR Title - uses: wagoid/commitlint-github-action@v5 + uses: wagoid/commitlint-github-action@v5 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: diff --git a/broken_links.json b/broken_links.json index 64bd6bb..fc7cfbb 100644 --- a/broken_links.json +++ b/broken_links.json @@ -1,8 +1,8 @@ { "summary": { - "total_files_scanned": 45, - "working_links": 80, - "broken_links": 2, + "total_files_scanned": 44, + "working_links": 81, + "broken_links": 0, "base_url": "http://127.0.0.1:8000" }, "broken_links": [ @@ -29,8 +29,8 @@ { "file": "index.md", "text": "Explorar charlas", - "url": "/meetups/index.md", - "full_url": "http://127.0.0.1:8000/meetups/index.html", + "url": "/meetups", + "full_url": "http://127.0.0.1:8000/meetups", "status": "200 OK", "line": 8, "link_type": "html" @@ -38,8 +38,8 @@ { "file": "index.md", "text": "Participa", - "url": "/comunidad/como-contribuir/", - "full_url": "http://127.0.0.1:8000/comunidad/como-contribuir/", + "url": "/comunidad/como-contribuir", + "full_url": "http://127.0.0.1:8000/comunidad/como-contribuir", "status": "200 OK", "line": 9, "link_type": "html" @@ -47,8 +47,8 @@ { "file": "index.md", "text": "Voluntarios", - "url": "/comunidad/voluntarios/#voluntarios-de-python-cdmx", - "full_url": "http://127.0.0.1:8000/comunidad/voluntarios/#voluntarios-de-python-cdmx", + "url": "/comunidad/voluntarios#voluntarios-de-python-cdmx", + "full_url": "http://127.0.0.1:8000/comunidad/voluntarios#voluntarios-de-python-cdmx", "status": "200 OK", "line": 21, "link_type": "html" @@ -56,8 +56,8 @@ { "file": "index.md", "text": "Ponentes", - "url": "/comunidad/ponentes/#ponentes-de-python-cdmx", - "full_url": "http://127.0.0.1:8000/comunidad/ponentes/#ponentes-de-python-cdmx", + "url": "/comunidad/ponentes#ponentes-de-python-cdmx", + "full_url": "http://127.0.0.1:8000/comunidad/ponentes#ponentes-de-python-cdmx", "status": "200 OK", "line": 22, "link_type": "html" @@ -65,8 +65,8 @@ { "file": "index.md", "text": "Conoce Más", - "url": "/comunidad/ponentes/", - "full_url": "http://127.0.0.1:8000/comunidad/ponentes/", + "url": "/comunidad/ponentes", + "full_url": "http://127.0.0.1:8000/comunidad/ponentes", "status": "200 OK", "line": 39, "link_type": "html" @@ -74,8 +74,8 @@ { "file": "index.md", "text": "Únete", - "url": "/comunidad/voluntarios/", - "full_url": "http://127.0.0.1:8000/comunidad/voluntarios/", + "url": "/comunidad/voluntarios", + "full_url": "http://127.0.0.1:8000/comunidad/voluntarios", "status": "200 OK", "line": 44, "link_type": "html" @@ -83,8 +83,8 @@ { "file": "index.md", "text": "Ver Eventos", - "url": "/meetups/index.md", - "full_url": "http://127.0.0.1:8000/meetups/index.html", + "url": "/meetups", + "full_url": "http://127.0.0.1:8000/meetups", "status": "200 OK", "line": 49, "link_type": "html" @@ -92,8 +92,8 @@ { "file": "about.md", "text": "guía para ponentes", - "url": "comunidad/ponentes/", - "full_url": "http://127.0.0.1:8000/comunidad/ponentes/", + "url": "comunidad/ponentes", + "full_url": "http://127.0.0.1:8000/comunidad/ponentes", "status": "200 OK", "line": 42, "link_type": "markdown" @@ -101,8 +101,8 @@ { "file": "about.md", "text": "nuestra página de voluntarios", - "url": "comunidad/voluntarios/", - "full_url": "http://127.0.0.1:8000/comunidad/voluntarios/", + "url": "comunidad/voluntarios", + "full_url": "http://127.0.0.1:8000/comunidad/voluntarios", "status": "200 OK", "line": 46, "link_type": "markdown" @@ -110,7 +110,7 @@ { "file": "meetups/2025/index.md", "text": "Ver detalles", - "url": "202508-agosto/", + "url": "202508-agosto", "full_url": "http://127.0.0.1:8000/meetups/2025/202508-agosto", "status": "200 OK", "line": 15, @@ -119,7 +119,7 @@ { "file": "meetups/2025/index.md", "text": "Ver detalles", - "url": "202507-julio/", + "url": "202507-julio", "full_url": "http://127.0.0.1:8000/meetups/2025/202507-julio", "status": "200 OK", "line": 16, @@ -128,7 +128,7 @@ { "file": "meetups/2025/index.md", "text": "Ver detalles", - "url": "202506-junio/", + "url": "202506-junio", "full_url": "http://127.0.0.1:8000/meetups/2025/202506-junio", "status": "200 OK", "line": 17, @@ -137,7 +137,7 @@ { "file": "meetups/2025/index.md", "text": "Ver detalles", - "url": "202505-mayo/", + "url": "202505-mayo", "full_url": "http://127.0.0.1:8000/meetups/2025/202505-mayo", "status": "200 OK", "line": 18, @@ -146,7 +146,7 @@ { "file": "meetups/2025/index.md", "text": "Ver detalles", - "url": "202504-unam/", + "url": "202504-unam", "full_url": "http://127.0.0.1:8000/meetups/2025/202504-unam", "status": "200 OK", "line": 19, @@ -155,7 +155,7 @@ { "file": "meetups/2025/index.md", "text": "Ver detalles", - "url": "202504-unam/", + "url": "202504-unam", "full_url": "http://127.0.0.1:8000/meetups/2025/202504-unam", "status": "200 OK", "line": 20, @@ -164,7 +164,7 @@ { "file": "meetups/2025/index.md", "text": "Ver detalles", - "url": "202504-abril/", + "url": "202504-abril", "full_url": "http://127.0.0.1:8000/meetups/2025/202504-abril", "status": "200 OK", "line": 21, @@ -173,7 +173,7 @@ { "file": "meetups/2025/index.md", "text": "Ver detalles", - "url": "202503-marzo/", + "url": "202503-marzo", "full_url": "http://127.0.0.1:8000/meetups/2025/202503-marzo", "status": "200 OK", "line": 22, @@ -182,7 +182,7 @@ { "file": "meetups/2025/index.md", "text": "Ver detalles", - "url": "202503-marzo/", + "url": "202503-marzo", "full_url": "http://127.0.0.1:8000/meetups/2025/202503-marzo", "status": "200 OK", "line": 23, @@ -191,7 +191,7 @@ { "file": "meetups/2025/index.md", "text": "Ver detalles", - "url": "202502-febrero/", + "url": "202502-febrero", "full_url": "http://127.0.0.1:8000/meetups/2025/202502-febrero", "status": "200 OK", "line": 24, @@ -200,7 +200,7 @@ { "file": "meetups/2025/index.md", "text": "Ver detalles", - "url": "202502-febrero/", + "url": "202502-febrero", "full_url": "http://127.0.0.1:8000/meetups/2025/202502-febrero", "status": "200 OK", "line": 25, @@ -209,7 +209,7 @@ { "file": "meetups/2025/index.md", "text": "Ver detalles", - "url": "202501-enero/", + "url": "202501-enero", "full_url": "http://127.0.0.1:8000/meetups/2025/202501-enero", "status": "200 OK", "line": 26, @@ -218,7 +218,7 @@ { "file": "meetups/2025/index.md", "text": "Ver detalles", - "url": "202501-enero/", + "url": "202501-enero", "full_url": "http://127.0.0.1:8000/meetups/2025/202501-enero", "status": "200 OK", "line": 27, @@ -227,7 +227,7 @@ { "file": "meetups/2025/index.md", "text": "ponentes y voluntarios reconocidos", - "url": "../../comunidad/como-contribuir/", + "url": "../../comunidad/como-contribuir", "full_url": "http://127.0.0.1:8000/comunidad/como-contribuir", "status": "200 OK", "line": 68, @@ -236,7 +236,7 @@ { "file": "meetups/2024/index.md", "text": "Ver detalles", - "url": "202411-noviembre/", + "url": "202411-noviembre", "full_url": "http://127.0.0.1:8000/meetups/2024/202411-noviembre", "status": "200 OK", "line": 15, @@ -245,7 +245,7 @@ { "file": "meetups/2024/index.md", "text": "Ver detalles", - "url": "202411-noviembre/", + "url": "202411-noviembre", "full_url": "http://127.0.0.1:8000/meetups/2024/202411-noviembre", "status": "200 OK", "line": 16, @@ -254,7 +254,7 @@ { "file": "meetups/2024/index.md", "text": "Ver detalles", - "url": "202410-octubre/", + "url": "202410-octubre", "full_url": "http://127.0.0.1:8000/meetups/2024/202410-octubre", "status": "200 OK", "line": 17, @@ -263,7 +263,7 @@ { "file": "meetups/2024/index.md", "text": "Ver detalles", - "url": "202409-septiembre/", + "url": "202409-septiembre", "full_url": "http://127.0.0.1:8000/meetups/2024/202409-septiembre", "status": "200 OK", "line": 18, @@ -272,7 +272,7 @@ { "file": "meetups/2024/index.md", "text": "Ver detalles", - "url": "202409-septiembre/", + "url": "202409-septiembre", "full_url": "http://127.0.0.1:8000/meetups/2024/202409-septiembre", "status": "200 OK", "line": 19, @@ -281,7 +281,7 @@ { "file": "meetups/2024/index.md", "text": "Ver detalles", - "url": "202408-agosto/", + "url": "202408-agosto", "full_url": "http://127.0.0.1:8000/meetups/2024/202408-agosto", "status": "200 OK", "line": 20, @@ -290,7 +290,7 @@ { "file": "meetups/2024/index.md", "text": "Ver detalles", - "url": "202408-agosto/", + "url": "202408-agosto", "full_url": "http://127.0.0.1:8000/meetups/2024/202408-agosto", "status": "200 OK", "line": 21, @@ -299,7 +299,7 @@ { "file": "meetups/2024/index.md", "text": "Ver detalles", - "url": "202407-julio/", + "url": "202407-julio", "full_url": "http://127.0.0.1:8000/meetups/2024/202407-julio", "status": "200 OK", "line": 22, @@ -308,7 +308,7 @@ { "file": "meetups/2024/index.md", "text": "Ver detalles", - "url": "202407-julio/", + "url": "202407-julio", "full_url": "http://127.0.0.1:8000/meetups/2024/202407-julio", "status": "200 OK", "line": 23, @@ -317,7 +317,7 @@ { "file": "meetups/2024/index.md", "text": "Ver detalles", - "url": "202406-junio/", + "url": "202406-junio", "full_url": "http://127.0.0.1:8000/meetups/2024/202406-junio", "status": "200 OK", "line": 24, @@ -326,7 +326,7 @@ { "file": "meetups/2024/index.md", "text": "Ver detalles", - "url": "202405-mayo/", + "url": "202405-mayo", "full_url": "http://127.0.0.1:8000/meetups/2024/202405-mayo", "status": "200 OK", "line": 25, @@ -335,7 +335,7 @@ { "file": "meetups/2024/index.md", "text": "Ver detalles", - "url": "202404-abril/", + "url": "202404-abril", "full_url": "http://127.0.0.1:8000/meetups/2024/202404-abril", "status": "200 OK", "line": 26, @@ -344,7 +344,7 @@ { "file": "meetups/2024/index.md", "text": "Ver detalles", - "url": "202403-marzo/", + "url": "202403-marzo", "full_url": "http://127.0.0.1:8000/meetups/2024/202403-marzo", "status": "200 OK", "line": 27, @@ -353,7 +353,7 @@ { "file": "meetups/2024/index.md", "text": "Ver detalles", - "url": "202402-febrero/", + "url": "202402-febrero", "full_url": "http://127.0.0.1:8000/meetups/2024/202402-febrero", "status": "200 OK", "line": 28, @@ -362,7 +362,7 @@ { "file": "meetups/2024/index.md", "text": "Ver detalles", - "url": "202401-enero/", + "url": "202401-enero", "full_url": "http://127.0.0.1:8000/meetups/2024/202401-enero", "status": "200 OK", "line": 29, @@ -371,7 +371,7 @@ { "file": "meetups/2024/index.md", "text": "ponentes y voluntarios reconocidos", - "url": "../../comunidad/como-contribuir/", + "url": "../../comunidad/como-contribuir", "full_url": "http://127.0.0.1:8000/comunidad/como-contribuir", "status": "200 OK", "line": 69, @@ -380,7 +380,7 @@ { "file": "meetups/2023/index.md", "text": "Ver detalles", - "url": "202311-noviembre/", + "url": "202311-noviembre", "full_url": "http://127.0.0.1:8000/meetups/2023/202311-noviembre", "status": "200 OK", "line": 15, @@ -389,7 +389,7 @@ { "file": "meetups/2023/index.md", "text": "Ver detalles", - "url": "202311-noviembre/", + "url": "202311-noviembre", "full_url": "http://127.0.0.1:8000/meetups/2023/202311-noviembre", "status": "200 OK", "line": 16, @@ -398,7 +398,7 @@ { "file": "meetups/2023/index.md", "text": "Ver detalles", - "url": "202310-octubre/", + "url": "202310-octubre", "full_url": "http://127.0.0.1:8000/meetups/2023/202310-octubre", "status": "200 OK", "line": 17, @@ -407,7 +407,7 @@ { "file": "meetups/2023/index.md", "text": "Ver detalles", - "url": "202309-septiembre/", + "url": "202309-septiembre", "full_url": "http://127.0.0.1:8000/meetups/2023/202309-septiembre", "status": "200 OK", "line": 18, @@ -416,7 +416,7 @@ { "file": "meetups/2023/index.md", "text": "Ver detalles", - "url": "202309-septiembre/", + "url": "202309-septiembre", "full_url": "http://127.0.0.1:8000/meetups/2023/202309-septiembre", "status": "200 OK", "line": 19, @@ -425,7 +425,7 @@ { "file": "meetups/2023/index.md", "text": "ponentes y voluntarios reconocidos", - "url": "../../comunidad/como-contribuir/", + "url": "../../comunidad/como-contribuir", "full_url": "http://127.0.0.1:8000/comunidad/como-contribuir", "status": "200 OK", "line": 59, @@ -434,8 +434,8 @@ { "file": "comunidad/ponentes.md", "text": "\"Mejora tu código: Evita anti-patrones en Python\" (Noviembre 2024)", - "url": "/meetups/2024/202411-noviembre/", - "full_url": "http://127.0.0.1:8000/meetups/2024/202411-noviembre/", + "url": "/meetups/2024/202411-noviembre", + "full_url": "http://127.0.0.1:8000/meetups/2024/202411-noviembre", "status": "200 OK", "line": 125, "link_type": "html" @@ -443,8 +443,8 @@ { "file": "comunidad/ponentes.md", "text": "\"Desarrollo de APIs con Python\" (Marzo 2024)", - "url": "/meetups/2024/202403-marzo/", - "full_url": "http://127.0.0.1:8000/meetups/2024/202403-marzo/", + "url": "/meetups/2024/202403-marzo", + "full_url": "http://127.0.0.1:8000/meetups/2024/202403-marzo", "status": "200 OK", "line": 126, "link_type": "html" @@ -452,8 +452,8 @@ { "file": "comunidad/ponentes.md", "text": "\"Una ida y una vuelta: Cómo iniciar en el opensource\" (Octubre 2024)", - "url": "/meetups/2024/202410-octubre/", - "full_url": "http://127.0.0.1:8000/meetups/2024/202410-octubre/", + "url": "/meetups/2024/202410-octubre", + "full_url": "http://127.0.0.1:8000/meetups/2024/202410-octubre", "status": "200 OK", "line": 158, "link_type": "html" @@ -461,8 +461,8 @@ { "file": "comunidad/ponentes.md", "text": "\"Aplicaciones de IA en la nube\" (Junio 2025)", - "url": "/meetups/2025/202506-junio/", - "full_url": "http://127.0.0.1:8000/meetups/2025/202506-junio/", + "url": "/meetups/2025/202506-junio", + "full_url": "http://127.0.0.1:8000/meetups/2025/202506-junio", "status": "200 OK", "line": 190, "link_type": "html" @@ -470,8 +470,8 @@ { "file": "comunidad/ponentes.md", "text": "\"Kubernetes y MLOps: Desplegando aplicaciones de IA\" (Abril 2025)", - "url": "/meetups/2025/202504-abril/", - "full_url": "http://127.0.0.1:8000/meetups/2025/202504-abril/", + "url": "/meetups/2025/202504-abril", + "full_url": "http://127.0.0.1:8000/meetups/2025/202504-abril", "status": "200 OK", "line": 222, "link_type": "html" @@ -479,8 +479,8 @@ { "file": "comunidad/ponentes.md", "text": "\"GitOps 101. Primeros pasos para desplegar aplicaciones en Kubernetes\" (Noviembre 2023)", - "url": "/meetups/2023/202311-noviembre/", - "full_url": "http://127.0.0.1:8000/meetups/2023/202311-noviembre/", + "url": "/meetups/2023/202311-noviembre", + "full_url": "http://127.0.0.1:8000/meetups/2023/202311-noviembre", "status": "200 OK", "line": 223, "link_type": "html" @@ -488,8 +488,8 @@ { "file": "comunidad/ponentes.md", "text": "\"Programar en tiempos del Vibe-Coding\" (Abril 2025 - UNAM)", - "url": "/meetups/2025/202504-unam/", - "full_url": "http://127.0.0.1:8000/meetups/2025/202504-unam/", + "url": "/meetups/2025/202504-unam", + "full_url": "http://127.0.0.1:8000/meetups/2025/202504-unam", "status": "200 OK", "line": 255, "link_type": "html" @@ -497,8 +497,8 @@ { "file": "comunidad/ponentes.md", "text": "\"Validación de datos con Python\" (Mayo 2024)", - "url": "/meetups/2024/202405-mayo/", - "full_url": "http://127.0.0.1:8000/meetups/2024/202405-mayo/", + "url": "/meetups/2024/202405-mayo", + "full_url": "http://127.0.0.1:8000/meetups/2024/202405-mayo", "status": "200 OK", "line": 256, "link_type": "html" @@ -506,8 +506,8 @@ { "file": "comunidad/ponentes.md", "text": "\"portafolio.py: Como hacer un portafolio web sin saber diseño web\" (Abril 2025 - UNAM)", - "url": "/meetups/2025/202504-unam/", - "full_url": "http://127.0.0.1:8000/meetups/2025/202504-unam/", + "url": "/meetups/2025/202504-unam", + "full_url": "http://127.0.0.1:8000/meetups/2025/202504-unam", "status": "200 OK", "line": 288, "link_type": "html" @@ -515,8 +515,8 @@ { "file": "comunidad/ponentes.md", "text": "\"Cómo preparar una ambiente de desarrollo con Python desde zero\" (Julio 2025)", - "url": "/meetups/2025/202507-julio/", - "full_url": "http://127.0.0.1:8000/meetups/2025/202507-julio/", + "url": "/meetups/2025/202507-julio", + "full_url": "http://127.0.0.1:8000/meetups/2025/202507-julio", "status": "200 OK", "line": 320, "link_type": "html" @@ -524,8 +524,8 @@ { "file": "comunidad/ponentes.md", "text": "\"Interfaces gráficas con PySide6\" (Marzo 2025)", - "url": "/meetups/2025/202503-marzo/", - "full_url": "http://127.0.0.1:8000/meetups/2025/202503-marzo/", + "url": "/meetups/2025/202503-marzo", + "full_url": "http://127.0.0.1:8000/meetups/2025/202503-marzo", "status": "200 OK", "line": 321, "link_type": "html" @@ -533,8 +533,8 @@ { "file": "comunidad/ponentes.md", "text": "\"Rich y Textual: Haz tus aplicaciones en la consola visualmente atractivas\" (Septiembre 2024)", - "url": "/meetups/2024/202409-septiembre/", - "full_url": "http://127.0.0.1:8000/meetups/2024/202409-septiembre/", + "url": "/meetups/2024/202409-septiembre", + "full_url": "http://127.0.0.1:8000/meetups/2024/202409-septiembre", "status": "200 OK", "line": 322, "link_type": "html" @@ -542,8 +542,8 @@ { "file": "comunidad/ponentes.md", "text": "\"Utilizando Servicios Administrados de AI de AWS con Python y Boto3\" (Septiembre 2023)", - "url": "/meetups/2023/202309-septiembre/", - "full_url": "http://127.0.0.1:8000/meetups/2023/202309-septiembre/", + "url": "/meetups/2023/202309-septiembre", + "full_url": "http://127.0.0.1:8000/meetups/2023/202309-septiembre", "status": "200 OK", "line": 323, "link_type": "html" @@ -551,8 +551,8 @@ { "file": "comunidad/ponentes.md", "text": "\"chit-chat: Representaciones fonéticas con python\" (Septiembre 2024)", - "url": "/meetups/2024/202409-septiembre/", - "full_url": "http://127.0.0.1:8000/meetups/2024/202409-septiembre/", + "url": "/meetups/2024/202409-septiembre", + "full_url": "http://127.0.0.1:8000/meetups/2024/202409-septiembre", "status": "200 OK", "line": 355, "link_type": "html" @@ -560,8 +560,8 @@ { "file": "comunidad/ponentes.md", "text": "\"Mi Primer Agente de Inteligencia Artificial con Python\" (Marzo 2025)", - "url": "/meetups/2025/202503-marzo/", - "full_url": "http://127.0.0.1:8000/meetups/2025/202503-marzo/", + "url": "/meetups/2025/202503-marzo", + "full_url": "http://127.0.0.1:8000/meetups/2025/202503-marzo", "status": "200 OK", "line": 387, "link_type": "html" @@ -569,8 +569,8 @@ { "file": "comunidad/ponentes.md", "text": "\"Guía Práctica para Convertirse en Contribuidor de Open Source en 10 Años (o más)\" (Agosto 2024)", - "url": "/meetups/2024/202408-agosto/", - "full_url": "http://127.0.0.1:8000/meetups/2024/202408-agosto/", + "url": "/meetups/2024/202408-agosto", + "full_url": "http://127.0.0.1:8000/meetups/2024/202408-agosto", "status": "200 OK", "line": 419, "link_type": "html" @@ -578,8 +578,8 @@ { "file": "comunidad/ponentes.md", "text": "\"Matemáticas y Python: La Ciencia Detrás de la Regresión Lineal\" (Junio 2024)", - "url": "/meetups/2024/202406-junio/", - "full_url": "http://127.0.0.1:8000/meetups/2024/202406-junio/", + "url": "/meetups/2024/202406-junio", + "full_url": "http://127.0.0.1:8000/meetups/2024/202406-junio", "status": "200 OK", "line": 451, "link_type": "html" @@ -587,8 +587,8 @@ { "file": "comunidad/ponentes.md", "text": "\"Protocolos en Python: El poder del tipado estático avanzado\" (Agosto 2024)", - "url": "/meetups/2024/202408-agosto/", - "full_url": "http://127.0.0.1:8000/meetups/2024/202408-agosto/", + "url": "/meetups/2024/202408-agosto", + "full_url": "http://127.0.0.1:8000/meetups/2024/202408-agosto", "status": "200 OK", "line": 483, "link_type": "html" @@ -596,8 +596,8 @@ { "file": "comunidad/ponentes.md", "text": "\"¡De Jupyter a Web en Minutos!\" (Octubre 2023)", - "url": "/meetups/2023/202310-octubre/", - "full_url": "http://127.0.0.1:8000/meetups/2023/202310-octubre/", + "url": "/meetups/2023/202310-octubre", + "full_url": "http://127.0.0.1:8000/meetups/2023/202310-octubre", "status": "200 OK", "line": 484, "link_type": "html" @@ -605,8 +605,8 @@ { "file": "comunidad/ponentes.md", "text": "\"Metaprogramación en Python\" (Septiembre 2023)", - "url": "/meetups/2023/202309-septiembre/", - "full_url": "http://127.0.0.1:8000/meetups/2023/202309-septiembre/", + "url": "/meetups/2023/202309-septiembre", + "full_url": "http://127.0.0.1:8000/meetups/2023/202309-septiembre", "status": "200 OK", "line": 485, "link_type": "html" @@ -614,8 +614,8 @@ { "file": "comunidad/ponentes.md", "text": "\"Python: La Forja de un Lenguaje\" (Noviembre 2023)", - "url": "/meetups/2023/202311-noviembre/", - "full_url": "http://127.0.0.1:8000/meetups/2023/202311-noviembre/", + "url": "/meetups/2023/202311-noviembre", + "full_url": "http://127.0.0.1:8000/meetups/2023/202311-noviembre", "status": "200 OK", "line": 486, "link_type": "html" @@ -623,8 +623,8 @@ { "file": "comunidad/ponentes.md", "text": "\"Python y los esquemas ETLs\" (Julio 2024)", - "url": "/meetups/2024/202407-julio/", - "full_url": "http://127.0.0.1:8000/meetups/2024/202407-julio/", + "url": "/meetups/2024/202407-julio", + "full_url": "http://127.0.0.1:8000/meetups/2024/202407-julio", "status": "200 OK", "line": 518, "link_type": "html" @@ -632,8 +632,8 @@ { "file": "comunidad/ponentes.md", "text": "\"Título de la charla\" (Noviembre 2024)", - "url": "/meetups/2024/202411-noviembre/", - "full_url": "http://127.0.0.1:8000/meetups/2024/202411-noviembre/", + "url": "/meetups/2024/202411-noviembre", + "full_url": "http://127.0.0.1:8000/meetups/2024/202411-noviembre", "status": "200 OK", "line": 519, "link_type": "html" @@ -641,8 +641,8 @@ { "file": "comunidad/ponentes.md", "text": "\"Desarrollo de aplicaciones FinTech con Python\" (Mayo 2025)", - "url": "/meetups/2025/202505-mayo/", - "full_url": "http://127.0.0.1:8000/meetups/2025/202505-mayo/", + "url": "/meetups/2025/202505-mayo", + "full_url": "http://127.0.0.1:8000/meetups/2025/202505-mayo", "status": "200 OK", "line": 551, "link_type": "html" @@ -650,8 +650,8 @@ { "file": "comunidad/ponentes.md", "text": "\"Embeddings - El lenguaje como las máquinas entienden el lenguaje humano\" (Febrero 2025)", - "url": "/meetups/2025/202502-febrero/", - "full_url": "http://127.0.0.1:8000/meetups/2025/202502-febrero/", + "url": "/meetups/2025/202502-febrero", + "full_url": "http://127.0.0.1:8000/meetups/2025/202502-febrero", "status": "200 OK", "line": 583, "link_type": "html" @@ -659,8 +659,8 @@ { "file": "comunidad/ponentes.md", "text": "\"El futuro de Python sin GIL\" (Julio 2024)", - "url": "/meetups/2024/202407-julio/", - "full_url": "http://127.0.0.1:8000/meetups/2024/202407-julio/", + "url": "/meetups/2024/202407-julio", + "full_url": "http://127.0.0.1:8000/meetups/2024/202407-julio", "status": "200 OK", "line": 615, "link_type": "html" @@ -668,8 +668,8 @@ { "file": "comunidad/ponentes.md", "text": "\"Lecciones del Advent of Code 2024\" (Febrero 2025)", - "url": "/meetups/2025/202502-febrero/", - "full_url": "http://127.0.0.1:8000/meetups/2025/202502-febrero/", + "url": "/meetups/2025/202502-febrero", + "full_url": "http://127.0.0.1:8000/meetups/2025/202502-febrero", "status": "200 OK", "line": 647, "link_type": "html" @@ -677,8 +677,8 @@ { "file": "comunidad/ponentes.md", "text": "\"Creando extensiones para LibreOffice, con Python\" (Enero 2025)", - "url": "/meetups/2025/202501-enero/", - "full_url": "http://127.0.0.1:8000/meetups/2025/202501-enero/", + "url": "/meetups/2025/202501-enero", + "full_url": "http://127.0.0.1:8000/meetups/2025/202501-enero", "status": "200 OK", "line": 679, "link_type": "html" @@ -686,8 +686,8 @@ { "file": "comunidad/ponentes.md", "text": "\"Seguridad y cumplimiento de Python: Garantizar el cumplimiento de PCI DSS en un entorno Python\" (Enero 2025)", - "url": "/meetups/2025/202501-enero/", - "full_url": "http://127.0.0.1:8000/meetups/2025/202501-enero/", + "url": "/meetups/2025/202501-enero", + "full_url": "http://127.0.0.1:8000/meetups/2025/202501-enero", "status": "200 OK", "line": 711, "link_type": "html" @@ -695,7 +695,7 @@ { "file": "comunidad/voluntarios.md", "text": "Más Información", - "url": "como-contribuir/", + "url": "como-contribuir", "full_url": "http://127.0.0.1:8000/comunidad/como-contribuir", "status": "200 OK", "line": 87, @@ -704,8 +704,8 @@ { "file": "comunidad/sedes_faq.md", "text": "Ser Ponente", - "url": "ponentes/#por-que-ser-ponente", - "full_url": "http://127.0.0.1:8000/comunidad/ponentes/#por-que-ser-ponente", + "url": "ponentes#por-que-ser-ponente", + "full_url": "http://127.0.0.1:8000/comunidad/ponentes#por-que-ser-ponente", "status": "200 OK", "line": 109, "link_type": "markdown" @@ -713,7 +713,7 @@ { "file": "comunidad/como-contribuir.md", "text": "Ser Ponente", - "url": "ponentes/", + "url": "ponentes", "full_url": "http://127.0.0.1:8000/comunidad/ponentes", "status": "200 OK", "line": 31, @@ -722,7 +722,7 @@ { "file": "comunidad/como-contribuir.md", "text": "Ser Voluntario", - "url": "voluntarios/", + "url": "voluntarios", "full_url": "http://127.0.0.1:8000/comunidad/voluntarios", "status": "200 OK", "line": 37, @@ -731,20 +731,29 @@ { "file": "comunidad/como-contribuir.md", "text": "Alianzas", - "url": "alianzas/", + "url": "alianzas", "full_url": "http://127.0.0.1:8000/comunidad/alianzas", "status": "200 OK", "line": 55, "link_type": "markdown" }, + { + "file": "comunidad/como-contribuir.md", + "text": "formas de contribuir", + "url": "como-contribuir#formas-de-contribuir", + "full_url": "http://127.0.0.1:8000/comunidad/como-contribuir#formas-de-contribuir", + "status": "200 OK", + "line": 63, + "link_type": "markdown" + }, { "file": "comunidad/como-contribuir.md", "text": "nuestros meetups", - "url": "../meetups/index.md", - "full_url": "http://127.0.0.1:8000/meetups/index.html", + "url": "../meetups", + "full_url": "http://127.0.0.1:8000/meetups", "status": "200 OK", "line": 70, "link_type": "markdown" } ] -} \ No newline at end of file +} diff --git a/docs/about.md b/docs/about.md index 507aeb0..9848b4a 100644 --- a/docs/about.md +++ b/docs/about.md @@ -39,11 +39,11 @@ Creemos que el verdadero crecimiento profesional viene de la colaboración y el ### Ser Ponente -Comparte tu experiencia y conocimiento con la comunidad. Consulta nuestra [guía para ponentes](comunidad/ponentes/) para más información. +Comparte tu experiencia y conocimiento con la comunidad. Consulta nuestra [guía para ponentes](comunidad/ponentes) para más información. ### Ser Voluntario -Ayuda a organizar eventos, gestionar redes sociales o contribuir con el desarrollo del sitio web. Conoce más en [nuestra página de voluntarios](comunidad/voluntarios/). +Ayuda a organizar eventos, gestionar redes sociales o contribuir con el desarrollo del sitio web. Conoce más en [nuestra página de voluntarios](comunidad/voluntarios). ### Asistir a Meetups diff --git a/docs/comunidad/como-contribuir.md b/docs/comunidad/como-contribuir.md index 12d897b..40dd917 100644 --- a/docs/comunidad/como-contribuir.md +++ b/docs/comunidad/como-contribuir.md @@ -28,13 +28,13 @@ Contribuir a Python CDMX te permite: Comparte tu conocimiento con la comunidad a través de charlas técnicas, casos de uso o introducciones a nuevas tecnologías. -**Más información:** [Ser Ponente](ponentes/) +**Más información:** [Ser Ponente](ponentes) ### Ser Voluntario Ayuda a organizar eventos, gestionar redes sociales, o contribuir con el desarrollo del sitio web. -**Más información:** [Ser Voluntario](voluntarios/) +**Más información:** [Ser Voluntario](voluntarios) ### Desarrollo Web @@ -52,7 +52,7 @@ Escribe artículos, documentación, o crea contenido para nuestras redes sociale Ayuda a establecer y mantener relaciones con otras comunidades y empresas. -**Más información:** [Alianzas](alianzas/) +**Más información:** [Alianzas](alianzas) --- @@ -60,14 +60,14 @@ Ayuda a establecer y mantener relaciones con otras comunidades y empresas. ### 1. Identifica tu Área -- Revisa las [formas de contribuir](#formas-de-contribuir) +- Revisa las [formas de contribuir](como-contribuir#formas-de-contribuir) - Considera tus habilidades e intereses - Evalúa tu disponibilidad de tiempo ### 2. Contacta con Nosotros - Envía un mensaje a través de nuestros canales oficiales -- Participa en [nuestros meetups](../meetups/index.md) para conocernos +- Participa en [nuestros meetups](../meetups) para conocernos - Asiste a sesiones informativas ### 3. Comienza Pequeño diff --git a/docs/comunidad/ponentes.md b/docs/comunidad/ponentes.md index 40031cc..ba113c9 100644 --- a/docs/comunidad/ponentes.md +++ b/docs/comunidad/ponentes.md @@ -122,8 +122,8 @@ Conoce a algunos de los ponentes que han compartido su conocimiento con nuestra Desarrollo de APIs, Frameworks Web, Buenas Prácticas Charlas recientes: @@ -155,7 +155,7 @@ Conoce a algunos de los ponentes que han compartido su conocimiento con nuestra OpenSource, Automatización, Hardening de Infraestructura Charlas recientes: @@ -187,7 +187,7 @@ Conoce a algunos de los ponentes que han compartido su conocimiento con nuestra Inteligencia Artificial, Tecnologías de Código Abierto Charlas recientes: @@ -219,8 +219,8 @@ Conoce a algunos de los ponentes que han compartido su conocimiento con nuestra Kubernetes, MLOps, GitOps, Cloud Native Charlas recientes: @@ -252,8 +252,8 @@ Conoce a algunos de los ponentes que han compartido su conocimiento con nuestra Validación de Datos, Mejores Prácticas, Nuevas Tecnologías Charlas recientes: @@ -285,7 +285,7 @@ Conoce a algunos de los ponentes que han compartido su conocimiento con nuestra Desarrollo Web, Portafolios, Python Charlas recientes: @@ -317,10 +317,10 @@ Conoce a algunos de los ponentes que han compartido su conocimiento con nuestra DevOps, Docker, Kubernetes, CI/CD, AWS Charlas recientes: @@ -352,7 +352,7 @@ Conoce a algunos de los ponentes que han compartido su conocimiento con nuestra NLP, Lenguas Indígenas, MLOps, Cultura Libre Charlas recientes: @@ -384,7 +384,7 @@ Conoce a algunos de los ponentes que han compartido su conocimiento con nuestra Agentes de IA, Machine Learning, LangGraph, LLMs Charlas recientes: @@ -416,7 +416,7 @@ Conoce a algunos de los ponentes que han compartido su conocimiento con nuestra Open Source, Ruby, Contribución Comunitaria Charlas recientes: @@ -448,7 +448,7 @@ Conoce a algunos de los ponentes que han compartido su conocimiento con nuestra Machine Learning, Análisis de Datos, Algoritmos Estadísticos Charlas recientes: @@ -480,10 +480,10 @@ Conoce a algunos de los ponentes que han compartido su conocimiento con nuestra Desarrollo Python, Análisis de Datos, Metaprogramación Charlas recientes: @@ -515,8 +515,8 @@ Conoce a algunos de los ponentes que han compartido su conocimiento con nuestra Ingeniería de Datos, Procesamiento ETL, Big Data Charlas recientes: @@ -548,7 +548,7 @@ Conoce a algunos de los ponentes que han compartido su conocimiento con nuestra FinTech, Performance, DevOps, Software Libre Charlas recientes: @@ -580,7 +580,7 @@ Conoce a algunos de los ponentes que han compartido su conocimiento con nuestra Inteligencia Artificial, Machine Learning, Embeddings, Google Developer Expert Charlas recientes: @@ -612,7 +612,7 @@ Conoce a algunos de los ponentes que han compartido su conocimiento con nuestra Core Python, Optimización, Concurrencia, GIL Charlas recientes: @@ -644,7 +644,7 @@ Conoce a algunos de los ponentes que han compartido su conocimiento con nuestra Ingeniería de Software, Algoritmos, Resolución de Problemas Charlas recientes: @@ -676,7 +676,7 @@ Conoce a algunos de los ponentes que han compartido su conocimiento con nuestra Extensiones LibreOffice, Automatización de Oficina Charlas recientes: @@ -708,7 +708,7 @@ Conoce a algunos de los ponentes que han compartido su conocimiento con nuestra Seguridad Informática, PCI DSS, Cumplimiento Normativo Charlas recientes: @@ -725,7 +725,7 @@ Si te interesa compartir tu conocimiento con la comunidad Python CDMX, ¡no dude Enviar Propuesta de Charla - + Más Información diff --git a/docs/comunidad/sedes_faq.md b/docs/comunidad/sedes_faq.md index 40a17c8..3c84373 100644 --- a/docs/comunidad/sedes_faq.md +++ b/docs/comunidad/sedes_faq.md @@ -106,7 +106,7 @@ Lo coordinamos con gusto durante la planeación. **¡Sí!** Solo pedimos que sigan el mismo proceso que cualquier miembro de la comunidad: -[Ser Ponente](ponentes/#por-que-ser-ponente) +[Ser Ponente](ponentes#por-que-ser-ponente) **Registrar su propuesta** en [python-cdmx-charlas/issues](https://github.com/PythonMexico/python-cdmx-charlas/issues) para mantener el espíritu abierto y curado del contenido. diff --git a/docs/comunidad/voluntarios.md b/docs/comunidad/voluntarios.md index 096a5f0..f0cdade 100644 --- a/docs/comunidad/voluntarios.md +++ b/docs/comunidad/voluntarios.md @@ -84,7 +84,7 @@ Ser voluntario en Python CDMX te permite: Ver Voluntarios - Más Información + Más Información diff --git a/docs/index.md b/docs/index.md index 9e8ef2e..8c42272 100644 --- a/docs/index.md +++ b/docs/index.md @@ -5,8 +5,8 @@

#PythonCDMX es un grupo de personas interesadas en aprender y compartir su conocimiento sobre el lenguaje de programación Python. El objetivo es estar en contacto con más gente interesada en innovación y tecnología.

- Explorar charlas - Participa + Explorar charlas + Participa
@@ -18,14 +18,14 @@

Conoce a quienes hacen posible
Python CDMX!

- Voluntarios - Ponentes + Voluntarios + Ponentes

¡Únete a Nuestros Meetups!

Charlas técnicas, networking y aprendizaje colaborativo

- Ver Meetups + Ver Meetups
--- @@ -36,17 +36,17 @@

Ser Ponente

Comparte tu conocimiento con la comunidad. Charlas técnicas, casos de uso, mejores prácticas y más.

- Conoce Más + Conoce Más

Ser Voluntario

Ayuda a organizar eventos, gestionar redes sociales, o contribuir con el desarrollo del sitio web.

- Únete + Únete

Asistir

Participa en nuestros meetups, aprende de expertos y conecta con otros desarrolladores Python.

- Ver Eventos + Ver Eventos
diff --git a/docs/meetups/2023/index.md b/docs/meetups/2023/index.md index 8a3c9de..7e781c3 100644 --- a/docs/meetups/2023/index.md +++ b/docs/meetups/2023/index.md @@ -12,11 +12,11 @@ | **Fecha** | **Charla** | **Ponente** | **Lugar** | **Detalles** | |:---|:---|:---|:---|:---| -| **14 Noviembre 2023** | GitOps: Automatizando el despliegue de aplicaciones | Carlos Reyes | Wizeline México | [Ver detalles](202311-noviembre/) | -| **14 Noviembre 2023** | Historia de Python: De Guido van Rossum a la actualidad | Gustavo Vera | Wizeline México | [Ver detalles](202311-noviembre/) | -| **10 Octubre 2023** | Jupyter a Web: De notebooks a aplicaciones web | Gustavo Vera | Wizeline México | [Ver detalles](202310-octubre/) | -| **12 Septiembre 2023** | Metaprogramación en Python | David Sol | Wizeline México | [Ver detalles](202309-septiembre/) | -| **12 Septiembre 2023** | AWS AI: Servicios de IA en la nube | Gustavo Vera | Wizeline México | [Ver detalles](202309-septiembre/) | +| **14 Noviembre 2023** | GitOps: Automatizando el despliegue de aplicaciones | Carlos Reyes | Wizeline México | [Ver detalles](202311-noviembre) | +| **14 Noviembre 2023** | Historia de Python: De Guido van Rossum a la actualidad | Gustavo Vera | Wizeline México | [Ver detalles](202311-noviembre) | +| **10 Octubre 2023** | Jupyter a Web: De notebooks a aplicaciones web | Gustavo Vera | Wizeline México | [Ver detalles](202310-octubre) | +| **12 Septiembre 2023** | Metaprogramación en Python | David Sol | Wizeline México | [Ver detalles](202309-septiembre) | +| **12 Septiembre 2023** | AWS AI: Servicios de IA en la nube | Gustavo Vera | Wizeline México | [Ver detalles](202309-septiembre) | --- @@ -56,4 +56,4 @@ --- -¿Te gustaría aparecer aquí? Conoce a nuestros [ponentes y voluntarios reconocidos](../../comunidad/como-contribuir/). +¿Te gustaría aparecer aquí? Conoce a nuestros [ponentes y voluntarios reconocidos](../../comunidad/como-contribuir). diff --git a/docs/meetups/2024/index.md b/docs/meetups/2024/index.md index 39b65bf..d6fcac7 100644 --- a/docs/meetups/2024/index.md +++ b/docs/meetups/2024/index.md @@ -12,21 +12,21 @@ | **Fecha** | **Charla** | **Ponente** | **Lugar** | **Detalles** | |:---|:---|:---|:---|:---| -| **12 Noviembre 2024** | Mejora tu código: Evita anti-patrones en Python | Alejandro Lopez | Wizeline México | [Ver detalles](202411-noviembre/) | -| **12 Noviembre 2024** | Exactamente qué y (sobre todo) por qué ChatGPT | Hugo Ramírez | Wizeline México | [Ver detalles](202411-noviembre/) | -| **08 Octubre 2024** | Contribuir a Open Source | Alex Callejas | Wizeline México | [Ver detalles](202410-octubre/) | -| **10 Septiembre 2024** | Protocolos en Python | Diego Barriga | Wizeline México | [Ver detalles](202409-septiembre/) | -| **10 Septiembre 2024** | Guía Open Source | David Sol | Wizeline México | [Ver detalles](202409-septiembre/) | -| **13 Agosto 2024** | ETLs con Python | Gustavo Vera | Wizeline México | [Ver detalles](202408-agosto/) | -| **13 Agosto 2024** | GIL: Global Interpreter Lock | Fer Perales | Wizeline México | [Ver detalles](202408-agosto/) | -| **09 Julio 2024** | Regresión Lineal | Konstantin Spirin | Wizeline México | [Ver detalles](202407-julio/) | -| **09 Julio 2024** | Fonética con Python | Hugo Ramirez | Wizeline México | [Ver detalles](202407-julio/) | -| **11 Junio 2024** | Regresión Lineal | Geovanni Zepeda Martínez | Wizeline México | [Ver detalles](202406-junio/) | -| **14 Mayo 2024** | Pydantic | Charly Román | Wizeline México | [Ver detalles](202405-mayo/) | -| **09 Abril 2024** | Contenedores | David Sol | Wizeline México | [Ver detalles](202404-abril/) | -| **12 Marzo 2024** | Flask APIs | Alejandro López | Wizeline México | [Ver detalles](202403-marzo/) | -| **13 Febrero 2024** | Entornos Virtuales | Gustavo Vera | Wizeline México | [Ver detalles](202402-febrero/) | -| **09 Enero 2024** | PyPI | David Sol | Wizeline México | [Ver detalles](202401-enero/) | +| **12 Noviembre 2024** | Mejora tu código: Evita anti-patrones en Python | Alejandro Lopez | Wizeline México | [Ver detalles](202411-noviembre) | +| **12 Noviembre 2024** | Exactamente qué y (sobre todo) por qué ChatGPT | Hugo Ramírez | Wizeline México | [Ver detalles](202411-noviembre) | +| **08 Octubre 2024** | Contribuir a Open Source | Alex Callejas | Wizeline México | [Ver detalles](202410-octubre) | +| **10 Septiembre 2024** | Protocolos en Python | Diego Barriga | Wizeline México | [Ver detalles](202409-septiembre) | +| **10 Septiembre 2024** | Guía Open Source | David Sol | Wizeline México | [Ver detalles](202409-septiembre) | +| **13 Agosto 2024** | ETLs con Python | Gustavo Vera | Wizeline México | [Ver detalles](202408-agosto) | +| **13 Agosto 2024** | GIL: Global Interpreter Lock | Fer Perales | Wizeline México | [Ver detalles](202408-agosto) | +| **09 Julio 2024** | Regresión Lineal | Konstantin Spirin | Wizeline México | [Ver detalles](202407-julio) | +| **09 Julio 2024** | Fonética con Python | Hugo Ramirez | Wizeline México | [Ver detalles](202407-julio) | +| **11 Junio 2024** | Regresión Lineal | Geovanni Zepeda Martínez | Wizeline México | [Ver detalles](202406-junio) | +| **14 Mayo 2024** | Pydantic | Charly Román | Wizeline México | [Ver detalles](202405-mayo) | +| **09 Abril 2024** | Contenedores | David Sol | Wizeline México | [Ver detalles](202404-abril) | +| **12 Marzo 2024** | Flask APIs | Alejandro López | Wizeline México | [Ver detalles](202403-marzo) | +| **13 Febrero 2024** | Entornos Virtuales | Gustavo Vera | Wizeline México | [Ver detalles](202402-febrero) | +| **09 Enero 2024** | PyPI | David Sol | Wizeline México | [Ver detalles](202401-enero) | --- @@ -66,4 +66,4 @@ --- -¿Te gustaría aparecer aquí? Conoce a nuestros [ponentes y voluntarios reconocidos](../../comunidad/como-contribuir/). +¿Te gustaría aparecer aquí? Conoce a nuestros [ponentes y voluntarios reconocidos](../../comunidad/como-contribuir). diff --git a/docs/meetups/2025/index.md b/docs/meetups/2025/index.md index f3b5ee1..e085648 100644 --- a/docs/meetups/2025/index.md +++ b/docs/meetups/2025/index.md @@ -12,19 +12,19 @@ | **Fecha** | **Charla** | **Ponente** | **Lugar** | **Detalles** | |:---|:---|:---|:---|:---| -| **12 Agosto 2025** | Cómo preparar una ambiente de desarrollo con Python desde zero | Juan Guillermo Gómez | Jardin Chapultepec | [Ver detalles](202508-agosto/) | -| **08 Julio 2025** | Cómo preparar una ambiente de desarrollo con Python desde zero | David Sol | Clara | [Ver detalles](202507-julio/) | -| **10 Junio 2025** | Usando Python y software libre para crear nuevas herramientas: Traductor de voz español-inglés | Carlos Cesar Caballero | Wizeline México | [Ver detalles](202506-junio/) | -| **13 Mayo 2025** | Construyendo un paquete en Python y publicándolo en PyPI | Javier Novoa | Wizeline México | [Ver detalles](202505-mayo/) | -| **25 Abril 2025** | portafolio.py: Como hacer un portafolio web sin saber diseño web | Daniel Paredes | UNAM Facultad de Ciencias | [Ver detalles](202504-unam/) | -| **25 Abril 2025** | Programar en tiempos del Vibe-Coding | Charly Roman | UNAM Facultad de Ciencias | [Ver detalles](202504-unam/) | -| **08 Abril 2025** | El para que cosa de Quien. Kubernetes y AI | Carlos Reyes | Wizeline México | [Ver detalles](202504-abril/) | -| **11 Marzo 2025** | Mi Primer Agente de Inteligencia Artificial con Python | Erik Rivera | Wizeline México | [Ver detalles](202503-marzo/) | -| **11 Maro 2025** | Interfases gráficas con Pyside6 | David Sol | Wizeline México | [Ver detalles](202503-marzo/) | -| **11 Febrero 2025** | Lecciones del Advent of Code 2024 | Manuel Rábade | Wizeline México | [Ver detalles](202502-febrero/) | -| **11 Febrero 2025** | Embeddings: El lenguaje como las máquinas entienden el lenguaje humano | Juan Guillermo Gómez | Wizeline México | [Ver detalles](202502-febrero/) | -| **14 Enero 2025** | Crea extensiones para LibreOffice con Python | elMau (Mauricio B.) | Wizeline México | [Ver detalles](202501-enero/) | -| **14 Enero 2025** | Seguridad y cumplimiento de Python: Garantizar el cumplimiento de PCI DSS | Mauro Parra | Wizeline México | [Ver detalles](202501-enero/) | +| **12 Agosto 2025** | Cómo preparar una ambiente de desarrollo con Python desde zero | Juan Guillermo Gómez | Jardin Chapultepec | [Ver detalles](202508-agosto) | +| **08 Julio 2025** | Cómo preparar una ambiente de desarrollo con Python desde zero | David Sol | Clara | [Ver detalles](202507-julio) | +| **10 Junio 2025** | Usando Python y software libre para crear nuevas herramientas: Traductor de voz español-inglés | Carlos Cesar Caballero | Wizeline México | [Ver detalles](202506-junio) | +| **13 Mayo 2025** | Construyendo un paquete en Python y publicándolo en PyPI | Javier Novoa | Wizeline México | [Ver detalles](202505-mayo) | +| **25 Abril 2025** | portafolio.py: Como hacer un portafolio web sin saber diseño web | Daniel Paredes | UNAM Facultad de Ciencias | [Ver detalles](202504-unam) | +| **25 Abril 2025** | Programar en tiempos del Vibe-Coding | Charly Roman | UNAM Facultad de Ciencias | [Ver detalles](202504-unam) | +| **08 Abril 2025** | El para que cosa de Quien. Kubernetes y AI | Carlos Reyes | Wizeline México | [Ver detalles](202504-abril) | +| **11 Marzo 2025** | Mi Primer Agente de Inteligencia Artificial con Python | Erik Rivera | Wizeline México | [Ver detalles](202503-marzo) | +| **11 Maro 2025** | Interfases gráficas con Pyside6 | David Sol | Wizeline México | [Ver detalles](202503-marzo) | +| **11 Febrero 2025** | Lecciones del Advent of Code 2024 | Manuel Rábade | Wizeline México | [Ver detalles](202502-febrero) | +| **11 Febrero 2025** | Embeddings: El lenguaje como las máquinas entienden el lenguaje humano | Juan Guillermo Gómez | Wizeline México | [Ver detalles](202502-febrero) | +| **14 Enero 2025** | Crea extensiones para LibreOffice con Python | elMau (Mauricio B.) | Wizeline México | [Ver detalles](202501-enero) | +| **14 Enero 2025** | Seguridad y cumplimiento de Python: Garantizar el cumplimiento de PCI DSS | Mauro Parra | Wizeline México | [Ver detalles](202501-enero) | --- @@ -65,4 +65,4 @@ --- -¿Te gustaría aparecer aquí? Conoce a nuestros [ponentes y voluntarios reconocidos](../../comunidad/como-contribuir/). +¿Te gustaría aparecer aquí? Conoce a nuestros [ponentes y voluntarios reconocidos](../../comunidad/como-contribuir). diff --git a/scripts/check_links.py b/scripts/check_links.py index 07787c7..045aa9e 100644 --- a/scripts/check_links.py +++ b/scripts/check_links.py @@ -165,6 +165,8 @@ def main(): # Find all markdown files for md_file in docs_dir.rglob("*.md"): + if "README.md" in md_file.name: + continue try: with open(md_file, "r", encoding="utf-8") as f: content = f.read() From a111f61c12f860937c9b835399107e1fb1d1124b Mon Sep 17 00:00:00 2001 From: AdanGQ <735873+pixelead0@users.noreply.github.com> Date: Tue, 21 Oct 2025 08:56:27 -0600 Subject: [PATCH 2/4] =?UTF-8?q?fix:=20resolver=20problema=20de=20URLs=20si?= =?UTF-8?q?n=20extensi=C3=B3n=20.html=20en=20producci=C3=B3n=20(#44)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(config): agregar use_directory_urls para manejar URLs sin extensión - Configurar use_directory_urls: true en mkdocs.yml - Permite que URLs como /meetups/ funcionen correctamente - Mantiene compatibilidad con estructura de directorios de MkDocs * feat(infra): implementar CloudFront Function para URLs sin extensión - Agregar CloudFront Function url_rewrite para manejar URLs sin .html - Función redirige /meetups/ a /meetups/index.html automáticamente - Asociar función con todos los cache behaviors para consistencia - Soluciona problema de enlaces que no funcionan en producción * docs: agregar documentación para fix de URLs sin extensión - Documentar problema de URLs que no funcionan en producción - Explicar solución implementada con CloudFront Function - Incluir pasos de despliegue y verificación - Agregar notas técnicas sobre funcionamiento de la solución --- docs/URL_FIX_DOCUMENTATION.md | 85 +++++++++++++++++++++++++++++++++++ mkdocs.yml | 3 ++ terraform/cloudfront.tf | 49 ++++++++++++++++++++ 3 files changed, 137 insertions(+) create mode 100644 docs/URL_FIX_DOCUMENTATION.md diff --git a/docs/URL_FIX_DOCUMENTATION.md b/docs/URL_FIX_DOCUMENTATION.md new file mode 100644 index 0000000..e441b37 --- /dev/null +++ b/docs/URL_FIX_DOCUMENTATION.md @@ -0,0 +1,85 @@ +# Fix para URLs sin extensión .html en producción + +## Problema +Los enlaces funcionaban correctamente en local pero no en producción. Por ejemplo: +- ❌ `https://pythoncdmx.org/meetups/` no funcionaba +- ✅ `https://pythoncdmx.org/meetups/index.html` sí funcionaba + +## Causa +El problema se debía a que CloudFront no estaba configurado para manejar URLs sin extensión `.html`. Cuando MkDocs genera el sitio con `use_directory_urls: true`, crea URLs como `/meetups/` que apuntan a `/meetups/index.html`, pero CloudFront no sabía cómo resolver estas URLs. + +## Solución Implementada + +### 1. Configuración en mkdocs.yml +```yaml +# URL configuration +use_directory_urls: true +``` + +### 2. CloudFront Function +Se agregó una función CloudFront que maneja automáticamente las URLs sin extensión: + +```javascript +function handler(event) { + var request = event.request; + var uri = request.uri; + + // If the URI ends with a slash, try to serve index.html + if (uri.endsWith('/')) { + request.uri = uri + 'index.html'; + } + // If the URI doesn't have an extension, try to add .html + else if (!uri.includes('.') && !uri.endsWith('/')) { + request.uri = uri + '.html'; + } + + return request; +} +``` + +### 3. Asociación con Cache Behaviors +La función se asoció con todos los cache behaviors de CloudFront para asegurar consistencia. + +## Archivos Modificados + +1. **mkdocs.yml**: Agregada configuración `use_directory_urls: true` +2. **terraform/cloudfront.tf**: + - Agregada CloudFront Function `url_rewrite` + - Asociada la función con todos los cache behaviors + +## Despliegue + +Para aplicar estos cambios: + +1. **Aplicar cambios de Terraform**: + ```bash + cd terraform + terraform plan + terraform apply + ``` + +2. **Desplegar el sitio**: + ```bash + # Los cambios se aplicarán automáticamente en el próximo deploy + git push origin main + ``` + +## Verificación + +Después del despliegue, verificar que funcionen: +- ✅ `https://pythoncdmx.org/meetups/` +- ✅ `https://pythoncdmx.org/meetups/index.html` +- ✅ `https://pythoncdmx.org/about/` +- ✅ `https://pythoncdmx.org/about/index.html` + +## Notas Técnicas + +- La CloudFront Function se ejecuta en el edge, por lo que tiene latencia mínima +- La función solo modifica la URI si es necesario, sin afectar assets estáticos +- Los cache behaviors mantienen sus configuraciones originales de TTL +- La solución es compatible con el comportamiento existente de MkDocs + +## Referencias + +- [MkDocs use_directory_urls documentation](https://www.mkdocs.org/user-guide/configuration/#use_directory_urls) +- [CloudFront Functions documentation](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cloudfront-functions.html) diff --git a/mkdocs.yml b/mkdocs.yml index 117abe8..7bc91d9 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -11,6 +11,9 @@ repo_url: https://github.com/PythonMexico/pythonCDMX/ # Copyright copyright: Copyright © 2025 Python CDMX +# URL configuration +use_directory_urls: true + # Theme configuration theme: name: material diff --git a/terraform/cloudfront.tf b/terraform/cloudfront.tf index 8e7da3c..07b5178 100644 --- a/terraform/cloudfront.tf +++ b/terraform/cloudfront.tf @@ -7,6 +7,31 @@ resource "aws_cloudfront_origin_access_control" "website" { signing_protocol = "sigv4" } +# CloudFront Function to handle URLs without .html extension +resource "aws_cloudfront_function" "url_rewrite" { + name = "pythoncdmx-url-rewrite" + runtime = "cloudfront-js-1.0" + comment = "Rewrite URLs without .html extension" + publish = true + code = <<-EOT +function handler(event) { + var request = event.request; + var uri = request.uri; + + // If the URI ends with a slash, try to serve index.html + if (uri.endsWith('/')) { + request.uri = uri + 'index.html'; + } + // If the URI doesn't have an extension, try to add .html + else if (!uri.includes('.') && !uri.endsWith('/')) { + request.uri = uri + '.html'; + } + + return request; +} +EOT +} + # CloudFront distribution resource "aws_cloudfront_distribution" "website" { enabled = true @@ -42,6 +67,12 @@ resource "aws_cloudfront_distribution" "website" { default_ttl = 3600 # 1 hour max_ttl = 86400 # 24 hours compress = true + + # Associate CloudFront Function for URL rewriting + function_association { + event_type = "viewer-request" + function_arn = aws_cloudfront_function.url_rewrite.arn + } } # Cache behavior for static assets (images, CSS, JS) @@ -63,6 +94,12 @@ resource "aws_cloudfront_distribution" "website" { default_ttl = 86400 # 24 hours max_ttl = 31536000 # 1 year compress = true + + # Associate CloudFront Function for URL rewriting + function_association { + event_type = "viewer-request" + function_arn = aws_cloudfront_function.url_rewrite.arn + } } ordered_cache_behavior { @@ -83,6 +120,12 @@ resource "aws_cloudfront_distribution" "website" { default_ttl = 86400 # 24 hours max_ttl = 31536000 # 1 year compress = true + + # Associate CloudFront Function for URL rewriting + function_association { + event_type = "viewer-request" + function_arn = aws_cloudfront_function.url_rewrite.arn + } } ordered_cache_behavior { @@ -103,6 +146,12 @@ resource "aws_cloudfront_distribution" "website" { default_ttl = 604800 # 7 days max_ttl = 31536000 # 1 year compress = true + + # Associate CloudFront Function for URL rewriting + function_association { + event_type = "viewer-request" + function_arn = aws_cloudfront_function.url_rewrite.arn + } } # Custom error responses for SPA-like behavior From e9b294a366cb4878970363d323b6215590272a09 Mon Sep 17 00:00:00 2001 From: AdanGQ <735873+pixelead0@users.noreply.github.com> Date: Tue, 21 Oct 2025 09:10:46 -0600 Subject: [PATCH 3/4] =?UTF-8?q?fix:=20resolver=20problema=20de=20URLs=20si?= =?UTF-8?q?n=20extensi=C3=B3n=20.html=20en=20producci=C3=B3n=20y=20staging?= =?UTF-8?q?=20(#45)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(config): agregar use_directory_urls para manejar URLs sin extensión - Configurar use_directory_urls: true en mkdocs.yml - Permite que URLs como /meetups/ funcionen correctamente - Mantiene compatibilidad con estructura de directorios de MkDocs * feat(infra): implementar CloudFront Function para URLs sin extensión - Agregar CloudFront Function url_rewrite para manejar URLs sin .html - Función redirige /meetups/ a /meetups/index.html automáticamente - Asociar función con todos los cache behaviors para consistencia - Soluciona problema de enlaces que no funcionan en producción * docs: agregar documentación para fix de URLs sin extensión - Documentar problema de URLs que no funcionan en producción - Explicar solución implementada con CloudFront Function - Incluir pasos de despliegue y verificación - Agregar notas técnicas sobre funcionamiento de la solución * feat(infra): aplicar CloudFront Function a staging environment - Agregar función url_rewrite a todos los cache behaviors de staging - Reutilizar la misma CloudFront Function global para consistencia - Soluciona problema de URLs sin extensión en staging.pythoncdmx.org - Mantiene configuración de cache más agresiva para staging * docs: actualizar documentación con soporte para staging - Agregar información sobre configuración de staging - Incluir URLs de verificación para ambos ambientes - Documentar que la misma CloudFront Function se reutiliza --- docs/URL_FIX_DOCUMENTATION.md | 13 ++++++++++++- terraform/cloudfront-staging.tf | 27 +++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/docs/URL_FIX_DOCUMENTATION.md b/docs/URL_FIX_DOCUMENTATION.md index e441b37..d6eeb0f 100644 --- a/docs/URL_FIX_DOCUMENTATION.md +++ b/docs/URL_FIX_DOCUMENTATION.md @@ -43,9 +43,12 @@ La función se asoció con todos los cache behaviors de CloudFront para asegurar ## Archivos Modificados 1. **mkdocs.yml**: Agregada configuración `use_directory_urls: true` -2. **terraform/cloudfront.tf**: +2. **terraform/cloudfront.tf**: - Agregada CloudFront Function `url_rewrite` - Asociada la función con todos los cache behaviors +3. **terraform/cloudfront-staging.tf**: + - Aplicada la misma CloudFront Function a staging + - Asociada la función con todos los cache behaviors de staging ## Despliegue @@ -67,11 +70,19 @@ Para aplicar estos cambios: ## Verificación Después del despliegue, verificar que funcionen: + +### Producción - ✅ `https://pythoncdmx.org/meetups/` - ✅ `https://pythoncdmx.org/meetups/index.html` - ✅ `https://pythoncdmx.org/about/` - ✅ `https://pythoncdmx.org/about/index.html` +### Staging +- ✅ `https://staging.pythoncdmx.org/meetups/` +- ✅ `https://staging.pythoncdmx.org/meetups/index.html` +- ✅ `https://staging.pythoncdmx.org/about/` +- ✅ `https://staging.pythoncdmx.org/about/index.html` + ## Notas Técnicas - La CloudFront Function se ejecuta en el edge, por lo que tiene latencia mínima diff --git a/terraform/cloudfront-staging.tf b/terraform/cloudfront-staging.tf index 3504eb0..bbe7ba9 100644 --- a/terraform/cloudfront-staging.tf +++ b/terraform/cloudfront-staging.tf @@ -7,6 +7,9 @@ resource "aws_cloudfront_origin_access_control" "website_staging" { signing_protocol = "sigv4" } +# CloudFront Function for staging (reuse the same function as production) +# Note: CloudFront Functions are global, so we can reference the same function + # CloudFront distribution for staging resource "aws_cloudfront_distribution" "website_staging" { enabled = true @@ -42,6 +45,12 @@ resource "aws_cloudfront_distribution" "website_staging" { default_ttl = 300 # 5 minutes - shorter cache for staging max_ttl = 3600 # 1 hour - shorter cache for staging compress = true + + # Associate CloudFront Function for URL rewriting (same as production) + function_association { + event_type = "viewer-request" + function_arn = aws_cloudfront_function.url_rewrite.arn + } } # Cache behavior for static assets (CSS) - shorter cache for staging @@ -63,6 +72,12 @@ resource "aws_cloudfront_distribution" "website_staging" { default_ttl = 1800 # 30 minutes max_ttl = 7200 # 2 hours compress = true + + # Associate CloudFront Function for URL rewriting + function_association { + event_type = "viewer-request" + function_arn = aws_cloudfront_function.url_rewrite.arn + } } # Cache behavior for static assets (JS) - shorter cache for staging @@ -84,6 +99,12 @@ resource "aws_cloudfront_distribution" "website_staging" { default_ttl = 1800 # 30 minutes max_ttl = 7200 # 2 hours compress = true + + # Associate CloudFront Function for URL rewriting + function_association { + event_type = "viewer-request" + function_arn = aws_cloudfront_function.url_rewrite.arn + } } # Cache behavior for images - shorter cache for staging @@ -105,6 +126,12 @@ resource "aws_cloudfront_distribution" "website_staging" { default_ttl = 3600 # 1 hour max_ttl = 86400 # 24 hours compress = true + + # Associate CloudFront Function for URL rewriting + function_association { + event_type = "viewer-request" + function_arn = aws_cloudfront_function.url_rewrite.arn + } } # Custom error responses for SPA-like behavior From 9dd2f31e6a19baefb8e5939cc014654d4d60c778 Mon Sep 17 00:00:00 2001 From: aleph Date: Sat, 25 Oct 2025 21:00:52 -0600 Subject: [PATCH 4/4] fix: resolve 404 errors on subdirectory URLs with CloudFront Functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add CloudFront Functions to rewrite directory URLs to include index.html. This fixes 404 errors on pages like /meetups/, /comunidad/ponentes/, etc. Changes: - Add CloudFront Function for production and staging environments - Associate functions with default cache behavior on distributions - Add comprehensive documentation in FIX_404_ERRORS.md The solution uses CloudFront Functions to intercept viewer requests and automatically append index.html to URLs ending with / or without file extensions, enabling MkDocs directory URLs to work correctly with S3/CloudFront. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- FIX_404_ERRORS.md | 218 +++++++++++++++++++++++++++++++ terraform/cloudfront-function.tf | 52 ++++++++ terraform/cloudfront-staging.tf | 22 ++-- terraform/cloudfront.tf | 16 ++- terraform/outputs.tf | 6 +- 5 files changed, 298 insertions(+), 16 deletions(-) create mode 100644 FIX_404_ERRORS.md create mode 100644 terraform/cloudfront-function.tf diff --git a/FIX_404_ERRORS.md b/FIX_404_ERRORS.md new file mode 100644 index 0000000..4ed5af5 --- /dev/null +++ b/FIX_404_ERRORS.md @@ -0,0 +1,218 @@ +# Solución a Errores 404 en pythoncdmx.org + +## 📋 Resumen del Problema + +**Problema identificado:** Las URLs de subdirectorios (`/meetups/`, `/comunidad/`, etc.) devuelven error 404, mientras que la página principal funciona correctamente. + +**Causa raíz:** +- MkDocs genera el sitio con `--use-directory-urls`, creando URLs limpias como `/meetups/` → `site/meetups/index.html` +- CloudFront tiene configurado `default_root_object = "index.html"` que **solo funciona para la raíz** (`/`) +- Para subdirectorios, CloudFront busca un objeto llamado `meetups/` en S3 (sin `index.html`) +- Como ese objeto no existe, S3 devuelve 403, que CloudFront convierte en 404 + +## ✅ Solución Implementada + +Se implementó **CloudFront Functions** para reescribir automáticamente las URLs y agregar `index.html` a las rutas que terminan en `/` o no tienen extensión. + +### Archivos Modificados/Creados + +#### 1. **Nuevo:** `terraform/cloudfront-function.tf` +- Crea dos CloudFront Functions (producción y staging) +- Función JavaScript que intercepta requests y añade `index.html` automáticamente +- Maneja dos casos: + - URLs que terminan en `/` → Añade `index.html` + - URLs sin extensión de archivo → Añade `/index.html` + +#### 2. **Modificado:** `terraform/cloudfront.tf` +- Líneas 46-50: Asocia la función CloudFront al `default_cache_behavior` +- La función se ejecuta en el evento `viewer-request` (antes de llegar a S3) + +#### 3. **Modificado:** `terraform/cloudfront-staging.tf` +- Líneas 46-50: Asocia la función CloudFront de staging al `default_cache_behavior` +- Misma lógica aplicada al ambiente de staging + +## 🚀 Pasos para Desplegar + +### Prerequisitos +- Acceso a AWS con credenciales configuradas +- Terraform instalado +- Variables de Terraform configuradas (archivo `terraform.tfvars`) + +### Despliegue + +1. **Navega al directorio de Terraform:** + ```bash + cd terraform + ``` + +2. **Revisa el plan de Terraform:** + ```bash + terraform plan + ``` + + Deberías ver: + - `+ aws_cloudfront_function.directory_index` (nuevo) + - `+ aws_cloudfront_function.directory_index_staging` (nuevo) + - `~ aws_cloudfront_distribution.website` (modificado) + - `~ aws_cloudfront_distribution.website_staging` (modificado) + +3. **Aplica los cambios:** + ```bash + terraform apply + ``` + +4. **Confirma los cambios:** Escribe `yes` cuando se te solicite + +### Tiempo de Propagación + +- **CloudFront Functions:** Se despliegan inmediatamente en todas las edge locations +- **Distribución de CloudFront:** Puede tardar 5-15 minutos en propagarse completamente +- **Cache:** Si hay contenido en caché, puede tardar hasta 1 hora (basado en `max_ttl`) + +### Invalidación de Caché (Opcional pero Recomendado) + +Para aplicar los cambios inmediatamente sin esperar la expiración del caché: + +```bash +# Para producción +aws cloudfront create-invalidation \ + --distribution-id \ + --paths "/*" + +# Para staging +aws cloudfront create-invalidation \ + --distribution-id \ + --paths "/*" +``` + +Puedes obtener los Distribution IDs con: +```bash +terraform output cloudfront_distribution_id +terraform output cloudfront_staging_distribution_id +``` + +## 🧪 Verificación + +Una vez desplegado, verifica que las siguientes URLs funcionan: + +### Producción (pythoncdmx.org) +- ✅ `https://pythoncdmx.org/` (ya funcionaba) +- ✅ `https://pythoncdmx.org/meetups/` +- ✅ `https://pythoncdmx.org/meetups/2025/` +- ✅ `https://pythoncdmx.org/comunidad/` +- ✅ `https://pythoncdmx.org/comunidad/ponentes/` +- ✅ `https://pythoncdmx.org/comunidad/voluntarios/` +- ✅ `https://pythoncdmx.org/blog/` + +### Staging (si aplica) +- ✅ Todas las rutas equivalentes en el dominio de staging + +## 📊 Impacto y Beneficios + +### Ventajas de la Solución +- ✅ **URLs limpias:** Mantiene `/meetups/` en lugar de `/meetups.html` +- ✅ **SEO amigable:** Las URLs siguen siendo las mismas +- ✅ **Sin cambios en el código:** No requiere modificar MkDocs +- ✅ **Bajo costo:** CloudFront Functions es prácticamente gratis ($0.10 por millón de invocaciones) +- ✅ **Alta performance:** Se ejecuta en edge locations (latencia mínima) +- ✅ **Escalable:** Funciona automáticamente para cualquier nueva página + +### Costo Estimado +- **CloudFront Functions:** ~$0.10 por millón de requests +- Para un sitio con 100,000 visitas/mes: **~$0.01/mes** + +## 🔍 Debugging + +Si después del despliegue aún hay errores 404: + +1. **Verifica que la función esté asociada:** + ```bash + aws cloudfront get-distribution --id \ + | jq '.Distribution.DistributionConfig.DefaultCacheBehavior.FunctionAssociations' + ``` + +2. **Verifica que la función esté publicada:** + ```bash + aws cloudfront list-functions + ``` + +3. **Revisa CloudWatch Logs (si está habilitado):** + ```bash + aws logs tail /aws/cloudfront/function/pythoncdmx-directory-index --follow + ``` + +4. **Invalida el caché de CloudFront** (ver comando arriba) + +5. **Prueba con curl para ver headers:** + ```bash + curl -I https://pythoncdmx.org/meetups/ + ``` + +## 📝 Notas Técnicas + +### Cómo Funciona la CloudFront Function + +```javascript +function handler(event) { + var request = event.request; + var uri = request.uri; + + // Ejemplo: /meetups/ → /meetups/index.html + if (uri.endsWith('/')) { + request.uri += 'index.html'; + } + // Ejemplo: /meetups → /meetups/index.html + else if (!uri.includes('.')) { + request.uri += '/index.html'; + } + + return request; +} +``` + +**Flujo de ejecución:** +1. Usuario solicita `https://pythoncdmx.org/meetups/` +2. CloudFront recibe el request en la edge location +3. **CloudFront Function** intercepta y reescribe: `/meetups/` → `/meetups/index.html` +4. CloudFront solicita a S3: `s3://bucket/meetups/index.html` +5. S3 devuelve el archivo (existe en S3 gracias a MkDocs) +6. CloudFront devuelve la respuesta al usuario + +### Alternativas Consideradas (No Implementadas) + +1. **Lambda@Edge:** Más potente pero: + - ❌ Más costoso (~$0.60 por millón vs $0.10) + - ❌ Mayor latencia (ejecuta en regional edge cache) + - ❌ Más complejo de mantener + +2. **Cambiar a `--no-directory-urls`:** + - ❌ URLs menos amigables (`/meetups.html`) + - ❌ Rompe links existentes + - ❌ Peor SEO + +3. **S3 Redirects:** + - ❌ No funciona con CloudFront OAC + - ❌ Requiere S3 public (inseguro) + +## 🎯 Próximos Pasos + +1. **Desplegar los cambios** siguiendo la sección "Pasos para Desplegar" +2. **Verificar** que todas las URLs funcionan correctamente +3. **Monitorear** CloudFront metrics durante las primeras 24 horas +4. **Documentar** en el README del proyecto que se usa CloudFront Functions + +## 🆘 Soporte + +Si encuentras problemas durante el despliegue: + +1. Revisa el output de `terraform plan` y `terraform apply` +2. Verifica los logs de CloudWatch (si están habilitados) +3. Consulta la documentación de AWS: + - [CloudFront Functions](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cloudfront-functions.html) + - [CloudFront Distribution](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/distribution-working-with.html) + +--- + +**Fecha de implementación:** 2025-10-25 +**Autor:** Claude Code +**Versión:** 1.0 diff --git a/terraform/cloudfront-function.tf b/terraform/cloudfront-function.tf new file mode 100644 index 0000000..990e9da --- /dev/null +++ b/terraform/cloudfront-function.tf @@ -0,0 +1,52 @@ +# CloudFront Function to handle directory index rewriting for production +# This function adds index.html to requests ending with / +resource "aws_cloudfront_function" "directory_index" { + name = "pythoncdmx-directory-index" + runtime = "cloudfront-js-1.0" + comment = "Rewrites URLs ending with / to /index.html for MkDocs directory structure" + publish = true + + code = <<-EOT +function handler(event) { + var request = event.request; + var uri = request.uri; + + // Check if the URI ends with '/' + if (uri.endsWith('/')) { + request.uri += 'index.html'; + } + // Check if the URI doesn't have a file extension + else if (!uri.includes('.')) { + request.uri += '/index.html'; + } + + return request; +} +EOT +} + +# CloudFront Function for staging environment +resource "aws_cloudfront_function" "directory_index_staging" { + name = "pythoncdmx-directory-index-staging" + runtime = "cloudfront-js-1.0" + comment = "Rewrites URLs ending with / to /index.html for MkDocs directory structure (Staging)" + publish = true + + code = <<-EOT +function handler(event) { + var request = event.request; + var uri = request.uri; + + // Check if the URI ends with '/' + if (uri.endsWith('/')) { + request.uri += 'index.html'; + } + // Check if the URI doesn't have a file extension + else if (!uri.includes('.')) { + request.uri += '/index.html'; + } + + return request; +} +EOT +} diff --git a/terraform/cloudfront-staging.tf b/terraform/cloudfront-staging.tf index 3504eb0..9d5bc91 100644 --- a/terraform/cloudfront-staging.tf +++ b/terraform/cloudfront-staging.tf @@ -39,9 +39,15 @@ resource "aws_cloudfront_distribution" "website_staging" { viewer_protocol_policy = "redirect-to-https" min_ttl = 0 - default_ttl = 300 # 5 minutes - shorter cache for staging - max_ttl = 3600 # 1 hour - shorter cache for staging + default_ttl = 300 # 5 minutes - shorter cache for staging + max_ttl = 3600 # 1 hour - shorter cache for staging compress = true + + # Associate CloudFront Function for directory index rewriting + function_association { + event_type = "viewer-request" + function_arn = aws_cloudfront_function.directory_index_staging.arn + } } # Cache behavior for static assets (CSS) - shorter cache for staging @@ -60,8 +66,8 @@ resource "aws_cloudfront_distribution" "website_staging" { viewer_protocol_policy = "redirect-to-https" min_ttl = 0 - default_ttl = 1800 # 30 minutes - max_ttl = 7200 # 2 hours + default_ttl = 1800 # 30 minutes + max_ttl = 7200 # 2 hours compress = true } @@ -81,8 +87,8 @@ resource "aws_cloudfront_distribution" "website_staging" { viewer_protocol_policy = "redirect-to-https" min_ttl = 0 - default_ttl = 1800 # 30 minutes - max_ttl = 7200 # 2 hours + default_ttl = 1800 # 30 minutes + max_ttl = 7200 # 2 hours compress = true } @@ -102,8 +108,8 @@ resource "aws_cloudfront_distribution" "website_staging" { viewer_protocol_policy = "redirect-to-https" min_ttl = 0 - default_ttl = 3600 # 1 hour - max_ttl = 86400 # 24 hours + default_ttl = 3600 # 1 hour + max_ttl = 86400 # 24 hours compress = true } diff --git a/terraform/cloudfront.tf b/terraform/cloudfront.tf index 8e7da3c..62bcc36 100644 --- a/terraform/cloudfront.tf +++ b/terraform/cloudfront.tf @@ -39,9 +39,15 @@ resource "aws_cloudfront_distribution" "website" { viewer_protocol_policy = "redirect-to-https" min_ttl = 0 - default_ttl = 3600 # 1 hour - max_ttl = 86400 # 24 hours + default_ttl = 3600 # 1 hour + max_ttl = 86400 # 24 hours compress = true + + # Associate CloudFront Function for directory index rewriting + function_association { + event_type = "viewer-request" + function_arn = aws_cloudfront_function.directory_index.arn + } } # Cache behavior for static assets (images, CSS, JS) @@ -60,7 +66,7 @@ resource "aws_cloudfront_distribution" "website" { viewer_protocol_policy = "redirect-to-https" min_ttl = 0 - default_ttl = 86400 # 24 hours + default_ttl = 86400 # 24 hours max_ttl = 31536000 # 1 year compress = true } @@ -80,7 +86,7 @@ resource "aws_cloudfront_distribution" "website" { viewer_protocol_policy = "redirect-to-https" min_ttl = 0 - default_ttl = 86400 # 24 hours + default_ttl = 86400 # 24 hours max_ttl = 31536000 # 1 year compress = true } @@ -100,7 +106,7 @@ resource "aws_cloudfront_distribution" "website" { viewer_protocol_policy = "redirect-to-https" min_ttl = 0 - default_ttl = 604800 # 7 days + default_ttl = 604800 # 7 days max_ttl = 31536000 # 1 year compress = true } diff --git a/terraform/outputs.tf b/terraform/outputs.tf index 18001f7..6d21944 100644 --- a/terraform/outputs.tf +++ b/terraform/outputs.tf @@ -27,9 +27,9 @@ output "certificate_validation_records" { description = "DNS validation records for the certificate" value = [ for dvo in aws_acm_certificate.website.domain_validation_options : { - name = dvo.resource_record_name - type = dvo.resource_record_type - value = dvo.resource_record_value + name = dvo.resource_record_name + type = dvo.resource_record_type + value = dvo.resource_record_value } ] }