Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add configurable timeout to the request call. #58

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ Parameters:
- **units** - (optional) A string of the preferred units of measurement, "auto" is the default. "us","ca","uk","si" are also available. See the API Docs (https://darksky.net/dev/docs/forecast) for exactly what each unit means.
- **lazy** - (optional) Defaults to `false`. If `true` the function will request the json data as it is needed. Results in more requests, but maybe a faster response time.
- **callback** - (optional) Pass a function to be used as a callback. If used, load_forecast() will use an asynchronous HTTP call and **will not return the forecast object directly**, instead it will be passed to the callback function. Make sure it can accept it.
- **timeout** - (optional) The timeout in seconds. (Defaults to 3 seconds)

----------------------------------------------------

Expand Down Expand Up @@ -196,4 +197,4 @@ Be caerful, things can get confusing when doing something like the below. Given

The result is actually a request for the weather in the future in Amsterdam (by 6 hours). In addition, since all returned times are in UTC, it will report a time two hours behind the *local* time in Amsterdam.

If you're doing lots of queries in the past/future in different locations, the best approach is to consistently use UTC time. Keep in mind ``datetime.datetime.utcnow()`` is **still a naive datetime**. To use proper timezone aware datetime objects you will need to use a library like `pytz <http://pytz.sourceforge.net/>`_
If you're doing lots of queries in the past/future in different locations, the best approach is to consistently use UTC time. Keep in mind ``datetime.datetime.utcnow()`` is **still a naive datetime**. To use proper timezone aware datetime objects you will need to use a library like `pytz <http://pytz.sourceforge.net/>`_
46 changes: 24 additions & 22 deletions forecastio/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,28 @@

from forecastio.models import Forecast

CONST_TIMEOUT = 3.0

def load_forecast(key, lat, lng, time=None, units="auto", lang="en", lazy=False,
callback=None):

def load_forecast(key, lat, lng, time=None, units="auto", lang="en",
lazy=False, callback=None, timeout=CONST_TIMEOUT):
"""
This function builds the request url and loads some or all of the
needed json depending on lazy is True

inLat: The latitude of the forecast
inLong: The longitude of the forecast
time: A datetime.datetime object representing the desired time of
the forecast. If no timezone is present, the API assumes local
time at the provided latitude and longitude.
units: A string of the preferred units of measurement, "auto" id
default. also us,ca,uk,si is available
lang: Return summary properties in the desired language
lazy: Defaults to false. The function will only request the json
data as it is needed. Results in more requests, but
probably a faster response time (I haven't checked)
inLat: The latitude of the forecast
inLong: The longitude of the forecast
time: A datetime.datetime object representing the desired time of
the forecast. If no timezone is present, the API assumes local
time at the provided latitude and longitude.
units: A string of the preferred units of measurement, "auto" id
default. also us,ca,uk,si is available
lang: Return summary properties in the desired language
lazy: Defaults to false. The function will only request the json
data as it is needed. Results in more requests, but
probably a faster response time (I haven't checked)
timeout: The timeout in seconds. Defaults to 3 seconds.
"""

if time is None:
url = 'https://api.darksky.net/forecast/%s/%s,%s' \
'?units=%s&lang=%s' % (key, lat, lng, units, lang)
Expand All @@ -38,25 +40,25 @@ def load_forecast(key, lat, lng, time=None, units="auto", lang="en", lazy=False,
else:
baseURL = url

return manual(baseURL, callback=callback)
return manual(baseURL, callback=callback, timeout=timeout)


def manual(requestURL, callback=None):
def manual(requestURL, callback=None, timeout=CONST_TIMEOUT):
"""
This function is used by load_forecast OR by users to manually
construct the URL for an API call.
"""

if callback is None:
return get_forecast(requestURL)
return get_forecast(requestURL, timeout)
else:
thread = threading.Thread(target=load_async,
args=(requestURL, callback))
args=(requestURL, callback, timeout))
thread.start()


def get_forecast(requestURL):
forecastio_reponse = requests.get(requestURL)
def get_forecast(requestURL, timeout=CONST_TIMEOUT):
forecastio_reponse = requests.get(requestURL, timeout=timeout)
forecastio_reponse.raise_for_status()

json = forecastio_reponse.json()
Expand All @@ -65,5 +67,5 @@ def get_forecast(requestURL):
return Forecast(json, forecastio_reponse, headers)


def load_async(url, callback):
callback(get_forecast(url))
def load_async(url, callback, timeout=CONST_TIMEOUT):
callback(get_forecast(url, timeout=timeout))