CARTER PAGE: Welcome
to this CS50 seminar,
Publishing Your Flask App to the Web.
My name's Carter Page, and I'm
here in New Haven, Connecticut,
at Yale University.
And today we're going to talk
about life outside the CS50 IDE.
Now, there comes a time when the
baby bird must leave the nest.
And likewise, it is time
for your CS50 Flask app
to leave the nest of the
CS50 IDE and fly on its own
in the big wide world of the internet
to become the next big Facebook.
Now, in this seminar, we're
going to walk through the steps
to take your Flask app running happily
in the CS50 IDE to a standalone web app
that millions of people
can visit across the globe.
Now, along the way, we're going to
learn about a ton of different tools,
including Heroku, GitHub,
Terminal, Postgres, Homebrew,
Atom, and many more.
Now, all these tools, each of them,
you could do your own seminar about.
But today, our goal is
just to introduce you
to a ton of different tools along the
way so you can get a sample of those
and so you can go back on your
own and learn more about them.
And before we start, life outside
the CS50 IDE can be very frustrating.
But I urge you to stick with it.
My best advice is to roll up your
sleeves, get ready to Google for help,
ask for help on Stack Overflow,
and be prepared to face
some mind-numbing error messages.
In this seminar, we divide
publishing your Flask app to the web
into five different parts.
Part one is taking your
Flask app from the CS50 IDE
and pushing that up to GitHub.
Part two is taking the files
that we've pushed up to GitHub
and bringing them down to
your local Mac computer.
Part three is our database tire change.
Much like NASCAR, where you
have the cars racing around
and they need to switch out
the tires, part three for us
is where we're going to switch out the
SQLite database that we use in the CS50
IDE, and replace it with
Heroku Postgres that'll
be able to work better with Heroku
when we publish the app onto the web.
Part four is taking the files in the
Flask app running locally on your Mac
and pushing that up to
Heroku, and then part five--
and it's the easiest one-- is taking
it from Heroku to the worldwide web.
So let's get started.
So part one is taking our
stuff from the CS50 IDE
and pushing those files up to GitHub.
Now, to begin, you want to
log in to your CS50 IDE and cd
into your project directory.
We're going to start off by getting
our Flask app out of the CS50 IDE.
To do so, we're going to upload
the files to the website GitHub,
using this thing called git.
So cd to the project.
Then you're going to run
the command git init.
So git init basically
initializes an empty repository.
Now, git add, you're
going to do git add dot,
and that period represents
the current working directory.
So when you do git add
dot, you're meaning,
let's load up these files in
the current working directory,
and let's get ready to send them off.
Now before you can send off these files,
though, to GitHub, what you need to do
is do a commit.
You can think of commit as
like a stamp of approval
that these files I've added and loaded
up, we're ready to send them off.
So we git commit with a
message "first commit,"
and we're ready to send them off.
Now, in order to send these files
off from the CS50 IDE into GitHub,
we need to tell them where to go in
GitHub, because GitHub's a big place.
So we need to get a URL from
GitHub to send these files to.
So now what you need to do is
log in to your GitHub account
and create a new repository.
And you should probably make
your repository name something
similar to the directory that you're
working with, to make things easier.
So once you finish
creating your repository,
GitHub will give you these commands
of a URL after git remote add origin.
So after you've created
this repository, GitHub
will give you this URL
after git remote add origin.
What you want to do
is take that command,
git remote add origin, with the URL, and
you want to run that in the CS50 IDE.
Your next step, then, will be to do git
push, and the -u here is not necessary.
Git push origin master.
And what that will do is take the
files that you added to load them up,
you committed them,
sealed them, and that push
is the final standoff to GitHub.
So now we have successfully pushed the
files from your CS50 IDE up to GitHub.
So great job on part one.
Part two now is taking the files
that we've sent off to GitHub
and bringing them down onto your Mac.
What we now need to do
is get your Mac ready
for these Flask app files that we've
taken from the CS50 IDE to GitHub,
and we're now ready to
bring them down to the Mac.
So we're going to have to
pimp out your dev setup.
The first thing you need to do is
get familiar with the Terminal app.
To find it, you can go to the
spotlight feature of your Mac and type
in "terminal."
It'll pop up right away.
All Macs have Terminal
pre-installed, so you have it
even if you've never used it before.
The first time you open up
Terminal, you'll notice that hey,
this looks a lot like the command
line prompt from the CS50 IDE.
And you're right, they're very similar.
But the only difference is that
when you type "ls," for example,
you'll see the files
on your own computer,
because the terminal, the file system
that it's working with, this command
line prompt, is that
of your own computer,
rather than CS50 IDE, which works
with the files in your workspace.
So let's cd into desktop,
and you can explore it
just like you did in the CS50 IDE.
So to prepare your Mac
for your Flask app,
you're going to need to
download many different tools--
and these tools are known as packages--
that our Flask app needs to run.
For example, you could think
of, oh, we need Python.
We need Flask.
We need stuff to work with our database.
All these different tools, it's
difficult to keep track of them.
And so there's this
fantastic thing called
Homebrew, which is a package manager.
And we're going to be using
that to keep track of it.
And Homebrew is a lifesaver.
Without it, it would be incredibly
difficult to keep track of anything.
So to get Homebrew, you need
to go to Homebrew's website.
And at their website, they
have this command for you
to copy and paste into
your terminal prompt.
And so you just take it, copy,
paste it, and click Enter.
And it'll walk you through the
installation process for Homebrew.
So Homebrew will take a
little while to install,
because it's installing quite a bit.
But once you have it, you'll
quickly see why it's fantastic.
So now that we have Homebrew, let's get
git, because what we're trying to do
is take those files from GitHub and
bring them down to our Mac using git.
So to get git, it's very simple.
Brew install git.
And you type that into your Terminal
app, and voila, you'll have git.
Now, what we want to do now is
take those files from GitHub
and bring them to the Mac.
So what we can do is do
a cd to change directory,
home directory slash
desktop, and then we
can run the command git clone, which
basically means download files.
But we need to tell git where to get
those files from, and that's the URL.
Now, to get this URL, you can
go to any repository on GitHub,
and you can tap on that green
button, Clone or Download,
and it'll give you a URL you can
literally copy and paste right where I
have those brackets and URL filled in.
My recommendation for
this walkthrough is
that you use the refo I provided in
the Who Was Here Flask app that I've
put together for this demonstration.
So once you do git clone, now
those files are on your desktop,
and you should be able to
even look at your desktop
and you'll see the folder there.
And the folder name
will be Who Was Here.
Now, let's keep going to building
out our Mac development environment.
So for our Flask app,
we're going to need Python.
And so let's do brew install python
and then brew install python3,
because remember there's
versions 2.7 and 3.6.
Homebrew keeps track of all the
different tools that we're using
and are present on our Mac.
But keeping track of all the
different dependencies and tools
that our specific Flask app is
using, that's a whole other job.
And to do that, we're going to be using
something called a virtual environment.
Virtual environments
are ways for us to keep
track of the different tools,
different dependencies,
that our Flask app is using.
So to get virtual environments-- you
might be getting the hang of this--
brew install virtualenv,
where "virtualenv"
stands for "virtual environment."
In the CS50 IDE, if you wanted to
edit a file, you just clicked on it,
and then the file would
pop up, and you could type
and you could make changes
on it, et cetera, et cetera.
But on your Mac, there's
no equivalent right now.
You just have the command line
prompt to interact with the program.
What you can do is download what
developers call text editors.
And there's many of them--
Sublime, Atom, and Atom's
my personal preference,
so we're going to use that
one for this walkthrough.
So to get Atom, you just go
to Atom's homepage, atom.io,
and download it, just like
you would any other program.
Now, once you have Atom
installed, you can take a look
at the files in your Flask app by
cding into the directory Who Was Here.
You always have to be in that directory.
And then you can type atom period.
And that period there stands for
the current working directory.
So it opens up the current
working directory in Atom.
And once you see this, you'll say, oh!
This is just like the CS50 IDE, where
you can tap on files on the left side
and make changes to them, just like
what we've been used to this semester.
Now things are going to start
getting a bit more complicated.
So last time, we downloaded
virtualenv, which
is the tool for us to make
these virtual environments.
But now we need to actually make them.
To make one, make sure you cd
into the project directory, which
is Who Was Here in your desktop, and
type in "virtualenv -p python3 venv."
All right.
That's a mouthful.
What's going on here?
So virtualenv is the tool that we
downloaded, we got from Homebrew,
to create virtual environments.
The -p python3 means we
want our virtual environment
to use Python 3.6 by
default, because that's
how we've been doing this in CS50 IDE.
And then venv is just the name
of this virtual environment
that we're creating.
Venv, virtual environment.
Now, to turn our virtual environment
into something that's useful--
because right now it's a virtual
environment that's empty--
we need to first turn it on, or activate
it, by source venv bin activate.
And then we're going
to use pip, which is--
you know how Homebrew's like
a package manager for programs
all over the computer?
Pip is very similar, but for Python.
So we're going to use pip to
install the requirements listed
in that pesky requirements.txt file.
And so you can do that by typing
pip install -r requirements.txt,
and that goes through and reads
all the different packages listed
in the requirements.txt file,
and downloads the ones you need.
And that concludes part two,
taking the files from GitHub
and bringing them down
onto our local computer.
Now, part three-- this is
where it's the tricky one,
and this one's pretty frustrating.
This is the tire change, where we're
switching the SQLite database that we
know and love from CS50 IDE, and we're
switching it out for Heroku Postgres.
So right now, the program
is looking for this thing
called DATABASE_URL to find the
database that it's going to connect to.
But we haven't told it
what DATABASE_URL is.
We're going to get that
DATABASE_URL from Heroku.
So what is Heroku?
Heroku is a online platform that
makes it really easy for developers
to publish web apps to the internet.
And to use Heroku--
you might have guessed
it by now-- we're going
to be using Homebrew to brew
get Heroku's command line
tools, which is heroku/brew/heroku.
Now, if you don't have a Heroku
account, no worries if you don't.
Go sign up at the link that I've
provided, signup.heroku.com.
And then once you have an
account, go back to your terminal,
and do heroku login.
Change directory into
Who Was Here, and then
this is where the fun
part is-- heroku create.
And congratulations,
you have successfully
made your Heroku web application.
The problem is it doesn't
work at all right now.
And the reason for that is we
still haven't done anything
about that database.
So another thing we
need to take care of is
Heroku needs this thing called
a Procfile in order to work.
Basically, the Procfile tells
Heroku what type of application
we've sent to it and what command
does it need to run to turn it on.
It's very easy to forget your
Procfile, so make sure you don't.
If you get an error message from
Heroku, first thing you can check
is, did you remember the Procfile?
The code that I've provided you
already has a Procfile with it,
but if you're porting your own
Flask application from CS50 IDE,
you're going to have to make your own.
And so the instructions to
make it are pretty simple.
Do pip install gunicorn.
And remember, when
you're pip installing,
make sure that you have the
virtual environment activated.
Then we're going to do touch
Procfile to create a Procfile,
and then inside of Atom or your
editor, type in, for your Procfile,
simply "web: gunicorn
space application:app."
Now, this is the most
difficult part of the journey.
And this is switching out the SQLite we
used in CS50 IDE for Heroku Postgres.
This step is going to take the
most time for you on your own,
and it will require you to learn
a bit more about Flask-SQLAlchemy
to find the answers for your
specific database implementation.
But what I've done here is
provided you with a sample app,
so you can see that, oh, switching this
over, at first it may look strange,
but actually, it makes sense.
So the first thing we're going to
do is pip install Flask-SQLAlchemy.
And now what we need to do is go
through our application.py file
and remove the references to SQLite.
For example, from CS50 import
SQL, db equals SQL space--
or SQL parenthesis SQLite, because we're
not going to be using SQLite anymore.
Next, what we're going
to be replacing it with--
and don't be intimidated at first--
is SQLAlchemy.
And specifically, what we're going to be
replacing it with is Flask-SQLAlchemy.
And if you look at this,
import OS is something that
helps us get environment variables.
From Flask-SQLAlchemy import SQLAlchemy.
That's very similar to
the from CS50 import SQL.
Next, this app.config
SQLALCHEMY_TRACK_MODIFICATIONS,
that part, yeah, that's confusing.
That's just a warning that if you
don't have it, you'll get that warning.
So just listen to the
computer, and just put it in.
Then you have an app.config
step, which basically
allows us to use the environment
variables DATABASE_URL
to find the database.
For this example application,
Who Was Here, it's very simple.
You go onto a website and there's
a form, and you type in your name,
and you press Submit.
And then your name shows up in a list
of other people who have been there.
So a very simple application.
Now, if you look at this
class implementation,
we see that we have User,
which is pretty similar to, oh,
that's the name of our table.
And you see, oh, ID equals db.Column.
That's a column in our table.
And Name is another column.
And ID is an integer, Name is a string,
and so you can piece together, oh, this
actually isn't that bad.
We've seen stuff like this.
But it's just in a different format.
Another thing we need
to go through and remove
are these db.execute
statements, because we're
going to be using Flask-SQLAlchemy
directly, rather than using it
through the CS50 library.
So if we go out and remove
those db.execute statements,
we're going to be replacing it
with something that at first looks
really different, but
actually it's pretty similar
when you go through the steps.
So in this example, what we're
trying to do is take a name,
give it to a new user, and then
add that new user to our database.
And that's pretty much
what's happening in both.
In the first one, we have our SQL
statement, our raw SQL query, of insert
into the table User, name,
with the value of name.
In the second one, it's pass
a name to create a new user,
and then we're going
to add that new user.
And then an important step is commit.
Commit is an important step
that you can't forget for insert
and remove statements, because those
are editing the database itself.
And for those statements,
you need the commit
to let it know that this is a permanent
change that I'm trying to make.
Similarly, if we wanted to
implement a select statement,
we can use
user.query.order_by(user.id).all.
So what does that mean?
So we are looking at our table User.
Inside of User, we want to query it.
And we're taking all of them, and
we're organizing them by user ID.
And we're going to take all
those users that we're selecting
and put them into Users.
So once we've switched to
Flask-SQLAlchemy, all we need to do now
is create our database.
The hard part's over.
And creating our database
is going to be two steps.
First, we need to create our Heroku
Postgres DATABASE_URL, that elusive
DATABASE_URL that I spoke
about at the beginning,
that this application that
I provide is looking for.
And so to generate this DATABASE_URL,
we type in "heroku addons:create
heroku-postgresql:hobby-dev."
What does that mean?
Heroku add-ons are different tools that
we can use to improve our web apps.
We're going to be using
Heroku PostgreSQL.
And then that hobby dev is the plan
we're on, and hobby dev's the free one.
So the next step, then, is to do
heroku config into your Mac terminal,
and voila, it spits
out your DATABASE_URL.
So Heroku now knows the DATABASE_URL.
We actually made the DATABASE_URL.
It's up in Heroku.
But if we wanted to run
the application locally,
our local application
has no way of knowing.
So to tell the local
application what it is,
tell a local application
where the DATABASE_URL is,
what we're going to do
is create a .env file.
So type "touch.env."
Then, inside of Atom, you can edit
the .env and make it look identical
to the one I provided, where you have
export FLASK_APP equals application.py,
telling when we do Flask run,
that we want Flask run to look
for application.py, not app.py
or server.py or whatever.
FLASK_DEBUG equals 1, that sets
another environment variable that
makes it easier for us to
interpret Flask errors,
because we'll all make mistakes.
And then for export
DATABASE_URL, that's where
we set the environment variable
DATABASE_URL to tell our program where
the database is.
To load these environment variables
to your Mac, type source .env.
Now we've created a DATABASE_URL,
but in fact, we've actually not
created the database itself.
We've told our application
where to go looking,
and we told it to go looking at
Heroku to find this database.
And we set aside that
space, but we actually
didn't put our database table in it.
So we want a way to look at our
database, much like in CS50 IDE,
we were able to use phpLiteAdmin to
visually inspect our SQLite tables.
So we're going to be downloading
this app called Postico,
and there's a free trial available.
So go to that website, download
Postico, and then once you open Postico,
it's actually really easy to use.
Go back to Terminal, copy that
DATABASE_URL, open Postico,
and then with the DATABASE_URL copied
to your clipboard, click New Favorite.
The fields should be
automatically populated,
and then click Connect to
connect to your database.
So right now, when we do that, we
don't see any table named User.
That's because we haven't
created the table User.
And that's what we're moving onto now.
So part four, taking the files from
your Mac and pushing those up to Heroku.
So we've gone from CS50 IDE to
GitHub, from GitHub to your Mac,
now we're going from your Mac to Heroku.
So this statement might seem familiar.
We're going to do a pip freeze
requirements.txt to update
our requirements file, though it
shouldn't have changed in this
walkthrough, but it's
a good habit to get--
it shouldn't have changed
in this walkthrough,
but it's a good habit to get into.
Then we're going to do
git add to load our files
and get them ready to send off.
We're going to get git commit,
with our seal of approval
that we're ready to send
these files to Heroku.
And then we're going to
do git push heroku master
to send them on their way.
Now it's time to actually create
the table for our database.
And to do so, type in
in your Mac terminal
"heroku run python," which
basically creates a read eval print
loop in Heroku for Python.
And once we're in there, then
we can make some changes.
So what we're going to do is type
in "from application import db."
We're going to do db.create_all,
and then exit to get out of it.
And what this does is goes
through our application.py
file, look for those classes that
we define with the db.models,
and once it finds those classes
and those columns that we set up,
it's just going to
create that table for us.
So this step's actually pretty easy.
So if you press Refresh in the upper
right hand corner of the Postico
application, you should
now see a User table
appear, because we've successfully
created our database table.
All right.
We're getting close.
Running locally-- so to run our
web app locally on our own machine,
we need to first load the environment
variables, and then type "flask run."
And remember, make sure
your virtual environment
is activated by source
bin slash activate.
Then we do source .env to load
the environment variables,
and then flask run.
All right, this is where it gets cool.
Then on Safari or Chrome,
go to localhost:5000,
and you should see your web app running.
Pretty cool.
But now, here we are--
part five.
It has been a long journey.
To see our Flask app on
the web, run heroku open,
and you should see your web
app running on the internet.
You can share the URL
with friends and family.
Notice that if you add names
to the web app, either locally
or on the internet, the
database updates in Postico.
For this seminar, we took our little
Flask app running in CS50 IDE,
and we, in step one, brought
it from the CS50 IDE to GitHub.
In step two, we took it
from GitHub to our Mac.
In step three, we switched
out our SQLite database
for a Heroku Postgres one.
In step four, we took it
from our Mac to Heroku.
And in step five, we took
it from Heroku to the web.
Be sure to check out the
sample code and the walkthrough
that I posted online to
accompany this seminar.
My name is Carter Page, and this is
CS50 seminar, Publishing Your Flask
App to the Web.
Thank you.
