Reputation: 53
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
Reputation: 9377
Your thoughts steer in the right direction, conceptually.
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 ?!
kwargs
as multi-purpose bagWhenever 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.
params
works pretty similarNow, 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.
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
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
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