<?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>DEV Community: Obakunle Oluseye</title>
    <description>The latest articles on DEV Community by Obakunle Oluseye (@oluseye).</description>
    <link>https://dev.to/oluseye</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%2F1166918%2F6625c70b-9a93-435b-941e-4e5300d51900.jpeg</url>
      <title>DEV Community: Obakunle Oluseye</title>
      <link>https://dev.to/oluseye</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/oluseye"/>
    <language>en</language>
    <item>
      <title>Build Webhooks with AWS Lambda and FastAPI in 10 Steps</title>
      <dc:creator>Obakunle Oluseye</dc:creator>
      <pubDate>Sun, 24 Sep 2023 23:58:26 +0000</pubDate>
      <link>https://dev.to/oluseye/build-webhooks-with-aws-lambda-and-fastapi-in-10-steps-f20</link>
      <guid>https://dev.to/oluseye/build-webhooks-with-aws-lambda-and-fastapi-in-10-steps-f20</guid>
      <description>&lt;p&gt;In today's fast-paced digital world, real-time data exchange is the key to responsive applications. Webhooks have become indispensable for enabling instant communication between systems. Webhooks play a crucial role in enabling real-time communication between applications, allowing them to respond to events as they occur. In this article, we'll explore how to create robust webhooks using FastAPI and AWS Lambda. FastAPI, known for its simplicity and performance, will serve as our webhook receiver, while AWS Lambda handles event processing.We'll build an endpoint to trigger a webhook event and another to receive and process webhook events.  By the end, you'll be equipped to build a scalable and efficient webhook system that can react to events from various sources, enhancing your application's real-time capabilities. Let's get started!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic knowledge of Python, AWS Lambda, and API Gateway&lt;/li&gt;
&lt;li&gt;Python virtual environment set up&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Setting Up the Environment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before we begin, ensure you've set up a Python virtual environment for your project. If you're unfamiliar with this process, you can find resources online to guide you through it &lt;a href="https://fastapi.tiangolo.com/contributing/"&gt;tap this link to learn more&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Creating the FastAPI Application&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In your project directory, create a file named &lt;code&gt;main.py&lt;/code&gt;. This file will house our FastAPI code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Import necessary libraries
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HTTPException&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BackgroundTasks&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;uvicorn&lt;/span&gt;

&lt;span class="c1"&gt;# Create a FastAPI app instance
&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Define the Pydantic schema for the payload
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
    &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;webhook_url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;

&lt;span class="c1"&gt;# Define a function to send webhook requests
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;send_webhook_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://api-gateway-url/path"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# Raise an exception for non-2xx response status codes
&lt;/span&gt;    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exceptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RequestException&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"Error sending webhook request: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Define the endpoint to simulate a payment event
&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/payment"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;payment_event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payment_event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PaymentEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;background_tasks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BackgroundTasks&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;payment_event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;HTTPException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;detail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Amount cannot be empty"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;payment_event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;
    &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;payment_event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;
    &lt;span class="n"&gt;webhook_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;payment_event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;webhook_url&lt;/span&gt;

    &lt;span class="c1"&gt;# Add the send_webhook_request function as a background task
&lt;/span&gt;    &lt;span class="n"&gt;background_tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;send_webhook_request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"webhook_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;webhook_url&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;response_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Payment event simulated successfully"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"webhook_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;webhook_url&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response_data&lt;/span&gt;

&lt;span class="c1"&gt;# Define the endpoint to receive webhook events
&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/webhook"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;receive_webhook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Webhook received successfully"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"payload"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Run the FastAPI app
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"__main__"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;uvicorn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"0.0.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4040&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3: Understanding the Code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the code snippet above:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We create a FastAPI app instance (&lt;code&gt;app&lt;/code&gt;) and import the required libraries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A Pydantic schema, &lt;code&gt;PaymentEvent&lt;/code&gt;, is defined to structure the payload that users will send.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;send_webhook_request&lt;/code&gt; function is created to send webhook requests to a specified URL. It is essential for triggering the webhook event.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We define an endpoint (&lt;code&gt;/payment&lt;/code&gt;) to simulate a payment event. This endpoint receives a &lt;code&gt;PaymentEvent&lt;/code&gt; payload, validates it, and then adds the &lt;code&gt;send_webhook_request&lt;/code&gt; function as a background task.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Another endpoint (&lt;code&gt;/webhook&lt;/code&gt;) is defined to receive webhook events and process them.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Running the FastAPI Application&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To run the FastAPI application, execute the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python app.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To facilitate communication between our Lambda function and the local server, we will employ ngrok, a powerful tool for tunneling requests. Follow these steps to set up ngrok:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Installation:&lt;/strong&gt; Begin by downloading and installing ngrok from its official website, available at &lt;a href="https://ngrok.com/download"&gt;https://ngrok.com/download&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Running ngrok:&lt;/strong&gt; Once installed, execute the following command in your terminal, replacing '4040' with the port number of your local server:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ngrok http 4040
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;This command will create a forwarding interface that efficiently redirects requests made to our ngrok URL to our local server. Your terminal should display information similar to the following:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Session Status: online
Account: email@gmail.com (Plan: Free)
Update: Update available (version 2.3.41, Ctrl-U to update)
Version: 2.3.40
Region: United States (us)
Web Interface: [http://127.0.0.1:4041](http://127.0.0.1:4041)
Forwarding: [http://38fe-2c0f-2a80-c4-3700-6a51-91da-f16e-2918.ngrok-free.app](http://38fe-2c0f-2a80-c4-3700-6a51-91da-f16e-2918.ngrok-free.app) -&amp;gt; [http://localhost:4040](http://localhost:4040)
Forwarding: [https://38fe-2c0f-2a80-c4-3700-6a51-91da-f16e-2918.ngrok-free.app](https://38fe-2c0f-2a80-c4-3700-6a51-91da-f16e-2918.ngrok-free.app) -&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This setup allows seamless redirection of requests from the ngrok URL to our local server. It's a crucial step in ensuring smooth communication between the two components of your system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5 - Verifying Ngrok Functionality&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To confirm that Ngrok is functioning correctly and to access your FastAPI Swagger documentation via Ngrok, follow these steps. Typically, you would access the documentation locally at &lt;code&gt;localhost:4040/docs&lt;/code&gt;, but with Ngrok, you'll use a modified URL. In this example, we'll use the URL &lt;code&gt;https://38fe-2c0f-2a80-c4-3700-6a51-91da-f16e-2918.ngrok-free.app/docs&lt;/code&gt;. Replace this URL with your own forwarding URL.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Access Your FastAPI Swagger Docs:&lt;/strong&gt; Open your web browser and enter the modified URL in the address bar. In this case, it should be &lt;code&gt;https://38fe-2c0f-2a80-c4-3700-6a51-91da-f16e-2918.ngrok-free.app/docs&lt;/code&gt;. Press Enter to navigate to the Swagger documentation page.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Verify Ngrok Functionality:&lt;/strong&gt; Once the page loads, you should see the Swagger documentation for your FastAPI project. This confirms that Ngrok is successfully forwarding requests to your local server.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Below is an image of what the Swagger documentation page loaded with Ngrok might look like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dRAd5Sbl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rdoduhxle2roae4s4v0m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dRAd5Sbl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rdoduhxle2roae4s4v0m.png" alt="Image description" width="800" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This visual confirmation assures you that Ngrok is effectively bridging the gap between your local environment and the internet, making your FastAPI documentation accessible via a public URL.&lt;/p&gt;




&lt;p&gt;You can insert the image of your Swagger documentation page as mentioned in the content. Incorporate this refined content into your article to guide your readers in verifying the functionality of Ngrok and accessing their FastAPI Swagger documentation. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Creating and Testing our Lambda Function Locally with SAM&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AWS SAM (Serverless Application Model) is an open-source framework designed for building serverless applications. It streamlines the process of creating, testing, and deploying Lambda functions locally. To get started with AWS SAM, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Installation:&lt;/strong&gt; Begin by installing the &lt;code&gt;sam-cli&lt;/code&gt; for your specific operating system. Detailed instructions can be found in the official AWS SAM documentation at &lt;a href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html"&gt;https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Project Initialization:&lt;/strong&gt; After installing &lt;code&gt;sam-cli&lt;/code&gt;, navigate to the directory where your &lt;code&gt;main.py&lt;/code&gt; file resides. In this directory, run the following command:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sam init
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;During initialization, you will be prompted to choose a template. Opt for the &lt;code&gt;HelloWorldExample&lt;/code&gt; template, which is a good starting point. When asked to select a runtime, ensure it matches the Python version installed on your local machine for testing purposes.&lt;/p&gt;

&lt;p&gt;Here's an example of the prompts you might encounter:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Which template source would you like to use?
    1 - AWS Quick Start Templates
    2 - Custom Template Location
Choice: 1

Choose an AWS Quick Start application template
    1 - Hello World Example
    2 - Data processing
    3 - Hello World Example With Powertools
    ... (other options)
Template: 1

Use the most popular runtime and package type? (Python and zip) [y/N]: n

Which runtime would you like to use?
    ... (list of runtimes)
Runtime: 18  # Choose the appropriate Python version

What package type would you like to use?
    1 - Zip
    2 - Image
Package type: 1

Would you like to enable X-Ray tracing on the function(s) in your application? [y/N]: y
(X-Ray may incur additional costs)

Would you like to enable monitoring using CloudWatch Application Insights? [y/N]: y
(AppInsights monitoring may incur additional costs)

Project name [sam-app]: hooks
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Project Structure:&lt;/strong&gt; AWS SAM will create a folder for your functions, and in your case, it will be named 'hooks'. You can navigate to the 'hooks/hello_world/app.py' folder. This is where you will edit your Lambda function code.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 7 - Modifying the AWS SAM Configuration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To enhance your AWS SAM configuration, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Updating the Events Section:&lt;/strong&gt; Navigate to the &lt;code&gt;template.yml&lt;/code&gt; file and replace the existing &lt;code&gt;Events&lt;/code&gt; section with the following code:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Events&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;HelloWorld&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Api&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;Path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/hooks&lt;/span&gt;
      &lt;span class="na"&gt;Method&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;post&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;This modification configures an API Gateway event source for your Lambda function, enabling it to respond to POST requests at the &lt;code&gt;/hooks&lt;/code&gt; path.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Modifying the API Gateway Endpoint:&lt;/strong&gt; Next, adjust the API Gateway endpoint configuration as follows:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;HelloWorldApi&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;API Gateway endpoint URL for Prod stage for Hello World function&lt;/span&gt;
  &lt;span class="na"&gt;Value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Sub&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hooks/"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;You can customize the endpoint as needed, but this format provides a standardized endpoint for your Hello World function within the API Gateway.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 8 - Updating the Lambda Function Code&lt;/strong&gt;&lt;br&gt;
Now, let's enhance the functionality of your Lambda function by modifying the lambda_handler function in the hooks/app.py file. Replace your existing app.py code with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;requests&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lambda_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Parse the JSON body from the incoming event
&lt;/span&gt;    &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'body'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;  &lt;span class="c1"&gt;# Initialize an empty response dictionary
&lt;/span&gt;
    &lt;span class="c1"&gt;# Check if the 'amount' in the body is less than 100
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'amount'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'event'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"payment_failed"&lt;/span&gt;  &lt;span class="c1"&gt;# Set the event to "payment_failed"
&lt;/span&gt;        &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'message'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"An error occurred"&lt;/span&gt;  &lt;span class="c1"&gt;# Set a corresponding error message
&lt;/span&gt;    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'event'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"payment_verified"&lt;/span&gt;  &lt;span class="c1"&gt;# Set the event to "payment_verified"
&lt;/span&gt;        &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'message'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"The payment was verified"&lt;/span&gt;  &lt;span class="c1"&gt;# Set a success message
&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Send a POST request to a webhook URL with the response data
&lt;/span&gt;        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'webhook_url'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;  &lt;span class="c1"&gt;# Print the webhook URL for debugging (optional)
&lt;/span&gt;        &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'webhook_url'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'Content-type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'application/json'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

        &lt;span class="c1"&gt;# Return a JSON response indicating success
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;"statusCode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"body"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                &lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Action sent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="c1"&gt;# "location": ip.text.replace("\n", "")
&lt;/span&gt;            &lt;span class="p"&gt;}),&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RequestException&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Handle any exceptions that occur during the POST request
&lt;/span&gt;        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's an explanation of the code:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The function receives two parameters: &lt;code&gt;event&lt;/code&gt; and &lt;code&gt;context&lt;/code&gt;. In this context, &lt;code&gt;event&lt;/code&gt; represents the input data for the Lambda function, and &lt;code&gt;context&lt;/code&gt; provides information about the execution environment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The code starts by parsing the JSON data from the &lt;code&gt;event['body']&lt;/code&gt;, assuming that the incoming request contains a JSON payload.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It initializes an empty &lt;code&gt;response&lt;/code&gt; dictionary to store the response data that will be sent back.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The code checks the 'amount' field in the JSON body. If the amount is less than 100, it sets the &lt;code&gt;response['event']&lt;/code&gt; to "payment_failed" and the &lt;code&gt;response['message']&lt;/code&gt; to "An error occurred." This indicates that the payment failed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the amount is greater than or equal to 100, it sets &lt;code&gt;response['event']&lt;/code&gt; to "payment_verified" and &lt;code&gt;response['message']&lt;/code&gt; to "The payment was verified." This indicates that the payment was successful.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The code then attempts to send a POST request to a webhook URL specified in &lt;code&gt;body['webhook_url']&lt;/code&gt;. It sends the &lt;code&gt;response&lt;/code&gt; data as a JSON payload in the request.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the POST request is successful (no exceptions are raised), it returns a JSON response with a 200 status code and a "message" field indicating that the action was sent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If an exception (such as a network error) occurs during the POST request, it is caught in the &lt;code&gt;except&lt;/code&gt; block, and the Lambda function raises the exception to handle it. This allows you to handle errors that may occur when communicating with the webhook.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This code essentially processes incoming payment data, checks the amount, sends a response to a webhook URL, and handles any potential errors that may occur during the process. &lt;br&gt;
Certainly, I'll rephrase the instructions for you:&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Step 9 - Testing and Deploying Your Lambda Function&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, let's proceed with testing your Lambda function. Follow these steps to ensure everything is working as expected:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Prepare Event Data:&lt;/strong&gt; Start by navigating to the &lt;code&gt;hooks/events/events.json&lt;/code&gt; file. Replace the content of &lt;code&gt;event.json&lt;/code&gt; with the expected payload for your test case. In your case, it should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"body"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hello world"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"webhook_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://38fe-2c0f-2a80-c4-3700-6a51-91da-f16e-2918.ngrok-free.app/webhook"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/prod/hooks"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"resourcePath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/hooks"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"httpMethod"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"POST"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;Ensure that you use the URL provided by ngrok (&lt;code&gt;https://38fe-2c0f-2a80-c4-3700-6a51-91da-f16e-2918.ngrok-free.app/webhook&lt;/code&gt;) as the &lt;code&gt;webhook_url&lt;/code&gt;. This URL will forward requests made to it to &lt;code&gt;http://localhost:4040/webhook&lt;/code&gt;.&lt;/p&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Build the SAM Application:&lt;/strong&gt; After updating the event data, build your AWS SAM application by running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;sam build
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;This command will prepare your application for testing and deployment.&lt;/p&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Test the Lambda Function Locally:&lt;/strong&gt; To test your Lambda function locally, use the following command:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;sam &lt;span class="nb"&gt;local &lt;/span&gt;invoke HelloWorldFunction &lt;span class="nt"&gt;--event&lt;/span&gt; events/event.json
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;You should expect to receive the following response in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Invoking app.lambda_handler (python3.10)
Local image is up-to-date
Using local image: public.ecr.aws/lambda/python:3.10-rapid-x86_64.

Mounting /path/to/your/webhook/hooks/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated, inside runtime container
START RequestId: [Your_Request_ID] Version: $LATEST
[Your_Webhook_URL]
{"statusCode": 200, "body": "{\"message\": \"Action sent\"}"}
END RequestId: [Your_Request_ID]
REPORT RequestId: [Your_Request_ID] Init Duration: 0.06 ms Duration: 1683.21 ms Billed Duration: 1684 ms Memory Size: 128 MB Max Memory Used: 128 MB
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;This response confirms that your Lambda function executed successfully, and you received a response with a status code of 200.&lt;/p&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Deploy Your Lambda Function:&lt;/strong&gt; To deploy your Lambda function, use the following command with the &lt;code&gt;--guided&lt;/code&gt; flag:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;sam deploy &lt;span class="nt"&gt;--guided&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;This command will guide you through the deployment process, allowing you to configure various deployment settings.If you deployment is successful head over to the aws management console to view your lambda function, you should have something in the image below:&lt;/p&gt;


&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LWbtTrd4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rinsz2dq33ex3uizxosc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LWbtTrd4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rinsz2dq33ex3uizxosc.png" alt="Image description" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BFukJVhb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xzbvy2nh7dba6nw4m12j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BFukJVhb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xzbvy2nh7dba6nw4m12j.png" alt="Image description" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 10 - Testing Your Webhooks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The next step in your journey is to test your webhooks by loading your documentation page. This test allows you to confirm that your webhooks are functioning correctly. Follow these steps to perform the test:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Load the Documentation Page:&lt;/strong&gt; Begin by accessing your swagger documentation page. Once there, you will have the opportunity to input your webhook payload. In this scenario, the objective is to make a request through the &lt;code&gt;/payment&lt;/code&gt; endpoint.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dRAd5Sbl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rdoduhxle2roae4s4v0m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dRAd5Sbl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rdoduhxle2roae4s4v0m.png" alt="Image description" width="800" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Input Payload:&lt;/strong&gt; Enter the following payload, which is tailored for your use case. It specifies an amount of 4000, a description of "payment_made," and a webhook URL:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"payment_made"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"webhook_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://38fe-2c0f-2a80-c4-3700-6a51-91da-f16e-2918.ngrok-free.app/webhook"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VS0j3DCr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lcau8oiabcgpa93p5fby.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VS0j3DCr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lcau8oiabcgpa93p5fby.png" alt="Image description" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Make the Request:&lt;/strong&gt; Once you've entered the payload, initiate the request. If everything is set up correctly, you should receive a success response on the documentation page.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4Hch4hV8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/btjl11inmt42xet9ny7t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4Hch4hV8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/btjl11inmt42xet9ny7t.png" alt="Image description" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Check the Logs:&lt;/strong&gt; To confirm that the webhook was received, inspect your server logs. Look specifically for a request made to the &lt;code&gt;POST /webhook&lt;/code&gt; endpoint. You can observe the request in the logs, verifying that it was indeed received and processed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here are sample logs from your local server that illustrate the successful webhook process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INFO: Started server process [300044]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:4040 (Press CTRL+C to quit)
INFO: 105.113.20.255:0 - "GET /docs HTTP/1.1" 200 OK
INFO: 105.113.20.255:0 - "GET /openapi.json HTTP/1.1" 200 OK
INFO: 105.113.20.255:0 - "POST /payment HTTP/1.1" 200 OK
INFO: 105.113.20.159:0 - "POST /webhook HTTP/1.1" 200 OK
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--y7yxDzG6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qxkozyksbxojyzeezhm5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y7yxDzG6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qxkozyksbxojyzeezhm5.png" alt="Image description" width="800" height="259"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This log excerpt confirms the successful webhook operation. The &lt;code&gt;POST /webhook&lt;/code&gt; request was received, processed, and responded to with a status code of 200.&lt;/p&gt;

&lt;p&gt;This is how you build a webhook with aws lambda and fastapi, if you have any questions please comment,I'll respond.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>fastapi</category>
      <category>webhook</category>
      <category>lambda</category>
    </item>
  </channel>
</rss>
