Open AI integration with IRIS - File management
Tags: ai, framework, programming, tutorial
Published: 2024-02-27 14:25:52


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/28bnaygtd2m9bavq8v9t.png)
<p>Artificial intelligence is not limited only to generating images through text with instructions or creating narratives with simple directions.</p>
<p>You can also make variations of a picture or include a special background to an already existing one.</p>
<p>Additionally, you can obtain the transcription of audio regardless of its language and the speed of the speaker.</p>
<p>So, let's analyze how the file management works.</p>
<p><!--break--></p>
<h1>The Problem</h1>
<p>When analyzing the OpenAI information about the methods that require a file as an input value, the parameters must be provided using a multipart/form-data.</p>
<p>In IRIS we know how to create a call to a POST method using JSON content. However, in this case, using a parameter with the file content in Base64 format will not be practical.</p>
<p>To include the file content in a multipart/form-data, you must employ the class <a href="https://docs.intersystems.com/irislatest/csp/documatic/%25CSP.Documatic.cls?LIBRARY=%25SYS&amp;CLASSNAME=%25Net.MIMEPart" target="_blank">%Net.MIMEPart</a>.</p>
<p>To include a file in our call, you should create a Content-Disposition header associated with the class object %Net.MIMEPart</p>
<pre class="codeblock-container" idlang="0" lang="ObjectScript" tabsize="4"><code class="language-cls hljs cos"><span class="hljs-keyword">set</span> content = <span class="hljs-keyword">##class</span>(<span class="hljs-built_in">%Net.MIMEPart</span>).<span class="hljs-built_in">%New</span>()
<span class="hljs-keyword">set</span> contentDisposition = <span class="hljs-string">"form-data; name="</span>_<span class="hljs-built_in">$CHAR</span>(<span class="hljs-number">34</span>)_<span class="hljs-string">"image"</span>_<span class="hljs-built_in">$CHAR</span>(<span class="hljs-number">34</span>)
<span class="hljs-keyword">set</span> contentDisposition = contentDisposition_<span class="hljs-string">"; filename="</span>_<span class="hljs-built_in">$CHAR</span>(<span class="hljs-number">34</span>)_fileName_<span class="hljs-built_in">$CHAR</span>(<span class="hljs-number">34</span>)
<span class="hljs-keyword">do</span> content.SetHeader(<span class="hljs-string">"Content-Disposition"</span>,contentDisposition)
</code></pre>
<p>Since we utilize a Request class to retain the values ​​of our process, we must convert the Base64 content into a stream that will constitute the Body of our content.</p>
<p>We can operate the <strong>StreamUtils</strong> utility to convert the Base64 into a Stream.</p>
<p>Note: the “<em>pImage</em>” variable contains the Base64 string of the file content.</p>
<pre class="codeblock-container" idlang="0" lang="ObjectScript" tabsize="4"><code class="language-cls hljs cos"><span class="hljs-keyword">Do</span> <span class="hljs-keyword">##class</span>(HS.Util.StreamUtils).Base64Encode(pImage, .tStream)
<span class="hljs-keyword">Set</span> content.Body = tStream</code></pre>
<p>Yet, there is a better trick that I was lucky enough to learn from an InterSystems expert at the Global Summit 2023. He taught me that the execution is more effective than StreamUtils, which, in the end, has a loop that reads the String and records in the Stream.</p>
<p>This solution is as simple as using a JSON and doing the Get that converts it into a Stream.</p>
<pre class="codeblock-container" idlang="0" lang="ObjectScript" tabsize="4"><code class="language-cls hljs cos"><span class="hljs-keyword">set</span> contentfile = {}
<span class="hljs-keyword">set</span> contentfile.file = pImage
<span class="hljs-keyword">set</span> content.Body = contentfile.<span class="hljs-built_in">%Get</span>(<span class="hljs-string">"file"</span>,,<span class="hljs-string">"stream&lt;base64"</span>)
</code></pre>
<p>Once we have included all the parameters required in the call, we can finally create a new MIMEPart class to enclose the parts.</p>
<pre class="codeblock-container" idlang="0" lang="ObjectScript" tabsize="4"><code class="language-cls hljs cos"><span class="hljs-keyword">Set</span> rootMIME = <span class="hljs-keyword">##class</span>(<span class="hljs-built_in">%Net.MIMEPart</span>).<span class="hljs-built_in">%New</span>()
<span class="hljs-keyword">do</span> rootMIME.Parts.Insert(content)
<span class="hljs-keyword">set</span> writer = <span class="hljs-keyword">##class</span>(<span class="hljs-built_in">%Net.MIMEWriter</span>).<span class="hljs-built_in">%New</span>()
<span class="hljs-keyword">set</span> tSC = writer.OutputToStream(tHttpRequest.EntityBody)
<span class="hljs-keyword">set</span> tSC = writer.WriteMIMEBody(rootMIME)
<span class="hljs-keyword">Set</span> tContentType = <span class="hljs-string">"multipart/form-data; boundary="</span>_rootMIME.Boundary
<span class="hljs-keyword">set</span> tSC = <span class="hljs-built_in">..Adapter</span>.SendFormDataArray(.tHttpResponse, <span class="hljs-string">"POST"</span>, tHttpRequest,,,url)
</code></pre>
<p>This is how we send the file content to the method we need in OpenAI.</p>
<h1>Image files</h1>
<p>The image method allows you to send a picture and perform a variation. Since all illustrations must be in PNG format, when we indicate the file content in Base64 format, the file name is generated randomly with the PNG extension.</p>
<p>Here is an example of how it alters a photo.</p>
<table border="0" cellpadding="1" cellspacing="1" style="width: 550px;">

Original
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hfidujhckmo3ja33kdxy.png)

Variation
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ky1igjkutuu1fbni6nmk.png)

<p>As you can see, the program has interpreted instructions in its own way.</p>
<p>It has decided that the company logo was a circle, so it has replaced it with another one. It has also recognized that the office had a glass door and substituted it with another one but with a brick wall for now.</p>
<p>Besides that, it has modified the color of the shirt and changed the position of the man's arms.</p>
<p>Additionally, OpenIA allows you to edit an image by providing a mask with the area where you want to insert the content indicated in the prompt.</p>
<p>Utilizing the same image, I have applied a mask that has removed the image background.</p>

Original
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iy8c6dz2y4n98zt5wtpx.png)
Mask
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xohgiy5ek5wucqq2y38d.png)


<p>When I asked it to transport me to a Jamaican beach, I got the following result:</p>

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ni39gkk7h91xyh8hezdn.png)

<p>Now you can brag about your holidays the next time you see your friends and family &#x1f60a;</p>
<h2>Image</h2>
<h3>Endpoint: POST <a href="https://api.openai.com/v1/images/variations" target="_blank">https://api.openai.com/v1/images/variations</a></h3>
<p>It allows you to create a modification of an already existing image. Since it does not require a prompt indicating how you want to alter it, we have to trust the AI's taste in how it would interpret this image. In addition, we can define the size and the way we want the result to be returned, be it through a link or content in Base64.</p>
<p>The input parameters would be as mentioned below:</p>
<ul>
<li><strong>image</strong>: Required</li>
<li style="list-style-type: none">Here, you mention the image file that you want to transform.</li>
<li><strong>n</strong>: Optional. Default 1</li>
<li style="list-style-type: none">In this area, you determine the maximum number of images to generate. (Use numbers between 1 and 10).</li>
<li><strong>size</strong>: Optional. Default 1024x1024</li>
<li style="list-style-type: none">This parameter characterizes the size of the generated image. The value here must be “256x256”, “512x512”, or “1024x1024”.</li>
<li><strong>response_format</strong>: Optional. By default, it is “url”</li>
<li style="list-style-type: none">This element is about the format of how you wish the generated images to be returned. The values here should be “url” or “b64_json”.</li>
</ul>
<h3>Endpoint: POST <a href="https://api.openai.com/v1/images/edits" target="_blank">https://api.openai.com/v1/images/edits</a></h3>
<p>It lets you modify an existing image that, based on the mask file, will create a picture according to the prompt. Besides, we can specify the dimensions and the way we want the result to be returned to us, whether through a link or content in Base64.</p>
<p>The input parameters should be as follows:</p>
<ul>
<li><strong>image</strong>: Required</li>
<li style="list-style-type: none">Here, you mention the image file that you want to alter.</li>
<li><strong>mask</strong>: Required</li>
<li style="list-style-type: none">This part is about the mask image file that should be applied.</li>
<li><strong>n</strong>: Optional. Default 1</li>
<li style="list-style-type: none">In this area, you determine the maximum number of images to generate. (Use numbers between 1 and 10).</li>
<li><strong>size</strong>: Optional. Default 1024x1024</li>
<li style="list-style-type: none">This parameter characterizes the size of the generated image. The value here must be “256x256”, “512x512”, or “1024x1024”.</li>
<li><strong>response_format</strong>: Optional. By default, it is “url”</li>
<li style="list-style-type: none">This element is about the format of how you wish the generated images to be returned. The values here should be “url” or “b64_json”.</li>
</ul>
<h1>Audio files</h1>
<p>Images are not the only ones to be managed by OpenAI. We can also use audio files to obtain a transcription or translation of the provided recording.</p>
<p>This method uses the Whisper model, which allows you to differentiate proper names, brands, and slang to provide correct transcription and translation. For instance, talking about the “micromachine” as a brand is not the same as translating “micro machines” as a common noun into Spanish.</p>
<p>The upcoming example is a transcription of a well-known advertising spot from the 80s:</p>
{% embed https://www.youtube.com/watch?v=zLP6oT3uqV8 %}
<p>So, the result of instructing Whisper to make a transcription of the audio for us is as stated below:</p>
<pre>{
    "text": "This is the Micromachine Man presenting the most midget miniature motorcade of micromachines. 
Each one has dramatic details, terrific trim, precision paint jobs, plus incredible micromachine pocket playsets. 
There's a police station, fire station, restaurant, service station, and more. Perfect pocket portables to take anyplace. 
And there are many miniature playsets to play with and each one comes with its own special edition micromachine vehicle and 
fun fantastic features that miraculously move. Raise the boat lift at the airport, marina, man the gun turret at 
the army base, clean your car at the car wash, raise the toll bridge. And these playsets fit together to form a micromachine world.
Micromachine pocket playsets, so tremendously tiny, so perfectly precise, so dazzlingly detailed, you'll want to pocket them all.
Micromachines and micromachine pocket playsets sold separately from Galoob. The smaller they are, the better they are."
}</pre>
<p>It is Amazing! Don't you think so?</p>
<p>The abovementioned outcome is possible due to the training the Whisper model has received. We can see some information about it in the following diagram offered by the OpenAI page.</p>

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wlhig5hspiw3cxe14cu1.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ijpvijcapt21to5g3uec.png)

<p>You can find more information at <a href="https://openai.com/research/whisper">https://openai.com/research/whisper</a></p>
<p>Remember that it is crucial to inform the program about the file name because the service needs to know what type of file it is processing (e.g. WAV, MP3, OGG, etc).</p>
<p>Since we only include the Base64 content in our call, we must also indicate the file extension to create the file name with random text and the suggested extension.</p>
<p>For example, the St.OpenAi.Msg.Audio.AudioRequest message has the “type” property to reveal the kind of audio: MP3, OGG, WAV, FLAC, etc.</p>
<h3>Endpoint: <a href="https://api.openai.com/v1/audio/transcriptions" target="_blank">https://api.openai.com/v1/audio/transcriptions</a></h3>
<p>This method lets you transcribe the audio content into the audio language.</p>
<p>The input parameters should be as follows:</p>
<ul>
<li><strong>file</strong>: Required</li>
<li style="list-style-type: none">Here you specify the audio file that you want to transcribe (not the file name). It supports the following formats: FLAC, MP3, MP4, MPEG, MPGA, M4A, OGG, WAV, or WEBM</li>
<li><strong>model</strong>: Required.</li>
<li style="list-style-type: none">The model to use to make the transcription. For now, only “whisper-1” is available</li>
<li><strong>language</strong>: Optional. By default, it is the audio language.</li>
<li style="list-style-type: none">If indicated, according to ISO-639-1, it will improve accuracy and latency.</li>
<li><strong>prompt</strong>: Optional.</li>
<li style="list-style-type: none">It is an optional text to guide the style of the model or continue the previous audio segment. The message here must match the language of the audio.</li>
<li><strong>response_format</strong>. Optional. By default, it is “json”.</li>
<li style="list-style-type: none">In this part, you clarify the format of the transcription output. Use one of the following options: “json”, “text”, “verbose_json”.</li>
<li><strong>temperature</strong>: Optional. By default, the value is 0.</li>
<li style="list-style-type: none">The sampling temperature should be between 0 and 1. While higher values like 0.8 will make the output more random, lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use the log-likelihood to increase the temperature automatically until certain thresholds are reached.</li>
</ul>
<p>You can see the documentation for this method at <a href="https://platform.openai.com/docs/api-reference/audio/createTranscription">https://platform.openai.com/docs/api-reference/audio/createTranscription&lt;</a>.</p>
<h3>Endpoint: <a href="https://api.openai.com/v1/audio/translations">https://api.openai.com/v1/audio/translations</a></h3>
<p>This method lets you translate the audio content into English.</p>
<p>The input parameters should be as follows:</p>
<ul>
<li><strong>file</strong>: Required</li>
<li style="list-style-type: none">It is the audio file that you wish to translate (not the file name). It supports the following formats: FLAC, MP3, MP4, MPEG, MPGA, M4A, OGG, WAV, or WEBM</li>
<li><strong>model</strong>: Required.</li>
<li style="list-style-type: none">In this field, you type the model to utilize to make the transcription. For now, only “whisper-1” is available.</li>
<li><strong>prompt</strong>: Optional.</li>
<li style="list-style-type: none">It is an optional text to guide the style of the model or continue the previous audio segment. The message here must be in English.</li>
<li><strong>response_format</strong>. Optional. By default, it is “json”.</li>
<li style="list-style-type: none">Here you determine the format of the transcription output in one of the following options: “json”, “text”, “verbose_json”.</li>
<li><strong>temperature</strong>: Optional. By default, the value is 0.</li>
<li style="list-style-type: none">The sampling temperature comes between 0 and 1. Whereas higher values like 0.8 will make the output more random, lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will employ log-likelihood to raise the temperature automatically until particular thresholds are reached.</li>
</ul>
<p>You can explore the documentation for this method at <a href="https://platform.openai.com/docs/api-reference/audio/createTranscription">https://platform.openai.com/docs/api-reference/audio/createTranscription</a>.</p>
<h1>What's next?</h1>
<p>Since OpenAi is in continuous evolution, the next iteration will be the method to convert text into audio, and some other new features.</p>
<p>Remember to mark the article with a “like” if you enjoyed it.</p>