Integrating OpenAI into a Ruby on Rails/React EdTech App

The craze around and promise of technological language models, such as OpenAI’s ChatGPT, is well deserved. After years of whittling and tailoring Google searches to find even vague answers to our myriad inquiries (often to only be met with unhelpful internet rabbit holes and paid advertisements), it is satisfying to finally feel understood in our quest for very specific knowledge by a ubiquitous and accessible technology. The general moral panics around these platforms (plagiarism, the reliance on technology resulting in the weakening of the human mind, hostile artificial intelligence takeovers, etc.) are akin to Socrates’ objections to the written word. The inherent goodness or evil that lies in these tools is in how we as humans regulate and use them–not in the tool themselves. But that is a blog post for another day.

For prescriptive or repetitive writing, the answer to a specific pondering, or an outline or prompt to boost the creative writing process, these tools are immeasurably helpful. As a former classroom educator and current tech worker and student, I wanted to create an app that would help teachers quickly write end-of-semester or end-of-year student reports as my Flatiron Capstone Project and knew that integrating OpenAI into this app would be a great fit. Any teacher passionate about their career will tell you that the experience is wonderful, but exhausting and replete with extra-curricular administrative and bureaucratic tasks. When I was teaching, writing reports for each of my students in each of my courses at the end of each semester filled me with a sense of dread that is hard to describe for folks outside of the profession. Educators often have anywhere from 50-150 students in their various courses, and creating detailed descriptions of each student’s behavioral and academic strengths and weaknesses is unbelievably tedious and slow. The goal of my Capstone app is to expedite the writing of these reports. By calling on OpenAI with an appropriate prompt and simple data for each student, this app harnesses the power of language models to generate a concise and generic starter report for each student that can then be further edited.

Integrating OpenAI into my Ruby on Rails/React app was challenging for me as a beginner programmer. While OpenAI has a generous usage policy and detailed documentation around Python and JavaScript integration, they do not offer official step-by-step documentation for full integration into a Ruby on Rails/React application. After much internet scouring, trial and error, and even calling upon ChatGPT itself to assist me, I cobbled together a fully functioning API call to OpenAI and was able to successfully return its content back to the client. For the sake of posterity, clarity, and all of the beginner Ruby on Rails developers out there, I am happy to document these steps here.

1. After creating a Rails/React application, add the necessary gems to your Gemfile that can handle API requests. There are a variety of gems that can do this, but I found the rest-client gem to be successful for my project. Type gem ‘rest-client’ into your Gemfile and run bundle install in the project directory in your terminal to install.

Add gem ‘rest-client’ to your Gemfile and bundle install.

2. Sign up for an OpenAI API account here and click API when you log in. This is the platform that provides an API key for your app, along with guidance and references for usage.

3. Generate a personal API Key from within your Profile. This is a secure key that is used in the API call. OpenAI will encrypt this key when it is generated.

OpenAI allows you to generate an API Key to use for your application.

4. Store your encrypted API key in your code editor. If your API key is not securely stored, it will work in development, but OpenAI will disable this key when you push your code to Github or another web service for production. To securely store your key,

a) In the config/environments/development.rb file, store your API key as an environment variable using the following language:

Store your API key in your config/environments/development.rb file.

b) Include this file in the .gitignore file. This will ensure that this file does not get pushed to production or Github and will prevent your secure key from being exposed.

Add the development.rb file to the .gitignore file.

c. For your code to work in production, add the OpenAI API key as an environment variable in your production environment. I used Render and was quickly able to add another environment variable to my web service:

Store your API Key in your production environment.

5. Create a ChatGPT class in your Rails application. I used rails generate to create a model of this in my app’s models folder. The method responsible for taking in the client’s prompt and information and returning a response is defined in this class. Again, for a beginner developer, this was a complex method to define and includes many steps. RestClient requires a few different arguments, which I will go over in detail.

a) Require your API handling gem at the top of your class.

Require ‘rest-client’ at the top of your ChatGPT class.

b) The first argument to supply to RestClient is the API URL. OpenAI has several different versions of Chat and Chat completions to use. The URL you supply RestClient is dependent on the version of ChatGPT you use. I used a recent model, gpt-3.5-turbo, which relies on the URL: https://api.openai.com/v1/chat/completions. I defined a variable with this URL in the first few lines of the Class:

Ensure you are using the correct Base URL for the Chat model you wish to employ.

c) Define the instance method that will take in a user’s prompt and return ChatGPT content. In the following snippet, I define the instance method and the second argument for RestClient–the headers. The headers use our securely stored API Key:

The headers argument will take in your securely stored API Key.

d) Create a data object, the last argument for RestClient. The data object stores information about the app’s model of ChatGPT, the roles of both ChatGPT (the system) and the user (which includes the user’s prompt), the length of the message to be returned (max_tokens), and the temperature (how random or focused the system is).

The data object sets the stage for ChatGPT’s response.

e) Finally, RestClient can generate the Chat response.

6. Generate a ChatController with rails generate. 

7. Create a custom route in config/routes.rb that routes to the ChatController.

8. Define the route in the ChatController that takes in the user’s prompt, calls upon the Class instance to generate a response, and returns the response as json.

9. Create a function on the front end that can take in either a hard-wired or dynamic prompt from the user. And voila!

Though a complex challenge for a beginner programmer, integrating OpenAI with my Ruby on Rails/React app allowed me to more deeply understand API calls, secure environment variables, and translating json between client and server in general. It has also increased the usability and ease of my app significantly, and I am excited to deploy this product for any educator looking to quickly get through those end-of-the-year reports.