<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>TomsBlog</title>
    <link>http://www.toms-blog.com/tags/python/index.xml</link>
    <description>Recent content on TomsBlog</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-uk</language>
    <atom:link href="http://www.toms-blog.com/tags/python/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>Deluge RPC Client Python</title>
      <link>http://www.toms-blog.com/post/deluge-rpc-client-python/</link>
      <pubDate>Thu, 21 Feb 2019 23:57:14 +0000</pubDate>
      
      <guid>http://www.toms-blog.com/post/deluge-rpc-client-python/</guid>
      <description>

&lt;h2 id=&#34;installing&#34;&gt;Installing&lt;/h2&gt;

&lt;p&gt;Deluge is a torrent client written in python. It however has an RPC API so you can interact with it remotely.
Using this API you can add, delete and gather status reports on torrents, you can therefore produce a nice looking frontend for it.
It is worth pointing out that there is a web interface for it already called deluge-web.&lt;/p&gt;

&lt;p&gt;The package on Ubuntu is simply deluge:&lt;/p&gt;

&lt;div class=&#34;highlight&#34; style=&#34;background: #f0f3f3&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;sudo apt update
sudo apt install -y deluge
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;There is a python client to make it easier to interact with the deluge RPC client which we will use.&lt;/p&gt;

&lt;p&gt;This can be installed through pip:&lt;/p&gt;

&lt;div class=&#34;highlight&#34; style=&#34;background: #f0f3f3&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;pip3 install deluge-client
&lt;/pre&gt;&lt;/div&gt;


&lt;h2 id=&#34;basic-code&#34;&gt;Basic Code&lt;/h2&gt;

&lt;p&gt;The following is the minimum code you need to connect to the RPC server:&lt;/p&gt;

&lt;div class=&#34;highlight&#34; style=&#34;background: #f0f3f3&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&#34;color: #006699; font-weight: bold&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color: #00CCFF; font-weight: bold&#34;&gt;deluge_client&lt;/span&gt; &lt;span style=&#34;color: #006699; font-weight: bold&#34;&gt;import&lt;/span&gt; DelugeRPCClient

delugeClient &lt;span style=&#34;color: #555555&#34;&gt;=&lt;/span&gt; DelugeRPCClient(&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;127.0.0.1&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color: #FF6600&#34;&gt;58846&lt;/span&gt;, &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;username&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;password&amp;#39;&lt;/span&gt;)
delugeClient&lt;span style=&#34;color: #555555&#34;&gt;.&lt;/span&gt;connect()
&lt;span style=&#34;color: #006699; font-weight: bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color: #000000; font-weight: bold&#34;&gt;not&lt;/span&gt; delugeClient&lt;span style=&#34;color: #555555&#34;&gt;.&lt;/span&gt;connected:
    &lt;span style=&#34;color: #006699; font-weight: bold&#34;&gt;raise&lt;/span&gt; &lt;span style=&#34;color: #CC0000; font-weight: bold&#34;&gt;Exception&lt;/span&gt;(&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;Error connecting to Deluge Daemon&amp;quot;&lt;/span&gt;)
&lt;/pre&gt;&lt;/div&gt;


&lt;h2 id=&#34;running-a-function&#34;&gt;Running a function&lt;/h2&gt;

&lt;p&gt;The following doc shows the RPC call:
&lt;a href=&#34;https://deluge.readthedocs.io/en/develop/reference/rpc.html&#34;&gt;https://deluge.readthedocs.io/en/develop/reference/rpc.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The following snippet from that doc shows the RPC function call format:&lt;/p&gt;

&lt;div class=&#34;box&#34;&gt;
&lt;p&gt;&lt;strong&gt;[[request_id, method, [args], {kwargs}], …]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;request_id (int)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An integer determined by the client that is used in replies from the server. This is used to ensure the client knows which request the data is in response to. Another alternative would be to respond in the same order the requests come in, but this could cause lag if an earlier request takes longer to process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;method (str)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The name of the remote method to call. This name can be in dotted format to call other objects or plugins methods.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;args (list)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The arguments to call the method with.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;kwargs (dict)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The keyword arguments to call the method with.&lt;/p&gt;

&lt;/div&gt;

&lt;p&gt;The request_id is taken care of by the plugin therefore all we have to put in is the method the args and the kwargs.
A list of methods and their inputs can be found here:&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;https://deluge.readthedocs.io/en/develop/reference/api.html&#34;&gt;https://deluge.readthedocs.io/en/develop/reference/api.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can now get an object of torrents currently in Deluge.&lt;/p&gt;

&lt;div class=&#34;highlight&#34; style=&#34;background: #f0f3f3&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;torrent &lt;span style=&#34;color: #555555&#34;&gt;=&lt;/span&gt; delugeClient&lt;span style=&#34;color: #555555&#34;&gt;.&lt;/span&gt;call(&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;core.get_torrents_status&amp;#39;&lt;/span&gt;, {}, [])
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This returns a python object of each torrent, for each torrent there are a lot of keys but here are some of the more interesting ones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;name&lt;/li&gt;
&lt;li&gt;state&lt;/li&gt;
&lt;li&gt;progress&lt;/li&gt;
&lt;li&gt;total_size&lt;/li&gt;
&lt;li&gt;download_payload_rate&lt;/li&gt;
&lt;li&gt;upload_payload_rate&lt;/li&gt;
&lt;li&gt;eta&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is worth noting that the keys in the object that is returned are in binary and not string format.
You therefore need to convert them by looping through and converting bytes to str.
The below code is an example of this&lt;/p&gt;

&lt;div class=&#34;highlight&#34; style=&#34;background: #f0f3f3&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&#34;color: #006699; font-weight: bold&#34;&gt;for&lt;/span&gt; key1, value1 &lt;span style=&#34;color: #000000; font-weight: bold&#34;&gt;in&lt;/span&gt; torrent&lt;span style=&#34;color: #555555&#34;&gt;.&lt;/span&gt;items():
	torrents&lt;span style=&#34;color: #555555&#34;&gt;=&lt;/span&gt;[]
	new_torrent&lt;span style=&#34;color: #555555&#34;&gt;=&lt;/span&gt;{}
	&lt;span style=&#34;color: #006699; font-weight: bold&#34;&gt;for&lt;/span&gt; key, value &lt;span style=&#34;color: #000000; font-weight: bold&#34;&gt;in&lt;/span&gt; value1&lt;span style=&#34;color: #555555&#34;&gt;.&lt;/span&gt;items():
		&lt;span style=&#34;color: #006699; font-weight: bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color: #336666&#34;&gt;isinstance&lt;/span&gt;(value, &lt;span style=&#34;color: #336666&#34;&gt;bytes&lt;/span&gt;):
			value &lt;span style=&#34;color: #555555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color: #336666&#34;&gt;str&lt;/span&gt;(value)&lt;span style=&#34;color: #555555&#34;&gt;.&lt;/span&gt;replace(&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;b&amp;#39;&amp;quot;&lt;/span&gt;, &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;)&lt;span style=&#34;color: #555555&#34;&gt;.&lt;/span&gt;replace(&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;&amp;#39;&amp;quot;&lt;/span&gt;, &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;)&lt;span style=&#34;color: #555555&#34;&gt;.&lt;/span&gt;replace(&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;b&amp;quot;&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;)&lt;span style=&#34;color: #555555&#34;&gt;.&lt;/span&gt;replace(&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;&amp;quot;&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;)
		new_torrent[&lt;span style=&#34;color: #336666&#34;&gt;str&lt;/span&gt;(key)&lt;span style=&#34;color: #555555&#34;&gt;.&lt;/span&gt;replace(&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;b&amp;#39;&amp;quot;&lt;/span&gt;, &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;)&lt;span style=&#34;color: #555555&#34;&gt;.&lt;/span&gt;replace(&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;&amp;#39;&amp;quot;&lt;/span&gt;, &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;)] &lt;span style=&#34;color: #555555&#34;&gt;=&lt;/span&gt; value
		torrents&lt;span style=&#34;color: #555555&#34;&gt;.&lt;/span&gt;append(new_torrent)
&lt;/pre&gt;&lt;/div&gt;

</description>
    </item>
    
    <item>
      <title>PCAP Python analyser with JSON d3 visualisation</title>
      <link>http://www.toms-blog.com/post/pcap-python-with-json-d3-visualisation/</link>
      <pubDate>Sat, 09 Dec 2017 11:14:51 +0000</pubDate>
      
      <guid>http://www.toms-blog.com/post/pcap-python-with-json-d3-visualisation/</guid>
      <description>

&lt;p&gt;I have been in a few environments where installing a full blown PCAP analyser is just not possible.
Therefore I created a Python script that will go through a PCAP file, split up IP flows and spit it out in a JSON format.
This depicts TCP and UDP flows with the amount of traffic uploaded and downloaded, it also attempts to map IP addresses to domains using DNS requests found in the same PCAP file.&lt;/p&gt;

&lt;p&gt;Having it in the this format then allows it to be easily visualised using something like d3.&lt;/p&gt;

&lt;p&gt;The code can be found here:&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;https://github.com/thomasweaver/pcap-visualizer&#34; title=&#34;PCAP Json Visualiser Github Page&#34;&gt;https://github.com/thomasweaver/pcap-visualizer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using the HTML files you can visualise the traffic with the forced graph, colour cordinating the traffic and showing flows that have downloaded or uploaded more in a bolder line.
The treemap allows you to drill down to IP address and port showing you the big hitters.&lt;/p&gt;

&lt;h1 id=&#34;requirements&#34;&gt;Requirements&lt;/h1&gt;

&lt;p&gt;Python Scapy is required which can be installed with pip:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pip install scapy
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Other packages that are required but are installed by default with python:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;os&lt;/li&gt;
&lt;li&gt;sys&lt;/li&gt;
&lt;li&gt;json&lt;/li&gt;
&lt;li&gt;hashlib&lt;/li&gt;
&lt;li&gt;copy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The HTML files get the d3 javascript files from the below URL&amp;rsquo;s:
* d3js.org/d3.v4.min.js
* d3js.org/d3-selection-multi.v1.js
* d3js.org/d3.v3.min.js&lt;/p&gt;

&lt;h1 id=&#34;using&#34;&gt;Using&lt;/h1&gt;

&lt;p&gt;Locate the folder that contains your PCAP file and run the python script&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pcap-analyzer.py C:\my-pcap-files\
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The script will then loop through all the pcap files in this folder. Try to make sure the PCAP file are named appropriately so that they are parsed chronologically this will ensure the DNS mapping will be as accurate as possible.&lt;/p&gt;

&lt;p&gt;This will create 2 JSON files:
* output.json - This is the main json file which can be used to visualise the data
* dnsMapping.json - This is the IP address to DNS name mappings. The script finds DNS requests in the pcap and maps IP addresses to domain names. This is the output of that mapping&lt;/p&gt;

&lt;p&gt;You can then use the below command to launch a simple web server:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;python -m SimpleHTTPServer
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then access the force map on the below url:
&lt;a href=&#34;http://127.0.0.1:8000/forced.html&#34;&gt;http://127.0.0.1:8000/forced.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and the treemap on:
&lt;a href=&#34;http://127.0.0.1:8000/treemap.html&#34;&gt;http://127.0.0.1:8000/treemap.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The d3 Treemap visualisation is based on &lt;a href=&#34;http://bl.ocks.org/ganeshv/6a8e9ada3ab7f2d88022&#34;&gt;http://bl.ocks.org/ganeshv/6a8e9ada3ab7f2d88022&lt;/a&gt;
THe d3 forced graph is based on various examples on &lt;a href=&#34;http://bl.ocks.org&#34;&gt;http://bl.ocks.org&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&#34;screenshots&#34;&gt;Screenshots:&lt;/h1&gt;

&lt;p&gt;&lt;img src=&#34;http://www.toms-blog.com/images/posts/pcap-visualiser/forced-screenshot.JPG&#34; alt=&#34;PCAP Analyser d3 Forced Graph&#34; /&gt;
&lt;img src=&#34;http://www.toms-blog.com/images/posts/pcap-visualiser/treemap-screenshot.JPG&#34; alt=&#34;PCAP Analyser d3 Treemap Graph&#34; /&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>AWS send email with Lambda and SES</title>
      <link>http://www.toms-blog.com/post/aws-send-email-with-lambda-and-ses/</link>
      <pubDate>Thu, 10 Nov 2016 20:20:18 +0000</pubDate>
      
      <guid>http://www.toms-blog.com/post/aws-send-email-with-lambda-and-ses/</guid>
      <description>

&lt;h2 id=&#34;lambda&#34;&gt;Lambda&lt;/h2&gt;

&lt;p&gt;&lt;img src=&#34;http://www.toms-blog.com/images/posts/aws/Compute_AWSLambda.png&#34; alt=&#34;Lamda AWS icon&#34; /&gt;
Lambda is an AWS feature that allows you to run functions based on triggers such as API calls, SNS events or s3 file uploads.
The advantage of Lambda is Amazon takes care of all the infrastructure for you so all you have to care about is the function. Amazon will elastically spin the infrastructure up and down to accommodate the load and even better will only charge you for the time your function is running.
Nodejs, Python and Java are all supported, the below example is written in python but there are plenty of other language examples out there.&lt;/p&gt;

&lt;h2 id=&#34;ses&#34;&gt;SES&lt;/h2&gt;

&lt;p&gt;&lt;img src=&#34;http://www.toms-blog.com/images/posts/aws/Application-Services_AmazonSES.png&#34; alt=&#34;SES AWS icon&#34; /&gt;
SES is Amazons email offering allowing you send or receive email in your AWS account. It can be used for marketing campaigns or adhoc emails and basically any email needs.
As with Lambda you only pay for what you use. To send emails from a domain you have to verify your domain first by adding a TXT record on your DNS, this is all explained when setting up SES in your console.&lt;/p&gt;

&lt;h2 id=&#34;example&#34;&gt;Example&lt;/h2&gt;

&lt;p&gt;In this example we set up a lambda function to send an email to a predefined address using SES.
We have already set up SES and verified our domain by adding the TXT record provided.&lt;/p&gt;

&lt;p&gt;The example code below does minimum user input validation and is meant only as an example.&lt;/p&gt;

&lt;div class=&#34;highlight&#34; style=&#34;background: #f0f3f3&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&#34;color: #006699; font-weight: bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color: #00CCFF; font-weight: bold&#34;&gt;boto3&lt;/span&gt;
        
&lt;span style=&#34;color: #006699; font-weight: bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color: #CC00FF&#34;&gt;lamda_sendMessage&lt;/span&gt;(event, context):
    &lt;span style=&#34;color: #006699; font-weight: bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color: #000000; font-weight: bold&#34;&gt;not&lt;/span&gt; ((&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;subject&amp;#39;&lt;/span&gt; &lt;span style=&#34;color: #000000; font-weight: bold&#34;&gt;in&lt;/span&gt; event) &lt;span style=&#34;color: #000000; font-weight: bold&#34;&gt;and&lt;/span&gt; (&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;message&amp;#39;&lt;/span&gt; &lt;span style=&#34;color: #000000; font-weight: bold&#34;&gt;in&lt;/span&gt; event) &lt;span style=&#34;color: #000000; font-weight: bold&#34;&gt;and&lt;/span&gt; (&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;from&amp;#39;&lt;/span&gt; &lt;span style=&#34;color: #000000; font-weight: bold&#34;&gt;in&lt;/span&gt; event) &lt;span style=&#34;color: #000000; font-weight: bold&#34;&gt;and&lt;/span&gt; (&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;name&amp;#39;&lt;/span&gt; &lt;span style=&#34;color: #000000; font-weight: bold&#34;&gt;in&lt;/span&gt; event)):
        &lt;span style=&#34;color: #006699; font-weight: bold&#34;&gt;return&lt;/span&gt; {&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;code&amp;quot;&lt;/span&gt;: &lt;span style=&#34;color: #FF6600&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;message&amp;quot;&lt;/span&gt;: &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;Must preovide all values&amp;quot;&lt;/span&gt;}
    &lt;span style=&#34;color: #006699; font-weight: bold&#34;&gt;if&lt;/span&gt; event[&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;subject&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color: #555555&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt; &lt;span style=&#34;color: #000000; font-weight: bold&#34;&gt;and&lt;/span&gt; event[&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;message&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color: #555555&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt; &lt;span style=&#34;color: #000000; font-weight: bold&#34;&gt;and&lt;/span&gt; event[&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;from&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color: #555555&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt; &lt;span style=&#34;color: #000000; font-weight: bold&#34;&gt;and&lt;/span&gt; event[&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;name&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color: #555555&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;:
        toEmail &lt;span style=&#34;color: #555555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;email@domain.com&amp;quot;&lt;/span&gt;
        fromEmail &lt;span style=&#34;color: #555555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;email@domain.com&amp;quot;&lt;/span&gt;
        replyTo &lt;span style=&#34;color: #555555&#34;&gt;=&lt;/span&gt; event[&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;from&amp;#39;&lt;/span&gt;]
        name &lt;span style=&#34;color: #555555&#34;&gt;=&lt;/span&gt; event[&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;name&amp;#39;&lt;/span&gt;]
        subject &lt;span style=&#34;color: #555555&#34;&gt;=&lt;/span&gt; event[&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;subject&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color: #555555&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot; - &amp;quot;&lt;/span&gt; &lt;span style=&#34;color: #555555&#34;&gt;+&lt;/span&gt; name
        message &lt;span style=&#34;color: #555555&#34;&gt;=&lt;/span&gt; event[&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;message&amp;#39;&lt;/span&gt;]

        client &lt;span style=&#34;color: #555555&#34;&gt;=&lt;/span&gt; boto3&lt;span style=&#34;color: #555555&#34;&gt;.&lt;/span&gt;client(&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;ses&amp;#39;&lt;/span&gt;)
        response &lt;span style=&#34;color: #555555&#34;&gt;=&lt;/span&gt; client&lt;span style=&#34;color: #555555&#34;&gt;.&lt;/span&gt;send_email(
			Source&lt;span style=&#34;color: #555555&#34;&gt;=&lt;/span&gt;fromEmail,
			Destination&lt;span style=&#34;color: #555555&#34;&gt;=&lt;/span&gt;{
				&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;ToAddresses&amp;#39;&lt;/span&gt;: [
					toEmail,
				],
			},
			Message&lt;span style=&#34;color: #555555&#34;&gt;=&lt;/span&gt;{
				&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;Subject&amp;#39;&lt;/span&gt;: {
					&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;Data&amp;#39;&lt;/span&gt;: subject,
					&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;Charset&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;utf8&amp;#39;&lt;/span&gt;
				},
				&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;Body&amp;#39;&lt;/span&gt;: {
					&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;Text&amp;#39;&lt;/span&gt;: {
						&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;Data&amp;#39;&lt;/span&gt;: message,
						&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;Charset&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;utf8&amp;#39;&lt;/span&gt;
					}
				}
			},
			ReplyToAddresses&lt;span style=&#34;color: #555555&#34;&gt;=&lt;/span&gt;[
				replyTo
			]
		)
			
        &lt;span style=&#34;color: #006699; font-weight: bold&#34;&gt;print&lt;/span&gt; response[&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;MessageId&amp;#39;&lt;/span&gt;]
        &lt;span style=&#34;color: #006699; font-weight: bold&#34;&gt;return&lt;/span&gt; {&lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;code&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color: #FF6600&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;message&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;success&amp;#39;&lt;/span&gt;}
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The above code uses the boto client to send an email using the SES &amp;ldquo;send_email&amp;rdquo; function.
More on the SES boto API can be found here:&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;http://boto.cloudhackers.com/en/latest/ref/ses.html&#34;&gt;http://boto.cloudhackers.com/en/latest/ref/ses.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the function is setup we need to give the role the function runs under access to SES.
To do this go to &amp;ldquo;Identity and Access Management&amp;rdquo; then Roles and click on the Role associated with the function.
Click the Policy and put the below JSON into the Policy replacing the ID with your ARN ID.&lt;/p&gt;

&lt;p&gt;&lt;div class=&#34;highlight&#34; style=&#34;background: #f0f3f3&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;{
    &lt;span style=&#34;color: #330099; font-weight: bold&#34;&gt;&amp;quot;Version&amp;quot;&lt;/span&gt;: &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;2012-10-17&amp;quot;&lt;/span&gt;,
    &lt;span style=&#34;color: #330099; font-weight: bold&#34;&gt;&amp;quot;Statement&amp;quot;&lt;/span&gt;: [
        {
            &lt;span style=&#34;color: #330099; font-weight: bold&#34;&gt;&amp;quot;Effect&amp;quot;&lt;/span&gt;: &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;Allow&amp;quot;&lt;/span&gt;,
            &lt;span style=&#34;color: #330099; font-weight: bold&#34;&gt;&amp;quot;Action&amp;quot;&lt;/span&gt;: &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;logs:CreateLogGroup&amp;quot;&lt;/span&gt;,
            &lt;span style=&#34;color: #330099; font-weight: bold&#34;&gt;&amp;quot;Resource&amp;quot;&lt;/span&gt;: &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;arn:aws:logs:eu-west-1:ID:*&amp;quot;&lt;/span&gt;
        },
        {
            &lt;span style=&#34;color: #330099; font-weight: bold&#34;&gt;&amp;quot;Effect&amp;quot;&lt;/span&gt;: &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;Allow&amp;quot;&lt;/span&gt;,
            &lt;span style=&#34;color: #330099; font-weight: bold&#34;&gt;&amp;quot;Action&amp;quot;&lt;/span&gt;: [
                &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;logs:CreateLogStream&amp;quot;&lt;/span&gt;,
                &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;logs:PutLogEvents&amp;quot;&lt;/span&gt;
            ],
            &lt;span style=&#34;color: #330099; font-weight: bold&#34;&gt;&amp;quot;Resource&amp;quot;&lt;/span&gt;: [
                &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;arn:aws:logs:eu-west-1:ID:log-group:/aws/lambda/function:*&amp;quot;&lt;/span&gt;
            ]
        },
        {
            &lt;span style=&#34;color: #330099; font-weight: bold&#34;&gt;&amp;quot;Effect&amp;quot;&lt;/span&gt;: &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;Allow&amp;quot;&lt;/span&gt;,
            &lt;span style=&#34;color: #330099; font-weight: bold&#34;&gt;&amp;quot;Action&amp;quot;&lt;/span&gt;: [
                &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;cloudwatch:PutMetricData&amp;quot;&lt;/span&gt;
            ],
            &lt;span style=&#34;color: #330099; font-weight: bold&#34;&gt;&amp;quot;Resource&amp;quot;&lt;/span&gt;: &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;*&amp;quot;&lt;/span&gt;
        },
        {
            &lt;span style=&#34;color: #330099; font-weight: bold&#34;&gt;&amp;quot;Effect&amp;quot;&lt;/span&gt;: &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;Allow&amp;quot;&lt;/span&gt;,
            &lt;span style=&#34;color: #330099; font-weight: bold&#34;&gt;&amp;quot;Action&amp;quot;&lt;/span&gt;: [
                &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;ses:SendEmail&amp;quot;&lt;/span&gt;
            ],
            &lt;span style=&#34;color: #330099; font-weight: bold&#34;&gt;&amp;quot;Resource&amp;quot;&lt;/span&gt;: &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;quot;*&amp;quot;&lt;/span&gt;
        }
    ]
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;Now we have a Lambda function we need to trigger it, in this example we will be triggering it through an API.
To do this we need to implement Amazons API Gateway.&lt;/p&gt;

&lt;h2 id=&#34;api-gateway&#34;&gt;API Gateway&lt;/h2&gt;

&lt;p&gt;Create an API and then add a resource, in our case we will call the Resource &amp;ldquo;sendmessage&amp;rdquo;.
Add a POST type method, select lambda function then set your Lambda region and then your lambda function&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;http://www.toms-blog.com/images/posts/lambda-ses/setup-api-gateway-lambda.JPG&#34; alt=&#34;API Gateway POST method setup&#34; /&gt;&lt;/p&gt;

&lt;p&gt;This gives you the basic setup now you can deploy your API by clicking Actions-&amp;gt;Deploy API.
It will ask you which stage you want to deploy it to, just create a new one and deploy it.
Go to Stages click on your stage you created previously and there will be a URL you can invoke the API with, it will look something like this:&lt;/p&gt;

&lt;p&gt;https://{apikey}.execute-api.{location}.amazonaws.com/{stage}&lt;/p&gt;

&lt;p&gt;This API can be called using a curl command similar to one below:&lt;/p&gt;

&lt;div class=&#34;highlight&#34; style=&#34;background: #f0f3f3&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;curl -i -XPOST &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;https://{apikey}.execute-api.{location}.amazonaws.com/prod/sendmessage&amp;#39;&lt;/span&gt; -d &lt;span style=&#34;color: #CC3300&#34;&gt;&amp;#39;{&amp;quot;message&amp;quot;: &amp;quot;sent from curl&amp;quot;, &amp;quot;subject&amp;quot;: &amp;quot;Sent from curl&amp;quot;, &amp;quot;from&amp;quot;: &amp;quot;email@domain.com&amp;quot;, &amp;quot;name&amp;quot;: &amp;quot;Test&amp;quot;}&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This should return some JSON with code 0 and a message of &amp;ldquo;success&amp;rdquo;.&lt;/p&gt;

&lt;h2 id=&#34;cors-consideration&#34;&gt;CORS Consideration&lt;/h2&gt;

&lt;p&gt;Another consideration that needs to be made is how to call your API. In most cases you will want to call the API from some Javascript on your website.&lt;/p&gt;

&lt;p&gt;This will not work by default due to &amp;ldquo;Access-Control-Allow-Origin&amp;rdquo; headers not being returned on the API call.&lt;/p&gt;

&lt;p&gt;This can be enabled in the API gateway by going to Actions-&amp;gt;Enable CORS by default this allows all Origins to query the API, you will want to change this to your own website.&lt;/p&gt;

&lt;p&gt;Don&amp;rsquo;t forget once you have made a change to the API gateway you need to re-deploy the API for the changes to go live.&lt;/p&gt;

&lt;p&gt;This example is a basic setup there are other considerations that need to be made such as API keys, rate limiting, input validation and response mappings.&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>