• Skip to primary navigation
  • Skip to main content

data Rebellion

Learning through Adventure

  • Home
  • Blog
  • Beginner Python Course
    • Preface – The Journey Ahead
    • Prologue – The Door
    • Chapter 1 – Arithmetic and Variables
    • Chapter 2 – Strings and Lists
    • Chapter 3 – Conditional Statements
    • Chapter 4 – Functions
    • Chapter 5 – Loops
    • Chapter 6 – Built-in Functions and Methods
    • Chapter 7 – Imports and Nesting
    • Chapter 8 – Opening the Door
    • Epilogue – Only the Beginning
  • About
  • Contact
You are here: Home / Web Apps / Easily Build and Deploy Your First Python Web App

Easily Build and Deploy Your First Python Web App

Updated March 25, 2021. Published February 17, 2019. 2 Comments

These days you can make your very own web app for free, in pure Python, with a minimal amount of code. The app we’re going to build is under 100 lines total. Not only that, the entire process, from coding and styling to hosting and embedding, can be surprisingly straightforward once you’ve seen an example. So let’s run through one now.

Say you have a gaming blog, and you want your home page to have an interactive web app that displays Twitch stream stats. More precisly, you want the user to be able to specify a video game and some number of streams, and then see a bar chart of the viewer numbers of those top streams, along with streamer names and stream titles (see the finished app at the end of the post).

First things first, let’s figure out how to get the stream data from Twitch.

Twitch API

If you wanted to you could scrape the info directly from the stream pages themselves. In general though it’s good to at least try out a site’s API if they have one before hacking together your own web scraper. And for our purposes, Twitch’s API will work just fine.

A little investigation of the developer documentation reveals that there are two Twitch APIs, the v5 API and the new API. We’ll be using the New Twitch API.

Follow the directions in the previous link to get your client ID, the key that authorizes you to interact with the API, then navigate to the reference guide’s “Get Streams” section.

If you want to get streams for a particular game, you’ll need to specify that game with the game_id query parameter. Note that game name is different from game_id, which is a number, so we’ll need to be able to convert game names entered by the user into game IDs for the API. This is described in the “Get Games” section.

Putting the two together, below is a sketch of our code for converting a game name to a game ID and then getting data on the top streams for that particular game.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import requests
 
client_id = 'xxxxxxxxxxxxxxxxxxxx'
headers = {'Client-ID': client_id}
 
# get twitch id for Grand Theft Auto V
url = 'https://api.twitch.tv/helix/games'
payload = {'name': 'Grand Theft Auto V'}
r = requests.get(url, headers=headers, params=payload).json()
game_id = r['data'][0]['id']
print('Grand Theft Auto V ID: ' + game_id + '\n')
 
# get top 10 Grand Theft Auto V streams
url = 'https://api.twitch.tv/helix/streams'
payload = {'game_id': 32982, 'first': 10}
r = requests.get(url, headers=headers, params=payload).json()
for d in r['data']:
print(d['user_name'], d['viewer_count'], d['title'], sep=' | ')
1
2
3
4
5
6
7
8
9
10
11
12
Grand Theft Auto V ID: 32982
 
pescocofino | 1366 | JOGANDO QUALQUER COISA Meta de SUBS: 125/200 !sub mande uma mensagem em: !loots
Lord_Kebun | 678 | Mr.Chang Most Wanted | Twitter @LordKebun
GameMixTreize | 506 | [FR] JE VENDS DU RÊVE SUR GTA V RP !
AladdinTV | 476 | [GVMP] Hakan Abi übernimmt die Stadt / Familiärer Stream
Spaceboy | 325 | Melbert! | NoPixel | https://twitter.com/imaSpaceboy | !D20
TheChief1114 | 318 | back at it
CivRyan | 276 | OCRP | Officer 247 | New Visuals and Sounds
Selvek | 269 | Devin King - TFRP
Men0rxD | 266 | [+18] [PT-BR] [UP-RP] Tamo com emotes quebrada, RPZIN  naquele pique encosta #SemTiltar
Bolshownaro | 248 | BOLSONARO DO GTA [+18]

And just like that we get the streamer name, current viewer count, and stream title for the top 10 GTA V streams. This is essentially the core of our app, but now we want to display this data in a visually compelling way and make it easy to play around with the inputs. This brings us to building the app itself.

Dash: A Python Framework for Analytical Web Apps

Dash is a framework that allows us to build an app in pure Python, which, if you ask me, is a beautiful thing. They even have a nice user guide that makes learning it relatively painless.

Follow the directions for getting Dash installed on your machine, and read through the rest of their tutorial to get a feel for how Dash works.

Once that’s done, check out the code below, which is our finished Twitch web app. For more details on how the code works and how to run it locally on your machine, see the youtube video.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import dash
from dash.dependencies import Input, Output, State
import dash_html_components as html
import dash_core_components as dcc
import plotly.graph_objs as go
import requests
 
# twitch api info
client_id = 'xxxxxxxxxxxxxxxxxxxx'
headers = {'Client-ID': client_id}
games_url = 'https://api.twitch.tv/helix/games'
streams_url = 'https://api.twitch.tv/helix/streams'
 
app = dash.Dash(__name__)
 
app.layout = html.Div(style={'backgroundColor': '#4b367b', 'padding': 30}, children=[
html.H1(
children='Top Twitch Streams',
style={'textAlign': 'center'}
),
 
html.Div(
children='Select a game and number of top streams you wish to see',
style={'textAlign': 'center', 'fontSize': 20}
),
 
html.Label('Game', style={'fontSize': 20}),
dcc.Input(id='game_name', value='Grand Theft Auto V', type='text'),
 
html.Label('Streams', style={'fontSize': 20, 'marginTop': 30}),
dcc.Slider(
id='stream_num',
min=5,
max=50,
marks={i*5: str(i*5) for i in range(1, 11)},
value=10,
),
 
dcc.Graph(id='jobs_barchart', style={'marginTop': 30, 'marginBottom': 30}),
 
html.Button(id='submit-button', n_clicks=0, children='Go',
style={
'display': 'block',
'margin': 'auto',
'width': 100,
'textAlign': 'center',
'fontSize': 20,
'fontFamily': 'inherit',
'color': '#00ff7f',
'border-color': '#00ff7f',
'border-width': 2,
}
),
])
 
@app.callback(
Output(component_id='jobs_barchart', component_property='figure'),
[Input(component_id='submit-button', component_property='n_clicks'),],
[State(component_id='game_name', component_property='value'),
State(component_id='stream_num', component_property='value'),],
)
def update_figure(n_clicks, game, n_streams):
# if no game specified, get top streams across all games
if game == '':
payload = {'first': n_streams}
r = requests.get(streams_url, headers=headers, params=payload).json()
else:
payload = {'name': game}
r = requests.get(games_url, headers=headers, params=payload).json()
game_id = r['data'][0]['id']
payload = {'game_id': game_id, 'first': n_streams}
r = requests.get(streams_url, headers=headers, params=payload).json()
 
return {
'data': [
go.Bar(
x=[d['user_name']],
y=[d['viewer_count']],
text=d['title'],
opacity=0.8,
name=d['user_name'],
hoverinfo='x+y+text',
showlegend=False
) for d in r['data']
],
'layout': go.Layout(
xaxis={'title': 'Streams'},
yaxis={'title': 'Viewers'},
hovermode='closest',
title = game + ' Streams with Most Current Viewers',
#font=dict(family='AR DESTINE, Arial, Helvetica, sans serif'),
)
}
 
if __name__ == '__main__':
app.run_server(debug=True)

Now that we have an app that’s working locally, let’s take a moment to discuss styling.

App Styling

One thing to note is that, while there is some styling in the code itself for certain margins, font size, background color, etc, a lot of styling comes from this CSS stylesheet.

In the Dash User Guide examples, you’ll find that they use this stylesheet, by Chris P, the cofounder of Plotly and author of Dash. For my own stylesheet, I simply copied Chris’ and made a few changes, such as adding the custom font AR Destine.

To test out the CSS and have it applied to your app running locally, within your main project folder you’ll need to make an “assets” folder where you place the stylesheet, custom font file, and any other external resources. See the youtube video for more details on this, or read through Dash’s article on external resources.

So now that we’ve got the app working and styled as we like, we need to figure out how to get it hosted online so it’s publicly accessible and we can embed it in our hypothetical gaming blog.

Web Hosting with Python Anywhere

There are a number of different options for hosting your code online, but if you’re new to this and don’t have a preference, I recommend trying out Python Anywhere. I’ve had good experiences with them so far, they’re very user-friendly, and they have a free “Beginner” account option (details in bottom table, far right column).

The free account option comes with limitations, but it’ll still allow us to get the app up and running. See the youtube video LINK for more details on configuring your app in Python Anywhere, but here’s a quick summary of the process:

  • Open Bash console, create virtual environment, install packages
    • If while installing packages you get errors relating to allowed disk usage (which can often happen with a free account), try installing requests or plotly first, instead of dash (which installs every package you need at once) to break up the installation process into smaller chunks
    • You can also try cleaning up unnecessary files
  • Upload files
  • Add a new app, choose manual configuration
  • Specify the source code folder and virtual environment
  • Configure the WSGI file by replacing its contents with the following code, altered for your situation:
  • 1
    2
    3
    4
    5
    6
    7
    8
    import sys
     
    path = '/home/grayson/twitch_apps'
    if path not in sys.path:
    sys.path.append(path)
     
    from top_twitch_streams import app
    application = app.server

  • Reload the app
  • Access the app at username.pythonanywhere.com
  • Check the Error log files in the Web tab if something goes wrong
  • If you get lost, check out Python Anywhere’s Help section

Once you’ve got the app hosted successfully, it’s time for the final step, embedding it in your website.

Embedding the Web App

Python Anywhere assigns our app a url where we can access it. If you have a free account, that url is yourusername.pythonanywhere.com. For example, you can see the web app embedded below at grayson.pythonanywhere.com. But it would be inconvenient for users to have to click a link and navigate to another site to use the app, and it would also look a lot cooler to have the app right there on our website.

This is the simplest step. You can easily embed the app anywhere you want using an iframe element. And all that entails is simply adding the following line to your web page:

<iframe src="https://username.pythonanywhere.com" width="100%" height="900" frameborder="0" sandbox="allow-same-origin allow-scripts"></iframe>

The Twitch app is embedded this same way below. If for some reason it’s not working (which could be due to browser settings or add-ons), just watch the youtube video to see how it works or better yet get your own version of it up and running. A great exercise would be to add some new features to it or improve existing ones. Maybe polish up its look too.

Wrapping Up

As you can see, building web apps can be within the reach of even relative beginners. If you’d like to build an app of your own design, check out the Dash gallery page or this other Dash app collection to get a feel for what’s possible.

This curated list of Dash resources and these Dash recipes are worth reviewing as well.

And if all else fails you can leave a comment below or ask the Dash or Python Anywhere communities for help.

So feel free to let me know if you have any questions, and consider subscribing to my newsletter below and youtube channel. Until next time.

Python Automation Project Ideas Ebook Front Page

Free Ebook: 88 Python Project Ideas for Automating Your Life

The best way to learn programming is by working on real-world projects, so why not work on projects that also save you time and sanity? In this free, curated collection, you'll find project ideas for automating:

  • Common office tasks
  • Birthday gifts and wishes
  • Grocery and meal planning
  • Relationships (just the tedious parts!)
  • And quite a bit more

Subscribe to Data Rebellion and get this Ebook delivered straight to your inbox, as well as other exclusive content from time to time on efficiently learning to code useful things, vanquishing soul-crushing work, and having fun along the way.

Reader Interactions

Comments

  1. Jane says

    August 14, 2019 at 12:05 am

    Hi,

    Are you able to provide some lead – if I wanted to host the Plotly Dash web application on my own website, how can I do it ?

    Reply
    • Grayson Stanton says

      August 14, 2019 at 4:59 pm

      Hi Jane. Take a look at the last section of this article, “Embedding the Web App”. You’ll need to use an iframe element.

      Reply

Leave a comment Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Copyright © 2023

Terms and Conditions - Privacy Policy