{"id":2010,"date":"2020-04-15T21:42:43","date_gmt":"2020-04-15T13:42:43","guid":{"rendered":"https:\/\/www.techcoil.com\/blog\/?p=2010"},"modified":"2020-05-12T14:21:03","modified_gmt":"2020-05-12T06:21:03","slug":"how-to-create-an-interval-task-that-runs-periodically-within-your-python-3-flask-application-with-flask-apscheduler","status":"publish","type":"post","link":"https:\/\/www.techcoil.com\/blog\/how-to-create-an-interval-task-that-runs-periodically-within-your-python-3-flask-application-with-flask-apscheduler\/","title":{"rendered":"How to create an interval task that runs periodically within your Python 3 Flask application with Flask-APScheduler"},"content":{"rendered":"<p>Previously, I talked about <a href=\"https:\/\/www.techcoil.com\/blog\/how-to-use-flask-apscheduler-in-your-python-3-flask-application-to-run-multiple-tasks-in-parallel-from-a-single-http-request\/\" rel=\"noopener\" target=\"_blank\">how to use Flask-APScheduler in your Python 3 Flask application to run multiple tasks in parallel, from a single HTTP request<\/a>.<\/p>\n<p>If you wish to run long running tasks triggered by an <a href=\"https:\/\/www.techcoil.com\/glossary\/http-request\/\" rel=\"noopener\" target=\"_blank\">HTTP request<\/a>, then that post will help you do so.<\/p>\n<p>However, what if you want to run jobs periodically without blocking your Flask <a href=\"https:\/\/www.techcoil.com\/glossary\/http-server\/\" rel=\"noopener\" target=\"_blank\">HTTP server<\/a> from serving HTTP requests?<\/p>\n<p>In this case, you will want to run an interval task with <a href=\"https:\/\/github.com\/viniciuschiele\/flask-apscheduler\" rel=\"noopener\" target=\"_blank\">Flask-APScheduler<\/a>.<\/p>\n<p>Given that, let's look at how we can use Flask-APScheduler to create an interval task within your Python 3 Flask application.<\/p>\n<h2>Some scenarios to run interval tasks within our Python 3 Flask application<\/h2>\n<p>So, under what circumstances do we run interval tasks within our Python 3 Flask application?<\/p>\n<p>Typically, we run interval tasks to prepare data in advance for future HTTP requests that our Flask application receives.<\/p>\n<p>For example, we may want to <a href=\"https:\/\/www.techcoil.com\/blog\/how-to-capture-images-in-the-dark-with-the-raspberry-pi-infrared-camera-module-from-seeed-studio\/\" rel=\"noopener\" target=\"_blank\">capture images in the dark with the Raspberry Pi<\/a>. In such a scenario, we can have an interval task snapping photos in advance. When an HTTP request is received to view the photos, we can then return the most recent photo that was taken earlier.<\/p>\n<p>Another example can be when we <a href=\"https:\/\/www.techcoil.com\/blog\/how-to-read-soil-moisture-level-with-raspberry-pi-and-a-yl-69-fc-28-moisture-sensor\/\" rel=\"noopener\" target=\"_blank\">monitor soil moisture with a Raspberry Pi<\/a>. In such a situation, we can use an interval task to capture time series data for soil moisture. Given that, our Flask application can then serve soil moisture statistics as <a href=\"https:\/\/www.techcoil.com\/glossary\/http-response\/\" rel=\"noopener\" target=\"_blank\">HTTP responses<\/a>.  <\/p>\n<h2>Installing Flask-APScheduler into your Python 3 environment<\/h2>\n<p>In order to use Flask-APScheduler, we will need to install it into our Python environment:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\npip install Flask-APScheduler\r\n<\/pre>\n<h2>Flask-APScheduler built-in trigger types<\/h2>\n<p>Since Flask-APScheduler is based on <a href=\"https:\/\/apscheduler.readthedocs.io\/en\/latest\/\" rel=\"noopener\" target=\"_blank\">APScheduler<\/a>, it has three built-in trigger types:<\/p>\n<ul>\n<li><strong>date<\/strong>: use when you want to run the job just once at a certain point of time<\/li>\n<li><strong>interval<\/strong>: use when you want to run the job at fixed intervals of time<\/li>\n<li><strong>cron<\/strong>: use when you want to run the job periodically at certain time(s) of day<\/li>\n<\/ul>\n<p>For the purpose of our objective, we will be using the <strong>interval<\/strong> trigger type for running interval tasks.<\/p>\n<h2>Example Python 3 Flask application that runs an interval task that updates a value periodically<\/h2>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nfrom flask import Flask\r\nfrom flask_apscheduler import APScheduler\r\n\r\nimport multiprocessing\r\nimport random\r\n\r\napp = Flask(__name__)\r\nscheduler = APScheduler()\r\nscheduler.init_app(app)\r\nscheduler.start()\r\n\r\nINTERVAL_TASK_ID = 'interval-task-id'\r\n\r\nsimulated_room_temperature = multiprocessing.Value('d', 29)\r\n\r\ndef interval_task():\r\n    simulated_room_temperature.value = random.uniform(19, 31)\r\n\r\nscheduler.add_job(id=INTERVAL_TASK_ID, func=interval_task, trigger='interval', seconds=2)\r\n\r\n@app.route('\/')\r\ndef welcome():\r\n    return 'Welcome to Flask_APscheduler interval task demo', 200\r\n\r\n@app.route('\/current-temperature')\r\ndef current_temperature():\r\n    return 'Current temperature is ' + str(simulated_room_temperature.value), 200\r\n\r\n@app.route('\/pause-interval-task')\r\ndef pause_interval_task():\r\n    scheduler.pause_job(id=INTERVAL_TASK_ID)\r\n    return 'Interval task paused', 200\r\n\r\n@app.route('\/resume-interval-task')\r\ndef resume_interval_task():\r\n    scheduler.resume_job(id=INTERVAL_TASK_ID)\r\n    return 'Interval task resumed', 200\r\n\r\napp.run(host='0.0.0.0', port=12345)\r\n<\/pre>\n<p>In order to show how we can use <code>Flask_APScheduler<\/code> to run tasks periodically, let's look at the above Python 3 script.<\/p>\n<p>When you run this script, a Python 3 Flask instance will listen for HTTP requests sent to port 12345 of your computer. In addition to that, the Flask instance will expose 4 routes that respond to HTTP GET requests.<\/p>\n<h2>Understanding the example Python 3 script<\/h2>\n<p>Given these points, let's inspect the script in detail.<\/p>\n<h3>Initializing Flask and APScheduler<\/h3>\n<p>When we had imported the dependencies that are needed, we create a <code>Flask<\/code> object and a <code>APScheduler<\/code> object. After we had created these two objects, we use <code>scheduler.init_app(app)<\/code> to associate our <code>APScheduler<\/code> object with our Flask object.<\/p>\n<h3>Starting the APScheduler object<\/h3>\n<p>Once we had associated the APScheduler object with our Flask object, we start the APScheduler object running in the background. At this point in time, we can add tasks that the APScheduler object will run.<\/p>\n<h3>Creating and running the interval task<\/h3>\n<p>After the APScheduler object had started, we:<\/p>\n<ul>\n<li>define a task id as <code>INTERVAL_TASK_ID<\/code>, <\/li>\n<li>create an instance of <a href=\"https:\/\/docs.python.org\/3\/library\/multiprocessing.html#multiprocessing.Value\" rel=\"noopener\" target=\"_blank\"><code>multiprocessing.Value<\/code><\/a> to keep a simulated temperature reading,<\/li>\n<li>define the <code>interval_task<\/code> function that contains the actions of the interval task. When the function is executed by <code>APScheduler<\/code>, a random value between 19 to 31 is generated by <a href=\"https:\/\/docs.python.org\/3\/library\/random.html#random.uniform\" rel=\"noopener\" target=\"_blank\"><code>random.uniform<\/code><\/a> and updated to the <code>simulated_room_temperature.Value<\/code>.<\/li>\n<li>create an interval job that runs every two seconds via a call to <a href=\"https:\/\/apscheduler.readthedocs.io\/en\/stable\/modules\/schedulers\/base.html#apscheduler.schedulers.base.BaseScheduler.add_job\" rel=\"noopener\" target=\"_blank\"><code>scheduler.add_job<\/code><\/a>.<\/li>\n<\/ul>\n<h3>Returning a HTTP response to a HTTP GET request for the root URL of the Flask application<\/h3>\n<p>When a HTTP request is sent to the root URL of the Flask application, a welcome message is returned.<\/p>\n<h3>Returning a HTTP response to a HTTP GET request for <code>\/current-temperature<\/code><\/h3>\n<p>In order to have a way to visualize the fluctuating temperature, we add a route for <code>\/current-temperature<\/code>. Whenever a HTTP GET request is received at <code>\/current-temperature<\/code>, our Flask instance will response with the current value of <code>simulated_room_temperature<\/code>.<\/p>\n<h3>Pausing the interval task with a HTTP GET request to <code>\/pause-interval-task<\/code><\/h3>\n<p>So how can we stop the interval task from running? When you look at the <code>\/pause-interval-task<\/code> route, you can see that we pause the interval task by running <a href=\"https:\/\/apscheduler.readthedocs.io\/en\/stable\/modules\/schedulers\/base.html#apscheduler.schedulers.base.BaseScheduler.pause_job\" rel=\"noopener\" target=\"_blank\"><code>scheduler.pause_job<\/code><\/a> with the task id.<\/p>\n<h3>Resuming the execution of the interval task with a HTTP GET request to <code>\/resume-interval-task<\/code><\/h3>\n<p>Finally, we also include a route to resume the execution of the interval task. When you look at the <code>\/resume-interval-task<\/code>, you can see that we resume the execution of the interval task by running <a href=\"https:\/\/apscheduler.readthedocs.io\/en\/stable\/modules\/schedulers\/base.html#apscheduler.schedulers.base.BaseScheduler.resume_job\" rel=\"noopener\" target=\"_blank\"><code>scheduler.resume_job<\/code><\/a> with the task id.<\/p>\n<h3>Starting the Python 3 Flask application<\/h3>\n<p>After we had created the routes, we start our Python 3 Flask application through a call to <code>app.run<\/code>.<\/p>\n\n      <ul id=\"social-sharing-buttons-list\">\n        <li class=\"facebook\">\n          <a href=\"https:\/\/www.facebook.com\/sharer\/sharer.php?u=https%3A%2F%2Fwp.me%2Fp245TQ-wq\" target=\"_blank\" role=\"button\" rel=\"nofollow\">\n            <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/Facebook.png\" alt=\"Facebook icon\"> Share\n          <\/a>\n        <\/li>\n        <li class=\"twitter\">\n          <a href=\"https:\/\/twitter.com\/intent\/tweet?text=&url=https%3A%2F%2Fwp.me%2Fp245TQ-wq&via=Techcoil_com\" target=\"_blank\" role=\"button\" rel=\"nofollow\">\n          <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/Twitter.png\" alt=\"Twitter icon\"> Tweet\n          <\/a>\n        <\/li>\n        <li class=\"linkedin\">\n          <a href=\"https:\/\/www.linkedin.com\/shareArticle?mini=1&title=&url=https%3A%2F%2Fwp.me%2Fp245TQ-wq&source=https:\/\/www.techcoil.com\" target=\"_blank\" role=\"button\" rel=\"nofollow\">\n          <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/linkedin.png\" alt=\"Linkedin icon\"> Share\n          <\/a>\n        <\/li>\n        <li class=\"pinterest\">\n          <a href=\"https:\/\/pinterest.com\/pin\/create\/button\/?url=https%3A%2F%2Fwww.techcoil.com%2Fblog%2Fwp-json%2Fwp%2Fv2%2Fposts%2F2010&description=\" class=\"pin-it-button\" target=\"_blank\" role=\"button\" rel=\"nofollow\" count-layout=\"horizontal\">\n          <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/Pinterest.png\" alt=\"Pinterest icon\"> Save\n          <\/a>\n        <\/li>\n      <\/ul>\n    ","protected":false},"excerpt":{"rendered":"<p>Previously, I talked about <a href=\"https:\/\/www.techcoil.com\/blog\/how-to-use-flask-apscheduler-in-your-python-3-flask-application-to-run-multiple-tasks-in-parallel-from-a-single-http-request\/\" rel=\"noopener\" target=\"_blank\">how to use Flask-APScheduler in your Python 3 Flask application to run multiple tasks in parallel, from a single HTTP request<\/a>.<\/p>\n<p>If you wish to run long running tasks triggered by an <a href=\"https:\/\/www.techcoil.com\/glossary\/http-request\/\" rel=\"noopener\" target=\"_blank\">HTTP request<\/a>, then that post will help you do so.<\/p>\n<p>However, what if you want to run jobs periodically without blocking your Flask <a href=\"https:\/\/www.techcoil.com\/glossary\/http-server\/\" rel=\"noopener\" target=\"_blank\">HTTP server<\/a> from serving HTTP requests?<\/p>\n<p>In this case, you will want to run an interval task with <a href=\"https:\/\/github.com\/viniciuschiele\/flask-apscheduler\" rel=\"noopener\" target=\"_blank\">Flask-APScheduler<\/a>.<\/p>\n<p>Given that, let&#8217;s look at how we can use Flask-APScheduler to create an interval task within your Python 3 Flask application.<\/p>\n","protected":false},"author":1,"featured_media":1244,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"footnotes":""},"categories":[375],"tags":[583,23,199,728,226,233,254,729],"jetpack_featured_media_url":"https:\/\/www.techcoil.com\/blog\/wp-content\/uploads\/Python-Logo.gif","jetpack_shortlink":"https:\/\/wp.me\/p245TQ-wq","jetpack-related-posts":[],"jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/posts\/2010"}],"collection":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/comments?post=2010"}],"version-history":[{"count":0,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/posts\/2010\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/media\/1244"}],"wp:attachment":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/media?parent=2010"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/categories?post=2010"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/tags?post=2010"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}