<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: James</title>
    <description>The latest articles on Forem by James (@sugrue).</description>
    <link>https://forem.com/sugrue</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F465545%2Faf3d5d10-d962-40f8-a54e-e612ae64d5b9.jpeg</url>
      <title>Forem: James</title>
      <link>https://forem.com/sugrue</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/sugrue"/>
    <language>en</language>
    <item>
      <title>Creating Live Dashboards With QuickSight</title>
      <dc:creator>James</dc:creator>
      <pubDate>Thu, 20 May 2021 14:20:23 +0000</pubDate>
      <link>https://forem.com/aws-builders/creating-live-dashboards-with-quicksight-2jdp</link>
      <guid>https://forem.com/aws-builders/creating-live-dashboards-with-quicksight-2jdp</guid>
      <description>&lt;p&gt;Liquid syntax error: 'raw' tag was never closed&lt;/p&gt;
</description>
      <category>aws</category>
      <category>quicksight</category>
      <category>analytics</category>
    </item>
    <item>
      <title>Container Images for AWS Lambda with Python</title>
      <dc:creator>James</dc:creator>
      <pubDate>Mon, 10 May 2021 18:32:09 +0000</pubDate>
      <link>https://forem.com/aws-builders/container-images-for-aws-lambda-with-python-286c</link>
      <guid>https://forem.com/aws-builders/container-images-for-aws-lambda-with-python-286c</guid>
      <description>&lt;p&gt;One of the best things about AWS Lambda is the variety of ways that you can create a serverless function. For example, you can dive right into the console, or use approaches like &lt;a href="https://chalice.readthedocs.io/en/stable/" rel="noopener noreferrer"&gt;Chalice&lt;/a&gt; or the &lt;a href="https://www.serverless.com/" rel="noopener noreferrer"&gt;Serverless Framework&lt;/a&gt;, to name a few. For me, the latest way, announced at re:Invent 2020, is the most efficient way of testing your serverless function locally and dealing with large or awkward dependencies in your code. As you'd expect, this works perfectly with &lt;a href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html" rel="noopener noreferrer"&gt;AWS SAM&lt;/a&gt;. This post will give you a quickstart into what you need to do to build a container-based function using containers &amp;amp; Python. &lt;/p&gt;

&lt;p&gt;In my case, I was building a function that would read data from Firestore in Google Cloud, run a data transformation and store the result in S3. I used to swear by Chalice, and built my application but found that it couldn't bundle the GRPC dependency - I would have to build it myself. While the solution to this is just to build the dependency and package it up in the &lt;code&gt;vendor&lt;/code&gt; directory of my Chalice application, I used the opportunity to finally try out container support. &lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;If you're reading this, you're probably using Python already. As well as having Python installed, you'll need to have &lt;a href="https://www.docker.com/get-started" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; too. &lt;/p&gt;

&lt;h3&gt;
  
  
  Building a Docker container with dependencies
&lt;/h3&gt;

&lt;p&gt;As always, the &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/python-image.html" rel="noopener noreferrer"&gt;AWS documentation&lt;/a&gt; will guide you through the basics. &lt;/p&gt;

&lt;p&gt;First you'll need to install the Python runtime interface client using &lt;code&gt;pip install awslamdaric&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Next, create a &lt;code&gt;Dockerfile&lt;/code&gt; that references the base image you are using. In the case below, I was using Python 3.8&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; public.ecr.aws/lambda/python:3.8&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Presuming your code is in app.py with a &lt;code&gt;handler&lt;/code&gt; as the function, you'll add these two lines too &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; app.py   ./&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["app.handler"]      &lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Dealing with dependencies is pretty straightforward. As with all Python application, all the modules you use should be defined in &lt;code&gt;requirements.txt&lt;/code&gt; like this: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

google-cloud-firestore
google-auth


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To make sure all dependencies are correctly bundled, just add these two lines to your Dockerfile &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; requirements.txt ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt 


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;It's as simple as that.&lt;/p&gt;

&lt;h3&gt;
  
  
  Building &amp;amp; Testing Locally
&lt;/h3&gt;

&lt;p&gt;The huge benefit to working with containers is the ability to completely test your Lambda function locally before deploying to your AWS account. Let's take a look into how to do that: &lt;/p&gt;

&lt;h4&gt;
  
  
  Build Your Container
&lt;/h4&gt;

&lt;p&gt;The standard docker build syntax applies here.  &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

docker build &lt;span class="nt"&gt;-t&lt;/span&gt; my-container-image &lt;span class="nb"&gt;.&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The commmand above creates 'my-container-image' in the local directory&lt;/p&gt;

&lt;h4&gt;
  
  
  Running Locally
&lt;/h4&gt;

&lt;p&gt;Typically you would run your container as follows &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 9000:8080  my-continer-image:latest


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;However, it's very likely that you're interacting with AWS services (in my case S3), so you will need to ensure the access credentials exist for your function &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/images-test.html" rel="noopener noreferrer"&gt;documentation here&lt;/a&gt;. These credentials can be set using the following environment variables: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AWS_SESSION_TOKEN&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AWS_REGION&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Provided you've got the credentials set on a user (which should be using the same policy as your Lambda would) you can pass them through as following when running locally: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;

docker run -p 9000:8080  
-e AWS_ACCESS_KEY_ID='ACCESS_KEY_ID_GOES_HERE'
-e AWS_SECRET_ACCESS_KEY= 'SECRET ACCESS KEY GOES HERE'
-e AWS_REGION= 'eu-west-1'
my-container-image:latest


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Finally, to invoke events, you can pass a payload through while the container is running as follows: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

curl &lt;span class="nt"&gt;-XPOST&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9000/2015-03-31/functions/function/invocations"&lt;/span&gt; 
&lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"param1":"parameter 1 value"}'&lt;/span&gt;  


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Note that you can also use the &lt;code&gt;AWS_LAMBDA_FUNCTION_TIMEOUT&lt;/code&gt; environment variable to set a timeout for your function in milliseconds.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Running your Lamba
&lt;/h3&gt;

&lt;p&gt;Now that you have a working container, you need to deploy it to your AWS account&lt;/p&gt;

&lt;h4&gt;
  
  
  Deploy Your Container
&lt;/h4&gt;

&lt;p&gt;Authenticate the Docker CLI to your ECR registry  &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

aws ecr get-login-password &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1 | docker login &lt;span class="nt"&gt;--username&lt;/span&gt; AWS &lt;span class="nt"&gt;--password-stdin&lt;/span&gt; &amp;lt;AWS ACCOUNT ID&amp;gt;.dkr.ecr.&amp;lt;REGION&amp;gt;.amazonaws.com    


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The first time that you are going through this process, you will need to create a repository on ECR with the name that you want to use &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

aws ecr create-repository —repository-name my-container-image


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After this you just need to tag your image before pushing it to ECR &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

docker tag  my-container-image:latest &amp;lt;AWS ACCOUNT ID&amp;gt;.dkr.ecr.&amp;lt;REGION&amp;gt;.amazonaws.com/my-container-image:latest


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

docker push &amp;lt;AWS ACCOUNT ID&amp;gt;.dkr.ecr.&amp;lt;REGION&amp;gt;.amazonaws.com/my-container-image:latest        


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Your container is now ready to be used in a Lambda function. &lt;/p&gt;

&lt;h4&gt;
  
  
  Creating Your Lambda Function
&lt;/h4&gt;

&lt;p&gt;Just open up the AWS console, go to AWS Lambda and click on Create Function &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fposts.jamessugrue.ie%2Fimages%2Farticles%2Faws-console-lambda-container.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fposts.jamessugrue.ie%2Fimages%2Farticles%2Faws-console-lambda-container.png" alt="Creating a container based function on the AWS console"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From there you'll be able to create a function from a container image, and simply select the image you need from ECR through Browse Images. &lt;/p&gt;

&lt;p&gt;Having taken this console based approach, you are obviously going toneed to attach a role to your Lambda at a minimum. &lt;br&gt;
If you want to be more disciplined, and less console dependent, on how you create your container based Lambda functions, check out &lt;a href="https://dev.toEric%20Johnson's"&gt;https://twitter.com/edjgeek&lt;/a&gt; post on &lt;a href="https://aws.amazon.com/blogs/compute/using-container-image-support-for-aws-lambda-with-aws-sam/" rel="noopener noreferrer"&gt;Using Container Image Support for AWS Lambda with AWS SAM&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Extra Resources
&lt;/h3&gt;

&lt;p&gt;As well as the documentation resources linked in this article, make sure to check &lt;a href="https://twitter.com/chrismunns" rel="noopener noreferrer"&gt;Chris Munns'&lt;/a&gt; excellent talk on &lt;a href="https://www.youtube.com/watch?v=X-1xf-DbCBk" rel="noopener noreferrer"&gt;Container Image Support in AWS Lambda&lt;/a&gt; from re:Invent 2020&lt;/p&gt;

</description>
      <category>serverless</category>
      <category>aws</category>
      <category>python</category>
      <category>docker</category>
    </item>
    <item>
      <title>Running An Online Meeting: A Beginners Guide</title>
      <dc:creator>James</dc:creator>
      <pubDate>Sat, 07 Nov 2020 15:15:49 +0000</pubDate>
      <link>https://forem.com/sugrue/running-an-online-meeting-a-beginners-guide-4kpj</link>
      <guid>https://forem.com/sugrue/running-an-online-meeting-a-beginners-guide-4kpj</guid>
      <description>&lt;p&gt;Running community meetups used to be pretty straightforward; get the speakers, organise the location and you’re set. Now that most events are run online and virtually, meetup organisers have a new set of challenges. The good news is that once you get around the initial learning curve, you’ll find it’s full of new opportunities too. Here’s my experience in bringing our local &lt;a href="https://corkdev.io" rel="noopener noreferrer"&gt;developer meetup&lt;/a&gt; to an online stage.&lt;/p&gt;

&lt;h1&gt;
  
  
  Find an Event Platform
&lt;/h1&gt;

&lt;p&gt;The default option for a lot of people seems to be to use Zoom for the event, maybe recording the meeting to share later. This works fine, but does it provide the level of engagement that you’d like? Having attended one of the &lt;a href="https://crowdcomms.com/awscdd2020/modules/58681/info-page" rel="noopener noreferrer"&gt;AWS Community Days&lt;/a&gt;, I noticed the event was using  CrowdComms, which allows clean navigation of the event schedule and the ability to interact; a much better experience for attendees than I had seen in the past.&lt;/p&gt;

&lt;p&gt;Then I remembered &lt;a href="https://vi.to/" rel="noopener noreferrer"&gt;Vito&lt;/a&gt;, a product that &lt;a href="https://twitter.com/paulca" rel="noopener noreferrer"&gt;Paul Campbell&lt;/a&gt; started to build at the beginning of the COVID-19 crisis to provide a better event experience. I sat in on one of the weekly demos of the product to see how it works, and it’s a deceptively simple interface that allows you to create a much better experience for you attendees in seconds.&lt;/p&gt;

&lt;p&gt;You get a place to stream your video content to (more on that shortly) and a number of options for page types to include. This will include an attendee list, and a posts section, which allows you to have a mini-social-network experience for people during (and after) the event where they can ask questions, or just discuss the event they’re watching.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ficnuvaxi0578oesolqgr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ficnuvaxi0578oesolqgr.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Our Vito Hub for CorkDev&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Once you’ve worked out your streaming tools, you simply use the key provided by Vito, and you can then test that the whole thing works before going live. The great thing about it is that your stream will automatically be recorded in Vito, so once completed, you can upload the video to the hub for people to watch later. So you are building up content for your hub as you go along.&lt;/p&gt;

&lt;p&gt;That’s the great thing about Vito for our meetup; people can drop in anytime and watch over again, and use other parts of the hub for things like adding local job listings. It saves you the work of creating a dedicated site for your meetup (we had previously), and just leave all the hard work to Vito.&lt;/p&gt;

&lt;h1&gt;
  
  
  Work Out Your Streaming Options
&lt;/h1&gt;

&lt;p&gt;When I was introduced to the options for streaming software, I have to say it was a bit overwhelming! Paul gave me some solid advice though, and I went with &lt;a href="https://obsproject.com/" rel="noopener noreferrer"&gt;OBS Studio&lt;/a&gt; in the end, purely because of the fact that it was free.&lt;/p&gt;

&lt;p&gt;With OBS you get a decent amount of options for managing the content that will be streamed, such as backgrounds and titles for you videos. You also get a “studio mode” that allows you to see the live content on one side while preparing what the next cut will look like on the the editing side.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdzfekswgruzsd06salsx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdzfekswgruzsd06salsx.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;My setup for the live event: edit on laptop, incoming video stream on the left, Vito on the right&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I sunk a lot of time into working out my audio issues though. On a Mac, sharing your desktop audio is a little bit tricky. To cut a long story short, follow the instructions &lt;a href="https://obsproject.com/forum/resources/os-x-capture-audio-with-ishowu-audio-capture.505/" rel="noopener noreferrer"&gt;here&lt;/a&gt; to set up &lt;a href="https://support.shinywhitebox.com/hc/en-us/articles/204161459-Installing-iShowU-Audio-Capture" rel="noopener noreferrer"&gt;iShowU Audio Capture&lt;/a&gt;. Make sure that the sample rate you choose in the Multi-Output Device settings matches those of the master device you’re using (like Airpods in my own case).&lt;/p&gt;

&lt;p&gt;On the topic of audio, you can easily mute and unmute your own microphone as the event happens in the audio mixer section. During the event make sure you stay aware of this!&lt;/p&gt;

&lt;p&gt;When you’re bringing someone else into the event, you could use Zoom/Microsoft Teams/FaceTime or your video chat tool of choice. However, if you want to go that extra mile and have even more control, I’d recommend &lt;a href="https://obs.ninja/" rel="noopener noreferrer"&gt;OBS.Ninja&lt;/a&gt; where you can create your own “room” for a group chat specific to your meetup. Each person in the room gets their own URL which can be then added to OBS as a stream. For Mac’s it a little more complicated (again) so I used &lt;a href="https://github.com/steveseguin/electroncapture" rel="noopener noreferrer"&gt;OBSN&lt;/a&gt; to share the content coming from OBS.Ninja.&lt;/p&gt;

&lt;p&gt;Make sure to put a lot of time in getting your setup just right and use the livestream testing tool on your Vito Hub to make sure that it works.&lt;/p&gt;

&lt;h1&gt;
  
  
  Work Hard on Event PR
&lt;/h1&gt;

&lt;p&gt;It goes without saying, but you’ll have to work hard on pushing the event out to the public. You’ll need to send a lot of annoying reminders on Twitter, and if you’re already using Meetup, make sure to use the tools there to push out reminders via email for event too.&lt;/p&gt;

&lt;p&gt;Running an online event as described here is an opportunity to get your branding right too. I used &lt;a href="https://www.canva.com/" rel="noopener noreferrer"&gt;Canva&lt;/a&gt; to create some basic backgrounds and titles for the event. Variations of those assets were used in the Vito hub too. Having a consistent colour/font/style combination really is worth it. Particularly when the event will be recorded and stored forever.&lt;/p&gt;

&lt;p&gt;After that, you’ve just got to get ready for the infinite loop and plan your next events! Some advice that I got that I’ll recycle here is: make sure you plan out your event calendar. Try to have topics and ideally people, lined up for the next three events. That way you’ll never have that last minute panic and scramble in trying to work out your next great event.&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F87bxw03fw27dyu8j91xa.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F87bxw03fw27dyu8j91xa.jpg" alt="pexels-hendrik-b-744318"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
