Use Open AI’s APIs in Flutter without Plugins

0



 Introduction: OpenAI Flutter

One of the most transformative applied sciences in improvement today, and one that most would agree will play an an increasing number of essential function in the years to come, is laptop gaining knowledge of or, colloquially, “artificial intelligence.” Machine studying is an expansive science with many, many applications. One specific area inside the computing device getting to know discipline is herbal language processing (NLP) and one of the agencies at the forefront of this technological know-how is OpenAI. OpenAI is satisfactory recognised for its GPT-3 language mannequin which is designed to produce human-like textual content in a range of scenarios. 

In this article, we will be gaining knowledge of how to use OpenAI’s herbal language processing APIs in your Flutter apps except relying on third-party libraries or any dependencies past plugins developed with the aid of the Flutter and Dart teams. This will allow you to use the effective computer gaining knowledge of equipment supplied with the aid of OpenAI in your Flutter web, mobile, and computer apps.

So, whether or not you are constructing a clever digital assistant, a content material moderation system, a textual content prediction input, a sentiment evaluation service, or, as is the case with the instance we will cowl in this tutorial, a vain work of satire, by way of the cease of this article you will at least be in a position to ship requests to the OpenAI’s laptop mastering structures and get responses back. What you do with these responses is up to you. 


Let’s get started.

Example Project: Partly Windy:

Actually, earlier than we get started, let’s get acquainted with the instance Flutter app we will be the use of in this article.

We will be making a Flutter app that leverages OpenAI textual content completion to provide us the climate forecast. No greater messing with rain gages and these spinning wind velocity gadgets, we are going to get our climate forecasts proper from the burning heart of pc science achievement, desktop learning. The app is named “Partly Windy.” 

This app is a satirical remark on the tendency for contemporary computer studying applied sciences to reply apparently easy questions with wildly inaccurate, and frequently nonsensical, responses. However, this app will provide us the probability to discover making requests and receiving responses from OpenAI’s APIs.

In this article, we will be focusing in mainly on the structures used to put into effect an OpenAI API layer. You can test out some of the different articles about Partly Windy for discussions of different components of this app.

Alright, now let’s get started. 


OpenAI API Integration Overview.

Before diving into the code, it will probable be beneficial to get a huge overview of the structure we will be the usage of to combine OpenAI API calls into our Flutter app, like having a photo on the puzzle container earlier than beginning to collect the pieces. Throughout the the rest of this article, we will work on constructing 4 primary files:


We will create a easy file to keep your OpenAI API key used to authenticate API calls to OpenAI endpoints. We will make certain to rule out this file from model manage to defend the API key.

We will create a type to symbolize API requests despatched to OpenAI endpoints.

We will create a classification to characterize API responses acquired from OpenAI endpoints.

We will create a type containing strategies and data used to engage with the OpenAI APIs. This is the category that the relaxation of the app will use to engage with OpenAI’s ML models. 




In phrases of standard venture organization, there is no proper answer. In the Partly Windy instance project, all these archives are saved in the identical directory, placed at lib/openai


Step 1: Create an OpenAI Account.

The first interesting step in constructing a Flutter app powered with the aid of OpenAI’s reducing part computer mastering technologies… is to take care of a bit of paperwork. Machine getting to know engineers don’t come low-cost so earlier than you can use the OpenAI APIs, you will want to signal up for an account and set up billing. The true information is that, for primary experimentation and learning, the expenses for the usage of the APIs are pretty low. 


So, to signal up for your OpenAI account, head over to the OpenAI website and honestly comply with alongside with the signup process. 


Step 2: Create an API Request Class

Let’s begin by means of putting up a type used to characterize a request that we will ship to OpenAI. This is a beneficial technique that can be used for most RESTful APIs and it begins by using studying over the documentation for the endpoint you prefer to use. OpenAI gives API documentation on their website: https://beta.openai.com/docs/api-reference/completions/create.


The parameters used in the “completions” endpoint will be the groundwork for growing the CompletionsRequest class. Note that this classification will be used to characterize simply the physique of the API request. We will take care of the request headers in a exclusive class. 


{

  "model": "text-curie-001",

  "prompt": "Say this is a test",

  "max_tokens": 6,

  "temperature": 0,

  "top_p": 1,

  "n": 1,

  "stream": false,

  "logprobs": null,

  "stop": "\n"

}


First of all, create a new Dart file to maintain the category representing the API request. In Partly Windy, this file is named “completions_request.dart.”

Then, inner this file, create a new type named “CompletionsRequest.” The type will incorporate fields for every of the parameters used in the OpenAI completions endpoint listed above. Among these parameters, some are required and have to be protected in the API request, whilst others are optional. In the CompletionsRequest class, the required parameters will use non-nullable sorts whilst the elective ones will use nullable sorts (denoted via a ? after the kind declaration). 


/// Represents the parameters used in the body of a request to the OpenAI completions endpoint.

class CompletionsRequest {

  final String model;

  final String prompt;

  final int maxTokens;

  final double? temperature;

  final int? topP;

  final int? n;

  final bool? stream;

  final int? longprobs;

  final String? stop;


  CompletionsRequest({

    required this.model,

    required this.prompt,

    required this.maxTokens,

    required this.temperature,

    this.topP,

    this.n,

    this.stream,

    this.longprobs,

    this.stop,

  });

}

There is additionally one approach we will consist of in this class. Since we can’t simply ship the API request in Dart format, we will consist of a feature to convert a CompletionsRequest object to a JSON-formatted String. We will ship this String in the genuine completions API call.

To flip a CompletionsRequest object into a JSON-formatted String, we will first convert all the non-null fields into a Map<string, dynamic=""> object. Then we will use Dart’s convert library to flip the Map into a JSON String. Then we will return the resulting String.</string,> 

String toJson() {

    Map<String, dynamic> jsonBody = {

      'model': model,

      'prompt': prompt,

      'max_tokens': maxTokens,

    };


    if (temperature != null) {

      jsonBody.addAll({'temperature': temperature});

    }


    if (topP != null) {

      jsonBody.addAll({'top_p': topP});

    }


    if (n != null) {

      jsonBody.addAll({'n': n});

    }


    if (stream != null) {

      jsonBody.addAll({'stream': stream});

    }


    if (longprobs != null) {

      jsonBody.addAll({'longprobs': longprobs});

    }


    if (stop != null) {

      jsonBody.addAll({'stop': stop});

    }


    return json.encode(jsonBody);

  }


With that function in place, the CompletionsRequest class is complete.

Step 3: Create an API Response Class

We will comply with a very comparable manner to create a category to signify responses obtained from the OpenAI completions endpoint. We will as soon as once more begin via studying over the completions endpoint documentation to apprehend the structure of the responses back from the API, and the fields these responses are anticipated to contain. 

{

  "id": "cmpl-uqkvlQyYK7bGYrRHQ0eXlWi7",

  "object": "text_completion",

  "created": 1589478378,

  "model": "text-curie-001",

  "choices": [

    {

      "text": "\n\nThis is a test",

      "index": 0,

      "logprobs": null,

      "finish_reason": "length"

    }

  ],

  "usage": {

    "prompt_tokens": 5,

    "completion_tokens": 6,

    "total_tokens": 11

  }

}

We will create a new file to comprise the classification we are about to complete. In the Partly Windy app, this file is referred to as “completions_response.dart.”

Inside this file, create a new classification referred to as “CompletionsResponse.” Just like we did for the classification representing API requests, the CompletionsResponse classification will incorporate fields for every of the parameters we assume to be again in the completions API responses. However, we choose to make positive that our app will no longer crash in the match that, for some thing reason, the API response does now not include one or greater anticipated fields. Therefore, we will make all the fields in this type nullable so that we can gracefully manage these fields being lacking or containing sudden null values. 

class CompletionsResponse {

  final String? id;

  final String object;

  final int? created;

  final String? model;

  final List<dynamic>? choices; // This list contains the completions

  final Map<String, dynamic>? usage;

  final int? promptTokens;

  final int? completionTokens;

  final int? totalTokens;

  final String? firstCompletion;


  const CompletionsResponse({

    required this.id,

    required this.object,

    required this.created,

    required this.model,

    required this.choices,

    required this.usage,

    required this.promptTokens,

    required this.completionTokens,

    required this.totalTokens,

    required this.firstCompletion,

    });

  }

You will note that I truely covered one greater subject in this class, the firstCompletion field. This subject is now not certainly protected in the OpenAI completions API response, however due to the fact of the way the Partly Windy app makes use of the API responses, it is beneficial to supply it a speedy way to reference the first completion back with the aid of the API.

We will additionally want one manufacturing facility constructor (which is like a approach that returns an occasion of a class) in this CompletionsResponse class. The genuine response acquired with the aid of the app from the OpenAI API is of course no longer formatted as a Dart class. Instead, it comes in as a JSON-formatted String. Therefore, we will want to create a technique to convert the response String into a CompletionsResponse object. We will put in force the JSON to CompletionsResponse approach in a manufacturing facility constructor. 


/// Returns a [CompletionResponse] from the JSON obtained from the

/// completions endpoint.

factory CompletionsResponse.fromResponse(Response response) {

  // Get the response body in JSON format

  Map<String, dynamic> responseBody = json.decode(response.body);


  // Parse out information from the response

  Map<String, dynamic> usage = responseBody['usage'];


  // Parse out the choices

  List<dynamic> choices = responseBody['choices'];


  // Get the text of the first completion

  String firstCompletion = choices[0]['text'];


  return CompletionsResponse(

    id: responseBody['userId'],

    object: responseBody['id'],

    created: responseBody['title'],

    model: responseBody['model'],

    choices: choices,

    usage: usage,

    promptTokens: usage['prompt_tokens'],

    completionTokens: usage['completion_tokens'],

    totalTokens: usage['total_tokens'],

    firstCompletion: firstCompletion,

  );

}

So now we can check the CompletionsResponse class off the TODO list.

Step 4: Create a File to Store the API Key (and exclude it from version control) 

Let’s take a quick spoil from constructing lessons and make a very easy file instead, however one with an extraordinarily necessary caveat. To authenticate your OpenAI API requests, you will require an API key. This is phase of the motive we wanted to signal up for an OpenAI account.

Get began via developing a new file alongside the different API-related documents we’ve been working on so a ways that will subsequently keep your API key. You can title this file some thing you would like. As an example, I named the one for the Partly Windy app “api_key.dart.”

Now, this file is going to include your tremendous secret OpenAI API key so you want to take some precautions to shield this key. If any person had been to steal it, they may want to use the key to ship API requests to OpenAI and you will get billed for it. Even worse than that, a nefarious character may want to use your API key for some type of dastardly reason and you would get blamed for it. So, as soon as again, make certain you defend your OpenAI API key.

There are a variety of methods to guard your API key that are included in a bunch of distinctive articles. For now, seeing that this is simply a demo project, we will simply be making certain to knock out the file containing the key from model control. To do this, open the .gitignore file in the root listing of your project. You will already have content material in this file so at the end, add the route to the file you simply created to shop the API key. 

# API authentication
/lib/openai/api_key.dart

With this line added, Git will now not song adjustments to this file and it will now not push the file to GitHub if you host your repository there. Now that we made positive to rule out the API key file from model control, we can add the API key to this file.

On the OpenAI website, you can locate your API key below your profile: https://beta.openai.com/account/api-keys 



Next to your secret key, faucet the Copy button. Then, create a new String variable in api_key.dart referred to as “openAIAPIKey” and paste in your key. 


So now, when we want to use the secret key in different components of the code, we can simply import api_key.dart and reference this variable. 

Step 5: Create an OpenAI API Class

We have one greater category to make and it is the one that knits all the different components we’ve made so some distance together. We have training that symbolize the API requests and responses, plus a file to preserve the API key used for authentication. So now we want one greater classification that will use these different components to speak with the OpenAI APIs.

Create a new file in the equal location as the others known as “completions_api.dart.” Inside this file, create a new category known as CompletionsAPI.

We will once once more flip to the OpenAI documentation to set up the fields in this class. We want two portions of information. First we will want the API endpoint, which is the URL to which the app will send the data contained inside the CompletionsRequest objects. This equal area of the documentation additionally lets us be aware of that this is a POST request. 

POST https://api.openai.com/v1/completions

Since this endpoint will not change, we will create a static field in the CompletionsApi class to store it as a String.

// The completions endpoint
static final Uri completionsEndpoint = Uri.parse('https://api.openai.com/v1/completions');

Next up, we will want the headers used for the endpoint. The CompletionsRequest category includes all the records wanted in the request body, however the headers are continually the same, regardless of the physique content. In the OpenAI documentation, you can see the headers in cURL format: 

-H 'Content-Type: application/json' \
-H 'Authorization: Bearer YOUR_API_KEY' \

Just like the API endpoint, these headers will remain the same for all API requests, so we will define them as a static field in the CompletionsApi class. In Dart we will define these headers in a Map<String, String>.

// The headers for the completions endpoint, which are the same for all requests
static final Map<String, String> headers = {
  'Content-Type': 'application/json',
  'Authorization': 'Bearer $openAIApiKey',

Then there is one other small bit of preparation to complete. We will use a Dart library to send the RESTful API request, the http library. Follow the instructions provided by the http library documentation to install and import the library.

Next up, we finally come to the method that does all the hard work for interacting with the OpenAI completions API. In the CompletionsApi class, we will create a method to send a REST API request to OpenAI. The method uses the following process to retrieve a response from the ML model:

Create a new CompletionsRequest object.
Send the CompletionsRequest, converted to JSON, to OpenAI and get a response back.
Check to make sure the API call was successful.
Create and return a new CompletionsResponse object.

/// Gets a "weather forecast" from the OpenAI completions endpoint
static Future<CompletionsResponse> getNewForecast() async {
  debugPrint('Getting a new weather forecast');

  CompletionsRequest request = CompletionsRequest(
    model: 'text-curie-001',
    prompt: 'Today's forecast is',
    maxTokens: 9,
    temperature: 0.6,
  );
  debugPrint('Sending OpenAI API request with prompt, "${completionsPrompts[promptIndex]}", and temperature, $temp.');
  http.Response response = await http.post(completionsEndpoint,
      headers: headers, body: request.toJson());
  debugPrint('Received OpenAI API response: ${response.body}');
  // Check to see if there was an error
  if (response.statusCode != 200) {
    // TODO handle errors
    debugPrint('Failed to get a forecast with status code, ${response.statusCode}');
  }
  CompletionsResponse completionsResponse = CompletionsResponse.fromResponse(response);
  return completionsResponse;
}

In the Partly Windy repository, you will discover a range of enhancements to this primary technique that adds extra range to the responses the app receives from OpenAI. The app consists of a listing of prompts that the getNewForecast technique chooses randomly. This provides some range to the responses the OpenAI ML mannequin generates. The app additionally generates a random temperature between 0.6 and 0.9. The greater the temperature, the extra “creative” the responses become. Randomly various temperature additionally helps provide a greater range to the responses. 

Step 6: Using the Completions API

At this factor, we have an absolutely practical integration for the OpenAI completions API in our Flutter app. The sole step final is to use this new capability. Since the getNewForecast approach returns a Future, the best way to use the approach is the usage of a FutureBuilder widget. 

return FutureBuilder(
  future: CompletionsApi.getForecast(constraints.maxWidth < 300 ? 6 : 9),
  builder: (BuildContext context, AsyncSnapshot<String?> forecast) {
    if (forecast.hasData) {
      dailyForecast = forecast.data;
      return Text(dailyForecast);
    } else {
      // Display a loading indicator while waiting for the forecast
      return const CircularProgressIndicator();
    }
  },
);

In this article we built-in OpenAI’s ML-powered APIs into a Flutter app barring the usage of any third-party plugins. The solely plugin used used to be the Dart http library. The Partly Windy instance app integrates the OpenAI APIs by using together with instructions to characterize requests to these APIs, responses acquired from these APIs, and the API calls themselves. Authentication for these APIs makes use of an API token bought after signing up for an account on the OpenAI website.

You ought to construct the ideas mentioned in this article in myriad exceptional ways. Machine getting to know applied sciences are already accountable for large adjustments in our world and societies and the tempo of alternate will solely amplify as the science turns into greater and greater sophisticated. Natural language processing technologies, like the ones used in this article, existing thrilling approaches to introducing intuitive interactivity into Flutter apps.

Thanks very lot for analyzing and joyful Fluttering! 

Post a Comment

0Comments
* Please Don't Spam Here. All the Comments are Reviewed by Admin.
Post a Comment (0)

#buttons=(Accept !) #days=(20)

Our website uses cookies to enhance your experience. Learn More
Accept !