Instructor: Now that we've tested our code
and we've managed to get it working locally,
the next step is to put our script online
so that it can be run on schedule
and we don't have to manually open up Python
and run it every morning at 7:00 AM.
How do we do this?
Well, we're going to use PythonAnywhere,
the same service that we used before
when we created the automatic birthday wisher.
Now, the first thing we're going to do is, of course,
log into the service
and we're going to delete all of our previous files,
so that includes the letter template folder
and also the main.py and the birthday.csv.
Now instead of the previous main.py,
we're going to upload our latest main.py.
So let's go ahead and locate this in our computer.
And then we're going to upload it to PythonAnywhere.
There you go.
Now let's open up this file and click Bash console here.
So that's going to create our console down at the bottom,
and once it's ready like this,
we can enter the command to run this code.
So it's python3, and then it's the name of our file,
which is main.py.
And because it's directly within my user's folder,
I don't have to specify a file path to it.
Now, I don't recommend to have your main.py nested
within other folders because it's going to make this
a little bit more complicated.
So as long as you've uploaded it to the same place
that I have, just straight after your username,
then we should be able to run this line of code.
And we can test out whether if this code now works
when it's being run from PythonAnywhere.
Now what you'll see instead of the message status, however,
is a exception, and it's a connection error.
And the connection error tells us something
about this api.twilio max retries exceeded with url.
So if we go ahead and highlight that, which we'll copy it,
then we can paste it into Google
and figure out what's wrong.
The first post you can see is a post
from Help at PythonAnywhere.
And they've created this post to tell you
how to get Twilio to work
on free accounts with PythonAnywhere.
As they say, if you're trying to use Twilio
on a PythonAnywhere free account,
you're going to run into an error
that looks something like this,
which is exactly what we got.
And that's where Google Search picked it up
to show us this article.
The reason for this is because the Twilio API
basically needs to be told how to connect
to the proxy servers that free accounts use.
When you have a paid account on PythonAnywhere,
you have an actual address to your dedicated server,
but when you only sign up with a free account
like we have here, we only get a proxy server.
So we need to change the code a little bit
in order for it to work.
Even though we are actually using the latest version
of Twilio, from testing I found
that this code doesn't seem to work for me.
Instead, we have to use this version of the fix
that they've specified here.
So the only difference from their version of the code
and what we have here in our main.py is three lines of code.
First, we have to import this class called TwilioHttpClient
from the Twilio module.
So let's copy that and paste it below our previous lines.
Now in addition, we have to create a proxy client
with the TwilioHttpClient class
that we just imported just now.
So we're going to put that in our IF statement
when we're about to create our SMS message.
The last step is,
where we have our client class being created,
we have to set this HTTP client parameter
to the proxy client that we created just now.
That's going to go right here.
The rest of the code, we can leave as is,
and we can simply hit Save to update that code.
Now once we've typed all of that code,
you can see we get an error in here.
It says undefined name os,
and that's because this os actually comes from an os module,
so we should import that in order for this error to go away.
So let's hit Save again,
and you can see we are now free of warnings and errors.
We're now ready to go into our console
and to run the same command again, which is python3
and then it's the name of our file, main.py.
So now when we hit enter,
you can see we get back the message queued,
which comes from this print statement,
and that's because the status of our message
has now been queued.
And you can see I've now received the message from Twilio,
and this is, of course, because my main.py was run
on the PythonAnywhere servers
instead of from my local computer.
So now that we've confirmed that this works,
we can now finally go back to PythonAnywhere
and go to the Tasks section in order to set up our task.
Now here, I've still got my previous task set up
when we created the automatic birthday wisher.
Now, because I'm demoing this
with a free PythonAnywhere account,
I can only create one scheduled task.
If I start paying them, then I can schedule
as many as I want and they never expire.
But because we're just learning here,
I don't want you to commit to a paid account
just to be able to see how it works.
So we're going to use the same scheduled task.
Now, if you don't have any task scheduled,
just go ahead and create one,
and the command is going to be the same.
It's python3, and then it's running our main.py.
So the same command that you entered previously.
And we're going to set the frequency to daily,
and it's going to run at 7:00 AM every day.
In order to test this, I'm going to change the time
from 7:00 AM to the current time.
So the current server time is registering as 10:01,
but, in fact, I'm actually seeing 02,
so I'm going to change that to 10:03,
and then hit the check mark.
And now I'm going to wait patiently to see
if that is going to be triggered automatically
from the scheduled tasks,
and I get the SMS sent to my phone.
And there you have it.
This is now being sent to me from Twilio
because we made the API call,
but it's being sent because I've got this scheduled task,
which is calling this command in order to run our main.py.
And it's being done at a time which I've specified,
which in fact I want to happen
at, probably, 7:00 AM in the morning.
Now, notice that this is UTC time.
So if you want to convert the UTC time to your local time,
so at the moment we're on British Summer Time where I'm at,
then you can type this into Google
and change this to whatever time zone you are in.
And that way you can figure out what time UTC is
relative to your local time.
In my case, it's just one hour behind.
So if I want this to run at 7:00 AM my local time,
then I have to change this to 6:00.
And now that's going to run every day at 6:00 AM
without me needing to do anything.
And I'm going to get my notification on time
if it's going to rain.