0

I'm writing this code for a project, and I have this class which parses the Weather from OWM. My code for this section looks like this:

class Meteo():
    def __init__(self):
        self.API = pyowm.OWM('My API Key', config_module=None,
                             language='it', subscription_type=None)
        self.location = self.API.weather_at_place('Rome,IT')
        self.weatherdata = self.location.get_weather()
        self.weather = str(self.weatherdata.get_detailed_status())

    def Temperature(self):
        self.tempvalue = self.weatherdata.get_temperature('celsius')
        temperature = str(self.tempvalue.get('temp'))
        return temperature

The problem is, of course that, by running the program at 2 pm, and it's 20°C, by 2am it would still show the same temperature, because (obviously)it stays the temperature it parses at launch. I've searched the web for auto updating a python function but I didn't find a question explaining my case. If someone could answer or point out to me a place where it is explained, I would be very grateful. Thanks

Shade Reogen
  • 136
  • 2
  • 13
  • So put this into a continuous loop. – Jongware Dec 11 '18 at 14:46
  • Which Loop should I use in order to tell it it should update on an hourly basis? – Shade Reogen Dec 11 '18 at 14:48
  • don't recommend a loop, due to resources it takes. What you probably need is a type os scheduler.. Try: https://stackoverflow.com/questions/373335/how-do-i-get-a-cron-like-scheduler-in-python – Aaron_ab Dec 11 '18 at 14:52
  • How are you running your code? Do you execute your code locally or is it part of some continously running application? There are many options, for instance you could run a cron job on an hourly basis. However it depends on your usecase which option makes the most sense. – jimfawkes Dec 11 '18 at 14:53
  • Thank you, this was helpful. I'll delete this question in a few minutes – Shade Reogen Dec 11 '18 at 14:54
  • What you need is a property that has a timestamped cached value so that if the the value is expired you issue a request to get the current value. – Dan D. Dec 11 '18 at 14:55
  • 1
    @DanD. Why so complicated. Just run the code on a preset schedule. – jimfawkes Dec 11 '18 at 15:00

3 Answers3

0

I would just update the weather data and then return the temperature:

def update_weather(self):
    self.weatherdata = self.location.get_weather()
    self.weather = str(self.weatherdata.get_detailed_status())

def Temperature(self):
    update_weather()
    self.tempvalue = self.weatherdata.get_temperature('celsius')
    temperature = str(self.tempvalue.get('temp'))
    return temperature
SilverC4t
  • 85
  • 1
  • 6
0

What you need is a property that has a timestamped cached value so that if the the value is expired you issue a request to get the current value. Something like this: It could be made into a decorator but that would take longer:

class Meteo():
    def __init__(self):
        self.last_update = 0

    def Temperature(self):

        if (time.time() - self.last_update) > 60: # cache the value for 60 seconds
            self.API = pyowm.OWM('My API Key', config_module=None,
                                 language='it', subscription_type=None)
            self.location = self.API.weather_at_place('Rome,IT')
            self.weatherdata = self.location.get_weather()
            self.weather = str(self.weatherdata.get_detailed_status())
            self.last_update = time.time()

        self.tempvalue = self.weatherdata.get_temperature('celsius')
        temperature = str(self.tempvalue.get('temp'))
        return temperature

No matter how often you call Temperature it will only issue one request at most every 60 seconds.

Dan D.
  • 73,243
  • 15
  • 104
  • 123
  • This does not really answer the question. You still need to run your method on some kind of schedule to actually get the current data. This just adds code without solving the problem. (Unless I misunderstood the question.) – jimfawkes Dec 11 '18 at 15:05
  • @jimfawkes The issue was that the program was only fetching the weather once when the program was started. – Dan D. Dec 11 '18 at 16:12
  • This is effectively a rate limited version of simply requesting the current weather every time we ask for the temperature. – Dan D. Dec 11 '18 at 16:15
  • Yes, your code makes sure, that the data is not updated on a greater frequency than once every minute. Your code does not actually solve the problem of retrieving the data in some form of loop or schedule. The question is about actually updating the data and not limiting the update. And if you set a schedule on which to update (e.g., every hour), your code is not relevant and it adds logic without the need for it. You are solving a problem which does not occur (at least in the question). – jimfawkes Dec 11 '18 at 16:57
0

In general, there is no magic going on. If you need current data, you will need to fetch it.

There are many conditions you could choose to trigger the 'data update' e.g., if you are processing the data in some form or on a schedule.

If it is sufficient in your use-case to fetch the current temperature on an hourly basis, it sounds like some form of a cron job would solve your problem. The whole point of a cron job is to execute tasks on a preset schedule. Checkout Wikipedia.

Maybe the link from Aaron_ab (How do I get a Cron like scheduler in Python?) fits best in your scenario. Or perhaps take a look at Celery Beat.

If you do not need your application running the entire time, it might be best to use cron on your OS and let it execute your application whenever it is necessary.

jimfawkes
  • 357
  • 2
  • 12