Somos muchos los que trabajamos con distintos entornos y ordenadores. Ya sea en el trabajo, en casa, con un portátil y con PC de sobremesa. Podemos llegar a tener distintas instalaciones de Visual Studio Code y eso puede ser un problema si trabajamos con los mismos proyectos, ya que tendremos que replicar las configuraciones y extensiones que utilicemos en cada una.
Hasta ahora podíamos utilizar esta famosa extensión llamada Settings Sync que consigue hacer esto mismo. Sincronizar configuraciones, snippets, temas, iconos, workspaces, y más. Para lograrlo utiliza el Gist de tu cuenta de Github.
Como es lógico, esto habrá llamado la atención de Microsoft y han decidido añadir de serie esta funcionalidad. De forma oficial, dentro de VS Code.
Al tratarse de una opción muy nueva, todavía no está disponible en las versiones estables de Visual Code, pero ya la están testeando en la versión para Insiders. En este mismo enlace podréis ver la documentación oficial. Al parecer le faltan opciones todavía para poder substituir el plugin anteriormente mencionado, pero si se trata de una opción oficial y viendo lo bien que trata Microsoft a VS Code, estoy convencido de que acabará siendo mejor opción.
Como explican en la página oficial, basta con activar la sincronización haciendo click en el icono del engranaje y seleccionando «Turn on Preferences Sync«
En este caso, la sincronización se realizará a través de vuestra cuenta de Microsoft o la de GitHub. Tras hacer login y enlazar la cuenta, VS Code empezará a sincronizar vuestra configuración en la nube.
Los atajos de teclado, como es lógico, se sincronizarán por plataforma (Mac, PC,…) aunque podemos desactivar esta limitación. Las extensiones se sincronizarán también por defecto, pudiendo desactivar extensiones concretas que no queramos sincronizar.
Muy interesante también la sincronización de la interfaz. Se incluyen, entre otros, el panel de entradas, los layouts y los comandos recientes.
Por el momento, tras unas horas de uso, puedo decir que no he notado mayor diferencia a utilizar la extensión Settings Sync, pero la configuración inicial ha sido mucho más sencilla y rápida. Como decía, habrá que esperar un poco porque al tratarse de una opción oficial de Microsoft, lo más probable es que termine siendo el método preferido.
Os explicaré como poder generar ficheros Word en formato .docx de forma dinámica con Django. En mi caso lo he utilizado para desarrollar una funcionalidad para StoryDevil, que permite a los usuarios exportar en .docx una serie de documentos necesarios para enviar cartas de presentación y propuestas editoriales en base a unos datos generados en la aplicación.
De esta forma, el usuario tiene ficheros editables que puede personalizar antes de generar un PDF o hacer el envío definitivo. Y esto, con Django y el paquete python-docx, es sorprendentemente sencillo.
Además, os compartiré el código que utilicé para que el documento se descargue directamente en el navegador del usuario, en lugar de almacenarse en el servidor.
Con la librería python-docx (Github y PyPI) puedes crear documentos Word y, como decía, de forma bastante sencilla. Tiene soporte para párrafos, estilos, tablas, personalizar cabecera y pié, objetos de forma, secciones, y más. Es compatible con Python 2.6, 2.7, 3.3 y 3.4. La única dependencia adicional es la librería lxml.
A modo de ejemplo, estas tres líneas son suficientes para crear un documento, añadirle un título, y un párrafo a continuación.
document = Document()
document.add_heading('Título del documento', 0)
p = document.add_paragraph('Esto es un documento Word generado con Python.')
Instalación
Como la mayoría de paquetes Python, la instalación se puede hacer con la utilidad pip o también con easy_install. Si preferimos el método manual, podemos descargar la última versión, descomprimirla, y instalar con python setup.py install.
# Instalar con pip
pip install python-docx
# Instalar con easy_install
easy_install python-docx
#Instalación manual
tar xvzf python-docx-{version}.tar.gz
cd python-docx-{version}
python setup.py install
También puedes añadir el paquete en el fichero requirements.txt de Django especificando la última versión compatible.
Django==3.0.3
...
python-docx==0.8.10
Crear el formulario para la descarga
Para este ejemplo vamos a crear un formulario sencillo con un botón que, tras pulsarlo, llamará a una vista que generará el documento y lo descargará directamente en el navegador.
Este es el formulario con un action que llamará a la URL que apunta a la vista.
De esta forma podemos llamar a la función url en la plantilla de Django para que cree automáticamente la URL correcta que llamará a nuestra vista.
Configurar la vista que generará el documento y la descarga
En el fichero views.py, he creado una función llamada coverletter_export tal y como se indica en el fichero urls.py.
Antes que nada, hay que importar lo necesario:
# Para la generación y descarga del fichero
import io
# Para utilizar algunas de las funciones de la librería
from docx import Document
from docx.shared import Inches, Pt
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.text import WD_BREAK
En mi caso he importado algunas funciones concretas de la API de python-docx como Inches y Pt, que permiten indicar longitudes (de párrafos por ejemplo) en pulgadas y en puntos, además de WD_ALIGN_PARAGRAPH que puedes utilizar para personalizar la alineación de los párrafos, pero debes consultar la documentación para ver qué necesitas exactamente.
Al grano, aquí va el ejemplo entero para generar un documento Word básico con un título centrado, y dos párrafos de texto.
Algunos detalles:
Podemos crear párrafos en blanco con add_paragraph()
Con add_heading() añadimos texto en un elemento de título, y con alignment = WD_ALIGN_PARAGRAPH.CENTER lo centramos.
Es posible que si le pasamos un texto con líneas en blanco a la función add_paragraph(), nos lo renderizará con párrafos enteros en blanco. Podemos recorrer el texto con splitlines() descartando las líneas en blanco y se renderizará como es debido.
También podemos modificar el espaciado entre líneas usando .paragraph_format.line_spacing e indicándole un valor float.
Podemos usar ‘\n’ en el texto para añadir saltos de línea.
def coverletter_export(request):
document = Document()
# Get the user's fullname
if request.user.get_full_name():
document_data_full_name = request.user.get_full_name()
else:
document_data_full_name = "[NOMBRE] [APELLIDOS]"
# Print the user's name
document_elements_heading = document.add_heading(document_data_full_name, 0)
document_elements_heading.alignment = WD_ALIGN_PARAGRAPH.CENTER
# Add empty paragraph
document.add_paragraph()
# Print biography and careerpath
for line in document_data_biography.splitlines():
if line:
document_element_biography = document.add_paragraph(line)
document_element_biography.alignment = WD_ALIGN_PARAGRAPH.LEFT
document_element_biography.paragraph_format.line_spacing = 1.15
for line in document_data_careerpath.splitlines():
if line:
document_element_careerpath = document.add_paragraph(line)
document_element_careerpath.alignment = WD_ALIGN_PARAGRAPH.LEFT
document_element_careerpath.paragraph_format.line_spacing = 1.15
# Add empty paragraph
document.add_paragraph()
# Sincerely and name
document.add_paragraph("Atentamente,\n" + document_data_full_name)
Descarga del documento generado
Como parte final, queda la generación del fichero docx.
En el ejemplo oficial se utiliza la función save() que guarda el fichero en el servidor.
document.save('demo.docx')
Pero en mi caso programé la siguiente función para que en lugar de guardarse en el servidor, el fichero se descargue directamente en el navegador del usuario y no se guarde ninguna copia en nuestros sistemas.
Basta con hacer lo siguiente:
# Save document to memory and download to the user's browser
document_data = io.BytesIO()
document.save(document_data)
document_data.seek(0)
response = HttpResponse(
document_data.getvalue(),
content_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
)
response["Content-Disposition"] = 'attachment; filename = "Carta de Presentación.docx"'
response["Content-Encoding"] = "UTF-8"
return response
Con esto deberías tener todo lo necesario para generar tus propios ficheros Word desde cualquier aplicación Python.
Siempre nos ha costado mucho arrancar un proyecto y conseguir usuarios. El marketing puede llegar a tener un presupuesto infinito, y nuestra idea principal era el boostrapping. Arrancar con capital propio y sin inversiones externas.
Publicamos el proyecto a principios de febrero. Sin avisar a prácticamente nadie. Solo a nuestros amigos, conocidos, y con algún post en nuestros propios perfiles de Facebook, Twitter y LinkedIn. No queríamos salir con grandes fallos así que nos decantamos por un soft-launch.
En nuestra hoja de ruta tenemos un par de planes que empezaremos a ejecutar en breve para lograr nuevos nichos de usuarios que creemos que pueden funcionar, pero antes de llegar a ese punto necesitábamos un poco de masa de usuarios para recibir feedback real y que no sea de nuestros amigos.
Aunque todavía es muy pronto para sacar conclusiones, estos son los primeros resultados.
La prensa especializada habla de nosotros
El dia 14 de abril apareció un pequeño artículo en Wwwhatsnew sobre StoryDevil. Este fue un primer punto de inflexión que causó una considerable subida en los nuevos registros. Hasta este momento no habíamos realizado ninguna campaña de marketing ni habíamos publicitado la web en ningún sitio.
Este gráfico muestra los nuevos usuarios registrados durante los primeros días tras la aparición del artículo. En total logramos 504 usuarios nuevos en 7 días.
De estos usuarios, nos interesaba analizar cuantos de ellos terminaban el registro correctamente activando la cuenta, y cuantos entraban en la aplicación y creaban como mínimo un proyecto.
Primeros problemas, usuarios sin activar
Sorprendentemente, el proceso de registro nos funcionó mucho mejor de lo esperado y de 504 usuarios, solo 14 no activaron la cuenta.
Igualmente queríamos saber el porqué de todos los fallidos. Quizá teníamos un problema con el envío del correo de verificación, o un problema de experiencia de usuario.
A las pocas horas del día 14, empezaron a llegar algunos comentarios enviados con la herramienta Userback que tenemos instalada dentro de la aplicación. Todos (4) nos comentaron lo mismo. No les había llegado el correo de confirmación para poder activar la cuenta. Pensamos que 4 de 500 eran muy pocos, pero algo estaba sucediendo. Resultó que todos ellos usaban una direccion de @hotmail. Descubrimos un pequeño desajuste en nuestra configuración de mailing que hacía que Hotmail detectase los correos como Spam. Contactamos con todos los usuarios y les activamos manualmente la cuenta.
Es imprescindible detectar todos los problemas en las primeras fases de un proyecto porque luego, si la actividad se dispara, los fallos tienen consecuencias más graves.
Más tarde llegaron más peticiones de soporte para el resto de cuentas. Pero solo detectamos un error nuevo, usuarios que se equivocaron al escribir su dirección de correo durante el registro. Por ejemplo, escribiendo @gmail.com en lugar de @outlook.com
Empezamos a recibir feedback
Empieza una de las partes más divertidas. Recibir feedback de usarios reales y que no sean de tus amigos y por compromiso.
Tras analizar unas cuantas herramientas para tal, nos decidimos por Userback, que permite empezar con una cuenta gratuita con la que puedes poner un widget en la web o aplicación y los usuarios pueden enviarte feedback que luego recibes en un entorno web, desde el cual puedes gestionarlos como un sistema de ticketing y incidencias.
Durante todos estos días hemos recibido 7 tickets a través de Userback.
De estos 7 mensajes, 5 de ellos han sido comentarios con propuestas de mejora, y 2 con bugs detectados por usuarios.
Propuestas de mejora
De entre las ideas que nos han llegado, destacamos las propuestas de:
Crear una sección donde guardar «Recursos» (objetos) utilizados en producciones.
Crear una sección con «Localizaciones» para marcar lugares en un mapa y/o añadir fotos sobre sitios donde grabar.
Formatos especiales para telenovelas en Latinoamérica.
2 propuestas de mejoras visuales para facilitar la escritura de textos.
Errores
Estamos bastante satisfechos con este punto porque solo dos usuarios nos han contactado tras detectar un bug que hemos podido corregir de forma bastante rápida. Eran sencillos. Uno de ellos era que al intentar subir una foto de un personaje editado, éste daba error. Permitía hacerlo con nuevos personajes pero no al editarlos si estos eran de tipo «Monstruo».
Causar una muy buena impresión
Es una herramienta gratuita y los usuarios no pagan nada, pero son tus usuarios y dedican su tiempo a utilizarla. Todos son importantes. No hace falta decir que sin usuarios no hay web.
Nuestra intención es responder lo más rápido posible y hacerlo de la mejor forma. Creo que es importante causar un efecto «wow» en este sentido, y que sepan que tras la aplicación hay un equipo con ganas.
A modo de ejemplo, una imagen vale más que mil palabras. Pudimos arreglar un error detectado por un usuario en apenas 13 minutos y a las 21h de un lunes.
Usuarios que se dan de baja
Por el momento, hemos tenido un total de 3 bajas. Todas realizadas en menos de 48 horas tras el registro, por lo que deducimos que estos usuarios se han percatado rápidamente que la herramienta no les encaja. A día de hoy (1 de mayo) no tenemos más bajas, aunque sí tenemos usuarios (8 en total) que tras el registro y primer día de uso, no han vuelto a entrar.
Visitas a la Wiki
StoryDevil tiene una Wiki completamente abierta donde todo el mundo puede consultar información sobre distintos aspectos de la producción cinematográfica y la escritura de guiones.
Estas son las estadísticas de acceso durante todo el mes de abril de 2020. Se notan los primeros días tras la publicación del artículo de Wwwhatsnew y luego una considerable bajada de actividad. Habrá que esperar un poco y analizar si los usuarios realmente lo utilizan a diario, de manera puntual, o bien reforzamos la estrategia SEO para que la Wiki sea un punto de entrada de usuarios y podamos convertirla en algo más global.
El otro día se me ocurrió crear una página en Notion con una serie de plantillas de correo para responder “No” de forma educada y elegante en distintas situaciones.
Quería ponerlas aquí pero es más cómodo mantener el repositorio en Notion por si voy añadiendo más. Si has llegado hasta aquí y quieres colaborar con alguna, no dudes en enviármela!
Creo que será interesante escribir una serie de artículos explicando de forma totalmente transparente el proceso de creación y evolución del proyecto StoryDevil, del que soy fundador junto a Carles Gòdia.
Carles es el típico amigo con el que compartes algo más que amistad. En mi caso, también aventuras empresariales. Empezamos YoteConozco.com en el año 2006, escribimos el guión de una película el año pasado, y publicamos StoryDevil hoy.
¿Por qué lo creamos?
Hace años que mi socio Carles se dedica, además de su profesión, a escribir, dirigir y incluso interpretar obras de teatro. Por mi parte, tras dedicarme muchos años al 3D y los VFX como hobby, empecé a escribir el guión de una película sobre una historia que llevaba gestando años.
Llegado a este punto, Carles y yo decidimos colaborar y escribir juntos el guión para otra película, una adaptación de su obra de teatro “Vecinas”. Más tarde nos dimos cuenta de que no existía ninguna herramienta online potente para juntar todo el trabajo de creación de una obra. Aquí es cuando decidimos crear StoryDevil.
Manos a la obra. ¿Cómo debía ser esta herramienta?
Un entorno para escribir debe ser amplio y limpio. Con una interfaz moderna. Enfocada a usuarios que escriben con dispositivos tipo ordenadores de sobremesa y tablets con teclados externos. No suele ser un trabajo para dispositivos smartphone.
Teníamos claro que StoryDevil sería una herramienta capaz de organizar y gestionar todo el trabajo de creación de una obra, con todos sus detalles, y de manera ordenada. Un lugar donde el creador tenga todo lo necesario para dar vida a su historia.
Nuestro otro objetivo era la formación. No encontramos ningún otro entorno web con información bien estructurada sobre cómo crear un guión. De ahí salió la idea de crear una Wiki para ordenar todos los documentos que explican cómo crear historias. Un lugar que pueda ser consultado en todo momento y, además, de forma libre y abierta para todo el mundo.
Diseño de la aplicación
Empezamos a diseñar los wireframes o retículas de la aplicación con el software Adobe XD. Hacerlo de esta manera nos otorgó una gran agilidad en poder cambiar constantemente los elementos de la interfaz para simular las funcionalidades de las distintas secciones.
Teníamos muy clara la estructura general de la aplicación, así que diseñamos de esta forma el esqueleto de todas y cada una de las secciones para validar los campos de datos a añadir, el funcionamiento de los botones y tenerlo todo muy claro antes de empezar a programar el front y el backend.
Mínimo Producto Viable (MVP)
Una de las cosas de las que te das cuenta en este proceso es de todo lo que sobra y no es indispensable para sacar la primera versión de un producto. Es importante no tener un listado extenso con todo lo que queremos implementar en una aplicación ideal. Teníamos claro que queríamos empezar siguiendo un MVP.
En el diseño anterior, por ejemplo, queríamos añadir la posibilidad de mercar como favoritas las ideas para las storylices. No es algo complejo, pero tampoco es indispensable y no hace más que añadir tiempo de desarrollo quizá innecesario. No definirá el futuro de la aplicación, así que puede esperar.
Tras definir todo lo que imaginamos como indispensable, terminamos con el diseño de todas las pantallas de StoryDevil.
Herramientras para trabajo en equipo y a distancia.
No tenemos oficina. Cada uno de nosotros tiene otro trabajo y otra casa. Nos toca crear StoryDevil completamente en remoto.
Dropbox para repositorio de ficheros de trabajo, Github para el código, y Google Docs para documentación colaborativa. Estas son las tres herramientas principales que hemos utilizado.
Poder trabajar con todo el código en Github nos ha facilitado también enormemente el día a día. Allí continuamos gestionando todas las tareas, actualizamos el estado de las mismas, y guardamos todo el código que forma parte de StoryDevil. La web, la aplicación y la Wiki.
En futuros artículos explicaré en detalle qué plataforma técnica elegimos y cómo empezamos el proceso de desarrollo del front-end y del back-end.
Si has llegado hasta aquí es porque quieres aprender un poco sobre esta arquitectura y probablemente tengas pocas nociones sobre esto. De lo contrario, te recomiendo que no sigas leyendo. Es un artículo para principiantes.
El problema con las API
Llegó el año 2000, y empezaron a verse de forma clara las ventajas de los Web Services para la comunicación entre sistemas. Entre aplicaciones web. Cliente-Servidor. En aquel entonces no existía ningún estándar sobre cómo diseñar una API. Se implementaban usando otros protocolos como SOAP. Difíciles de implementar. Pesados. Más complejos en todos los aspectos.
Entonces, un grupo de expertos liderado por Roy Fielding, creó la llamada arquitectura REST. Esto cambió por completo el desarrollo de servicios web hasta la fecha.
REpresentational State Transfer
Esto es lo que significan sus siglas. Se trata de una arquitectura para estandarizar comunicaciones web entre sistemas, logrando que se entiendan mucho mejor entre ellos. A los servicios que cumplen con este diseño se les llama servicios RESTful.
Cliente y Servidor
El servidor expone la API para que el cliente haga uso de ella. Por ejemplo, los servidores de Twitter o Instagram nos facilitan el formato de sus API y nosotros, desde una aplicación web o móvil, accedemos a las mismas para leer o incluso modificar información.
El cliente hace una petición, y el servidor envía una respuesta.
Una de las ventajas de REST es que cliente y servidor no tienen porqué depender del mismo código para entenderse intercambiando mensajes. El servidor puede actualizarse y cambiar, sin que el cliente tenga que hacerlo. Y al revés. Mientras no cambie el formato de los mensajes, no hay problema.
Sistemas Stateless (sin estado)
Antes que nada es importante saber qué significa que un sistema no tenga estado. En una arquitectura REST, cuando se comunican servidor con cliente, estos no necesitan saber en qué estado se encuentra cada uno. Entienden igualmente el mensaje. Ambos pueden entenderlo sin tener en cuenta los anteriores. La base de la arquitectura REST define una interacción orientada a recursos.
Estructura de las comunicaciones
La arquitectura REST se basa en que el cliente envía peticiones para recuperar o modificar recursos, y el servidor responde con el resultado, que puede ser con los datos que hemos pedido o el estado de la petición.
Una petición está formada por:
Un verboHTTP que define la operación a realizar.
Una cabecera o header que incluye información sobre la petición.
Una ruta o path hacia un recurso.
El cuerpo del mensaje o body con los datos de la petición.
Verbos HTTP
Existen 4 verbos principales que forman parte de las peticiones HTTP para interactuar con una API REST, estos son:
GET Para recuperar información sobre un recurso específico.
POST Para crear un nuevo recurso.
PUT Actualizar un recurso
DELETE Eliminar un recurso
Por ejemplo, en el caso de una API sobre películas.
GET: Consulta y lee información sobre películas. “/movies” nos permite acceder a todas ellas “/movies/419” accedemos a la película con ID 419
PUT: Actualiza los datos de una película “/movies/419” Actualizamos los datos de la película con id: 419
PUT https://www.domain.com/movies/419
Respuesta: Status Code - 200 (OK)
DELETE: Elimina una película “/movies/419” Elimina la película con id: 419
DELETE https://www.domain.com/movies/419
Respuesta: Status Code - 204 (NO CONTENT)
Con esto deberíamos ofrecer las 4 funciones básicas de un modelo de datos. También conocidas con las siglas CRUD. Crear (Create), Leer (Read), Actualizar (Update) y Eliminar (Delete).
Cabeceras (headers) y parámetros Accept
A lo que he explicado le falta un detalle. Las cabeceras a incluir en las peticiones. El cliente debe enviar un tipo de contenido que el servidor sea capaz de entender. Para esto sirve el campo Accept. Se asegura que el servidor no enviará contenido que el cliente no pueda interpretar. Las opciones a enviar son MIME Types. Estos se utilizan para identificar los tipos de contenido del campo Accept. Consisten en un tipo y un subtipo.
Un tipo puede ser “image”, y un subtipo “image/jpeg”. O bien “text/css” para contenido de estilos CSS o “text/plain” para texto plano.
Por ejemplo, un cliente que quiera acceder al contenido de una película, podría enviar una petición como esta:
GET /movies/885 Accept: text/html, application/xhtml
Respuestas del servidor
Cuando termina la operación de la API en el servidor, este nos enviará el resultado junto con una serie de datos para que podamos interpretar el éxito o no de la operación y el tipo de datos que recibimos.
Content Types
Cuando el servidor envía un payload hacia el cliente, debe incluir una cabecera llamada content-type. Esto es para que el cliente sepa qué tipo de contenido le llega. Estos datos también son MIME Types, tal y como indicamos anteriormente. Y además, el MIME Type que nos envía el servidor debe coincidir con el que envía el cliente en la cabecera Accept.
Pongamos un ejemplo sencillo que lo explica todo mucho mejor.
Petición del cliente:
GET /movies/445 HTTP/1.1 Accept: text/html, application/xhtml
Respuesta del servidor:
HTTP/1.1 200 (OK) Content-Type: text/html
Códigos de respuesta
Las respuestas del servidor deben contener códigos de estado para avisar al cliente del éxito o no de cada operación. Para cada verbo HTTP tenemos una serie de códigos esperados que nos indicarán la ejecución correcta de cada operación:
Las 3 mejores dashboard admin templates gratuitas de 2020
He hecho un poco de investigación para encontrar buenos Dashboards estilo “Admin” para uno de mis proyectos, y los he publicado en este artículo para compartir mi lista. Son solo 3, pero son las que he elegido tras analizar más de 30 porque creo que son las mejores.
Todos los que expongo son totalmente gratuitos con licencia MIT y tienen un mínimo de actividad y seguidores que aseguran, en mayor o menor medida, su continuidad y soporte de la comunidad.
Puntos a tener en cuenta para elegir un buen dashboard
Continuidad y soporte. Lo que os comentaba. Por muy bonito que sea, debe tener una comunidad mínimamente activa.
Que use un framework de CSS conocido y actualizado. La última versión de Foundation o de Bootstrap.
Que esté mínimanente probado en entornos productivos.
Que tenga repositorio público.
Revisa el apartado “Issues” para comprobar que los pequeños detalles e imperfecciones se van corrigiendo.
Que sea modular y utilice un gestor de paquetes.
Sleek Dashboard
Uno de los que más me ha gustado. Aunque todavía está en beta, a día de hoy la última versión es del 14 de enero de 2020. Además de los típicos componentes, formularios y tablas, tiene algunas páginas personalizadas interesantes como las de Chat, Contactos, Team y Calendario.
Uno de los más veteranos, con distintas versiones para Bootstrap 3 y Bootstrap 4. Está creada por Colorlib y tiene plantillas premium opcionales. Se actualiza constantemente (la última actualización en el momento de escribir esto es de hace apenas 11 días). Actualizan constantemente las dependencias y hay mucha actividad. A tener muy en cuenta.
Con el uso de contenedores virtualizados con Docker, el proceso de debug ha cambiado un poco. Ahora debemos conectarnos a las instancias virtualizadas para poder hacer debug de nuestro código, y a veces no es tan sencillo como parece.
En este caso explicaré cómo configuro normalmente mi entorno con VS Code para hacer debug remoto para el desarrollo de mis aplicaciones Django bajo Docker.
VS Code ya tiene una extensión de Docker que facilita las cosas. Soporta Node.js, Python y .NET Core.
Si abrimos la pestaña de docker, ya deberíamos ver un resumen con los contenedores, imágenes y demás.
El primer paso es añadir el módulo ptvsd (Python Tools for Visual Studio debug server) en nuestro fichero requirements.txt
ptvsd == 4.3.2
La versión 5 lleva tiempo en alpha, por lo que te recomiendo mirar en el repositorio oficial.
Ahora debes modificar el fichero launch.json de VS Code con este contenido:
Lo siguiente es modificar el fichero manage.py para añadir las siguientes lineas:
if settings.DEBUG:
if os.environ.get('RUN_MAIN') or os.environ.get('WERKZEUG_RUN_MAIN'):
import ptvsd
ptvsd.enable_attach(address = ('0.0.0.0', 3000))
print "Attached remote debugger"
Django hace live reload de manera que actualiza cada vez que detecta cambios en el código mientras trabajamos. El segundo if es para evitar que se inicialice dos veces.
El fichero manage.py (en mi caso con Django 3) quedaría de la siguiente forma:
El siguiente paso es asegurar que tenemos abierto el puerto 3000 desde Docker. En el caso de docker-compose.yml, yo tengo:
Una vez hecho esto, ya deberíamos poder lanzar la instancia con nuestra configuración de debug. Deberíamos tener el perfil Python: Django (creado en el fichero launch.json) disponible en la pestaña de debug de VSCode, y basta con darle al play para que todo arranque.
Si lo hemos hecho bien, podremos ver como aparece “Dev Container: Existing Docker Compose…” en la parte inferior, lo cual nos indica que estamos conectados al contenedor Docker a través de VSCode y tenemos todo listo para debugar. En la siguiente captura podemos ver también el print del mensaje “Attached remote debugger” que hemos puesto en el manage.py.
Muchos de nosotros, lo primero que hacemos tras registrar un dominio o cuando llega la hora de publicar una web, es activar el registro y la cuenta en Cloudflare para apuntar las DNS del mismo y aprovechar las aplicaciones y mejoras que ofrece incluso con la capa gratuita.
Pero hay que tener mucho cuidado con lo que configuramos en Cloudflare. Al actuar como proxy pudiendo ser capaz de alterar todo el código y comportamiento de la web, también es posible que alguna de las modificaciones acabe causando un problema y que, en el caso que nos ocupa, lo apliquemos a un eCommerce Magento y deje de funcionar, por ejemplo, la pasarela de pago.
Y si, esto es lo que puede ocurrir si utilizamos la pasarela de pago Redsys y nuestro eCommerce pasa por el proxy de Cloudflare, que los pagos dejen de confirmarse.
El usuario que realiza el pago en nuestro eCommerce Magento, sale de la web para dirigirse a la pasarela de pago. Una vez introducidos los datos y confirmada la compra, Redsys nos envía un callback con los datos de confirmación de la misma para que Magento cambie el estado de la transacción.
Asegurar constantemente el correcto funcionamiento de los cambios de estado con Redsys es clave para no terminar desquiciado y con tu cliente con los cojones hinchados.
El problema es que Cloudflare bloquea las peticiones callback que envía Redsys a nuestra web y estas no se registran correctamente.
Lo que hace Cloudflare concretamente es bloquear la petición de Redsys por no superar el “Browser integrity check”. En la siguiente captura podréis ver un ejemplo real de una petición callback hacia la url: /es/redsys/index/notify
Esto hace que el eCommerce (Magento, Prestashop, WooCommerce o cualquiera) no pueda cambiar el estado del pedido y el responsable de servirlos tenga problemas para saber si el pago se ha realizado correctamente o no.
Solución? Crear una regla de Firewall
La solución pasa por crear una regla en Cloudflare para que las peticones de Redsys no pasen por su sistema de comprobación de seguridad.
Podríamos crear una regla de URL con las ‘Page Rules’ pero no podemos limitarlas por IP y eso lo hace menos seguro. Debemos crear una regla de Firewall por URL y también por ASN.
Como vemos en la captura anterior, el ASN de Redsys / Sermepa es 31627. La regla de Firewall quedaría de esta manera:
Igualmente, tras hacer este cambio, es indispensable que hagas una nueva prueba de compra para asegurar que funciona. Duda siempre de todo, incluso de este post. Aprende qué significa crear esta regla y todo lo que conlleva. Puede que me funcione a mi pero no a ti. Puede que funcione hoy y no mañana. Que cambie el ASN de Redsys. Mil cosas para que todo vuelva a fallar.
Bienvenidos al fantástimo mundo de los eCommerce 😉
He estado un tiempo estudiando y probando distintos motores de búsqueda para Magento 2 y he llegado a varias conclusiones que quiero compartir.
En primer lugar, si estás en un artículo como este es porque probablemente el buscador de Magento se te haya quedado pequeño y estás buscando una alternativa. De todas formas, Magento 2.3.1 activa Elasticsearch como buscador por defecto. ¡Será por algo!
Pues bien, esto es lo que me pasó a mi en uno de los proyectos corporativos con Magento que desarrollamos en ACTIUM Digital. Se trataba de un proyecto relativamente ambicioso y el buscador era el punto clave. Pude dedicar cierto tiempo a estudiar e incluso probar unos cuantos para decantarnos por el que mejor se adaptaba a nuestras necesidades. Si una cosa tenemos clara, es que aunque hay que ser ágil y rápido probando y descartando, escatimar en I+D genera hipoteca técnica a largo plazo.
Dedícale tiempo y cariño. Un buen buscador mejorará la conversión en tu tienda online.
En este artículo explicaré mi experiencia y las conclusiones a las que he llegado utilizando:
El buscador que trae por defecto Magento no es más que una búsqueda a través de la base de datos MySQL. No podemos compararlo con otros buscadores, especialmente con los que comento aquí. Esto trae la ventaja de que es fácil de configurar y nos ofrece un buscador en funcionamiento out of the box. Esto es suficiente para la mayoría de eCommerce relativamente pequeños y con un catálogo de productos que no supere los pocos miles.
Ahora bien, si nuestro eCommerce crece o es un proyecto que ya sabemos desde un principio que va a ser grande (miles de productos, visitas, etc.) o que simplemente queremos que tenga un buen buscador, hay que estudiar alternativas, además de pensar en crear una arquitectura escalable en todos los aspectos.
Otras desventajas
Además de ser ahora mismo una opción oficialmente deprecada. Con el buscador de MySQL no podremos usar funcionalidades como las sugerencias, el clustering, o la configuración del peso por atributo.
El indexer de Magento
Una de las partes más importantes a tener en cuenta y a entender cómo funciona es el propio sistema de indexación del catálogo de Magento.
Magento tiene un proceso para indexar toda la información del catálogo de productos, categorías y precios. Para que las búsquedas sean rápidas, Magento debe actualizar constantemente dicho índice. Si no pasamos por este proceso, cada vez que queramos buscar información sobre un producto Magento tendrá que pasar por todo un proceso de cálculo y consultas hasta obtenerlo. Esto ocurre por ejemplo con los precios y su constante actualización.
Para actualizar todos estos datos, Magento realiza una reindexación programable. Esta reindexación permite que la base de datos esté constantemente actualizada, pero es un proceso que puede llegar a ser muy lento.
Este proceso de reindexación tiene dos modos de actuación a tener muy en cuenta. Actualizar al guardar (Update on Save) que se ejecutará cada vez que modifiquemos datos, o actualización programada (Update on Schedule) que ejecutará el proceso programado cuando nosotros queramos.
Es importante conocer las dos modalidades de indexación porque entran muy en juego en cómo se actualiza también la información en buscadores externos a Magento como Elasticsearch, Doofinder o Algolia.
Elasticsearch
La primera opción a tener en cuenta si no queremos depender de servicios externos y de pago.
Elasticsearch está basado en un modelo de negocio Open Source, así que también podemos descargarlo y instalarlo en nuestra propia infraestructura. En mi caso, creamos un servidor adicional y exclusivo para Elasticsearch y, desde Magento, conectamos a la instancia del buscador.
Basta con indicarle el host, el puerto y el prefijo del índice. Magento se encargará de enviarle la información para que elastic la tenga almacenada en su motor, y Elastic devolverá los resultados cuando el usuario haga una búsqueda. Todo de forma rápida y transparente.
Aunque la mejora interna y del buscador es indiscutible respecto a la opción MySQL, la parte visual y la personalización de Elastic siguen un poco limitadas y son complejas de modificar. Una opción a tener en cuenta es utilizar plugins como Elastic Search for Magento 2 de Amasty que permite, entre otras cosas, configurar el autocompletado, utilizar sinónimos y búsqueda personalizable con atributos y el peso de los mismos.
Una de las grandes ventajas es que al tratarse de un motor de búsqueda que puedes instalar en tus servidor sin depender de otros, el precio se reduce significativamente. A cambio, tendrás que mantener el servicio, actualizarlo y quizá perder más tiempo configurándolo, pero tienes el control absoluto del mismo y no tendrás un susto en la factura si pasas de 5.000 SKU a 100 o 200.000 como era nuestro caso.
Doofinder
Se trata de un buscador inteligente, de los que puedes añadir y configurar en el Frontend en pocos minutos y con una simple llamada a un JavaScript. Ofrecen un plugin para Magento 2 que se encarga de enviar via API los productos a sus servidores para procesarlos y ofrecerte de vuelta los resultados de cada búsqueda.
El proceso es realmente sencillo y funciona a la primera. Creas un buscador, configuras las claves de la API, instalas el módulo de Doofinder para Magento y poca cosa más. Eso si, hay que repasar bien el manual oficial del módulo doofinder-magento2.
Hace tiempo tenían un método de integración mediante feeds (como el Feed URL que se ve en la imagen) pero en breve será eliminado. El método principal es a través de su API Rest.
Además de filtros y sugerencias, también puedes configurar qué campos de tus productos y con qué “peso” se utilizarán para las búsquedas.
Lo importante a tener en cuenta es que el módulo de Doofinder, a través del cron de Magento, envía los datos de los productos a su motor de búsqueda. Tras un primer envío, hay que cambiar la configuración del indexer a Update on Save para que cualquier actualización sea enviada a Doofinder, quien cobra por uso de su API, así que este método reduce el número de peticiones.
Actualización a 16 de marzo de 2020 Desde Doofinder me comentan que están trabajando en una nueva versión que incluirá una implementación del Instant Search similar a la de Algolia, con la que permitirán una capa de personalización superior a la actual, logrando un resultado similar al del Instantsearch.js. En cuanto pueda probarlo volveré a actualizar el post.
Cuidado, porque si cambiamos el método de indexación a Update on Schedule, Doofinder reindexará todo el contenido y además nos cobrará por todas las peticiones enviadas. No recomiendan esta opción. El módulo, por otra parte, se asegura de cambiar la configuración a Update on Save tras la primera actualización.
Antes de integrar Doofinder, asegurate de entender bien cómo funciona el workflow de integración para evitar que choque con alguno de tus módulos o integraciones.
Debo añadir que tienen un soporte técnico muy bueno y rápido. También en español. Además de ayudarte en el proceso de integración, resuelven muy bien cualquier tipo de duda que tengas y se adaptan todo lo que pueden a tus problemas o necesidades. A nosotros nos ampliaron el periodo de prueba tras tener algunos problemas y fueron comprensivos en todo momento.
Por desgracia, en nuestro caso en concreto, el sistema de actualización de artículos de Magento necesitaba atacar directamente la base de datos y no podíamos ejecutar la actualización con el Update on Save de Magento.
Algolia
Algolia nos pareció algo más maduro y fiable, así que decidimos probarlo incluso sabiendo que probablemente se nos escaparía de presupuesto. Todo estaba encima de la mesa. Como comentaba, un buen buscador es clave para un buen retorno en ventas. Si sabemos lo que buscamos, utilizamos el buscador. No la navegación por categorías.
El plugin para Magento 2 tiene una página en Github más quedecente, con actualizaciones constantes y varios participantes. Ver cosas como esta nos garantiza que, desactualizado, no lo está.
Algolia es quizá el más completo de todos. La documentación oficial es ordenada, limpia y no le falta nada! Al igual que Doofinder, Algolia también se configura con Magento a través de clave de API. El módulo se puede descargar de forma gratuita a través del Marketplace de Magento
Recomiendo probar la demo que tienen publicada con un Magento y la plantilla Luma. En ella podemos ver lo rápido que aparecen los resultados y lo robusta que es la visualización en todo tipo de dispositivos, punto también muy imporante.
Algolia tiene una ventaja frente a Doofinder que nos pareció muy interesante, y es que tras plantearles el problema de la actualización directa de infomación de Magento en la base de datos (algo que Doofinder no podía detectar al funcionar exclusivamente con el indexer de Magento) nos comentaron que el plugin de Algolia era capaz de detectar los cambios de datos en la BBDD de Magento a través de un campo de última actualización, lo cual solucionaba esa problemática.
El buscador SaaS más completo que hemos encontrado.
Algolia es enorme. Muy potente. Tiene una interfaz muy cuidada y da una sensación de robustez que es lo que necesita un cliente de eCommerce.
Gestión de índices, reglas, analítica, monitorización,… basta con verlo y probarlo. Puedes hacerlo durante 14 días.
Instantsearch.js
Otra cosa muy chula que tiene Algolia es la librería instantsearch.js con la que podemos personalizar prácticamente al completo la experiéncia de usuario en las búsquedas en tiempo real. Algo que no encontramos en Doofinder y que es bastante más complejo y limitado en Elasticsearch. Incomparable, diría yo.
Conclusión
Aunque Algolia y Doofinder son bastante intuitivos, potentes y rápidos, al final nos decantamos por Elasticsearch. Nuestro caso era un poco peculiar porque teníamos más de 50.000 productos con previsión de llegar a 100.000, además de una actualización de precios constante y la necesidad de controlar de forma muy precisa el indexado y renderizado de resultados. Nuestros requisitos son de cambio constante, por eso necesitamos algo que podamos trastear, no un SaaS.
Por otra parte, sabemos que en un futuro es posible que debamos cambiar, así que aunque nos quedamos de momento con Elastic, estamos preparados para, si se da el caso, migrar rápidamente a uno tipo SaaS.
Si no tienes un eCommerce muy peculiar y personalizado como el nuestro, seguramente Algolia y Doofinder sean una gran opción a tener en cuenta. Como en todo, el producto ideal para todos los casos no existe.
La bala de plata no existe. Para cada proyecto nuevo que valoramos, volvemos a tener en cuenta todas estas opciones.
Presta también atención al precio porque son productos de pago por uso, y depende del número de productos y las llamadas a su API (entre otras cosas) el precio puede dispararse.
También hay que decir que detrás de estas dos empresas encontramos muy buenos profesionales técnicos que nos ayudaron en todo momento a implementar, probar y solucionar todo tipo de dudas. No te quedes con las ganas de probarlos.