diff --git a/README.md b/README.md index 357339f..00d103d 100644 --- a/README.md +++ b/README.md @@ -1,122 +1 @@ -# How to deploy your Flask app to Azure (with example) - -This tutorial will show you, how to deploy your Flask app to Azure App Service. - -## What is Azure App Service? - -It's a hosting provider (cloud) by Microsoft, similar to Google's App Engine. - -## Deployment steps - -### Prepare your Flask app - -First create a your Flask project on your computer (if you haven't yet). - -You can copy the code from this repository. At minimum, the Flask project needs to have: - -- **One Python file:** ours is called main.py. See the code that it contains. -- **The requirements.txt file:** This file contains the list of Python (PIP) libraries that the project depends on. In -our case it depends on Flask. - -### Push to GitHub - -Create a repository on your GitHub account and push this code to it. We will use GitHub to deploy the project to Azure later. - -### Create an account on Azure - -Go to this URL: [https://azure.microsoft.com/en-us/free/](https://azure.microsoft.com/en-us/free/) and create a free -Microsoft Azure account for yourself. - -You will also be asked to provide your credit card info, but this is only to verify your identity and an anti-spam -measure. Your credit card will not be charged as long as you use the free Azure services (as we'll do in our tutorial). - -### Create an App Service - -Once you have your Azure account ready, you can log into the Azure dashboard and create your first App Service. This is -similar to a GAE project on Google Cloud. - -**Step 1:** - -![](img/create-app-service-1.png) - -**Step 2:** - -![](img/create-app-service-2.png) - -**Step 3:** - -![](img/create-app-service-3.png) - -**Step 4:** - -![](img/create-app-service-4.png) - -### Wait for the App Service to be created - -Wait a minute or two that Azure creates a new App Service project for you. You can see the progress in the upper right -corner (click on the bell icon): - -**In progress:** - -![](img/app-service-created-1.png) - -**Success:** - -![](img/app-service-created-2.png) - -Click on **Go to resource** now. - -### App Services list - -Go to the App Services tab, where you can see your new web app listed (click on it): - -![](img/app-services-list.png) - -Click on the URL for your new website: - -![](img/browse-website-1a.png) - -This will open a new tab in your browser and show you your web app: - -![](img/browse-website-2.png) - -Right now there's some text by Microsoft on it, but your Flask app is not there yet. Let's get it deployed on Azure. - -### Connect your GitHub account to Azure - -In order to deploy your Flask app on Azure, you'll need to connect your GitHub account to it. Go to **Deployment Center** -tab and follow these steps: - -**Step 1:** Click on GitHub and authorize your GitHub account. - -![](img/deployment-1.png) - -**Step 2:** Select App Service Kudu Build Service. - -![](img/deployment-2.png) - -**Step 3:** Choose your Flask repository. - -![](img/deployment-3.png) - -**Step 4:** - -![](img/deployment-4.png) - -**Step 5:** Your GitHub code has been deployed to Azure - -![](img/deployment-5.png) - -### One last thing - -Since your Python file in your Flask project is named main.py, Azure does not recognize it automatically. If you would -name it application.py, you wouldn't need to do this last step. - -So the last step is to go to the **Application settings** and add the following line into the Startup file input box: - - gunicorn --bind=0.0.0.0 --timeout 600 main:app - -![](img/startup-file.png) - -Now go check your webiste URL (you'll probably need to refresh it a couple of times). It should show the -"Hello, SmartNinja!" text. +# Plotly Dash boilerplate for multi page App diff --git a/app.py b/app.py new file mode 100644 index 0000000..bc787fd --- /dev/null +++ b/app.py @@ -0,0 +1,13 @@ +import dash +import dash_core_components as dcc +import dash_html_components as html + +print(dcc.__version__) # 0.6.0 or above is required + +app = dash.Dash() + +server = app.server +app.config.suppress_callback_exceptions = True + +# if __name__ == '__main__': +# app.run_server(debug=True) \ No newline at end of file diff --git a/application.py b/application.py new file mode 100644 index 0000000..05b84ef --- /dev/null +++ b/application.py @@ -0,0 +1,34 @@ +import dash_core_components as dcc +import dash_html_components as html +from dash.dependencies import Input, Output + +from app import app +from apps import linechart, barchart, home , scatterplot + + +app.layout = html.Div([ + dcc.Location(id='url', refresh=False), + html.Div(id='page-content') +]) + + +@app.callback(Output('page-content', 'children'), + [Input('url', 'pathname')]) +def display_page(pathname): + if pathname == '/': + return home.layout + elif pathname == '/linechart': + return linechart.layout + elif pathname == '/barchart': + return barchart.layout + elif pathname == '/scatterplot': + return scatterplot.layout + else: + return '404' + +external_css = ["hhttps://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css", + "//fonts.googleapis.com/css?family=Raleway:400,300,600", + "https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"] + +if __name__ == '__main__': + app.run_server(debug=True) \ No newline at end of file diff --git a/apps/barchart.py b/apps/barchart.py new file mode 100644 index 0000000..dd826c0 --- /dev/null +++ b/apps/barchart.py @@ -0,0 +1,25 @@ +import dash_core_components as dcc +import dash_html_components as html +from dash.dependencies import Input, Output +from apps import commonmodules + +from app import app + +layout = html.Div([ + commonmodules.get_header(), + commonmodules.get_menu(), + html.H3('Line Chart'), + dcc.Graph( + id='example-graph', + figure={ + 'data': [ + {'x': [1, 2, 3], 'y': [4, 1, 2], 'type': 'bar', 'name': 'SF'}, + {'x': [1, 2, 3], 'y': [2, 4, 5], 'type': 'bar', 'name': u'Montréal'}, + ], + 'layout': { + 'title': 'Dash Data Visualization' + } + } + ), + +]) \ No newline at end of file diff --git a/apps/commonmodules.py b/apps/commonmodules.py new file mode 100644 index 0000000..1e096cc --- /dev/null +++ b/apps/commonmodules.py @@ -0,0 +1,25 @@ +import dash_core_components as dcc +import dash_html_components as html +from dash.dependencies import Input, Output + +def get_header(): + header = html.Div([ + + html.Div([ + html.H1( + 'Dash Boiler Plate') + ], className="twelve columns padded"), + + ], className="row gs-header gs-text-header") + return header + +def get_menu(): + menu = html.Div([ + + dcc.Link('Home ', href='/', className="p-2 text-dark"), + dcc.Link('Line Chart ', href='/linechart', className="p-2 text-dark"), + dcc.Link('Bar Chart ', href='/barchart', className="p-2 text-dark"), + dcc.Link('Scatterplot ', href='/scatterplot', className="p-2 text-dark"), + + ], className="d-flex flex-column flex-md-row align-items-center p-3 px-md-4 mb-3 bg-white border-bottom shadow-sm") + return menu \ No newline at end of file diff --git a/apps/home.py b/apps/home.py new file mode 100644 index 0000000..1688237 --- /dev/null +++ b/apps/home.py @@ -0,0 +1,14 @@ +import dash_core_components as dcc +import dash_html_components as html +from dash.dependencies import Input, Output +from apps import barchart, barchart, commonmodules + +from app import app + + +layout = html.Div([ + commonmodules.get_header(), + commonmodules.get_menu(), + html.Br(), + html.H3('This is home screen'), +]) diff --git a/apps/linechart.py b/apps/linechart.py new file mode 100644 index 0000000..7e95d12 --- /dev/null +++ b/apps/linechart.py @@ -0,0 +1,20 @@ +import dash_core_components as dcc +import dash_html_components as html +from dash.dependencies import Input, Output +from apps import commonmodules + +from app import app + +layout = html.Div([ + commonmodules.get_header(), + commonmodules.get_menu(), + dcc.Input(id='my-id', value='initial value', type='text'), + html.Div(id='my-div') +]) + +@app.callback( + Output(component_id='my-div', component_property='children'), + [Input(component_id='my-id', component_property='value')] +) +def update_output_div(input_value): + return 'You\'ve entered "{}"'.format(input_value) \ No newline at end of file diff --git a/apps/scatterplot.py b/apps/scatterplot.py new file mode 100644 index 0000000..b0cf35f --- /dev/null +++ b/apps/scatterplot.py @@ -0,0 +1,33 @@ +import dash_core_components as dcc +import dash_html_components as html +from dash.dependencies import Input, Output +import plotly.graph_objs as go + +from apps import commonmodules + +from app import app +import numpy as np + +N = 1000 +random_x = np.random.randn(N) +random_y = np.random.randn(N) + +layout = html.Div([ + commonmodules.get_header(), + commonmodules.get_menu(), + html.H3('Scatter Chart'), + dcc.Graph( + id='life-exp-vs-gdp', + figure={ + 'data': [ + go.Scatter( + x = random_x, + y = random_y, + mode = 'markers', + + ) + ], + } + ) + +]) diff --git a/requirements.txt b/requirements.txt index ae09db0..4afc3b2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,42 @@ -Flask==1.0.2 \ No newline at end of file +boto==2.49.0 +boto3==1.9.253 +botocore==1.12.253 +certifi==2019.9.11 +chardet==3.0.4 +Click==7.0 +dash==1.3.1 +dash-core-components==1.2.1 +dash-daq==0.2.2 +dash-html-components==1.0.1 +dash-renderer==1.1.0 +dash-table==4.3.0 +docutils==0.15.2 +Flask==1.1.1 +Flask-Compress==1.4.0 +future==0.17.1 +gensim==3.8.1 +gunicorn==19.9.0 +idna==2.8 +itsdangerous==1.1.0 +Jinja2==2.10.3 +jmespath==0.9.4 +joblib==0.14.0 +MarkupSafe==1.1.1 +numpy==1.17.2 +pandas==0.25.1 +plotly==4.1.1 +psycopg2==2.8.3 +python-dateutil==2.8.0 +pytz==2019.3 +requests==2.22.0 +retrying==1.3.3 +s3transfer==0.2.1 +scikit-learn==0.21.3 +scipy==1.3.1 +six==1.12.0 +sklearn==0.0 +smart-open==1.8.4 +SQLAlchemy==1.3.10 +squarify==0.4.3 +urllib3==1.25.6 +Werkzeug==0.16.0