# Challenge Starter This week we will be integrating with OpenAI. Some code will be given to you because the focus of today will be around researching how to authenticate to OpenAI's API and how the API responds based on a given input. We want the response to be as deterministic as possible and you will need to write a prompt that can satify this requirement. ## OpenAI 1. Make a new file called openai.js in the root directory with the following contents: ```js import { Configuration, OpenAIApi } from "openai"; const configuration = new Configuration({ organization: "<>", apiKey: "<>", }); const openai = new OpenAIApi(configuration); export default async function (transactions, categories) { if (!configuration.apiKey) { return "OpenAI API key not configured"; } try { const completion = await openai.createCompletion({ model: "text-davinci-003", prompt: generatePrompt(transactions, categories), temperature: 0.0, max_tokens: 2000, }); return completion.data.choices[0].text; } catch (error) { // Consider adjusting the error handling logic for your use case if (error.response) { console.error(error.response.status, error.response.data); } else { console.error(`Error with OpenAI API request: ${error.message}`); } return "Failed to sort transactions" } } function generatePrompt(transactions, categories) { return ``; } ``` 2. Spend some time understanding how the code works and refactor it to meet your purposes. Again, you will need a prompt that is deterministic and can be used to sort transactions. Because the API can be tough to test, OpenAI has given us a [playground](https://platform.openai.com/playground) to experiment within. 3. Inside your sortTransactions.js file, import the openai.js file and call the function with the transactions and categories. You will need to await the response and then return it. ## Route Endpoint 1. In your app.js file, we will import `neat-csv` to parse the csv text we receive from `sortTransactions` to transform it into a json object and return that to the client. Your complete endpoint should look something like this: ```js app.post('/api/upload/', upload.single('file'), async (req, res) => { if(!req.file) { res.send('No file uploaded.') return } const csvString = req.file.buffer.toString('utf8') let results = await sortTransactions(csvString, ['Bills', 'Groceries', 'Restaurants', 'Entertainment', 'Shopping', 'Travel'] ) let transactions = await neatCsv(results) res.send(transactions) }) ``` ## sortTransactions.js Starting Point ```js import returnCategoriesCSV from './openai.js'; export default async function (transactions, categories) { returnedCSVText = await returnCategoriesCSV(transactions, categories); return returnedCSVText } ``` ## Getting it working through the entire stack You may be asking yourself what is the point of `sortTransactions.js`. You are handling the request and response in `app.js` and you are handling the sorting in `openai.js`. But in between you have the `sortTransactions.js` file. This is where you will be doing the work of parsing the inputs and outputs from the client and openAI in a structured manner taking into account the considerations below. Pseudo code and remembering your advanced array methods like .split() and .join() will be *incredibly* helpful here. There is no "right solution" to this challenge. The goal is to get you thinking about how to structure your code and how to think about the problem. I've solved it in one manner but there are many ways to do it. Be prepared to spend a lot of your effort on thinking about the conceptual steps you will need to take. ### Considerations - What is async/await and how does it work? - How many transactions can you sort at once? - How many requests to the API can you make every minute? ### Warning - The API will be slow, it has to do a lot of work as a Large Language Model.