[PYTHON] Flask can't be RESTful with azure API Apps

Introduction

Anyway, python is very easy to write a simple Web API application. Flask is a framework that takes advantage of this convenience and makes path routing easy. A sample for writing API Apps in python with Azure App Service is also available in Flask (https://docs.microsoft.com/ja-jp/azure/app-service-web/app-service-web) -get-started-python). My main job is java, but most language-unconstrained programs are written in python, and if I deploy an API using Flask to API Apps with the same glue, this doesn't work.

Problems and countermeasures

Event

What didn't work was that Flask's @ app.route () didn't work. To be precise, @ app.route ("/ ") works, but something like @ app.route ("/ user / <id> / status ") doesn't work. GET /user/1/status HTTP / 1.1 returns with an IIS (?) 404. What's wrong with this is that (probably) Web Apps has IIS on the front and dispatches to Flask in python, but by default only "/" is passed to Flask, / user. I think this is because paths like / 1 / status are out of scope [^ 1]. [^ 1]: I'm new to azure App Service so I don't even know how to read the log, but the ghost whispers so.

policy

If this is java, it is realized by registering which Servlet to process with url-pattern in Web Application Container, and if it is cgi, HTTP Server is mapping with Request Handler. So I can imagine that I'm teaching Web Apps how to move. According to Configuring Python with Azure App Service Web Apps

To specify how the server handles the request, you need to create a web.config file. If you have a web.x.y.config file in your repository (where x.y is the Python runtime of your choice), Azure will automatically copy the appropriate file as web.config.

a. This time I was trying to run it with python3.4, so I think I should do something with web.3.4.config.

solution

First of all, ** I can't take responsibility even if I read this and implement it and the security becomes sloppy, so please judge whether there is no problem by yourself (bar reading) **

So, how to do it, as described in the previous article

xml:web.3.4.config


<?xml version="1.0"?>
<configuration>
  <appSettings>
    <add key="WSGI_ALT_VIRTUALENV_HANDLER" value="app.wsgi_app" />
    <add key="WSGI_ALT_VIRTUALENV_ACTIVATE_THIS"
         value="D:\home\site\wwwroot\env\Scripts\python.exe" />
    <add key="WSGI_HANDLER"
         value="ptvs_virtualenv_proxy.get_venv_handler()" />
    <add key="PYTHONPATH" value="D:\home\site\wwwroot" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
    <handlers>
      <remove name="Python27_via_FastCGI" />
      <remove name="Python34_via_FastCGI" />
      <add name="Python FastCGI"
           path="handler.fcgi"
           verb="*"
           modules="FastCgiModule"
           scriptProcessor="D:\Python34\python.exe|D:\Python34\Scripts\wfastcgi.py"
           resourceType="Unspecified"
           requireAccess="Script" />
    </handlers>
    <rewrite>
      <rules>
        <rule name="Static Files" stopProcessing="true">
          <conditions>
            <add input="true" pattern="false" />
          </conditions>
        </rule>
        <rule name="Configure Python" stopProcessing="true">
          <match url="(.*)" ignoreCase="false" />
          <conditions>
            <add input="{REQUEST_URI}" pattern="^/static/.*" ignoreCase="true" negate="true" />
          </conditions>
          <action type="Rewrite" url="handler.fcgi/{R:1}" appendQueryString="true" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

If it is, it seems that routing like @ app.route ("/ user / <id> / status ") works properly [^ 2]. The definition of <rule name =" Configure Python "stopProcessing =" true "> ~ </ rule> in <system.webServer> Hogehogehoge </ system.webServer> hooks the URL pattern and python It seems that I'm trying to give it to, but I'm thinking about checking the operation again. Maybe you can see how it works by reading the IIS documentation.

[^ 2]: Of course, you need to consider that static content can also be handled by Flask.

Recommended Posts

Flask can't be RESTful with azure API Apps
Getting Started with Flask with Azure Web Apps
Try to make RESTful API with MVC using Flask 1.0.2
API with Flask + uWSGI + Nginx
TensorFlow 2.2 can't be installed with Python 3.8!
Persist Flask API server with forever
Efficiently develop Azure Python apps with CI/CD
Azure table storage with PTVS Flask app
[Python] Quickly create an API with Flask
Try slack OAuth authentication with flask (Slack API V2)
Monitor Python apps with New Relic's APM (Flask)
Text extraction (Read API) with Azure Computer Vision API (Python3.6)