<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Serverless on thomaspaulin.me</title><link>https://thomaspaulin.me/tags/serverless/</link><description>Serverless</description><generator>Hugo -- gohugo.io</generator><language>en-nz</language><lastBuildDate>Sat, 27 Apr 2024 00:00:00 +0000</lastBuildDate><atom:link href="https://thomaspaulin.me/tags/serverless/index.xml" rel="self" type="application/rss+xml"/><item><title>How to write a Python Lambda function in AWS CDK (without Docker)</title><link>https://thomaspaulin.me/2024/04/how-to-write-a-python-lambda-function-in-aws-cdk-without-docker/</link><pubDate>Sat, 27 Apr 2024 00:00:00 +0000</pubDate><guid>https://thomaspaulin.me/2024/04/how-to-write-a-python-lambda-function-in-aws-cdk-without-docker/</guid><description>&lt;p>Most of the time you when you write Python code for AWS Lambda Functions you&amp;rsquo;ll include external dependencies such as &lt;a href="https://boto3.amazonaws.com/v1/documentation/api/latest/index.html">boto3&lt;/a>.
There are two approaches you can take to including those dependencies.&lt;/p>
&lt;ol>
&lt;li>You create a Docker-based function and run &lt;code>pip install&lt;/code> or otherwise within the image build process.&lt;/li>
&lt;li>You create a zip file containing your code and the appropriate vendor code e.g. you bundle your virtualenv&amp;rsquo;s &lt;code>site-packages&lt;/code> folder and configure your &lt;code>PYTHONPATH&lt;/code> as appropriate.&lt;/li>
&lt;li>Bonus: You take the same approach as 2. but put some of your dependencies as layers for re-use across different AWS Lambda functions. As of April 2024 you may only have five (5) layers so choose wisely.&lt;/li>
&lt;/ol>
&lt;p>If you use AWS CDK there is a fourth option in the form of the &lt;code>PythonFunction&lt;/code> construct, provided via the &lt;a href="https://docs.aws.amazon.com/cdk/api/v2/docs/aws-lambda-python-alpha-readme.html">aws-lambda-python-alpha module&lt;/a>. This construct will bundle your dependencies automatically if it detects a &lt;code>requirements.txt&lt;/code>, &lt;code>Pipfile&lt;/code>, or &lt;code>poetry.lock&lt;/code> file.&lt;/p>
&lt;p>A brief example of what using this construct might look like is shown below.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">aws_cdk.aws_lambda&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl"> &lt;span class="n">Runtime&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">aws_cdk.aws_lambda_python_alpha&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">BundlingOptions&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">PythonFunction&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">&lt;span class="n">python&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">PythonFunction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="bp">self&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;MyFunction&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> &lt;span class="n">entry&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;/path/to/lambda/handler/module&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># required&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl"> &lt;span class="n">runtime&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">Runtime&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">PYTHON_3_12&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># required&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl"> &lt;span class="n">index&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;my_index.py&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># optional, defaults to &amp;#39;index.py&amp;#39;, the file containing your lambda handler function&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl"> &lt;span class="n">handler&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;my_lambda_handler_func&amp;#34;&lt;/span> &lt;span class="c1"># required&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl"> &lt;span class="n">bundling&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">BundlingOptions&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl"> &lt;span class="n">asset_excludes&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;.pytest_cache&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;__pycache__&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;...&amp;#34;&lt;/span>&lt;span class="p">],&lt;/span> &lt;span class="c1"># the paths to exclude from the final product, I like to omit what isn&amp;#39;t relevant to the final runtime&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl"> &lt;span class="n">poetry_include_hashes&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">False&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># when generating outputs like requirements.txt Poetry will produce hashes by default, you may wish to turn them off&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">15&lt;/span>&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">16&lt;/span>&lt;span class="cl"> &lt;span class="c1"># other properties from the aws_cdk.aws_lambda.Function class can be used too&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">17&lt;/span>&lt;span class="cl">&lt;span class="p">)&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item></channel></rss>