What's the syntax for web REST fastAPI GET function, and the request.get function where one of the input variable is List, or Numpy Array

Question:

been driving me crazy with the syntax for the past week, so hopefully an enlightened one can point me out! I’ve traced these posts, but somehow I couldn’t get them to work

I am looking to have an input variable where it is a list, and a numpy array; for feeding into a fastAPI get function, and then calling it via a request.get. Somehow, I cannot get the arguments/syntax correct.

FastAPI POST request with List input raises 422 Unprocessable Entity error

Can FastAPI/Pydantic individually validate input items in a list?

I have the following web API defined :

import typing
from typing import List
from fastapi import Query
from fastapi import FastAPI

 @appOne.get("/sabr/funcThree")
        def funcThree(x1: List[float], x2: np.ndarray):
            return {"x1" : x1, "x2" : x2}

Then, I try to call the function from a jupyter notebook:

import requests
url_ = "http://127.0.0.1:8000/sabr/"
func_ = "funcThree"

items = [1, 2, 3, 4, 5]

params = {"x1" : items, "x2" : np.array([3,100])}
print(url_ + func_)
requests.get(url_ + func_, params = params).json()

I get the following error below…

{'detail': [{'loc': ['body', 'x1'],
   'msg': 'field required',
   'type': 'value_error.missing'}]}

It’s driving me CRAZY …. Help!!!!


though answered in the above, as it is a related question….. I put a little update.

I add in a ‘type_’ field, so that it can return different type of results. But somehow, the json= params is NOT picking it up. Below is the python fastAPI code :

@app.get("/sabr/calib_test2")
    def calib_test2(x1: List[float] = [1, 2, 3], x2: List[float] = [4, 5, 6]
,  type_: int = 1):
        s1 = np.array(x1)
        s2 = np.array(x2)
        # corr = np.corrcoef(x1, x2)[0][1]
        if type_ == 1:
            return {"x1": x1, "x1_sum": s1.sum(), "x2": x2, 
"x2_sum": s2.sum(), "size_x1": s1.shape}
        elif type_ == 2:
            return ['test', x1, s1.sum(), x2, s2.sum(), s1.shape]
        else:
            return [0, 0, 0]

But, it seems somehow the type_ input I am keying in, is NOT being fed-through… Help…

url_ = "http://127.0.0.1:8000/sabr/"
func_ = "calib_test2"
item1 = [1, 2, 3, 4, 5]
item2 = [4, 5, 6, 7, 8]

all_ = url_ + func_
params = {"x1": item1, "x2": item2, "type_": '2', "type_": 2}
resp = requests.get(all_, json = params)
# resp.raise_for_status()
resp.json()

Results keep being :

{'x1': [1.0, 2.0, 3.0, 4.0, 5.0],
 'x1_sum': 15.0,
 'x2': [4.0, 5.0, 6.0, 7.0, 8.0],
 'x2_sum': 30.0,
 'size_x1': [5]}
Asked By: Kiann

||

Answers:

You can’t use a Numpy array directly as a data format. If you’re looking to ingest a 2D numpy array, you’ll

  • need to use POST (there’s no good way to represent a 2D array as a query paremeter)
  • need to cast a list-of-lists back to a numpy array

so the server side ends up looking like

from typing import List

import numpy as np
from fastapi import FastAPI

app = FastAPI()


@app.post("/sabr")
def sabr(x1: List[float], x2: List[List[float]]):
    s = np.array(x2)
    return {"x1": x1, "x2": s.sum(), "size": s.shape}

and on the client side, you’ll need to tolist the numpy array and POST it as JSON:

import numpy as np
import requests

url = "http://127.0.0.1:8000/sabr"
items = [1, 2, 3, 4, 5]
params = {
    "x1": items,
    "x2": np.random.randint(0, 100, size=[3, 100]).tolist(),
}
resp = requests.post(url, json=params)
resp.raise_for_status()
print(resp.json())

This outputs (e.g., since it’s random)

{'x1': [1.0, 2.0, 3.0, 4.0, 5.0], 'x2': 15320.0, 'size': [3, 100]}
Answered By: AKX
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.