<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tu codigo cotidiano</title>
    <description>The latest articles on DEV Community by Tu codigo cotidiano (@tu_codigocotidiano_f173d).</description>
    <link>https://dev.to/tu_codigocotidiano_f173d</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3375057%2Ffa90e872-13fe-4a57-b3d6-e75515a50879.png</url>
      <title>DEV Community: Tu codigo cotidiano</title>
      <link>https://dev.to/tu_codigocotidiano_f173d</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tu_codigocotidiano_f173d"/>
    <language>en</language>
    <item>
      <title>Construye tu primer servidor MCP con Python: de archivos Markdown a herramientas reutilizables</title>
      <dc:creator>Tu codigo cotidiano</dc:creator>
      <pubDate>Tue, 03 Nov 2026 16:09:39 +0000</pubDate>
      <link>https://dev.to/tu_codigocotidiano_f173d/construye-tu-primer-servidor-mcp-con-python-de-archivos-markdown-a-herramientas-reutilizables-16d1</link>
      <guid>https://dev.to/tu_codigocotidiano_f173d/construye-tu-primer-servidor-mcp-con-python-de-archivos-markdown-a-herramientas-reutilizables-16d1</guid>
      <description>&lt;p&gt;¿Y si pudieras convertir una carpeta de documentos Markdown en herramientas que otras aplicaciones puedan descubrir e invocar mediante un protocolo estándar?&lt;/p&gt;

&lt;p&gt;Eso es precisamente lo que construiremos utilizando &lt;strong&gt;Python y Model Context Protocol (MCP)&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué es MCP?
&lt;/h2&gt;

&lt;p&gt;Model Context Protocol es un protocolo abierto que permite que aplicaciones cliente se comuniquen con servidores que ofrecen herramientas y otras capacidades.&lt;/p&gt;

&lt;p&gt;No es un modelo de inteligencia artificial y tampoco necesitas contratar una API de IA para aprender a utilizarlo.&lt;/p&gt;

&lt;h2&gt;
  
  
  El proyecto: un servidor MCP para consultar notas
&lt;/h2&gt;

&lt;p&gt;En este tutorial desarrollamos un servidor local con tres herramientas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;listar_notas&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;buscar_notas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;consulta&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;leer_nota&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nombre&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sus responsabilidades son sencillas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;listar_notas()&lt;/code&gt; enumera los documentos Markdown permitidos.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;buscar_notas()&lt;/code&gt; busca texto en el contenido de las notas.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;leer_nota()&lt;/code&gt; recupera el contenido de un archivo validado.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;El proyecto separa la comunicación MCP de la lógica que administra los archivos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cliente MCP
    ↓
Servidor MCP (server.py)
    ↓
NotesStore (notas_core.py)
    ↓
Documentos Markdown
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  No se trata solamente de hacer funcionar el servidor
&lt;/h2&gt;

&lt;p&gt;También exploramos decisiones de ingeniería importantes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validación de nombres para rechazar rutas no permitidas.&lt;/li&gt;
&lt;li&gt;Restricción de tamaño y cantidad de documentos.&lt;/li&gt;
&lt;li&gt;Manejo de errores controlados.&lt;/li&gt;
&lt;li&gt;Pruebas unitarias y de integración con pytest.&lt;/li&gt;
&lt;li&gt;Ejecución de un cliente Python.&lt;/li&gt;
&lt;li&gt;Inspección visual con MCP Inspector.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;El servidor es un ejemplo educativo de solo lectura, no un sistema de aislamiento completo para ejecutar con archivos no confiables.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué aprenderás?
&lt;/h2&gt;

&lt;p&gt;Al terminar, comprenderás cómo un cliente descubre herramientas, cómo invoca operaciones con argumentos estructurados y cómo recibe resultados mediante MCP.&lt;/p&gt;

&lt;p&gt;También podrás ampliar el proyecto para integrar tus propios documentos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No necesitas un LLM ni claves de API. Solo Python, curiosidad y ganas de comprender cómo funciona el protocolo.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;📚 &lt;strong&gt;Tutorial completo en Tu Código Cotidiano:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tucodigocotidiano.yarumaltech.com/leer_tutoriales/crea-tu-primer-servidor-mcp-con-python-herramientas-para-consultar-documentos-markdown/" rel="noopener noreferrer"&gt;https://tucodigocotidiano.yarumaltech.com/leer_tutoriales/crea-tu-primer-servidor-mcp-con-python-herramientas-para-consultar-documentos-markdown/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;El tutorial incluye código fuente, ejemplos, pruebas y ejercicios para seguir experimentando.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Qué herramienta MCP te gustaría construir después?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>mcp</category>
      <category>tutorial</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Harvest Now, Decrypt Later: ¿por qué Internet está cambiando su criptografía?</title>
      <dc:creator>Tu codigo cotidiano</dc:creator>
      <pubDate>Mon, 02 Nov 2026 12:49:00 +0000</pubDate>
      <link>https://dev.to/tu_codigocotidiano_f173d/harvest-now-decrypt-later-por-que-internet-esta-cambiando-su-criptografia-299c</link>
      <guid>https://dev.to/tu_codigocotidiano_f173d/harvest-now-decrypt-later-por-que-internet-esta-cambiando-su-criptografia-299c</guid>
      <description>&lt;p&gt;Imagina que alguien intercepta hoy una comunicación cifrada.&lt;/p&gt;

&lt;p&gt;No puede leerla.&lt;/p&gt;

&lt;p&gt;No conoce las claves.&lt;/p&gt;

&lt;p&gt;No tiene capacidad para romper los mecanismos criptográficos utilizados.&lt;/p&gt;

&lt;p&gt;Pero decide almacenarla.&lt;/p&gt;

&lt;p&gt;Diez años después, una nueva generación de computadoras podría permitirle analizar esa información con técnicas que hoy no están disponibles.&lt;/p&gt;

&lt;p&gt;¿Podría recuperar datos que parecían protegidos para siempre?&lt;/p&gt;

&lt;p&gt;Esta es la pregunta detrás de una amenaza conocida como Harvest Now, Decrypt Later (HNDL).&lt;/p&gt;

&lt;p&gt;Y explica por qué la criptografía poscuántica se está convirtiendo en una prioridad real para la seguridad de Internet.&lt;/p&gt;

&lt;p&gt;El problema no comienza cuando llega la computadora cuántica&lt;/p&gt;

&lt;p&gt;La computación cuántica promete resolver determinadas clases de problemas matemáticos de formas muy diferentes a la computación convencional.&lt;/p&gt;

&lt;p&gt;En particular, una computadora cuántica suficientemente potente y tolerante a fallos podría comprometer algoritmos de clave pública basados en problemas como la factorización de enteros o el logaritmo discreto.&lt;/p&gt;

&lt;p&gt;Eso incluye mecanismos clásicos como RSA y determinados sistemas de intercambio de claves basados en curvas elípticas.&lt;/p&gt;

&lt;p&gt;Pero hay una distinción importante:&lt;/p&gt;

&lt;p&gt;No toda la criptografía actual quedaría automáticamente inutilizada.&lt;/p&gt;

&lt;p&gt;La amenaza es especialmente relevante para ciertos mecanismos de clave pública. Los algoritmos simétricos presentan un panorama diferente.&lt;/p&gt;

&lt;p&gt;El problema es que algunas comunicaciones capturadas hoy podrían depender de mecanismos vulnerables a futuros ataques cuánticos.&lt;/p&gt;

&lt;p&gt;¿Qué tiene que ver esto con HTTPS?&lt;/p&gt;

&lt;p&gt;Cuando navegamos por Internet, TLS permite establecer conexiones protegidas entre clientes y servidores.&lt;/p&gt;

&lt;p&gt;En una conexión TLS moderna, el establecimiento de claves y el cifrado del tráfico cumplen funciones diferentes.&lt;/p&gt;

&lt;p&gt;Primero se establece material secreto compartido.&lt;/p&gt;

&lt;p&gt;Después se utiliza criptografía simétrica para proteger los datos intercambiados.&lt;/p&gt;

&lt;p&gt;Una conexión que dependa exclusivamente de un intercambio clásico vulnerable a ataques cuánticos futuros podría exponer información histórica si un adversario conserva los datos necesarios.&lt;/p&gt;

&lt;p&gt;Eso convierte el tiempo en una variable de seguridad.&lt;/p&gt;

&lt;p&gt;Si un secreto solo necesita mantenerse privado durante unas horas, su riesgo es diferente del de una historia clínica o un documento confidencial que debe permanecer protegido durante décadas.&lt;/p&gt;

&lt;p&gt;ML-KEM: una respuesta diseñada para el futuro&lt;/p&gt;

&lt;p&gt;En agosto de 2024, el NIST publicó el estándar FIPS 203, que especifica ML-KEM.&lt;/p&gt;

&lt;p&gt;ML-KEM es un mecanismo de encapsulación de claves diseñado para permitir que dos participantes establezcan un secreto compartido utilizando técnicas basadas en problemas matemáticos para los que no se conocen ataques cuánticos eficientes capaces de romper sus parámetros recomendados.&lt;/p&gt;

&lt;p&gt;Algo especialmente interesante es que no necesitamos una computadora cuántica para utilizar criptografía poscuántica.&lt;/p&gt;

&lt;p&gt;Los algoritmos se ejecutan en computadores convencionales.&lt;/p&gt;

&lt;p&gt;La palabra poscuántica describe el modelo de amenazas frente al cual se busca resistencia, no el hardware necesario para ejecutarlos.&lt;/p&gt;

&lt;p&gt;¿Por qué combinar algoritmos clásicos y poscuánticos?&lt;/p&gt;

&lt;p&gt;Una estrategia de transición consiste en utilizar mecanismos híbridos.&lt;/p&gt;

&lt;p&gt;Por ejemplo, un intercambio de claves puede combinar X25519 con ML-KEM y derivar secretos utilizando los resultados de ambos.&lt;/p&gt;

&lt;p&gt;La idea es no depender exclusivamente de un solo mecanismo criptográfico.&lt;/p&gt;

&lt;p&gt;Bajo una combinación correctamente diseñada, la protección puede mantenerse si al menos uno de los componentes conserva las propiedades de seguridad esperadas.&lt;/p&gt;

&lt;p&gt;Pero migrar Internet no consiste simplemente en cambiar una función criptográfica.&lt;/p&gt;

&lt;p&gt;También hay que considerar certificados digitales, firmas, bibliotecas, protocolos, infraestructura heredada, interoperabilidad y rendimiento.&lt;/p&gt;

&lt;p&gt;El mundo ya está preparando la transición&lt;/p&gt;

&lt;p&gt;El 27 de octubre de 2026, el NIST publicó nuevas directrices para orientar la migración hacia estándares de criptografía poscuántica.&lt;/p&gt;

&lt;p&gt;Esto no demuestra que ya exista una computadora cuántica capaz de romper los principales sistemas criptográficos desplegados a gran escala.&lt;/p&gt;

&lt;p&gt;Demuestra algo diferente: la transición es suficientemente compleja como para comenzar antes de que esa amenaza se materialice.&lt;/p&gt;

&lt;p&gt;Y hay una razón adicional.&lt;/p&gt;

&lt;p&gt;Los datos interceptados hoy no pueden protegerse retroactivamente simplemente actualizando mañana el servidor que los transmitió.&lt;/p&gt;

&lt;p&gt;Una pregunta de ingeniería&lt;/p&gt;

&lt;p&gt;Quizás la cuestión más importante no sea cuándo tendremos una computadora cuántica capaz de atacar determinados sistemas.&lt;/p&gt;

&lt;p&gt;Quizás sea esta:&lt;/p&gt;

&lt;p&gt;¿Cuánto tiempo necesita seguir siendo secreta la información que estamos transmitiendo hoy?&lt;/p&gt;

&lt;p&gt;Esa pregunta cambia la forma de diseñar sistemas seguros.&lt;/p&gt;

&lt;p&gt;La criptografía no debe proteger únicamente frente a las capacidades presentes de un atacante. También debe considerar la vida útil de los datos.&lt;/p&gt;

&lt;p&gt;🎙️ Una explicación en menos de cuatro minutos&lt;/p&gt;

&lt;p&gt;En Tu Código Cotidiano, preparamos un episodio donde Javier y Laura exploran esta amenaza, el funcionamiento de la criptografía poscuántica y por qué Internet está adoptando nuevos mecanismos de protección.&lt;/p&gt;

&lt;p&gt;El episodio está narrado en español y pensado para personas interesadas en tecnología, ingeniería y seguridad.&lt;/p&gt;

&lt;p&gt;🎧 Escuchar: ¿Y si roban tus datos hoy para descifrarlos en 10 años?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tucodigocotidiano.yarumaltech.com/escuchar-podcast/y-si-roban-tus-datos-hoy-para-descifrarlos-en-10-anos-criptografia-poscuantica/" rel="noopener noreferrer"&gt;https://tucodigocotidiano.yarumaltech.com/escuchar-podcast/y-si-roban-tus-datos-hoy-para-descifrarlos-en-10-anos-criptografia-poscuantica/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para profundizar, puedes consultar la documentación oficial:&lt;/p&gt;

&lt;p&gt;NIST — Post-Quantum Cryptography&lt;/p&gt;

&lt;p&gt;NIST — FIPS 203: ML-KEM&lt;/p&gt;

&lt;p&gt;NIST — Transición a estándares poscuánticos (2026)&lt;/p&gt;

&lt;p&gt;Pregunta para la comunidad:&lt;/p&gt;

&lt;p&gt;Si estuvieras diseñando hoy una API que almacena datos sensibles durante veinte años, ¿incluirías criptografía poscuántica desde el inicio o esperarías a que la adopción fuera más amplia?&lt;/p&gt;

</description>
      <category>security</category>
      <category>cybersecurity</category>
      <category>cryptography</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Cómo conectar una IA con tus datos usando MCP y Python</title>
      <dc:creator>Tu codigo cotidiano</dc:creator>
      <pubDate>Fri, 30 Oct 2026 21:13:13 +0000</pubDate>
      <link>https://dev.to/tu_codigocotidiano_f173d/como-conectar-una-ia-con-tus-datos-usando-mcp-y-python-fkh</link>
      <guid>https://dev.to/tu_codigocotidiano_f173d/como-conectar-una-ia-con-tus-datos-usando-mcp-y-python-fkh</guid>
      <description>&lt;h1&gt;
  
  
  Cómo conectar una IA con tus datos usando MCP y Python
&lt;/h1&gt;

&lt;p&gt;¿Una inteligencia artificial puede consultar tu inventario en lugar de inventar una respuesta?&lt;/p&gt;

&lt;p&gt;Para explorar esta pregunta construí &lt;strong&gt;StockBridge&lt;/strong&gt;, un servidor MCP en Python que permite a un asistente consultar productos, precios y existencias desde un archivo JSON.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué es MCP?
&lt;/h2&gt;

&lt;p&gt;Model Context Protocol (MCP) es un protocolo que permite conectar aplicaciones de inteligencia artificial con herramientas y fuentes de información externas.&lt;/p&gt;

&lt;p&gt;En nuestro ejemplo, el funcionamiento es:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Usuario → Asistente de IA → Servidor MCP → Inventario JSON&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;El asistente solicita una consulta, el servidor ejecuta una función Python y devuelve los resultados.&lt;/p&gt;

&lt;h2&gt;
  
  
  Construyendo StockBridge
&lt;/h2&gt;

&lt;p&gt;El proyecto utiliza Python, el SDK &lt;code&gt;mcp==2.3.0&lt;/code&gt; y un inventario ficticio de cinco productos.&lt;/p&gt;

&lt;p&gt;Implementé dos herramientas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;buscar_producto(nombre)&lt;/code&gt;: encuentra productos por nombre.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;productos_por_agotarse(limite=5)&lt;/code&gt;: identifica productos cuyas existencias están por debajo de un límite.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Esta es la segunda herramienta:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@mcp.tool&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;productos_por_agotarse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;limite&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;BajoStock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;limite&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;limite&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ToolError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Límite inválido&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;encontrados&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;INVENTARIO&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stock&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;limite&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stock&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;productos&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;encontrados&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;total&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;encontrados&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;limite&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;limite&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este fragmento forma parte del servidor completo, donde se definen &lt;code&gt;mcp&lt;/code&gt;, &lt;code&gt;BajoStock&lt;/code&gt;, &lt;code&gt;ToolError&lt;/code&gt; e &lt;code&gt;INVENTARIO&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;El decorador &lt;code&gt;@mcp.tool()&lt;/code&gt; permite registrar la función como una herramienta que un cliente MCP puede descubrir y ejecutar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resultados de la consulta
&lt;/h2&gt;

&lt;p&gt;Al ejecutar la herramienta con &lt;code&gt;limite=5&lt;/code&gt;, obtuvimos:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Producto&lt;/th&gt;
&lt;th&gt;Existencias&lt;/th&gt;
&lt;th&gt;Precio&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Miel 250 g&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;$18.000 COP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Café en grano 500 g&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;$28.000 COP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Café molido 500 g&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;$24.000 COP&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Los productos y precios son ficticios, pero la consulta se realiza sobre el archivo JSON.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Cómo sabemos que realmente funciona?
&lt;/h2&gt;

&lt;p&gt;No quería limitarme a mostrar una respuesta aparentemente correcta.&lt;/p&gt;

&lt;p&gt;Por eso desarrollé &lt;strong&gt;11 pruebas automatizadas&lt;/strong&gt;: diez verificaciones funcionales y una prueba de integración que inicia el servidor y se comunica mediante MCP sobre &lt;code&gt;stdio&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;También conecté StockBridge con GitHub Copilot en Visual Studio Code.&lt;/p&gt;

&lt;p&gt;Durante la demostración, Copilot ejecutó la herramienta &lt;code&gt;productos_por_agotarse&lt;/code&gt; y utilizó sus resultados.&lt;/p&gt;

&lt;p&gt;Esto demuestra una diferencia importante:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No es lo mismo que una IA genere una respuesta a que consulte datos mediante una herramienta verificable.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tutorial completo
&lt;/h2&gt;

&lt;p&gt;Documenté el proyecto paso a paso en TuCodigoCotidiano.&lt;/p&gt;

&lt;p&gt;El tutorial explica cómo crear el inventario JSON, construir el servidor Python, validar datos, ejecutar pruebas, utilizar MCP Inspector y conectar las herramientas con GitHub Copilot.&lt;/p&gt;

&lt;p&gt;Incluye el código necesario para reproducir el laboratorio.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://tucodigocotidiano.yarumaltech.com/leer_tutoriales/mcp-con-python-permite-que-una-ia-consulte-tu-inventario/" rel="noopener noreferrer"&gt;Leer el tutorial completo: MCP con Python, permite que una IA consulte tu inventario&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;MCP permite construir asistentes que pueden utilizar herramientas para acceder a información específica.&lt;/p&gt;

&lt;p&gt;Pero también necesitamos verificar las llamadas, validar los datos y controlar los permisos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Una cosa es que una IA responda. Otra muy distinta es demostrar que consultó los datos.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;¿Qué herramienta conectarías primero a un asistente mediante MCP?&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>mcp</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Bitácora Git: convierte cambios en una historia verificable</title>
      <dc:creator>Tu codigo cotidiano</dc:creator>
      <pubDate>Tue, 27 Oct 2026 17:01:07 +0000</pubDate>
      <link>https://dev.to/tu_codigocotidiano_f173d/bitacora-git-convierte-cambios-en-una-historia-verificable-1572</link>
      <guid>https://dev.to/tu_codigocotidiano_f173d/bitacora-git-convierte-cambios-en-una-historia-verificable-1572</guid>
      <description>&lt;p&gt;Un laboratorio educativo para aprender Git y GitHub conectando cambios, decisiones, revisiones, pruebas y firmas.&lt;/p&gt;

&lt;p&gt;Inspiración:&lt;br&gt;
Un proyecto puede conservar todas sus versiones y seguir siendo difícil de entender. Quería crear una práctica donde cada cambio tuviera un motivo y una evidencia que permitiera comprobarlo.&lt;/p&gt;

&lt;p&gt;El laboratorio:&lt;br&gt;
La guía propone construir bitacora-git, un pequeño proyecto en Python que normaliza títulos. Una mejora incorpora el rechazo de entradas vacías y permite recorrer un flujo completo de desarrollo.&lt;/p&gt;

&lt;p&gt;Quien siga la práctica aprenderá a preparar cambios, crear commits claros, trabajar con ramas, abrir pull requests y configurar pruebas automáticas. Después resolverá un conflicto, recuperará un commit y localizará una regresión con git bisect.&lt;/p&gt;

&lt;p&gt;El recorrido termina con firmas SSH, una etiqueta de entrega y la comprobación desde un clon limpio.&lt;/p&gt;

&lt;p&gt;Qué aporta:&lt;br&gt;
Cada etapa conecta una decisión con una evidencia concreta. También explica los límites: unas pruebas correctas cubren determinados casos y una firma válida requiere comprobar la confianza en la clave.&lt;/p&gt;

&lt;p&gt;Tecnologías:&lt;br&gt;
Git, GitHub, Python, unittest, PowerShell y GitHub Actions.&lt;/p&gt;

&lt;p&gt;Guía y procedimiento:&lt;br&gt;
&lt;a href="https://tucodigocotidiano.yarumaltech.com/leer_guias/git-y-github-convierte-cambios-en-una-historia-verificable/" rel="noopener noreferrer"&gt;https://tucodigocotidiano.yarumaltech.com/leer_guias/git-y-github-convierte-cambios-en-una-historia-verificable/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>programming</category>
      <category>devops</category>
    </item>
    <item>
      <title>Python 3.15: ¿lazy import acelera tus programas? Una prueba real</title>
      <dc:creator>Tu codigo cotidiano</dc:creator>
      <pubDate>Tue, 13 Oct 2026 10:24:30 +0000</pubDate>
      <link>https://dev.to/tu_codigocotidiano_f173d/python-315-lazy-import-acelera-tus-programas-una-prueba-real-1dcj</link>
      <guid>https://dev.to/tu_codigocotidiano_f173d/python-315-lazy-import-acelera-tus-programas-una-prueba-real-1dcj</guid>
      <description>&lt;p&gt;Python 3.15 se lanzó oficialmente el 9 de octubre de 2026, incorporando nuevas características para mejorar la expresividad del lenguaje y ofrecer más control sobre la ejecución de nuestros programas.&lt;/p&gt;

&lt;p&gt;Pero hay una diferencia importante entre conocer una novedad y comprobar su funcionamiento.&lt;/p&gt;

&lt;p&gt;Decidí instalar Python 3.15.0 en Windows y realizar un pequeño experimento.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué sucede con lazy import?
&lt;/h2&gt;

&lt;p&gt;Tradicionalmente, cuando Python encuentra una instrucción &lt;code&gt;import&lt;/code&gt;, carga e inicializa el módulo correspondiente.&lt;/p&gt;

&lt;p&gt;Python 3.15 incorpora la posibilidad de realizar importaciones diferidas mediante la nueva sintaxis &lt;code&gt;lazy import&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Esto permite aplazar la inicialización de determinados módulos hasta que sean utilizados.&lt;/p&gt;

&lt;h3&gt;
  
  
  El experimento
&lt;/h3&gt;

&lt;p&gt;Preparé un módulo llamado &lt;code&gt;modulo_pesado.py&lt;/code&gt; con una espera artificial de dos segundos durante su inicialización.&lt;/p&gt;

&lt;p&gt;Después comparé dos situaciones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Una importación tradicional mediante &lt;code&gt;import modulo_pesado&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Una importación diferida mediante &lt;code&gt;lazy import modulo_pesado&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Utilicé &lt;code&gt;time.perf_counter()&lt;/code&gt; para medir los tiempos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resultados
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operación&lt;/th&gt;
&lt;th&gt;Tiempo observado&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Importación tradicional&lt;/td&gt;
&lt;td&gt;2,006 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Declaración con lazy import&lt;/td&gt;
&lt;td&gt;0,000 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Primer uso del módulo diferido&lt;/td&gt;
&lt;td&gt;2,002 s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;El valor de 0,000 segundos está redondeado a tres decimales. No significa que la declaración tenga un costo absolutamente nulo.&lt;/p&gt;

&lt;p&gt;Además, la espera utilizada era artificial, por lo que estos números no representan una mejora general de rendimiento.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué aprendí?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;lazy import&lt;/code&gt; no elimina el costo de importar un módulo: cambia el momento en que se realiza.&lt;/p&gt;

&lt;p&gt;Puede resultar útil en herramientas de línea de comandos, aplicaciones con funcionalidades opcionales o proyectos con numerosas dependencias.&lt;/p&gt;

&lt;p&gt;Sin embargo, también hay que considerar que la inicialización y los posibles errores de importación pueden ocurrir más tarde.&lt;/p&gt;

&lt;p&gt;La recomendación es medir antes de optimizar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Otras novedades de Python 3.15
&lt;/h2&gt;

&lt;p&gt;Además de las importaciones diferidas, esta versión incorpora mejoras interesantes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;frozendict:&lt;/strong&gt; diccionarios cuyas entradas no pueden modificarse.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;sentinel:&lt;/strong&gt; marcadores únicos para diferenciar la ausencia de un valor de &lt;code&gt;None&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unpacking en comprensiones:&lt;/strong&gt; nuevas formas de combinar colecciones mediante &lt;code&gt;*&lt;/code&gt; y &lt;code&gt;**&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UTF-8 por defecto:&lt;/strong&gt; un comportamiento más uniforme en el manejo de texto.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tachyon:&lt;/strong&gt; herramientas integradas para analizar dónde consume tiempo un programa.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Guía completa en español
&lt;/h2&gt;

&lt;p&gt;En Tu Código Cotidiano publiqué una guía dedicada a Python 3.15, que incluye instalación en Windows, ejemplos ejecutables y pruebas de sus seis novedades destacadas.&lt;/p&gt;

&lt;p&gt;Puedes consultar gratuitamente la primera parte. El contenido restante forma parte de la membresía Premium.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://tucodigocotidiano.yarumaltech.com/leer_guias/python-315-desde-cero-instalacion-seis-novedades-y-pruebas-reales/" rel="noopener noreferrer"&gt;Leer Python 3.15 desde cero: instalación, seis novedades y pruebas reales&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Y ahora una pregunta para la comunidad:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Qué novedad de Python 3.15 consideras más útil para proyectos reales?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Publicado por Tu Código Cotidiano.&lt;/p&gt;

</description>
      <category>python</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>performance</category>
    </item>
    <item>
      <title>Python Virtual Environments Finally Explained: venv, pip and Dependencies</title>
      <dc:creator>Tu codigo cotidiano</dc:creator>
      <pubDate>Tue, 06 Oct 2026 16:41:39 +0000</pubDate>
      <link>https://dev.to/tu_codigocotidiano_f173d/python-virtual-environments-finally-explained-venv-pip-and-dependencies-1p7a</link>
      <guid>https://dev.to/tu_codigocotidiano_f173d/python-virtual-environments-finally-explained-venv-pip-and-dependencies-1p7a</guid>
      <description>&lt;h1&gt;
  
  
  Python Virtual Environments Finally Explained: venv, pip and Dependencies
&lt;/h1&gt;

&lt;p&gt;A Python virtual environment isn't a tiny virtual machine.&lt;/p&gt;

&lt;p&gt;It's a much simpler idea:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Give each project its own Python dependency context.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Imagine two projects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Project A → package 1.x
Project B → package 2.x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If both projects depend on the same global Python installation, sooner or later those requirements can collide.&lt;/p&gt;

&lt;p&gt;With virtual environments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Project A → .venv → package 1.x
Project B → .venv → package 2.x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each project gets its own dependency space.&lt;/p&gt;

&lt;h2&gt;
  
  
  Activating isn't magic
&lt;/h2&gt;

&lt;p&gt;When you activate a virtual environment, you're not starting another operating system.&lt;/p&gt;

&lt;p&gt;You're mainly changing which executables your shell finds first.&lt;/p&gt;

&lt;p&gt;That's why this is such a useful diagnostic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"import sys; print(sys.executable)"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of trusting the &lt;code&gt;(.venv)&lt;/code&gt; label, ask Python which interpreter is actually running.&lt;/p&gt;

&lt;h2&gt;
  
  
  The same idea applies to pip
&lt;/h2&gt;

&lt;p&gt;I prefer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install &lt;/span&gt;requests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;because it makes the relationship explicit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chosen Python
→ its pip
→ its packages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  And the environment shouldn't be precious
&lt;/h2&gt;

&lt;p&gt;A useful mental model is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The environment is disposable. The recipe to rebuild it isn't.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's why we usually keep things like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;source code
requirements.txt
.gitignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in Git, but not the entire &lt;code&gt;.venv&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;I wrote a complete visual guide covering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;venv&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;activation&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pip&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;direct vs transitive dependencies&lt;/li&gt;
&lt;li&gt;&lt;code&gt;requirements.txt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Git&lt;/li&gt;
&lt;li&gt;rebuilding environments&lt;/li&gt;
&lt;li&gt;common debugging mistakes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Full guide in Spanish:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tucodigocotidiano.yarumaltech.com/leer_guias/entornos-virtuales-y-dependencias-cada-proyecto-en-su-propia-burbuja/" rel="noopener noreferrer"&gt;https://tucodigocotidiano.yarumaltech.com/leer_guias/entornos-virtuales-y-dependencias-cada-proyecto-en-su-propia-burbuja/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One question for Python developers:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can you delete your virtual environment today and rebuild it without guessing what was installed?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fag04rdhbwfe8pqs6uv32.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fag04rdhbwfe8pqs6uv32.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>beginners</category>
      <category>programming</category>
      <category>devops</category>
    </item>
    <item>
      <title>El candado no significa lo que crees: qué protege realmente HTTPS</title>
      <dc:creator>Tu codigo cotidiano</dc:creator>
      <pubDate>Mon, 05 Oct 2026 13:19:26 +0000</pubDate>
      <link>https://dev.to/tu_codigocotidiano_f173d/el-candado-no-significa-lo-que-crees-que-protege-realmente-https-4a6b</link>
      <guid>https://dev.to/tu_codigocotidiano_f173d/el-candado-no-significa-lo-que-crees-que-protege-realmente-https-4a6b</guid>
      <description>&lt;p&gt;Hay una idea que hemos aprendido casi automáticamente al navegar por Internet:&lt;/p&gt;

&lt;p&gt;🔒 Candado = página segura.&lt;/p&gt;

&lt;p&gt;Pero no es exactamente así.&lt;/p&gt;

&lt;p&gt;HTTPS puede ofrecer una conexión criptográficamente protegida con una página que, aun así, pertenece a un atacante.&lt;/p&gt;

&lt;p&gt;Entonces, ¿qué protege realmente HTTPS?&lt;/p&gt;

&lt;p&gt;HTTPS protege la conexión&lt;/p&gt;

&lt;p&gt;Cuando visitas una dirección que comienza con https://, HTTP funciona sobre TLS.&lt;/p&gt;

&lt;p&gt;Antes de intercambiar normalmente el contenido de la página, navegador y servidor realizan un TLS handshake.&lt;/p&gt;

&lt;p&gt;De forma simplificada, durante ese proceso deben resolver varias cosas:&lt;/p&gt;

&lt;p&gt;cómo protegerán la comunicación;&lt;/p&gt;

&lt;p&gt;cómo establecerán claves;&lt;/p&gt;

&lt;p&gt;cómo comprobará el navegador la identidad del servidor;&lt;/p&gt;

&lt;p&gt;y cómo sabrán si los datos fueron modificados.&lt;/p&gt;

&lt;p&gt;El resultado es un canal protegido entre ambos extremos.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Confidencialidad&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Imagina que estás conectado a una red Wi-Fi y escribes una contraseña.&lt;/p&gt;

&lt;p&gt;Sin protección criptográfica adecuada, alguien situado en el camino podría intentar observar el tráfico.&lt;/p&gt;

&lt;p&gt;TLS cifra el contenido de la comunicación.&lt;/p&gt;

&lt;p&gt;Eso significa que capturar los paquetes no debería permitir simplemente leer tu contraseña, una cookie de sesión o los datos HTTP intercambiados.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Integridad&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Cifrar no es suficiente.&lt;/p&gt;

&lt;p&gt;También necesitamos saber que alguien no cambió los datos mientras viajaban.&lt;/p&gt;

&lt;p&gt;Supongamos que una aplicación envía:&lt;/p&gt;

&lt;p&gt;transferir 100.000 pesos&lt;/p&gt;

&lt;p&gt;Un atacante situado en medio de la comunicación no debería poder transformarlo silenciosamente en:&lt;/p&gt;

&lt;p&gt;transferir 1.000.000 de pesos&lt;/p&gt;

&lt;p&gt;TLS utiliza mecanismos criptográficos que permiten detectar alteraciones en los datos protegidos.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Autenticación&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Aquí aparecen los certificados digitales.&lt;/p&gt;

&lt;p&gt;El servidor presenta un certificado relacionado con el dominio que estás visitando y demuestra que posee la clave privada correspondiente.&lt;/p&gt;

&lt;p&gt;Tu navegador comprueba, entre otras cosas, la cadena de confianza, el dominio y la validez del certificado.&lt;/p&gt;

&lt;p&gt;Eso ayuda a evitar que cualquier servidor pueda simplemente afirmar:&lt;/p&gt;

&lt;p&gt;“Yo soy ese sitio web”.&lt;/p&gt;

&lt;p&gt;¿Y de dónde sale la clave para cifrar?&lt;/p&gt;

&lt;p&gt;Esta es una de las partes más interesantes.&lt;/p&gt;

&lt;p&gt;Al principio, navegador y servidor todavía no comparten el secreto que utilizarán para proteger la sesión.&lt;/p&gt;

&lt;p&gt;Durante el handshake utilizan criptografía de clave pública e intercambio de claves para conseguir material secreto compartido.&lt;/p&gt;

&lt;p&gt;Después pueden derivar claves de sesión.&lt;/p&gt;

&lt;p&gt;Y una vez establecida la sesión, la mayor parte de la comunicación puede protegerse mediante criptografía simétrica, mucho más eficiente para grandes cantidades de datos.&lt;/p&gt;

&lt;p&gt;Conceptualmente:&lt;/p&gt;

&lt;p&gt;Navegador&lt;br&gt;
    ↓&lt;br&gt;
TLS handshake&lt;br&gt;
    ↓&lt;br&gt;
Certificado + autenticación&lt;br&gt;
    ↓&lt;br&gt;
Intercambio de claves&lt;br&gt;
    ↓&lt;br&gt;
Claves de sesión&lt;br&gt;
    ↓&lt;br&gt;
Canal HTTP protegido&lt;br&gt;
    ↓&lt;br&gt;
Servidor&lt;/p&gt;

&lt;p&gt;Entonces… ¿qué significa realmente el candado?&lt;/p&gt;

&lt;p&gt;Aquí está la distinción importante.&lt;/p&gt;

&lt;p&gt;HTTPS puede decirte que estás manteniendo una conexión protegida con el dominio que aparece en tu navegador.&lt;/p&gt;

&lt;p&gt;Pero no puede garantizar que la persona que creó ese dominio tenga buenas intenciones.&lt;/p&gt;

&lt;p&gt;Un atacante puede registrar un dominio parecido al de un banco, obtener un certificado válido y construir una página de phishing.&lt;/p&gt;

&lt;p&gt;Y entonces ocurre algo curioso:&lt;/p&gt;

&lt;p&gt;TLS puede proteger perfectamente tu contraseña mientras viaja hacia el atacante.&lt;/p&gt;

&lt;p&gt;La criptografía funcionó.&lt;/p&gt;

&lt;p&gt;El problema estaba en que nosotros confiamos en el sitio equivocado.&lt;/p&gt;

&lt;p&gt;HTTPS tampoco significa anonimato&lt;/p&gt;

&lt;p&gt;TLS protege el contenido de la comunicación que transporta, pero no hace invisible toda tu actividad en Internet.&lt;/p&gt;

&lt;p&gt;Direcciones IP, DNS, características de las conexiones y otros metadatos pueden seguir proporcionando información dependiendo de la arquitectura utilizada.&lt;/p&gt;

&lt;p&gt;Por eso HTTPS es una pieza fundamental de la seguridad web, pero no es una capa mágica.&lt;/p&gt;

&lt;p&gt;La próxima vez que veas el candado…&lt;/p&gt;

&lt;p&gt;No pienses simplemente:&lt;/p&gt;

&lt;p&gt;“Esta página es segura”.&lt;/p&gt;

&lt;p&gt;Una interpretación mucho mejor sería:&lt;/p&gt;

&lt;p&gt;“Mi navegador ha establecido un canal criptográficamente protegido con este dominio”.&lt;/p&gt;

&lt;p&gt;Detrás de ese pequeño candado hay certificados, firmas digitales, intercambio de claves, criptografía simétrica y décadas de ingeniería de seguridad.&lt;/p&gt;

&lt;p&gt;🎙️ Hice un episodio de menos de cuatro minutos de Tu Código Cotidiano donde Javier y Laura explican toda esta historia de forma conversacional:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tucodigocotidiano.yarumaltech.com/escuchar-podcast/que-protege-hoy-https/" rel="noopener noreferrer"&gt;https://tucodigocotidiano.yarumaltech.com/escuchar-podcast/que-protege-hoy-https/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pregunta para la comunidad: ¿qué otra tecnología usamos todos los días pero casi nunca nos detenemos a pensar cómo funciona?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frsa1fc86opcnck5aj0ki.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frsa1fc86opcnck5aj0ki.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>I built Deception Mesh: an open-source Rust MVP for defensive cybersecurity telemetry</title>
      <dc:creator>Tu codigo cotidiano</dc:creator>
      <pubDate>Thu, 01 Oct 2026 14:41:18 +0000</pubDate>
      <link>https://dev.to/tu_codigocotidiano_f173d/i-built-deception-mesh-an-open-source-rust-mvp-for-defensive-cybersecurity-telemetry-4bka</link>
      <guid>https://dev.to/tu_codigocotidiano_f173d/i-built-deception-mesh-an-open-source-rust-mvp-for-defensive-cybersecurity-telemetry-4bka</guid>
      <description>&lt;p&gt;I just published &lt;strong&gt;Deception Mesh&lt;/strong&gt;, an open-source cybersecurity MVP built in Rust.&lt;/p&gt;

&lt;p&gt;Project page: &lt;a href="https://tucodigocotidiano.yarumaltech.com/proyectos/deception-mesh/" rel="noopener noreferrer"&gt;https://tucodigocotidiano.yarumaltech.com/proyectos/deception-mesh/&lt;/a&gt;&lt;br&gt;&lt;br&gt;
GitHub: &lt;a href="https://github.com/tucodigocotidiano/deception-mesh" rel="noopener noreferrer"&gt;https://github.com/tucodigocotidiano/deception-mesh&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I built it
&lt;/h2&gt;

&lt;p&gt;Most small projects and learning environments think about security only after something goes wrong.&lt;/p&gt;

&lt;p&gt;Firewalls, authentication and monitoring are important, but there is another useful defensive idea:&lt;/p&gt;

&lt;p&gt;What if we could deploy small decoy services that are not real production systems, but can help us observe suspicious behavior?&lt;/p&gt;

&lt;p&gt;That is the core idea behind Deception Mesh.&lt;/p&gt;

&lt;p&gt;Instead of exposing only real services, the project uses lightweight decoy sensors that can capture suspicious HTTP and SSH activity and turn it into structured telemetry.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Deception Mesh does
&lt;/h2&gt;

&lt;p&gt;Deception Mesh is a defensive MVP.&lt;/p&gt;

&lt;p&gt;It is not an offensive tool.&lt;/p&gt;

&lt;p&gt;It does not try to exploit systems.&lt;/p&gt;

&lt;p&gt;It does not provide attack automation.&lt;/p&gt;

&lt;p&gt;Its purpose is to help observe suspicious interactions against decoy services and make those events easier to inspect.&lt;/p&gt;

&lt;p&gt;The MVP includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP decoy sensor&lt;/li&gt;
&lt;li&gt;SSH decoy sensor&lt;/li&gt;
&lt;li&gt;REST API&lt;/li&gt;
&lt;li&gt;JWT authentication&lt;/li&gt;
&lt;li&gt;Role-based access control&lt;/li&gt;
&lt;li&gt;Webhook notifications&lt;/li&gt;
&lt;li&gt;CSV export&lt;/li&gt;
&lt;li&gt;Docker deployment&lt;/li&gt;
&lt;li&gt;Documentation for local execution and testing&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The technical idea
&lt;/h2&gt;

&lt;p&gt;The project is based on a simple flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A suspicious client interacts with a decoy service.&lt;/li&gt;
&lt;li&gt;The sensor captures the event.&lt;/li&gt;
&lt;li&gt;The system stores or exposes the event as structured telemetry.&lt;/li&gt;
&lt;li&gt;The operator can review the signal through logs, CSV exports, API responses or webhook notifications.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The goal is not to replace enterprise security platforms.&lt;/p&gt;

&lt;p&gt;The goal is to show that a small, understandable and auditable deception layer can be built with practical software engineering.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Rust
&lt;/h2&gt;

&lt;p&gt;I chose Rust because it is a strong fit for infrastructure-oriented security projects.&lt;/p&gt;

&lt;p&gt;It gives a good balance between performance, memory safety and explicit design.&lt;/p&gt;

&lt;p&gt;For a project that handles network-facing components, Rust also encourages discipline around error handling, data structures and system boundaries.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I wanted to prove
&lt;/h2&gt;

&lt;p&gt;With this MVP, I wanted to validate four things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A deception-based security concept can be implemented without building a huge platform.&lt;/li&gt;
&lt;li&gt;Rust can be used to create small defensive sensors with clean architecture.&lt;/li&gt;
&lt;li&gt;Security telemetry can be made understandable for developers and students.&lt;/li&gt;
&lt;li&gt;A project can be useful even when its scope is intentionally limited.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That last point matters.&lt;/p&gt;

&lt;p&gt;This is not presented as a finished commercial product.&lt;/p&gt;

&lt;p&gt;It is a validated MVP with a clear defensive scope and room for improvement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who this project is for
&lt;/h2&gt;

&lt;p&gt;This project may be useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Software engineering students&lt;/li&gt;
&lt;li&gt;Cybersecurity students&lt;/li&gt;
&lt;li&gt;Backend developers&lt;/li&gt;
&lt;li&gt;Rust learners&lt;/li&gt;
&lt;li&gt;People interested in defensive infrastructure&lt;/li&gt;
&lt;li&gt;Anyone curious about deception-based security&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It can also be a starting point for discussions around telemetry, detection, infrastructure hardening and practical security engineering.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current limitations
&lt;/h2&gt;

&lt;p&gt;The project is intentionally honest about its current stage.&lt;/p&gt;

&lt;p&gt;It is an MVP.&lt;/p&gt;

&lt;p&gt;It still needs more hardening, better testing, stronger deployment guidance and deeper validation before being treated as production-ready.&lt;/p&gt;

&lt;p&gt;That is part of the reason I am publishing it openly.&lt;/p&gt;

&lt;p&gt;I want feedback, technical criticism and ideas from people who care about building useful defensive systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;Deception Mesh started as a practical experiment, but it became a valuable learning project around cybersecurity, Rust, backend systems and telecommunications.&lt;/p&gt;

&lt;p&gt;If you are interested in open-source cybersecurity, defensive telemetry or Rust-based infrastructure, I would be happy if you take a look.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/tucodigocotidiano/deception-mesh" rel="noopener noreferrer"&gt;https://github.com/tucodigocotidiano/deception-mesh&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feedback, issues, stars and technical suggestions are welcome.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjyti7gth994gt1x6s1af.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjyti7gth994gt1x6s1af.png" alt=" " width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>rust</category>
      <category>opensource</category>
      <category>backend</category>
    </item>
    <item>
      <title>¿Cómo puede tu celular conectarse directamente con un satélite?</title>
      <dc:creator>Tu codigo cotidiano</dc:creator>
      <pubDate>Mon, 07 Sep 2026 23:16:10 +0000</pubDate>
      <link>https://dev.to/tu_codigocotidiano_f173d/como-puede-tu-celular-conectarse-directamente-con-un-satelite-1326</link>
      <guid>https://dev.to/tu_codigocotidiano_f173d/como-puede-tu-celular-conectarse-directamente-con-un-satelite-1326</guid>
      <description>&lt;p&gt;Imagina esto:&lt;/p&gt;

&lt;p&gt;Estás en una carretera, una montaña o una zona rural.&lt;/p&gt;

&lt;p&gt;Miras tu teléfono.&lt;/p&gt;

&lt;p&gt;Sin servicio.&lt;/p&gt;

&lt;p&gt;No hay una torre celular suficientemente cerca, pero cientos de kilómetros sobre tu cabeza pasa un satélite.&lt;/p&gt;

&lt;p&gt;¿Podría tu mismo teléfono conectarse con él?&lt;/p&gt;

&lt;p&gt;En determinados servicios, la respuesta ya es sí.&lt;/p&gt;

&lt;p&gt;Y técnicamente es fascinante.&lt;/p&gt;

&lt;p&gt;Una torre celular que se mueve por el espacio&lt;/p&gt;

&lt;p&gt;Una forma sencilla de entender Direct to Cell es imaginar ciertos satélites como una extensión de la infraestructura de una red móvil.&lt;/p&gt;

&lt;p&gt;El teléfono sigue teniendo enormes limitaciones:&lt;/p&gt;

&lt;p&gt;transmite con relativamente poca potencia;&lt;br&gt;
utiliza una antena diminuta;&lt;br&gt;
no fue diseñado como una gran terminal satelital.&lt;/p&gt;

&lt;p&gt;Por eso buena parte de la dificultad está del otro lado del enlace.&lt;/p&gt;

&lt;p&gt;El sistema satelital necesita detectar señales extremadamente débiles, gestionar haces de cobertura y mantener comunicación mientras el satélite se desplaza rápidamente respecto al usuario.&lt;/p&gt;

&lt;p&gt;Y entonces aparece Doppler&lt;/p&gt;

&lt;p&gt;Una torre terrestre normalmente permanece en el mismo lugar.&lt;/p&gt;

&lt;p&gt;Un satélite LEO no.&lt;/p&gt;

&lt;p&gt;Su velocidad relativa provoca desplazamiento Doppler en la señal, mientras cambian continuamente distancia, retardo y geometría del enlace.&lt;/p&gt;

&lt;p&gt;La red tiene que compensar todo eso mientras intenta ofrecer al teléfono una experiencia que se parezca, en lo posible, a conectarse a una red móvil convencional.&lt;/p&gt;

&lt;p&gt;De la red terrestre a las NTN&lt;/p&gt;

&lt;p&gt;Aquí entran las Non-Terrestrial Networks (NTN).&lt;/p&gt;

&lt;p&gt;La evolución de las redes móviles está integrando cada vez más componentes terrestres y satelitales.&lt;/p&gt;

&lt;p&gt;Eso abre una posibilidad interesante:&lt;/p&gt;

&lt;p&gt;En ciudades y lugares con alta demanda seguimos utilizando infraestructura terrestre por su enorme capacidad.&lt;/p&gt;

&lt;p&gt;Pero cuando esa cobertura desaparece, una red satelital podría convertirse en una capa adicional de conectividad.&lt;/p&gt;

&lt;p&gt;No significa “Internet ilimitado desde cualquier lugar”.&lt;/p&gt;

&lt;p&gt;La capacidad sigue siendo limitada y existen requisitos de espectro, compatibilidad, regulación y acuerdos con operadores.&lt;/p&gt;

&lt;p&gt;Pero incluso poder mantener mensajería o determinados servicios donde antes había cero conectividad cambia bastante las cosas.&lt;/p&gt;

&lt;p&gt;Hicimos un episodio para explicarlo&lt;/p&gt;

&lt;p&gt;En el nuevo episodio de Tu Código Cotidiano, Javier y Laura explican Direct to Cell desde cero:&lt;/p&gt;

&lt;p&gt;LEO&lt;br&gt;
espectro móvil&lt;br&gt;
Doppler&lt;br&gt;
estaciones base en el espacio&lt;br&gt;
NTN&lt;br&gt;
limitaciones actuales&lt;br&gt;
cobertura rural&lt;/p&gt;

&lt;p&gt;Todo en menos de cuatro minutos y sin asumir conocimientos avanzados de telecomunicaciones.&lt;/p&gt;

&lt;p&gt;🎧 Escuchar episodio:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tucodigocotidiano.yarumaltech.com/escuchar-podcast/tu-celular-conectado-directamente-a-satelites-como-es-posible/" rel="noopener noreferrer"&gt;https://tucodigocotidiano.yarumaltech.com/escuchar-podcast/tu-celular-conectado-directamente-a-satelites-como-es-posible/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La pregunta que más me interesa es esta:&lt;/p&gt;

&lt;p&gt;¿Crees que la conectividad satelital terminará siendo simplemente otra capa de nuestras redes móviles, hasta el punto de que los usuarios ni siquiera notemos cuándo cambiamos de una torre terrestre a un satélite?&lt;/p&gt;

</description>
      <category>telecommunications</category>
      <category>networking</category>
      <category>5g</category>
      <category>satellite</category>
    </item>
    <item>
      <title>How to Organize Python Code with Modules and Packages — A Practical Beginner Guide</title>
      <dc:creator>Tu codigo cotidiano</dc:creator>
      <pubDate>Thu, 03 Sep 2026 15:54:20 +0000</pubDate>
      <link>https://dev.to/tu_codigocotidiano_f173d/how-to-organize-python-code-with-modules-and-packages-a-practical-beginner-guide-4cp5</link>
      <guid>https://dev.to/tu_codigocotidiano_f173d/how-to-organize-python-code-with-modules-and-packages-a-practical-beginner-guide-4cp5</guid>
      <description>&lt;p&gt;A Python program can work perfectly and still become difficult to maintain.&lt;/p&gt;

&lt;p&gt;That usually happens when one file slowly starts doing everything:&lt;/p&gt;

&lt;p&gt;program.py&lt;/p&gt;

&lt;p&gt;├── register expenses&lt;br&gt;
├── save CSV files&lt;br&gt;
├── calculate totals&lt;br&gt;
├── generate reports&lt;br&gt;
└── run the program&lt;/p&gt;

&lt;p&gt;Nothing is necessarily broken.&lt;/p&gt;

&lt;p&gt;The problem is that finding and changing one responsibility starts requiring you to understand several unrelated parts of the file.&lt;/p&gt;

&lt;p&gt;The first useful question&lt;/p&gt;

&lt;p&gt;When a Python project grows, don't start by asking:&lt;/p&gt;

&lt;p&gt;How many lines should a file have?&lt;/p&gt;

&lt;p&gt;A better question is:&lt;/p&gt;

&lt;p&gt;Which responsibilities belong together, and which ones should be able to change separately?&lt;/p&gt;

&lt;p&gt;For example, an expense tracker could evolve from one large file into:&lt;/p&gt;

&lt;p&gt;expense_tracker/&lt;br&gt;
├── main.py&lt;br&gt;
└── finance/&lt;br&gt;
    ├── &lt;strong&gt;init&lt;/strong&gt;.py&lt;br&gt;
    ├── expenses.py&lt;br&gt;
    ├── files.py&lt;br&gt;
    └── reports.py&lt;/p&gt;

&lt;p&gt;Now the structure itself tells us something:&lt;/p&gt;

&lt;p&gt;expenses.py handles expense logic.&lt;/p&gt;

&lt;p&gt;files.py handles persistence.&lt;/p&gt;

&lt;p&gt;reports.py handles calculations and summaries.&lt;/p&gt;

&lt;p&gt;main.py coordinates the program.&lt;/p&gt;

&lt;p&gt;That is the real value of modules and packages: they help the code communicate its structure.&lt;/p&gt;

&lt;p&gt;A tiny example&lt;/p&gt;

&lt;p&gt;Instead of keeping every function in main.py, we can create a module:&lt;/p&gt;

&lt;h1&gt;
  
  
  file: finance/expenses.py
&lt;/h1&gt;

&lt;p&gt;def add_expense(expenses, date, category, amount):&lt;br&gt;
    expenses.append({&lt;br&gt;
        "date": date,&lt;br&gt;
        "category": category,&lt;br&gt;
        "amount": amount&lt;br&gt;
    })&lt;/p&gt;

&lt;p&gt;Then use it from another file:&lt;/p&gt;

&lt;h1&gt;
  
  
  file: main.py
&lt;/h1&gt;

&lt;p&gt;from finance.expenses import add_expense&lt;/p&gt;

&lt;p&gt;expenses = []&lt;/p&gt;

&lt;p&gt;add_expense(&lt;br&gt;
    expenses,&lt;br&gt;
    "2026-09-02",&lt;br&gt;
    "Food",&lt;br&gt;
    18000&lt;br&gt;
)&lt;/p&gt;

&lt;p&gt;The behavior is simple, but the important change is architectural:&lt;/p&gt;

&lt;p&gt;the responsibility now has a clear home.&lt;/p&gt;

&lt;p&gt;The mistake to avoid&lt;/p&gt;

&lt;p&gt;Learning modules doesn't mean creating one file for every function.&lt;/p&gt;

&lt;p&gt;This:&lt;/p&gt;

&lt;p&gt;calculator/&lt;br&gt;
├── add.py&lt;br&gt;
├── subtract.py&lt;br&gt;
├── multiply.py&lt;br&gt;
└── divide.py&lt;/p&gt;

&lt;p&gt;is not automatically better than:&lt;/p&gt;

&lt;p&gt;calculator.py&lt;/p&gt;

&lt;p&gt;More files do not always mean better organization.&lt;/p&gt;

&lt;p&gt;The goal is not fragmentation.&lt;/p&gt;

&lt;p&gt;The goal is clarity.&lt;/p&gt;

&lt;p&gt;Want the full visual walkthrough?&lt;/p&gt;

&lt;p&gt;I wrote a complete step-by-step guide in Spanish on TuCódigoCotidiano.&lt;/p&gt;

&lt;p&gt;It covers:&lt;/p&gt;

&lt;p&gt;modules and packages;&lt;/p&gt;

&lt;p&gt;import;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;init&lt;/strong&gt;.py;&lt;/p&gt;

&lt;p&gt;if &lt;strong&gt;name&lt;/strong&gt; == "&lt;strong&gt;main&lt;/strong&gt;";&lt;/p&gt;

&lt;p&gt;absolute and relative imports;&lt;/p&gt;

&lt;p&gt;circular imports;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;pycache&lt;/strong&gt;;&lt;/p&gt;

&lt;p&gt;when to split code — and when not to.&lt;/p&gt;

&lt;p&gt;👉 Read the complete guide:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tucodigocotidiano.yarumaltech.com/leer_guias/modulos-y-paquetes-organiza-tu-codigo-sin-perderte/" rel="noopener noreferrer"&gt;https://tucodigocotidiano.yarumaltech.com/leer_guias/modulos-y-paquetes-organiza-tu-codigo-sin-perderte/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're moving from small Python scripts to projects with multiple files, this is exactly the transition the guide is designed to explain.&lt;/p&gt;

</description>
      <category>python</category>
      <category>beginners</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>¿Qué ocurre realmente cuando ejecutas un contenedor Docker?</title>
      <dc:creator>Tu codigo cotidiano</dc:creator>
      <pubDate>Mon, 31 Aug 2026 15:10:41 +0000</pubDate>
      <link>https://dev.to/tu_codigocotidiano_f173d/que-ocurre-realmente-cuando-ejecutas-un-contenedor-docker-5396</link>
      <guid>https://dev.to/tu_codigocotidiano_f173d/que-ocurre-realmente-cuando-ejecutas-un-contenedor-docker-5396</guid>
      <description>&lt;h1&gt;
  
  
  ¿Qué ocurre realmente cuando ejecutas un contenedor Docker?
&lt;/h1&gt;

&lt;p&gt;Escribes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unos segundos después nginx está funcionando.&lt;/p&gt;

&lt;p&gt;Puede parecer que Docker acaba de crear una pequeña computadora dentro de tu computador.&lt;/p&gt;

&lt;p&gt;Pero eso no es realmente lo que ocurre.&lt;/p&gt;

&lt;h2&gt;
  
  
  Todo comienza con una imagen
&lt;/h2&gt;

&lt;p&gt;Docker necesita una imagen que contenga los elementos necesarios para ejecutar la aplicación.&lt;/p&gt;

&lt;p&gt;Las imágenes normalmente están construidas mediante capas.&lt;/p&gt;

&lt;p&gt;Eso permite reutilizar partes que ya existen en el sistema y evita descargar o almacenar todo nuevamente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Después aparece el contenedor
&lt;/h2&gt;

&lt;p&gt;Docker utiliza la imagen como base y crea un entorno donde ejecutará la aplicación.&lt;/p&gt;

&lt;p&gt;Aquí aparece una diferencia fundamental:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;una imagen y un contenedor no son lo mismo.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;La imagen es reutilizable.&lt;/p&gt;

&lt;p&gt;El contenedor es una instancia creada a partir de ella.&lt;/p&gt;

&lt;h2&gt;
  
  
  En el fondo hay procesos
&lt;/h2&gt;

&lt;p&gt;En Linux, un contenedor no necesita ejecutar un sistema operativo completo independiente.&lt;/p&gt;

&lt;p&gt;La aplicación se ejecuta como uno o varios procesos que comparten el kernel del host.&lt;/p&gt;

&lt;p&gt;Entonces, ¿cómo consigue Docker que parezca un entorno independiente?&lt;/p&gt;

&lt;h2&gt;
  
  
  Namespaces: aislamiento
&lt;/h2&gt;

&lt;p&gt;Linux dispone de mecanismos llamados namespaces.&lt;/p&gt;

&lt;p&gt;Gracias a ellos, un proceso puede tener una visión aislada de elementos como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;procesos&lt;/li&gt;
&lt;li&gt;interfaces de red&lt;/li&gt;
&lt;li&gt;puntos de montaje&lt;/li&gt;
&lt;li&gt;usuarios&lt;/li&gt;
&lt;li&gt;hostname&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para la aplicación, parece que existe dentro de su propio entorno.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cgroups: controlar recursos
&lt;/h2&gt;

&lt;p&gt;También necesitamos evitar que un contenedor consuma todos los recursos de la máquina.&lt;/p&gt;

&lt;p&gt;Para eso Linux dispone de los cgroups.&lt;/p&gt;

&lt;p&gt;Permiten gestionar y contabilizar recursos como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CPU&lt;/li&gt;
&lt;li&gt;memoria&lt;/li&gt;
&lt;li&gt;entrada y salida&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Docker utiliza estos mecanismos para aplicar límites a los contenedores.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué ocurre con la red?
&lt;/h2&gt;

&lt;p&gt;Docker también puede crear redes virtuales.&lt;/p&gt;

&lt;p&gt;Por ejemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:80 nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aquí estamos indicando que el tráfico recibido en el puerto 8080 del host pueda llegar al puerto 80 utilizado por nginx dentro del contenedor.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Y los datos?
&lt;/h2&gt;

&lt;p&gt;Un contenedor puede eliminarse.&lt;/p&gt;

&lt;p&gt;Pero nuestros datos muchas veces deben sobrevivir.&lt;/p&gt;

&lt;p&gt;Para eso existen los volúmenes.&lt;/p&gt;

&lt;p&gt;Los volúmenes permiten almacenar información fuera de la capa efímera del contenedor.&lt;/p&gt;

&lt;p&gt;Son especialmente importantes cuando trabajamos con bases de datos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Entonces, ¿qué hay detrás de &lt;code&gt;docker run&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;Podemos visualizarlo así:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IMAGEN
   ↓
PROCESO
   ↓
AISLAMIENTO
   ↓
CONTROL DE RECURSOS
   ↓
RED
   ↓
ALMACENAMIENTO
   ↓
CONTENEDOR
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Docker hace que toda esta coordinación parezca sencilla.&lt;/p&gt;

&lt;p&gt;Y esa es precisamente una de sus mayores virtudes.&lt;/p&gt;

&lt;p&gt;🎧 En &lt;strong&gt;Tu Código Cotidiano&lt;/strong&gt; preparé un episodio corto explicando todo este recorrido:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Qué ocurre dentro de Docker cuando ejecutas un contenedor?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tucodigocotidiano.yarumaltech.com/escuchar-podcast/que-ocurre-dentro-de-docker-cuando-ejecutas-un-contenedor/" rel="noopener noreferrer"&gt;https://tucodigocotidiano.yarumaltech.com/escuchar-podcast/que-ocurre-dentro-de-docker-cuando-ejecutas-un-contenedor/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fff8hr1ic617gh008bu0m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fff8hr1ic617gh008bu0m.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>linux</category>
      <category>devops</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Tu programa funciona… pero olvida todo: persistencia de datos con Python</title>
      <dc:creator>Tu codigo cotidiano</dc:creator>
      <pubDate>Thu, 27 Aug 2026 20:16:50 +0000</pubDate>
      <link>https://dev.to/tu_codigocotidiano_f173d/tu-programa-funciona-pero-olvida-todo-persistencia-de-datos-con-python-516n</link>
      <guid>https://dev.to/tu_codigocotidiano_f173d/tu-programa-funciona-pero-olvida-todo-persistencia-de-datos-con-python-516n</guid>
      <description>&lt;h1&gt;
  
  
  Tu programa funciona… pero olvida todo
&lt;/h1&gt;

&lt;p&gt;Imagina que estás creando un pequeño programa en Python para registrar gastos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;gastos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

&lt;span class="n"&gt;gastos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;categoria&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Comida&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;valor&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18000&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gastos&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Todo funciona.&lt;/p&gt;

&lt;p&gt;Pero cierras el programa, lo ejecutas nuevamente y &lt;code&gt;gastos&lt;/code&gt; vuelve a estar vacío.&lt;/p&gt;

&lt;p&gt;¿Por qué?&lt;/p&gt;

&lt;p&gt;Porque tener información dentro de una variable no significa haberla guardado permanentemente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Memoria no es persistencia
&lt;/h2&gt;

&lt;p&gt;Mientras nuestro programa está ejecutándose puede trabajar con listas, diccionarios, números y otros objetos.&lt;/p&gt;

&lt;p&gt;Pero si queremos encontrar esa información después de cerrar el programa necesitamos representarla fuera de ese ciclo de ejecución.&lt;/p&gt;

&lt;p&gt;Una de las formas más sencillas de hacerlo es utilizando archivos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nota.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;archivo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;archivo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Mi primer dato persistente&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ahora la información puede continuar existiendo incluso después de que Python termine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tres letras importantes: r, w y a
&lt;/h2&gt;

&lt;p&gt;Cuando empezamos a trabajar con archivos hay tres modos especialmente útiles:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;r → leer
w → escribir desde cero
a → añadir
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hay que tener especial cuidado con &lt;code&gt;w&lt;/code&gt;: si el archivo ya contenía información, podemos reemplazarla.&lt;/p&gt;

&lt;p&gt;Si queremos añadir algo sin borrar lo anterior:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nota.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;archivo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;archivo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Otra línea&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ¿TXT, CSV o JSON?
&lt;/h2&gt;

&lt;p&gt;Una forma sencilla de pensarlo es observar la estructura de nuestros datos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TXT&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Útil cuando queremos guardar texto sencillo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CSV&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Tiene sentido cuando nuestros datos se parecen a una tabla:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fecha,categoria,valor
2026-08-27,Comida,18000
2026-08-27,Transporte,6500
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Python incluye el módulo &lt;code&gt;csv&lt;/code&gt;, por lo que no necesitamos construir el archivo concatenando comas manualmente.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JSON&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Empieza a resultar interesante cuando nuestros datos contienen claves, listas, números, booleanos o estructuras anidadas.&lt;/p&gt;

&lt;p&gt;La decisión no consiste simplemente en memorizar tres extensiones.&lt;/p&gt;

&lt;p&gt;Consiste en preguntarnos:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿qué forma tienen mis datos?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ese cambio de perspectiva hace mucho más sencillo entender la persistencia.&lt;/p&gt;

&lt;p&gt;Preparé una guía completa en español donde desarrollamos el recorrido desde memoria y archivos TXT hasta CSV y JSON, con ejemplos paso a paso:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://tucodigocotidiano.yarumaltech.com/leer_guias/archivos-de-texto-csv-y-json-datos-que-sobreviven-al-programa/" rel="noopener noreferrer"&gt;https://tucodigocotidiano.yarumaltech.com/leer_guias/archivos-de-texto-csv-y-json-datos-que-sobreviven-al-programa/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Una frase resume bastante bien todo el concepto:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;El programa puede terminar. Los datos no tienen por qué desaparecer.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
