1

I'm trying to build a web app using FastAPI.

After lunching the web app and entering this URL into a web browser:

http://localhost:8080/mall/customers/segmentation?genre=Female&age=65&income=38&spending=35

the app will return the prediction for that one instance (i.e., a 65 yo female customer with income of 38K and spending 35K)

How can I modify the above URL to query for two observations, for example: 65 yo female customer with income of 38K and spending 35K AND 50 yo male with income of 40K and spending 37K?

Chris
  • 18,724
  • 6
  • 46
  • 80
Nemo
  • 1,124
  • 2
  • 16
  • 39

2 Answers2

1

I would highly suggest you send the data as a request body (in JSON form) using a POST request instead, as described in the documentation. You can create a Pydantic model (let's say Item), as described in the above documentation, and then define your endpoint to expect a list of that Item (as shown here). For the gender, you could make use of the Python's Literal type, which is supported by Pydantic and allows you specifying that a field may accept only specific literal values. Example is given below. You could test that through OpenAPI at http://127.0.0.1:8000/docs.

from pydantic import BaseModel
from typing import List
from typing import Literal

class Item(BaseModel):
    gender: Literal['male', 'female']
    age: int
    income: int
    spending: int

@app.post("/items")
def create_item(items: List[Item]):
    return items

If you still, however, need to do that using a GET request and query parameters (which I wouldn't suggest), you could define List fields explicitly declared with Query, so that gender, age, etc., can appear multiple times in the URL, and you would have to loop through all the parameters to get your instances (see here and here). Alternatively, you could use arbitrary query parameters, where you send the data in a form that suits you to get your instances. You can get the query params using the Request object, i.e., request.url.query or request.query_params (see this answer for more details). However, in this way, your data won't be validated, and thus, you need to make sure you get the correct types and required parameters for your input data.

Chris
  • 18,724
  • 6
  • 46
  • 80
  • Thanks for your detailed response, Chris. I have no knowledge in fastapi so I'll take time to digest all your information. – Nemo Mar 22 '22 at 11:05
0

As far as I can see you are using a GET query which actually doesn't suit well for querying multiple data.

I suggest you move it to a POST request and use something like the below as a body:

data = [
{
    "gender": "Female", 
    "age": 64,
    "income": 65,
    "spending": 35,

},
{
    "gender": "Male", 
    "age": 33,
    "income": 120,
    "spending": 35,

}...
]

Or I you insist on using GET you might try using the encoding: for instance {foo: ['1', '2', '3']} can be encoded as:

'foo[]=1&foo[]=2&foo[]=3'
'foo[0]=1&foo[1]=2&foo[3]=3'
'foo=1,2,3'
'foo=1&foo=2&foo=3'
// Any custom separator can be used:
'foo=1|2|3'
// ... and more custom formats
Akado2009
  • 381
  • 1
  • 4
  • 11
  • Thanks. I don't know how to do `POST` but the your suggestion on encoding for `GET` seemed easy for me to follow. Where should I do the encoding though? As in the `url` like this `http://localhost:8080/mall/customers/segmentation?genre=Female&genre=Male&age=65&age=50....`? – Nemo Mar 22 '22 at 11:14
  • 1
    @Nemo yes, I believe: https://stackoverflow.com/questions/1763508/passing-arrays-as-url-parameter -- check here :) – Akado2009 Mar 22 '22 at 11:17