Bot Telegram + Python + Gestión recetas/menú semanal WIP

vago_21

Hola camaradas,

Antes de empezar, aclaro que voy a seguir metiéndole cosas a la parte de recetas/menú semanal, pero prometí poner algo cuando tuviese algún avance, además, tratando ya con BBDD me gustaría que me dieseis feedback. A parte de hacer algo que me sea útil, me gustaría seguir aprendiendo Python, ni idea de si la forma de tratar los objetos o las consultas a la base de datos están correctas (lo dudo, en el lenguaje que trabajo habitualmente no pongo las queries en el código). Se me ocurre montar una API Rest con Django Rest framework que he montado un par de aplicaciones en AWS así, pero para esto igual es matar moscas a cañonazos, aunque quedaría mejor que hardcodear las consultas a la base de datos.

Es el mismo bot que da la previsión según la AEMET, pero le he añadido un nuevo comando para la gestión de recetas. De momento solo lista todas las recetas que hay en la base de datos y da una aleatoria usando botones dentro del chat de Telegram.

La finalidad es que pueda darme una receta que no haya repetido la semana actual y poder decidir si la quiero para adultos, para niños o ambos. También me gustaría que me diese un menú semanal para no andar mareando con los botoncitos.

En el repositorio están las instrucciones para montar el Postgre y para la creación de la primera tabla, así como la configuración necesaria en su fichero correspondiente del proyecto.

Dejo por aquí el repositorio de GitHub para que mandéis PR desde ya.

Y por aquí un gif del funcionamiento

Lo dicho, a tope con las críticas constructivas y si os animáis a colaborar, encantado.

7
Troyer

Que guapo, gracias.

1
HeXaN

¡Tú no mami!

3
Comodiin

Buena pinta !

1
JuAn4k4

si te hace te lo dockerizo e inicializo postgresql en docker así será más sencillo ir tirando.

estaría bien tener menus guardados con comidas/cenas ( en lugar de recetas) yo por ejemplo no ceno lo mismo que como.

1 1 respuesta
vago_21

#5 te invito a unas cañas!!!

1 respuesta
JuAn4k4

#6 jajajaj ok, lo tengo hecho para muchos lenguajes diferentes, para Python no me costará mucho, mi problema es de time management jajaj, que con la niña y toda la historia voy de culo

1 respuesta
vago_21

#7 te entiendo, yo tengo una de un año, aquí sin prisas, cuando se pueda

1 1 respuesta
JuAn4k4

#8 Te lo he hecho al final, no me ha costado mucho aunque he tenido que cambiar la config y meterla en environment vars, no entiendo mucho de python aún y entiendo que hay formas mejor de hacerlo pero bueno:
https://github.com/Dynam1co/Python_Telegram_Bot/pull/3

He probado y funciona bien:

docker-compose build
docker-compose up (crea la base de datos on un init.sql de postgres docker, pero vamos que lo puedes cambiar a como te venga mejor)

Te recomiendo que programes en ingles, hay una mezcla muy rara de spanglish.

1 2 respuestas
vago_21

#9 Yeahhh muchas gracias, en poder mergeo y pruebo. Lo del spanglish es un error de comienzo de proyecto que estoy solucionando poco a poco xd

Lo dicho, en cuanto pueda lo pruebo y te cuento. Gracias de nuevo

ududud

#1 Hace poco hice un proyecto con Dialogflow con NodeJS y NoSQL(Firebase) y desplegado en Telegram, y si quieres darle ese toque de conversación más natural con la ayuda de IA, échale un vistazo a DialogFlow, tiene mucho potencial. Y también en vez de botones (para que no ocupen en la pantalla) puedes probar los Suggestion o QuickReplies (aunque este componente lo vi en la librería de Dialogflow fulfilment, pero entiendo que Telegram debería tenerlo también)
que es para que le aparezca encima del teclado directamente

1 1 respuesta
vago_21

#9 un tema, me ha montado el contenedor de postgres y de python sin problemas, pero tengo dudas.

Cuando lanzo el comando que saluda al usuario, lo hace correctamente, por lo que creo que está pillando bien el token de telegram, para el del tiempo no me responde nada, y para el que está conectado con postgre me da error de autentificación.

La pregunta es, para poder seguir con el debuger el código, ¿tengo que hacerlo con la extensión de remote-container de vs code y hacer rebuild o cómo se desarrolla ahora con el entorno dockerizado? es la primera vez que lo hago.

#11 ni lo conocía, mejor que los botones sin duda, muchas gracias, seguiré por ahí

1 respuesta
JuAn4k4

#12 La verdad es que yo debugeo muy poco y nunca lo he necesitado en docker, pero si hay tools que te meten otro compose override y tal, nunca lo he probado.

El auth de postgres me iba bien, lo tienes todo por environment vars. Me sacaba las recetas que tenía ya metidas (meti algunas a mano)

El de AEMET no llegue a probarlo, no tenía ni idea de cómo sacar el CityID.

¿Pero imagino que lo de AEMET es otro bot no?

1 respuesta
vago_21

#13 yo creo que te conecta porque tenías ya la base de datos creada, el archivo init.sql solo tiene la creación de la tabla, pero no la creación del usuario ni de la base de datos, creo que el problema está por ahí, he modificado el init.sql para que los cree, pero aún así sigue sin funcionarme ¿dónde le cides que ejecute el init.sql? no lo encuentro

El de AEMET es el mismo bot, pero con otro comando de telegram, el city id lo saqué en de la web de la aemet, viendo el tiempo en mi ciudad, te pone el city id en la url

1 respuesta
JuAn4k4

#14 Postgres se crea directamente con user/password y base de datos en docker-compose. Si haces

docker-compose up

te crea todo. Y le paso por env-vars el user/pw/database name correctos. El bot se conecta bien vaya a la base de datos si lo haces por docker-compose.

El init.sql se pone en una carpeta determinada de la imagen de postgres, y lo pilla solo (puedes leerlo en los logs) la primera vez que lo inicias (puedes borrar todo con

docker-compose down -v

Probe ayer lo de AEMET, y no hace nada, probe con "id50297" ( http://www.aemet.es/en/eltiempo/prediccion/municipios/zaragoza-id50297 ) igual debería ser 50297. Ayer lo hice desde postman para obtener la lista de municipios.

Si tienes postgres corriendo en local, igual te falla al iniciar el postgres de docker-compose al pillar el mismo puerto en ambos sitios y estar ya pillado, y te falla por eso. Yo nunca me instalo nada en local si puedo evitarlo, me lo pongo siempre por docker, mysql, postgres, rabbitmq, redis, lo que haga falta, asi no se llena de mierda el portatil.

Fijate en el docker compose: (Te añado comentarios a las lineas importantes)

postgres:
    restart: unless-stopped
    image: "postgres"
    environment: 
      - POSTGRES_USER=recipesbot    #Este es el usuario root de postgres
      - POSTGRES_PASSWORD=recipesbot #Esta es la contraseña del usuario root
      - POSTGRES_DB=recipesbot  #Esta es la base de datos que se crea por defecto
    ports:
      - 5432:5432
    volumes:
      - database-data:/var/lib/postgresql/data/  # Aqui se guardan los datos de postgres
      - ./docker/postgres:/docker-entrypoint-initdb.d/  # Aqui va el init.sql que se ejecuta al crear la bd 
  recipesbot:
    restart: unless-stopped
    depends_on: 
      - postgres
    build: 
        context: .
    image: recipesbot
    environment: 
        - TELEGRAM_TOKEN=AAAA
        - TELEGRAM_GROUP_ID=1111
        - POSTGRES_HOST=postgres
        - POSTGRES_USER=recipesbot
        - POSTGRES_PASSWORD=recipesbot
        - POSTGRES_DATABASE=recipesbot
        - WEATHER_SCHEDULE=08:00,12:00,15:00,18:00,22:00,00:00

Te tienes que crear docker-compose.override.yml en local, y ponerle el environment que quieras, o un env-file si lo prefieres

1 respuesta
vago_21

#15 No tengo postgre en local, estaba en un docker y paré el contenedor para que no diese problemas.

El docker-compose-override lo tengo creado y modificado el token de telegram etc, pero lo

#15JuAn4k4:

ponerle el environment que quieras, o un env-file si lo prefieres

[/quote] no lo pillo, igual es eso lo que falta ¿a qué te refieres?

perdón por lo noob

1 respuesta
JuAn4k4

#16 si ya le pasas el token, ya estás pasandolo por environment vars. Mira a ver si puedes conectarte al postgres del compose a ver si es que por lo que sea no se levanta bien.

1 1 respuesta
vago_21

#17

He hecho funcionar el postgre en Mac Os, luego he probado en windows y ha funcionado sin cambiar nada. ¿Cómo sigo ahora con el desarrollo? Si cambio algo en la aplicación ¿como vuelvo a ejecutar? tengo que hacer docker-compose up de nuevo?

Otra cosa, como paro la aplicación? parando los contenedores? Yo estoy plusando ctrl+c

vago_21

He actualizado el readme, si veis alguna cagada avisad

JuAn4k4

detached mode:

docker-compose up -d

o lo mismo tras ejecutar sin -d:

cntrl+z
bg

cntrl+c -> hace shutdown de todo (lo que se está ejecutando) como lo harias con:

docker-compose down

Y si tienes que hacer docker-compose build && docker-compose up
Puedes seguir desarrollando como hasta ahora lanzando postgres en docker con -d, y luego settear las env vars (el host de postgres es localhost desde fuera) y lanzar python desde el host.

Con docker los logs se pintan por consola y puedes leerlos con:
docker-compose logs recipesbot

Generalmente se usa la consola directamente y se recogen desde fuera.

1 respuesta
bLaKnI

#20 Con docker tengo asignatura pendiente...
Y veo que va muy de la mano con lo que haya en docker-hub en general. Ya que veo que al principio, mucho Dockerfile define las imagenes, y actualmente muchas se pueden llamar directamente de docker-hub (como la de postgres) con su parametrización citada en los readme.

Porque no llamas a la imagen directa de Python en el compose? Para poder usar el requirements en el Dockerfile y indicar el ejecutable directo una vez haga el "up"?

Tengo que apretar en DevOps... demasiados años de infra clasica :\
Quiero meterme con todo el mundo kubernetes, docker, ansible/terraform/cloudformation, pipelines, Jenkins, en fin...

1 respuesta
vago_21

ok sigo probando

Yo me descargué un curso de docker de puta madre, pero no he tenido tiempo todavía de hacerlo

JuAn4k4

#21 la idea es poder desplegar la imagen sin tener el código en el host. Asi luego es trivial ponerlo en K8s por ejemplo. Y si la imagen ya tiene el install hecho será más rápido de desplegar.

Se puede hacer como dices pero estarías duplicando el código que hay en el dockerfile en el compose, y dejarías de probar el del dockerfile.

Es la primera vez que lo hago para un lenguaje interpretado de todas formas.. por ll general se hace así porque hace falta compilarlo.

1 respuesta
bLaKnI

#23 Entonces,el objetivo es inyectar el codigo en el contenedor levantado para no tirar de local volumes? Pero eso no tiene mas sentido en una release a produccion? Que entonces paquetizas todo? Para desarrollo, creo es mas lógico montar un volumen local y trabajar con el codigo ahí, no? Quizás no te he entendido, perdona...

1 respuesta
eondev

#24 creas un dockerfile con el codigo de un repo git o de cualquier lado y con compose cada vwz haces el build y el up y compilas o haces lo que tengas que hacer. Pero eso lo veo yo para CI despliegues y tal.

Para desarrollar es más comodo usar volúmenes imho.

1 2 respuestas
bLaKnI

#25 This.

JuAn4k4

#25 Si, siendo interpretado tiene sentido para dev tirar de un volumen con el código y listo, no lo pensé mucho y tire a tiro hecho acostumbrado a compilar siempre.

#1 eso si, para aprovechar el layer caching, copia primero requirements.txt haz el pip install y luego copias el resto y ejecutas. Asi cacheas el pip install a no ser que cambie el fichero requirements.txt

Usuarios habituales

  • JuAn4k4
  • bLaKnI
  • eondev
  • vago_21
  • Comodiin
  • HeXaN
  • Troyer