lunes, mayo 03, 2021

Python Snippets: path, time, datetime

Este es un snippet sobre encontrar el archivo mas reciente de un directorio y calcular el tiempo que ha pasado desde su creación, esto es solo la base para una función que busco hacer para un script 


import glob
import os.path
import time
from datetime import datetime

folder_path = 'D:\\python\\doodles\\'
file_type = '*.txt'
now = datetime.now()

# get the most recent file from directory
files = glob.glob(folder_path +file_type)
latest_file = max(files, key=os.path.getctime)

# get the creation time from the most recent file
latest_creation_ctime = os.path.getctime(latest_file)
latest_creation_time = datetime.fromtimestamp(latest_creation_ctime)

# calculate the diference
duration = now - latest_creation_time
duration_in_seconds = duration.total_seconds() 

# print the number of minutes since the file was created
print(int(duration_in_seconds)/60)

miércoles, abril 21, 2021

Python Snippets - dotenv

python-dotenv es una libreria para usar variables de entorno u otra información sensible, este es solo un ejemplo sencillo:

podemos codificar en base64 cierta información como:

$ echo 'joe' | base64
am9lCg==
$ echo 'mysecret' | base64
bXlzZWNyZXQK

en un archivo llamado .env dejamos lo siguiente :

test_user = "am9lCg=="
test_secret = "bXlzZWNyZXQK"

Instalamos la librería:

pip install python-dotenv


Y podemos usarlo de esta forma:

import base64
from dotenv import load_dotenv
import os

load_dotenv()
duser = base64.b64decode(os.environ.get("test_user")).decode('utf-8')
dsecret = base64.b64decode(os.environ.get("test_secret")).decode('utf-8')

print("Decoded information")
print(duser)
print(dsecret)

lo cual entregara como output:

Decoded information
joe
mysecret


Esto no es lo mas seguro y para producción u otras situaciones es necesario buscar una alternativa segura.


 https://pypi.org/project/python-dotenv/


lunes, abril 12, 2021

Ejemplo sencillo de python con selenium con docker

 He usado Selenium (https://www.selenium.dev) para interactuar con sitios web, en particular Selenium WebDriver y lo he usado con Python, en el ejemplo de abajo tengo un script solo para sacar el titulo del ultimo post de este blog, para este caso estoy usando chrome junto con el chromedriver los cuales necesitan tener la misma versión.

web.py

from selenium import webdriver

# define webdriver options
options = webdriver.ChromeOptions()
options.add_argument('--ignore-certificate-errors')
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')

driver = webdriver.Chrome(executable_path="/usr/local/bin/chromedriver",options=options)
driver.get('https://moyoy.blogspot.com')

# get title of last post based on xpath 
last_post_xpath = '//*[@id="Blog1"]/div[1]/div[1]/div/div/div/h3/a'
last_post_title = driver.find_element_by_xpath(last_post_xpath).text
print(last_post_title)
driver.quit()


Como esto se puede ejecutar desde una maquina sin interfaz grafica buscaba crear un contenedor para poder estar haciendo pruebas y después poder desplegar una pequeña aplicación que usaría las librerías de Selenium pero me tope con varios problemas hasta que logre crear un contenedor que me pudiera ejecutar el script de arriba

Dockerfile

FROM python:3.8

# install google chrome
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
RUN sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list'
RUN apt-get -y update
RUN apt-get install -y google-chrome-stable

# install chromedriver
RUN apt-get install -yqq unzip
RUN wget -O /tmp/chromedriver.zip http://chromedriver.storage.googleapis.com/`curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE`/chromedriver_linux64.zip
RUN unzip /tmp/chromedriver.zip chromedriver -d /usr/local/bin/

# set display port to avoid crash
ENV DISPLAY=:99

# upgrade pip
RUN pip install --upgrade pip

# install selenium
RUN pip install selenium

# add basic script
ADD web.py .
CMD ["python3", "web.py"]


Con los siguientes comandos construyen el contenedor y después lo ejecutan 

$docker build -t selenium-python .

$docker run -it selenium-python


tony@x220:~/docker/selenium-python$ docker run -it selenium-python
Invocando un pipeline de gitlab a través de la API


Dure varias horas buscando la configuración de un contenedor que me funcionara por lo que dejo este ejemplo muy básico aquí en caso de que otra persona tenga el mismo problema.

Existen algunos cambios recientes en Selenium y en como se define el driver en el código de python, posiblemente haga una actualización sobre ello


Gracias a la información en este repo pude resolver algunos de los problemas con los que me encontré:

https://hub.docker.com/r/joyzoursky/python-chromedriver/


miércoles, abril 07, 2021

Invocando un pipeline de gitlab a través de la API

Este es un ejemplo muy sencillo de como ejecutar un pipeline a través del uso de su API sobrescribiendo un valor en de una variable previamente definida

En esta sección: CI / CD -> Settings -> Variables he definido una variable simple llamada GREETING con el valor Hola

mi archivo .gitlab-ci.yaml es el siguiente:

image: "tonymoyoy/ubuntu_ansible:v1"


stages:
    - build
    - test

build:
    stage: build
    script:
        - echo $GREETING
        - echo "Construyendo"
        - mkdir build
        - touch build/info2.txt
    artifacts:
        paths:
            - build/

test:
    stage: test
    script:
        - echo "Probando"
        - test -f "build/info2.txt"

En la sección: CI / CD -> Settings -> Pipeline triggers agregue un trigger llamado pew, el cual genera un Token

Con esto podemos usar curl para iniciar el pipeline, en este caso sobre el branch master y proporcionando el valor Hello a la variable GREETING


curl -X POST \
    -F token=<YOUR-TRIGGER-TOKEN> \
    -F "ref=master" \
    -F "variables[GREETING]=Hello" \
http://<YOURGITLAB>/api/v4/projects/4/trigger/pipeline


En el log del pipeline podremos ver que tomo el valor de la variable:



lunes, abril 05, 2021

NCurses Disk Usage

 Me tope con esta herramienta para análisis de espacio en disco: ncdu

Comúnmente se usa el comando du pero esta herramienta facilita mucho la búsqueda de los directorios y archivos que están consumiendo gran parte de nuestro espacio.

Ncdu is a disk usage analyzer with an ncurses interface. It is designed to find space hogs on a remote server where you don't have an entire graphical setup available, but it is a useful tool even on regular desktop systems. Ncdu aims to be fast, simple and easy to use, and should be able to run in any minimal POSIX-like environment with ncurses installed.

https://dev.yorhel.nl/ncdu





sábado, abril 03, 2021

sábado, marzo 27, 2021

Probando Ansible Playbook en un Docker Container con Gitlab

 Estoy probando ansible y quería tener un setup sencillo para que gitlab hiciera pruebas del código en un contenedor de docker a través de un pipeline, por el momento aquí dejo algo sencillo, tengo este playbook:


simple_playbook.yml

---
- hosts: all
  connection: local
  tasks:
          - name: curl instalation
            apt: pkg=curl update_cache=yes

La conexión es local para ya que no es necesario trabajar con llaves ssh al estar aplicando las pruebas al contendor cada vez.

el archivo .gitlab-ci.yml es el siguiente:

image: "tonymoyoy/ubuntu_ansible:v2"

stages:
    - build
    - test

build:
    stage: build
    script:
        - echo $HOSTNAME > hosts
        - echo "Running ansible playbook"
        - ansible-playbook -i hosts local-playbook.yml

test:
    stage: test
    script:
        - echo "Test pending"

La forma que logre que se ejecutara en el contenedor fue agregando el hostname a un archivo y luego haciendo referencia al archivo hosts como variable del comando ansible-playbook

En este caso use la variable HOSTNAME de gitlab-ci (ver https://docs.gitlab.com/ee/ci/variables/) aunque también pude simplemente usar el comando hostname y enviar el resultado a el archivo, intente hacer la llamada después del comando ansible-playbook pero no encontré una forma de hacerlo funcionar.

Espero que este material puede servir de referencia para alguien