{"id":235786,"date":"2024-04-01T08:02:49","date_gmt":"2024-04-01T08:02:49","guid":{"rendered":"https:\/\/osmosys.co\/ca\/developing-python-flask-apis-with-celery-and-rabbitmq-a-complete-how-to-guide\/"},"modified":"2025-12-03T11:50:55","modified_gmt":"2025-12-03T11:50:55","slug":"developing-python-flask-apis-with-celery-and-rabbitmq-a-complete-how-to-guide","status":"publish","type":"post","link":"https:\/\/osmosys.co\/ca\/developing-python-flask-apis-with-celery-and-rabbitmq-a-complete-how-to-guide\/","title":{"rendered":"Developing Python Flask APIs with Celery and RabbitMQ &#8211; A Complete How-to Guide"},"content":{"rendered":"<div id=\"bsf_rt_marker\"><\/div>\n<h2 class=\"wp-block-heading\" id=\"introduction\">Introduction<\/h2>\n\n\n\n<p>In today\u2019s tech driven world, building scalable and efficient web applications is a top priority for developers and businesses alike. Python, with its versatility and power, has gained immense popularity in multiple fields of development, including the web. Flask, a lightweight and easy-to-scale microframework, is a preferred choice for building RESTful APIs. When it comes to handling background tasks and queuing, Celery combined with RabbitMQ is a formidable duo. Unlock the potential of Python Flask APIs with Celery and RabbitMQ in this detailed step-by-step guide, where we will walk you through the process of setting up a Python Flask API from scratch with Celery and RabbitMQ on an IIS (Internet Information Services) server.<\/p>\n\n\n\n<div class=\"wp-block-rank-math-toc-block\" id=\"rank-math-toc\"><h2>Table of Contents<\/h2><nav><div><div><a href=\"#introduction\">Introduction<\/a><\/div><div><a href=\"#why-choose-python-flask-ap-is\">Why choose Python Flask APIs?<\/a><\/div><div><a href=\"#what-is-celery-and-rabbit-mq\">What is Celery and RabbitMQ?<\/a><\/div><div><a href=\"#pre-requisites\">Pre-Requisites<\/a><\/div><div><a href=\"#setup-guide\">Setup Guide<\/a><div><div><a href=\"#setting-up-the-python-environment-and-flask-api\">Setting up the python environment and Flask API<\/a><div><div><a href=\"#setting-up-python\">Setting up python<\/a><\/div><div><a href=\"#setting-up-iis-with-cgi\">Setting up IIS with CGI<\/a><\/div><div><a href=\"#setting-up-the-flask-api-and-the-python-environment\">Setting up the Flask API and the python environment<\/a><\/div><\/div><\/div><div><a href=\"#setting-up-erlang-and-rabbit-mq\">Setting up Erlang and RabbitMQ<\/a><div><div><a href=\"#erlang-otp\">Erlang OTP<\/a><\/div><div><a href=\"#rabbit-mq\">RabbitMQ<\/a><\/div><\/div><\/div><div><a href=\"#setting-up-celery\">Setting up Celery<\/a><div><div><a href=\"#setting-up-nssm-and-the-windows-service\">Setting up NSSM and the windows service<\/a><\/div><\/div><\/div><div><a href=\"#deploying-application-with-iis-and-w-fast-cgi\">Deploying Application with IIS and WFastCGI<\/a><div><div><a href=\"#setup-website-to-point-to-folder\">Setup website to point to folder<\/a><\/div><div><a href=\"#add-permissions-to-iis\">Add permissions to IIS<\/a><\/div><div><a href=\"#add-handler-mappings\">Add Handler Mappings<\/a><\/div><div><a href=\"#update-the-fast-cgi-application\">Update the FastCGI Application<\/a><\/div><\/div><\/div><\/div><\/div><div><a href=\"#conclusion\">Conclusion<\/a><\/div><\/div><\/nav><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"why-choose-python-flask-ap-is\">Why choose Python Flask APIs?<\/h2>\n\n\n\n<p>Python and Flask are a dynamic duo for building APIs, and their versatility makes them an excellent choice in various scenarios. Python&#8217;s simplicity, readability, and extensive libraries make it a developer favorite. Flask, a microframework, is lightweight, easy to understand, and highly customizable. It&#8217;s an excellent choice when you want to build APIs quickly without unnecessary complexities. <\/p>\n\n\n\n<p>Python&#8217;s ecosystem also boasts robust data processing capabilities, which align perfectly with tasks involving data normalization and database operations. Additionally, Python&#8217;s extensive community support ensures you&#8217;ll find solutions to your challenges quickly. With Flask, you can create APIs that efficiently handle requests, and with Python, you can manipulate data effortlessly. Together, Python Flask APIs provide a solid foundation for creating responsive and reliable APIs.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"what-is-celery-and-rabbit-mq\">What is Celery and RabbitMQ?<\/h2>\n\n\n\n<div class=\"wp-block-media-text alignwide is-stacked-on-mobile\"><figure class=\"wp-block-media-text__media\"><img decoding=\"async\" width=\"1024\" height=\"527\" data-src=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/2-jpg.webp\" alt=\"\" class=\"wp-image-235808 size-full lazyload\" data-srcset=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/2-jpg.webp 1024w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/2-980x504.webp 980w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/2-480x247.webp 480w\" data-sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1024px; --smush-placeholder-aspect-ratio: 1024\/527;\" \/><\/figure><div class=\"wp-block-media-text__content\">\n<p>Celery and RabbitMQ form a powerful combination for handling background tasks and asynchronous processing in Python applications. Celery is a distributed task queue that allows you to offload time-consuming and resource-intensive tasks to separate worker processes. It excels in managing tasks concurrently, making it suitable for scenarios like API requests triggering large data handling functions or compute\/time intensive tasks.<\/p>\n<\/div><\/div>\n\n\n\n<p>RabbitMQ, on the other hand, serves as the message broker for Celery. It efficiently manages the communication between the API and worker processes by handling task distribution and results retrieval. In our setup, Celery will act as the engine that processes the task coming from the API, while RabbitMQ ensures seamless task coordination and communication. This combination provides the reliability and scalability required for background processing while keeping your API responsive.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"pre-requisites\">Pre-Requisites<\/h2>\n\n\n\n<p>Before getting into the setup process, let us list out and understand all the pre-requisites of the complete process. The steps to install and set up each requirement will come in subsequent sections:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Python: <\/strong>Make sure you have Python 3.x (&gt;=3.7) installed on your server. You can download the latest version from the <a href=\"https:\/\/www.python.org\/\" target=\"_blank\" rel=\"noopener\">official python website<\/a>. Make sure the initial install is added to PATH and Install <code>virtualenv<\/code> on the global version so that environments can be created for the app to run.<\/li>\n\n\n\n<li><strong>Flask<\/strong>: Since this is a python framework\/library, we will be setting this up along with the application that we aim to deploy.<\/li>\n\n\n\n<li><strong>Erlang OTP<\/strong>: Since we will be using RabbitMQ and it is built on Erlang, we will need Erlang OTP installed.<\/li>\n\n\n\n<li><strong>RabbitMQ<\/strong>: RabbitMQ is a message broker that Celery uses for task queueing.<\/li>\n\n\n\n<li><strong>WFastCGI<\/strong>: For deploying Flask applications on IIS, we will need WFastCGI, which will allow us to run Python web applications behind IIS. This can also be installed as a package in python using pip, so we will use that method.<\/li>\n\n\n\n<li><strong>NSSM<\/strong>: NSSM, or the Non-Sucking Service Manager, is a tool for creating and managing Windows services. It will be used to setup Celery workers as windows services. It can be downloaded from <a href=\"http:\/\/nssm.cc\/download\" target=\"_blank\" rel=\"noopener\">here<\/a>.<\/li>\n\n\n\n<li><strong>IIS<\/strong>: IIS comes installed and running on all Windows machines. If not, you can enable it through the \u201cTurn Windows Features On or Off\u201d menu.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"setup-guide\">Setup Guide<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"setting-up-the-python-environment-and-flask-api\">Setting up the python environment and Flask API<\/h3>\n\n\n\n<p>Let us first setup our python environment and app that we would be deploying. As Flask is a web framework and runs using python, this step is a necessary first. Since we would be deploying on a windows server, all steps mentioned so forth will be for windows only.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"setting-up-python\">Setting up python<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Download the latest Windows x86-64 executable installer from the <a href=\"https:\/\/www.python.org\/\" target=\"_blank\" rel=\"noopener\">official python website<\/a>.<\/li>\n\n\n\n<li>Continue with the Install now option. Make sure to <strong>check yes, <\/strong>the box for add python to PATH on the first page. If you wish you can choose to customize the installation and set up your global python in a location of your choice. Click \u201cInstall\u201d.<\/li>\n\n\n\n<li>When the installation is complete, click close. You can verify the installation by running <code>where python<\/code> in your command prompt (CMD). It should give you a response like so, giving you the path where all and any pythons are downloaded to the machine, and added to the system environment variables.<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img decoding=\"async\" width=\"493\" height=\"186\" data-src=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/3.png\" alt=\"\" class=\"wp-image-235810 lazyload\" data-srcset=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/3.png 493w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/3-480x181.png 480w\" data-sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 493px, 100vw\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 493px; --smush-placeholder-aspect-ratio: 493\/186;\" \/><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"setting-up-iis-with-cgi\">Setting up IIS with CGI<\/h4>\n\n\n\n<p>The Flask app will connect with the FastCGI module of the server to expose the APIs. So, we have to install IIS with CGI. You can follow the below steps to do so:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open Server Manager and select Manage -&gt; Add Roles and Features<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img decoding=\"async\" width=\"987\" height=\"702\" data-src=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/4.png\" alt=\"\" class=\"wp-image-235811 lazyload\" data-srcset=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/4.png 987w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/4-980x697.png 980w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/4-480x341.png 480w\" data-sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 987px, 100vw\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 987px; --smush-placeholder-aspect-ratio: 987\/702;\" \/><\/figure>\n\n\n\n<ol class=\"wp-block-list\" start=\"2\">\n<li>You will see the before you begin page. Click next and select \u201cRole-based or feature-based installation\u201d in the Installation type section and click Next.<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img decoding=\"async\" width=\"982\" height=\"700\" data-src=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/5.png\" alt=\"\" class=\"wp-image-235812 lazyload\" data-srcset=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/5.png 982w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/5-980x699.png 980w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/5-480x342.png 480w\" data-sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 982px, 100vw\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 982px; --smush-placeholder-aspect-ratio: 982\/700;\" \/><\/figure>\n\n\n\n<ol class=\"wp-block-list\" start=\"3\">\n<li>Select the server in the \u201cServer Selection\u201d section and select &#8220;Next&#8221;.<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img decoding=\"async\" width=\"994\" height=\"706\" data-src=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/6.png\" alt=\"\" class=\"wp-image-235813 lazyload\" data-srcset=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/6.png 994w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/6-980x696.png 980w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/6-480x341.png 480w\" data-sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 994px, 100vw\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 994px; --smush-placeholder-aspect-ratio: 994\/706;\" \/><\/figure>\n\n\n\n<ol class=\"wp-block-list\" start=\"4\">\n<li>On \u201cServer Roles\u201d, select \u201cWeb Server (IIS)\u201d, select \u201cAdd features\u201d and select \u201cNext&#8221;.<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img decoding=\"async\" width=\"959\" height=\"582\" data-src=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/7.png\" alt=\"\" class=\"wp-image-235815 lazyload\" data-srcset=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/7.png 959w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/7-480x291.png 480w\" data-sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 959px, 100vw\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 959px; --smush-placeholder-aspect-ratio: 959\/582;\" \/><\/figure>\n\n\n\n<ol class=\"wp-block-list\" start=\"5\">\n<li>Accept the default configurations and continue till we see the \u201cRole Services\u201d screen. Select \u201cCGI\u201d under \u201cApplication Development\u201d and select \u201cNext\u201d.<\/li>\n\n\n\n<li>Accept the default configurations and select \u201cInstall\u201d.<\/li>\n<\/ol>\n\n\n\n<p>After the installation is complete, close the installation wizard and launch IIS manager by using the command <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\"><code>inetmgr<\/code><\/code> in Windows Run (win + r). This will launch the IIS Manager in the system. If prompted with the following message, select \u201cNo\u201d. Microsoft Web Platform helps to install the Python and FastCGI modules, which we will do ourselves at a later stage with the Flask app.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img decoding=\"async\" width=\"441\" height=\"236\" data-src=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/8.png\" alt=\"\" class=\"wp-image-235816 lazyload\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 441px; --smush-placeholder-aspect-ratio: 441\/236;\" \/><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"setting-up-the-flask-api-and-the-python-environment\">Setting up the Flask API and the python environment<\/h4>\n\n\n\n<p>Now that we have python setup, lets setup our Flask API. If you already have an application hosted on a version control system, you can use git to get the repository onto the server at the following path:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>C:\/inetpub\/wwwroot<\/code><\/pre>\n\n\n\n<p>This is required as to deploy a web app on IIS, the app is required to be in this folder for it to be read by IIS. For the sake of this guide, we will be using the following piece of code as our Flask app:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"\"\"\nDeploy Flask App in IIS Server\n\"\"\"\nimport time\nfrom flask import Flask\nfrom celery import Celery\napp = Flask(__name__)\napp.config&#91;\u2018CELERY_BROKER_URL\u2019] = \u2018pyamqp:\/\/guest:guest@localhost:5672\/\u2019\napp.config&#91;\u2018CELEREY_RESULT_BACKEND\u2019] = \u2018rpc:\/\/guest:guest@localhost:5672\u2019\ncelery = Celery(app.name, broker=app.config&#91;\u2018CELERY_BROKER_CONFIG\u2019, backend=app.config&#91;\u2018CELERY_RESULTS_BACKEND\u2019])\n@app.route(\"\/\")\ndef home():\n    background_task = hello.delay()\n    return \"Hello! This is our Flask App in IIS Server.\"\n@celery.task\ndef hello():\n    time.sleep(30)\n    print(\u201chello\u201d)\n\"if __name__ == \"__main__\":\n    app.run()<\/code><\/pre>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Create a folder in <code><code data-enlighter-language=\"bash\" class=\"EnlighterJSRAW\">wwwroot<\/code><\/code> and add the above code in a file called app.py. (Or open CMD and run a git clone on <code><code data-enlighter-language=\"bash\" class=\"EnlighterJSRAW\">wwwroot<\/code><\/code> to get your repository)<\/li>\n\n\n\n<li>Open CMD as Admin and as a pre-step, run the command <code data-enlighter-language=\"bash\" class=\"EnlighterJSRAW\">where python<\/code> and copy the path to the python.exe file for the required python version. If there are different versions present from other apps running on the server, make sure to select the python version we just downloaded. run the following command to create a virtualenv. Before doing so, navigate to the folder where to code is present in CMD, a.k.a. <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">C:inetpubwwwrootFlaskApp<\/code><\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>Path\/to\/python.exe -m venv env\nenvScriptsactivate<\/code><\/pre>\n\n\n\n<ol class=\"wp-block-list\" start=\"3\">\n<li>Now that we have our virtual environment and code set up, we can install our packages into the env. If you have a requirements.txt folder, run the command <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">pip install -r requirements.txt<\/code>, or you can directly use pip install in the CMD. Install the following packages using the command:<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>pip install flask wfastcgi celery<\/code><\/pre>\n\n\n\n<p>This will install all packages required for our basic code and we can then move on to setting up Celery, RabbitMQ and deploying our app to IIS.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"setting-up-erlang-and-rabbit-mq\">Setting up Erlang and RabbitMQ<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"erlang-otp\">Erlang OTP<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li>From the <a href=\"https:\/\/erlang.org\/download\/otp_versions_tree.html\" target=\"_blank\" rel=\"noopener\">official version tree of Erlang<\/a>, download the latest stable version &amp; install using an <strong>administrative user<\/strong>.<\/li>\n\n\n\n<li>Set ERLANG_HOME to where you actually put your Erlang installation, e.g., C:Program Fileserl{version} (full path, we have version=23.1.5). The RabbitMQ batch files expect to execute %ERLANG_HOME%binerl.exe.<\/li>\n\n\n\n<li>Go to Start &gt; Settings &gt; Control Panel &gt; System &gt; Advanced &gt; Environment Variables. Create the system environment variable ERLANG_HOME and set it to the full path of the directory which contains binerl.exe.<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img decoding=\"async\" width=\"655\" height=\"155\" data-src=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/9.png\" alt=\"\" class=\"wp-image-235817 lazyload\" data-srcset=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/9.png 655w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/9-480x114.png 480w\" data-sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 655px, 100vw\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 655px; --smush-placeholder-aspect-ratio: 655\/155;\" \/><\/figure>\n\n\n\n<ol class=\"wp-block-list\" start=\"4\">\n<li>Open CMD and type <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">\"%ERLANG_HOME%\"binerl.exe<\/code> . You should see an E-Shell prompt.<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img decoding=\"async\" width=\"595\" height=\"134\" data-src=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/10.png\" alt=\"\" class=\"wp-image-235818 lazyload\" data-srcset=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/10.png 595w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/10-480x108.png 480w\" data-sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 595px, 100vw\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 595px; --smush-placeholder-aspect-ratio: 595\/134;\" \/><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"rabbit-mq\">RabbitMQ<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li>download the RabbitMQ installer, rabbitmq-server-{version}.exe and run it using the following command.<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>cd C:Program FilesRabbitMQ Serverrabbitmq_server-3.11.6sbin\nrabbitmq-plugins.bat enable rabbitmq_management<\/code><\/pre>\n\n\n\n<ol class=\"wp-block-list\" start=\"2\">\n<li>After the above 2 commands, run this command.<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>rabbitmq-plugins enable rabbitmq_shovel rabbitmq_shovel_management<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img decoding=\"async\" width=\"1024\" height=\"256\" data-src=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/11.png\" alt=\"\" class=\"wp-image-235819 lazyload\" data-srcset=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/11.png 1024w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/11-980x245.png 980w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/11-480x120.png 480w\" data-sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1024px; --smush-placeholder-aspect-ratio: 1024\/256;\" \/><\/figure>\n\n\n\n<ol class=\"wp-block-list\" start=\"3\">\n<li>&nbsp;Open Windows search, search for notepad and right click to select &#8220;Run as administrator&#8221;. Search for and open <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">C:WindowsSystem32driversetchosts<\/code> file. Add to it the following line, and save:<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>127.0.0.1 rabbitmq<\/code><\/pre>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Once all done, open <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">http:\/\/rabbitmq:15672\/<\/code> on a web browser for opening the RabbitMQ management. The default credentials are always as follows:<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>Username: guest\nPassword: guest<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"setting-up-celery\">Setting up Celery<\/h3>\n\n\n\n<p>In our Flask app \u2013 app.py, we have already added all necessary configurations and functions to set up celery, use RabbitMQ as a task broker on the port 5672, and added a function that will get called in the background asynchronously from the actual API call.<\/p>\n\n\n\n<p>To make all of this happen, we need what is called a worker. A celery worker is responsible for executing asynchronous tasks in the background. The worker listens to the task queue, which in this case is RabbitMQ, waits for oncoming tasks, and once a task is received, it processes it independently from the main application.<\/p>\n\n\n\n<p>The worker will need admin permissions since our complete code base is in the C drive. To achieve this and help run the worker, we will create a windows batch file. The following steps can be used to create the batch file:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open a text editor, like notepad.<\/li>\n\n\n\n<li>Add the following commands in the first 2 lines of the file.<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@REM #run as admin\ncd \"C:inetpubwwwrootFlaskApp\"&amp;&amp;envScriptsactivate&amp;&amp;celery -A app.celery worker --pool=solo -l info<\/pre><\/code><\/pre>\n\n\n\n<p>The first line here will tell the batch file to be opened as admin, and the second line will in order, go to the code directory, activate the python environment, and then call the celery configuration stored in our app.py file to create a worker.<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"3\">\n<li>Save the text file, preferably in the Folder with the rest of the code. Name it as celery_worker.bat and keep the &#8220;Save as&#8221; type as &#8220;All Files (*.*)&#8221;.<\/li>\n<\/ol>\n\n\n\n<p>To set up the worker to run indefinitely, we will be using NSSM, or the Non-sucking service manager. It is a 3<sup>rd<\/sup> party open-source tool that allows us to convert batch\/executable files into windows services.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"setting-up-nssm-and-the-windows-service\">Setting up NSSM and the windows service<\/h4>\n\n\n\n<ol class=\"wp-block-list\" type=\"1\">\n<li>Download <a href=\"http:\/\/nssm.cc\/download\" target=\"_blank\" rel=\"noreferrer noopener\">nssm<\/a>. Follow the steps as mentioned on website for download.<\/li>\n\n\n\n<li>Unzip the contents, go to &#8220;nssm-2.24win32&#8221; and copy-paste the executable into any external folder. There are no other installation steps required. This external folder should be added to PATH environment variable. It should be a user variable.<\/li>\n<\/ol>\n\n\n\n<p>Now that we have NSSM set up, we will go ahead and create the service using the celery_worker.bat file we created earlier.<\/p>\n\n\n\n<ol class=\"wp-block-list\" type=\"1\">\n<li>Open CMD as admin<\/li>\n\n\n\n<li>Run the following command in CLI<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>nssm install service_name<\/code><\/pre>\n\n\n\n<p>In this case, service_name = flask_app<\/p>\n\n\n\n<ol class=\"wp-block-list\" type=\"1\" start=\"3\">\n<li>This will open a service installer window and all aspects of the service can be configured\/edited from here.<\/li>\n<\/ol>\n\n\n\n<ol class=\"wp-block-list\" start=\"4\">\n<li>In the &#8220;Application&#8221; tab, Path should be pointed to the batch file to be run indefinitely, in this case the celery_worker.bat.<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img decoding=\"async\" width=\"546\" height=\"306\" data-src=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/12.png\" alt=\"\" class=\"wp-image-235820 lazyload\" data-srcset=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/12.png 546w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/12-480x269.png 480w\" data-sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 546px, 100vw\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 546px; --smush-placeholder-aspect-ratio: 546\/306;\" \/><\/figure>\n\n\n\n<ol class=\"wp-block-list\" start=\"5\">\n<li>Go to the details tab and add an appropriate name, description, and keep the startup type as \u201cAutomatic\u201d.<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img decoding=\"async\" width=\"547\" height=\"298\" data-src=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/13.png\" alt=\"\" class=\"wp-image-235821 lazyload\" data-srcset=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/13.png 547w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/13-480x261.png 480w\" data-sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 547px, 100vw\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 547px; --smush-placeholder-aspect-ratio: 547\/298;\" \/><\/figure>\n\n\n\n<ol class=\"wp-block-list\" start=\"6\">\n<li>Go to the log on tab and select \u201cthis account\u201d enter your credentials here, or if you have a service account for the server with appropriate access and permissions, add the credentials to that account here. This account will be used to run the service. The rest of the configurations are optional in the rest of the tabs and can be added as required (such as logging from the I\/O tab and File rotation to rotate the log files).<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img decoding=\"async\" width=\"544\" height=\"299\" data-src=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/14.png\" alt=\"\" class=\"wp-image-235822 lazyload\" data-srcset=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/14.png 544w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/14-480x264.png 480w\" data-sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 544px, 100vw\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 544px; --smush-placeholder-aspect-ratio: 544\/299;\" \/><\/figure>\n\n\n\n<ol class=\"wp-block-list\" start=\"7\">\n<li>Click finish and the service will get installed. For the first time, the service would be stopped and will have to be started manually by going to the \u201cServices\u201d application, locating the service and clicking start. On system startup\/reboot, it will start automatically because of the slection done in step 5.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"deploying-application-with-iis-and-w-fast-cgi\">Deploying Application with IIS and WFastCGI<\/h3>\n\n\n\n<p>Now that we have all the other aspects of the project up and running, we can get to deploying the API on IIS, which will allow users to run the API through a port on the server. If you have one, you can also add a domain to the web app we will set up now \u2013<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"setup-website-to-point-to-folder\">Setup website to point to folder<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open the IIS application and go to Sites. Right click and click on Add new website.<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img decoding=\"async\" width=\"358\" height=\"330\" data-src=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/15.png\" alt=\"\" class=\"wp-image-235823 lazyload\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 358px; --smush-placeholder-aspect-ratio: 358\/330;\" \/><\/figure>\n\n\n\n<ol class=\"wp-block-list\" start=\"2\">\n<li>Give a name to your website and set the physical path to your project directory. Assign a port number and click ok. If you have a domain name, you can add that as well in the &#8220;Host name&#8221; field.<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img decoding=\"async\" width=\"730\" height=\"845\" data-src=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/16.png\" alt=\"\" class=\"wp-image-235824 lazyload\" data-srcset=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/16.png 730w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/16-480x556.png 480w\" data-sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 730px, 100vw\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 730px; --smush-placeholder-aspect-ratio: 730\/845;\" \/><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"add-permissions-to-iis\">Add permissions to IIS<\/h4>\n\n\n\n<ol class=\"wp-block-list\" start=\"3\">\n<li>Open CMD as admin, navigate to the app directory, and activate the environment. run the following 2 commands to give appropriate permissions to IIS to run the code in the folder:<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>icacls . \/grant \"NT AUTHORITYIUSR:(OI)(CI)(RX)\"\nicacls . \/grant \"BuiltinIIS_IUSRS:(OI)(CI)(RX)\"<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img decoding=\"async\" width=\"760\" height=\"256\" data-src=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/17.png\" alt=\"\" class=\"wp-image-235825 lazyload\" data-srcset=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/17.png 760w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/17-480x162.png 480w\" data-sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 760px, 100vw\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 760px; --smush-placeholder-aspect-ratio: 760\/256;\" \/><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"add-handler-mappings\">Add Handler Mappings<\/h4>\n\n\n\n<ol class=\"wp-block-list\" type=\"1\" start=\"4\">\n<li>On IIS, go to the FlaskApp site, present under Sites. Click on that and select the \u201cHandler Mappings\u201d icon.<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img decoding=\"async\" width=\"1024\" height=\"435\" data-src=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/18.png\" alt=\"\" class=\"wp-image-235826 lazyload\" data-srcset=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/18.png 1024w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/18-980x416.png 980w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/18-480x204.png 480w\" data-sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1024px; --smush-placeholder-aspect-ratio: 1024\/435;\" \/><\/figure>\n\n\n\n<ol class=\"wp-block-list\" start=\"5\">\n<li>Here, select &#8220;Add Module Mapping&#8221; and insert the following values:<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">Request Path: *\nModule: FastCgiModule (Select from the dropdown menu)\nExecutable(optional): \nC:inetpubwwwrootFlaskAppenvScriptspython.exe|C:inetpubwwwrootFlaskAppenvLibsite-packageswfastcgi.py\nName: FlaskHandler<\/pre>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img decoding=\"async\" width=\"578\" height=\"511\" data-src=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/19.png\" alt=\"\" class=\"wp-image-235827 lazyload\" data-srcset=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/19.png 578w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/19-480x424.png 480w\" data-sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 578px, 100vw\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 578px; --smush-placeholder-aspect-ratio: 578\/511;\" \/><\/figure>\n\n\n\n<ol class=\"wp-block-list\" start=\"6\">\n<li>Click on Request Restrictions and uncheck \u201cInvoke handler only if request is mapped to:\u201d checkbox and select OK, followed by another OK. Select \u201cYes\u201d if prompted by this warning.<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img decoding=\"async\" width=\"507\" height=\"215\" data-src=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/20.png\" alt=\"\" class=\"wp-image-235828 lazyload\" data-srcset=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/20.png 507w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/20-480x204.png 480w\" data-sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 507px, 100vw\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 507px; --smush-placeholder-aspect-ratio: 507\/215;\" \/><\/figure>\n\n\n\n<ol class=\"wp-block-list\" start=\"7\">\n<li>Now, verify the module mapping in FastCGI settings in the root server. This should create an entry in FastCGI Settings.<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img decoding=\"async\" width=\"1024\" height=\"301\" data-src=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/21.png\" alt=\"\" class=\"wp-image-235829 lazyload\" data-srcset=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/21.png 1024w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/21-980x288.png 980w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/21-480x141.png 480w\" data-sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1024px; --smush-placeholder-aspect-ratio: 1024\/301;\" \/><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"update-the-fast-cgi-application\">Update the FastCGI Application<\/h4>\n\n\n\n<ol class=\"wp-block-list\" start=\"8\">\n<li>Double click the application entry in FastCGI settings to edit the application and select &#8220;Environment variables&#8221;. Click on &#8220;&#8230;&#8221; and open the &#8220;EnvironmentVariables Collection Editor&#8221;. Add the below entries:<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">Name: PYTHONPATH\nValue: C:inetpubwwwrootFlaskApp<\/pre>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img decoding=\"async\" width=\"623\" height=\"466\" data-src=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/22.png\" alt=\"\" class=\"wp-image-235830 lazyload\" data-srcset=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/22.png 623w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/22-480x359.png 480w\" data-sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 623px, 100vw\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 623px; --smush-placeholder-aspect-ratio: 623\/466;\" \/><\/figure>\n\n\n\n<p>The PYTHONPATH must point to the directory containing the Flask Application.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Name: WSGI_Handler\nValue: app.app<\/pre>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img decoding=\"async\" width=\"619\" height=\"466\" data-src=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/23.png\" alt=\"\" class=\"wp-image-235831 lazyload\" data-srcset=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/23.png 619w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/23-480x361.png 480w\" data-sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 619px, 100vw\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 619px; --smush-placeholder-aspect-ratio: 619\/466;\" \/><\/figure>\n\n\n\n<p>The WSGI_HANDLER must point to the application name followed by \u201c.app\u201d. In our case, the application name is \u201capp.py\u201d so WSGI_HANDLER is pointing to \u201capp.app\u201d.<\/p>\n\n\n\n<p>Your website is now ready to use over the port you set at the beginning of the website setup on IIS. Enjoy!<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"686\" height=\"346\" data-src=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/24.png\" alt=\"\" class=\"wp-image-235832 lazyload\" data-srcset=\"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/24.png 686w, https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/24-480x242.png 480w\" data-sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 686px, 100vw\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 686px; --smush-placeholder-aspect-ratio: 686\/346;\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"conclusion\">Conclusion<\/h2>\n\n\n\n<p>Setting up a Python Flask API with Celery and RabbitMQ on IIS can be a complex and lengthy task, but it&#8217;s a powerful combination for building robust web applications that can handle background tasks and queueing efficiently. By following this step-by-step guide, you&#8217;ve learned how to configure each component and integrate them into a seamless web application. With the right setup, your Flask app can now handle concurrent tasks and deliver a smooth user experience while processing background jobs asynchronously. This combination opens up a world of possibilities for building feature-rich and efficient web applications.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction In today\u2019s tech driven world, building scalable and efficient web applications is a top priority for developers and businesses alike. Python, with its versatility and power, has gained immense popularity in multiple fields of development, including the web. Flask, a lightweight and easy-to-scale microframework, is a preferred choice for building RESTful APIs. When it [&hellip;]<\/p>\n","protected":false},"author":11,"featured_media":235809,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"off","_et_pb_old_content":"<!-- wp:image {\"id\":236913,\"sizeSlug\":\"full\",\"linkDestination\":\"none\"} -->\n<figure class=\"wp-block-image size-full\"><img src=\"https:\/\/osmosys.co\/wp-content\/uploads\/2024\/03\/1-jpg.webp\" alt=\"python flask api\" class=\"wp-image-236913\"\/><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:rank-math\/toc-block {\"headings\":[{\"key\":\"df52aa63-b0da-4248-92b4-bd3beb21379f\",\"content\":\"Introduction\",\"level\":2,\"link\":\"#introduction\",\"disable\":false,\"isUpdated\":false,\"isGeneratedLink\":true},{\"key\":\"cf5c3314-8e87-4dcf-b780-73414097a5b9\",\"content\":\"Why choose Python Flask APIs?\",\"level\":2,\"link\":\"#why-choose-python-flask-ap-is\",\"disable\":false,\"isUpdated\":false,\"isGeneratedLink\":true},{\"key\":\"f6a4db4f-f962-49d1-9b89-a53265f24987\",\"content\":\"What is Celery and RabbitMQ?\",\"level\":2,\"link\":\"#what-is-celery-and-rabbit-mq\",\"disable\":false,\"isUpdated\":false,\"isGeneratedLink\":true},{\"key\":\"bdaea904-8df5-4e53-9e0c-06802fdafc19\",\"content\":\"Pre-Requisites\",\"level\":2,\"link\":\"#pre-requisites\",\"disable\":false,\"isUpdated\":false,\"isGeneratedLink\":true},{\"key\":\"689a35d2-9ee5-488b-990b-14621ee331f1\",\"content\":\"Setup Guide\",\"level\":2,\"link\":\"#setup-guide\",\"disable\":false,\"isUpdated\":false,\"isGeneratedLink\":true},{\"key\":\"7c590370-d6af-46f4-9c67-94fa5cc46df1\",\"content\":\"Setting up the python environment and Flask API\",\"level\":3,\"link\":\"#setting-up-the-python-environment-and-flask-api\",\"disable\":false,\"isUpdated\":false,\"isGeneratedLink\":true},{\"key\":\"810aa206-7a8b-48f8-b801-c25f486fd201\",\"content\":\"Setting up python\",\"level\":4,\"link\":\"#setting-up-python\",\"disable\":false,\"isUpdated\":false,\"isGeneratedLink\":true},{\"key\":\"9fc834c3-7641-41e3-99f6-3d3dc178f65a\",\"content\":\"Setting up IIS with CGI\",\"level\":4,\"link\":\"#setting-up-iis-with-cgi\",\"disable\":false,\"isUpdated\":false,\"isGeneratedLink\":true},{\"key\":\"df450e34-fe4d-4ca5-822e-a97877d8fb2d\",\"content\":\"Setting up the Flask API and the python environment\",\"level\":4,\"link\":\"#setting-up-the-flask-api-and-the-python-environment\",\"disable\":false,\"isUpdated\":false,\"isGeneratedLink\":true},{\"key\":\"6f3157e3-8be1-41cb-9166-028b94bfd818\",\"content\":\"Setting up Erlang and RabbitMQ\",\"level\":3,\"link\":\"#setting-up-erlang-and-rabbit-mq\",\"disable\":false,\"isUpdated\":false,\"isGeneratedLink\":true},{\"key\":\"c0db36d9-a5ea-4864-b769-7d9fbd7a3a61\",\"content\":\"Erlang OTP\",\"level\":4,\"link\":\"#erlang-otp\",\"disable\":false,\"isUpdated\":false,\"isGeneratedLink\":true},{\"key\":\"7987738c-0a54-4871-9ba7-0103ff56a131\",\"content\":\"RabbitMQ\",\"level\":4,\"link\":\"#rabbit-mq\",\"disable\":false,\"isUpdated\":false,\"isGeneratedLink\":true},{\"key\":\"4e568fba-87c9-4a13-bd24-77e830b5b128\",\"content\":\"Setting up Celery\",\"level\":3,\"link\":\"#setting-up-celery\",\"disable\":false,\"isUpdated\":false,\"isGeneratedLink\":true},{\"key\":\"dfc80dca-f0a0-4993-947f-aa74065cb681\",\"content\":\"Setting up NSSM and the windows service\",\"level\":4,\"link\":\"#setting-up-nssm-and-the-windows-service\",\"disable\":false,\"isUpdated\":false,\"isGeneratedLink\":true},{\"key\":\"f659ba0d-6284-4a92-b35b-7188a8a13d74\",\"content\":\"Deploying Application with IIS and WFastCGI\",\"level\":3,\"link\":\"#deploying-application-with-iis-and-w-fast-cgi\",\"disable\":false,\"isUpdated\":false,\"isGeneratedLink\":true},{\"key\":\"21a9e490-b172-4a59-946b-aa6ca8ca3f5a\",\"content\":\"Setup website to point to folder\",\"level\":4,\"link\":\"#setup-website-to-point-to-folder\",\"disable\":false,\"isUpdated\":false,\"isGeneratedLink\":true},{\"key\":\"2ac6c905-6016-4919-a7da-412bcedce6e0\",\"content\":\"Add permissions to IIS\",\"level\":4,\"link\":\"#add-permissions-to-iis\",\"disable\":false,\"isUpdated\":false,\"isGeneratedLink\":true},{\"key\":\"17e97576-8040-43f4-aed9-a1a82b628e7d\",\"content\":\"Add Handler Mappings\",\"level\":4,\"link\":\"#add-handler-mappings\",\"disable\":false,\"isUpdated\":false,\"isGeneratedLink\":true},{\"key\":\"9485b234-ab96-4e1d-81a6-b90b4fa710e2\",\"content\":\"Update the FastCGI Application\",\"level\":4,\"link\":\"#update-the-fast-cgi-application\",\"disable\":false,\"isUpdated\":false,\"isGeneratedLink\":true},{\"key\":\"29931e1c-3d8d-4a54-89a3-2320f656a113\",\"content\":\"Conclusion\",\"level\":2,\"link\":\"#conclusion\",\"disable\":false,\"isUpdated\":false,\"isGeneratedLink\":true}],\"listStyle\":\"div\"} -->\n<div class=\"wp-block-rank-math-toc-block\" id=\"rank-math-toc\"><nav><div><div class=\"\"><a href=\"#introduction\">Introduction<\/a><\/div><div class=\"\"><a href=\"#why-choose-python-flask-ap-is\">Why choose Python Flask APIs?<\/a><\/div><div class=\"\"><a href=\"#what-is-celery-and-rabbit-mq\">What is Celery and RabbitMQ?<\/a><\/div><div class=\"\"><a href=\"#pre-requisites\">Pre-Requisites<\/a><\/div><div class=\"\"><a href=\"#setup-guide\">Setup Guide<\/a><div><div class=\"\"><a href=\"#setting-up-the-python-environment-and-flask-api\">Setting up the python environment and Flask API<\/a><div><div class=\"\"><a href=\"#setting-up-python\">Setting up python<\/a><\/div><div class=\"\"><a href=\"#setting-up-iis-with-cgi\">Setting up IIS with CGI<\/a><\/div><div class=\"\"><a href=\"#setting-up-the-flask-api-and-the-python-environment\">Setting up the Flask API and the python environment<\/a><\/div><\/div><\/div><div class=\"\"><a href=\"#setting-up-erlang-and-rabbit-mq\">Setting up Erlang and RabbitMQ<\/a><div><div class=\"\"><a href=\"#erlang-otp\">Erlang OTP<\/a><\/div><div class=\"\"><a href=\"#rabbit-mq\">RabbitMQ<\/a><\/div><\/div><\/div><div class=\"\"><a href=\"#setting-up-celery\">Setting up Celery<\/a><div><div class=\"\"><a href=\"#setting-up-nssm-and-the-windows-service\">Setting up NSSM and the windows service<\/a><\/div><\/div><\/div><div class=\"\"><a href=\"#deploying-application-with-iis-and-w-fast-cgi\">Deploying Application with IIS and WFastCGI<\/a><div><div class=\"\"><a href=\"#setup-website-to-point-to-folder\">Setup website to point to folder<\/a><\/div><div class=\"\"><a href=\"#add-permissions-to-iis\">Add permissions to IIS<\/a><\/div><div class=\"\"><a href=\"#add-handler-mappings\">Add Handler Mappings<\/a><\/div><div class=\"\"><a href=\"#update-the-fast-cgi-application\">Update the FastCGI Application<\/a><\/div><\/div><\/div><\/div><\/div><div class=\"\"><a href=\"#conclusion\">Conclusion<\/a><\/div><\/div><\/nav><\/div>\n<!-- \/wp:rank-math\/toc-block -->\n\n<!-- wp:heading -->\n<h2 class=\"wp-block-heading\" id=\"introduction\">Introduction<\/h2>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>In today\u2019s tech driven world, building scalable and efficient web applications is a top priority for developers and businesses alike. Python, with its versatility and power, has gained immense popularity in multiple fields of development, including the web. Flask, a lightweight and easy-to-scale microframework, is a preferred choice for building RESTful APIs. When it comes to handling background tasks and queuing, Celery combined with RabbitMQ is a formidable duo. Unlock the potential of Python Flask APIs with Celery and RabbitMQ in this detailed step-by-step guide, where we will walk you through the process of setting up a Python Flask API from scratch with Celery and RabbitMQ on an IIS (Internet Information Services) server.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading -->\n<h2 class=\"wp-block-heading\" id=\"why-choose-python-flask-ap-is\">Why choose Python Flask APIs?<\/h2>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>Python and Flask are a dynamic duo for building APIs, and their versatility makes them an excellent choice in various scenarios. Python's simplicity, readability, and extensive libraries make it a developer favorite. Flask, a microframework, is lightweight, easy to understand, and highly customizable. It's an excellent choice when you want to build APIs quickly without unnecessary complexities. <\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>Python's ecosystem also boasts robust data processing capabilities, which align perfectly with tasks involving data normalization and database operations. Additionally, Python's extensive community support ensures you'll find solutions to your challenges quickly. With Flask, you can create APIs that efficiently handle requests, and with Python, you can manipulate data effortlessly. Together, Python Flask APIs provide a solid foundation for creating responsive and reliable APIs.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading -->\n<h2 class=\"wp-block-heading\" id=\"what-is-celery-and-rabbit-mq\">What is Celery and RabbitMQ?<\/h2>\n<!-- \/wp:heading -->\n\n<!-- wp:media-text {\"mediaId\":4631,\"mediaLink\":\"https:\/\/blog.osmosys.co\/?attachment_id=4631\",\"mediaType\":\"image\"} -->\n<div class=\"wp-block-media-text alignwide is-stacked-on-mobile\"><figure class=\"wp-block-media-text__media\"><img src=\"https:\/\/blog.osmosys.co\/wp-content\/uploads\/2023\/09\/celery_rabbitmq-2-1024x527.jpg\" alt=\"\" class=\"wp-image-4631 size-full\"\/><\/figure><div class=\"wp-block-media-text__content\"><!-- wp:paragraph {\"placeholder\":\"Content\u2026\"} -->\n<p>Celery and RabbitMQ form a powerful combination for handling background tasks and asynchronous processing in Python applications. Celery is a distributed task queue that allows you to offload time-consuming and resource-intensive tasks to separate worker processes. It excels in managing tasks concurrently, making it suitable for scenarios like API requests triggering large data handling functions or compute\/time intensive tasks.<\/p>\n<!-- \/wp:paragraph --><\/div><\/div>\n<!-- \/wp:media-text -->\n\n<!-- wp:paragraph -->\n<p>RabbitMQ, on the other hand, serves as the message broker for Celery. It efficiently manages the communication between the API and worker processes by handling task distribution and results retrieval. In our setup, Celery will act as the engine that processes the task coming from the API, while RabbitMQ ensures seamless task coordination and communication. This combination provides the reliability and scalability required for background processing while keeping your API responsive.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading -->\n<h2 class=\"wp-block-heading\" id=\"pre-requisites\">Pre-Requisites<\/h2>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>Before getting into the setup process, let us list out and understand all the pre-requisites of the complete process. The steps to install and set up each requirement will come in subsequent sections:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:list -->\n<ul><!-- wp:list-item -->\n<li><strong>Python: <\/strong>Make sure you have Python 3.x (&gt;=3.7) installed on your server. You can download the latest version from the <a href=\"https:\/\/www.python.org\/\">official python website<\/a>. Make sure the initial install is added to PATH and Install <code>virtualenv<\/code> on the global version so that environments can be created for the app to run.<\/li>\n<!-- \/wp:list-item -->\n\n<!-- wp:list-item -->\n<li><strong>Flask<\/strong>: Since this is a python framework\/library, we will be setting this up along with the application that we aim to deploy.<\/li>\n<!-- \/wp:list-item -->\n\n<!-- wp:list-item -->\n<li><strong>Erlang OTP<\/strong>: Since we will be using RabbitMQ and it is built on Erlang, we will need Erlang OTP installed.<\/li>\n<!-- \/wp:list-item -->\n\n<!-- wp:list-item -->\n<li><strong>RabbitMQ<\/strong>: RabbitMQ is a message broker that Celery uses for task queueing.<\/li>\n<!-- \/wp:list-item -->\n\n<!-- wp:list-item -->\n<li><strong>WFastCGI<\/strong>: For deploying Flask applications on IIS, we will need WFastCGI, which will allow us to run Python web applications behind IIS. This can also be installed as a package in python using pip, so we will use that method.<\/li>\n<!-- \/wp:list-item -->\n\n<!-- wp:list-item -->\n<li><strong>NSSM<\/strong>: NSSM, or the Non-Sucking Service Manager, is a tool for creating and managing Windows services. It will be used to setup Celery workers as windows services. It can be downloaded from <a href=\"http:\/\/nssm.cc\/download\">here<\/a>.<\/li>\n<!-- \/wp:list-item -->\n\n<!-- wp:list-item -->\n<li><strong>IIS<\/strong>: IIS comes installed and running on all Windows machines. If not, you can enable it through the \u201cTurn Windows Features On or Off\u201d menu.<\/li>\n<!-- \/wp:list-item --><\/ul>\n<!-- \/wp:list -->\n\n<!-- wp:separator -->\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n<!-- \/wp:separator -->\n\n<!-- wp:heading -->\n<h2 class=\"wp-block-heading\" id=\"setup-guide\">Setup Guide<\/h2>\n<!-- \/wp:heading -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3 class=\"wp-block-heading\" id=\"setting-up-the-python-environment-and-flask-api\">Setting up the python environment and Flask API<\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>Let us first setup our python environment and app that we would be deploying. As Flask is a web framework and runs using python, this step is a necessary first. Since we would be deploying on a windows server, all steps mentioned so forth will be for windows only.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading {\"level\":4} -->\n<h4 class=\"wp-block-heading\" id=\"setting-up-python\">Setting up python<\/h4>\n<!-- \/wp:heading -->\n\n<!-- wp:list {\"ordered\":true} -->\n<ol><!-- wp:list-item -->\n<li>Download the latest Windows x86-64 executable installer from the <a href=\"https:\/\/www.python.org\/\">official python website<\/a>.<\/li>\n<!-- \/wp:list-item -->\n\n<!-- wp:list-item -->\n<li>Continue with the Install now option. Make sure to <strong>check yes, <\/strong>the box for add python to PATH on the first page. If you wish you can choose to customize the installation and set up your global python in a location of your choice. Click \u201cInstall\u201d.<\/li>\n<!-- \/wp:list-item -->\n\n<!-- wp:list-item -->\n<li>When the installation is complete, click close. You can verify the installation by running <code>where python<\/code> in your command prompt (CMD). It should give you a response like so, giving you the path where all and any pythons are downloaded to the machine, and added to the system environment variables.<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:image {\"align\":\"center\",\"id\":4635,\"width\":493,\"height\":186,\"sizeSlug\":\"full\",\"linkDestination\":\"none\"} -->\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img src=\"https:\/\/blog.osmosys.co\/wp-content\/uploads\/2023\/09\/image-1.png\" alt=\"\" class=\"wp-image-4635\" width=\"493\" height=\"186\"\/><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:heading {\"level\":4} -->\n<h4 class=\"wp-block-heading\" id=\"setting-up-iis-with-cgi\">Setting up IIS with CGI<\/h4>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>The Flask app will connect with the FastCGI module of the server to expose the APIs. So, we have to install IIS with CGI. You can follow the below steps to do so:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:list {\"ordered\":true} -->\n<ol><!-- wp:list-item -->\n<li>Open Server Manager and select Manage -&gt; Add Roles and Features<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:image {\"align\":\"center\",\"id\":4643,\"width\":584,\"height\":415,\"sizeSlug\":\"full\",\"linkDestination\":\"none\"} -->\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img src=\"https:\/\/blog.osmosys.co\/wp-content\/uploads\/2023\/09\/image-3.png\" alt=\"\" class=\"wp-image-4643\" width=\"584\" height=\"415\"\/><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:list {\"ordered\":true,\"start\":2} -->\n<ol start=\"2\"><!-- wp:list-item -->\n<li>You will see the before you begin page. Click next and select \u201cRole-based or feature-based installation\u201d in the Installation type section and click Next.<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:image {\"align\":\"center\",\"id\":4644,\"width\":560,\"height\":399,\"sizeSlug\":\"full\",\"linkDestination\":\"none\"} -->\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img src=\"https:\/\/blog.osmosys.co\/wp-content\/uploads\/2023\/09\/image-4.png\" alt=\"\" class=\"wp-image-4644\" width=\"560\" height=\"399\"\/><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:list {\"ordered\":true,\"start\":3} -->\n<ol start=\"3\"><!-- wp:list-item -->\n<li>Select the server in the \u201cServer Selection\u201d section and select \"Next\".<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:image {\"align\":\"center\",\"id\":4645,\"width\":550,\"height\":391,\"sizeSlug\":\"full\",\"linkDestination\":\"none\"} -->\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img src=\"https:\/\/blog.osmosys.co\/wp-content\/uploads\/2023\/09\/image-5.png\" alt=\"\" class=\"wp-image-4645\" width=\"550\" height=\"391\"\/><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:list {\"ordered\":true,\"start\":4} -->\n<ol start=\"4\"><!-- wp:list-item -->\n<li>On \u201cServer Roles\u201d, select \u201cWeb Server (IIS)\u201d, select \u201cAdd features\u201d and select \u201cNext\".<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:image {\"align\":\"center\",\"id\":4646,\"width\":545,\"height\":330,\"sizeSlug\":\"full\",\"linkDestination\":\"none\"} -->\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img src=\"https:\/\/blog.osmosys.co\/wp-content\/uploads\/2023\/09\/image-6.png\" alt=\"\" class=\"wp-image-4646\" width=\"545\" height=\"330\"\/><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:list {\"ordered\":true,\"start\":5} -->\n<ol start=\"5\"><!-- wp:list-item -->\n<li>Accept the default configurations and continue till we see the \u201cRole Services\u201d screen. Select \u201cCGI\u201d under \u201cApplication Development\u201d and select \u201cNext\u201d.<\/li>\n<!-- \/wp:list-item -->\n\n<!-- wp:list-item -->\n<li>Accept the default configurations and select \u201cInstall\u201d.<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:paragraph -->\n<p>After the installation is complete, close the installation wizard and launch IIS manager by using the command <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\"><code>inetmgr<\/code><\/code> in Windows Run (win + r). This will launch the IIS Manager in the system. If prompted with the following message, select \u201cNo\u201d. Microsoft Web Platform helps to install the Python and FastCGI modules, which we will do ourselves at a later stage with the Flask app.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:image {\"align\":\"center\",\"id\":4647,\"width\":360,\"height\":193,\"sizeSlug\":\"full\",\"linkDestination\":\"none\"} -->\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img src=\"https:\/\/blog.osmosys.co\/wp-content\/uploads\/2023\/09\/image-7.png\" alt=\"\" class=\"wp-image-4647\" width=\"360\" height=\"193\"\/><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:separator -->\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n<!-- \/wp:separator -->\n\n<!-- wp:heading {\"level\":4} -->\n<h4 class=\"wp-block-heading\" id=\"setting-up-the-flask-api-and-the-python-environment\">Setting up the Flask API and the python environment<\/h4>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>Now that we have python setup, lets setup our Flask API. If you already have an application hosted on a version control system, you can use git to get the repository onto the server at the following path:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>C:\/inetpub\/wwwroot<\/code><\/pre>\n<!-- \/wp:code -->\n\n<!-- wp:paragraph -->\n<p>This is required as to deploy a web app on IIS, the app is required to be in this folder for it to be read by IIS. For the sake of this guide, we will be using the following piece of code as our Flask app:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>\"\"\"\nDeploy Flask App in IIS Server\n\"\"\"\nimport time\nfrom flask import Flask\nfrom celery import Celery\napp = Flask(__name__)\napp.config&#91;\u2018CELERY_BROKER_URL\u2019] = \u2018pyamqp:\/\/guest:guest@localhost:5672\/\u2019\napp.config&#91;\u2018CELEREY_RESULT_BACKEND\u2019] = \u2018rpc:\/\/guest:guest@localhost:5672\u2019\ncelery = Celery(app.name, broker=app.config&#91;\u2018CELERY_BROKER_CONFIG\u2019, backend=app.config&#91;\u2018CELERY_RESULTS_BACKEND\u2019])\n@app.route(\"\/\")\ndef home():\n    background_task = hello.delay()\n    return \"Hello! This is our Flask App in IIS Server.\"\n@celery.task\ndef hello():\n    time.sleep(30)\n    print(\u201chello\u201d)\n\"if __name__ == \"__main__\":\n    app.run()<\/code><\/pre>\n<!-- \/wp:code -->\n\n<!-- wp:list {\"ordered\":true} -->\n<ol><!-- wp:list-item -->\n<li>Create a folder in <code><code data-enlighter-language=\"bash\" class=\"EnlighterJSRAW\">wwwroot<\/code><\/code> and add the above code in a file called app.py. (Or open CMD and run a git clone on <code><code data-enlighter-language=\"bash\" class=\"EnlighterJSRAW\">wwwroot<\/code><\/code> to get your repository)<\/li>\n<!-- \/wp:list-item -->\n\n<!-- wp:list-item -->\n<li>Open CMD as Admin and as a pre-step, run the command <code data-enlighter-language=\"bash\" class=\"EnlighterJSRAW\">where python<\/code> and copy the path to the python.exe file for the required python version. If there are different versions present from other apps running on the server, make sure to select the python version we just downloaded. run the following command to create a virtualenv. Before doing so, navigate to the folder where to code is present in CMD, a.k.a. <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">C:inetpubwwwrootFlaskApp<\/code><\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>Path\/to\/python.exe -m venv env\nenvScriptsactivate<\/code><\/pre>\n<!-- \/wp:code -->\n\n<!-- wp:list {\"ordered\":true,\"start\":3} -->\n<ol start=\"3\"><!-- wp:list-item -->\n<li>Now that we have our virtual environment and code set up, we can install our packages into the env. If you have a requirements.txt folder, run the command <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">pip install -r requirements.txt<\/code>, or you can directly use pip install in the CMD. Install the following packages using the command:<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>pip install flask wfastcgi celery<\/code><\/pre>\n<!-- \/wp:code -->\n\n<!-- wp:paragraph -->\n<p>This will install all packages required for our basic code and we can then move on to setting up Celery, RabbitMQ and deploying our app to IIS.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:separator -->\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n<!-- \/wp:separator -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3 class=\"wp-block-heading\" id=\"setting-up-erlang-and-rabbit-mq\">Setting up Erlang and RabbitMQ<\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:heading {\"level\":4} -->\n<h4 class=\"wp-block-heading\" id=\"erlang-otp\">Erlang OTP<\/h4>\n<!-- \/wp:heading -->\n\n<!-- wp:list {\"ordered\":true} -->\n<ol><!-- wp:list-item -->\n<li>From the <a href=\"https:\/\/erlang.org\/download\/otp_versions_tree.html\">official version tree of Erlang<\/a>, download the latest stable version &amp; install using an <strong>administrative user<\/strong>.<\/li>\n<!-- \/wp:list-item -->\n\n<!-- wp:list-item -->\n<li>Set ERLANG_HOME to where you actually put your Erlang installation, e.g., C:Program Fileserl{version} (full path, we have version=23.1.5). The RabbitMQ batch files expect to execute %ERLANG_HOME%binerl.exe.<\/li>\n<!-- \/wp:list-item -->\n\n<!-- wp:list-item -->\n<li>Go to Start &gt; Settings &gt; Control Panel &gt; System &gt; Advanced &gt; Environment Variables. Create the system environment variable ERLANG_HOME and set it to the full path of the directory which contains binerl.exe.<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:image {\"align\":\"center\",\"id\":4661,\"width\":535,\"height\":127,\"sizeSlug\":\"full\",\"linkDestination\":\"none\"} -->\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img src=\"https:\/\/blog.osmosys.co\/wp-content\/uploads\/2023\/09\/image-8.png\" alt=\"\" class=\"wp-image-4661\" width=\"535\" height=\"127\"\/><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:list {\"ordered\":true,\"start\":4} -->\n<ol start=\"4\"><!-- wp:list-item -->\n<li>Open CMD and type <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">\"%ERLANG_HOME%\"binerl.exe<\/code> . You should see an E-Shell prompt.<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:image {\"align\":\"center\",\"id\":4662,\"width\":429,\"height\":97,\"sizeSlug\":\"full\",\"linkDestination\":\"none\"} -->\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img src=\"https:\/\/blog.osmosys.co\/wp-content\/uploads\/2023\/09\/image-9.png\" alt=\"\" class=\"wp-image-4662\" width=\"429\" height=\"97\"\/><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:heading {\"level\":4} -->\n<h4 class=\"wp-block-heading\" id=\"rabbit-mq\">RabbitMQ<\/h4>\n<!-- \/wp:heading -->\n\n<!-- wp:list {\"ordered\":true} -->\n<ol><!-- wp:list-item -->\n<li>download the RabbitMQ installer, rabbitmq-server-{version}.exe and run it using the following command.<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>cd C:Program FilesRabbitMQ Serverrabbitmq_server-3.11.6sbin\nrabbitmq-plugins.bat enable rabbitmq_management<\/code><\/pre>\n<!-- \/wp:code -->\n\n<!-- wp:list {\"ordered\":true,\"start\":2} -->\n<ol start=\"2\"><!-- wp:list-item -->\n<li>After the above 2 commands, run this command.<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>rabbitmq-plugins enable rabbitmq_shovel rabbitmq_shovel_management<\/code><\/pre>\n<!-- \/wp:code -->\n\n<!-- wp:image {\"align\":\"center\",\"id\":4663,\"width\":790,\"height\":198,\"sizeSlug\":\"large\",\"linkDestination\":\"none\"} -->\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img src=\"https:\/\/blog.osmosys.co\/wp-content\/uploads\/2023\/09\/image-10-1024x256.png\" alt=\"\" class=\"wp-image-4663\" width=\"790\" height=\"198\"\/><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:list {\"ordered\":true,\"start\":3} -->\n<ol start=\"3\"><!-- wp:list-item -->\n<li>&nbsp;Open Windows search, search for notepad and right click to select \"Run as administrator\". Search for and open <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">C:WindowsSystem32driversetchosts<\/code> file. Add to it the following line, and save:<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>127.0.0.1 rabbitmq<\/code><\/pre>\n<!-- \/wp:code -->\n\n<!-- wp:list {\"ordered\":true} -->\n<ol><!-- wp:list-item -->\n<li>Once all done, open <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">http:\/\/rabbitmq:15672\/<\/code> on a web browser for opening the RabbitMQ management. The default credentials are always as follows:<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>Username: guest\nPassword: guest<\/code><\/pre>\n<!-- \/wp:code -->\n\n<!-- wp:separator -->\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n<!-- \/wp:separator -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3 class=\"wp-block-heading\" id=\"setting-up-celery\">Setting up Celery<\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>In our Flask app \u2013 app.py, we have already added all necessary configurations and functions to set up celery, use RabbitMQ as a task broker on the port 5672, and added a function that will get called in the background asynchronously from the actual API call.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>To make all of this happen, we need what is called a worker. A celery worker is responsible for executing asynchronous tasks in the background. The worker listens to the task queue, which in this case is RabbitMQ, waits for oncoming tasks, and once a task is received, it processes it independently from the main application.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>The worker will need admin permissions since our complete code base is in the C drive. To achieve this and help run the worker, we will create a windows batch file. The following steps can be used to create the batch file:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:list {\"ordered\":true} -->\n<ol><!-- wp:list-item -->\n<li>Open a text editor, like notepad.<\/li>\n<!-- \/wp:list-item -->\n\n<!-- wp:list-item -->\n<li>Add the following commands in the first 2 lines of the file.<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@REM #run as admin\ncd \"C:inetpubwwwrootFlaskApp\"&amp;&amp;envScriptsactivate&amp;&amp;celery -A app.celery worker --pool=solo -l info<\/pre><\/code><\/pre>\n<!-- \/wp:code -->\n\n<!-- wp:paragraph -->\n<p>The first line here will tell the batch file to be opened as admin, and the second line will in order, go to the code directory, activate the python environment, and then call the celery configuration stored in our app.py file to create a worker.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:list {\"ordered\":true,\"start\":3} -->\n<ol start=\"3\"><!-- wp:list-item -->\n<li>Save the text file, preferably in the Folder with the rest of the code. Name it as celery_worker.bat and keep the \"Save as\" type as \"All Files (*.*)\".<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:paragraph -->\n<p>To set up the worker to run indefinitely, we will be using NSSM, or the Non-sucking service manager. It is a 3<sup>rd<\/sup> party open-source tool that allows us to convert batch\/executable files into windows services.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading {\"level\":4} -->\n<h4 class=\"wp-block-heading\" id=\"setting-up-nssm-and-the-windows-service\">Setting up NSSM and the windows service<\/h4>\n<!-- \/wp:heading -->\n\n<!-- wp:list {\"ordered\":true,\"type\":\"1\"} -->\n<ol type=\"1\"><!-- wp:list-item -->\n<li>Download <a href=\"http:\/\/nssm.cc\/download\" target=\"_blank\" rel=\"noreferrer noopener\">nssm<\/a>. Follow the steps as mentioned on website for download.<\/li>\n<!-- \/wp:list-item -->\n\n<!-- wp:list-item -->\n<li>Unzip the contents, go to \"nssm-2.24win32\" and copy-paste the executable into any external folder. There are no other installation steps required. This external folder should be added to PATH environment variable. It should be a user variable.<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:paragraph -->\n<p>Now that we have NSSM set up, we will go ahead and create the service using the celery_worker.bat file we created earlier.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:list {\"ordered\":true,\"type\":\"1\"} -->\n<ol type=\"1\"><!-- wp:list-item -->\n<li>Open CMD as admin<\/li>\n<!-- \/wp:list-item -->\n\n<!-- wp:list-item -->\n<li>Run the following command in CLI<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>nssm install service_name<\/code><\/pre>\n<!-- \/wp:code -->\n\n<!-- wp:paragraph -->\n<p>In this case, service_name = flask_app<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:list {\"ordered\":true,\"type\":\"1\",\"start\":3} -->\n<ol type=\"1\" start=\"3\"><!-- wp:list-item -->\n<li>This will open a service installer window and all aspects of the service can be configured\/edited from here.<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:list {\"ordered\":true,\"start\":4} -->\n<ol start=\"4\"><!-- wp:list-item -->\n<li>In the \"Application\" tab, Path should be pointed to the batch file to be run indefinitely, in this case the celery_worker.bat.<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:image {\"align\":\"center\",\"id\":4668,\"width\":362,\"height\":203,\"sizeSlug\":\"full\",\"linkDestination\":\"none\"} -->\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img src=\"https:\/\/blog.osmosys.co\/wp-content\/uploads\/2023\/09\/image-11.png\" alt=\"\" class=\"wp-image-4668\" width=\"362\" height=\"203\"\/><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:list {\"ordered\":true,\"start\":5} -->\n<ol start=\"5\"><!-- wp:list-item -->\n<li>Go to the details tab and add an appropriate name, description, and keep the startup type as \u201cAutomatic\u201d.<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:image {\"align\":\"center\",\"id\":4669,\"width\":382,\"height\":209,\"sizeSlug\":\"full\",\"linkDestination\":\"none\"} -->\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img src=\"https:\/\/blog.osmosys.co\/wp-content\/uploads\/2023\/09\/image-12.png\" alt=\"\" class=\"wp-image-4669\" width=\"382\" height=\"209\"\/><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:list {\"ordered\":true,\"start\":6} -->\n<ol start=\"6\"><!-- wp:list-item -->\n<li>Go to the log on tab and select \u201cthis account\u201d enter your credentials here, or if you have a service account for the server with appropriate access and permissions, add the credentials to that account here. This account will be used to run the service. The rest of the configurations are optional in the rest of the tabs and can be added as required (such as logging from the I\/O tab and File rotation to rotate the log files).<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:image {\"align\":\"center\",\"id\":4670,\"width\":398,\"height\":219,\"sizeSlug\":\"full\",\"linkDestination\":\"none\"} -->\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img src=\"https:\/\/blog.osmosys.co\/wp-content\/uploads\/2023\/09\/image-13.png\" alt=\"\" class=\"wp-image-4670\" width=\"398\" height=\"219\"\/><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:list {\"ordered\":true,\"start\":7} -->\n<ol start=\"7\"><!-- wp:list-item -->\n<li>Click finish and the service will get installed. For the first time, the service would be stopped and will have to be started manually by going to the \u201cServices\u201d application, locating the service and clicking start. On system startup\/reboot, it will start automatically because of the slection done in step 5.<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3 class=\"wp-block-heading\" id=\"deploying-application-with-iis-and-w-fast-cgi\">Deploying Application with IIS and WFastCGI<\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>Now that we have all the other aspects of the project up and running, we can get to deploying the API on IIS, which will allow users to run the API through a port on the server. If you have one, you can also add a domain to the web app we will set up now \u2013<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading {\"level\":4} -->\n<h4 class=\"wp-block-heading\" id=\"setup-website-to-point-to-folder\">Setup website to point to folder<\/h4>\n<!-- \/wp:heading -->\n\n<!-- wp:list {\"ordered\":true} -->\n<ol><!-- wp:list-item -->\n<li>Open the IIS application and go to Sites. Right click and click on Add new website.<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:image {\"align\":\"center\",\"id\":4671,\"width\":233,\"height\":215,\"sizeSlug\":\"full\",\"linkDestination\":\"none\"} -->\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img src=\"https:\/\/blog.osmosys.co\/wp-content\/uploads\/2023\/09\/image-14.png\" alt=\"\" class=\"wp-image-4671\" width=\"233\" height=\"215\"\/><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:list {\"ordered\":true,\"start\":2} -->\n<ol start=\"2\"><!-- wp:list-item -->\n<li>Give a name to your website and set the physical path to your project directory. Assign a port number and click ok. If you have a domain name, you can add that as well in the \"Host name\" field.<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:image {\"align\":\"center\",\"id\":4672,\"width\":404,\"height\":468,\"sizeSlug\":\"full\",\"linkDestination\":\"none\"} -->\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img src=\"https:\/\/blog.osmosys.co\/wp-content\/uploads\/2023\/09\/image-15.png\" alt=\"\" class=\"wp-image-4672\" width=\"404\" height=\"468\"\/><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:heading {\"level\":4} -->\n<h4 class=\"wp-block-heading\" id=\"add-permissions-to-iis\">Add permissions to IIS<\/h4>\n<!-- \/wp:heading -->\n\n<!-- wp:list {\"ordered\":true,\"start\":3} -->\n<ol start=\"3\"><!-- wp:list-item -->\n<li>Open CMD as admin, navigate to the app directory, and activate the environment. run the following 2 commands to give appropriate permissions to IIS to run the code in the folder:<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>icacls . \/grant \"NT AUTHORITYIUSR:(OI)(CI)(RX)\"\nicacls . \/grant \"BuiltinIIS_IUSRS:(OI)(CI)(RX)\"<\/code><\/pre>\n<!-- \/wp:code -->\n\n<!-- wp:image {\"align\":\"center\",\"id\":4673,\"width\":560,\"height\":189,\"sizeSlug\":\"full\",\"linkDestination\":\"none\"} -->\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img src=\"https:\/\/blog.osmosys.co\/wp-content\/uploads\/2023\/09\/image-16.png\" alt=\"\" class=\"wp-image-4673\" width=\"560\" height=\"189\"\/><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:heading {\"level\":4} -->\n<h4 class=\"wp-block-heading\" id=\"add-handler-mappings\">Add Handler Mappings<\/h4>\n<!-- \/wp:heading -->\n\n<!-- wp:list {\"ordered\":true,\"type\":\"1\",\"start\":4} -->\n<ol type=\"1\" start=\"4\"><!-- wp:list-item -->\n<li>On IIS, go to the FlaskApp site, present under Sites. Click on that and select the \u201cHandler Mappings\u201d icon.<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:image {\"align\":\"center\",\"id\":4674,\"width\":593,\"height\":252,\"sizeSlug\":\"large\",\"linkDestination\":\"none\"} -->\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img src=\"https:\/\/blog.osmosys.co\/wp-content\/uploads\/2023\/09\/image-17-1024x435.png\" alt=\"\" class=\"wp-image-4674\" width=\"593\" height=\"252\"\/><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:list {\"ordered\":true,\"start\":5} -->\n<ol start=\"5\"><!-- wp:list-item -->\n<li>Here, select \"Add Module Mapping\" and insert the following values:<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:preformatted -->\n<pre class=\"wp-block-preformatted\">Request Path: *\nModule: FastCgiModule (Select from the dropdown menu)\nExecutable(optional): \nC:inetpubwwwrootFlaskAppenvScriptspython.exe|C:inetpubwwwrootFlaskAppenvLibsite-packageswfastcgi.py\nName: FlaskHandler<\/pre>\n<!-- \/wp:preformatted -->\n\n<!-- wp:image {\"align\":\"center\",\"id\":4676,\"width\":453,\"height\":401,\"sizeSlug\":\"full\",\"linkDestination\":\"none\"} -->\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img src=\"https:\/\/blog.osmosys.co\/wp-content\/uploads\/2023\/09\/image-18.png\" alt=\"\" class=\"wp-image-4676\" width=\"453\" height=\"401\"\/><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:list {\"ordered\":true,\"start\":6} -->\n<ol start=\"6\"><!-- wp:list-item -->\n<li>Click on Request Restrictions and uncheck \u201cInvoke handler only if request is mapped to:\u201d checkbox and select OK, followed by another OK. Select \u201cYes\u201d if prompted by this warning.<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:image {\"align\":\"center\",\"id\":4677,\"width\":432,\"height\":183,\"sizeSlug\":\"full\",\"linkDestination\":\"none\"} -->\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img src=\"https:\/\/blog.osmosys.co\/wp-content\/uploads\/2023\/09\/image-19.png\" alt=\"\" class=\"wp-image-4677\" width=\"432\" height=\"183\"\/><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:list {\"ordered\":true,\"start\":7} -->\n<ol start=\"7\"><!-- wp:list-item -->\n<li>Now, verify the module mapping in FastCGI settings in the root server. This should create an entry in FastCGI Settings.<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:image {\"align\":\"center\",\"id\":4679,\"width\":822,\"height\":242,\"sizeSlug\":\"large\",\"linkDestination\":\"none\"} -->\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img src=\"https:\/\/blog.osmosys.co\/wp-content\/uploads\/2023\/09\/image-20-1024x301.png\" alt=\"\" class=\"wp-image-4679\" width=\"822\" height=\"242\"\/><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:heading {\"level\":4} -->\n<h4 class=\"wp-block-heading\" id=\"update-the-fast-cgi-application\">Update the FastCGI Application<\/h4>\n<!-- \/wp:heading -->\n\n<!-- wp:list {\"ordered\":true,\"start\":8} -->\n<ol start=\"8\"><!-- wp:list-item -->\n<li>Double click the application entry in FastCGI settings to edit the application and select \"Environment variables\". Click on \"...\" and open the \"EnvironmentVariables Collection Editor\". Add the below entries:<\/li>\n<!-- \/wp:list-item --><\/ol>\n<!-- \/wp:list -->\n\n<!-- wp:preformatted -->\n<pre class=\"wp-block-preformatted\">Name: PYTHONPATH\nValue: C:inetpubwwwrootFlaskApp<\/pre>\n<!-- \/wp:preformatted -->\n\n<!-- wp:image {\"align\":\"center\",\"id\":4680,\"width\":457,\"height\":342,\"sizeSlug\":\"full\",\"linkDestination\":\"none\"} -->\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img src=\"https:\/\/blog.osmosys.co\/wp-content\/uploads\/2023\/09\/image-21.png\" alt=\"\" class=\"wp-image-4680\" width=\"457\" height=\"342\"\/><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:paragraph -->\n<p>The PYTHONPATH must point to the directory containing the Flask Application.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:preformatted -->\n<pre class=\"wp-block-preformatted\">Name: WSGI_Handler\nValue: app.app<\/pre>\n<!-- \/wp:preformatted -->\n\n<!-- wp:image {\"align\":\"center\",\"id\":4681,\"width\":454,\"height\":341,\"sizeSlug\":\"full\",\"linkDestination\":\"none\"} -->\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img src=\"https:\/\/blog.osmosys.co\/wp-content\/uploads\/2023\/09\/image-22.png\" alt=\"\" class=\"wp-image-4681\" width=\"454\" height=\"341\"\/><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:paragraph -->\n<p>The WSGI_HANDLER must point to the application name followed by \u201c.app\u201d. In our case, the application name is \u201capp.py\u201d so WSGI_HANDLER is pointing to \u201capp.app\u201d.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>Your website is now ready to use over the port you set at the beginning of the website setup on IIS. Enjoy!<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:image {\"id\":4682,\"sizeSlug\":\"full\",\"linkDestination\":\"none\"} -->\n<figure class=\"wp-block-image size-full\"><img src=\"https:\/\/blog.osmosys.co\/wp-content\/uploads\/2023\/09\/image-23.png\" alt=\"\" class=\"wp-image-4682\"\/><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:heading -->\n<h2 class=\"wp-block-heading\" id=\"conclusion\">Conclusion<\/h2>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>Setting up a Python Flask API with Celery and RabbitMQ on IIS can be a complex and lengthy task, but it's a powerful combination for building robust web applications that can handle background tasks and queueing efficiently. By following this step-by-step guide, you've learned how to configure each component and integrate them into a seamless web application. With the right setup, your Flask app can now handle concurrent tasks and deliver a smooth user experience while processing background jobs asynchronously. This combination opens up a world of possibilities for building feature-rich and efficient web applications.<\/p>\n<!-- \/wp:paragraph -->","_et_gb_content_width":"795","_lmt_disableupdate":"","_lmt_disable":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[87],"tags":[92,93,94,95,96,97],"class_list":["post-235786","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-web-development","tag-celery","tag-flask-api","tag-iis","tag-python","tag-rabbitmq","tag-setup-guide"],"modified_by":"mounika","jetpack_featured_media_url":"https:\/\/osmosys.co\/ca\/wp-content\/uploads\/sites\/5\/2024\/04\/1-jpg.webp","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/osmosys.co\/ca\/wp-json\/wp\/v2\/posts\/235786","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/osmosys.co\/ca\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/osmosys.co\/ca\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/osmosys.co\/ca\/wp-json\/wp\/v2\/users\/11"}],"replies":[{"embeddable":true,"href":"https:\/\/osmosys.co\/ca\/wp-json\/wp\/v2\/comments?post=235786"}],"version-history":[{"count":3,"href":"https:\/\/osmosys.co\/ca\/wp-json\/wp\/v2\/posts\/235786\/revisions"}],"predecessor-version":[{"id":235833,"href":"https:\/\/osmosys.co\/ca\/wp-json\/wp\/v2\/posts\/235786\/revisions\/235833"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/osmosys.co\/ca\/wp-json\/wp\/v2\/media\/235809"}],"wp:attachment":[{"href":"https:\/\/osmosys.co\/ca\/wp-json\/wp\/v2\/media?parent=235786"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/osmosys.co\/ca\/wp-json\/wp\/v2\/categories?post=235786"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/osmosys.co\/ca\/wp-json\/wp\/v2\/tags?post=235786"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}