33using Newtonsoft . Json ;
44using System . Threading . Tasks ;
55using UnityEngine . Networking ;
6+ using System . Collections . Generic ;
67using Newtonsoft . Json . Serialization ;
78
8- #if ! UNITY_WEBGL
9- using System . Net . Http ;
10- #endif
11-
129namespace OpenAI
1310{
1411 public class OpenAIApi
@@ -88,24 +85,32 @@ private async Task<T> DispatchRequest<T>(string path, string method, byte[] payl
8885 return data ;
8986 }
9087
91- #if ! UNITY_WEBGL
9288 /// <summary>
9389 /// Dispatches an HTTP request to the specified path with a multi-part data form.
9490 /// </summary>
9591 /// <param name="path">The path to send the request to.</param>
9692 /// <param name="form">A multi-part data form to upload with the request.</param>
9793 /// <typeparam name="T">Response type of the request.</typeparam>
9894 /// <returns>A Task containing the response from the request as the specified type.</returns>
99- private async Task < T > DispatchRequest < T > ( string path , MultipartFormDataContent form ) where T : IResponse
95+ private async Task < T > DispatchRequest < T > ( string path , List < IMultipartFormSection > form ) where T : IResponse
10096 {
101- var client = new HttpClient ( ) ;
102- client . SetHeaders ( Configuration , ContentType . MultipartFormData ) ;
103-
104- var response = await client . PostAsync ( path , form ) ;
105- var content = await response . Content . ReadAsStringAsync ( ) ;
97+ T data ;
10698
107- var data = JsonConvert . DeserializeObject < T > ( content , jsonSerializerSettings ) ;
99+ using ( var request = new UnityWebRequest ( path , "POST" ) )
100+ {
101+ request . SetHeaders ( Configuration ) ;
102+ var boundary = UnityWebRequest . GenerateBoundary ( ) ;
103+ var formSections = UnityWebRequest . SerializeFormSections ( form , boundary ) ;
104+ var contentType = $ "{ ContentType . MultipartFormData } ; boundary={ Encoding . UTF8 . GetString ( boundary ) } ";
105+ request . uploadHandler = new UploadHandlerRaw ( formSections ) { contentType = contentType } ;
106+ request . downloadHandler = ( DownloadHandler ) new DownloadHandlerBuffer ( ) ;
107+ var asyncOperation = request . SendWebRequest ( ) ;
108108
109+ while ( ! asyncOperation . isDone ) await Task . Yield ( ) ;
110+
111+ data = JsonConvert . DeserializeObject < T > ( request . downloadHandler . text , jsonSerializerSettings ) ;
112+ }
113+
109114 if ( data != null && data . Error != null )
110115 {
111116 ApiError error = data . Error ;
@@ -114,7 +119,6 @@ private async Task<T> DispatchRequest<T>(string path, MultipartFormDataContent f
114119
115120 return data ;
116121 }
117- #endif
118122
119123 /// <summary>
120124 /// Create byte array payload from the given request object that contains the parameters.
@@ -184,7 +188,6 @@ public async Task<CreateImageResponse> CreateImage(CreateImageRequest request)
184188 return await DispatchRequest < CreateImageResponse > ( path , UnityWebRequest . kHttpVerbPOST , payload ) ;
185189 }
186190
187- #if ! UNITY_WEBGL
188191 /// <summary>
189192 /// Creates an edited or extended image given an original image and a prompt.
190193 /// </summary>
@@ -193,16 +196,15 @@ public async Task<CreateImageResponse> CreateImage(CreateImageRequest request)
193196 public async Task < CreateImageResponse > CreateImageEdit ( CreateImageEditRequest request )
194197 {
195198 var path = $ "{ BASE_PATH } /images/edits";
196-
197- var form = new MultipartFormDataContent ( ) ;
199+
200+ var form = new List < IMultipartFormSection > ( ) ;
198201 form . AddImage ( request . Image , "image" ) ;
199202 form . AddImage ( request . Mask , "mask" ) ;
200203 form . AddValue ( request . Prompt , "prompt" ) ;
201204 form . AddValue ( request . N , "n" ) ;
202205 form . AddValue ( request . Size , "size" ) ;
203206 form . AddValue ( request . ResponseFormat , "response_format" ) ;
204- form . AddValue ( request . User , "user" ) ;
205-
207+
206208 return await DispatchRequest < CreateImageResponse > ( path , form ) ;
207209 }
208210
@@ -215,15 +217,15 @@ public async Task<CreateImageResponse> CreateImageVariation(CreateImageVariation
215217 {
216218 var path = $ "{ BASE_PATH } /images/variations";
217219
218- var form = new MultipartFormDataContent ( ) ;
220+ var form = new List < IMultipartFormSection > ( ) ;
219221 form . AddImage ( request . Image , "image" ) ;
220222 form . AddValue ( request . N , "n" ) ;
221223 form . AddValue ( request . Size , "size" ) ;
222224 form . AddValue ( request . ResponseFormat , "response_format" ) ;
223225 form . AddValue ( request . User , "user" ) ;
226+
224227 return await DispatchRequest < CreateImageResponse > ( path , form ) ;
225228 }
226- #endif
227229
228230 /// <summary>
229231 /// Creates an embedding vector representing the input text.
@@ -247,7 +249,6 @@ public async Task<ListFilesResponse> ListFiles()
247249 return await DispatchRequest < ListFilesResponse > ( path , UnityWebRequest . kHttpVerbGET ) ;
248250 }
249251
250- #if ! UNITY_WEBGL
251252 /// <summary>
252253 /// Upload a file that contains document(s) to be used across various endpoints/features.
253254 /// Currently, the size of all the files uploaded by one organization can be up to 1 GB.
@@ -259,13 +260,12 @@ public async Task<OpenAIFile> CreateFile(CreateFileRequest request)
259260 {
260261 var path = $ "{ BASE_PATH } /files";
261262
262- var form = new MultipartFormDataContent ( ) ;
263+ var form = new List < IMultipartFormSection > ( ) ;
263264 form . AddJsonl ( request . File , "file" ) ;
264265 form . AddValue ( request . Purpose , "purpose" ) ;
265266
266267 return await DispatchRequest < OpenAIFileResponse > ( path , form ) ;
267268 }
268- #endif
269269
270270 /// <summary>
271271 /// Delete a file.
0 commit comments