Luke Simpson
Luke Simpson

Reputation: 53

Passing query-prameters in an API-request

Why do I need to use a dictionary and set the parameters? Such as lat, lng in following:

parameters = {
    "lat": MY_LAT,
    "lng": MY_LONG,
    "formatted": 0
}

response = requests.get(url="https://api.sunrise-sunset.org/json", params=parameters)

Why can't I do the below, for instance to put in latitude?

response = requests.get(url="https://api.sunrise-sunset.org/json", params=parameters, lat=MY_LAT)

Upvotes: 5

Views: 10786

Answers (3)

hc_dev
hc_dev

Reputation: 9377

Your thoughts steer in the right direction, conceptually.

Passing query-parameters as arbitrary key-value pairs

Calling the requests.get method with arguments like lat=MY_LAT is exactly what the method needs. But the designer(s) of the requests library wanted to keep the method generic. That means, it should be suitable for all GET requests, no matter, what their query-parameters will be.

Hence, not knowing upfront, what the future query-parameters would be named, what type they require, or how many of them are needed, they couldn't have named and counted them fix. The opposite was the case: The query-parameters should be flexible and sticking to the HTTP query-string specification (RFC). So, why not design one single parameter that holds this query-string, or its components as flexible key-value pairs ?!

A dictionary parameter like kwargs as multi-purpose bag

Whenever you like to design a method for an arbitrary number of parameters, you will craft a parameter like commonly-known kwargs. This is actually a dictionary or map, that can hold as many and as manifold named parameters.

The parameter named params works pretty similar

Now, the parameter called params in requests.get() method is exactly that dictionary where you can put in as manifold key-value pairs.

In your case:

parameters = {
    "lat": MY_LAT,
    "lng": MY_LONG,
    "formatted": 0
}

parameters as defined above is that dictionary or map. It can be used as catch-all single param to hold all the query-parameters with their arbitrary names and values. Just as currently required for the web-API or URL resource called.

You can wrap the call, explicitly using the coordinates

What you can do, especially in domain-driven design, wrap the GET call in your own method. For example:

def get_sunrise_sunset_for(lat, lng):
    parameters = {
        "lat": lat,
        "lng": lng,
        "formatted": 0
    }
    response = requests.get(url="https://api.sunrise-sunset.org/json", params=parameters)
    return response.json() # actually you would parse and return extracted times, etc.

There you designed it for a specific purpose (sunset/sunrise, instead of generic HTTP GET). So you can use parameters lat and lng explicitly. Furthermore you can return a specific response, like day-times.

Upvotes: 5

Bill the Lizard
Bill the Lizard

Reputation: 405675

You can't pass the arguments by name because the Python requests library doesn't know what parameters a given URL accepts. The API at sunrise-sunset.org takes lat and lng parameters, but most other APIs would have no use for them. By passing a dictionary of key=value pairs, you tell requests both the names and values of the parameters expected by the specific API you're calling.

Upvotes: 0

dir
dir

Reputation: 719

Because this is how the library you're using (requests) works. It's also how Python and almost every programming language handles method parameters.

Have you ever written a function like...

def add(a, b):
    return a + b

Notice how it's very clear what a and b are.

The same goes for the library you're using, requests. It doesn't know that the endpoint you are posting to has a lat parameter, how would it figure that out? How would you handle errors not knowing if parameters are correct or not?

If I were you, I'd read up on how parameters are handled in Python methods, and also on HTTP requests, and maybe that will help you see why they can't align.

Upvotes: 0

Related Questions