<?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>Forem: Rafnix Guzmán</title>
    <description>The latest articles on Forem by Rafnix Guzmán (@rafnixg).</description>
    <link>https://forem.com/rafnixg</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F181624%2Fa30a556d-7b1e-4acd-bce7-997841984987.jpg</url>
      <title>Forem: Rafnix Guzmán</title>
      <link>https://forem.com/rafnixg</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/rafnixg"/>
    <language>en</language>
    <item>
      <title>⚙️ Como automatizar tu librería en PyPI con GitHub Actions</title>
      <dc:creator>Rafnix Guzmán</dc:creator>
      <pubDate>Fri, 11 Apr 2025 14:00:56 +0000</pubDate>
      <link>https://forem.com/rafnixg/como-automatizar-tu-libreria-en-pypi-con-github-actions-4p61</link>
      <guid>https://forem.com/rafnixg/como-automatizar-tu-libreria-en-pypi-con-github-actions-4p61</guid>
      <description>&lt;p&gt;Continuando con un post anterior donde publicamos nuestra librera a &lt;strong&gt;PyPI,&lt;/strong&gt; vamos a ir un paso ms all en el proceso de construccin y despliegue (o, mejor dicho, &lt;strong&gt;build&lt;/strong&gt; y &lt;strong&gt;release).&lt;/strong&gt; En este tutorial, crearemos nuestro propio &lt;strong&gt;workflow&lt;/strong&gt; en &lt;strong&gt;GitHub Actions&lt;/strong&gt; , aprovechando que nuestro repositorio ya est en &lt;strong&gt;GitHub,&lt;/strong&gt; para automatizar este proceso y hacerlo ms eficiente y menos propenso a errores.&lt;/p&gt;

&lt;p&gt;Al final de este tutorial tendremos configurado un &lt;strong&gt;workflow&lt;/strong&gt; que construye y publica en &lt;strong&gt;PyPI&lt;/strong&gt; de forma automtica con cada nueva &lt;strong&gt;release&lt;/strong&gt; que se cree en el repositorio de &lt;strong&gt;GitHub.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;👉 Si an no publicaste tu librera en &lt;strong&gt;PyPI&lt;/strong&gt; , te recomiendo comenzar por este tutorial previo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/rafnixg/como-publicar-tu-propia-libreria-de-python-guia-paso-a-paso-510o-temp-slug-2123391"&gt;https://blog.rafnixg.dev/como-publicar-tu-propia-libreria-de-python-guia-paso-a-paso&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Qu es GitHub Actions?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;GitHub Actions&lt;/strong&gt; es una plataforma de &lt;strong&gt;CI/CD (Integracin y Entrega Continua)&lt;/strong&gt; integrada directamente en &lt;strong&gt;GitHub&lt;/strong&gt;. Permite automatizar tareas dentro del ciclo de vida de tu proyecto, como ejecutar tests, construir paquetes, y desplegar cdigo, todo sin salir de tu repositorio.&lt;/p&gt;

&lt;p&gt;La magia est en los &lt;strong&gt;workflows&lt;/strong&gt; , que son conjuntos de instrucciones definidas en archivos &lt;strong&gt;YAML&lt;/strong&gt;. Estos &lt;strong&gt;workflows&lt;/strong&gt; se ejecutan en respuesta a eventos especficos, como hacer un push, crear un tag, abrir un pull request o crear un nuevo release.&lt;/p&gt;

&lt;p&gt;En el caso de una librera de Python, esto nos permite automatizar pasos como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Construir los paquetes (&lt;code&gt;sdist&lt;/code&gt; y &lt;code&gt;wheel&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Publicar automticamente en &lt;strong&gt;PyPI&lt;/strong&gt; o &lt;strong&gt;TestPyPI&lt;/strong&gt; cuando subimos una nueva versin&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Con unas pocas lneas de configuracin, podemos lograr que todo esto suceda de forma automtica cada vez que haces un &lt;strong&gt;release&lt;/strong&gt; , reduciendo errores y ganando tiempo.&lt;/p&gt;

&lt;h2&gt;
  
  
  📦 Automatizando la publicacin en PyPI con GitHub Actions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Requisitos previos
&lt;/h3&gt;

&lt;p&gt;Antes de iniciar, asegrate de tener:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Un repositorio de &lt;strong&gt;GitHub&lt;/strong&gt; con tu librera&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Una cuenta de &lt;a href="https://pypi.org/" rel="noopener noreferrer"&gt;&lt;strong&gt;PyPI&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Un &lt;a href="https://blog.rafnixg.dev/como-publicar-tu-propia-libreria-de-python-guia-paso-a-paso#heading-creando-api-key" rel="noopener noreferrer"&gt;&lt;strong&gt;API Token&lt;/strong&gt;&lt;/a&gt; generado de tu cuenta de &lt;strong&gt;PyPI&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Si ya seguiste el tutorial anterior, deberas tener todo esto listo. Si no, te recomiendo revisarlo antes de seguir.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔐 Agregar tu token de PyPI como secret en GitHub
&lt;/h3&gt;

&lt;p&gt;Debemos configurar en nuestro repositorio un nuevo &lt;strong&gt;secret&lt;/strong&gt; para usarlo en los &lt;strong&gt;workflows&lt;/strong&gt; , para esto solo debemos seguir los siguientes pasos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Ir a tu repositorio en &lt;strong&gt;GitHub&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hacer clic en &lt;strong&gt;Settings&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;En el men lateral, clic en &lt;strong&gt;Secrets and variables Actions&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&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.amazonaws.com%2Fuploads%2Farticles%2Fc06u2zc7t3fnrdnyt6sj.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.amazonaws.com%2Fuploads%2Farticles%2Fc06u2zc7t3fnrdnyt6sj.png" width="328" height="141"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Clic en &lt;strong&gt;New repository secret&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;El nombre ser &lt;code&gt;PYPI_API_TOKEN&lt;/code&gt; y en el valor peg tu &lt;strong&gt;API key&lt;/strong&gt; de &lt;strong&gt;PyPI&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clic en &lt;strong&gt;Add secret.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&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.amazonaws.com%2Fuploads%2Farticles%2Fgv4t87ruuaxcab8ahrsf.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.amazonaws.com%2Fuploads%2Farticles%2Fgv4t87ruuaxcab8ahrsf.png" width="800" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esto es lo que usa &lt;strong&gt;GitHub Actions&lt;/strong&gt; para autenticar y publicar la librera.&lt;/p&gt;

&lt;h3&gt;
  
  
  📁 Estructura de archivos
&lt;/h3&gt;

&lt;p&gt;Ya con todo esto listo podemos empezar, lo primero que debemos saber es que para que nuestra &lt;strong&gt;Github Actions&lt;/strong&gt; funcione los &lt;strong&gt;workflows&lt;/strong&gt; deben estar en una carpeta llama &lt;code&gt;.github/workflows&lt;/code&gt; en la raz de nuestro repositorio, dentro de esta carpeta ira nuestro archivo de &lt;strong&gt;workflow&lt;/strong&gt; llamado &lt;code&gt;python-publish.yml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Podemos crear todo usando los siguientes comandos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir -p .github/workflows$ touch .github/workflows/python-publish.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La estructura de archivos quedara similar a esta:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rafnixg-lib/ .github/ workflows/ python-publish.yml src/ rafnixg/ __init__.py __main__.py rafnixg.py LICENSE README.md pyproject.toml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🚀 Configurando el workflow
&lt;/h2&gt;

&lt;p&gt;Vamos a iniciar creando el contenido de nuestro archivo de &lt;strong&gt;workflow&lt;/strong&gt; &lt;code&gt;python-publish.yml&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  🎯Activando el workflow al publicar un release
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: Publicar Paquete a PyPIon: release: types: [published]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto indica el nombre que tendr nuestro &lt;strong&gt;workflow&lt;/strong&gt; y tambin define que solo se va a ejecutar cuando las &lt;code&gt;release&lt;/code&gt; sean &lt;code&gt;published&lt;/code&gt; con esto limitamos que solo estas acciones sean las que disparen nuestro &lt;strong&gt;workflow.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🛡Definir permisos mnimos necesarios
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;permissions: contents: read
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ac le decimos a GitHub Actions que este workflow solo necesita &lt;strong&gt;leer el contenido del repositorio&lt;/strong&gt;. Es una buena prctica limitar los permisos al mnimo necesario.&lt;/p&gt;

&lt;h3&gt;
  
  
  🛠Crear el job y configurar el entorno
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jobs: deploy: runs-on: ubuntu-latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Creamos un &lt;strong&gt;job&lt;/strong&gt; llamado &lt;code&gt;deploy&lt;/code&gt;, que se ejecutar en un entorno virtual Ubuntu. Este &lt;strong&gt;job&lt;/strong&gt; va a encargarse de construir y publicar nuestro paquete.&lt;/p&gt;

&lt;h3&gt;
  
  
  📋Agregar los pasos del workflow
&lt;/h3&gt;

&lt;p&gt;Los &lt;strong&gt;steps&lt;/strong&gt; son partes del proceso que irn ejecutando de forma secuencia y sern lo que ejecutarn los pasos para publicar nuestra librera en &lt;strong&gt;PyPI&lt;/strong&gt; luego de ser construida.&lt;/p&gt;

&lt;p&gt;En los &lt;strong&gt;steps&lt;/strong&gt; se puede hacer uso de otros &lt;strong&gt;actions&lt;/strong&gt; creados por otros usuarios como si de libreras se tratase, solo debemos indicarlo con &lt;code&gt;uses: actions/nombre-del-actions@version&lt;/code&gt; y tambien podemos usar comando sobre la mquina virtual donde se est ejecutando la &lt;strong&gt;actions&lt;/strong&gt; con el comando &lt;code&gt;run: comando bash&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;steps: - name: Clonando repositorio uses: actions/checkout@v3 - name: Configurando Python 3 uses: actions/setup-python@v3 with: python-version: '3.x' - name: Instalando dependencias run: | python -m pip install --upgrade pip pip install build - name: Construir Paquete run: python -m build - name: Publicar Paquete uses: pypa/gh-action-pypi-publish@release/v1 with: user: __token__ password: ${{ secrets.PYPI_API_TOKEN }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  📂 Clonando el repositorio
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: Clonando repositorio uses: actions/checkout@v3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usamos la accin oficial para &lt;strong&gt;clonar el cdigo del repositorio&lt;/strong&gt; , paso necesario para poder construir el paquete.&lt;/p&gt;

&lt;h4&gt;
  
  
  🐍 Configurar el entorno de Python
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: Configurando Python 3 uses: actions/setup-python@v3 with: python-version: '3.x'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Le decimos a GitHub Actions que configure un entorno de Python (versin 3.x). Esto es clave para poder instalar dependencias y ejecutar los comandos de build.&lt;/p&gt;

&lt;h4&gt;
  
  
  📥 Instalando las dependencias necesarias
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: Instalando dependencias run: | python -m pip install --upgrade pip pip install build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Actualizamos &lt;code&gt;pip&lt;/code&gt; y luego instalamos el mdulo &lt;code&gt;build&lt;/code&gt;, que nos permite crear los archivos &lt;code&gt;.tar.gz&lt;/code&gt; y &lt;code&gt;.whl&lt;/code&gt; que necesita PyPI.&lt;/p&gt;

&lt;h4&gt;
  
  
  🏗Construir el paquete
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: Construir Paquete run: python -m build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este paso ejecuta &lt;code&gt;python -m build&lt;/code&gt;, que genera el paquete listo para ser publicado en la carpeta &lt;code&gt;dist/&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  📤Publicar el paquete en PyPI
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: Publicar Paquete uses: pypa/gh-action-pypi-publish@release/v1 with: user: __token__ password: ${{ secrets.PYPI_API_TOKEN }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finalmente, usamos la accin oficial para subir el paquete a &lt;a href="https://pypi.org" rel="noopener noreferrer"&gt;PyPI&lt;/a&gt;. Aqu usamos el API Key que se guarda como &lt;strong&gt;Secret&lt;/strong&gt; en el repositorio de GitHub (&lt;code&gt;PYPI_API_TOKEN&lt;/code&gt;), para evitar exponer credenciales.&lt;/p&gt;

&lt;h2&gt;
  
  
  📄 &lt;strong&gt;Archivo completo del workflow&lt;/strong&gt; (&lt;code&gt;python-publish.yml&lt;/code&gt;)
&lt;/h2&gt;

&lt;p&gt;El archivo &lt;code&gt;python-publish.yml&lt;/code&gt; finalmente queda de la siguiente manera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: Publicar Paquete a PyPIon: release: types: [published]jobs: deploy: runs-on: ubuntu-latest steps: - name: Clonando repositorio uses: actions/checkout@v3 - name: Configurando Python 3 uses: actions/setup-python@v3 with: python-version: '3.x' - name: Instalando dependencias run: | python -m pip install --upgrade pip pip install build - name: Construir Paquete run: python -m build - name: Publicar Paquete uses: pypa/gh-action-pypi-publish@release/v1 with: user: __token__ password: ${{ secrets.PYPI_API_TOKEN }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  💾 Subiendo los cambios al repositorio
&lt;/h2&gt;

&lt;p&gt;Ya con nuestro archivo creado, solo nos resta subir un &lt;strong&gt;commit&lt;/strong&gt; con los cambios que tenemos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git add .github/workflows/python-publish.yml$ git commit -m "Add GitHub Actions workflow for PyPI release"$ git push origin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Creamos un &lt;strong&gt;tag&lt;/strong&gt; y lo subimos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git tag v1.0.1$ git push origin --tags
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Revisamos nuestro repositorio de &lt;strong&gt;GitHub&lt;/strong&gt; y nos aseguramos de que se subi todo correctamente, para seguir con la creacin de una nueva &lt;strong&gt;release&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  🏷 Crear una nueva release en GitHub
&lt;/h3&gt;

&lt;p&gt;En nuestro repositorio hacemos clic en &lt;strong&gt;Releases.&lt;/strong&gt; para ingresar a la pgina de todas las &lt;strong&gt;releases&lt;/strong&gt; que vamos a haciendo.&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.amazonaws.com%2Fuploads%2Farticles%2Fvt2hsj5fvteatnwxvpbe.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.amazonaws.com%2Fuploads%2Farticles%2Fvt2hsj5fvteatnwxvpbe.png" width="269" height="160"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En esta pgina hacemos clic en &lt;strong&gt;draf a new release&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.amazonaws.com%2Fuploads%2Farticles%2Fhww7wdm17tn0px2cx863.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.amazonaws.com%2Fuploads%2Farticles%2Fhww7wdm17tn0px2cx863.png" width="800" height="303"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esto nos abre el formulario para crear nuevas releases, ac debemos seleccionar el tag correspondiente con la release en &lt;strong&gt;Choose a tag&lt;/strong&gt; y hacer clic en &lt;strong&gt;Generate release notes,&lt;/strong&gt; esto genera una descripcin usando los &lt;strong&gt;commits&lt;/strong&gt; y los &lt;strong&gt;Pull Request.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Por ltimo, revisa la descripcin ajusta si lo necesitas y dale clic a &lt;strong&gt;Publish release.&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.amazonaws.com%2Fuploads%2Farticles%2Fl9th7t9zi5k22onmapla.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.amazonaws.com%2Fuploads%2Farticles%2Fl9th7t9zi5k22onmapla.png" width="800" height="650"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Verificar el resultado de la publicacin
&lt;/h2&gt;

&lt;p&gt;Cada vez que crees una nueva &lt;strong&gt;release&lt;/strong&gt; , se publicar una nueva versin de tu paquete en &lt;strong&gt;PyPI&lt;/strong&gt;. En la tab &lt;strong&gt;Actions&lt;/strong&gt; de nuestro repositorio vamos a ver cmo se ejecuta el &lt;strong&gt;workflow&lt;/strong&gt; que lo publica.&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.amazonaws.com%2Fuploads%2Farticles%2Faedg8sip03ii76lhq3m7.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.amazonaws.com%2Fuploads%2Farticles%2Faedg8sip03ii76lhq3m7.png" width="800" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 &lt;strong&gt;Conclusin&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Automatizar la publicacin con &lt;strong&gt;GitHub Actions&lt;/strong&gt; no solo te ahorra tiempo, tambin reduce errores y hace que todo el proceso sea mucho ms limpio y profesional. Una vez configurado, solo tienes que enfocarte en mejorar tu librera y dejar que la publicacin se maneje sola&lt;/p&gt;

&lt;h2&gt;
  
  
  🔍Referencias
&lt;/h2&gt;

&lt;h4&gt;
  
  
  🔗 Documentacin oficial GitHub Actions
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/actions/about-github-actions/understanding-github-actions" rel="noopener noreferrer"&gt;https://docs.github.com/en/actions/about-github-actions/understanding-github-actions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  🔗 Documentacin oficial PyPI usando GitHub Actions
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows" rel="noopener noreferrer"&gt;https://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  🔗 Documentacion del GitHub Actions PyPI Publish
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/pypa/gh-action-pypi-publish" rel="noopener noreferrer"&gt;https://github.com/pypa/gh-action-pypi-publish&lt;/a&gt;
]]&amp;gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>pypi</category>
      <category>githubactions</category>
      <category>cicd</category>
    </item>
    <item>
      <title>🏗️ Cómo publicar tu propia librería de Python: Guía paso a paso</title>
      <dc:creator>Rafnix Guzmán</dc:creator>
      <pubDate>Fri, 04 Apr 2025 20:43:39 +0000</pubDate>
      <link>https://forem.com/rafnixg/como-publicar-tu-propia-libreria-de-python-guia-paso-a-paso-83m</link>
      <guid>https://forem.com/rafnixg/como-publicar-tu-propia-libreria-de-python-guia-paso-a-paso-83m</guid>
      <description>&lt;p&gt;El objetivo de este tutorial es guiarte paso a paso en el proceso de creacin y publicacin de tu propia librera en Python. Aunque Python ofrece una biblioteca estndar muy completa, aprovechar las contribuciones de la comunidad en &lt;a href="https://pypi.org/" rel="noopener noreferrer"&gt;PyPI&lt;/a&gt; te permite extender sus capacidades y crear soluciones personalizadas que se adapten a tus necesidades.&lt;/p&gt;

&lt;p&gt;La motivacin detrs de este proyecto es doble: por un lado, adquirir un conocimiento profundo sobre el proceso de preparacin, versionado, construccin y despliegue de paquetes; y por el otro, consolidar un repositorio centralizado de herramientas que funcione como una tarjeta de presentacin profesional en el mundo del desarrollo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/rafnixg/rafnixg-lib" rel="noopener noreferrer"&gt;https://github.com/rafnixg/rafnixg-lib&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🧭 Introduccin y primeros pasos
&lt;/h2&gt;

&lt;p&gt;El primer paso es comprender el ecosistema de paquetes en Python, especialmente el rol fundamental que juega &lt;a href="https://pypi.org/" rel="noopener noreferrer"&gt;PyPI&lt;/a&gt; (Python Packaging Index). Este es el repositorio oficial de paquetes de Python, y alberga una vasta coleccin de libreras, desde implementaciones simples hasta complejas soluciones en reas como ciencia de datos, inteligencia artificial y desarrollo web.&lt;/p&gt;

&lt;p&gt;Al entender cmo se organizan y distribuyen los paquetes en &lt;a href="https://pypi.org/" rel="noopener noreferrer"&gt;PyPI&lt;/a&gt;, puedes orientar el desarrollo de tu librera para que cumpla con los estndares que facilitan su instalacin y uso por parte de otros desarrolladores. Adems, al prepararla para su publicacin, te adentras en prcticas modernas como el versionado semntico y la automatizacin del despliegue.&lt;/p&gt;

&lt;p&gt;Nuestro inicio en el mundo de las libreras lo vamos a tener en la prxima seccin donde ya iniciaremos el cdigo fuente que usaremos como base para todo el proceso de tener nuestra propia librera en &lt;a href="https://pypi.org/" rel="noopener noreferrer"&gt;PyPI&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pypi.org/project/rafnixg/" rel="noopener noreferrer"&gt;https://pypi.org/project/rafnixg/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🏗 Crear la base de tu librera en Python
&lt;/h2&gt;

&lt;p&gt;En esta seccin crearemos el cdigo base que usaremos para subir a PyPI, t puedes usar este cdigo como ejemplo o ser libre de usar el cdigo de tu preferencia, y saltar a la siguiente seccin.&lt;/p&gt;

&lt;p&gt;Si te quedaste ac el paquete que vamos a crear se llama &lt;code&gt;rafnixg&lt;/code&gt; y muestra por consola tus datos personales y por otro lado podr ser usado en tu propio cdigo para descargar post de tu blog de &lt;strong&gt;&lt;em&gt;HashNode&lt;/em&gt;&lt;/strong&gt; usando &lt;strong&gt;&lt;em&gt;GraphQL&lt;/em&gt;&lt;/strong&gt;. Este es bsicamente mi caso de uso de ejemplo, pero tu librera puede tener las funciones que tu consideres necesarias.&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.amazonaws.com%2Fuploads%2Farticles%2Fzsv80stp3ssnij2u3omm.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.amazonaws.com%2Fuploads%2Farticles%2Fzsv80stp3ssnij2u3omm.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para lograr obtener este diseo de card vamos a hacer uso de la librera &lt;code&gt;rich&lt;/code&gt; que nos ayuda a crear diseos de tablas para la terminal de forma fcil, los invito a revisar el potencial de &lt;code&gt;rich&lt;/code&gt;, puede agregar iconos, gestionar paleta de colores, Markdown.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pypi.org/project/rich/" rel="noopener noreferrer"&gt;https://pypi.org/project/rich/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🧪Preparacin del entorno de desarrollo
&lt;/h3&gt;

&lt;p&gt;Para este caso hare uso de &lt;strong&gt;VSCode&lt;/strong&gt; pero puedes usar el editor que prefieras, ac lo importante es crear un entorno virtual de Python para aislar las dependencias y no tener problemas en el futuro.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; venv &lt;span class="nb"&gt;env&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;source env&lt;/span&gt;/bin/activate &lt;span class="c"&gt;# Para Linux$ env\Scripts\activate # Para Windows(env) $ pip install rich&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lo segundo ser crear un archivo &lt;code&gt;.gitignore&lt;/code&gt; que nos ayudar a indicar que no queremos que se suba a nuestro repositorio, podemos hacer uso de la siguiente web para generar uno con la configuracin para Python.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.toptal.com/developers/gitignore" rel="noopener noreferrer"&gt;Create Useful .gitignore Files For Your Project&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="c"&gt;# Created by https://www.toptal.com/developers/gitignore/api/python# Edit at https://www.toptal.com/developers/gitignore?templates=python### Python #### Byte-compiled / optimized / DLL files __pycache__ /*.py[cod]*$py.classenv.env/venvvenv# End of https://www.toptal.com/developers/gitignore/api/python
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Debemos recordar que es importante evitar subir archivos con contenido sensibles como API Keys, Claves o algn tipo de informacin que permita acceso no autorizado.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Luego de esto inicializamos nuestro repositorio de &lt;code&gt;git&lt;/code&gt; y creamos nuestra estructura de archivos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(env) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;git init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  📁 Estructura del proyecto
&lt;/h3&gt;

&lt;p&gt;Toda librera de Python inicia dentro de una carpeta, as que para esto cree el directorio &lt;code&gt;rafnixg-lib&lt;/code&gt; y dentro creo la siguiente estructura de archivos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rafnixg-lib/ src/ rafnixg/ __init__.py __main__.py rafnixg.py LICENSE README.md pyproject.toml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Todo el cdigo fuente se encuentra de &lt;code&gt;src/&lt;/code&gt; esto no es obligatorio, pero es una buena prctica. Si estas usando tu propio cdigo, dentro de &lt;code&gt;src/&lt;/code&gt; es donde debera ir para mantener la mejor estructura.&lt;/p&gt;

&lt;p&gt;En esta seccin nos enfocaremos en los archivos de Python y en las siguientes secciones veremos estos archivos especiales &lt;code&gt;LICENSE, README.md, pyproject.toml&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧾 Crear el archivo principal src/rafnixg/rafnixg.py
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;src/rafnixg/rafnixg.pyRafnixG - Personal Card&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;rich.console&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Consolefrom&lt;/span&gt; &lt;span class="n"&gt;rich&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;table&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Tableclass&lt;/span&gt; &lt;span class="n"&gt;RafnixG&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;RafnixG - Personal Card&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rafnixg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Rafnix Guzmn&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Python Software Developer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;links&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://links.rafnixg.dev&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;web&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://rafnixg.dev&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://blog.rafnixg.dev&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://resume.rafnixg.dev&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;github&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://github.com/rafnixg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;twitter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;@rafnixg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;about&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Experienced software developer with 10+ years of expertise in designing, developing and implementing web systems across various sectors. Backend specialist skilled in Python, Linux, and Git. Passionate about continuous learning and open-source technology.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__str__&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (@&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;) - &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;display&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Display personal card&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt; &lt;span class="c1"&gt;# Crea un objeto Console para imprimir en la consola console = Console() table = Table( show_header=False, # No mostrar encabezados title=str(self), # Ttulo de la tabla highlight=True, # Resaltar la tabla title_style="bold magenta", # Estilo del ttulo ) # Agrega columnas a la tabla table.add_column("Attribute", style="bold", width=16) table.add_column("Value") # Agrega filas a la tabla con los atributos y valores de la clase # Itera sobre los atributos de la clase y los agrega a la tabla for key, value in self. __dict__.items(): if isinstance(value, dict): for sub_key, sub_value in value.items(): table.add_row(sub_key, ", ".join(sub_value)) elif isinstance(value, list): table.add_row(key, ", ".join(value)) else: table.add_row(key, value) # Imprime la tabla en la consola console.print(table)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🧩 Inicializar el paquete con src/rafnixg/__init__.py
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;src/rafnixg/ __init__.pyRafnixG - Personal Card&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;rafnixg.rafnixg&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RafnixG&lt;/span&gt; &lt;span class="n"&gt;__version__&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1.0.0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🧩 Ejecutar como modulo con src/rafnixg/__main__.py
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;src/rafnixg/ __main__.pyRafnixG - Personal Card&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;rafnixg&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RafnixGdef&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Main function.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt; &lt;span class="n"&gt;me&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RafnixG&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;me&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;display&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; __main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🖥 Ejecutar y probar tu cdigo localmente
&lt;/h3&gt;

&lt;p&gt;Para probar nuestro cdigo debemos movernos a la carpeta &lt;code&gt;src/&lt;/code&gt; y luego correr el paquete como un mdulo de Python:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(env) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;src&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;env&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls &lt;/span&gt;rafnixg/&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;env&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; rafnixg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recuerda que si estas usando tu cdigo aqu debes colocar el nombre la carpeta que contiene tu cdigo fuente.&lt;/p&gt;

&lt;h2&gt;
  
  
  📦 Preparar la librera para ser publicada
&lt;/h2&gt;

&lt;h3&gt;
  
  
  📘Documentando nuestra librera
&lt;/h3&gt;

&lt;p&gt;Un &lt;strong&gt;README&lt;/strong&gt; es esencial para cualquier proyecto ya que aqu es donde otros desarrolladores y usuarios obtendrn informacin sobre tu librera, en este archivo no solo se explica que es y lo que hace tu proyecto, sino que tambin contiene informacin de como instalarlo, utilizarlo y contribuir. En una prxima publicacin profundizaremos ms sobre el &lt;strong&gt;README&lt;/strong&gt; y que debera contener, por los momentos creamos el archivo &lt;code&gt;README.md&lt;/code&gt; con el siguiente contenido:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Rafnix Guzmn - Personal Card (README.md)## Hi there 👋This is my personal card [rafnixg.dev](https://rafnixg.dev)![image](https://github.com/user-attachments/assets/4c1c368b-83ca-4ff7-89d0-c131efe60c9f)## How to use it? 🤔Install using pip:```&lt;/span&gt;

bashpip install rafnixg

&lt;span class="p"&gt;```&lt;/span&gt;&lt;span class="nl"&gt;Then run it:```
&lt;/span&gt;&lt;span class="sb"&gt;
bashrafnixg

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


### 🛠Configurar el sistema de construccin (build system)

Para preparar nuestra librera para ser publicada en **_PyPI_** necesitamos configurar algunas secciones en el archivo `pyproject.toml` primero debemos indicar el **build system** que es la parte responsable de crear los archivos que se suben a PyPI, usualmente se usa el formato **wheel** o **sdist**.

Nosotros usaremos el [setuptools](https://setuptools.pypa.io/) como **build system.**



```toml
# pyproject.toml[build-system]requires = ["setuptools&amp;gt;=61.0.0", "wheel"]build-backend = "setuptools.build_meta"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🗂 Organizar el archivo &lt;code&gt;pyproject.toml&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Ahora agregaremos una seccin para configurar informacin del proyecto, ac es donde indicaremos el nombre de nuestro paquete, recordemos que debemos verificar que el nombre no este usado por ningn otro paquete dentro del ecosistema &lt;strong&gt;&lt;em&gt;PyPI&lt;/em&gt;&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="c"&gt;# pyproject.toml...[project]name = "rafnixg"version = "1.0.0"description = "Rafnix Guzman Personal Card"readme = "README.md"authors = [{ name = "Rafnix Guzman", email = "rafnixg@gmail.com" }]license = { file = "LICENSE" }classifiers = ["License :: OSI Approved :: MIT License", "Programming Language :: Python", "Programming Language :: Python :: 3",]keywords = ["personal card", "console"]dependencies = ["rich",]requires-python = "&amp;gt;=3.9"[project.optional-dependencies]dev = ["black", "bumpver", "isort", "pip-tools", "pytest"][project.urls]Homepage = "https://github.com/rafnixg/rafnixg-lib"[project.scripts]rafnixg = "rafnixg. __main__ :main"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;No toda esta informacin es obligatoria, pero es importante dar la mayor cantidad de informacin posible sobre nuestra librera, la informacin mnima que podemos ingresar es &lt;code&gt;name&lt;/code&gt; y &lt;code&gt;version&lt;/code&gt; .&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Las siguientes secciones son importantes por la informacin que le proporcionan a PyPI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;classifiers&lt;/code&gt;: Lista de &lt;a href="https://pypi.org/classifiers/" rel="noopener noreferrer"&gt;classifiers&lt;/a&gt; de &lt;strong&gt;&lt;em&gt;PyPI&lt;/em&gt;&lt;/strong&gt; que ayudan a la bsqueda.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;keywords&lt;/code&gt;: Lista de etiquetas que seran usadas para identicar y categorizar la libreria.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;dependencies&lt;/code&gt;: Lista de dependencias que tu librera necesita, en nuestro caso &lt;strong&gt;rich.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;project.optional-dependencies&lt;/code&gt;: Lista de las dependencias de desarrollo.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;project.urls&lt;/code&gt;: Links que relacione a tu proyecto en github o alguna pgina web.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;project.scripts&lt;/code&gt;: Punto de entrada para tu librera. en este caso el comando ser &lt;code&gt;rafnixg&lt;/code&gt; y el punto de entrada ser &lt;code&gt;rafnixg. __main__ :main&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Toda esta informacin hace que en &lt;strong&gt;&lt;em&gt;PyPI&lt;/em&gt;&lt;/strong&gt; tu librera se vea mucho mejor y cuando se haga una bsqueda tambin sea ms fcil de encontrar. ac un ejemplo de la informacin que se muestra en &lt;strong&gt;&lt;em&gt;PyPI&lt;/em&gt;&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.amazonaws.com%2Fuploads%2Farticles%2F3vlkzatxqa0bnraosksj.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.amazonaws.com%2Fuploads%2Farticles%2F3vlkzatxqa0bnraosksj.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vemos como tambin usa el archivo &lt;code&gt;README.md&lt;/code&gt; para mostrar del lado derecho la documentacin de la librera en &lt;strong&gt;&lt;em&gt;PyPI&lt;/em&gt;&lt;/strong&gt; , y los datos del archivo &lt;code&gt;pyproject.toml&lt;/code&gt; tambin se muestran a la izquierda.&lt;/p&gt;

&lt;p&gt;Para saber ms sobre este archivo de configuracin ac esta la &lt;a href="https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html" rel="noopener noreferrer"&gt;documentacin&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔢 Usar versionamiento semntico
&lt;/h3&gt;

&lt;p&gt;Toda librera debe tener un versionamiento para poder tener un control de lo que se publica, existen diferentes esquemas de versionamiento, en nuestro caso usaremos &lt;a href="https://semver.org/" rel="noopener noreferrer"&gt;Semantic Versioning&lt;/a&gt; que es una forma simple de gestionar el versionamiento formado por 3 grupo de nmeros, ejemplo: &lt;strong&gt;MAJOR.MINOR.PATCH&lt;/strong&gt; las recomendaciones para cambiar estos nmeros son:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;MAJOR&lt;/strong&gt; : Cuando tus cambios son tan grandes que rompen tu API anterior.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;MINOR&lt;/strong&gt; : Cuando agregas nuevas funciones y todo se mantiene compatible, Vuelve a 0 cuando MAJOR cambia.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;PATCH&lt;/strong&gt; : Cuando agregas bug fixes, vuelve a 0 cuando MINOR cambia.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para gestionar esto en Python haremos uso de una librera llamada &lt;code&gt;bumpver&lt;/code&gt; esto modifica directamente los archivos y as mantiene sincronizado en todos lados la versin.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(venv) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install &lt;/span&gt;bumpver&lt;span class="o"&gt;(&lt;/span&gt;venv&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;bumpver initWARNING - Couldn&lt;span class="s1"&gt;'t parse pyproject.toml: Missing version_patternUpdated pyproject.toml
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este comando inicializa en &lt;code&gt;pyproject.toml&lt;/code&gt; la gestin de las versiones, si vemos agrego una nueva seccin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[tool.bumpver]&lt;/span&gt;&lt;span class="py"&gt;current_version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="py"&gt;"1.0.0"version_pattern&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="py"&gt;"MAJOR.MINOR.PATCH"commit_message&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"bump version {old_version} -&amp;gt; {new_version}"&lt;/span&gt;&lt;span class="py"&gt;commit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="py"&gt;tag&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="py"&gt;push&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="py"&gt;[tool.bumpver.file_patterns]"pyproject.toml"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="py"&gt;['current_version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"{version}"', '&lt;/span&gt;&lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"{version}"']"src/rafnixg/ __init__.py" = ["{version}"]&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si no se parece a esta ajustar el &lt;code&gt;version_pattern&lt;/code&gt; para que sean iguales, despus de configurar esto, t puedes cambiar la versin usando los comandos de &lt;code&gt;bumpver&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(venv) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;bumpver update &lt;span class="nt"&gt;--minorINFO&lt;/span&gt; - Old Version: 1.0.0INFO - New Version: 1.1.0INFO - git commit &lt;span class="nt"&gt;--message&lt;/span&gt; &lt;span class="s1"&gt;'bump version 1.0.0 -&amp;gt; 1.1.0'&lt;/span&gt;INFO - git tag &lt;span class="nt"&gt;--annotate&lt;/span&gt; 1.1.0 &lt;span class="nt"&gt;--message&lt;/span&gt; &lt;span class="s1"&gt;'1.1.0'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  📜 Elegir una licencia adecuada
&lt;/h3&gt;

&lt;p&gt;Cuando creamos una librera debemos elegir que permisos queremos que los dems tengan sobre nuestro cdigo, as se podr saber qu es lo que quiere que se haga o no con tu librera. Una licencia muy usada para compartir cdigo es la &lt;a href="https://mit-license.org/" rel="noopener noreferrer"&gt;Licencia MIT&lt;/a&gt; con esta licencia simple y bastante permisiva.&lt;/p&gt;

&lt;p&gt;Lo que debemos hacer es crear un archivo de texto llamado &lt;code&gt;LICENSE&lt;/code&gt; que contenga el texto de nuestra licencia, si no sabes que licencia escoger existe esta web que permite ver cul es la ms conveniente segn tus necesidades: &lt;a href="https://choosealicense.com/" rel="noopener noreferrer"&gt;Choose an open source license&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  📥 Instalar tu librera localmente
&lt;/h3&gt;

&lt;p&gt;Para este punto ya tenemos nuestra librera lista para ser publicada, ahora lo que vamos a necesitar hacer es probar nuestra librera instalndola directamente en nuestro entorno virtual, para esto haremos uso de los siguientes comandos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(env) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Con el flag &lt;code&gt;-e&lt;/code&gt; se instala tu librera en modo editable y con &lt;code&gt;.&lt;/code&gt; indicamos donde se encuentra el archivo &lt;code&gt;pyproject.toml&lt;/code&gt; esto ya deja disponible nuestro comando &lt;code&gt;rafnixg&lt;/code&gt; que est definido en la seccin &lt;code&gt;project.scripts&lt;/code&gt; indicando el punto de entrada.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(env) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;rafnixg Rafnix Guzmn Garcia &lt;span class="o"&gt;(&lt;/span&gt;@rafnixg&lt;span class="o"&gt;)&lt;/span&gt; - Python Software Developer username rafnixg name Rafnix Guzmn Garcia position Python Software Developer links https://links.rafnixg.dev web https://rafnixg.dev blog https://blog.rafnixg.dev cv https://resume.rafnixg.dev github https://github.com/rafnixg twitter @rafnixg about Experienced software developer with 10+ years of expertise &lt;span class="k"&gt;in &lt;/span&gt;designing, developing and implementing web systems across various sectors. Backend specialist skilled &lt;span class="k"&gt;in &lt;/span&gt;Python, Linux, and Git. Passionate about continuous learning and open-source technology.                     
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🚀 Publica tu librera a PyPI
&lt;/h2&gt;

&lt;p&gt;Ya nuestra librera se encuentra lista y a la espera de conocer el mundo, en esta seccin haremos el empaquetado y despliegue a &lt;strong&gt;PyPI.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🧑💻 Crear cuentas en PyPI y TestPyPI
&lt;/h3&gt;

&lt;p&gt;Lo primero que debemos tener es una cuenta en &lt;strong&gt;&lt;em&gt;PyPI&lt;/em&gt;&lt;/strong&gt; , as que si no la tienes este es tu momento de registrarte: &lt;a href="https://pypi.org/account/register/" rel="noopener noreferrer"&gt;https://pypi.org/account/register/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tambin deberamos crear una cuenta en el ambiente de pruebas de &lt;strong&gt;&lt;em&gt;PyPI&lt;/em&gt;&lt;/strong&gt; , as siempre podemos verificar que todo va bien antes de lanzar algo a produccin: &lt;a href="https://test.pypi.org/account/register/" rel="noopener noreferrer"&gt;https://test.pypi.org/account/register/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Recuerden crear sus &lt;code&gt;API Key&lt;/code&gt; porque en el proceso de publicacin mas adelante sern necesarias.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔐 Generar una API Key
&lt;/h3&gt;

&lt;p&gt;Para esto ingresamos a &lt;a href="https://pypi.org/manage/account/" rel="noopener noreferrer"&gt;Configuracion de la cuenta&lt;/a&gt; bajamos y buscamos la opcin &lt;strong&gt;Fichas de API&lt;/strong&gt; , hacemos clic en el botn &lt;code&gt;Aadir ficha de API&lt;/code&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.amazonaws.com%2Fuploads%2Farticles%2F4powzai9e3q2rtd31ssj.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.amazonaws.com%2Fuploads%2Farticles%2F4powzai9e3q2rtd31ssj.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Luego le ponen algn nombre descriptivo a esta &lt;strong&gt;Key&lt;/strong&gt; , seleccionamos el &lt;strong&gt;Alcance&lt;/strong&gt; y por ltimo clic al botn &lt;code&gt;Create Token&lt;/code&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.amazonaws.com%2Fuploads%2Farticles%2F2x7c56asmuaa1bpqejnk.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.amazonaws.com%2Fuploads%2Farticles%2F2x7c56asmuaa1bpqejnk.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Con esto nos mostrara nuestra API Key que siempre empieza por &lt;code&gt;pypy-&lt;/code&gt; como se muestra en la imagen de abajo:&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.amazonaws.com%2Fuploads%2Farticles%2F68tlf63q7a94pqga969u.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.amazonaws.com%2Fuploads%2Farticles%2F68tlf63q7a94pqga969u.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hacemos clic en Copiar Ficha y guardamos nuestra &lt;code&gt;API Key&lt;/code&gt; en algn lugar seguro**.** Siempre van a tener la posibilidad de borrar la key y generar otra si es necesario la pierden.&lt;/p&gt;

&lt;p&gt;🚩&lt;/p&gt;

&lt;p&gt;Nunca debemos compartir la API Key o agregarla directamente a un archivo que pueda estar trackeado en &lt;strong&gt;GIT.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Luego de todo esto debemos instalar 2 libreras que nos ayudaran a construir y publicar nuestro paquete:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(env) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install &lt;/span&gt;build twine
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🛠 Construir el paquete con &lt;code&gt;build&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Ahora que tenemos nuestra librera lista, ya podemos hacer la distribucin del cdigo a &lt;strong&gt;PyPI&lt;/strong&gt; , para esto primero debemos empaquetar nuestra librera en formato &lt;strong&gt;wheels&lt;/strong&gt; , un formato que consiste en empaquetar en un archivo &lt;code&gt;tar&lt;/code&gt; todo el cdigo fuente de la librera. Para crear este archivo haremos uso de la librera &lt;code&gt;build&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(env) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; build[...]Successfully built rafnixg-1.0.0.tar.gz and rafnixg-1.0.0-py3-none-any.whl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto nos crea una nueva carpeta llamada &lt;code&gt;dist/&lt;/code&gt; que contiene el archivo &lt;code&gt;.tar.gz&lt;/code&gt; con el cdigo de nuestra librera y el archivo &lt;code&gt;.whl&lt;/code&gt; que es nuestro archivo &lt;strong&gt;wheels&lt;/strong&gt; , esto es todo lo que necesitamos para subir a &lt;strong&gt;PyPI&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Verificar el paquete con &lt;code&gt;twine check&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Para validar que todo fue empaquetado correctamente podemos usar &lt;code&gt;twine&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(env) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;twine check dist/&lt;span class="k"&gt;*&lt;/span&gt;Checking dist/rafnixg-1.0.0-py3-none-any.whl: PASSEDChecking dist/rafnixg-1.0.0.tar.gz: PASSED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Subir el paquete a PyPI
&lt;/h3&gt;

&lt;p&gt;Ahora que tenemos todo listo y verificado, podemos subir a &lt;strong&gt;&lt;em&gt;TestPyPI&lt;/em&gt;&lt;/strong&gt; para ver que todo va con normalidad y no tenemos ningn error en nuestra librera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(env) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;twine upload &lt;span class="nt"&gt;-r&lt;/span&gt; testpypi dist/&lt;span class="k"&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nos pedir nuestra &lt;code&gt;API Key&lt;/code&gt;. Ya con esto podemos probar nuestra librera usando el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(env) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; https://test.pypi.org/simple/ rafnixg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si todo sali con normalidad, podemos subir a l repositorio principal de &lt;strong&gt;&lt;em&gt;PyPI&lt;/em&gt;&lt;/strong&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(env) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;twine upload dist/&lt;span class="k"&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Con esto tendramos nuestro proyecto ya disponible para usar con &lt;code&gt;pip&lt;/code&gt;, podemos a &lt;strong&gt;&lt;em&gt;PyPI&lt;/em&gt;&lt;/strong&gt; y buscar nuestra librera.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pypi.org/project/rafnixg" rel="noopener noreferrer"&gt;https://pypi.org/project/rafnixg&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.amazonaws.com%2Fuploads%2Farticles%2Fnqyi6924bkdnfn6qkqzl.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.amazonaws.com%2Fuploads%2Farticles%2Fnqyi6924bkdnfn6qkqzl.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  📥 Instalar tu paquete desde PyPI
&lt;/h3&gt;

&lt;p&gt;Ya con nuestra librera publicada en &lt;strong&gt;&lt;em&gt;PyPI&lt;/em&gt;&lt;/strong&gt; podemos usarla con el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(env) $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install &lt;/span&gt;rafnixg&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;env&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;rafnixg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧠 Conclusiones
&lt;/h2&gt;

&lt;p&gt;Crear y publicar tu propio paquete en Python es una experiencia enriquecedora que va ms all de compartir cdigo: es una oportunidad para aprender sobre la estructuracin de proyectos, el versionado semntico y las buenas prcticas de la comunidad. A lo largo de este tutorial, hemos recorrido desde la configuracin del entorno de desarrollo hasta la publicacin en &lt;strong&gt;&lt;em&gt;PyPI&lt;/em&gt;&lt;/strong&gt; , enfatizando la importancia de una documentacin clara y una estructura ordenada. Con estos conocimientos, no solo mejoras tus habilidades tcnicas, sino que tambin das un paso significativo hacia la consolidacin de tu perfil profesional en el mundo del desarrollo. Atrvete a experimentar, optimizar tu paquete y contribuir al ecosistema &lt;strong&gt;open source&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;📰&lt;/p&gt;

&lt;p&gt;En una prxima publicacin veremos cmo podemos crear un flujo de &lt;strong&gt;CI/CD&lt;/strong&gt; con &lt;strong&gt;Github Actions&lt;/strong&gt; para automatizar la publicacin de nuestra librera, tambin como documentarla y publicar con &lt;strong&gt;Github Pages&lt;/strong&gt; esta documentacin. Cualquier duda o consulta djalo en la seccin de comentarios.&lt;/p&gt;

&lt;p&gt;]]&amp;gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>pypi</category>
      <category>package</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Shell de Odoo: Domina Operaciones Avanzadas, Integración de Librerías y Automatización de Tareas</title>
      <dc:creator>Rafnix Guzmán</dc:creator>
      <pubDate>Mon, 10 Apr 2023 21:24:39 +0000</pubDate>
      <link>https://forem.com/rafnixg/shell-de-odoo-domina-operaciones-avanzadas-integracion-de-librerias-y-automatizacion-de-tareas-80a</link>
      <guid>https://forem.com/rafnixg/shell-de-odoo-domina-operaciones-avanzadas-integracion-de-librerias-y-automatizacion-de-tareas-80a</guid>
      <description>&lt;p&gt;En un post anterior, exploramos los conceptos bsicos de la shell de la &lt;a href="https://hashnode.com/post/clfv2dvp4014vmvnvgeie8rtc" rel="noopener noreferrer"&gt;CLI de Odoo y cmo configurar IPython como REPL&lt;/a&gt; para mejorar nuestra experiencia de desarrollo. Ahora, profundizaremos en el uso de la shell de Odoo, abordando temas ms avanzados y descubriendo cmo sacarle el mximo provecho a esta poderosa herramienta.&lt;/p&gt;

&lt;p&gt;El propsito de este post es proporcionar una gua completa para los desarrolladores de Odoo que deseen llevar sus habilidades al siguiente nivel y dominar el uso de la shell en sus proyectos. A lo largo del artculo, cubriremos temas como acceso avanzado, operaciones avanzadas, integracin de libreras externas, automatizacin de tareas y seguridad en la shell de Odoo.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Acceso avanzado a la shell de Odoo&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;La shell de Odoo es una herramienta poderosa que nos permite interactuar con el sistema Odoo y ejecutar tareas de desarrollo y administracin. En esta seccin, profundizaremos en algunas tcnicas avanzadas para acceder y utilizar la shell de Odoo de manera ms efectiva.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Uso de diferentes archivos de configuracin&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;En ocasiones, puede ser til tener diferentes archivos de configuracin para distintos entornos o propsitos. Por ejemplo, podras querer tener un archivo de configuracin especfico para trabajar con la shell de Odoo, que incluya parmetros ajustados para este propsito, como el nmero de workers, los lmites de memoria y los puertos XML-RPC y Longpolling.&lt;/p&gt;

&lt;p&gt;Para utilizar un archivo de configuracin especfico al acceder a la shell de Odoo, simplemente especifica la ruta del archivo con el parmetro &lt;code&gt;-c&lt;/code&gt; al ejecutar el comando &lt;code&gt;odoo-bin shell&lt;/code&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;./odoo-bin shell &lt;span class="nt"&gt;-c&lt;/span&gt; /path/to/your/custom/odoo.conf

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Asegrate de que tu archivo de configuracin personalizado incluye todos los parmetros necesarios para que la shell de Odoo funcione correctamente.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Acceso remoto a la shell de Odoo&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;En algunos casos, es posible que desees acceder a la shell de Odoo en un servidor remoto, en lugar de ejecutarla localmente. Para hacer esto, puedes utilizar una herramienta como &lt;code&gt;ssh&lt;/code&gt; para establecer una conexin segura con el servidor remoto y acceder a la shell de Odoo desde all.&lt;/p&gt;

&lt;p&gt;Primero, asegrate de tener &lt;code&gt;ssh&lt;/code&gt; instalado en tu mquina local y que tienes acceso al servidor remoto con las credenciales adecuadas. Luego, ejecuta el siguiente comando para establecer una conexin &lt;code&gt;ssh&lt;/code&gt; con el servidor remoto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ssh"&gt;&lt;code&gt;&lt;span class="k"&gt;ssh&lt;/span&gt; user@remote-server-ip

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Una vez que hayas iniciado sesin en el servidor remoto, navega hasta el directorio de instalacin de Odoo y sigue los pasos habituales para acceder a la shell de Odoo utilizando el comando &lt;code&gt;odoo-bin shell&lt;/code&gt; y el archivo de configuracin deseado.&lt;/p&gt;

&lt;p&gt;Al utilizar el acceso remoto a la shell de Odoo, ten en cuenta las implicaciones de seguridad y sigue las mejores prcticas para proteger tus datos y evitar accesos no autorizados.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Operaciones avanzadas en la shell de Odoo&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;La shell de Odoo ofrece muchas posibilidades para realizar tareas de desarrollo y administracin de manera eficiente. En esta seccin, abordaremos algunas operaciones avanzadas que puedes realizar en la shell de Odoo, lo que te permitir aprovechar an ms esta herramienta.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Actualizacin de mdulos desde la shell&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Es posible actualizar mdulos directamente desde la shell de Odoo. Para actualizar un mdulo existente, utiliza el mtodo &lt;code&gt;button_upgrade()&lt;/code&gt; en el mdulo que deseas actualizar:&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;module&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ir.module.module&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;([(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name&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;=&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;my_module&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;
&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;button_upgrade&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Donde &lt;code&gt;'my_module'&lt;/code&gt; es el nombre del modulo que deseo actualizar.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Importacin y exportacin de datos en formatos CSV&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;La shell de Odoo tambin facilita la importacin y exportacin de datos en formatos CSV y XML. Para importar datos desde un archivo CSV, sigue estos pasos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Instala la librera &lt;code&gt;csv&lt;/code&gt; en tu entorno de Odoo.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Utiliza la siguiente estructura para leer y procesar el archivo CSV:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&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;data.csv&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;r&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;csvfile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DictReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;csvfile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Procesa cada fila del archivo CSV
&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para exportar datos a un archivo CSV, puedes utilizar un enfoque similar:&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="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&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;data.csv&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="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;csvfile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;fieldnames&lt;/span&gt; &lt;span class="o"&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;field1&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;field2&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;field3&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;writer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DictWriter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;csvfile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fieldnames&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fieldnames&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeheader&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;records&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Escribe cada registro en el archivo CSV
&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para trabajar con datos en formato XML, puedes utilizar libreras como &lt;code&gt;lxml&lt;/code&gt; o &lt;code&gt;xml.etree.ElementTree&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Trabajo con registros y campos relacionales&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;La shell de Odoo facilita el trabajo con registros y campos relacionales. Para acceder a un campo relacional (por ejemplo, un campo Many2one), simplemente utiliza la notacin de punto:&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;record&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;res.partner&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;browse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&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;record&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parent_id&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;record&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;company_id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para acceder a campos relacionales inversos (por ejemplo, campos One2many o Many2many), utiliza la misma notacin de punto:&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;record&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;res.partner&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;browse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&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;record&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;child_ids&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;child&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;child_ids&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;child&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Bsqueda y manipulacin de registros con filtros y operadores avanzados&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;La shell de Odoo te permite buscar y manipular registros utilizando filtros y operadores avanzados usando la notacion de domains de Odoo. Por ejemplo, puedes utilizar el operador &lt;code&gt;like&lt;/code&gt; para buscar registros que coincidan con un patrn especfico:&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;records&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;res.partner&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;([(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name&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;like&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;R%&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;Tambin puedes combinar mltiples criterios de bsqueda utilizando operadores lgicos como &lt;code&gt;&amp;amp;&lt;/code&gt; (AND) y &lt;code&gt;|&lt;/code&gt; (OR):&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;records&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;res.partner&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;&amp;amp;&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="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name&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;like&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;R%&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="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;country_id.code&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;=&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;PE&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;h3&gt;
  
  
  &lt;strong&gt;Uso de contextos&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Los contextos en Odoo son una herramienta til para personalizar el comportamiento de las operaciones en funcin de ciertos parmetros, como el idioma o el usuario. Puedes utilizar contextos para realizar consultas en diferentes idiomas o para aplicar filtros especficos a nivel de usuario.&lt;/p&gt;

&lt;p&gt;Por ejemplo, para buscar registros en un idioma especfico, puedes pasar el cdigo de idioma en el contexto:&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;records&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;res.partner&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;with_context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;es_ES&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;([])&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto retornar los registros traducidos al idioma especificado en el contexto (en este caso, espaol).&lt;/p&gt;

&lt;p&gt;Tambin puedes utilizar contextos para aplicar filtros especficos a nivel de usuario. Por ejemplo, si deseas buscar registros que solo sean visibles para un usuario especfico, puedes hacer lo siguiente:&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;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="c1"&gt;# ID del usuario especfico
&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;res.users&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;browse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;records&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;res.partner&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;with_context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;([])&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto retornar los registros de socios comerciales que solo son visibles para el usuario con ID 2.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Integracin de libreras externas en la shell de Odoo&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;La shell de Odoo es un entorno interactivo de Python, lo que significa que puedes importar y utilizar libreras externas de Python para mejorar y ampliar la funcionalidad de la shell. En esta seccin, exploraremos cmo utilizar algunas libreras tiles para el anlisis y tratamiento de datos y tambin mencionaremos otras libreras que podran resultar de inters.&lt;/p&gt;

&lt;h3&gt;
  
  
  Uso de Pandas para el anlisis y tratamiento de datos
&lt;/h3&gt;

&lt;p&gt;Pandas es una biblioteca de Python popular y poderosa que ofrece estructuras de datos y herramientas de anlisis de datos. Su integracin en la shell de Odoo puede ser til para realizar anlisis de datos y para trabajar con grandes conjuntos de registros.&lt;/p&gt;

&lt;p&gt;Para utilizar Pandas en la shell de Odoo, primero debes instalarla en tu entorno de Python:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;pandas

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Una vez instalada, puedes importar Pandas en la shell de Odoo y empezar a utilizar sus funciones. Por ejemplo, puedes utilizar la funcin &lt;code&gt;DataFrame&lt;/code&gt; de Pandas para convertir un conjunto de registros de Odoo en un DataFrame de Pandas:&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="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;

&lt;span class="n"&gt;partners&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;res.partner&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;([])&lt;/span&gt;
&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;partner&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;partners&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;data&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;id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;partner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;partner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;partner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;country&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;partner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;country_id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ahora que tienes un DataFrame de Pandas, puedes utilizar todas las funciones y herramientas de anlisis de datos que ofrece Pandas. Por ejemplo, puedes realizar agrupaciones, filtrados, ordenamientos y mucho ms.&lt;/p&gt;

&lt;h3&gt;
  
  
  Otras libreras tiles para mejorar el trabajo en la shell
&lt;/h3&gt;

&lt;p&gt;Adems de Pandas, hay muchas otras libreras de Python que pueden ser tiles en la shell de Odoo. A continuacin, se mencionan algunas de ellas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;NumPy&lt;/strong&gt; : Esta biblioteca es muy til para realizar clculos matemticos y estadsticos en conjuntos de datos. Puedes utilizar NumPy junto con Pandas para llevar a cabo anlisis avanzados en tus datos de Odoo.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Requests&lt;/strong&gt; : Requests es una biblioteca popular para realizar solicitudes HTTP en Python. Puedes utilizarla en la shell de Odoo para interactuar con servicios web y APIs externas.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;OpenPyXL&lt;/strong&gt; : OpenPyXL es una biblioteca de Python para leer y escribir archivos Excel. Puedes utilizarla en la shell de Odoo para importar y exportar datos en formato Excel.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Estas son solo algunas de las muchas libreras disponibles para Python que pueden mejorar tu experiencia de trabajo en la shell de Odoo. No dudes en explorar otras libreras y adaptarlas a tus necesidades especficas.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Automatizacin de tareas con la shell de Odoo&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Una de las ventajas de trabajar con la shell de Odoo es la posibilidad de automatizar tareas y procesos. En esta seccin, exploraremos cmo ejecutar scripts y comandos desde archivos externos y cmo programar tareas automatizadas y cron jobs desde la shell.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ejecucin de scripts y comandos desde archivos externos
&lt;/h3&gt;

&lt;p&gt;En lugar de ejecutar comandos individualmente en la shell de Odoo, puedes crear un archivo de script de Python que contenga una serie de comandos y ejecutar ese archivo. Esto facilita la automatizacin y la reutilizacin de cdigo.&lt;/p&gt;

&lt;p&gt;Para ejecutar un script de Python usando el entorno de Odoo, debemos crear primero un script wrapper que nos permita ejecutar nuestros scripts inyectando el entorno de odoo. sigue estos pasos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Crea un archivo llamado &lt;code&gt;odoo_wrapper.py&lt;/code&gt; con el siguiente contenido:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Crea un archivo de script de Python (por ejemplo, &lt;code&gt;mi_script.py&lt;/code&gt;) con una funcin llamada &lt;code&gt;run&lt;/code&gt; que reciba un argumento &lt;code&gt;env&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Tus comandos aqui, utilizando la variable 'env' para acceder a la API de Odoo
&lt;/span&gt;    &lt;span class="c1"&gt;# Este archivo puede ser todo lo complejo que tu quieras
&lt;/span&gt;    &lt;span class="c1"&gt;# Para probar usemos esto de ejemplo:
&lt;/span&gt;    &lt;span class="n"&gt;partners&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;res.partner&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;search&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Numero de contactos:&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;partners&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Desde la lnea de comandos, navega hasta el directorio donde se encuentra el archivo &lt;code&gt;odoo_wrapper.py&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ejecuta el siguiente comando para ejecutar el archivo &lt;code&gt;odoo_wrapper.py&lt;/code&gt; y que a su vez ejecute tu archivo &lt;code&gt;mi_script.py&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 odoo_wrapper.py /path/to/mi_script.py

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El archivo &lt;code&gt;odoo_wrapper.py&lt;/code&gt; se encargar de ejecutar el archivo &lt;code&gt;mi_script.py&lt;/code&gt; utilizando la API de Odoo y la base de datos especificada en el archivo de configuracin. La funcin &lt;code&gt;run&lt;/code&gt; en tu archivo &lt;code&gt;mi_script.py&lt;/code&gt; se ejecutar con el entorno de Odoo proporcionado.&lt;/p&gt;

&lt;h3&gt;
  
  
  Programacin de tareas automatizadas y cron jobs desde la shell
&lt;/h3&gt;

&lt;p&gt;La shell de Odoo tambin te permite programar tareas automatizadas y cron jobs directamente desde la shell. Estas tareas se ejecutarn en intervalos especficos y pueden ser tiles para automatizar procesos como copias de seguridad, actualizaciones, sincronizaciones y ms.&lt;/p&gt;

&lt;p&gt;Para programar una tarea automatizada o un cron job desde la shell de Odoo, sigue estos pasos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;En la shell de Odoo, accede al modelo &lt;code&gt;ir.cron&lt;/code&gt;:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Crea un nuevo registro de cron job utilizando el mtodo &lt;code&gt;create()&lt;/code&gt; y proporciona los detalles necesarios, como el nombre, el modelo, el mtodo y el intervalo de tiempo:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;ir_cron&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name&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;Mi Cron Job&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;model_id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;base.model_res_partner&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;state&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;code&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;code&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;model.my_custom_method()&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;interval_number&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;interval_type&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;days&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;numbercall&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;doall&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;active&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este ejemplo, hemos creado un cron job que ejecutar el mtodo &lt;code&gt;my_custom_method()&lt;/code&gt; en el modelo &lt;code&gt;res.partner&lt;/code&gt; cada da. Puedes personalizar los parmetros segn tus necesidades.&lt;/p&gt;

&lt;p&gt;Una vez creada la tarea, se ejecutar automticamente segn el intervalo de tiempo especificado. Puedes verificar y administrar las tareas automatizadas y los cron jobs en la interfaz web de Odoo, bajo Configuracin &amp;gt; Tcnico &amp;gt; Automatizacin &amp;gt; Tareas programadas.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Seguridad y buenas prcticas en el uso de la shell de Odoo&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Recomendaciones para proteger la informacin y evitar accesos no autorizados&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Cuando trabajamos con la shell de Odoo, es importante tener en cuenta la seguridad y garantizar que la informacin y los datos estn protegidos. A continuacin, se presentan algunas recomendaciones para proteger la informacin y evitar accesos no autorizados:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Controlar el acceso a la shell de Odoo&lt;/strong&gt; : Limita el acceso a la shell de Odoo a los usuarios que realmente necesitan usarla. Asegrate de que las credenciales de inicio de sesin y los permisos estn configurados correctamente para restringir el acceso solo a los usuarios autorizados.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Proteger el archivo de configuracin&lt;/strong&gt; : El archivo de configuracin de Odoo puede contener informacin sensible, como contraseas de base de datos y otros datos de configuracin. Asegrate de proteger este archivo mediante permisos de lectura y escritura adecuados y almacenarlo en una ubicacin segura.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hacer copias de seguridad de los datos&lt;/strong&gt; : Realiza copias de seguridad peridicas de la base de datos de Odoo y almacena estas copias de seguridad en un lugar seguro y protegido. Esto te permitir restaurar los datos en caso de un problema de seguridad o una prdida de datos accidental.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Uso responsable de la shell en entornos de produccin&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Es importante utilizar la shell de Odoo de manera responsable en entornos de produccin para evitar problemas y garantizar la estabilidad del sistema. Aqu hay algunas pautas para usar la shell de Odoo de manera responsable:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Evitar cambios en tiempo real en entornos de produccin&lt;/strong&gt; : Aunque la shell de Odoo permite realizar cambios en tiempo real en la base de datos y el sistema, estos cambios pueden tener consecuencias imprevistas. Siempre es mejor realizar cambios en un entorno de desarrollo o prueba antes de aplicarlos en un entorno de produccin.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Limitar el uso de la shell en entornos de produccin&lt;/strong&gt; : Utiliza la shell de Odoo en entornos de produccin solo cuando sea necesario y por el tiempo estrictamente necesario. Evita dejar sesiones de shell abiertas innecesariamente.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Registrar y auditar el uso de la shell&lt;/strong&gt; : Mantn un registro de quin accede a la shell de Odoo y qu acciones se realizan en la shell. Estos registros pueden ser tiles para identificar problemas de seguridad y realizar auditoras.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Seguir las mejores prcticas de desarrollo&lt;/strong&gt; : Al utilizar la shell de Odoo para desarrollar mdulos y realizar cambios en la plataforma, sigue las mejores prcticas de desarrollo de Odoo para garantizar un cdigo seguro, eficiente y fcil de mantener.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusin&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;En este artculo, se profundizado en el uso y la configuracin de la shell de Odoo para aprovechar su potencial y mejorar nuestras habilidades en el desarrollo y la gestin de Odoo. Hemos cubierto temas esenciales como el acceso avanzado a la shell, la realizacin de operaciones avanzadas, la integracin de libreras externas, la automatizacin de tareas y la implementacin de medidas de seguridad y buenas prcticas.&lt;/p&gt;

&lt;p&gt;Espero que este artculo te haya proporcionado una comprensin ms profunda del potencial de la shell de Odoo y te haya equipado con el conocimiento necesario para aprovechar sus capacidades en tus proyectos. Te invitos a aplicar y experimentar con lo aprendido, y a compartir tus experiencias y conocimientos con otros miembros de la comunidad Odoo.&lt;/p&gt;

</description>
      <category>automation</category>
      <category>cli</category>
      <category>python</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Explorando Odoo a fondo: Cómo trabajar con la shell de la CLI y configurar IPython como REPL</title>
      <dc:creator>Rafnix Guzmán</dc:creator>
      <pubDate>Thu, 30 Mar 2023 12:00:39 +0000</pubDate>
      <link>https://forem.com/rafnixg/explorando-odoo-a-fondo-como-trabajar-con-la-shell-de-la-cli-y-configurar-ipython-como-repl-1kp4</link>
      <guid>https://forem.com/rafnixg/explorando-odoo-a-fondo-como-trabajar-con-la-shell-de-la-cli-y-configurar-ipython-como-repl-1kp4</guid>
      <description>&lt;p&gt;Hola a todos! Hoy vamos a explorar un tema esencial para todos los programadores de Odoo que deseen profundizar en el desarrollo y uso del ORM de Odoo: la shell de la CLI de Odoo. La CLI (Command Line Interface) de Odoo es la forma en que se ejecuta Odoo en la mayora de los casos, ya sea en modo de desarrollo o en produccin. Conocer cmo funciona la CLI y cmo usarla de manera efectiva nos permitir aprovechar al mximo las herramientas y funciones de Odoo y mejorar la eficiencia de nuestro trabajo.&lt;/p&gt;

&lt;p&gt;En este post, te guiar a travs de cmo acceder a la shell de Odoo y cmo configurarla para trabajar con IPython.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Cmo ejecutar una shell usando la CLI de Odoo&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Para acceder a la shell de Odoo, primero debemos asegurarnos de que Odoo est instalado en nuestro sistema. Si an no lo has hecho, te recomiendo seguir los pasos de instalacin de Odoo para tu sistema operativo o &lt;a href="https://dev.to/rafnixg/creando-un-entorno-de-desarrollo-para-odoo-140-con-vscode-en-ubuntu-2204-1fa"&gt;Creando un entorno de desarrollo para Odoo 14.0 con VSCode&lt;/a&gt;. Una vez instalado, sigue estos pasos para acceder a la shell de Odoo:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Abre la lnea de comandos o terminal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Navega hasta el directorio de instalacin de Odoo. Normalmente, esto se encuentra en "/usr/lib/odoo" o "/opt/odoo".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ejecuta el siguiente comando si tienes una instalacion desde codigo fuente:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./odoo-bin shell -c /path/to/odoo.conf --xmlrpc-port 8888 --longpolling-port 8899

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si es desde una instalcion usando los paquetes del sistema operativo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;odoo shell -c /path/to/odoo.conf --xmlrpc-port 8888 --longpolling-port 8899

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;-c /path/to/odoo.conf&lt;/code&gt;: especifica la ruta al archivo de configuracin de Odoo que deseas utilizar.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--xmlrpc-port 8888&lt;/code&gt;: establece el puerto XML-RPC que utiliza Odoo para comunicarse con otras aplicaciones.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--longpolling-port 8899&lt;/code&gt;: establece el puerto de long polling que utiliza Odoo para notificaciones en tiempo real.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cambiamos los puertos para que no choque con los puertos de nuestra instancia de Odoo que se esta ejecutando.&lt;/p&gt;

&lt;p&gt;Si todo funciona correctamente, deberas ver la siguiente lnea en la terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;env: &amp;lt;odoo.api.Environment object at 0x7efc89670ef0&amp;gt;
odoo: &amp;lt;module 'odoo' from '/usr/lib/python3/dist-packages/odoo/ __init__.py'&amp;gt;
openerp: &amp;lt;module 'odoo' from '/usr/lib/python3/dist-packages/odoo/ __init__.py'&amp;gt;
self: res.users(1,)
Python 3.x.x (default, MMM DD YYYY, HH:MM:SS)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ahora ests en la shell de Odoo. Puedes empezar a ejecutar comandos de Odoo y explorar la plataforma ERP. Por ejemplo, puedes ejecutar el siguiente comando para el usuario que se ejecuta en esta shell Odoo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;print(self.name)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tambin puedes interactuar con la base de datos de Odoo utilizando la sintaxis de ORM de Odoo. Por ejemplo, el siguiente comando cuenta todos los modelos de datos que tiene esta instancia de Odoo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;print(env['ir.model'].search_count([]))

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Cmo configurar la interfaz de la shell para usar IPython como REPL&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;IPython es un shell interactivo de Python que proporciona funciones avanzadas como autocompletado, resaltado de sintaxis, historial de comandos y ms. Utilizar IPython como REPL (Read-Eval-Print Loop) en lugar del shell estndar de Python puede mejorar nuestra experiencia de programacin en Odoo.&lt;/p&gt;

&lt;p&gt;Para configurar la shell de Odoo para usar IPython como REPL, sigue estos pasos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Instala IPython en tu sistema. En la mayora de los sistemas operativos, puedes instalarlo ejecutando el siguiente comando:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install ipython

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Ahora que IPython est instalado, debes modificar el comando que usamos anteriormente para acceder a la shell de Odoo, incluyendo la opcin &lt;code&gt;--shell-interface ipython&lt;/code&gt;. El comando modificado se ver as:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Desde codigo fuente
./odoo-bin shell -c /path/to/odoo.conf --xmlrpc-port 8888 --longpolling-port 8899 --shell-interface ipython


# Binario instalado
odoo shell -c /path/to/odoo.conf --xmlrpc-port 8888 --longpolling-port 8899 --shell-interface ipython

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1680142682619%2F4e5967a9-664c-4b2e-a86c-d2d044b443f4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1680142682619%2F4e5967a9-664c-4b2e-a86c-d2d044b443f4.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Al ejecutar este comando, acceders a la shell de Odoo con IPython como REPL,como vemos en la imagen, lo que te permitir aprovechar sus funciones avanzadas mientras trabajas con Odoo, para salir del modo shell con IPython debes usar &lt;code&gt;ctrl+D&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Recomendaciones para el uso de la shell de Odoo&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Configuracin separada para la shell de Odoo&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Es altamente recomendable tener un archivo de configuracin separado para la shell de Odoo. Esto nos permite ajustar los parmetros especficos para la shell sin afectar la configuracin de nuestra instancia de Odoo en produccin o desarrollo. Algunos de los parmetros que podras considerar ajustar en este archivo de configuracin separado incluyen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--xmlrpc-port 8888&lt;/code&gt;: Establecer un puerto XML-RPC diferente para evitar conflictos con la instancia principal de Odoo.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--longpolling-port 8899&lt;/code&gt;: Establecer un puerto de Long Polling diferente para evitar conflictos con la instancia principal de Odoo.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cambiar los valores de lmite de memoria (soft y hard memory limit) para asignar ms o menos recursos a la shell.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ajustar el nmero de workers para adaptarlo a tus necesidades especficas.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para crear un archivo de configuracin separado, simplemente copia tu archivo de configuracin principal y modifica los parmetros mencionados anteriormente. Luego, al ejecutar la shell de Odoo, usa la opcin &lt;code&gt;-c&lt;/code&gt; para especificar la ruta a este nuevo archivo de configuracin. Por ejemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./odoo-bin shell -c /path/to/shell-odoo.conf --shell-interface ipython


odoo- shell -c /path/to/shell-odoo.conf --shell-interface ipython

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Uso de libreras externas&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Al trabajar con la shell de Odoo, no ests limitado a utilizar solo las funcionalidades integradas en Odoo. Puedes aprovechar tambin las ventajas de libreras externas de Python para mejorar tu productividad y facilitar el anlisis y procesamiento de datos. Una de estas libreras es Pandas, una herramienta popular y potente para el anlisis y manipulacin de datos en Python.&lt;/p&gt;

&lt;p&gt;Puedes importar Pandas en la shell de Odoo e interactuar con los datos utilizando sus estructuras de datos como DataFrames y Series. Por ejemplo, puedes convertir los registros de un modelo de Odoo en un DataFrame de Pandas y luego realizar anlisis y manipulacin de datos avanzados. Esto puede ser especialmente til cuando necesitas generar informes o analizar datos de forma rpida y eficiente.&lt;/p&gt;

&lt;p&gt;Recuerda que al usar libreras externas como Pandas, es importante garantizar que estn correctamente instaladas y configuradas en tu entorno de desarrollo y, si es necesario, en el entorno de produccin.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusin&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;En resumen, la shell de la CLI de Odoo es una herramienta muy til para los desarrolladores de Odoo que desean profundizar en la programacin del ERP. A travs de la CLI, podemos interactuar con Odoo de una manera ms avanzada y personalizada. Adems, al configurar la interfaz de la shell para usar IPython como REPL, podemos aprovechar las funciones avanzadas de IPython y mejorar nuestra experiencia de programacin en Odoo.&lt;/p&gt;

&lt;p&gt;Espero que este post te haya sido til y te haya brindado una mejor comprensin de cmo trabajar con la shell de Odoo y configurarla con IPython. Si te ha gustado este post y crees que puede ser til para otros desarrolladores de Odoo, no dudes en compartirlo en tus redes sociales. Nos vemos en un proximo post donde profundizaremos en el uso de la shell de Odoo.&lt;/p&gt;

&lt;p&gt;Si quieren saber mas sobre IPython y la CLI de Odoo, aca les dejo los enlaces a su documentacin.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://ipython.readthedocs.io/en/stable/" rel="noopener noreferrer"&gt;Documentacin Oficial de IPython&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.odoo.com/documentation/master/developer/reference/cli.html" rel="noopener noreferrer"&gt;Documentacin Oficial de Odoo CLI&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Crea tu propio chatbot con la API de OpenAI y Gradio en Python</title>
      <dc:creator>Rafnix Guzmán</dc:creator>
      <pubDate>Wed, 22 Mar 2023 19:05:18 +0000</pubDate>
      <link>https://forem.com/rafnixg/crea-tu-propio-chatbot-con-la-api-de-openai-y-gradio-en-python-1gn3</link>
      <guid>https://forem.com/rafnixg/crea-tu-propio-chatbot-con-la-api-de-openai-y-gradio-en-python-1gn3</guid>
      <description>&lt;p&gt;Hoy vamos a aprender a crear una aplicacin en Python utilizando la API de OpenAI y Gradio. Esta publicacin ser til para las personas que quieren aprender a utilizar la API de OpenAI y crear una aplicacin con una interfaz de usuario interactiva de forma rapida y sin necesidad de usar HTML, CSS y Javscript.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduccin
&lt;/h2&gt;

&lt;p&gt;Antes de empezar, debemos entender qu es la API de OpenAI y Gradio.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://openai.com/" rel="noopener noreferrer"&gt;OpenAI&lt;/a&gt; es una organizacin de investigacin en inteligencia artificial. Ofrecen una API que permite acceder a modelos de inteligencia artificial avanzados para realizar diversas tareas, como responder preguntas, traducir oraciones, resumir noticias y ms.&lt;/p&gt;

&lt;p&gt;Por otro lado, &lt;a href="https://gradio.app/" rel="noopener noreferrer"&gt;Gradio&lt;/a&gt; es una herramienta de cdigo abierto para crear interfaces de usuario interactivas para modelos de inteligencia artificial. Ofrece una manera fcil y rpida de crear una interfaz de usuario para cualquier modelo de aprendizaje automtico.&lt;/p&gt;

&lt;p&gt;Ahora que tenemos una comprensin bsica de ambas herramientas, comencemos con el tutorial.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conectando a la API de OpenAI&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Para usar la API de OpenAI, necesitamos generar una clave API. Siga estos pasos para obtener su clave API:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Visite el sitio web de &lt;a href="https://platform.openai.com/signup" rel="noopener noreferrer"&gt;OpenAI&lt;/a&gt; y regstrese para obtener una cuenta gratuita.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Inicie sesin en su cuenta y vaya a la pgina de la &lt;a href="https://platform.openai.com/account/api-keys" rel="noopener noreferrer"&gt;API&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cree una nueva clave API y cpiela porque la usaremos mas adelante.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Instalacin de dependencias
&lt;/h2&gt;

&lt;p&gt;En este tutorial, crearemos una aplicacin de Chatbot utilizando la API de OpenAI y Gradio. Para empezar, necesitamos ubicarnos en la carpeta donde vamos a trabajar nuestro proyecto e instalar ambos paquetes en nuestra mquina. Como un paso previo a la instalacin de las dependecias se puede crear un entorno virtual de python para que las librerias no tengan colision con las del sistema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python3 -m venv venv
source venv/bin/activate

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Luego de activar el entorno virtual, procedemos a instalar las dependencias:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install openai
pip install gradio

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuracin de la clave API de OpenAI
&lt;/h2&gt;

&lt;p&gt;Una vez que tengamos ambos paquetes instalados, podemos comenzar a escribir nuestro cdigo.&lt;/p&gt;

&lt;p&gt;Primero, debemos configurar la API de OpenAI para poder acceder a sus servicios. Una vez que tengamos la clave API, podemos configurarla en nuestro cdigo de Python creando un archivo llamado &lt;code&gt;chatbot.py&lt;/code&gt; utilizando el siguiente cdigo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import openai
import os

# Obtener la clave API de OpenAI de la variable de entorno
openai.api_key = os.environ.get("OPENAI_API_KEY", None)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Asegrate de configurar la variable de entorno &lt;code&gt;OPENAI_API_KEY&lt;/code&gt; con tu clave API real antes de ejecutar el cdigo, sino en la ultima seccin te explico como hacerlo.&lt;/p&gt;

&lt;p&gt;Ahora que tenemos la clave API configurada, podemos comenzar a interactuar con la API de OpenAI. En este tutorial, crearemos un chatbot que puede responder a las preguntas de los usuarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuracin del mensaje por defecto
&lt;/h2&gt;

&lt;p&gt;Para crear un chatbot utilizando la API de OpenAI, necesitamos proporcionar una serie de mensajes como entrada a la API. Cada mensaje es una cadena de texto que representa el mensaje enviado por un usuario o el chatbot. Usaremos un mensaje por defecto para configurar y condicionar las respuesta GPT:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;messages = [
    {
        "role": "system",
        "content": "Act like a personal assistant. You can respond to questions, translate sentences, summarize news, and give recommendations."
    }
]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este ejemplo, el chatbot comienza presentndose como un asistente personal y proporcionando una lista de tareas que puede realizar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Funcin de llamada a la API de OpenAI
&lt;/h2&gt;

&lt;p&gt;Una vez que tenemos los mensajes de entrada preparados, podemos enviarlos a la API de OpenAI para generar una respuesta utilizando el siguiente cdigo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
def openai_process_message(user_message):
    # Set the prompt for OpenAI Api
    messages = [
        {
            "role": "system",
            "content": "Act like a personal assistant. You can respond to questions, translate sentences, summarize news, and give recommendations."
        }
    ]
    messages.append({"role": "user", "content": user_message})
    # Call the OpenAI Api to process our prompt
    openai_response = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=messages, max_tokens=2000)
    # Parse the response to get the response text for our prompt
    response_text = openai_response.choices[0].message.content
    return response_text

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La funcin &lt;code&gt;openai_process_message&lt;/code&gt; toma como entrada el mensaje del usuario y lo agrega a la lista de mensajes como un mensaje de usuario. A continuacin, llama a la API de OpenAI para procesar los mensajes y generar una respuesta. Por ltimo, la funcin devuelve la respuesta generada por la API de OpenAI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creacin de la UI con Gradio
&lt;/h2&gt;

&lt;p&gt;A continuacin, crearemos una lista de ejemplos que se utilizarn para mostrar ejemplos en la interfaz de usuario. En este caso, utilizaremos preguntas sobre la inteligencia artificial.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;examples = [
    "Que es la IA?",
    "Como funciona una red neuronal?",
    "pueden las maquinas aprender?",
]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Luego, creamos una instancia de la clase &lt;code&gt;Interface&lt;/code&gt; de Gradio y le pasamos la funcin &lt;code&gt;openai_process_message()&lt;/code&gt; como argumento. A continuacin, definimos el tipo de entrada y salida que deseamos para nuestra interfaz. En este caso, utilizaremos una caja de texto para la entrada del usuario y otra para mostrar la respuesta del chatbot.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Create a Gradio interface instance
demo = gr.Interface(
    fn=openai_process_message,
    inputs=gr.Textbox(lines=5, label='Pregunta', placeholder='Escribe tu pregunta aqu...'),
    outputs=gr.Textbox(label='Respuesta'),
    examples=examples,
    title="Chatbot OpenAI API",
)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finalmente, lanzamos la interfaz de usuario utilizando el mtodo &lt;code&gt;launch()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if __name__ == " __main__":
    demo.launch()

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Corriendo nuestra aplicacin
&lt;/h2&gt;

&lt;p&gt;Recuerda que antes de lanzar la aplicacin, debes configurar la variable de entorno "OPENAI_API_KEY" con tu clave de API de OpenAI. Puedes hacerlo de la siguiente manera en tu terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export OPENAI_API_KEY=&amp;lt;tu_clave_de_api&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Donde  debe ser reemplazada con tu clave de API real de OpenAI.&lt;/p&gt;

&lt;p&gt;Para lanzar la aplicacin, puedes simplemente ejecutar el archivo Python en tu terminal o IDE de Python:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python chatbot.py

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1679438402612%2Fe8a57a90-5afd-4d5e-9dfa-a6ef90d6bd3e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1679438402612%2Fe8a57a90-5afd-4d5e-9dfa-a6ef90d6bd3e.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Con esto ya tenemos nuestra app corriendo sobre &lt;a href="https://127.0.0.1:7860" rel="noopener noreferrer"&gt;https://127.0.0.1:7860&lt;/a&gt; y con la siguiente UI de forma facil y rapida:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1679438572766%2F7cba6334-d1b2-43bb-b34c-4c60369c4151.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1679438572766%2F7cba6334-d1b2-43bb-b34c-4c60369c4151.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusiones
&lt;/h2&gt;

&lt;p&gt;Ahora tenemos una aplicacin completa de preguntas y respuestas que utiliza la API de OpenAI para generar respuestas a cualquier pregunta que el usuario pueda tener. Esta aplicacin es solo un ejemplo de lo que se puede hacer con la API de OpenAI y la biblioteca Gradio. Hay muchas otras aplicaciones de inteligencia artificial que se pueden crear utilizando estas herramientas.&lt;/p&gt;

&lt;p&gt;En un proximo post voy a implementar otra UI usando el componente Chatbot de Gradio para darle un diseo mas acoorde al un chatbot y algunos otros tips a la hora de usar Gradio, por el momento es un buen punto de partida para practicar y probar estas tecnologias.&lt;/p&gt;

&lt;h2&gt;
  
  
  Codigo completo
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Archivo chatbot.py
import gradio as gr
import openai
import os

# Get OpenAI API Key from environment variable
openai.api_key = os.environ.get("OPENAI_API_KEY", None)

def openai_process_message(user_message):
    # Set the prompt for OpenAI Api
    messages = [
        {
            "role": "system",
            "content": "Act like a personal assistant. You can respond to questions, translate sentences, summarize news, and give recommendations."
        }
    ]
    messages.append({"role": "user", "content": user_message})
    # Call the OpenAI Api to process our prompt
    openai_response = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=messages, max_tokens=2000)
    # Parse the response to get the response text for our prompt
    response_text = openai_response.choices[0].message.content
    return response_text

examples = [
    "Que es un chatbot?",
    "podrias definir que es una IA?",
    "dime cual seria una receta para hacer salsa bechamel?",
]

demo=gr.Interface(
    fn=openai_process_message,
    inputs=gr.Textbox(lines=5, label='Pregunta',placeholder='Escribe tu pregunta'),
    outputs=gr.Textbox(label='Respuesta'),
    examples=examples,
    title="Chatbot OpenAI API",
)
if __name__ == " __main__":
    demo.launch()

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>python</category>
      <category>chatgpt</category>
      <category>gradio</category>
      <category>openai</category>
    </item>
    <item>
      <title>Los servicios que uso en mi HomeLab server: virtualización, contenedores y más.</title>
      <dc:creator>Rafnix Guzmán</dc:creator>
      <pubDate>Mon, 20 Mar 2023 23:42:31 +0000</pubDate>
      <link>https://forem.com/rafnixg/los-servicios-que-uso-en-mi-homelab-server-virtualizacion-contenedores-y-mas-4hce</link>
      <guid>https://forem.com/rafnixg/los-servicios-que-uso-en-mi-homelab-server-virtualizacion-contenedores-y-mas-4hce</guid>
      <description>&lt;p&gt;Hola nuevamente! hoy quiero profundizar en cada uno de los servicios y aplicaciones que tengo en mi homelab server y compartirlas contigo.&lt;/p&gt;

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

&lt;p&gt;En mi camino como desarrollador y entusiasta de la tecnologa, he construido un homelab server en mi casa para experimentar con nuevas tecnologas y aprender de forma autodidacta. Es un servidor casero donde puedo ejecutar diferentes servicios y herramientas en un ambiente controlado.&lt;/p&gt;

&lt;p&gt;En este artculo, compartir con ustedes los servicios que actualmente estoy corriendo en mi homelab server. Estos servicios incluyen virtualizacin con Proxmox, contenedores con LXC y Docker, una plataforma como servicio (PaaS) llamada Coolify, un backend as a service (BaaS) llamado Appwrite, Pi-hole para bloquear anuncios y rastreadores, Plausible para analizar las mtricas de mi sitio, y mucho ms. Si ests interesado en crear tu propio homelab server o simplemente deseas conocer qu servicios estoy usando, sigue leyendo para conocer ms.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Proxmox VE&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AYSUPB_j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1679354595439/a606ff2f-6af1-497c-9a35-71f59a74bc02.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AYSUPB_j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1679354595439/a606ff2f-6af1-497c-9a35-71f59a74bc02.png" alt="" width="800" height="323"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.proxmox.com/"&gt;Proxmox VE&lt;/a&gt; es una plataforma de virtualizacin de cdigo abierto que utilizo para virtualizar y administrar mis servidores. Proxmox me permite crear y gestionar contenedores Linux (LXC) y mquinas virtuales (VM), lo que me brinda una gran flexibilidad y ahorro de recursos en mi homelab server.&lt;/p&gt;

&lt;p&gt;Los contenedores LXC son una forma ligera y eficiente de virtualizacin que me permiten ejecutar mltiples servicios en mi homelab server de manera aislada y segura. Por otro lado, las mquinas virtuales son una forma ms tradicional de virtualizacin que me permiten ejecutar sistemas operativos completos en mi homelab server, lo que es til para probar diferentes configuraciones y experimentar con nuevas tecnologas.&lt;/p&gt;

&lt;p&gt;Proxmox tiene una interfaz web fcil de usar que me permite crear y gestionar mis contenedores LXC y mquinas virtuales de manera sencilla. Tambin cuenta con una comunidad activa y una amplia documentacin que me ha sido de gran ayuda a lo largo del tiempo.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Coolify&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4VNFnhnZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1679354733424/3149397a-9f00-444b-844d-2d918f1d7a94.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4VNFnhnZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1679354733424/3149397a-9f00-444b-844d-2d918f1d7a94.png" alt="" width="800" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://coolify.io/"&gt;Coolify&lt;/a&gt; es una plataforma como servicio (PaaS) que utilizo para alojar mi sitio web. Es una alternativa a Heroku, pero self-hosted, lo que me brinda ms control y flexibilidad. Dentro de Coolify, tengo desplegado mi sitio &lt;a href="https://rafnixg.dev"&gt;web&lt;/a&gt;. Adems, utilizo Appwrite, un Backend as a Service (BaaS) del que hablare mas adelante y algunas aplicaciones desplegadas usando docker.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Appwrite&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--e_X7UDBu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1679354761054/c8fd9ad7-b7a9-44e1-8a5a-0cb47d698f52.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--e_X7UDBu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1679354761054/c8fd9ad7-b7a9-44e1-8a5a-0cb47d698f52.png" alt="" width="800" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://appwrite.io/"&gt;Appwrite&lt;/a&gt; es un Backend as a Service (BaaS) que utilizo para gestionar mi sitio web. Me ayuda a manejar fcilmente usuarios, bases de datos y autenticacin en mi sitio web, lo que me ahorra mucho tiempo y esfuerzo. Appwrite es muy fcil de integrar con Coolify, y tiene una interfaz de usuario web muy intuitiva.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Plausible&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--B-VoNqTJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1679354407326/3617b113-832c-4f33-bd2f-ba2709e781c8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B-VoNqTJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1679354407326/3617b113-832c-4f33-bd2f-ba2709e781c8.png" alt="" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://plausible.io/"&gt;Plausible&lt;/a&gt; es una herramienta de anlisis web de cdigo abierto que utilizo para analizar las mtricas de mi sitio web. Es una alternativa a Google Analytics, pero ms centrada en la privacidad. Plausible utiliza una arquitectura simple y ligera que no rastrea a los usuarios y no recopila informacin personal. Plausible me brinda informacin detallada sobre el trfico de mi sitio web, como la cantidad de visitas, la ubicacin geogrfica de los visitantes y el tiempo promedio en el sitio.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Portainer&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jGOtoFXC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.portainer.io/hubfs/Edge%2520Aug22/edge-mockup.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jGOtoFXC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.portainer.io/hubfs/Edge%2520Aug22/edge-mockup.png" alt="Portainer User Interface - Multiple endpoints" width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.portainer.io/"&gt;Portainer&lt;/a&gt; es una herramienta de gestin de contenedores de Docker que utilizo para administrar y supervisar mis contenedores. Portainer tiene una interfaz de usuario web que me permite ver fcilmente el estado de mis contenedores, administrar imgenes y supervisar logs. Utilizo Portainer para gestionar Pi-Hole y otros servicios como el speedtracker en mi homelab server.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Pi-Hole&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JRbRdO07--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1679354884844/267bfbbc-b436-43b2-8fbf-6e749f0df02b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JRbRdO07--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1679354884844/267bfbbc-b436-43b2-8fbf-6e749f0df02b.png" alt="" width="800" height="526"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pi-hole.net/"&gt;Pi-hole&lt;/a&gt; es una aplicacin de bloqueo de anuncios y rastreadores en Internet que utilizo para proteger mi navegacin web y reducir la cantidad de anuncios. Pi-Hole utiliza una lista de bloqueo de anuncios actualizada regularmente para bloquear anuncios en todos mis dispositivos de red. Pi-hole funciona bloqueando las solicitudes de DNS de anuncios y rastreadores, lo que significa que la mayora de los anuncios y rastreadores simplemente no se cargan.&lt;/p&gt;

&lt;p&gt;En mi homelab server, utilizo Pi-hole como mi servidor de DNS local y bloqueador de anuncios y rastreadores. Pi-hole es fcil de configurar y puedo personalizar las listas de bloqueo de anuncios y rastreadores segn mis necesidades. Tambin puedo ver estadsticas detalladas sobre los dominios bloqueados y la cantidad de solicitudes de DNS procesadas por Pi-hole. Es una herramienta til para mantener la privacidad y seguridad en mi red domstica.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Speedtest Tracker&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6U6DjFV8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1679354922703/afb58053-71c3-4ce7-801d-6c62a6ad0355.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6U6DjFV8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1679354922703/afb58053-71c3-4ce7-801d-6c62a6ad0355.png" alt="" width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.speedtest-tracker.dev/"&gt;Speedtest Tracker&lt;/a&gt; es una herramienta de monitoreo de velocidad de internet que utilizo para supervisar la velocidad de mi conexin a internet. Speedtest Tracker se ejecuta en un contenedor de Docker y utiliza Speedtest CLI para realizar pruebas de velocidad en intervalos regulares. Speedtest Tracker me brinda informacin detallada sobre la velocidad de mi conexin a internet, como la velocidad de descarga, la velocidad de carga y la latencia. Tambin puedo ver grficas de tendencias y estadsticas de velocidad a lo largo del tiempo.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Cloudflare Tunnels&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Cloudflare Tunnels es un servicio que utilizo para conectar mis contenedores y mi dominio. Con Cloudflare Tunnels, puedo acceder a mis servicios de forma segura desde cualquier lugar, sin tener que preocuparme por abrir puertos en mi firewall. Cloudflare Tunnels tambin me ayuda a ocultar la direccin IP de mi servidor, lo que aumenta mi privacidad y seguridad. Si quieres conocer ms acerca de Cloudflare Tunnels, puedes visitar &lt;a href="https://developers.cloudflare.com/cloudflare-one/tutorials/share-localhost-on-the-internet"&gt;&lt;strong&gt;su sitio web&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Nginx Proxy Manager&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RuoFtstK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1679355046298/fb56717b-721d-422f-bf9c-6c140bfbe487.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RuoFtstK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1679355046298/fb56717b-721d-422f-bf9c-6c140bfbe487.png" alt="" width="800" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nginx Proxy Manager es una herramienta de gestin de proxies que utilizo para gestionar la redireccin en dominios locales junto con Pi-Hole. Nginx Proxy Manager tiene una interfaz de usuario web sencilla que me permite configurar fcilmente proxies y redirecciones para mis servicios en contenedores. Adems, Nginx Proxy Manager me ayuda a asegurar mis servicios al permitirme configurar SSL/TLS para mis dominios. Si ests interesado en conocer ms sobre Nginx Proxy Manager, puedes visitar &lt;a href="https://nginxproxymanager.com/"&gt;&lt;strong&gt;su sitio web&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resumen
&lt;/h2&gt;

&lt;p&gt;En mi homelab server, tengo configurados varios servicios para llevar a cabo diversas tareas. Proxmox me permite virtualizar y administrar mis servidores, y utilizo tanto contenedores LXC como mquinas virtuales para ejecutar diferentes servicios y experimentar con nuevas tecnologas.&lt;/p&gt;

&lt;p&gt;Coolify es una plataforma como servicio que utilizo para alojar mi sitio web, con un backend as a service llamado Appwrite para manejar usuarios y bases de datos. Para analizar las mtricas de mi sitio, utilizo Plausible, y para bloquear anuncios y rastreadores en mi red, utilizo Pi-hole.&lt;/p&gt;

&lt;p&gt;Adems, utilizo Cloudflare Tunnels para conectar mis contenedores dentro de mi servidor y mi dominio de forma segura, y Nginx Proxy Manager para gestionar la redireccin en dominios locales junto con Pi-hole.&lt;/p&gt;

&lt;p&gt;En resumen, estos son los servicios que tengo en mi homelab server y que me permiten experimentar con diferentes tecnologas y aplicaciones en un entorno seguro y controlado. Si ests interesado en crear tu propio homelab server, te recomiendo comenzar con algunos de estos servicios y experimentar para encontrar lo que mejor se adapte a tus necesidades. Que disfrutes la creacin de tu homelab server!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Creando un entorno de desarrollo para Odoo 14.0 con VSCode en Ubuntu 22.04</title>
      <dc:creator>Rafnix Guzmán</dc:creator>
      <pubDate>Tue, 14 Mar 2023 13:00:39 +0000</pubDate>
      <link>https://forem.com/rafnixg/creando-un-entorno-de-desarrollo-para-odoo-140-con-vscode-en-ubuntu-2204-1fa</link>
      <guid>https://forem.com/rafnixg/creando-un-entorno-de-desarrollo-para-odoo-140-con-vscode-en-ubuntu-2204-1fa</guid>
      <description>&lt;p&gt;En este artculo aprenders a configurar un entorno de desarrollo para Odoo 14.0 en Ubuntu 22.04. Si ests leyendo esto, probablemente ya sabes que Odoo es un ERP basado en Python, PostgreSQL y XML que permite a las empresas gestionar sus procesos empresariales de manera integrada.&lt;/p&gt;

&lt;p&gt;Antes de empezar con la configuracin del entorno de desarrollo, asegrate de tener instalado los siguientes requisitos previos: Python 3, Git, PostgreSQL y VSCode. Si an no los tienes, puedes seguir los siguientes enlaces para instalarlos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Python 3: &lt;a href="https://www.python.org/downloads/"&gt;&lt;strong&gt;https://www.python.org/downloads/&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Git: &lt;a href="https://git-scm.com/downloads"&gt;&lt;strong&gt;https://git-scm.com/downloads&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PostgreSQL: &lt;a href="https://www.postgresql.org/download/"&gt;&lt;strong&gt;https://www.postgresql.org/download/&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VSCode: &lt;a href="https://code.visualstudio.com/download"&gt;&lt;strong&gt;https://code.visualstudio.com/download&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Una vez que tengas estos requisitos previos instalados, ests listo para empezar a configurar tu entorno de desarrollo de Odoo. En este post, te enseare cmo crear una estructura de carpetas adecuada para trabajar con Odoo y cmo configurar VSCode para poder debuggear el cdigo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Instalacin de PostgreSQL
&lt;/h2&gt;

&lt;p&gt;Para trabajar con Odoo, necesitars tener instalado PostgreSQL. PostgreSQL es un sistema de gestin de bases de datos relacional de cdigo abierto. Para instalar PostgreSQL en Ubuntu/Debian, puede seguir los siguientes pasos en la terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update
sudo apt upgrade
sudo apt install postgresql postgresql-client
sudo -u postgres createuser -s $USER
createdb odoo-dev-14.0

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;sudo apt update&lt;/code&gt;: Este comando se utiliza para actualizar la lista de paquetes disponibles en los repositorios de Ubuntu/Debian. Es importante ejecutar este comando antes de instalar cualquier software nuevo en Ubuntu para asegurarse de que se estn utilizando las versiones ms recientes de los paquetes disponibles.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;sudo apt upgrade&lt;/code&gt;: Este comando se utiliza para actualizar los paquetes existentes en el sistema operativo. Al ejecutar este comando, se descargarn e instalarn las actualizaciones disponibles para todos los paquetes instalados en el sistema.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;sudo apt install postgresql postgresql-client&lt;/code&gt;: Estos comandos se utilizan para instalar PostgreSQL y su cliente en el sistema operativo. PostgreSQL es un sistema de gestin de bases de datos relacionales que se utiliza comnmente como base de datos para Odoo.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;sudo -u postgres createuser -s $USER&lt;/code&gt;: Este comando se utiliza para crear un usuario en PostgreSQL con todos los privilegios necesarios para trabajar con Odoo. El comando se ejecuta como el usuario "postgres", que es el usuario por defecto de PostgreSQL. &lt;code&gt;$USER&lt;/code&gt; es una variable de entorno que contiene el nombre de usuario actual.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;createdb odoo-dev-14.0&lt;/code&gt;: Este comando se utiliza para crear una nueva base de datos en PostgreSQL llamada "odoo-dev-14.0". Esta ser la base de datos que se utilizar para desarrollar y probar Odoo en este entorno de desarrollo.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Es importante destacar que despus de la instalacin, es necesario realizar algunas configuraciones de seguridad adicionales para garantizar la proteccin de los datos de la empresa. Sin embargo, para fines de este tutorial y dado que nos encontramos en un ambiente de desarrollo, no profundizaremos en este aspecto&lt;/p&gt;

&lt;h2&gt;
  
  
  Instalacin de dependencias
&lt;/h2&gt;

&lt;p&gt;Antes de empezar a trabajar con Odoo, necesitamos instalar algunas dependencias en nuestro sistema operativo. Para hacerlo, podemos seguir las instrucciones &lt;a href="https://www.odoo.com/documentation/14.0/es/administration/install/install.html#id14"&gt;oficiales&lt;/a&gt; que recomiendan utilizar los siguientes comandos en la terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update
sudo apt upgrade
sudo apt install python3-dev python3-pip python3-venv libxml2-dev \
libxslt1-dev libldap2-dev libsasl2-dev libtiff5-dev \
libjpeg8-dev libopenjp2-7-dev zlib1g-dev libfreetype6-dev \
liblcms2-dev libwebp-dev libharfbuzz-dev libfribidi-dev libxcb1-dev libpq-dev

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Estos comandos nos permitirn instalar todas las dependencias necesarias para trabajar con Odoo en nuestro sistema Ubuntu 22.04. Es importante asegurarse de que todas las dependencias se instalen correctamente antes de continuar con la configuracin de nuestro entorno de desarrollo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creacin de la estructura de carpetas
&lt;/h2&gt;

&lt;p&gt;Una vez instalado PostgreSQL y las dependencias necesarias, es hora de crear una estructura de carpetas para trabajar con Odoo. Para ello, ejecuta en la terminal el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir -p ~/Odoo/{src,workspaces,instances,instances/odoo-dev-14.0}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esta una forma abreviada de crear varias carpetas a la vez utilizando llaves y una lista de nombres de carpeta separados por comas.&lt;/p&gt;

&lt;p&gt;En este caso, el comando crea una estructura de carpetas dentro de la carpeta principal del usuario (representado por el smbolo "~" que se refiere al directorio de inicio del usuario) con los siguientes nombres de carpeta:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;src&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;workspaces&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;instances&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;instances/odoo-dev-14.0&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;La opcin "-p" indica que se crearn todas las carpetas necesarias en la ruta, incluso si algunas de ellas ya existen. De esta manera, se crea una estructura de carpetas adecuada para trabajar con Odoo y se asegura de que todas las carpetas necesarias estn disponibles en el directorio de inicio del usuario.&lt;/p&gt;

&lt;h2&gt;
  
  
  Instalacin de Odoo 14.0
&lt;/h2&gt;

&lt;p&gt;Ahora que hemos instalado PostgreSQL, Python y las dependencias necesarias, podemos proceder a instalar Odoo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Descargar el cdigo fuente de Odoo 14.0
&lt;/h3&gt;

&lt;p&gt;Para descargar el cdigo fuente de Odoo 14.0, ejecuta en la terminal el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/odoo/odoo.git --single-branch --depth 1 --branch 14.0 ~/Odoo/src/14.0

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este comando descargar el cdigo fuente de Odoo 14.0 en la carpeta &lt;code&gt;~/Odoo/src/14.0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;El parmetro --single-branch indica que solo se clonar la rama especificada en lugar de todas las ramas del repositorio. El parmetro --depth 1 indica que solo se clonar el historial ms reciente del repositorio, lo que reduce el tiempo y espacio necesarios para la descarga.&lt;/p&gt;

&lt;h3&gt;
  
  
  Crear un entorno virtual
&lt;/h3&gt;

&lt;p&gt;Para crear un entorno virtual de Python para Odoo, ejecute el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python3 -m venv ~/Odoo/instances/odoo-dev-14.0/venv

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este comando crear un entorno virtual para Odoo en la carpeta &lt;code&gt;~/Odoo/instances/odoo-dev-14.0/venv&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Instalar las dependencias de Odoo
&lt;/h3&gt;

&lt;p&gt;Para instalar las dependencias de python para Odoo, ejecute los siguientes comandos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;source ~/Odoo/instances/odoo-dev-14.0/venv/bin/activate
pip3 install setuptools wheel inotify psycopg2-binary
pip3 install -r ~/Odoo/src/14.0/requirements.txt
deactivate

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Estos comandos activarn el entorno virtual de Odoo, instalarn las dependencias necesarias y desactivarn el entorno virtual.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;source ~/Odoo/instances/odoo-dev-14.0/venv/bin/activate&lt;/code&gt;: este comando activa el entorno virtual de Odoo para que puedas instalar las dependencias necesarias sin afectar al sistema operativo.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;pip3 install setuptools wheel inotify psycopg2-binary&lt;/code&gt;: estos son paquetes de Python necesarios para ejecutar Odoo. &lt;code&gt;setuptools&lt;/code&gt; y &lt;code&gt;wheel&lt;/code&gt; son herramientas de construccin de paquetes, &lt;code&gt;inotify&lt;/code&gt; es una biblioteca para monitorear cambios en archivos y directorios, y &lt;code&gt;psycopg2-binary&lt;/code&gt; es un controlador de base de datos PostgreSQL para Python.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;pip3 install -r ~/Odoo/src/14.0/requirements.txt&lt;/code&gt;: este comando instala todas las dependencias adicionales requeridas por Odoo, que estn enumeradas en el archivo &lt;code&gt;requirements.txt&lt;/code&gt;. El prefijo &lt;code&gt;-r&lt;/code&gt; significa "de un archivo de requisitos".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;deactivate&lt;/code&gt;: este comando desactiva el entorno virtual de Odoo, lo que significa que ya no se estn utilizando las dependencias instaladas en dicho entorno.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Con estos pasos, hemos instalado Odoo 14.0 en nuestro entorno de desarrollo de Ubuntu 22.04. Ahora podemos empezar a trabajar con Odoo y personalizarlo segn nuestras necesidades.&lt;/p&gt;

&lt;h3&gt;
  
  
  Crear el archivo de configuracin de Odoo
&lt;/h3&gt;

&lt;p&gt;Despus de haber creado el entorno virtual de Python y haber instalado las dependencias necesarias, el siguiente paso es configurar Odoo para que se ejecute correctamente en el entorno virtual. Para esto, es necesario crear un archivo de configuracin especfico para su instancia de Odoo.&lt;/p&gt;

&lt;p&gt;Para crear el archivo de configuracin, ejecute los siguientes comandos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cp ~/Odoo/src/14.0/debian/odoo.conf ~/Odoo/instances/odoo-dev-14.0 
sed -i 's/db_user = odoo/db_user = '$USER'/' ~/Odoo/instances/odoo-dev-14.0/odoo.conf

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El primer comando copia el archivo de configuracin predeterminado de Odoo a la carpeta de su instancia de Odoo. El segundo comando utiliza el comando "sed" para reemplazar el usuario de la base de datos predeterminado de "odoo" por el usuario actual. Esto es necesario para que Odoo pueda acceder a la base de datos en el entorno virtual.&lt;/p&gt;

&lt;p&gt;Una vez que haya creado el archivo de configuracin de Odoo, podr personalizarlo para adaptarlo a sus necesidades especficas. Puede configurar la direccin IP, el puerto, la base de datos y otras opciones para su instancia de Odoo si ya tenia una instalacin de PostgreSQL.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Inicializar la base de datos de Odoo&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Una vez que se han instalado las dependencias de Odoo y se ha creado el archivo de configuracin, el siguiente paso es inicializar la base de datos de Odoo. Para hacer esto, se utilizar el comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/Odoo/instances/odoo-dev-14.0/venv/bin/python3 ~/Odoo/src/14.0/odoo-bin -c ~/Odoo/instances/odoo-dev-14.0/odoo.conf -d odoo-dev-14.0 -i base --stop-after-init

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este comando ejecuta el archivo &lt;code&gt;odoo-bin&lt;/code&gt; que se encuentra en la carpeta &lt;code&gt;src/14.0&lt;/code&gt; del directorio raz de Odoo. El parmetro &lt;code&gt;-c&lt;/code&gt; especifica la ruta del archivo de configuracin de Odoo que se cre anteriormente. El parmetro &lt;code&gt;-d&lt;/code&gt; especifica el nombre de la base de datos que se crear e inicializar. En este caso, se est utilizando &lt;code&gt;odoo-dev-14.0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;El parmetro &lt;code&gt;-i&lt;/code&gt; indica los mdulos de Odoo que se instalarn. En este caso, solo se est instalando el mdulo base de Odoo. Sin embargo, es posible agregar ms mdulos separndolos por comas.&lt;/p&gt;

&lt;p&gt;Finalmente, el parmetro &lt;code&gt;--stop-after-init&lt;/code&gt; detiene el servidor de Odoo despus de inicializar la base de datos. Esto es til si solo se desea inicializar la base de datos y no ejecutar el servidor completo de Odoo.&lt;/p&gt;

&lt;p&gt;Una vez que se ejecuta este comando, se crear y se inicializar la base de datos de Odoo. Este proceso puede tardar unos minutos, dependiendo de la velocidad de su computadora.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuracin del debugger de VSCode para Odoo 14.0
&lt;/h2&gt;

&lt;p&gt;Una herramienta til para desarrollar en Odoo es el debugger de Visual Studio Code (VSCode), que permite depurar cdigo en tiempo real. A continuacin, se muestra cmo configurar el debugger de VSCode para trabajar con Odoo 14.0.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Abre Visual Studio Code en la carpta de la instancia &lt;code&gt;~/Odoo/instances/odoo-dev-14.0/&lt;/code&gt; y haz clic en la pestaa "Debug" en la barra lateral izquierda.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Haz clic en el botn "cree un archivo &lt;code&gt;launch.json&lt;/code&gt;" en la parte inferior de la pestaa "Debug".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copia y pega el siguiente cdigo en el archivo "launch.json" que se ha creado:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "odoo-dev-14.0",
            "type": "python",
            "request": "launch",
            "program": "~/Odoo/src/14.0/odoo-bin",
            "console": "integratedTerminal",
            "args": [
                "-c","~/Odoo/instances/odoo-dev-14.0/odoo.conf",
                "--limit-time-real", "99999",
                "-d", "odoo-dev-14.0"
            ]
        },
        {
            "name": "odoo-dev-14.0-install-addons",
            "type": "python",
            "request": "launch",
            "program": "~/Odoo/src/14.0/odoo-bin",
            "console": "integratedTerminal",
            "args": [
                "-c","~/Odoo/instances/odoo-dev-14.0/odoo.conf",
                "--limit-time-real", "99999",
                "-d", "odoo-dev-14.0",
                "-i","",
                "--stop-after-init"
            ]
        },
        {
            "name": "odoo-dev-14.0-update-addons",
            "type": "python",
            "request": "launch",
            "program": "~/Odoo/src/14.0/odoo-bin",
            "console": "integratedTerminal",
            "args": [
                "-c","~/Odoo/instances/odoo-dev-14.0/odoo.conf",
                "--limit-time-real", "99999",
                "-d", "odoo-dev-14.0",
                "-u","",
                "--stop-after-init"
            ]
        },
        {
            "name": "odoo-dev-14.0-repl",
            "type": "python",
            "request": "launch",
            "program": "~/Odoo/src/14.0/odoo-bin",
            "console": "integratedTerminal",
            "args": [
                "shell",
                "-c","~/Odoo/instances/odoo-dev-14.0/odoo.conf",
                "--limit-time-real", "99999",
                "--xmlrpc-port","8888",
                "--longpolling-port","8899",
                "-d", "odoo-dev-14.0",
                "--shell-interface", "ipython"
            ]
        }
    ]
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Ahora, puedes elegir una de las siguientes opciones de configuracin del debugger:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;odoo-dev-14.0: esta opcin inicia Odoo en modo de desarrollo con la base de datos "odoo-dev-14.0".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;odoo-dev-14.0-install-addons: esta opcin instala los mdulos de Odoo que agregemos al parametro "-i", en la base de datos "odoo-dev-14.0".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;odoo-dev-14.0-update-addons: esta opcin actualiza los mdulos de Odoo que agregemos al parametro "-u", en la base de datos "odoo-dev-14.0".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;odoo-dev-14.0-repl: esta opcion inicia Odoo en modo de consola interactiva (REPL) donde puedes ejecutar comandos del ORM&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;El parametro "--limit-time-real" establece el tiempo mximo permitido para la ejecucin de una solicitud de servidor en Odoo, con un valor de "99999" establece este lmite en un tiempo muy alto, prcticamente ilimitado. Esto es til durante el desarrollo, ya que nos permite depurar el cdigo sin interrupciones debido a la expiracin del tiempo lmite de Odoo&lt;/p&gt;

&lt;p&gt;Con la configuracin adecuada, podemos utilizar el debugger de VSCode para solucionar problemas en el cdigo de Odoo y mejorar la calidad del software. Adems, al tener un debugger integrado en su entorno de desarrollo, pueden ahorrar tiempo y mejorar la eficiencia de su trabajo.&lt;/p&gt;

&lt;p&gt;Espero que este tutorial haya sido til para aquellos que buscan configurar el debugger de VSCode para trabajar con Odoo 14.0. Si tienes alguna pregunta o comentario, no dudes en escribirme.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Creando tu primer HomeLab Server: Consideraciones clave para empezar</title>
      <dc:creator>Rafnix Guzmán</dc:creator>
      <pubDate>Fri, 10 Mar 2023 00:15:50 +0000</pubDate>
      <link>https://forem.com/rafnixg/creando-tu-primer-homelab-server-consideraciones-clave-para-empezar-155p</link>
      <guid>https://forem.com/rafnixg/creando-tu-primer-homelab-server-consideraciones-clave-para-empezar-155p</guid>
      <description>&lt;p&gt;Ests interesado en crear tu propio homelab server pero no sabes por dnde empezar? Aqu te presentamos algunas consideraciones clave que debes tener en cuenta para planificar y armar tu homelab.&lt;/p&gt;

&lt;h2&gt;
  
  
  Por qu tener un homelab es importante
&lt;/h2&gt;

&lt;p&gt;Un homelab es una infraestructura de tecnologa personal que te permite experimentar y aprender de una manera prctica cmo funcionan diferentes sistemas operativos, aplicaciones y servicios. Adems, tener tu propio homelab te da la libertad de tener el control total sobre tus aplicaciones, datos y recursos. Tambin te permite realizar pruebas en un ambiente controlado y seguro sin afectar los sistemas de produccin en una empresa.&lt;/p&gt;

&lt;h2&gt;
  
  
  No es necesario hardware empresarial
&lt;/h2&gt;

&lt;p&gt;A menudo, la gente piensa que es necesario tener hardware empresarial costoso para crear un homelab server. Sin embargo, esto no es cierto. Para proyectos personales o pequeas empresas, no es necesario tener un servidor costoso y de alta gama. Un equipo de escritorio potente puede ser suficiente para comenzar, siempre y cuando se planifique cuidadosamente la configuracin de hardware.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cmo planificar el armado de tu homelab server
&lt;/h2&gt;

&lt;p&gt;Antes de planificar la configuracin de hardware para tu homelab server, debes tener claro el objetivo de tu homelab y los proyectos que deseas ejecutar. Esto te permitir determinar los requerimientos de hardware que vas a necesitar. A continuacin, algunos factores clave que debes considerar:&lt;/p&gt;

&lt;h3&gt;
  
  
  Procesador
&lt;/h3&gt;

&lt;p&gt;El procesador es uno de los componentes ms importantes de cualquier servidor. Se recomienda tener al menos un procesador de multiples nucleos, minimo 2. Para un mejor rendimiento, se recomienda optar por procesadores de la serie i7 de Intel o la serie Ryzen 7 de AMD estos proporcionar suficiente potencia de procesamiento para ejecutar varias aplicaciones y servicios simultneamente.&lt;/p&gt;

&lt;h3&gt;
  
  
  RAM
&lt;/h3&gt;

&lt;p&gt;La memoria RAM es otro componente crtico en la construccin de un homelab server, especialmente si planeas ejecutar varias mquinas virtuales al mismo tiempo. Se recomienda tener al menos 16 GB o 32 GB de RAM para asegurar un rendimiento ptimo. Si tienes un presupuesto ajustado, puedes empezar con 8 GB de RAM y luego actualizar a medida que sea necesario.&lt;/p&gt;

&lt;h3&gt;
  
  
  Almacenamiento
&lt;/h3&gt;

&lt;p&gt;En cuanto al almacenamiento, hay varias opciones disponibles. Aunque los SSD son ms rpidos y fiables que los discos duros tradicionales (HDD), tambin son ms caros. Para proyectos personales o pequeas empresas, un disco duro HDD de alta capacidad puede ser una opcin ms econmica. Un disco duro de 1 TB o ms es suficiente para la mayora de las necesidades de almacenamiento.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conexin a red
&lt;/h3&gt;

&lt;p&gt;La conexin a red es crucial para el rendimiento del servidor. Asegrate de tener una tarjeta de red Gigabit Ethernet para un rendimiento ptimo. Si planeas configurar tu servidor como un router o firewall, considera utilizar una tarjeta de red con mltiples puertos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Equipos pre-armados de bajo consumo
&lt;/h2&gt;

&lt;p&gt;Existen diversas opciones de equipos pre-armados de poco consumo que pueden ser utilizados como servidores para proyectos personales o pequeas empresas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Raspberry Pi: La Raspberry Pi es una pequea computadora de bajo costo que consume muy poca energa. Es perfecta para ejecutar aplicaciones de servidor livianas.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Odroid: Odroid es otra pequea computadora similar a la Raspberry Pi. Tambin consume muy poca energa y es capaz de ejecutar aplicaciones de servidor.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Crear tu propio servidor homelab puede ser una experiencia emocionante y valiosa. Te permite aprender y experimentar en un entorno controlado, lo que te ayuda a desarrollar habilidades tiles en el mundo de la tecnologa e informtica.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Actualiza tu perfil de GitHub con README y GitHub Actions - Parte 3</title>
      <dc:creator>Rafnix Guzmán</dc:creator>
      <pubDate>Sun, 09 Aug 2020 00:59:16 +0000</pubDate>
      <link>https://forem.com/rafnixg/actualiza-tu-perfil-de-github-con-readme-y-github-actions-parte-3-4iea</link>
      <guid>https://forem.com/rafnixg/actualiza-tu-perfil-de-github-con-readme-y-github-actions-parte-3-4iea</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--T0-5yyms--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.unsplash.com/photo-1590595906931-81f04f0ccebb%3Fixlib%3Drb-1.2.1%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D2000%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--T0-5yyms--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.unsplash.com/photo-1590595906931-81f04f0ccebb%3Fixlib%3Drb-1.2.1%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D2000%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ" alt="Actualiza tu perfil de GitHub con README y GitHub Actions - Parte 3" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Si aun no has leído las otras dos partes te invito a que las revises:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/rafnixg/actualiza-tu-perfil-de-github-con-readme-y-github-actions-parte-1-308"&gt;Crear nuestro README en GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/rafnixg/actualiza-tu-perfil-de-github-con-readme-y-github-actions-parte-2-3k43"&gt;Escribir un script en python para crear nuestro README dinámico&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;En esta tercera entrega vamos a automatizar mediante GitHub Actions la generación de nuestro archivo README.md ejecutando de forma programada nuestro script de Python que creamos en la publicación anterior.&lt;/p&gt;

&lt;p&gt;GitHub Actions es una funcionalidad de GitHub que nos permite automatizar flujos de desarrollo directamente en nuestro repositorio de código, lo que nos da la ventaja de poder crear nuestros propios flujos y trabajos a ejecutar.&lt;/p&gt;

&lt;p&gt;Al estar integrado con nuestro repositorio de código, tenemos la ventaja de poder crear nuestros flujos de trabajo de CI/CD, en esta publicación no profundizaremos en este tipo de implementaciones, pero si haremos uso de GitGub Actions para ejecutar nuestro propio flujo que consiste en ejecutar un script de Python y realizar un &lt;strong&gt;PUSH&lt;/strong&gt; a nuestro repositorio de datos cuando exista un cambio en el archivo README.md.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creando nuestro primer GitHub Actions
&lt;/h2&gt;

&lt;p&gt;Para poder activar esta funcionalidad solo debemos crear un directorio en la raíz de nuestro proyecto llamado &lt;em&gt;.github&lt;/em&gt; dentro de este directorio creamos otro directorio llamado _ &lt;strong&gt;workflows&lt;/strong&gt;._&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir .github
$ cd .github
$ mkdir workflows

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ya con esto podemos comenzara crear nuestro &lt;strong&gt;workflow&lt;/strong&gt; usando un archivo YAML, para este caso mi archivo se va a llamar &lt;em&gt;&lt;a href="https://github.com/rafnixg/rafnixg/blob/master/.github/workflows/python-app.yml"&gt;python-app.yml&lt;/a&gt;&lt;/em&gt; pero puede tener el nombre que ustedes quieran.&lt;/p&gt;

&lt;p&gt;Si hacemos un push al repositorio y revisamos el tab de "Actions" veremos nuestro &lt;strong&gt;workflow&lt;/strong&gt; y estará en un estado de falla ya que aun no hemos agregado ningún trabajo ni los pasos a seguir.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Raíz del proyecto
$ git add .github/workflows/python-app.yml
$ git commit -m "[ADD] new workflow for GitHub Actions"
$ git push origin master

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8VjtoGQm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://rafnixg.dev/content/images/2020/08/image.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8VjtoGQm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://rafnixg.dev/content/images/2020/08/image.png" alt="Actualiza tu perfil de GitHub con README y GitHub Actions - Parte 3" width="800" height="278"&gt;&lt;/a&gt;GitHub Actions tab&lt;/p&gt;

&lt;p&gt;Para editar nuestro archivo lo haremos directamente desde GitHub para aprovechar el auto completado y otras herramientas que tiene GitHub para la creación de Actions, al abrir nuestro archivo escribimos lo siguiente:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kb-kXLlL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://rafnixg.dev/content/images/2020/08/image-3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kb-kXLlL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://rafnixg.dev/content/images/2020/08/image-3.png" alt="Actualiza tu perfil de GitHub con README y GitHub Actions - Parte 3" width="800" height="288"&gt;&lt;/a&gt;Editor de GitHub&lt;/p&gt;

&lt;p&gt;Acá podemos ver del lado derecho un panel que nos puede ayudar a buscar Actions creadas por la comunidad y también nos muestra la documentación de GitHub Actions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: Python workflow # Nombre del workflow
on: # llave que indica que se realizara una acción sobre algun evento 
  schedule: # El evento que ejecutara la acción
    - cron: "0 */6 * * *" # configuración del intervalo de ejecución

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pudimos haber hecho que esta acción se ejecutara con otros eventos como un push o un pull request, pero de esto hablare en una siguiente publicación, para profundizar les recomiendo estas dos lecturas:&lt;/p&gt;

&lt;p&gt;[&lt;/p&gt;

&lt;p&gt;Workflow syntax for GitHub Actions - GitHub Docs&lt;/p&gt;

&lt;p&gt;A workflow is a configurable automated process made up of one or more jobs. You must create a YAML file to define your workflow configuration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I5qgggl6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://docs.github.com/assets/images/site/favicon.ico" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I5qgggl6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://docs.github.com/assets/images/site/favicon.ico" alt="Actualiza tu perfil de GitHub con README y GitHub Actions - Parte 3" width="32" height="32"&gt;&lt;/a&gt;GitHub Docs&lt;/p&gt;

&lt;p&gt;](&lt;a href="https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#onschedule"&gt;https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#onschedule&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;[&lt;/p&gt;

&lt;p&gt;Events that trigger workflows - GitHub Docs&lt;/p&gt;

&lt;p&gt;You can configure your workflows to run when specific activity on GitHub happens, at a scheduled time, or when an event outside of GitHub occurs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I5qgggl6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://docs.github.com/assets/images/site/favicon.ico" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I5qgggl6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://docs.github.com/assets/images/site/favicon.ico" alt="Actualiza tu perfil de GitHub con README y GitHub Actions - Parte 3" width="32" height="32"&gt;&lt;/a&gt;GitHub Docs&lt;/p&gt;

&lt;p&gt;](&lt;a href="https://docs.github.com/en/actions/reference/events-that-trigger-workflows#scheduled-events"&gt;https://docs.github.com/en/actions/reference/events-that-trigger-workflows#scheduled-events&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Hasta este momento solo hemos indicado, el nombre de nuestro &lt;strong&gt;workflow&lt;/strong&gt; y que sera una acción que se ejecutara de forma programada cada 6 horas, pero aun no hemos definido el &lt;strong&gt;job&lt;/strong&gt; y la secuencia de pasos que se van a ejecutar, para esto debemos editar nuestro archivo y nos debe quedar de la siguiente manera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: Python workflow # Nombre del workflow
on: # llave que indica que se realizara una acción sobre algun evento 
  schedule: # El evento que ejecutara la acción
    - cron: "0 */6 * * *" # configuración del intervalo de ejecución

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2
      - name: Set up Python 3.8
        uses: actions/setup-python@v2
        with:
          python-version: 3.8
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt
      - name: Run script
        run: |
          python app.py
          git config user.name rafnixg
          git config user.email rafnixg@gmail.com
          git add README.md
          git diff --quiet &amp;amp;&amp;amp; git diff --staged --quiet || git commit -m "[BOT] Update README with latest info"
          git push origin master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
https://github.com/rafnixg/rafnixg/blob/master/.github/workflows/python-app.yml





&lt;p&gt;Al guardar los cambios en nuestro archivo tenemos ya definido un &lt;strong&gt;job&lt;/strong&gt; de nombre &lt;strong&gt;&lt;em&gt;build&lt;/em&gt;&lt;/strong&gt; con el key &lt;strong&gt;&lt;em&gt;run-on&lt;/em&gt;&lt;/strong&gt; donde indicamos que el sistema operativo que va a correr es un ubuntu-latest, si han trabajado con este tipo de archivos YAML en docker, se les hará fácil comprender este archivo, sino no hay problema acá explico que hace nuestro archivo.&lt;/p&gt;

&lt;p&gt;Después de la definición del jobs tenemos que definir los &lt;strong&gt;steps,&lt;/strong&gt; que son esos pasos que va a seguir nuestro job, aqui usamos dos actions que están disponibles en el marketplace, esta creo es una de las cosas mas interesantes de GitHub Actions, ya que podemos crear actions y compartirlas con la comunidad para que otras personas las puedan implementar, yo estaré usando en esta oportunidad "action/checkout@v2" que nos ayuda a configurar git en nuestro &lt;strong&gt;workspace&lt;/strong&gt; y poder tener acceso desde el &lt;strong&gt;Workflow&lt;/strong&gt; que estamos definiendo hacia nuestro repositorio y "action/setup-python@v2" que nos ayuda a configurar python en el workspace para poder correr nuestro script.&lt;/p&gt;

&lt;p&gt;Lo siguiente sera actualizar pip e instalar las dependencias de nuestro script y ejecutar nuestro script, ya en este punto tenemos nuestro archivo READM.md actualizado en nuestro &lt;strong&gt;workspace&lt;/strong&gt; , solo nos resta crear un commit con este cambio y hacer push a nuestro repositorio.&lt;/p&gt;

&lt;p&gt;Con este push ya tenemos nuestro README.md actualizado en nuestro repositorio, ahora cada 6 horas va a correr este Workflow en donde definimos un jobs que se encarga de correr nuestro script y hacer un commit cuando exista un cambio en el archivo README.md&lt;/p&gt;

&lt;p&gt;En próximas publicaciones hablara un poco mas sobre las GitHubs Actions y de como crear nuestras propias actions y publicarlas para que puedan ser reutilizadas, si te gusto el contenido espero tu comentario.&lt;/p&gt;

&lt;p&gt;Sígueme en twitter &lt;a href="https://twitter.com/rafnixg"&gt;@rafnixg&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Referencias
&lt;/h2&gt;

&lt;p&gt;[&lt;/p&gt;

&lt;p&gt;Features • GitHub Actions&lt;/p&gt;

&lt;p&gt;Easily build, package, release, update, and deploy your project in any language—on GitHub or any external system—without having to run code yourself.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GiYjWU4I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.githubassets.com/favicons/favicon.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GiYjWU4I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.githubassets.com/favicons/favicon.svg" alt="Actualiza tu perfil de GitHub con README y GitHub Actions - Parte 3" width="32" height="32"&gt;&lt;/a&gt;GitHub&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yATjEonN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.githubassets.com/images/modules/site/social-cards/actions.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yATjEonN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.githubassets.com/images/modules/site/social-cards/actions.png" alt="Actualiza tu perfil de GitHub con README y GitHub Actions - Parte 3" width="800" height="419"&gt;&lt;/a&gt;&lt;br&gt;
](&lt;a href="https://github.com/features/actions"&gt;https://github.com/features/actions&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;[&lt;/p&gt;

&lt;p&gt;GitHub Actions Documentation - GitHub Docs&lt;/p&gt;

&lt;p&gt;Automate, customize, and execute your software development workflows right in your repository with GitHub Actions. You can discover, create, and share actions to perform any job you’d like, including CI/CD, and combine actions in a completely customized workflow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I5qgggl6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://docs.github.com/assets/images/site/favicon.ico" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I5qgggl6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://docs.github.com/assets/images/site/favicon.ico" alt="Actualiza tu perfil de GitHub con README y GitHub Actions - Parte 3" width="32" height="32"&gt;&lt;/a&gt;GitHub Docs&lt;/p&gt;

&lt;p&gt;](&lt;a href="https://docs.github.com/en/actions"&gt;https://docs.github.com/en/actions&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;[&lt;/p&gt;

&lt;p&gt;Using Python with GitHub Actions - GitHub Docs&lt;/p&gt;

&lt;p&gt;You can create a continuous integration (CI) workflow to build and test your Python project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I5qgggl6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://docs.github.com/assets/images/site/favicon.ico" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I5qgggl6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://docs.github.com/assets/images/site/favicon.ico" alt="Actualiza tu perfil de GitHub con README y GitHub Actions - Parte 3" width="32" height="32"&gt;&lt;/a&gt;GitHub Docs&lt;/p&gt;

&lt;p&gt;](&lt;a href="https://docs.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#requirements-file"&gt;https://docs.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#requirements-file&lt;/a&gt;)&lt;/p&gt;

</description>
      <category>github</category>
      <category>githubactions</category>
      <category>python</category>
    </item>
    <item>
      <title>Actualiza tu perfil de GitHub con README y GitHub Actions - Parte 2</title>
      <dc:creator>Rafnix Guzmán</dc:creator>
      <pubDate>Wed, 29 Jul 2020 19:24:33 +0000</pubDate>
      <link>https://forem.com/rafnixg/actualiza-tu-perfil-de-github-con-readme-y-github-actions-parte-2-3k43</link>
      <guid>https://forem.com/rafnixg/actualiza-tu-perfil-de-github-con-readme-y-github-actions-parte-2-3k43</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--T0-5yyms--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.unsplash.com/photo-1590595906931-81f04f0ccebb%3Fixlib%3Drb-1.2.1%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D2000%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--T0-5yyms--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.unsplash.com/photo-1590595906931-81f04f0ccebb%3Fixlib%3Drb-1.2.1%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D2000%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ" alt="Actualiza tu perfil de GitHub con README y GitHub Actions - Parte 2" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La idea principal es poder generar un archivo README.md con una lista de los últimos 5 post de este Blog, pero en esencia este código con muy poco o hasta nula modificacion en algunos casos puede servir para otros servicios como &lt;a href="https://dev.to/"&gt;dev.to&lt;/a&gt;, &lt;a href="https://medium.com/"&gt;Medium&lt;/a&gt; o WordPress.&lt;/p&gt;

&lt;p&gt;Ya teniendo nuestro archivo README.md creado en el post &lt;a href="https://dev.to/rafnixg/actualiza-tu-perfil-de-github-con-readme-y-github-actions-parte-1-oh-temp-slug-6537241"&gt;Actualiza tu perfil de GitHub con README y Github Actions - Parte 1&lt;/a&gt; , nos ubicamos en la carpeta de nuestro proyecto y empezaremos creamos una copia de nuestro archivo pero con extensión &lt;strong&gt;.template&lt;/strong&gt; , quedándonos algo como esto: README.md.template, este sera el archivo que usaremos como base para generar nuestro README.md&lt;/p&gt;

&lt;p&gt;Luego editamos la sección de "Latest post (Spanish)" sustituyendo nuestros post estáticos con este código en Jinja2, que nos ayuda a iterar sobre una lista de post.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jinja"&gt;&lt;code&gt;&lt;span class="c"&gt;## Latest Posts (Spanish)&lt;/span&gt;

&lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nv"&gt;post&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;latest_post&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;
- [&lt;span class="cp"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;post.title&lt;/span&gt;&lt;span class="cp"&gt;}}&lt;/span&gt;](&lt;span class="cp"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;post.link&lt;/span&gt;&lt;span class="cp"&gt;}}&lt;/span&gt;)
&lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;endfor&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En esta plantilla indico que le voy a pasar &lt;em&gt;latest_post&lt;/em&gt; y que debo recorrer sus post e imprimirlos dentro de un link en markdown.&lt;/p&gt;

&lt;p&gt;Ahora necesitamos el endpoint a el que consultaremos para obtener nuestras lista de posts, para esto haré uso de las &lt;a href="https://es.wikipedia.org/wiki/RSS"&gt;RSS&lt;/a&gt; que tiene Ghost y con el siguiente servicio lo convertiré de XML a JSON&lt;/p&gt;

&lt;p&gt;&lt;a href="https://rss2json.com"&gt;https://rss2json.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Acá pudimos haberlo hecho de muchas maneras distintas, se pudo haber usado la API ded Ghost y hacer la peticion directa o se pudo haber hecho el cambio de XML a JSON usando Python, mi idea era hacerlo lo mas simple posible, si tienes una idea mejor la espero en los comentarios o un Pull Request, ya con esto aclarado podemos continuar xD.&lt;/p&gt;

&lt;p&gt;Teniendo nuestro endpoint listo procederemos a crear nuestro script en Python, por lo que primero debemos preparar, es nuestro entorno virtual que nos ayude a aislar nuestras dependencias para este proyecto, podemos hacer uso de Pipenv del cual tengo un tutorial por acá (&lt;a href="https://rafnixg.dev/entornos-virtuales-en-python-usando-pipenv/"&gt;Entornos virtuales en python usando Pipenv&lt;/a&gt;), pero en este caso lo haremos de la siguiente manera ya que es la mas común.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv &lt;span class="nb"&gt;env&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;source env&lt;/span&gt;/bin/activate
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;app.py

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lo que creara una carpeta &lt;em&gt;env&lt;/em&gt; en el &lt;em&gt;root&lt;/em&gt; de nuestro proyecto, activara nuestro entorno virtual y crea nuestro archivo &lt;strong&gt;app.py&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Para poder usar nuestras librerías debemos instalarlas, en este caso haré uso de PIP que es nuestro gestor de paquetes en python y las librería a instalar son:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;urllib3&lt;/strong&gt; : Para realizar las consultas HTTP&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;json&lt;/strong&gt; : para parsear la información recibida en la respuesta HTTP&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;jinja2&lt;/strong&gt; : para renderizar nuestro archivo README con la potencia de esta librería de plantillas
&amp;lt;!--kg-card-begin: markdown--&amp;gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;urllib3 json jinja2
&lt;span class="nv"&gt;$ &lt;/span&gt;pip freeze &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; requirements.txt

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ya tenemos nuestras dependencias instaladas nuestras dependencias, así que procederemos a crear nuestro script, quedándonos algo como esto:&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="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;urllib3&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;jinja2&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FileSystemLoader&lt;/span&gt;

&lt;span class="c1"&gt;# Cantidad maxima de posts a mostrar
&lt;/span&gt;&lt;span class="n"&gt;MAX_POSTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;

&lt;span class="c1"&gt;# Setup
&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;FileSystemLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;.&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;http&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;urllib3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;PoolManager&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;get_latest_posts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_posts&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="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;GET&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;https://api.rss2json.com/v1/api.json?rss_url=https%3A%2F%2Frafnixg.dev%2Frss%2F&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&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="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;items&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;max_posts&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;render_readme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;README.template&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&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;README.md&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="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;f&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="n"&gt;render&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;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;

    &lt;span class="n"&gt;latest_posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_latest_posts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MAX_POSTS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&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;latest_post&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;latest_posts&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;render_readme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; __main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Las primeras 3 lineas de nuestro código son básicamente la importación de las librerías y utilidades que vamos a usar, luego definimos una constante para el numero máximo de post que vamos a escribir en nuestro archivo README.&lt;/p&gt;

&lt;p&gt;El setup es donde indicamos a jinja en que fichero debe buscar los templates y creamos una instancia que llamaremos http para nuestras consultas HTTP&lt;/p&gt;

&lt;p&gt;Como ven en la función &lt;em&gt;get_latest_posts()&lt;/em&gt; es un simple petición GET a el enpoint, como parámetro le podemos limitar el numero de items que retornara&lt;/p&gt;

&lt;p&gt;En la función &lt;em&gt;render_readme()&lt;/em&gt; indicamos el archivo a usar como template, cargamos la data obtenida de los últimos post y lo renderizamos en nuestro template para luego escribirlo en el archivo final README.md&lt;/p&gt;

&lt;p&gt;Con esto ya podemos correr nuestro script y ver como nos genera de forma dinámica nuestro archivo README.md&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ptyhon3 app.py

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nuestro script ya genere de forma dinámica nuestro archivo README.md, con este mismo enfoque se pueden agregar muchísimas mas funciones consultando a diferentes servicios y editar desde el template como se va a renderizar esta información.&lt;/p&gt;

&lt;p&gt;En la tercera y ultima parte veremos como automatizar la ejecución de nuestro script y actualizar README.md en nuestro repositorio de GitHub, gracias a las GitHub Actions.&lt;/p&gt;

&lt;p&gt;Gracias por leerme y los espero por twitter &lt;a href="https://twitter.com/rafnixg"&gt;@rafnixg&lt;/a&gt; y su estrella en GitHub &lt;a href="https://github.com/rafnixg/rafnixg"&gt;rafnixg&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>git</category>
    </item>
    <item>
      <title>Actualiza tu perfil de GitHub con README y GitHub Actions - Parte 1</title>
      <dc:creator>Rafnix Guzmán</dc:creator>
      <pubDate>Tue, 28 Jul 2020 21:35:14 +0000</pubDate>
      <link>https://forem.com/rafnixg/actualiza-tu-perfil-de-github-con-readme-y-github-actions-parte-1-308</link>
      <guid>https://forem.com/rafnixg/actualiza-tu-perfil-de-github-con-readme-y-github-actions-parte-1-308</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--T0-5yyms--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.unsplash.com/photo-1590595906931-81f04f0ccebb%3Fixlib%3Drb-1.2.1%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D2000%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--T0-5yyms--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.unsplash.com/photo-1590595906931-81f04f0ccebb%3Fixlib%3Drb-1.2.1%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D2000%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ" alt="Actualiza tu perfil de GitHub con README y GitHub Actions - Parte 1" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esta sera una serie de 3 Post:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Crear nuestro README en GitHub&lt;/li&gt;
&lt;li&gt;Escribir un script en python para crear nuestro README dinámico&lt;/li&gt;
&lt;li&gt;Implementar GitHub Actions para automatizar nuestro README&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Acá te dejo una mirada de como quedo &lt;a href="https://github.com/rafnixg"&gt;mi perfil&lt;/a&gt;, espero me dejes una estrella :D&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--R3xWCAzO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/rafnixg/rafnixg/master/readme.md.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--R3xWCAzO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/rafnixg/rafnixg/master/readme.md.png" alt="Actualiza tu perfil de GitHub con README y GitHub Actions - Parte 1" width="800" height="1061"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Preparando nuestro repositorio
&lt;/h2&gt;

&lt;p&gt;Para iniciar, debemos crear un repositorio en GitHub con nuestro nombre de usuario, en mi caso "rafnixg", tiene que ser publico y estar inicializado con un archivo README.&lt;/p&gt;

&lt;p&gt;Ingresando a &lt;a href="https://github.com/new"&gt;https://github.com/new&lt;/a&gt; podemos crear nuestro repositorio&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UwbfoJPt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://rafnixg.dev/content/images/2020/07/Screenshot_2020-07-26-Build-software-better--together.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UwbfoJPt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://rafnixg.dev/content/images/2020/07/Screenshot_2020-07-26-Build-software-better--together.png" alt="Actualiza tu perfil de GitHub con README y GitHub Actions - Parte 1" width="800" height="883"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En mi caso ya me indica que tengo este repositorio creado, pero ademas se ve un mensaje que nos indica que activamos esta funcionalidad "secreta"&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iKKrWi9X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://rafnixg.dev/content/images/2020/07/Screenshot_2020-07-26-Build-software-better--together-1-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iKKrWi9X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://rafnixg.dev/content/images/2020/07/Screenshot_2020-07-26-Build-software-better--together-1-.png" alt="Actualiza tu perfil de GitHub con README y GitHub Actions - Parte 1" width="704" height="105"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Creando nuestro README
&lt;/h2&gt;

&lt;p&gt;En esta parte del proceso tendremos que empezar clonando nuestro repositorio y editar nuestro archivo README con la información que quisiéramos mostrar, para esto usaremos el siguiente comando de Git:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git clone https://github.com/tu_username/tu_username.git

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Luego de clonar nuestro repositorio procedemos a crear nuestro archivo README usando Markdown, yo en esta parte del proceso use varias referencias para tomar ideas y armar algo que me gustara, les dejo por acá los enlaces para que las visiten y tomen ideas.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/kautukkundan/Awesome-Profile-README-templates"&gt;https://github.com/kautukkundan/Awesome-Profile-README-templates&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/abhisheknaiidu/awesome-github-profile-readme"&gt;https://github.com/abhisheknaiidu/awesome-github-profile-readme&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ya con una idea de lo que queremos hacer, escribimos nuestro archivo y subimos estos cambios a GitHub&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git add README.md
$ git commit -m "[IMP] Mejora de nuestro README"
$ git push -u origin master

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Con esto ya tendremos nuestro archivo README desplegado en nuestro perfil de GitHub.&lt;/p&gt;

&lt;p&gt;En la segunda entrega veremos como poder obtener datos de una API como la Ghost o Dev.to y actualizar nuestro archivo README usando Python.&lt;/p&gt;

&lt;p&gt;Gracias por leerme! los espero por mi twitter &lt;a href="https://rafnixg@gmail.com"&gt;@rafnixg&lt;/a&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>python</category>
      <category>markdown</category>
    </item>
    <item>
      <title>Crea tu blog con python usando GitHub Pages y Pelican</title>
      <dc:creator>Rafnix Guzmán</dc:creator>
      <pubDate>Sat, 18 May 2019 15:30:00 +0000</pubDate>
      <link>https://forem.com/rafnixg/crea-tu-blog-con-python-usando-github-pages-y-pelican-pbk</link>
      <guid>https://forem.com/rafnixg/crea-tu-blog-con-python-usando-github-pages-y-pelican-pbk</guid>
      <description>&lt;p&gt;Cuando comencé a darle vuelta a la idea de empezar un blog de nuevo me vinieron muchas ideas de como hacerlo a la mente, como el de usar el famoso &lt;a href="https://wordpress.org"&gt;Wordpress&lt;/a&gt;, teniendo en cuenta que el blog lo quería hacer para hablar un poco de python y las tecnologías que iba a ir conociendo y aprendiendo decidí mejor usar Pelican ya que esta desarrollado en Python.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://blog.getpelican.com/"&gt;Pelican&lt;/a&gt; es un generador de sitios estáticos desarrollado en python que nos permite escribir los post en archivos escritos en reStructuredText, Markdown, o AsciiDoc, y estos serán luego procesados para generar un sitio web estático como este blog, por lo que no necesitaremos una base de datos ni un servidor web que soporte un lenguaje de Backend como lo es GitHub Pages.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué es GitHub Pages?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://pages.github.com/"&gt;GitHub Pages&lt;/a&gt; es un hosting de sitios estáticos y como su página web lo indica, está diseñado para hostear directamente en un repositorio de GitHub la página web de nuestros proyecto, paginas personales o de organizaciones, además de ser un servicio gratuito.&lt;/p&gt;

&lt;p&gt;Gracias a estas características, podemos fácilmente crear nuestros sitios estáticos y subirlos a un repositorio de GitHub que debe tener la siguiente estructura &lt;code&gt;username.github.io&lt;/code&gt; mas adelante indicaré como crear y configurar el repositorio para que pueda servir nuestro sitio web.&lt;/p&gt;

&lt;p&gt;GitHub recomienda el uso de &lt;a href="https://jekyllrb.com/"&gt;Jekyll&lt;/a&gt; para generar nuestros sitios estáticos, pero este esta hecho en Ruby, lo que no es un problema si usas Ruby pero yo al ser un #PythonLover decidí usar Pelican que esta desarrollado en Python.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creando nuestro repositorio en GitHub
&lt;/h2&gt;

&lt;p&gt;Esta parte es la más sencilla de post, ya que solo debemos entrar a nuestra cuenta de GitHub y crear un nuevo repositorio público, que tenga el siguiente nombre.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;tu_username.github.io&lt;/code&gt;, en mi caso el repositorio donde se aloja este blog se llama &lt;a href="https://rafnixg.github.io"&gt;rafnixg.github.io&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Solo con esto ya tendremos nuestro Github Pages listo para comenzar a subir nuestro contenido estático.&lt;/p&gt;

&lt;h2&gt;
  
  
  Instalando y configurando Pelican
&lt;/h2&gt;

&lt;p&gt;Instalar y tener Pelican funcionando es super sencillo. Pero si les quiero recomendar que toda la instalación se haga en un entorno virtual usando Pipenv, para mantener separado esta instalación de los demás paquetes de Python que tengan instalados en sus sistema, si no saben como usar Pipenv acá les dejo un post que tengo sobre este tema, &lt;a href="https://dev.to/rafnixg/entornos-virtuales-en-python-usando-pipenv-5e0d-temp-slug-8710604"&gt;Entornos virtuales en Python usando Pipenv&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Antes de iniciar con la instalación de pelican, debemos clonar nuestro repositorio donde está hosteada nuestro blog, para esto solo debemos ubicarnos donde queramos tener nuestro proyecto, en este caso yo lo haré en la raíz de mi sistema.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cd ~ $ git clone https://github.com/tu_username/tu_username.github.io.git 
$ cd tu_username.github.io
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Luego de esto, procedemos a instalar nuestro Pelican, lo primero que debemos hacer es crear un nuevo branch llamado &lt;code&gt;source&lt;/code&gt; donde irá todo nuestro código fuente y librerías, ya que para GitHub todo lo que esté en la rama &lt;code&gt;master&lt;/code&gt; es lo que será servido, para nuestro interés solo debemos subir a &lt;code&gt;master&lt;/code&gt; lo que pelican genera en su carpeta output, pero más adelante nos preocuparemos de esto.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git checkout -b source
$ pipenv shell
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Con esto ya tendremos nuestro entorno virtual para nuestra instalación de pelican, ahora procedemos a instalar &lt;code&gt;pelican&lt;/code&gt; que es nuestro generador de sitios estáticos, &lt;code&gt;markdown&lt;/code&gt; que nos ayudará para escribir nuestros post usando este lenguaje y &lt;code&gt;ghp-import&lt;/code&gt; que nos ayuda a publicar nuestro sitio a GitHub.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pipenv install pelican markdown ghp-import 
Installing pelican… 
Adding pelican to Pipfile's [packages]…
✔ Installation Succeeded 
Installing markdown…
Adding markdown to Pipfile's [packages]… 
✔ Installation Succeeded 
Installing ghp-import… 
Adding ghp-import to Pipfile's [packages]… 
✔ Installation Succeeded 
Pipfile.lock not found, creating… 
Locking [dev-packages] dependencies… 
Locking [packages] dependencies… 
✔ Success! 
Updated Pipfile.lock (b0c318)! 
Installing dependencies from Pipfile.lock (b0c318)… 
🐍 ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 13/13 —
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ya con esto tenemos todo listo para empezar a usar Pelican, así que creemos nuestro primer blog usándolo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pelican-quickstart 
Welcome to pelican-quickstart v4.0.1. 
This script will help you create a new Pelican-based website. 
Please answer the following questions so this script can generate the files needed by Pelican. 
Using project associated with current virtual environment.Will save to:
/home/username/blog/pelican
&amp;gt; What will be the title of this web site? prueba pelican 
&amp;gt; Who will be the author of this web site? rafnix guzman 
&amp;gt; What will be the default language of this web site? [es] es 
&amp;gt; Do you want to specify a URL prefix? e.g., https://example.com (Y/n) n 
&amp;gt; Do you want to enable article pagination? (Y/n) y 
&amp;gt; How many articles per page do you want? [10] 
&amp;gt; What is your time zone? [Europe/Paris] America/Lima 
&amp;gt; Do you want to generate a tasks.py/Makefile to automate generation and publishing? (Y/n) Y # Responder Y, esto nos ayuda mucho! 
&amp;gt; Do you want to upload your website using FTP? (y/N) n 
&amp;gt; Do you want to upload your website using SSH? (y/N) n 
&amp;gt; Do you want to upload your website using Dropbox? (y/N) n 
&amp;gt; Do you want to upload your website using S3? (y/N) n 
&amp;gt; Do you want to upload your website using Rackspace Cloud Files? (y/N) n 
&amp;gt; Do you want to upload your website using GitHub Pages? (y/N) y 
&amp;gt; Is this your personal page (username.github.io)? (y/N) y 
Done. Your new project is available at /home/username/blog/pelican
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si tienen alguna duda respecto a la zona horaria aca les dejo una lista con todas las &lt;a href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones"&gt;zonas horarias&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; Do you want to generate a tasks.py/Makefile to automate generation and publishing? (Y/n)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A esta pregunta deben responder (Y), ya que este Makefile nos ayudará a generar nuestro sitio de forma más fácil, como podemos ver ya con esto se nos ha generado nuestro proyecto de pelican con el que podemos empezar a trabajar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Escribiendo nuestro primer post
&lt;/h2&gt;

&lt;p&gt;Vamos a crear nuestro primer post, para esto nos debemos ubicar en la carpeta &lt;code&gt;content&lt;/code&gt; y con nuestro editor de texto favorito procedemos a crear un archivo llamado hola-mundo.md (si, lo se, la imaginación está a la orden del día), este archivo luego puede ser borrado es solo para pruebas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Title: Hola Mundo
Date: 2019-05-18 10:30
Modified: 2019-05-18 11:30
Category: blogTags: principal, otros
Slug: hola-mundo
Authors: Rafnix Guzmán
Summary: Mi primer post usando Pelican y GitHub Pages

Acá pueden empezar a escribir todo lo que quieran pueden agregar todas las sintaxis de *Markdown* que deseen.
## Título
### Subtítulo
Este es un ejemplo de texto que da entrada a una lista genérica de elementos:
- Elemento 1
- Elemento 2
- Elemento 3

Este es un ejemplo de texto que da entrada a una lista numerada:
1. Elemento 1
2. Elemento 2
3. Elemento 3

Al texto en Markdown puedes añadirle formato como **negrita** o *cursiva* de una manera muy sencilla.
Todo esto fue extraído de este [Post sobre markdown](https://markdown.es/sintaxis-markdown/)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Probando nuestro blog en local
&lt;/h2&gt;

&lt;p&gt;Luego de escribir y guardar su primer post, procedemos a generar un servidor de pruebas para ver nuestro resultado antes de subir nuestra web a GitHub, estando en la raíz de nuestro proyecto ejecutamos el siguiente comando.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ make devserver pelican -lr /home/username/blog/pelican/content -o /home/username/blog/pelican/output -s /home/username/blog/pelican/pelicanconf.py 

-&amp;gt; Modified: content, theme, settings. re-generating... 
Done: Processed 1 article, 0 drafts, 0 pages, 0 hidden pages and 0 draft pages in 0.15 seconds.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para entrar a nuestro servidor local de pruebas debemos ingresar a la siguiente URL &lt;a href="http://localhost:8000"&gt;http://localhost:8000&lt;/a&gt; con nuestro explorador favorito(espero no se IE, xD)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---nAN74wx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://rafnixg.github.io/images/hola-mundo-pelican.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---nAN74wx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://rafnixg.github.io/images/hola-mundo-pelican.jpg" alt="Hola mundo Pelican" width="800" height="503"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Subir nuestro blog a GitHub Pages
&lt;/h2&gt;

&lt;p&gt;Ya con esto procederemos a preparar todo para subirlo a github, este primer comando sube nuestro código fuente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git add -A &amp;amp;&amp;amp; git commit -a -m 'post hola-mundo.md' &amp;amp;&amp;amp; git push --all
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ahora subimos todo a la rama &lt;code&gt;master&lt;/code&gt;, recuerdan que les dije que no se preocuparan por esto, es debido a que este comando hace toda esta preparación de subir todo lo que se encuentra en la carpeta &lt;code&gt;output&lt;/code&gt; a nuestra rama &lt;code&gt;master&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ make github
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Acá se les preguntaran sus credenciales de github, para poder subir a su repositorio todo el sitio estático ya generado, con esto su blog estará funcionando en &lt;a href="https://su_username.github.io/"&gt;https://su_username.github.io/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para el próximo post veremos cómo configurar un &lt;code&gt;Thema&lt;/code&gt; y algunos &lt;code&gt;Plugins&lt;/code&gt; para potenciar el funcionamiento de Pelican, además de unas configuraciones extra que nos ayudaran a tener mejor SEO.&lt;/p&gt;

&lt;p&gt;Nos vemos en el próximo post, muchas gracias por leerme y cualquier duda, comentario, o lo que sea, lo pueden dejar por aca o por mi cuenta de Twitter &lt;a href="https://twitter.com/rafnixg"&gt;@rafnixg&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>pipenv</category>
      <category>python</category>
      <category>herramientas</category>
    </item>
  </channel>
</rss>
