![](https://alexholmeset.blog/wp-content/uploads/2024/05/image-14.png?w=1024)
On May 13th GPT-4o was released in preview in the Azure OpenAI Playground. No API access, only accessible in the browser. Today I was going into the playground to test something with the GPT-4o model, but could not find it. What had happened? Turnes out it suddenly was in GA and available to choose under Deploy model. The API version was 2024-05-13. I found some documentation on it here, but nothing about how to do the API requests.
![](https://alexholmeset.blog/wp-content/uploads/2024/05/image-8.png?w=591)
I figured it might use the same request as the Vision models as I was going to do calls with text/image. I created a PowerShell script using the deployment I created with API version 2024-05-13, but I got the following error:
![](https://alexholmeset.blog/wp-content/uploads/2024/05/image-10.png?w=1024)
Looks like it could not find the endpoint. Why was that happening? My first thought was to see what API calls the playground was doing in the background, so I opened dev mode in my browser. Turns out the API version the playground was using was 2024-04-01-preview, even though the only model deployed was GPT-4o with version 2024-05-13. I tried switching to 2024-04-01-preview when doing the API calls in PowerShell, and it worked!
![](https://alexholmeset.blog/wp-content/uploads/2024/05/image-11.png?w=1024)
So I have created a PowerShell script that keeps the context of the conversation, analyze images and get responses based on them. I have written the script so you can both use local images and URL from online images. Below you have a couple examples of what is possible to do. All the way at the bottom I have the script I wrote.
![](https://alexholmeset.blog/wp-content/uploads/2024/05/cards.jpg?w=768)
![](https://alexholmeset.blog/wp-content/uploads/2024/05/image.png?w=1024)
![](https://alexholmeset.blog/wp-content/uploads/2024/05/mario3.jpg?w=768)
![](https://alexholmeset.blog/wp-content/uploads/2024/05/image-1.png?w=1024)
![](https://alexholmeset.blog/wp-content/uploads/2024/05/image-2.png?w=1024)
![](https://alexholmeset.blog/wp-content/uploads/2024/05/mario4.jpg?w=768)
![](https://alexholmeset.blog/wp-content/uploads/2024/05/image-3.png?w=1024)
![](https://alexholmeset.blog/wp-content/uploads/2024/05/img_1091.jpg?w=1024)
![](https://alexholmeset.blog/wp-content/uploads/2024/05/image-4.png?w=1024)
![](https://alexholmeset.blog/wp-content/uploads/2024/05/office.jpg?w=768)
![](https://alexholmeset.blog/wp-content/uploads/2024/05/image-5.png?w=1024)
![](https://alexholmeset.blog/wp-content/uploads/2024/05/image-6.png?w=712)
![](https://alexholmeset.blog/wp-content/uploads/2024/05/image-7.png?w=494)
Here i analyzed 5 images one by one, and then asked to list objects from all of them.
![](https://alexholmeset.blog/wp-content/uploads/2024/05/image-13.png?w=985)
# This function takes a path to a file as a parameter and returns the base64 string of that file. | |
function Get-Photo { | |
param ( | |
[Parameter(Mandatory=$true)] | |
[string]$path | |
) | |
[convert]::ToBase64String((get-content $path -Raw -AsByteStream)) | |
} | |
function Get-AzureOpenAIToken{ | |
<# .SYNOPSIS | |
Get an azure token for user or managed identity thats required to authenticate to Azure OpenAI with Rest API. | |
Also construct the header if you are using an Azure OpenAI API key instead of Azure AD authentication. | |
.PARAMETER ManagedIdentity | |
Use this parameter if you want to use a managed identity to authenticate to Azure OpenAI. | |
.PARAMETER User | |
Use this parameter if you want to use a user to authenticate to Azure OpenAI. | |
.PARAMETER APIKey | |
Use this parameter if you want to use an API key to authenticate to Azure OpenAI. | |
.EXAMPLE | |
# Manually specify username and password to acquire an authentication token: | |
Get-AzureOpenAIToken -APIKey "ghgkfhgfgfgkhgh" | |
Get-AzureOpenAIToken -ManagedIdentity $true | |
Get-AzureOpenAIToken -User $true | |
.NOTES | |
Author: Alexander Holmeset | |
Twitter: @AlexHolmeset | |
Website: https://www.alexholmeset.blog | |
Created: 09-02-2023 | |
Updated: | |
Version history: | |
1.0.0 - (09-02-2023) Function created | |
#> | |
[CmdletBinding()] | |
param ( | |
[Parameter(Mandatory=$false)] | |
[string]$APIKey, | |
[Parameter(Mandatory=$false)] | |
[string]$ManagedIdentity, | |
[Parameter(Mandatory=$false)] | |
[string]$User | |
) | |
Process { | |
$ErrorActionPreference = "Stop" | |
if (Get-Module -ListAvailable -Name Az.Accounts) { | |
# Write-Host "You have the Az.Accounts module installed" | |
} | |
else { | |
Write-Host "You need to install the Az.Accounts module"; | |
break | |
} | |
If(!$MyHeader){ | |
If($ManagedIdentity -eq $true){ | |
"managed" | |
try { | |
Connect-AzAccount -Identity | |
$MyTokenRequest = Get-AzAccessToken -ResourceUrl "https://cognitiveservices.azure.com" | |
$MyToken = $MyTokenRequest.token | |
If(!$MyToken){ | |
Write-Warning "Failed to get API access token!" | |
Exit 1 | |
} | |
$Global:MyHeader = @{"Authorization" = "Bearer $MyToken" } | |
} | |
catch [System.Exception] { | |
Write-Warning "Failed to get Access Token, Error message: $($_.Exception.Message)"; break | |
} | |
} | |
If($User -eq $true){ | |
"USER" | |
try { | |
Connect-AzAccount | |
$MyTokenRequest = Get-AzAccessToken -ResourceUrl "https://cognitiveservices.azure.com" | |
$MyToken = $MyTokenRequest.token | |
If(!$MyToken){ | |
Write-Warning "Failed to get API access token!" | |
Exit 1 | |
} | |
$Global:MyHeader = @{"Authorization" = "Bearer $MyToken" } | |
} | |
catch [System.Exception] { | |
Write-Warning "Failed to get Access Token, Error message: $($_.Exception.Message)"; break | |
} | |
} | |
If($APIkey){ | |
"APIKEY" | |
$Global:MyHeader = @{"api-key" = $apikey } | |
} | |
} | |
} | |
} | |
function Get-Chat { | |
<# .SYNOPSIS | |
Get a resposne from the chat endpoint in Azure OpenAI. | |
.PARAMETER DeploymentName | |
A deployment name should be provided. | |
.PARAMETER ResourceName | |
A Resource name should be provided. | |
.PARAMETER Prompt | |
A prompt name should be provided. | |
.PARAMETER Token | |
A token name should be provided. | |
.EXAMPLE | |
Get-Chat -DeploymentName $DeploymentName -ResourceName $ResourceName -maxtokens 1000 -prompt "What is the meaning of life?" -AssitantInstruction $AssitantInstruction | |
.NOTES | |
Author: Alexander Holmeset | |
Twitter: @AlexHolmeset | |
Website: https://www.alexholmeset.blog | |
Created: 09-02-2023 | |
Updated: | |
Version history: | |
1.0.0 - (09-02-2023) Function created | |
#>[CmdletBinding()] | |
param ( | |
[parameter(Mandatory = $false, HelpMessage = "Your azure openai deployment name")] | |
[ValidateNotNullOrEmpty()] | |
[string]$DeploymentName, | |
[parameter(Mandatory = $false, HelpMessage = "your azure openai resource name")] | |
[ValidateNotNullOrEmpty()] | |
[string]$ResourceName, | |
[parameter(Mandatory = $false, HelpMessage = "Your Azure OpenAI prompt")] | |
[ValidateNotNullOrEmpty()] | |
[string]$Prompt, | |
[parameter(Mandatory = $false, HelpMessage = "Your Azure OpenAI service instructions")] | |
[ValidateNotNullOrEmpty()] | |
[string]$AssitantInstruction, | |
[parameter(Mandatory = $true, HelpMessage = "Use photo?")] | |
[ValidateNotNullOrEmpty()] | |
[string]$ReadImage, | |
[parameter(Mandatory = $true, HelpMessage = "Set number of max tokens")] | |
[ValidateNotNullOrEmpty()] | |
[string]$Maxtokens, | |
[parameter(Mandatory = $true, HelpMessage = "Is image local or online?")] | |
[ValidateNotNullOrEmpty()] | |
[string]$ImageLocalOrOnline | |
) | |
Process { | |
$ErrorActionPreference = "Stop" | |
$APIVersion = "2024-04-01-preview" | |
# Construct URI | |
$uri = "https://$ResourceName.openai.azure.com/openai/deployments/$DeploymentName/chat/completions?api-version=$ApiVersion" | |
# Construct Body | |
if ($ReadImage -eq $true) { | |
If($ImageLocalOrOnline -like "online"){ | |
$script:conversation += @" | |
{"role": "user", "content": [{"type": "text", "text": "$Prompt"},{"type": "image_url","image_url": {"url": "$url"}}]}, | |
"@ | |
} | |
else{ $script:conversation += @" | |
{"role": "user", "content": [{"type": "text", "text": "$Prompt"},{"type": "image_url","image_url": {"url": "data:image/jpeg;base64,$photo"}}]}, | |
"@ | |
} | |
} | |
else { | |
$script:conversation += @" | |
{"role": "user", "content": [{"type": "text", "text": "$Prompt"}]}, | |
"@ | |
} | |
$body = @" | |
{ | |
"messages": [ | |
$script:conversation | |
{"role": "system", "content": "$assitantInstruction"} | |
], | |
"max_tokens": $maxtokens, | |
"stream": false | |
} | |
"@ | |
try { | |
$Global:Request = invoke-restmethod -Method POST -Uri $uri -ContentType "application/json" -Body $body -Headers $Global:MyHeader | |
$script:conversation += @" | |
{"role": "assistant", "content": "$($Request.choices.message.content)"}, | |
"@ | |
} | |
catch [System.Exception] { | |
$_ | |
Write-Warning "Failed to to POST request: $($_.Exception.Message)"; break | |
} | |
"User: $Prompt" | |
"Assistant: $($Request.choices.message.content)" | |
} | |
} | |
Get-AzureOpenAIToken -APIKey "Enter API key here." | |
$DeploymentName = "Enter deployment name here." | |
$ResourceName = "Enter resource name here." | |
$AssitantInstruction = "You are a helpfull assistant." | |
#Path to the image to upload. | |
$path = "Enter path to image here." | |
$photo = Get-Photo -path $path | |
#URL to image to upload. | |
$url = "Enter URL to image here." | |
$Prompt = "Please describe this photo." | |
#If doing a request with an image, set ReadImage to true, and ImageLocalOrOnline to either local or online. | |
Get-Chat -DeploymentName $DeploymentName -ResourceName $ResourceName -AssitantInstruction $AssitantInstruction -Prompt $Prompt -ReadImage $true -ImageLocalOrOnline local -maxtokens 4000 | |