Flask + MongoDB: An "Azure Web App For Dummies" guide - azure

After spending many hours reading dozens of guides, I finally got into a working setup, and decided to publish the instructions here.
The problem: I have a working flask app running in my machine. How do I launch it as a web app using Microsoft Azure platform?

So here is my guide. I hope it will help others!
Steps for launching a new web app under Azure:
0. Login to Azure
Goto Azure portal https://portal.azure.com/ and sign-in using your Microsoft account.
1. Create a resource group:
Home > create a resource > Resource group
fill in: subscription(Free Trial), name (something with _resgrp), Region (e.g. West Europe)
2. DB:
Home > create a resource > create Azure Cosmos DB > Azure Cosmos DB for MongoDB
fill in: subscription(Free Trial), resource group (see above), account name (something with _db), Region (West Europe), [create]
goto Home > db account > connection strings, copy line marked "PRIMARY CONNECTION STRING" and keep it aside.
3. App:
Home > create a resource > create Web App
fill in: subscription(Free Trial), resource group (see above), name (will appear in the site url!),
publish: code, run time stack: python 3.9, region: West Europe, plan: Basic B1 ($13/mon), [create]
Home > our-web-app > configuration > Application settings > Connection strings
click "New Connection strings" and set MYDB with the connection string from step 2.
4. Code:
We will use a nice "to-do list" minimalist app published by Prashant Shahi. Thank you Prashant!
Clone code from https://github.com/prashant-shahi/ToDo-List-using-Flask-and-MongoDB into some local folder.
Delete everything but app.py, static, templates, requirements.txt
Edit requirements.txt so that Flask appears without "==version", because an older version is there by default.
create wsgi.py with:
from app import app
if __name__ == '__main__':
app.run()
Create go.sh with the following code. These commands are will setup the environment and then start gunicorn to respond to web requests. Some of these commands are used for debug only.
# azure webapp: called under sh from /opt/startup/startup.sh
set -x
ls -la
pip install -r /home/site/wwwroot/requirements.txt
echo "$(pwd) $(date)"
ps aux
gunicorn --bind=0.0.0.0 --log-level=debug --timeout 600 wsgi:app
edit app.py:
replace first 3 lines about db connection with: (btw, MYDB comes from steps 3)
CON_STR = os.environ['CUSTOMCONNSTR_MYDB']
client = MongoClient(CON_STR) #Configure the connection to the database
after app = Flask(name) add these lines for logging:
if __name__ != '__main__':
gunicorn_logger = logging.getLogger('gunicorn.error')
app.logger.handlers = gunicorn_logger.handlers
app.logger.setLevel(gunicorn_logger.level)
add first line under def about(): #clicking [about] in the app will dump environment vars to the logs)
app.logger.debug('\n'.join([f'{k}={os.environ[k]}' for k in os.environ.keys()]))
5. Ftp:
Home > our-web-app > Deployment Center > FTPS Ceredentials
Open FileZilla, top-left icon, [new site]
copy paste from web to FileZilla: FTPS endpoint into host, user to username, password to password, [connect]
upload the content (not the parent!) of the folder from step 4 to the remote path /site/wwwroot
6. Launch:
Home > our-web-app > configuration > General settings > Startup Command
paste this: sh -c "cp go.sh go_.sh && . go_.sh"
7. Test:
Browse to https://[our-web-app].azurewebsites.net
8. Logging / debugging:
Install Azure CLI (command line interface) from https://learn.microsoft.com/en-us/cli/azure/install-azure-cli
Open cmd and run
az login
# turn on container logging (run once):
az webapp log config --name [our-web-app] --resource-group [our-step1-group] --docker-container-logging filesystem
# tail the logs:
az webapp log tail --name [our-web-app] --resource-group [our-step1-group]
9. Kudu SCM management for the app
(must be logged into Azure for these to work):
Show file/dir: https://[our-web-app].scm.azurewebsites.net/api/vfs/site/[path]
Downloads full site: https://[our-web-app].scm.azurewebsites.net/api/zip/site/wwwroot
Status: https://[our-web-app].scm.azurewebsites.net/Env
SSH: https://[our-web-app].scm.azurewebsites.net/webssh/host
Bash: https://[our-web-app].scm.azurewebsites.net/DebugConsole
More on REST API here: https://github.com/projectkudu/kudu/wiki/REST-API
10. Notes:
I don't recommend on using automatic deployment from GitHub / BitBucket, unless you have Azure's support available. We encountered many difficulties with that.
Any comments are most welcome.

Related

Google Cloud Run Second Flask Application - requirements.txt issue

I have a google cloud run flask application named "HelloWorld1" already up and running however i need to create a second flask application. I followed the below steps as per documentation:
1- On "Cloud Shell Editor" clicked "<>Cloud Code" --> "New Application" --> "Cloud Run Application Basic Cloud Run Application .."-->"Python (Flask): Cloud Run", provide and new folder and application is created.
2- When i try to run it using "Run on Cloud Run Emulator" i get the following error:
Starting to run the app using configuration 'Cloud Run: Run/Debug Locally' from .vscode/launch.json...
To view more detailed logs, go to Output channel : "Cloud Run: Run/Debug Locally - Detailed"
Dependency check started
Dependency check succeeded
Starting minikube, this may take a while...................................
minikube successfully started
The minikube profile 'cloud-run-dev-internal' has been scheduled to stop automatically after exiting Cloud Code. To disable this on future deployments, set autoStop to false in your launch configuration /home/mian/newapp/.vscode/launch.json
Update initiated
Update failed with error code DEVINIT_REGISTER_BUILD_DEPS
listing files: file pattern [requirements.txt] must match at least one file
Skaffold exited with code 1.
Cleaning up...
Finished clean up.
I tried following:
1- tried to create different type of application e.g django instead of flask however always getting the same error
2- tried to give full path of [requirements.txt] in docker settings, no luck.
Please if someone help me understanding why i am not able to run a second cloud run Flask app due to this error?
It's likely that your Dockerfile references the 'requirements.txt' file, but that file is not in your local directory. So, it gives the error that it's missing:
listing files: file pattern [requirements.txt] must match at least one file

I am trying to connect to databricks through cli, wated to replicate same in Azure devops

In the local system i am writing commands:
pip install databricks-cli
databricks configure--token
token value and later token
Now the thing is In azure devops i am using task cli and in that i have to enter the code but the catch is in local when code is running then i have to give the token and workspace but in azure devops i have to give in code only.
so is there is any way how to do this i have wriiten this code but its failing:
the pic from azure devops
Instead of configure we tend to write the configuration straight to the ~/.databrickscfg
echo "
[DEFAULT]
host = ...
token = ...
" > ~/.databrickscfg

Azure flask app deployed always shows the default landing page

I have deployed a simple Flask application on an azure webapp by forking the repo from https://github.com/Azure-Samples/python-docs-hello-world
Here is my application.py
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "Hello World!"
#app.route("/sms")
def hello_sms():
return "Hello World SMS!"
# if __name__ == '__main__':
# app.run(debug = True)
And this is my requirements.txt
click==6.7
Flask==1.0.2
itsdangerous==0.24
Jinja2==2.10
MarkupSafe==1.0
Werkzeug==0.14.1
At first when I opened the URL ( https://staysafe.azurewebsites.net/ ) i got this message, "The resource you are looking for has been removed, had its name changed, or is temporarily unavailable."
After which i when to the application settings in the webapp dashboard in azure and set a python version.
And ever since this is what I get when i open my URL
Any clue as to what is going wrong?
Seams that your code is not uploaded to portal.
Please follow this official document for your test.
I Used your code from https://github.com/Azure-Samples/python-docs-hello-world, and works fine. The steps as below:
Environment: python3.7, windows 10
1.Open git bash,download the code to local using git clone https://github.com/Azure-Samples/python-docs-hello-world.git
2.In git bash, execute cd python-docs-hello-world
3.In git bash, execute following command one by one:
py -3 -m venv venv
venv/scripts/activate
pip install -r requirements.txt
FLASK_APP=application.py flask run
4.Open a web browser, and navigate to the sample app at http://localhost:5000/ .
It is to make sure it can work well in local.
5.Then just follow the article to create deployment credetial / resource group / service plan / a web app
6.If no issues, in git bash, push the code to azure:
git remote add azure <deploymentLocalGitUrl-from-create-step>
Then execute git push azure master
7.Browse to the website like https://your_app_name.azurewebsites.net, or https://your_app_name.azurewebsites.net/sms,
it works fine, screenshot as below:

Upload of WebJob fails with Azure CLI on Linux (process out of memory)

We are trying to use the Azure CLI on linux to upload a WebJob as part of our continuous deployment pipeline.
azure site job upload -v $WEB_JOB_NAME $WEB_JOB_TYPE run.zip $WEB_SITE_NAME
But the command fails after > 20 mins of waiting on the "Uploading WebJob" step.
FATAL ERROR: CALL_AND_RETRY_2 Allocation failed - process out of memory
Some more info:
The cli is properly authenticated. We can trigger already existing WebJobs just fine.
The exact same run.zip uploads successfully from Microsoft Azure Powershell on Windows.
The zip-file contains a runnable jar, and a small .cmd-script to start it. File size: 30 MB
We tried setting the verbose-flag, but it does not give any more information.
It looks like a bug in the xplat-cli. I don't think it's related to linux because I get the same error when I run the xplat-cli on Windows with a zip file that's around 30 MB too. I'd suggest opening an issue for them here https://github.com/Azure/azure-xplat-cli/issues
Workaround:
You can use the cli to get the site creds and then use curl to upload the webjob. Here is a little script that would do that.
# get site config from azure cli
siteConfig=`azure site show $WEB_SITE_NAME -d --json`
# extract publishing username and password for the site
publishingUserName=`echo $siteConfig| python -c "import json,sys;obj=json.load(sys.stdin);print obj['config']['publishingUserName'];"`
publishingPassword=`echo $siteConfig| python -c "import json,sys;obj=json.load(sys.stdin);print obj['config']['publishingPassword'];"`
siteScmUrl=`echo $siteConfig | python -c "import json,sys;obj=json.load(sys.stdin);print obj['site']['siteProperties']['properties']['RepositoryUri'];"`
# build the path for the webjob on the server
jobPath="zip/site/wwwroot/App_Data/jobs/$WEB_JOB_TYPE/$WEB_JOB_NAME"
fullUrl=$siteScmUrl$jobPath
# Upload the zip file using curl
curl -XPUT --data-binary #run.zip -u $publishingUserName:$publishingPassword $fullUrl
You can read more about the webjob REST APIs here https://github.com/projectkudu/kudu/wiki/WebJobs-API

Node.js cannot find mysql-database service

I'm trying to follow the tutorial noted below:
http://www.ibm.com/developerworks/cloud/library/cl-bluemix-nodejs-app/
But when I push my app, I see the following:
Using manifest file /mytests/bluemix-node-mysql-upload/manifest.yml
Updating app jea-node-mysql-upload in org jea68#gmail.com / space dev as jea68#gmail.com...
OK
Uploading jea-node-mysql-upload...
Uploading app files from: /mytests/bluemix-node-mysql-upload/app
Uploading 53.6K, 11 files
Done uploading
OK
FAILED
Could not find service mysql-database to bind to jea-node-mysql-upload
Is there a problem with the node.js buildpack or is the documentation faulty?
I've been able to push apps to Node.js without any problems this morning. The documentation assumes the user knows that the service has already been created. The manifest.yml included in the github repo of the tutorial defines a service (mysql-database) that has not been created. Run the following command to create the service:
$ cf create-service mysql 100 jea-mysql-node-upload-service
Then modify the manifest.yml to include:
services:
- jea-mysql-node-upload-service
Alternatively, since you already have an app, you can bind the application to the service by running the following:
$ cf bind-service jea-node-mysql-upload jea-mysql-node-upload-service
$ cf start jea-node-mysql-upload
It looks like a fault in the documentation. If you look at Step 2 part 3 it says to create the my-sql service using this command:
cf create-service mysql 100 mysql-node-upload
which will name the service instance as mysql-node-upload, however the manifest.yml file that you cloned from github contains the service name of just mysql-service. It is the manifest.yml file that links the app with the service instance.
The options are either the change the manifest.yml file to be the correct name of your mysql service instance or recreate the mysql service instance with the name that is in your manifest.yml.

Resources