Can I use a different file structure in azure app services? - python

I have a python flask API in azure app services. When deploying to it from vs code, I get a "successful deployment" message, but the app still shows the default initial web page provided as a template from Microsoft for new app services.
The current file structure looks something like this:
├───README.md
├───docs
├───data
└───src
├───main.py
└───other_files.py
I changed the file structure to look like the following:
├───README.md
├───docs
├───data
├───app.py
└───src
└───other_files.py
After deploying it like this, the application was able to start normally instead of displaying the boilerplate webpage from Microsoft. What do I need to do to have the app.py inside the src directory?
Can it actually be done?

I was able to solve it on my own by providing a custom startup command in the configuration of the app service. It can be done from the azure portal, in the "Configuration" section, or with the azure CLI.
az webapp config set --resource-group <resource-group-name> --name <app-name> --startup-file "<custom-command>"
And the custom command was:
gunicorn --bind=0.0.0.0 --timeout 600 --chdir src main:app
More details of this here: https://learn.microsoft.com/en-us/azure/app-service/configure-language-python#customize-startup-command

Related

Dash app cannot find pages folder when deploying on GCP using gunicorn

I am trying to deploy my dash app which uses dash_extensions, Dash_proxy and has multiple pages in the pages folder on GCP cloud run using gunicorn but the app cannot find the pages folder. It works perfectly fine when I use the development server but breaks in the production server because it cannot find the folder path.
The app (following code is inside the app.py file):
app = DashProxy(use_pages=True, pages_folder=pages_folder, external_stylesheets=[dbc.themes.SIMPLEX])
The app.py file and the pages folder are in the same directory
I have tried tried to following methods to get the folder path:
pages_folder="pages"
pages_folder=os.path.join(os.path.dirname(__file__), "pages")
for p in Path('.').rglob('*'):
if str(p).endswith('pages'):
pages_folder = str(p)
break
None of the above three work in when deploying on gcp using gunicorn through docker:
Dockerfile command:
CMD ["gunicorn" , "-b", "0.0.0.0:8000", "app:server"]
But if I use dev server through docker like following code it works:
CMD python app.py
Does anyone have any ideas of how to make it work with gunicorn?
Thanks for the help!
-Rexon
Yes I did. Just had to specify the root folder. This is what I did and it seems to work for me.
pages_folder=os.path.join(os.path.dirname(__name__), "pages")
app = DashProxy(__name__,use_pages=True, pages_folder=pages_folder, external_stylesheets=[dbc.themes.SIMPLEX])
server=app.server

Change from app.py to main.py when deploying a FLASK app in Google App Engine

I am following the instructions here to deploy an app in Google App Engine. Everything works correctly.
Nevertheless, Google, by default, looks for the main folder (where app = Flask(__name__) is defined) in main.py. How could I redefine this? I would like to define this main folder as app.py.
Rename main.py to app.py
Add entrypoint: gunicorn -b :$PORT app:app to your app.yaml file. This is where you are telling Google to find the app object in a file called app
Add gunicorn to your requirements.txt file
Notes:
i. Because you're changing from main.py to app.py, you need to specify an entrypoint. GAE documentation says
If your app meets the following requirements, App Engine will start
your app with the gunicorn web server if you don't specify the
entrypoint field:
The root of your app directory contains a main.py file with a WSGI-compatible object called app.
Your app does not contain Pipfile or Pipfile.lock files.
ii. If you add an entrypoint, then you need to include gunicorn in your requirements.txt file
iii. I just tested the above configuration (the answer I gave) on a dev environment (Python 3.9 environment on Macbook using dev_appserver.py) and it works

Deploying Flask Application to Azure App Servce (Linux)

I was deploying a flask applications to Azure App Services with the following (example) file structure.
flask-app
├── application.py
└── web
└── __init__.py
Inside __init__.py I declared app = Flask(__name__) (and of course do other things such as setup the configuration and add the controllers). Then, inside application.py, I just did from web import app.
When attempting to deploying this to Azure App Services, I would receive the following error when App Services would try to start the application: "Failed to find attribute 'app' in 'application'".
In order to fix this, I modified application.py to do the following:
from web import app
app = app
And then the app was able to be deployed. Of course, I'm somewhat skeptical that this is a proper fix or if what was happening was a bug, but I thought I would share this in case it helped others in the future.

ModuleNotFoundError: No module named 'django' by Deploying on Azure

I'm trying to deploy a django web app to the Microsoft Azure and this is correctly deployed by the pipeline on DevOps Azure, but I get the error message (ModuleNotFoundError: No module named 'django) on portal Azure and cannot reach my app via the URL.
The app also works properly locally
Here is the whole error message: '''https://pastebin.com/mGHSS8kQ'''
How can I solve this error?
I understand you have tried the steps suggested in the SO thread Eyap shared, and few things here are already covers that. Kindly review these settings.
You can use this command instead - source /antenv3.6/bin/activate.
As a side note- The antenv will be available only after a deployment is initiated. Kindly check the “/” path from SSH and you should see a folder with name starting from antenv.
Browse to .python_packages/lib/python3.6/site-packages/ or .python_packages/lib/site-packages/. Kindly review the file path exists.
Review the Application logs as well (/home/LogFiles folder) from Kudu- https://<yourwebpp-name>.scm.azurewebsites.net/api/logs/docker
The App Service deployment engine automatically activates a virtual environment and runs
pip install -r requirements.txt
The requirements.txt file must be in the project root for dependencies to be installed.
For Django apps, App Service looks for a file named wsgi.py within your app code, and then runs Gunicorn using the following command:
is the name of the folder that contains wsgi.py
gunicorn --bind=0.0.0.0 --timeout 600 .wsgi
If you want more specific control over the startup command, use a custom startup command, replace with the name of folder that contains wsgi.py, and add a --chdir argument if that module is not in the project root.
For additional details, please checkout this document
Configure a Linux Python app for Azure App Service
Quickstart: Create a Python app in Azure App Service on Linux

Predix - Polymer frontend to communicate with Flask Python server?

I'm trying to push a program containing of 2 apps to Cloudfoundry - a Flask server to run a Python API and a Polymer app for frontend. Currently I'm using the following structure:
manifest.yml:
---
applications:
- name: flask_min
path: ./flask_min
buildpack: https://github.com/cloudfoundry/python-buildpack
memory: 512M
- name: pacing_app
memory: 512M
buildpack: nodejs_buildpack
command: node server/app.js
path: ./pacing_app/build/es5-basic
And then in the folder ./flask_min I have a Procfile:
web: python3 app.py
and app.py has a Flask server (plus the decorator for CORS for local testing that I left out from here for brevity):
app = Flask(__name__)
port = int(os.getenv("PORT", 7733))
#app.route('/hello', methods=['GET', 'OPTIONS'])
#crossdomain(origin='*')
def hello():
return "Hello"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=port)
I can cf push it, and the instances show up running. However, when I visit the url of the flask_min app, I don't get the "Hello" it's supposed to print out, I get an HTTP ERROR 503.
As for the pacing_app, I am using the Predix Webapp Starter, except that I removed the elements in seed-app.html and just replaced it with the API call:
<template>
<iron-ajax url="http://localhost:7733/hello" handle-as="text" last-response="{{data}}" auto></iron-ajax>
<p>{{data}}</p>
</template>
Locally this is working, however, on Predix it is not. First question is: How can I link to the Flask API once it's on Predix?
Also, even though the whole thing is working locally, the Polymer frontend also won't load when on Predix. I also get
Failed to load resource: the server responded with a status of 503
(Service Unavailable)
Even though the cf push seems successful, the same IS running locally when I do a gulp in the pacing-app folder and run thy python server "by hand" locally.
Do you know what I'm doing wrong? How can I set up a Polymer frontend with Predix components that uses a Python API also running on Predix?
I'm not set on using two separate apps, I just don't know how to do this with one app. I would prefer to have the Polymer app run on the NodeJS server instead of serving it from Flask because of performance and the Python/Flask server is important because I intend to run some SKLearn code in the background.
I see two options for you.
Use the predix-webapp-starter with NodeJS as your front end server. Use a separate Python microservice as your back end server. This approach might be better, especially if your backend SKLearn processes take a long time.
Run everything in a single Python/Flask server. You could look at the Predix Digital Volcano App as an example. This approach might be easier if you have more experience with Python.
The combination of polymer and flask requires a bit of 'adjusting' for the flask server to serve the correct polymer folder... Starting from a simple flask server as below:
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return app.send_static_file('index.html')
#app.route('/<path:the_path>')
def all_other_routes(the_path):
return app.send_static_file(the_path)
if __name__ == '__main__':
app.run(debug=True)
and by using the polymer starter kit in a new folder:
mkdir polymer && cd polymer && polymer init polymer-3-starter-kit && polymer build && cd ..
Then, you either have to change the default flask serving folder (static) or you can simply create a symbolic link to your polymer build folder. I prefer to do the second, by issuing the following command on the root directory (alongside your server file):
ln -s ./polymer/build/es6-bundled ./static

Categories

Resources