WEBVTT

0
00:00.510 --> 00:02.700
Now that we've tested our code

1
00:02.700 --> 00:05.340
and we've managed to get it working locally,

2
00:05.340 --> 00:08.730
the next step is to put our script online

3
00:08.730 --> 00:10.950
so that it can be run on schedule

4
00:10.950 --> 00:13.380
and we don't have to manually open up PyCharm

5
00:13.380 --> 00:16.020
and run it every morning at 7:00 AM.

6
00:16.020 --> 00:16.950
How do we do this?

7
00:16.950 --> 00:18.750
Well, we're going to use PythonAnywhere,

8
00:18.750 --> 00:20.970
the same service that we used before

9
00:20.970 --> 00:24.420
when we created the automatic birthday wisher.

10
00:24.420 --> 00:26.430
Now, the first thing we're going to do is, of course,

11
00:26.430 --> 00:27.540
log into the service

12
00:27.540 --> 00:30.300
and we're going to delete all of our previous files,

13
00:30.300 --> 00:33.990
so that includes the letter_templates folder,

14
00:33.990 --> 00:37.443
and also the main.py and the birthday.csv.

15
00:39.990 --> 00:42.450
Now instead of the previous main.py,

16
00:42.450 --> 00:45.270
we're going to upload our latest main.py.

17
00:45.270 --> 00:49.353
So let's go ahead and locate this in our computer.

18
00:50.400 --> 00:53.133
And then we're going to upload it to PythonAnywhere.

19
00:55.710 --> 00:56.910
There you go.

20
00:56.910 --> 01:01.910
Now let's open up this file and click, "Bash console here".

21
01:02.250 --> 01:05.253
So that's going to create our console down at the bottom,

22
01:07.080 --> 01:09.150
and once it's ready like this,

23
01:09.150 --> 01:11.940
we can enter the command to run this code.

24
01:11.940 --> 01:15.210
So it's python3, and then it's the name of our file,

25
01:15.210 --> 01:17.850
which is main.py.

26
01:17.850 --> 01:21.180
And because it's directly within my user's folder,

27
01:21.180 --> 01:24.210
I don't have to specify a file path to it.

28
01:24.210 --> 01:26.820
Now, I don't recommend to have your main.py nested

29
01:26.820 --> 01:29.670
within other folders because it's going to make this

30
01:29.670 --> 01:31.410
a little bit more complicated.

31
01:31.410 --> 01:33.630
So as long as you've uploaded it to the same place

32
01:33.630 --> 01:36.510
that I have, just straight after your username,

33
01:36.510 --> 01:38.910
then we should be able to run this line of code.

34
01:40.530 --> 01:43.980
And we can test out whether if this code now works

35
01:43.980 --> 01:45.980
when it's being run from PythonAnywhere.

36
01:46.830 --> 01:51.120
Now what you'll see instead of the message status, however,

37
01:51.120 --> 01:55.650
is an exception, and it's a ConnectionError.

38
01:55.650 --> 01:57.930
And the ConnectionError tells us something

39
01:57.930 --> 02:02.930
about this api.twilio, Max retries exceeded with url.

40
02:04.440 --> 02:08.400
So if we go ahead and highlight that, which we'll copy it,

41
02:08.400 --> 02:10.470
then we can paste it into Google

42
02:10.470 --> 02:12.600
and figure out what's wrong.

43
02:12.600 --> 02:15.630
The first post you can see is a post

44
02:15.630 --> 02:17.283
from help at pythonanywhere.

45
02:18.150 --> 02:20.340
And they've created this post to tell you

46
02:20.340 --> 02:21.660
how to get Twilio to work

47
02:21.660 --> 02:24.333
on free accounts with PythonAnywhere.

48
02:25.530 --> 02:27.330
As they say, if you're trying to use Twilio

49
02:27.330 --> 02:29.520
on a PythonAnywhere free account,

50
02:29.520 --> 02:30.630
you're going to run into an error

51
02:30.630 --> 02:32.160
that looks something like this,

52
02:32.160 --> 02:33.840
which is exactly what we got.

53
02:33.840 --> 02:35.940
And that's where Google Search picked it up

54
02:35.940 --> 02:37.443
to show us this article.

55
02:38.340 --> 02:41.190
The reason for this is because the Twilio API

56
02:41.190 --> 02:43.560
basically needs to be told how to connect

57
02:43.560 --> 02:47.280
to the proxy servers that free accounts use.

58
02:47.280 --> 02:50.340
When you have a paid account on PythonAnywhere,

59
02:50.340 --> 02:53.580
you have an actual address to your dedicated server,

60
02:53.580 --> 02:55.860
but when you only sign up with a free account

61
02:55.860 --> 02:59.580
like we have here, we only get a proxy server.

62
02:59.580 --> 03:01.740
So we need to change the code a little bit

63
03:01.740 --> 03:03.063
in order for it to work.

64
03:03.930 --> 03:06.570
Even though we are actually using the latest version

65
03:06.570 --> 03:08.700
of Twilio, from testing I found

66
03:08.700 --> 03:11.100
that this code doesn't seem to work for me.

67
03:11.100 --> 03:14.460
Instead, we have to use this version of the fix

68
03:14.460 --> 03:16.680
that they've specified here.

69
03:16.680 --> 03:19.740
So the only difference from their version of the code

70
03:19.740 --> 03:24.600
and what we have here in our main.py is three lines of code.

71
03:24.600 --> 03:28.740
First, we have to import this class called TwilioHttpClient

72
03:28.740 --> 03:30.450
from the Twilio module.

73
03:30.450 --> 03:34.083
So let's copy that and paste it below our previous lines.

74
03:35.460 --> 03:39.330
Now in addition, we have to create a proxy client

75
03:39.330 --> 03:41.790
with the TwilioHttpClient class

76
03:41.790 --> 03:44.310
that we just imported just now.

77
03:44.310 --> 03:46.740
So we're going to put that in our if-statement

78
03:46.740 --> 03:49.860
when we're about to create our SMS message.

79
03:49.860 --> 03:51.300
The last step is,

80
03:51.300 --> 03:54.630
where we have our client class being created,

81
03:54.630 --> 03:58.080
we have to set this http_client parameter

82
03:58.080 --> 04:00.663
to the proxy client that we created just now.

83
04:01.620 --> 04:04.020
That's going to go right here.

84
04:04.020 --> 04:06.600
The rest of the code, we can leave as is,

85
04:06.600 --> 04:10.623
and we can simply hit Save to update that code.

86
04:11.580 --> 04:13.530
Now once we've typed all of that code,

87
04:13.530 --> 04:15.900
you can see we get an error in here.

88
04:15.900 --> 04:18.270
It says, "undefined name 'os' ",

89
04:18.270 --> 04:22.560
and that's because this os actually comes from an os module,

90
04:22.560 --> 04:26.193
so we should import that in order for this error to go away.

91
04:27.090 --> 04:29.220
So let's hit Save again,

92
04:29.220 --> 04:33.060
and you can see we are now free of warnings and errors.

93
04:33.060 --> 04:35.700
We're now ready to go into our console

94
04:35.700 --> 04:39.510
and to run the same command again, which is python3

95
04:39.510 --> 04:42.600
and then it's the name of our file, main.py.

96
04:42.600 --> 04:44.130
So now when we hit enter,

97
04:44.130 --> 04:46.470
you can see we get back the message queued,

98
04:46.470 --> 04:48.390
which comes from this print statement,

99
04:48.390 --> 04:50.610
and that's because the status of our message

100
04:50.610 --> 04:52.323
has now been queued.

101
04:53.190 --> 04:57.510
And you can see I've now received the message from Twilio,

102
04:57.510 --> 05:00.300
and this is, of course, because my main.py was run

103
05:00.300 --> 05:02.100
on the PythonAnywhere servers

104
05:02.100 --> 05:04.560
instead of from my local computer.

105
05:04.560 --> 05:06.990
So now that we've confirmed that this works,

106
05:06.990 --> 05:09.430
we can now finally go back to PythonAnywhere

107
05:11.100 --> 05:16.100
and go to the Tasks section in order to set up our task.

108
05:16.920 --> 05:19.890
Now here, I've still got my previous task set up

109
05:19.890 --> 05:23.310
when we created the automatic birthday wisher.

110
05:23.310 --> 05:24.480
Now, because I'm demoing this

111
05:24.480 --> 05:27.030
with a free PythonAnywhere account,

112
05:27.030 --> 05:30.150
I can only create one scheduled task.

113
05:30.150 --> 05:32.370
If I start paying them, then I can schedule

114
05:32.370 --> 05:35.580
as many as I want and they never expire.

115
05:35.580 --> 05:37.380
But because we're just learning here,

116
05:37.380 --> 05:39.690
I don't want you to commit to a paid account

117
05:39.690 --> 05:41.730
just to be able to see how it works.

118
05:41.730 --> 05:44.400
So we're going to use the same scheduled task.

119
05:44.400 --> 05:46.110
Now, if you don't have any task scheduled,

120
05:46.110 --> 05:48.000
just go ahead and create one,

121
05:48.000 --> 05:49.770
and the command is going to be the same.

122
05:49.770 --> 05:53.070
It's python3, and then it's running our main.py.

123
05:53.070 --> 05:56.280
So the same command that you entered previously.

124
05:56.280 --> 05:58.980
And we're going to set the frequency to daily,

125
05:58.980 --> 06:01.383
and it's going to run at 7:00 AM every day.

126
06:02.460 --> 06:05.460
In order to test this, I'm going to change the time

127
06:05.460 --> 06:08.670
from 7:00 AM to the current time.

128
06:08.670 --> 06:11.910
So the current server time is registering as 10:01,

129
06:11.910 --> 06:14.280
but, in fact, I'm actually seeing 02,

130
06:14.280 --> 06:17.850
so I'm going to change that to 10:03,

131
06:17.850 --> 06:20.850
and then hit the check mark.

132
06:20.850 --> 06:24.030
And now I'm going to wait patiently to see

133
06:24.030 --> 06:27.120
if that is going to be triggered automatically

134
06:27.120 --> 06:28.680
from the scheduled tasks,

135
06:28.680 --> 06:30.783
and I get the SMS sent to my phone.

136
06:32.010 --> 06:33.270
And there you have it.

137
06:33.270 --> 06:36.000
This is now being sent to me from Twilio

138
06:36.000 --> 06:37.950
because we made the API call,

139
06:37.950 --> 06:41.850
but it's being sent because I've got this scheduled task,

140
06:41.850 --> 06:46.680
which is calling this command in order to run our main.py.

141
06:46.680 --> 06:49.800
And it's being done at a time which I've specified,

142
06:49.800 --> 06:51.750
which in fact I want to happen

143
06:51.750 --> 06:54.570
at, probably, 7:00 AM in the morning.

144
06:54.570 --> 06:56.790
Now, notice that this is UTC time.

145
06:56.790 --> 07:01.470
So if you want to convert the UTC time to your local time,

146
07:01.470 --> 07:05.010
so at the moment we're on British Summer Time where I'm at,

147
07:05.010 --> 07:06.720
then you can type this into Google

148
07:06.720 --> 07:10.170
and change this to whatever time zone you are in.

149
07:10.170 --> 07:14.250
And that way you can figure out what time UTC is

150
07:14.250 --> 07:17.040
relative to your local time.

151
07:17.040 --> 07:19.440
In my case, it's just one hour behind.

152
07:19.440 --> 07:22.530
So if I want this to run at 7:00 AM my local time,

153
07:22.530 --> 07:25.560
then I have to change this to six o'clock.

154
07:25.560 --> 07:28.140
And now that's going to run every day at 6:00 AM

155
07:28.140 --> 07:30.180
without me needing to do anything.

156
07:30.180 --> 07:33.210
And I'm going to get my notification on time

157
07:33.210 --> 07:34.593
if it's going to rain.