The Developer Space

Developer's Cafe

  • Cloud
  • Database
  • Open Source
  • Programming
  • Web Dev
  • Mobile
  • Security
  • QuickRef
  • Home
  • Cloud
  • How to build a REST API using Amazon API Gateway to invoke OpenAI APIs

How to build a REST API using Amazon API Gateway to invoke OpenAI APIs

Shameel Ahmed - Artificial Intelligence, AWS, Cloud, Conversational Bots, Programming, Python
March 11, 2023March 11, 2023 No Comments
Invoke OpenAI APIs from API Gateway
1 0
1 0
Read Time11 Minute, 12 Second

One of my previous articles provided a step-by-step guide to invoke OpenAI APIs from AWS Lambda functions. This article expands the topic by front-ending the Lambda function with a REST API built with Amazon API Gateway.

Table of Contents

  • Introduction
  • Prerequisites
  • Create the API
    • Integration Request
    • Integration Response
  • Modify the Lambda function
  • Test the API locally
  • Deploy the API
  • Test the Deployed API
  • What next?
  • Conclusion
  • Share

Introduction

This article will take you through the step-by-step process to build a REST API using API Gateway. The API invokes a Lambda function that in turn invokes OpenAI APIs and returns a response. Your applications can invoke this API to embed Artificial Intelligence capabilities similar to ChatGPT. Note that this article walks you through the very basic API Gateway features and options to build a bare-bones working API that can invoke a Lambda function and return a response. API Gateway provides several other features that are not covered in this article. Also, this example does not use authentication, please consider using a supported authentication method to protect your APIs from unauthorized use and DDoS attacks.

Prerequisites

  1. Familiarity with OpenAI APIs and how to invoke them from an AWS Lambda function.
  2. An OpenAI account and a Secret key
  3. An AWS account

Check out How to invoke OpenAI APIs from AWS Lambda functions before reading this article.

Create the API

In this example, we’ll build a REST API with a POST method and pass on the input prompt in the method body as raw JSON. The input prompt will be passed on to the Lambda function that houses the logic to invoke OpenAI APIs.

  1. Login to your AWS console
  2. Go to Services -> API Gateway
  3. Select APIs from the left menu
  4. Click on the Create API button on the top-right
  5. Under Choose an API type, select REST API (not REST API Private) and click Build
  6. Under Choose the protocol, leave REST selected
  7. Under Create new API, select New API
  8. Enter an API name, for example “apigw_invoke_openai_api”
  9. Leave Endpoint type as Regional

Regional APIs are deployed in the current region. Edge Optimized APIs are deployed to the CloudFront network. Private APIs are accessible only from VPCs.

At this point, your screen should look like this:

Click the Create API button.

The next screen takes you to the Resources section where you can define your methods.

  1. Click on the Actions dropdown button
  2. Select Create method
  3. From the resulting dropdown, select POST and click on the Tick button.

Select Integration type as Lambda function, select your region and select the Lambda function that you created in the previous article (e.g. openai_invoke_api)

At this point, your screen should look like this:

Click on the Save button, and click OK in the resulting popup warning you about giving Lambda access permission to your API.

In the next screen, you will be able to configure the Integration Request and Integration Response as shown here:

Integration Request

Since we have defined a POST method and not a GET method, we do not have to define any query parameters. Instead, we define Mapping Templates to tell API Gateway how to handle and parse fields passed on in the request body. Mapping Templates are based on Apache Velocity Templating Language and allow us to validate and modify incoming request to a format that is required by the backend services that power the API. In this example, we’ll use Mapping Templates to map fields sent in request body to input parameters required by the Lambda function.

Click Integration Request link and expand the Mapping Templates section.

  1. Select When there are no templates defined (recommended) option
  2. Click the Add mapping template link, enter application/json in the Content-Type textbox and click the Tick icon.
  3. Click on the application/json link that is created and then select Method Request passthrough option from the Generate template dropdown.

The following Velocity mapping template is automatically generated. This code automatically maps the entire request body inside the body-json JSON element, and also maps every individual parameter under the params element.

##  See http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html
##  This template will pass through all parameters including path, querystring, header, stage variables, and context through to the integration endpoint via the body/payload
#set($allParams = $input.params())
{
"body-json" : $input.json('$'),
"params" : {
#foreach($type in $allParams.keySet())
    #set($params = $allParams.get($type))
"$type" : {
    #foreach($paramName in $params.keySet())
    "$paramName" : "$util.escapeJavaScript($params.get($paramName))"
        #if($foreach.hasNext),#end
    #end
}
    #if($foreach.hasNext),#end
#end
},
"stage-variables" : {
#foreach($key in $stageVariables.keySet())
"$key" : "$util.escapeJavaScript($stageVariables.get($key))"
    #if($foreach.hasNext),#end
#end
},
"context" : {
    "account-id" : "$context.identity.accountId",
    "api-id" : "$context.apiId",
    "api-key" : "$context.identity.apiKey",
    "authorizer-principal-id" : "$context.authorizer.principalId",
    "caller" : "$context.identity.caller",
    "cognito-authentication-provider" : "$context.identity.cognitoAuthenticationProvider",
    "cognito-authentication-type" : "$context.identity.cognitoAuthenticationType",
    "cognito-identity-id" : "$context.identity.cognitoIdentityId",
    "cognito-identity-pool-id" : "$context.identity.cognitoIdentityPoolId",
    "http-method" : "$context.httpMethod",
    "stage" : "$context.stage",
    "source-ip" : "$context.identity.sourceIp",
    "user" : "$context.identity.user",
    "user-agent" : "$context.identity.userAgent",
    "user-arn" : "$context.identity.userArn",
    "request-id" : "$context.requestId",
    "resource-id" : "$context.resourceId",
    "resource-path" : "$context.resourcePath"
    }
}

Click the Save button to save the template.

Integration Response

  1. Navigate to the Method Execution screen
  2. Click Integration Response link
  3. Expand the default row (with Method response status = 200) in the table
  4. Expand the Mapping Templates section
  5. Click the Add mapping template link, enter application/json in the Content-Type textbox and click the Tick icon. There is no need to define a Mapping Template for the response as the response from the Lambda function would be returned by the REST API “as-is” without any transformations.

Modify the Lambda function

Before testing the API that we just created, we need to make a small update to the Lambda function that we created in the previous article (openai_invoke_api). Change line #9 to replace the literal string to an expression that reads the input_prompt variable from the event parameter.

input_prompt=event['body-json']['input_prompt']

event['body-json'] contains the complete HTTP request body. The complete function should look like this:

import json
import openai
import boto3

def lambda_handler(event, context):
    #print(event)
    
    model_to_use = "text-davinci-003"
    input_prompt=event['body-json']['input_prompt']
    
    openai.api_key = get_api_key()
    response = openai.Completion.create(
      model=model_to_use,
      prompt=input_prompt,
      temperature=0,
      max_tokens=1000,
      top_p=1,
      frequency_penalty=0.0,
      presence_penalty=0.0
    )
    #print(response)
    text_response = response['choices'][0]['text'].strip()
    return {
        'statusCode':200,
        'body': {
            'response' : text_response
        }
    }
    
def get_api_key():
    lambda_client = boto3.client('lambda')
    response = lambda_client.invoke(
            FunctionName = 'arn:aws:lambda:us-east-1:388685834121:function:openai_get_api_key',
            InvocationType = 'RequestResponse'
        )
    openai_api_key = json.load(response['Payload'])['body']['api_key']
    return openai_api_key

To view the complete event parameter that is passed on to the function, uncomment line # 6.

Test the API locally

Now that we are done with configuring the API and updating the Lambda function, it’s time to test our API. Go back to the Method Execution screen and click the Test button. Enter an input prompt like this:

{
    "input_prompt": "What is the capital of Belarus?"
}

If you followed the article along and did everything as instructed, you should see a response like this. The request and response are highlighted in red boxes.

Deploy the API

Once you have successfully tested your API locally from within the API Gateway console, it is time to deploy your API and make it available for external consumption.

  1. Navigate to your API page
  2. Click Resources menu on the left menu
  3. Click the Actions dropdown button
  4. Select Deploy API menu option
y

In the resulting popup, select [New Stage] from the dropdown and provide a name for the Stage. For example, if you want to deploy it to your DEV environment, enter DEV and click Deploy.

Once deployed, you will receive an Invoke Url that serves as the endpoint to the API stage deployed. The Invoke Url is specific to the STAGE and you can always get the Url by visiting your API page and selecting Stages from the left side menu.

Test the Deployed API

After deployment, you can test the API from a HTTP client like Postman. Make note of the highlighted elements in the image, and change them to the provided values.

Method: Post

Endpoint: https://[API_ID].execute-api.[REGION].amazonaws.com/[STAGE]

Pass the input JSON in the Body in raw format (JSON)

What next?

The example provided in this article is very basic and can be extended to handle advanced use cases. The next things you can do it to:

  1. Build multiple APIs on top of this template for different use cases. (each using a different model/prompt)
  2. Provide an authentication mechanism to protect your APIs from unauthorized use.
  3. Explore Messaging Templates for advanced input and output transformations between your APIs and Lambda functions.
  4. Build multiple Lambda functions with the ability to choose different OpenAI models
  5. Experiment with different OpenAI models and explore how they return different outputs for the same input which can help you decide which model is best suited for a specific use case. In the openai_invoke_api Lambda function, model is specified in Line #8.

Conclusion

I believe that you found this article and the examples provided here useful. If you enjoyed reading this article, please leave a comment and do not forget to share this article with your friends and colleagues who might be interested in the topic. Thank you and happy reading.

Share

Facebook
Twitter
LinkedIn
Email

Post navigation

How to fix “‘StreamingBody’ object is not subscriptable” in AWS Lambda boto3

Related Articles

How to fix “‘StreamingBody’ object is not subscriptable” in AWS Lambda boto3

Shameel Ahmed
February 12, 2023February 12, 2023 No Comments
Invoke OpenAI APIs from Lambda

How to invoke OpenAI APIs from AWS Lambda functions

Shameel Ahmed
February 5, 2023February 18, 2023 14 Comments
GoogleSearch vs ChatGPT

Can ChatGPT replace Google Search?

Shameel Ahmed
January 11, 2023January 13, 2023 No Comments

Average Rating

5 Star
0%
4 Star
0%
3 Star
0%
2 Star
0%
1 Star
0%
(Add your review)

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Contents

  • Introduction
  • Prerequisites
  • Create the API
    • Integration Request
    • Integration Response
  • Modify the Lambda function
  • Test the API locally
  • Deploy the API
  • Test the Deployed API
  • What next?
  • Conclusion
  • Share

Categories

.NET Architecture Artificial Intelligence ASP.NET AWS Azure Books C# Career Cloud CodeProject Conversational Bots Database Data Security Facade IDEs Java Mobile MongoDB MySQL Open Source Patterns PostgreSQL Programming Python Redis Security SQL Server Tools Uncategorized Web Development Windows Phone

Recent Posts

  • How to build a REST API using Amazon API Gateway to invoke OpenAI APIs March 11, 2023
  • How to fix “‘StreamingBody’ object is not subscriptable” in AWS Lambda boto3 February 12, 2023
  • How to invoke OpenAI APIs from AWS Lambda functions February 5, 2023
  • Developer to Architect Series (Red Hat Enable Architect) January 16, 2023
  • Can ChatGPT replace Google Search? January 11, 2023

Archives

  • March 2023 (1)
  • February 2023 (2)
  • January 2023 (2)
  • December 2022 (1)
  • October 2022 (1)
  • July 2022 (2)
  • February 2022 (1)
  • November 2021 (1)
  • July 2021 (1)
  • June 2021 (1)
  • September 2020 (1)
  • May 2020 (2)
  • April 2020 (1)
  • October 2019 (1)
  • September 2019 (4)
  • July 2019 (2)
  • May 2018 (1)
  • September 2017 (1)
  • April 2017 (1)
  • April 2014 (1)
  • August 2011 (1)
  • June 2009 (1)
Copyright 2022. The Developer Space | Theme: OMag by LilyTurf Themes
  • DbStudio
  • Re:Link
  • shameel.net
  • Privacy Policy
We use cookies on our website to give you the most relevant experience by remembering your preferences and repeat visits. By clicking “Accept”, you consent to the use of ALL the cookies.
Do not sell my personal information.
Cookie settingsACCEPT
Privacy & Cookies Policy

Privacy Overview

This website uses cookies to improve your experience while you navigate through the website. Out of these cookies, the cookies that are categorized as necessary are stored on your browser as they are as essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may have an effect on your browsing experience.
Necessary
Always Enabled
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.
SAVE & ACCEPT