2

I am trying this api endpoint. I can call this in python, no problem, like the below

get_model_versions={
    "filter":"name='model_name'",
    "order_by":["version DESC"],
    "max_results":1
}

init_get = requests.get("baseurl/api/2.0/preview/mlflow/model-versions/search",headers=header_read,json=get_model_versions)

However, I just can't seem to find a way to make it work in Powershell.

First the powershell "get" Invoke-RestMethod does not accept a body

and then I can't seem to find a way to append it in Powershell as a query string.

I have tried (among other failed attempts), the following

$get_model_versions=([PSCustomObject]@{
  filter = "name=`'model_name`'"
  order_by = @("version desc")
} | ConvertTo-Json)

$resp=Invoke-RestMethod -Uri $searchuri -Headers $auth -Method Get -Body $get_model_versions

But that gives me an error that body can't be used with a get method

trying to append it as a query string (like if I even just keep the name filter and remove the others), also fails

$searchuri= "baseurl/api/2.0/preview/mlflow/model-versions/search?filter=""name==model_name"""

$resp=Invoke-RestMethod -Uri $searchuri -Headers $auth -Method Get

fails with

{"error_code":"INVALID_PARAMETER_VALUE","message":"Unsupported filter query : `\"name==model_name\"`. Unsupported operator."}

How can I mimic the same behaviour in Powershell, as I do in Python?

EDIT 1: I did try to encode the query param (maybe I did it wrong), but here's how my failed attempt looked like

$encodedvalue = [System.Web.HttpUtility]::UrlEncode("`"name='model_name'`"")
$searchuri= "baseurl/api/2.0/preview/mlflow/model-versions/search?filter=$encodedvalue"

$resp=Invoke-RestMethod -Uri $searchuri -Headers $auth -Method Get

But that too gives me

"Unsupported filter query : `\"name='model_name'\"`. Unsupported operator."

I have also tried it successfully in Postman by passing a raw json body (the same as python) and when I look at the generated PowerShell code in Postman I see this

$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", "Bearer token")
$headers.Add("Content-Type", "application/json")

$body = "{
`n    `"filter`":`"name='model_name'`",
`n    `"order_by`":[`"version DESC`"],
`n    `"max_results`":1
`n}
`n"

$response = Invoke-RestMethod 'baseurl/api/2.0/preview/mlflow/model-versions/search' -Method 'GET' -Headers $headers -Body $body
$response | ConvertTo-Json

But of course that fails (if you copy that in an powershell editor and run it

Invoke-RestMethod : Cannot send a content-body with this verb-type
Saugat Mukherjee
  • 778
  • 8
  • 32
  • try `Invoke-RestMethod -Uri 'baseurl/api/2.0/preview/mlflow/model-versions/search?filter=%22name%3d%27my-model-name%27%22%26max_results%3d1' -Method Get` – Avshalom May 15 '22 at 18:30
  • @Avshalom: Thanks for this but I get an error `{"error_code":"INVALID_PARAMETER_VALUE","message":"Unsupported filter query : `\"name='my-model-name'\"&max_results=1`. Expected binary operations."} ` – Saugat Mukherjee May 15 '22 at 18:44
  • I did try encoding earlier btw , something like `$encodedvalue = [System.Web.HttpUtility]::UrlEncode("`"name='model_name'`"")` and then passing it for the filter param, but that too failed. I will update my question with that attempt as well. – Saugat Mukherjee May 15 '22 at 18:45

1 Answers1

2

Finally, after struggling for a long time, I found the answer !

The crux is in the documentation here. Especially this section

enter image description here

So, if you want to pass on a body for your "get" method in powershell, pass it as a hashtable.

So, finally the answer is

$query=@{"filter"="name='model_name'";"order_by"=@("version DESC"); "max_results"=1};
$searchuri="baseurl/api/2.0/preview/mlflow/model-versions/search"

$resp=Invoke-RestMethod -Uri $searchuri -Headers $auth -Method Get -Body $query

Hope this helps someone looking for something similar.

Saugat Mukherjee
  • 778
  • 8
  • 32
  • Nice; note that this mirrors your Python solution, given that PowerShell's (.NET's) equivalent of Python's `dict` data type is a [hashtable](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Hash_Tables). As for your attempts to construct a query string directly: at least one potential problem is trying to include `"` chars. – mklement0 May 15 '22 at 21:57
  • Yeah , I know. The api specifically mentioned it. But, I tried all possible combinations (with, without) , but it just wouldn’t work with query strings (with or without). I would like to know however, how the hashtable is actually added as a query string (which the doc specifies). I could inspect Fiddler (proxy) logs. – Saugat Mukherjee May 16 '22 at 05:58
  • 1
    You can use the `-Verbose` switch to see the resulting query string constructed from a `-Body` argument; e.g.: `Invoke-RestMethod 'https://postman-echo.com/get' -Body @{ foo1='bar 1'; foo2='bar+2' } -Verbose` – mklement0 May 16 '22 at 15:31