{"id":5975,"date":"2020-10-08T09:01:25","date_gmt":"2020-10-08T09:01:25","guid":{"rendered":"https:\/\/bluetab.net\/?p=5975"},"modified":"2020-10-08T09:01:25","modified_gmt":"2020-10-08T09:01:25","slug":"como-depurar-una-lambda-de-aws-en-local","status":"publish","type":"post","link":"https:\/\/bluetab.net\/en\/2020\/10\/como-depurar-una-lambda-de-aws-en-local\/","title":{"rendered":"C\u00f3mo depurar una Lambda de AWS en local"},"content":{"rendered":"<h1>C\u00f3mo depurar una Lambda de AWS en local<\/h1>\n<figure><a href=\"https:\/\/www.linkedin.com\/company\/bluetab-solutions\/?viewAsMember=true\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" width=\"300\" height=\"300\" src=\"https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/avatarP-bluetab.jpg.png\" alt=\"\" loading=\"lazy\" srcset=\"https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/avatarP-bluetab.jpg.png 300w, https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/avatarP-bluetab.jpg-150x150.png 150w, https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/avatarP-bluetab.jpg-75x75.png 75w\" sizes=\"(max-width: 300px) 100vw, 300px\"><\/a><\/figure>\n<h4><a href=\"https:\/\/www.linkedin.com\/company\/bluetab-solutions\/?viewAsMember=true\" target=\"_blank\" rel=\"noopener\">Bluetab<\/a><\/h4>\n<p>Share on twitter<br \/>\nShare on linkedin<\/p>\n<p>AWS Lambda es un servicio serverless mediante el que se puede ejecutar c\u00f3digo sin necesidad de levantar ni administrar m\u00e1quinas. Se paga solamente por el tiempo consumido en la ejecuci\u00f3n (15 minutos como m\u00e1ximo).<\/p>\n<p>El servicio dispone de un IDE simple, pero por su propia naturaleza no permite a\u00f1adir puntos de ruptura para depurar el c\u00f3digo. Seguro que algunos de vosotros os hab\u00e9is visto en esta situaci\u00f3n y hab\u00e9is tenido que hacer uso de m\u00e9todos poco ortodoxos como prints o ejecutar el c\u00f3digo directamente en vuestra m\u00e1quina, pero esto \u00faltimo no reproduce las condiciones reales de ejecuci\u00f3n del servicio.<\/p>\n<p>Para permitir depurar con fiabilidad desde nuestro propio PC, AWS pone a disposici\u00f3n SAM (Serverless Application Model).<\/p>\n<p><strong>Instalaci\u00f3n<\/strong><\/p>\n<p>Los requisitos necesarios son (se ha usado Ubuntu 18.04 LTS):<\/p>\n<ul>\n<li>Python (2.7 \u00f3 &gt;= 3.6)<\/li>\n<li>Docker<\/li>\n<li>IDE que se pueda enlazar a un puerto de debug (en nuestro caso usamos VS Code)<\/li>\n<li>awscli<\/li>\n<\/ul>\n<p>Para instalar la CLI de AWS SAM desde AWS recomiendan brew tanto para Linux como macOS, pero en este caso se ha optado por hacerlo con pip por homogeneidad:<\/p>\n<pre><code class=\"language-python\">python3 -m pip install aws-sam-cli <\/code><\/pre>\n<h2>Configuraci\u00f3n y ejecuci\u00f3n<\/h2>\n<p><strong>1. Iniciamos un proyecto SAM<\/strong><\/p>\n<pre><code class=\"language-solid\">sam init <\/code><\/pre>\n<ul>\n<li>Por simplicidad se selecciona \u201cAWS Quick Start Templates\u201d para crear un proyecto a trav\u00e9s de plantillas predefinidas<\/li>\n<li>Se elige la opci\u00f3n 9 \u2013 python3.6 como el lenguaje del c\u00f3digo que contendr\u00e1 nuestra lambda<\/li>\n<li>Se selecciona la plantilla de \u201cHello World Example\u00bb<\/li>\n<\/ul>\n<p><img decoding=\"async\" width=\"768\" height=\"729\" src=\"https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/sam-init-768x729.png\" alt=\"\" loading=\"lazy\" srcset=\"https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/sam-init-768x729.png 768w, https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/sam-init-300x285.png 300w, https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/sam-init.png 825w\" sizes=\"(max-width: 768px) 100vw, 768px\"><\/p>\n<p>En este momento ya tenemos nuestro proyecto creado en la ruta especificada:<\/p>\n<ul>\n<li><strong>\/helloworld<\/strong>: app.py con el c\u00f3digo Python a ejecutar y requirements.txt con sus dependencias<\/li>\n<li><strong>\/events<\/strong>: events.json con ejemplo de evento a enviar a la lambda para su ejecuci\u00f3n. En nuestro caso el trigger ser\u00e1 un GET a la API a&nbsp;<a href=\"http:\/\/localhost:3000\/hello\">http:\/\/localhost:3000\/hello<\/a><\/li>\n<li><strong>\/tests<\/strong>&nbsp;: test unitario<\/li>\n<li><strong>template.yaml<\/strong>: plantilla con los recursos de AWS a desplegar en formato YAML de CloudFormation. En esta aplicaci\u00f3n de ejemplo ser\u00eda un API gateway + lamba y se emular\u00e1 ese despliegue localmente<\/li>\n<\/ul>\n<p><strong>2. Se levanta la API en local y se hace un GET al endpoint<\/strong><\/p>\n<pre><code class=\"language-python\">sam local start-api <\/code><\/pre>\n<p>Concretamente el endpoint de nuestro HelloWorld<br \/>\nser\u00e1 <a href=\"http:\/\/localhost:3000\/hello\">http:\/\/localhost:3000\/hello<\/a>&nbsp;Hacemos un GET<\/p>\n<p><img decoding=\"async\" width=\"424\" height=\"120\" src=\"https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/get-api.png\" alt=\"\" loading=\"lazy\" srcset=\"https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/get-api.png 424w, https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/get-api-300x85.png 300w\" sizes=\"(max-width: 424px) 100vw, 424px\"><\/p>\n<p>Y obtenemos la respuesta de la API<\/p>\n<p><img decoding=\"async\" width=\"768\" height=\"195\" src=\"https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/event-invokation-768x195.png\" alt=\"\" loading=\"lazy\" srcset=\"https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/event-invokation-768x195.png 768w, https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/event-invokation-300x76.png 300w, https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/event-invokation.png 884w\" sizes=\"(max-width: 768px) 100vw, 768px\"><\/p>\n<p><strong>3. A\u00f1adimos la librer\u00eda ptvsd (Python Tools for Visual Studio) para debugging a requirements.txt quedando como:<\/strong><\/p>\n<pre><code class=\"language-python\">requests\nptvsd <\/code><\/pre>\n<p><strong>4. Habilitamos el modo debug en el puerto 5890 haciendo uso del siguiente c\u00f3digo en helloworld\/app.py<\/strong><\/p>\n<pre><code class=\"language-python\">import ptvsd\nptvsd.enable_attach(address=('0.0.0.0', 5890), redirect_output=True)\nptvsd.wait_for_attach() <\/code><\/pre>\n<p>A\u00f1adimos tambi\u00e9n en app.py dentro de la funci\u00f3n lambda_handler varios prints para usar en la depuraci\u00f3n<\/p>\n<pre><code class=\"language-python\">print('punto de ruptura')\nprint('siguiente l\u00ednea')\nprint('contin\u00faa la ejecuci\u00f3n')\nreturn {\n    \"statusCode\": 200,\n    \"body\": json.dumps({\n        \"message\": \"hello world\",\n        # \"location\": ip.text.replace(\"n\", \"\")\n    }),\n} <\/code><\/pre>\n<p><strong>5. Aplicamos los cambios realizados y construimos el contenedor<\/strong><\/p>\n<pre><code class=\"language-python\">sam build --use-container <\/code><\/pre>\n<p><img decoding=\"async\" width=\"850\" height=\"400\" src=\"https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/build-succeeded.png\" alt=\"\" loading=\"lazy\" srcset=\"https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/build-succeeded.png 850w, https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/build-succeeded-300x141.png 300w, https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/build-succeeded-768x361.png 768w\" sizes=\"(max-width: 850px) 100vw, 850px\"><\/p>\n<p><strong>6. Configuramos el debugger de nuestro IDE<\/strong><\/p>\n<p>En VSCode se utiliza el fichero launch.json. Creamos en la ruta principal de nuestro proyecto la carpeta .vscode y dentro el fichero<\/p>\n<pre><code class=\"language-python\">{\n  \"version\": \"0.2.0\",\n  \"configurations\": [\n      {\n          \"name\": \"SAM CLI Python Hello World\",\n          \"type\": \"python\",\n          \"request\": \"attach\",\n          \"port\": 5890,\n          \"host\": \"127.0.0.1\",\n          \"pathMappings\": [\n              {\n                  \"localRoot\": \"${workspaceFolder}\/hello_world\",\n                  \"remoteRoot\": \"\/var\/task\"\n              }\n          ]\n      }\n  ]\n} <\/code><\/pre>\n<p><strong>7. Establecemos un punto de ruptura en el c\u00f3digo en nuestro IDE<\/strong><\/p>\n<p><img decoding=\"async\" width=\"742\" height=\"845\" src=\"https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/breakpoint.png\" alt=\"\" loading=\"lazy\" srcset=\"https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/breakpoint.png 742w, https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/breakpoint-263x300.png 263w\" sizes=\"(max-width: 742px) 100vw, 742px\"><\/p>\n<p><strong>8. Levantamos nuestra aplicaci\u00f3n con la API en el puerto de debug<\/strong><\/p>\n<pre><code class=\"language-python\">sam local start-api --debug-port 5890 <\/code><\/pre>\n<p><strong>9. Hacemos de nuevo un GET a la URL del endpoint&nbsp;<a href=\"http:\/\/localhost:3000\/hello\">http:\/\/localhost:3000\/hello<\/a><\/strong><\/p>\n<p><strong>10. Lanzamos la aplicaci\u00f3n desde VSCode en modo debug, seleccionando la configuraci\u00f3n creada en launch.json<\/strong><\/p>\n<p><img decoding=\"async\" width=\"880\" height=\"604\" src=\"https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/debug-vscode.png\" alt=\"\" loading=\"lazy\" srcset=\"https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/debug-vscode.png 880w, https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/debug-vscode-300x206.png 300w, https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/debug-vscode-768x527.png 768w\" sizes=\"(max-width: 880px) 100vw, 880px\"><\/p>\n<p>Y ya estamos en modo debug, pudiendo avanzar desde nuestro punto de ruptura<\/p>\n<p><img decoding=\"async\" width=\"1024\" height=\"733\" src=\"https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/breakpoint-debugging-1024x733.png\" alt=\"\" loading=\"lazy\" srcset=\"https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/breakpoint-debugging-1024x733.png 1024w, https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/breakpoint-debugging-300x215.png 300w, https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/breakpoint-debugging-768x550.png 768w, https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/breakpoint-debugging.png 1099w\" sizes=\"(max-width: 1024px) 100vw, 1024px\"><\/p>\n<h5><strong>Alternativa: Se puede hacer uso de events\/event.json para lanzar la lambda a trav\u00e9s de un evento definido por nosotros<\/strong><\/h5>\n<p>En este caso lo modificamos incluyendo un solo par\u00e1metro de entrada:<\/p>\n<pre><code class=\"language-python\">{\n   \"numero\": \"1\"\n} <\/code><\/pre>\n<h5>Y el c\u00f3digo de nuestra funci\u00f3n para hacer uso del evento:<\/h5>\n<pre><code class=\"language-python\">print('punto de ruptura n\u00famero: ' + event[\"numero\"]) <\/code><\/pre>\n<h5>De esta manera, invocamos a trav\u00e9s del evento en modo debug:<\/h5>\n<pre><code class=\"language-python\">sam local invoke HelloWorldFunction -d 5890 -e events\/event.json <\/code><\/pre>\n<h5>Podemos ir depurando paso a paso, viendo como en este caso se hace uso del evento creado:<\/h5>\n<p><img decoding=\"async\" width=\"796\" height=\"159\" src=\"https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/api-get.png\" alt=\"\" loading=\"lazy\" srcset=\"https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/api-get.png 796w, https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/api-get-300x60.png 300w, https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/api-get-768x153.png 768w\" sizes=\"(max-width: 796px) 100vw, 796px\"><\/p>\n<h5>\u00bfQuieres saber m\u00e1s de lo que ofrecemos y ver otros casos de \u00e9xito?<\/h5>\n<p><a href=\"\/\" role=\"button\"><br \/>\nDESCUBRE BLUETAB<br \/>\n<\/a><br \/>\nShare on twitter<br \/>\nShare on linkedin<\/p>\n<p><b>SOLUCIONES, <\/b>SOMOS EXPERTOS<\/p>\n<p><a href=\"\/soluciones\/data-strategy\/\"><\/a><\/p>\n<p><a href=\"\/soluciones\/data-strategy\/\"><\/p>\n<h5>\n\t\t\t\t\t\tDATA STRATEGY<\/h5>\n<p><\/a><a href=\"\/soluciones\/data-strategy\/\">\t\t\t\t\t\t<\/a><br \/>\n<a href=\"\/soluciones\/data-fabric\/\"><\/a><\/p>\n<p><a href=\"\/soluciones\/data-fabric\/\"><\/p>\n<h5>\n\t\t\t\t\t\tDATA FABRIC<\/h5>\n<p><\/a><a href=\"\/soluciones\/data-fabric\/\">\t\t\t\t\t\t<\/a><br \/>\n<a href=\"\/soluciones\/augmented-analytics\/\"><\/a><\/p>\n<p><a href=\"\/soluciones\/augmented-analytics\/\"><\/p>\n<h5>\n\t\t\t\t\t\tAUGMENTED ANALYTICS<\/h5>\n<p><\/a><a href=\"\/soluciones\/augmented-analytics\/\">\t\t\t\t\t\t<\/a><\/p>\n<p>Te puede interesar<\/p>\n","protected":false},"excerpt":{"rendered":"<p>C\u00f3mo depurar una Lambda de AWS en local Bluetab Share on twitter Share on linkedin AWS Lambda es un servicio serverless mediante el que se puede ejecutar c\u00f3digo sin necesidad de levantar ni administrar m\u00e1quinas. Se paga solamente por el tiempo consumido en la ejecuci\u00f3n (15 minutos como m\u00e1ximo). El servicio dispone de un IDE [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":20764,"comment_status":"open","ping_status":"open","sticky":false,"template":"elementor_header_footer","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[7,30],"tags":[],"class_list":["post-5975","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog-es","category-tech-en"],"acf":[],"jetpack_featured_media_url":"https:\/\/bluetab.net\/wp-content\/uploads\/2020\/10\/blog-jose-ramon-monteverde.png","_links":{"self":[{"href":"https:\/\/bluetab.net\/en\/wp-json\/wp\/v2\/posts\/5975","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bluetab.net\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bluetab.net\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bluetab.net\/en\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/bluetab.net\/en\/wp-json\/wp\/v2\/comments?post=5975"}],"version-history":[{"count":0,"href":"https:\/\/bluetab.net\/en\/wp-json\/wp\/v2\/posts\/5975\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/bluetab.net\/en\/wp-json\/wp\/v2\/media\/20764"}],"wp:attachment":[{"href":"https:\/\/bluetab.net\/en\/wp-json\/wp\/v2\/media?parent=5975"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bluetab.net\/en\/wp-json\/wp\/v2\/categories?post=5975"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bluetab.net\/en\/wp-json\/wp\/v2\/tags?post=5975"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}