Hey, welcome to this new lecture, and I hope you
had an easy time trying to build the geocoding app.
I know that should have been tough, but if you
have gone through a certain point, then that's great too.
In this lecture now, you'll get two things.
The first thing is you'll find the
attachment, in the resources of this lecture.
There you'll find all the files, that
contain the code for this web app.
Specifically, you'll find four directories, so static, templates, uploads
and visual, and also an app.py file.
Now, here I happen to have four app files,
but basically the last one is the final version.
So this is very basic, the ver1 where I
just add a couple of functions in a Python script.
And then I added some more to these functions, and
then some more, and then I added, and then I
eventually added some more code, that completed the application.
So this is what you get.
And you'll find this in a zip file.
So please download that.
Yeah, that's the first thing you'll get in this
lecture, the zip file of the solution code.
And the second thing is, I'll go ahead now and explain how
I approach this problem, and I'll show you the code and what
I built first, and second, and third, and so on.
[No Audio]
So these are the four versions. I have.
ver1, when I added some
code, 2, 3, and 4.
So let's ignore this for a moment, because the first
thing I want to explain is the user interface.
So we'll start from the front end first.
Now, the first thing I did,
though, was creating a directory structure.
So I created an empty static
folder, templates, and uploads, and virtual.
So static and templates are
standard for a Flask application.
And the uploads folder will be just folder where,
I generate these intermediate files, that the application
makes available for download for the users.
You'll see that in just a bit.
I also created this virtual folder there, which
is actually the directory of the virtual environment.
So I made that with Python with the m flag,
virtualenv and virtual for the name of the directory.
So if you execute that, you will get
this virtual directory. With fresh installation of Python,
and pip, and other built in libraries.
And then I went ahead and installed Flask and
I installed Pandas, because you will need Pandas to
read the data, that the user is submitting and
you want to calculate some columns there.
And you also need geopy to geocode
those values, from the Pandas DataFrame.
And, yeah, those are the three third
party libraries, that you need to install.
And once I created these empty directories, then the
second step was to create the user interface.
So what I did was, I created an
index.html template, in the templates folder.
So at first that was quite simple.
So it didn't contain this much code, that
simply contained like a title and some headings there,
and also a basic form.
[No Audio]
And initially, I didn't put anything in the action.
So when the user submits, I had this submit button and
I also had this file type of input in there.
So if you can remember it File, this is a
form, we have this File input and the Submit button.
So these two and I also restricted file submission
to CSV only and yeah, that's the form.
I didn't have this in the beginning, so I won't go
and explain this for now, I'll go through this later.
And yeah, that was the interface.
Later I went and created this main.css file.
So here you find the CSS styling for the web page.
I won't go into this now,
this is quite self explanatory.
So we have done CSS earlier in the
course, and this file is also included in
the resources among the other files.
But I never expected, you have the same styling.
So you may have some different things,
some colors or sizings and so on.
And then you go add and reference
the CSS file to these head tags.
Yeah, basically that's what I did in that second step.
So, first step creating a directory and second step
creating the basic interface and adding the CSS file
into that, if you simply created the HTML code
and then later when you finish our application, you
create a CSS file, that's perfectly okay too.
Or even if you started with a
Python file directly, that's also fine.
Some developers start from the front end and some
start from the back end, that's perfectly okay.
So yeah, once I have the interface, then
I went ahead and created an app file.
So an app.py file.
These four versions are just
for demonstration for this video.
So I made it four different files, to show you the
stages, that I went through to build my final code.
So, ver1, this is what I did,
basically, I imported this libraries.
So from flask, I imported the usual Flask class
and normally render_template method, to return HTML templates.
And I knew that my application involved some
user submission, so some post request, therefore I
included the request method there as well.
And then the send_file method, which is used
to send a file to the browser for downloading.
And yeah, that's about flask.
And then we want to geocode data, right?
So I uploaded from geopy.geocoders, I
imported Nominatim and also pandas.
And once I imported the dependencies, then I went ahead
and created a Flask instance just here, and then three
functions which for now, they don't do anything.
So the first would be the home page as
you see here with this backslash. And I name
that index the function, and I simply return render_template.
And of course here goes index.html.
So this will render the homepage which is index.html.
Then the next thing that you might expect
is, you know the user is, in your web page.
And once the user presses the Choose File button and
they select a file, and then they press Submit.
What you want to do when they press the Submit button?
Is you want now to load that file in Python and
you want to read that as a Pandas DataFrame.
I want to calculate a coordinates column,
where you calculate the latitude and longitude
from the address column using geopy.
And then out of coordinates column, you
want to calculate latitude and longitude.
So we have done this previously in
the course, in the Pandas section.
And then eventually you want to return a
DataFrame, and you want to send that
DataFrame via a render_template method.
You want to send that DataFrame here, down here.
So what we're talking here is, we're talking
about creating a function that does all this.
So it reads the csv file and process
it with Pandas, and then it displays the
table, the DataFrame, as a table.
And I created such a function
and called it success-table.
If you remember, that has to have
this methods parameter, equal to POST because
we are expecting a POST request.
And then we have yet another
function, I call this download-file.
So that's a URL, success-table.
And this is a function name, that we have yet
another URL and another function attached to that URL.
So I call this download.
Again, as I said, every time the user
does something, you want to create a decorator
and a function attached to that.
So first the user will do a submission and you
want to capture that in this function, success-table.
And then, the next thing that the user will do is
it will press the Download button that will be displayed down
here, and that has to trigger another function in Python and
that has to trigger the send_file method in Python, so
that we send the file to the user.
That means we need another
function here called download.
At least that's how I named it.
And yeah, let's go to ver2 now,
so see the difference here, and here,
the index function remains the same.
So that's all we do for index, it's quite simple.
We simply return the initial index.html template.
And then here I've added quite a load of code.
And basically what we have is we check for the request,
If we got a POST request, then I get
the file using request.files and file here is the name,
[No Audio]
of the input in here.
So, yeah, what happens is that when the
user presses the Submit button, this one here,
a URL is triggered, and that URL is
URL for the success_table function.
So this function here, that means this function will be
executed and then we create a DataFrame where, which
will read the file, this file, that we are getting
from the user, from the user form.
And then we do this, Nominatim and
we create a dataframe column there.
You know this from the Pandas section.
We use apply method, and then apply
the geocode, to the Address column.
And then out of the coordinates column, I get
a Latitude column, and I use a lambda function
to extract the latitude from each of the coordinates
rows. And also count for null values there.
And then I don't need this coordinates column, so
I just drop that using the drop method.
And then I convert this to a csv.
So here I'm generating a csv file.
This is the output that we want to give to the user.
And I'm storing this in the uploads folder.
So you just need to pass a
path there, the relative path uploads/geocoded,
that's how I'm naming this. At the moment
later, I'll do something more advanced.
So let's name it geocoded for now, .csv.
And then, what this will do, it will return a
template, so it will return the index.html template.
But then if you look here, let
me open this to another view.
Here we have a division, node, the
Geocoder syntax, that I'm using there.
So I'm including the btn variable and
I'm ignoring when that is missing.
Now this is different from here, up here.
Here I'm returning a HTML as a string,
and here I'm returning an HTML template.
So the syntax is different.
And this is also different from when we use extend.
So when we extending a layout, you extend a layout
when you want that, as soon as the user visits,
let's say the index.html template, the index.html template
will display other HTML templates, so it will extend as
soon as user visits, that index.html page,
so the home page. This is different, because we
don't want this to be displayed right away.
That's why you're saying ignore missing.
So ignore that when it's missing and include it,
only when the user is visiting this success-table
URL. And when the user visits that,
so when the user presses Submit, after
having submitted a file, then you want
to render this download.html template.
So what this contains is a button here.
You want to generate a button there
which should be, you know, we Choose File, Submit.
[No Audio]
So yeah, you get this Download file in
there, and you also get the HTML table,
so the DataFrame as an HTML table.
So the first row, the second row, the first
row, the second row, and yeah, that button now
is attached to a reference, which suggests that when
the user presses download, the url_for the Python
download function will be visited.
So we go here.
This URL of the download function will be visited.
And now what we want to do when the user visits
this URL, is we want to return a send_file method.
Actually this should be uploads/geocoded.csv.
So we want to send to the user the
file that we generated up here earlier in this
function, we want to send that to the user
under the name yourfile.csv. And also as attachments, True.
You know this code from the previous lectures
and yeah, that's about the download.html template.
And yeah, we're basically done.
I mean, you can get away with this
version of the program, and it will be
almost excellent if you went this far.
However, we may have some small problems with this.
The problem would be, you know, if you choose a file, a
csv file that doesn't have an address column inside, so
a column named Address, then what would happen is you'd
be able to load that file as a DataFrame.
And then when you try to create a new
column in the DataFrame called coordinates, and then
you try to access an existing column named Address
in the DataFrame, Python will throw an error
and it will stop the application.
That means when the user visits the success-table
URL, they will be shown an error page.
And that is not very user friendly.
So what you might want to do instead, is you
may add some functionality here that checks, if the
DataFrame, if the csv file entered by the user.
So you want to read the file as a DataFrame, and
then in the DataFrame, check if you have an address column.
If you have one, then you go ahead and do the calculations.
But if you don't, then you
return something to the user.
So instead of returning df.to_html, you return a
message saying that, sorry, you don't have such a column in your csv file.
So, yeah, I'll show you the code
for that in the next lecture, so see you.