Skip to content

Commit 68a714a

Browse files
authored
Merge pull request #8 from FullStackWithLawrence/client
Add React front end
2 parents eae06d9 + a8e27de commit 68a714a

File tree

135 files changed

+33331
-198
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

135 files changed

+33331
-198
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,7 @@ tardigrade-ci/
2121

2222
# go tests
2323
tests/go.*
24+
25+
# ReactJS
26+
client/node_modules/
27+
node_modules

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/)
66
and this project adheres to [Semantic Versioning](http://semver.org/).
77

8+
## [0.2.0] (2023-10-11)
9+
10+
- add full CORS support to API
11+
- add a Vite ReactJS front end
12+
813
## [0.1.2] (2023-10-08)
914

1015
- CoPilot code improvement suggestions

Makefile

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,67 @@ SHELL := /bin/bash
22

33
.PHONY: init activate lint clean test
44

5-
init: $(.env)
5+
api-init: $(.env)
66
python3.11 -m venv .venv
77
echo -e "OPENAI_API_ORGANIZATION=PLEASE-ADD-ME\nOPENAI_API_KEY=PLEASE-ADD-ME" >> .env
88
pre-commit install
99

10-
activate:
10+
api-activate:
1111
. .venv/bin/activate
1212
pip install -r requirements.txt
1313

14-
lint:
14+
api-lint:
1515
terraform fmt -recursive
1616
pre-commit run --all-files
17-
black ./terraform/python/
17+
black ./api/terraform/python/
1818

19-
clean:
19+
api-clean:
2020
rm -rf .venv
2121
# Add any other generated files to remove here
22+
23+
24+
client-init:
25+
cd ./client && npm install
26+
27+
client-lint:
28+
cd ./client && npm run lint
29+
30+
client-update:
31+
npm install -g npm
32+
npm install -g npm-check-updates
33+
ncu --upgrade --packageFile ./client/package.json
34+
npm update -g
35+
npm install ./client/
36+
37+
client-build:
38+
cd ./client && npm run build
39+
40+
client-release:
41+
#---------------------------------------------------------
42+
# usage: deploy prouduction build of openai.lawrencemcdaniel.com
43+
# app to AWS S3 bucket.
44+
#
45+
# https://gist.github.com/kellyrmilligan/e242d3dc743105fe91a83cc933ee1314
46+
#
47+
# 1. Build the React application
48+
# 2. Upload to AWS S3
49+
# 3. Invalidate all items in the AWS Cloudfront CDN.
50+
#---------------------------------------------------------
51+
npm run build --prefix ./client/
52+
53+
# ------------------------
54+
# add all built files to the S3 bucket.
55+
# ------------------------
56+
aws s3 sync ./client/dist/ s3://openai.lawrencemcdaniel.com \
57+
--acl public-read \
58+
--delete --cache-control max-age=31536000,public \
59+
--expires '31 Dec 2050 00:00:01 GMT'
60+
61+
# ------------------------
62+
# remove the cache-control header created above with a "no-cache" header so that browsers never cache this page
63+
# ------------------------
64+
aws s3 cp s3://openai.lawrencemcdaniel.com/index.html s3://openai.lawrencemcdaniel.com/index.html --metadata-directive REPLACE --cache-control max-age=0,no-cache,no-store,must-revalidate --content-type text/html --acl public-read
65+
aws s3 cp s3://openai.lawrencemcdaniel.com/manifest.json s3://openai.lawrencemcdaniel.com/manifest.json --metadata-directive REPLACE --cache-control max-age=0,no-cache,no-store,must-revalidate --content-type text/json --acl public-read
66+
67+
# invalidate the Cloudfront cache
68+
aws cloudfront create-invalidation --distribution-id E3AIBM1KMSJOP1 --paths "/*" "/index.html" "/manifest.json"

README.md

Lines changed: 10 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,21 @@
11
[![OpenAI](https://a11ybadges.com/badge?logo=openai)](https://platform.openai.com/)
2-
[![AWS](https://img.shields.io/badge/AWS-%23FF9900.svg?style=for-the-badge&logo=amazon-aws&logoColor=white)](https://aws.amazon.com/)
2+
[![Amazon AWS](https://a11ybadges.com/badge?logo=amazonaws)](https://aws.amazon.com/)
3+
[![ReactJS](https://a11ybadges.com/badge?logo=react)](https://react.dev/)
4+
[![FullStackWithLawrence](https://a11ybadges.com/badge?text=FullStackWithLawrence&badgeColor=orange&logo=youtube&logoColor=282828)](https://www.youtube.com/@FullStackWithLawrence)
35

4-
# OpenAI API on AWS
6+
# Customized chatGPT Application
7+
8+
## ReactJS chat application
9+
10+
add text here.
11+
12+
## Custom OpenAI REST API Backend
513

614
A REST API implementing each of the [30 example applications](https://platform.openai.com/examples) from the official [OpenAI API Documentation](https://platform.openai.com/docs/api-reference/making-requests?lang=python) using a modularized Terraform approach. Implemented as a serverless microservice using AWS [API Gateway](https://aws.amazon.com/api-gateway/), [Lambda](https://aws.amazon.com/lambda/) and the [OpenAI Python Library](https://pypi.org/project/openai/). Leverages OpenAI's suite of AI models, including [GPT-3.5](https://platform.openai.com/docs/models/gpt-3-5), [GPT-4](https://platform.openai.com/docs/models/gpt-4), [DALL·E](https://platform.openai.com/docs/models/dall-e), [Whisper](https://platform.openai.com/docs/models/whisper), [Embeddings](https://platform.openai.com/docs/models/embeddings), and [Moderation](https://platform.openai.com/docs/models/moderation).
715

816
- Creating new OpenAI applications and endpoints for this API only takes a few lines of code and is as easy as it is fun! Follow [this link](./terraform/apigateway_endpoints.tf) to see how each of these are coded.
917
- **Follow [this link](./doc/examples/README.md) for detailed documentation on each URL endpoint.**
1018

11-
## Usage
12-
13-
An example request and response. This endpoint inspects and corrects gramatical errors.
14-
15-
```console
16-
curl --location --request PUT 'https://api.openai.yourdomain.com/examples/default-grammar' \
17-
--header 'x-api-key: your-apigateway-api-key' \
18-
--header 'Content-Type: application/json' \
19-
--data '{"input_text": "She no went to the market."}'
20-
```
21-
22-
return value
23-
24-
```json
25-
{
26-
"isBase64Encoded": false,
27-
"statusCode": 200,
28-
"headers": {
29-
"Content-Type": "application/json"
30-
},
31-
"body": {
32-
"id": "chatcmpl-7yLxpF7ZsJzF3FTUICyUKDe1Ob9nd",
33-
"object": "chat.completion",
34-
"created": 1694618465,
35-
"model": "gpt-3.5-turbo-0613",
36-
"choices": [
37-
{
38-
"index": 0,
39-
"message": {
40-
"role": "assistant",
41-
"content": "The correct way to phrase this sentence would be: \"She did not go to the market.\""
42-
},
43-
"finish_reason": "stop"
44-
}
45-
],
46-
"usage": {
47-
"prompt_tokens": 36,
48-
"completion_tokens": 10,
49-
"total_tokens": 46
50-
}
51-
}
52-
}
53-
```
54-
5519
## Official YouTube Video For This Repo
5620

5721
[![OpenAI Python API With AWS API Gateway + Lambda](https://img.youtube.com/vi/FqARAi8nS2M/hqdefault.jpg)](https://www.youtube.com/watch?v=FqARAi8nS2M)
@@ -65,106 +29,6 @@ return value
6529
- [OpenAI platform API key](https://platform.openai.com/).
6630
*If you're new to OpenAI API then see [How to Get an OpenAI API Key](./doc/openai-api-key.md)*
6731

68-
## Setup
69-
70-
1. clone this repo and setup a Python virtual environment
71-
72-
```console
73-
git clone https://github.com/FullStackWithLawrence/aws-openai.git
74-
cd aws-openai
75-
make init
76-
```
77-
78-
2. add your OpenAI API credentials to the [.env](./.env) file in the root folder of this repo. Your organization ID and API Key should appear similar in format to these examples below.
79-
80-
```console
81-
OPENAI_API_ORGANIZATION=org-YJzABCDEFGHIJESMShcyulf0
82-
OPENAI_API_KEY=sk-7doQ4gAITSez7ABCDEFGHIJlbkFJKLOuEbRhAFadzjtnzAV2
83-
```
84-
85-
*Windows/Powershell users: you'll need to modify [./terraform/lambda_openai.tf](./terraform/lambda_openai.tf) data "external" "env" as per instructions in this code block.*
86-
87-
88-
3. Add your AWS account number and region to Terraform. Set these three values in [terraform.tfvars](./terraform/terraform.tfvars):
89-
90-
```terraform
91-
account_id = "012345678912" # Required: your 12-digit AWS account number
92-
aws_region = "us-east-1" # Optional: an AWS data center
93-
aws_profile = "default" # Optional: for aws cli credentials
94-
```
95-
96-
*see the README section **"Installation Prerequisites"** below for instructions on setting up Terraform for first-time use.*
97-
98-
4. Build and deploy the microservice..
99-
100-
```terraform
101-
terraform init
102-
terraform apply
103-
```
104-
105-
*Note the output variables for your API Gateway root URL and API key.*
106-
![Postman](https://raw.githubusercontent.com/FullStackWithLawrence/aws-openai/main/doc/terraform-apply2.png "Postman")
107-
108-
5. (Optional) use the [preconfigured import files](./postman/) to setup a Postman collection with all 30 URL endpoints.
109-
110-
![Postman](https://raw.githubusercontent.com/FullStackWithLawrence/aws-openai/main/doc/postman-1.png "Postman")
111-
112-
### Custom Domain (Optional)
113-
114-
If you manage a domain name using AWS Route53 then you can optionally deploy this API using your own custom domain name. Modify the following variables in [terraform/terraform.tfvars](./terraform/terraform.tfvars) and Terraform wil take care of the rest.
115-
116-
```terraform
117-
create_custom_domain = true
118-
root_domain = "yourdomain.com"
119-
```
120-
121-
## How It Works
122-
123-
![API Workflow](https://raw.githubusercontent.com/FullStackWithLawrence/aws-openai/main/doc/api-workflow.png "API Workflow")
124-
125-
1. a JSON object and custom headers are added to an HTTP request and sent to the API as a 'PUT' method.
126-
2. API Gateway uses a [Request Mapping Template](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html) in a non-proxy Lambda integration request to combine user request text with your OpenAPI application definition, and then forward the combined data as a custom JSON object to a Lambda function.
127-
3. Lambda parses and validates the custom JSON object and then invokes the OpenAI API, passing your api key which is stored as a Lambda environment variable.
128-
4. OpenAI API results are returned as JSON objects.
129-
5. Lambda creates a custom JSON response containing the http response body as well as system information for API Gateway.
130-
6. API Gateway passes through the http response to the client.
131-
132-
You'll find a detailed narrative explanation of the design strategy in this article, [OpenAI API With AWS Lambda](https://blog.lawrencemcdaniel.com/openai-api-with-aws-lambda/)
133-
134-
### Services and Technologies Used
135-
136-
* **[OpenAI](https://pypi.org/project/openai/)**: a PyPi package thata provides convenient access to the OpenAI API from applications written in the Python language. It includes a pre-defined set of classes for API resources that initialize themselves dynamically from API responses which makes it compatible with a wide range of versions of the OpenAI API.
137-
* **[API Gateway](https://aws.amazon.com/api-gateway/)**: an AWS service for creating, publishing, maintaining, monitoring, and securing REST, HTTP, and WebSocket APIs at any scale.
138-
* **[IAM](https://aws.amazon.com/iam/)**: a web service that helps you securely control access to AWS resources. With IAM, you can centrally manage permissions that control which AWS resources users can access. You use IAM to control who is authenticated (signed in) and authorized (has permissions) to use resources.
139-
* **[Lambda](https://aws.amazon.com/lambda/)**: an event-driven, serverless computing platform provided by Amazon as a part of Amazon Web Services. It is a computing service that runs code in response to events and automatically manages the computing resources required by that code. It was introduced on November 13, 2014.
140-
* **[CloudWatch](https://aws.amazon.com/cloudwatch/)**: CloudWatch enables you to monitor your complete stack (applications, infrastructure, network, and services) and use alarms, logs, and events data to take automated actions and reduce mean time to resolution (MTTR).
141-
* **[Route53](https://aws.amazon.com/route53/)**: (OPTIONAL). a scalable and highly available Domain Name System service. Released on December 5, 2010.
142-
* **[Certificate Manager](https://aws.amazon.com/certificate-manager/)**: (OPTIONAL). handles the complexity of creating, storing, and renewing public and private SSL/TLS X.509 certificates and keys that protect your AWS websites and applications.
143-
144-
## OpenAI API
145-
146-
This project leverages the official [OpenAI PyPi](https://pypi.org/project/openai/) Python library. The openai library is added to the AWS Lambda installation package. You can review [terraform/lambda_openai_text.tf](./terraform/lambda_openai_text.tf) to see how this actually happens from a technical perspective.
147-
148-
Other reference materials on how to use this libary:
149-
150-
- [How to Get an OpenAI API Key](./doc/openai-api-key.md)
151-
- [OpenAI Official Example Applications](https://platform.openai.com/examples)
152-
- [OpenAI API Documentation](https://platform.openai.com/docs/api-reference/making-requests?lang=python)
153-
- [OpenAI PyPi](https://pypi.org/project/openai/)
154-
- [OpenAI Python Source](https://github.com/openai/openai-python)
155-
- [OpenAI Official Cookbook](https://github.com/openai/openai-cookbook/)
156-
157-
Be aware that the OpenAI platform API is not free. Moreover, the costing models vary signficantly across the family of OpenAI models. GPT-4 for example cost significantly more to use than GPT-3.5. Having said that, for development purposes, the cost likely will be negligible. I spent a total of around $0.025 USD while developing and testing the initial release of this project, whereupon I invoked the openai api around 200 times (rough guess).
158-
159-
## Trouble Shooting and Logging
160-
161-
The terraform scripts will automatically create a collection of CloudWatch Log Groups. Additionally, note the Terraform global variable 'debug_mode' (defaults to 'true') which will increase the verbosity of log entries in the [Lambda functions](./terraform/python/), which are implemented with Python.
162-
163-
I refined the contents and formatting of each log group to suit my own needs while building this solution, and in particular while coding the Python Lambda functions.
164-
165-
![CloudWatch Logs](https://raw.githubusercontent.com/FullStackWithLawrence/aws-openai/main/doc/cloudwatch-1.png "CloudWatch Logs")
166-
![CloudWatch Logs](https://raw.githubusercontent.com/FullStackWithLawrence/aws-openai/main/doc/cloudwatch-2.png "CloudWatch Logs")
167-
16832
## Documentation
16933

17034
Detailed documentation for each endpoint is available here: [Documentation](./doc/examples/)

0 commit comments

Comments
 (0)