Durante varios meses he estado creado algunos script en Python que interactúan con la API de Hive por medio de la biblioteca Beem. Como siempre, tenemos que lidiar con dependencias, versiones y una lista de detalles importantes para el desarrollo, despliegue y para compartir el código con otros desarrolladores.
Al principio no tuve ningún problema, ya que parece que estaba con las versiones de Python correctas y el entorno de desarrollo bien configurado. El problema inició cuando comencé a intentar desplegarlos en otros entornos y servidores. Las versiones de Python me estuvieron dando alguno que otro conflicto. Aún no tengo todo claro, pero con la versión de Python 3.9 o anterior, todo funciona perfectamente.
Error con Python > 3.9 y Beem.
Voy a compartir un error común que sube con versiones de Python superiores a la 3.9, esto me sucedía al instalar las librerías necesarias para trabajar con Beem:
error: subprocess-exited-with-error
× Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─> [54 lines of output]
running egg_info
writing lib/PyYAML.egg-info/PKG-INFO
writing dependency_links to lib/PyYAML.egg-info/dependency_links.txt
writing top-level names to lib/PyYAML.egg-info/top_level.txt
Traceback (most recent call last):
File "/home/alberto/Proyectos/transfer-delegations/env/lib64/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 353, in <module>
main()
File "/home/alberto/Proyectos/transfer-delegations/env/lib64/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 335, in main
json_out['return_val'] = hook(**hook_input['kwargs'])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/alberto/Proyectos/transfer-delegations/env/lib64/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 118, in get_requires_for_build_wheel
return hook(config_settings)
^^^^^^^^^^^^^^^^^^^^^
File "/tmp/pip-build-env-djtmtemg/overlay/lib/python3.12/site-packages/setuptools/build_meta.py", line 325, in get_requires_for_build_wheel
return self._get_build_requires(config_settings, requirements=['wheel'])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/pip-build-env-djtmtemg/overlay/lib/python3.12/site-packages/setuptools/build_meta.py", line 295, in _get_build_requires
self.run_setup()
File "/tmp/pip-build-env-djtmtemg/overlay/lib/python3.12/site-packages/setuptools/build_meta.py", line 311, in run_setup
exec(code, locals())
File "<string>", line 288, in <module>
File "/tmp/pip-build-env-djtmtemg/overlay/lib/python3.12/site-packages/setuptools/__init__.py", line 103, in setup
return distutils.core.setup(**attrs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/pip-build-env-djtmtemg/overlay/lib/python3.12/site-packages/setuptools/_distutils/core.py", line 185, in setup
return run_commands(dist)
^^^^^^^^^^^^^^^^^^
File "/tmp/pip-build-env-djtmtemg/overlay/lib/python3.12/site-packages/setuptools/_distutils/core.py", line 201, in run_commands
dist.run_commands()
File "/tmp/pip-build-env-djtmtemg/overlay/lib/python3.12/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands
self.run_command(cmd)
File "/tmp/pip-build-env-djtmtemg/overlay/lib/python3.12/site-packages/setuptools/dist.py", line 963, in run_command
super().run_command(command)
File "/tmp/pip-build-env-djtmtemg/overlay/lib/python3.12/site-packages/setuptools/_distutils/dist.py", line 988, in run_command
cmd_obj.run()
File "/tmp/pip-build-env-djtmtemg/overlay/lib/python3.12/site-packages/setuptools/command/egg_info.py", line 321, in run
self.find_sources()
File "/tmp/pip-build-env-djtmtemg/overlay/lib/python3.12/site-packages/setuptools/command/egg_info.py", line 329, in find_sources
mm.run()
File "/tmp/pip-build-env-djtmtemg/overlay/lib/python3.12/site-packages/setuptools/command/egg_info.py", line 551, in run
self.add_defaults()
File "/tmp/pip-build-env-djtmtemg/overlay/lib/python3.12/site-packages/setuptools/command/egg_info.py", line 589, in add_defaults
sdist.add_defaults(self)
File "/tmp/pip-build-env-djtmtemg/overlay/lib/python3.12/site-packages/setuptools/command/sdist.py", line 112, in add_defaults
super().add_defaults()
File "/tmp/pip-build-env-djtmtemg/overlay/lib/python3.12/site-packages/setuptools/_distutils/command/sdist.py", line 251, in add_defaults
self._add_defaults_ext()
File "/tmp/pip-build-env-djtmtemg/overlay/lib/python3.12/site-packages/setuptools/_distutils/command/sdist.py", line 336, in _add_defaults_ext
self.filelist.extend(build_ext.get_source_files())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<string>", line 204, in get_source_files
File "/tmp/pip-build-env-djtmtemg/overlay/lib/python3.12/site-packages/setuptools/_distutils/cmd.py", line 107, in __getattr__
raise AttributeError(attr)
AttributeError: cython_sources
[end of output]
note: This error originates from a subprocess, and is likely not a problem with pip.
error: subprocess-exited-with-error
× Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─> See above for output.
note: This error originates from a subprocess, and is likely not a problem with pip.
Quizás el problema no sea necesariamente con Been sino con algunas dependencias como lo muestra en los mensajes de error, fue un dolor de cabeza para mi. Encontré dos formas de solucionar este problema, el primero es con contenedores docker por ejemplo, eligiendo las imágenes de las versiones de Python compatibles. Y el otro es con Anaconda, que es una distribución de python que permite crear entornos de desarrollos con la versión de Python disponible que queramos.
Error con las variables de entorno y dotenv.
Este es el error más curioso, ya que al declarar el nombre de la cuenta de hive en el archivo .env
como USERNAME=user_hive, me generaba un conflicto, en lugar de devolverme la instancia de Hive a la cual quería extraer la información, me devolvía el nombre de usuario de mi máquina, dando error en los datos y en la firma de las transacciones. Paso el ejemplo del código:
.env:
HIVED_NODES=https://anyx.io,https://api.hive.blog,https://api.openhive.network
USERNAME=user_hive
KEY=active_key
main.py:
import os
from dotenv import load_dotenv
# Cargar las variables de entorno desde el archivo .env
load_dotenv('.env')
# Obtener los valores de las variables
hived_nodes = os.getenv("HIVED_NODES").split(',')
username = os.getenv("USERNAME")
# Objeto Hive para interactuar con la blockchain de Hive
hive = Hive(node=hived_nodes)
# Crea una instancia de la clase Account para la cuenta 'visualblock'
#account = Account("visualblock", blockchain_instance=hive)
account = Account(username, blockchain_instance=hive)
print(account)
Lo anterior debería devolverme <Account user_hive>
, pero es su lugar me devolvía <Account nombre_usuario_seccion>
, es decir, el usuario de la sección iniciada en mi máquina. Por supuesto, esto me generaba un error al extraer los datos y al firmar la transacción con la llave active. Esto lo solucioné cambiando los nombres de las variables a nombres más genéricos, como HIVE_USER y hive_user respectivamente.
Otro problema que te puedes encontrar...
Si quieres conectarte con la base de datos de Hive, HiveSQL, necesitas instalar el driver de conexión ODBC Driver for SQL Server. Lo he probado con Debian 11, Ubuntu, Arch Linux y Fedora sin ningún problema; el detalle es que si deseas usarlo para Debian 12 y sigues la documentación oficial de Microsoft vas a tener problemas. La documentación no ha actualizado la forma en que Debian 12 está firmando y obteniendo las llaves de los repositorios de terceros, generando un conflicto al intentar descargar e instalar el driver necesario. Una solución no muy elegante, es hacerlo con los repositorios de Debian 11.
Esto son algunos de los aspectos que debemos considerar si queremos desarrollar alguna solución en Hive usando las API y la base de datos HiveSQL. Quizás no sean las mejores formas resolver los tropiezos, pero me han funcionado y los comparto para quién esté pasando por los mismos inconvenientes. Si has encontrado otras soluciones, por favor deja un comentario para que toda la comunidad pueda servirse de ello. Espero que les sea de utilidad, un abrazo.
Las imágenes son mías o capturas de pantalla tomadas por mí, a menos que se indiquen fuentes externas. La portada fue creada con Canva e imágenes libres de derechos de autor.
Vota por nuestro Testigo aliado - @hispapro
Discord: alberto0607
Sígueme en Twitter: alberto_0607