title
Python Tutorial: Write a Script to Monitor a Website, Send Alert Emails, and Reboot Servers
description
In this Python Programming Tutorial, we're going to be looking at a real-world example of writing a script to monitor a website. If the website doesn't return a successful response for any reason then we will send an email and reboot the web server. Let's get started...
The code from this video (with added logging) can be found at:
http://bit.ly/monitor-script
Google Account Settings:
https://myaccount.google.com/lesssecureapps
https://myaccount.google.com/apppasswords
Requests Video - https://youtu.be/tb8gHvYlCFs
Environment Variables (Windows) - https://youtu.be/IolxqkL7cD8
Environment Variables (Mac and Linux) - https://youtu.be/5iWhQWVXosU
Try/Except Video - https://youtu.be/NIWwJbo-9_8
F-String Video - https://youtu.be/nghuHvKLhJA
Crontab Video - https://youtu.be/QZJ1drMQz1A
✅ Support My Channel Through Patreon:
https://www.patreon.com/coreyms
✅ Become a Channel Member:
https://www.youtube.com/channel/UCCezIgC97PvUuR4_gbFUs5g/join
✅ One-Time Contribution Through PayPal:
https://goo.gl/649HFY
✅ Cryptocurrency Donations:
Bitcoin Wallet - 3MPH8oY2EAgbLVy7RBMinwcBntggi7qeG3
Ethereum Wallet - 0x151649418616068fB46C3598083817101d3bCD33
Litecoin Wallet - MPvEBY5fxGkmPQgocfJbxP6EmTo5UUXMot
✅ Corey's Public Amazon Wishlist
http://a.co/inIyro1
✅ Equipment I Use and Books I Recommend:
https://www.amazon.com/shop/coreyschafer
▶️ You Can Find Me On:
My Website - http://coreyms.com/
My Second Channel - https://www.youtube.com/c/coreymschafer
Facebook - https://www.facebook.com/CoreyMSchafer
Twitter - https://twitter.com/CoreyMSchafer
Instagram - https://www.instagram.com/coreymschafer/
#Python
detail
{'title': 'Python Tutorial: Write a Script to Monitor a Website, Send Alert Emails, and Reboot Servers', 'heatmap': [{'end': 197.561, 'start': 166.28, 'weight': 1}, {'end': 276.762, 'start': 245.123, 'weight': 0.78}], 'summary': 'Learn to set up python environment on mac and linux, monitor a website, and automatically restart the server using python and linode api. also covers setting up smtp connection to gmail, using linode python library for server reboot, and automating website monitoring with cron.', 'chapters': [{'end': 339.842, 'segs': [{'end': 49.405, 'src': 'embed', 'start': 0.209, 'weight': 1, 'content': [{'end': 1.229, 'text': "Hey there, how's it going everybody?", 'start': 0.209, 'duration': 1.02}, {'end': 7.931, 'text': "In this video, I'm going to write a quick and easy script that monitors my personal website and sends me an email if it's down for any reason.", 'start': 1.569, 'duration': 6.362}, {'end': 14.293, 'text': "Now, if the site is down, then I'm also going to have the script automatically restart my server to see if that fixes the problem.", 'start': 8.331, 'duration': 5.962}, {'end': 19.374, 'text': 'Now a lot of people have wanted me to make videos on real-world problems that I can solve with programming,', 'start': 14.713, 'duration': 4.661}, {'end': 22.035, 'text': "and this is a script that I've been needing to write for a while now.", 'start': 19.374, 'duration': 2.661}, {'end': 26.56, 'text': 'So my personal website runs on a server that is pretty old at this point,', 'start': 22.615, 'duration': 3.945}, {'end': 30.205, 'text': "and it really just needs to be completely wiped and updated so that it's more stable.", 'start': 26.56, 'duration': 3.645}, {'end': 33.409, 'text': "But it's one of those things that I just haven't had the time to do.", 'start': 30.586, 'duration': 2.823}, {'end': 40.439, 'text': 'But with the server in its current state, sometimes web processes occasionally quit unexpectedly and cause my website not to load.', 'start': 33.99, 'duration': 6.449}, {'end': 45.523, 'text': "uh, now, for those of you who have followed along with either my flask or django series, then don't worry,", 'start': 40.999, 'duration': 4.524}, {'end': 49.405, 'text': 'the servers that we set up in that series are completely fine and stable.', 'start': 45.523, 'duration': 3.882}], 'summary': 'Script to monitor personal website and auto-restart server to fix downtimes needed due to unstable server causing occasional web processes to quit unexpectedly.', 'duration': 49.196, 'max_score': 0.209, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY209.jpg'}, {'end': 107.018, 'src': 'embed', 'start': 80.188, 'weight': 0, 'content': [{'end': 87.834, 'text': "so I'll also use the Linode API to automatically restart the server so that it possibly fixes itself before I even get the email.", 'start': 80.188, 'duration': 7.646}, {'end': 94.075, 'text': 'So this is going to be a pretty quick and easy script, but I thought some of you might find it useful to see me write this up.', 'start': 88.314, 'duration': 5.761}, {'end': 99.876, 'text': "Now I'm not going to go into as much step by step detail as to exactly what I'm doing like I do in my other tutorials.", 'start': 94.495, 'duration': 5.381}, {'end': 107.018, 'text': "I'm just going to step through this quickly and give you an idea of how a quick script can help you solve a real world problem like this.", 'start': 100.217, 'duration': 6.801}], 'summary': 'Using linode api for server restart to fix issues proactively.', 'duration': 26.83, 'max_score': 80.188, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY80188.jpg'}, {'end': 197.561, 'src': 'heatmap', 'start': 166.28, 'weight': 1, 'content': [{'end': 170.184, 'text': 'So now I have a new virtual environment called monitor underscore env.', 'start': 166.28, 'duration': 3.904}, {'end': 172.105, 'text': 'So now I can activate that.', 'start': 170.584, 'duration': 1.521}, {'end': 173.426, 'text': "So I'll say source.", 'start': 172.506, 'duration': 0.92}, {'end': 178.527, 'text': 'monitorenv forward slash bin forward slash activate.', 'start': 174.304, 'duration': 4.223}, {'end': 181.349, 'text': 'So that is now activated.', 'start': 178.967, 'duration': 2.382}, {'end': 183.611, 'text': "We can see from the prompt here that it's active.", 'start': 181.389, 'duration': 2.222}, {'end': 186.553, 'text': 'And again, this source command is for Mac and Linux.', 'start': 184.071, 'duration': 2.482}, {'end': 190.056, 'text': "If you're on Windows, then you would do something like this.", 'start': 186.893, 'duration': 3.163}, {'end': 197.561, 'text': "You'd say monitorenv backslash scripts backslash activate dot bat or something like that.", 'start': 190.096, 'duration': 7.465}], 'summary': "Activated new virtual environment 'monitor_env' for monitoring purposes.", 'duration': 31.281, 'max_score': 166.28, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY166280.jpg'}, {'end': 278.564, 'src': 'heatmap', 'start': 245.123, 'weight': 4, 'content': [{'end': 248.844, 'text': "So once we've got the environment activated let's pip install these packages.", 'start': 245.123, 'duration': 3.721}, {'end': 251.185, 'text': "So first I'll install the request library.", 'start': 249.184, 'duration': 2.001}, {'end': 253.867, 'text': "So I'll say pip install requests.", 'start': 251.305, 'duration': 2.562}, {'end': 255.728, 'text': 'And this one is usually pretty quick.', 'start': 254.087, 'duration': 1.641}, {'end': 256.789, 'text': "Okay, that's done.", 'start': 255.949, 'duration': 0.84}, {'end': 264.054, 'text': 'And also I want to install the Linode Python library that I can use to talk to my Linode servers through Python.', 'start': 257.329, 'duration': 6.725}, {'end': 266.376, 'text': 'So to do that, I can say pip install.', 'start': 264.394, 'duration': 1.982}, {'end': 270.919, 'text': 'And that is Linode underscore API 4.', 'start': 266.856, 'duration': 4.063}, {'end': 274.161, 'text': "Now, if you want to know how I got that, it's here in their documentation.", 'start': 270.919, 'duration': 3.242}, {'end': 276.762, 'text': 'Pip install Linode API 4.', 'start': 274.241, 'duration': 2.521}, {'end': 278.564, 'text': 'So let me run that.', 'start': 276.762, 'duration': 1.802}], 'summary': 'Installed requests library using pip and linode python library for linode servers.', 'duration': 38.442, 'max_score': 245.123, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY245123.jpg'}], 'start': 0.209, 'title': 'Website monitoring and automatic server restart', 'summary': 'Focuses on setting up a python environment on mac and linux, installing request and linode python libraries, and writing a script to monitor a personal website and automatically restart the server using python and the linode api.', 'chapters': [{'end': 198.602, 'start': 0.209, 'title': 'Website monitoring and automatic server restart', 'summary': "Discusses writing a script to monitor a personal website, which runs on an unstable server, and automatically restart the server if it's down, using python and the linode api.", 'duration': 198.393, 'highlights': ["The script monitors the personal website and sends an email if it's down, and also automatically restarts the server. Monitoring website, sending email, and automatic server restart.", 'The personal website runs on an unstable server, which needs to be updated for stability. Unstable server requiring update for stability.', "The server's instability causes occasional web process failures, resulting in the website not loading. Instability causing web process failures and website downtime.", 'The script aims to solve the real-world problem of unstable website hosting using Python and the Linode API for automatic server restart. Real-world problem solving using Python and Linode API.', 'The process of creating a virtual environment using the venv module in Python is explained. Creating virtual environment using venv module in Python.']}, {'end': 339.842, 'start': 199.643, 'title': 'Setting up python environment for website monitoring', 'summary': 'Illustrates setting up a python environment on mac and linux, installing request and linode python libraries using pip, obtaining a personal access token for linode server interaction, and creating an empty python script for website monitoring.', 'duration': 140.199, 'highlights': ["Installed request library using 'pip install requests' to check website response.", "Installed Linode Python library using 'pip install Linode_API_4' to interact with Linode servers through Python.", 'Emphasized the need for a personal access token for interacting with Linode account, adding a layer of security.', "Created an empty Python script named 'monitor.py' for website monitoring within the project directory."]}], 'duration': 339.633, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY209.jpg', 'highlights': ['The script aims to solve the real-world problem of unstable website hosting using Python and the Linode API for automatic server restart. Real-world problem solving using Python and Linode API.', "The script monitors the personal website and sends an email if it's down, and also automatically restarts the server. Monitoring website, sending email, and automatic server restart.", 'The personal website runs on an unstable server, which needs to be updated for stability. Unstable server requiring update for stability.', "The server's instability causes occasional web process failures, resulting in the website not loading. Instability causing web process failures and website downtime.", "Installed Linode Python library using 'pip install Linode_API_4' to interact with Linode servers through Python.", "Installed request library using 'pip install requests' to check website response."]}, {'end': 999.658, 'segs': [{'end': 405.378, 'src': 'embed', 'start': 340.162, 'weight': 0, 'content': [{'end': 344.763, 'text': "Okay, so first I'm going to import the request library.", 'start': 340.162, 'duration': 4.601}, {'end': 350.486, 'text': "Okay, so now we're going to use request to make a request to my homepage.", 'start': 345.743, 'duration': 4.743}, {'end': 355.928, 'text': 'So we can do that by saying r is equal to request dot get.', 'start': 350.826, 'duration': 5.102}, {'end': 358.47, 'text': 'And this needs to be in a string here.', 'start': 356.529, 'duration': 1.941}, {'end': 365.113, 'text': 'So this is HTTPS forward slashes, query ms.com.', 'start': 358.49, 'duration': 6.623}, {'end': 369.515, 'text': "And I'm going to set a timeout there equal to let's say five seconds.", 'start': 365.633, 'duration': 3.882}, {'end': 375.961, 'text': "Now you want to set a timeout when doing something like this, because if your site isn't responding and it gets hung up,", 'start': 369.955, 'duration': 6.006}, {'end': 378.923, 'text': 'then by default the request library will just wait indefinitely.', 'start': 375.961, 'duration': 2.962}, {'end': 385.229, 'text': 'So with a timeout set, it will only wait that number of seconds that you specify before giving up and throwing an exception.', 'start': 379.324, 'duration': 5.905}, {'end': 389.431, 'text': "So if my site doesn't respond in five seconds, then I'll just assume that something's up.", 'start': 385.669, 'duration': 3.762}, {'end': 396.294, 'text': "Okay, so now I'm going to check to make sure that the response of that request has a status code of 200.", 'start': 389.891, 'duration': 6.403}, {'end': 399.336, 'text': 'So 200 response is a successful response.', 'start': 396.294, 'duration': 3.042}, {'end': 405.378, 'text': "And if the response isn't a 200 response, then I'll want to send myself an email and restart my server.", 'start': 399.816, 'duration': 5.562}], 'summary': 'Using request library to make a request to homepage and set a 5-second timeout, checking for a successful 200 response, and handling non-200 responses by sending an email and restarting the server.', 'duration': 65.216, 'max_score': 340.162, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY340162.jpg'}, {'end': 522.644, 'src': 'embed', 'start': 479.468, 'weight': 4, 'content': [{'end': 487.672, 'text': "So if you don't have two-factor authentication, then you can just go to your Google settings and allow connection through Less Secure Apps.", 'start': 479.468, 'duration': 8.204}, {'end': 493.035, 'text': 'So this is at myaccount.google.com forward slash less secure apps.', 'start': 488.052, 'duration': 4.983}, {'end': 495.556, 'text': "And I'll put links to these in the description sections below.", 'start': 493.055, 'duration': 2.501}, {'end': 499.498, 'text': 'But I do have two-factor authentication on my machine.', 'start': 496.416, 'duration': 3.082}, {'end': 506.42, 'text': 'So, in order to connect to your account while you have two-factor authentication,', 'start': 500.278, 'duration': 6.142}, {'end': 509.961, 'text': "then you're going to need to create a password specifically for our app.", 'start': 506.42, 'duration': 3.541}, {'end': 517.183, 'text': 'And you can do that through this account here, myaccount.google.com forward slash app passwords.', 'start': 510.421, 'duration': 6.762}, {'end': 522.644, 'text': 'And I will put a link to this URL in the description section below as well.', 'start': 517.623, 'duration': 5.021}], 'summary': 'Enable two-factor authentication or create app-specific passwords for secure google account access.', 'duration': 43.176, 'max_score': 479.468, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY479468.jpg'}, {'end': 563.671, 'src': 'embed', 'start': 537.054, 'weight': 3, 'content': [{'end': 546.821, 'text': 'So once you have your Google security settings in order, then we connect to the Google mail server with the built in SMTP lib module in Python.', 'start': 537.054, 'duration': 9.767}, {'end': 550.664, 'text': "So first, I'm going to import that at the top of our script.", 'start': 547.241, 'duration': 3.423}, {'end': 551.765, 'text': "So I'll pull this back up.", 'start': 550.844, 'duration': 0.921}, {'end': 563.671, 'text': "and right above request I'm going to say import smtplib and save that and now to set this up to send an email within my conditional.", 'start': 552.505, 'duration': 11.166}], 'summary': 'Setting up google mail server with smtp lib module in python.', 'duration': 26.617, 'max_score': 537.054, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY537054.jpg'}, {'end': 778.69, 'src': 'embed', 'start': 748.148, 'weight': 7, 'content': [{'end': 753.05, 'text': "So first I'm going to pass in the email address, then I'm going to pass in the email password.", 'start': 748.148, 'duration': 4.902}, {'end': 756.893, 'text': "okay. so now let's create a simple message for our email.", 'start': 753.55, 'duration': 3.343}, {'end': 767.922, 'text': "so i'm just going to create a simple plain text email in this video and i'll be doing a more advanced email video in the near future where we cover attachments and html messages and things like that.", 'start': 756.893, 'duration': 11.029}, {'end': 770.704, 'text': 'but for this video we just want text.', 'start': 767.922, 'duration': 2.782}, {'end': 772.826, 'text': "so first i'm going to create a subject line.", 'start': 770.704, 'duration': 2.122}, {'end': 778.69, 'text': "Since this will be an email about my website being down, I'm going to make it something that will catch my eye.", 'start': 773.586, 'duration': 5.104}], 'summary': 'Creating a simple plain text email with a subject line about website being down.', 'duration': 30.542, 'max_score': 748.148, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY748148.jpg'}], 'start': 340.162, 'title': 'Website monitoring and smtp connection in python', 'summary': 'Discusses using the request library to monitor a homepage, setting a 5-second timeout, and checking for a 200 response status code. it also covers setting up an smtp connection to gmail in python, including enabling access for less secure apps and creating a specific app password for two-factor authentication, as well as constructing and sending a simple email.', 'chapters': [{'end': 458.536, 'start': 340.162, 'title': 'Using request library for website monitoring', 'summary': 'Discusses using the request library to make a request to a homepage, setting a timeout of 5 seconds to avoid indefinite waiting, and checking for a 200 response status code, with a plan to send an email and restart the server if the response is not successful.', 'duration': 118.374, 'highlights': ['Setting a timeout of 5 seconds when making a request to the homepage to avoid indefinite waiting The transcript emphasizes the importance of setting a timeout when making a request to the homepage to avoid indefinite waiting, with a specific mention of setting it to 5 seconds.', 'Checking for a 200 response status code and planning to send an email and restart the server if the response is not successful The chapter explains the process of checking for a 200 response status code and the plan to send an email and restart the server if the response is not successful, ensuring site reliability.', 'Importing the request library and using it to make a request to the homepage The chapter begins with the process of importing the request library and using it to make a request to the homepage, establishing the foundation for website monitoring.']}, {'end': 999.658, 'start': 458.876, 'title': 'Setting up smtp connection in python', 'summary': 'Explains the process of setting up an smtp connection to gmail using python, including enabling access for less secure apps and creating a specific app password for two-factor authentication, as well as constructing and sending a simple email.', 'duration': 540.782, 'highlights': ["Explaining the process of setting up an SMTP connection to Gmail using Python The chapter covers the steps to connect to Gmail's mail server via the SMTP lib module in Python, including enabling access for Less Secure Apps, creating a specific app password for two-factor authentication, and constructing and sending a simple email.", 'Enabling access for Less Secure Apps in Google settings For users without two-factor authentication, the process involves enabling access for Less Secure Apps in Google settings, accessible at myaccount.google.com/lesssecureapps.', 'Creating a specific app password for two-factor authentication For users with two-factor authentication, it is necessary to create a password specifically for the application, which can be done through the URL myaccount.google.com/apppasswords.', "Importing smtplib module to establish the SMTP connection The process involves importing the smtplib module at the beginning of the script to establish the SMTP connection to Gmail's mail server.", 'Constructing and sending a simple email The chapter covers the construction and sending of a simple plain text email, combining the subject and body of the email using the smtplib.sendmail method, and testing the email functionality.']}], 'duration': 659.496, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY340162.jpg', 'highlights': ['Setting a timeout of 5 seconds when making a request to the homepage to avoid indefinite waiting', 'Checking for a 200 response status code and planning to send an email and restart the server if the response is not successful', 'Importing the request library and using it to make a request to the homepage', 'Explaining the process of setting up an SMTP connection to Gmail using Python', 'Enabling access for Less Secure Apps in Google settings', 'Creating a specific app password for two-factor authentication', 'Importing smtplib module to establish the SMTP connection', 'Constructing and sending a simple email']}, {'end': 1242.18, 'segs': [{'end': 1047.567, 'src': 'embed', 'start': 1022.187, 'weight': 1, 'content': [{'end': 1026.851, 'text': "But now I'm going to use the Linode Python library to reboot my Linode server.", 'start': 1022.187, 'duration': 4.664}, {'end': 1034.578, 'text': "So in order to interact with my Linode account programmatically, I'm going to need to create an API token through my account.", 'start': 1027.212, 'duration': 7.366}, {'end': 1039.242, 'text': 'So I have my Linode account open here, let me exit out of that.', 'start': 1034.978, 'duration': 4.264}, {'end': 1042.464, 'text': "Okay, so I've got my Linode account open here.", 'start': 1039.702, 'duration': 2.762}, {'end': 1047.567, 'text': 'So in order to create an API token, we need to first go to our profile.', 'start': 1042.844, 'duration': 4.723}], 'summary': 'Using linode python library to reboot server, creating api token programmatically.', 'duration': 25.38, 'max_score': 1022.187, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY1022187.jpg'}, {'end': 1176.118, 'src': 'embed', 'start': 1148.189, 'weight': 2, 'content': [{'end': 1151.79, 'text': "But, like I said, if anyone doesn't know how to set environment variables,", 'start': 1148.189, 'duration': 3.601}, {'end': 1156.451, 'text': "then there's a link to those videos in the description section below on how to do that.", 'start': 1151.79, 'duration': 4.661}, {'end': 1168.253, 'text': "Okay, so I'm going to pull up my terminal here and I'm going to pause the video while I add that token to my environment variables and I'll pick it up after I've added that token.", 'start': 1156.871, 'duration': 11.382}, {'end': 1176.118, 'text': 'Okay, so I went in and I set an environment variable called Linode token to that token that I got from Linode.', 'start': 1169.215, 'duration': 6.903}], 'summary': "Demonstrating setting environment variable 'linode token'", 'duration': 27.929, 'max_score': 1148.189, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY1148189.jpg'}, {'end': 1252.486, 'src': 'embed', 'start': 1225.387, 'weight': 0, 'content': [{'end': 1232.633, 'text': 'Now one important thing is that you usually need to restart everything after you set an environment variable so that those changes can take effect.', 'start': 1225.387, 'duration': 7.246}, {'end': 1237.456, 'text': "Some people don't do that and then they wonder why they can't see their variable that they just set.", 'start': 1233.273, 'duration': 4.183}, {'end': 1242.18, 'text': "So if you haven't restarted, then it's probably not going to pick up those changes.", 'start': 1237.857, 'duration': 4.323}, {'end': 1252.486, 'text': 'So for example, let me comment out everything below here and try to print out my environment variable that I just set.', 'start': 1242.54, 'duration': 9.946}], 'summary': 'Restart after setting environment variable to see changes.', 'duration': 27.099, 'max_score': 1225.387, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY1225387.jpg'}], 'start': 999.938, 'title': 'Using linode python library for server reboot', 'summary': 'Explains the process of rebooting a linode server using the linode python library, covering steps such as creating an api token, setting environment variables, and importing the linode client. it emphasizes the significance of restarting after setting environment variables.', 'chapters': [{'end': 1242.18, 'start': 999.938, 'title': 'Using linode python library for server reboot', 'summary': 'Explains how to use the linode python library to reboot a linode server, including creating an api token, setting environment variables, and importing the linode client, while emphasizing the importance of restarting after setting environment variables.', 'duration': 242.242, 'highlights': ['The importance of restarting after setting environment variables It is emphasized that restarting is essential after setting an environment variable to ensure the changes take effect, as some people may overlook this and wonder why their variable is not visible.', 'Creating an API token for Linode account The process of creating an API token involves going to the profile, clicking on the tab for API tokens, adding a personal access token with specified label, expiration date, and access permissions, and copying the generated token for future use.', 'Setting environment variables for API token The speaker mentions setting an environment variable for the API token but opts not to show it on video due to email credentials being included, and directs viewers to related tutorial links for setting environment variables.']}], 'duration': 242.242, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY999938.jpg', 'highlights': ['The importance of restarting after setting environment variables It is emphasized that restarting is essential after setting an environment variable to ensure the changes take effect, as some people may overlook this and wonder why their variable is not visible.', 'Creating an API token for Linode account The process of creating an API token involves going to the profile, clicking on the tab for API tokens, adding a personal access token with specified label, expiration date, and access permissions, and copying the generated token for future use.', 'Setting environment variables for API token The speaker mentions setting an environment variable for the API token but opts not to show it on video due to email credentials being included, and directs viewers to related tutorial links for setting environment variables.']}, {'end': 1641.573, 'segs': [{'end': 1268.292, 'src': 'embed', 'start': 1242.54, 'weight': 3, 'content': [{'end': 1252.486, 'text': 'So for example, let me comment out everything below here and try to print out my environment variable that I just set.', 'start': 1242.54, 'duration': 9.946}, {'end': 1257.368, 'text': "So I'm going to print out that Linode token.", 'start': 1252.786, 'duration': 4.582}, {'end': 1261.149, 'text': 'And let me try to save that and run it.', 'start': 1257.848, 'duration': 3.301}, {'end': 1264.911, 'text': "And actually I do get a response there, which I shouldn't have.", 'start': 1261.709, 'duration': 3.202}, {'end': 1268.292, 'text': 'I should have restarted this before I started recording this video.', 'start': 1264.951, 'duration': 3.341}], 'summary': 'An attempt to print and save an environment variable results in an unexpected response.', 'duration': 25.752, 'max_score': 1242.54, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY1242540.jpg'}, {'end': 1401.217, 'src': 'embed', 'start': 1368.782, 'weight': 2, 'content': [{'end': 1372.324, 'text': "And after we get that working, then I'll put that logic in the correct place.", 'start': 1368.782, 'duration': 3.542}, {'end': 1376.607, 'text': "So first, let's connect to Linode through our client.", 'start': 1372.785, 'duration': 3.822}, {'end': 1380.089, 'text': "So we can do that, I'm going to remove this print statement.", 'start': 1376.967, 'duration': 3.122}, {'end': 1385.353, 'text': "So I'm going to say client is equal to Linode client that we imported right here.", 'start': 1380.39, 'duration': 4.963}, {'end': 1394.855, 'text': 'and we need to pass in this Linode token.', 'start': 1386.293, 'duration': 8.562}, {'end': 1401.217, 'text': "So we're connecting to this Linode client, passing in that Linode token.", 'start': 1395.475, 'duration': 5.742}], 'summary': 'Connecting to linode client using linode token.', 'duration': 32.435, 'max_score': 1368.782, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY1368782.jpg'}, {'end': 1548.661, 'src': 'embed', 'start': 1504.121, 'weight': 0, 'content': [{'end': 1512.187, 'text': "so we're using instance that we imported there and now I'm going to pass in the ID of the instance that we want to connect to.", 'start': 1504.121, 'duration': 8.066}, {'end': 1524.035, 'text': "so now that I've loaded that particular Linode, I should be able to reboot that machine simply by saying myserver.reboot.", 'start': 1512.187, 'duration': 11.848}, {'end': 1528.616, 'text': 'So let me make this output a little bit smaller here so that we can see a little bit more.', 'start': 1524.035, 'duration': 4.581}, {'end': 1536.298, 'text': "So now I'm going to run this and I'm going to open up my Linode account and check that that machine is actually rebooting.", 'start': 1529.216, 'duration': 7.082}, {'end': 1539.798, 'text': 'So I will save that and run it.', 'start': 1536.698, 'duration': 3.1}, {'end': 1544.059, 'text': 'So it should be rebooting that server with that ID.', 'start': 1540.279, 'duration': 3.78}, {'end': 1548.661, 'text': 'So let me open up my Linode account here, go to my dashboard.', 'start': 1544.179, 'duration': 4.482}], 'summary': 'Rebooting a linode instance using its id and checking the reboot status in the linode account.', 'duration': 44.54, 'max_score': 1504.121, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY1504121.jpg'}, {'end': 1601.278, 'src': 'embed', 'start': 1571.66, 'weight': 1, 'content': [{'end': 1574.643, 'text': 'Okay, so now that server is going to reboot.', 'start': 1571.66, 'duration': 2.983}, {'end': 1577.806, 'text': 'And that was triggered through our Python program.', 'start': 1575.143, 'duration': 2.663}, {'end': 1579.227, 'text': "So that's great.", 'start': 1578.386, 'duration': 0.841}, {'end': 1581.408, 'text': 'The script is working well so far.', 'start': 1579.267, 'duration': 2.141}, {'end': 1584.129, 'text': 'So let me go back to the script here.', 'start': 1581.808, 'duration': 2.321}, {'end': 1590.932, 'text': "So now let's take all that logic that we used to reboot our machine and move that into our conditional,", 'start': 1584.569, 'duration': 6.363}, {'end': 1595.715, 'text': "for if our website isn't returning a response code of 200..", 'start': 1590.932, 'duration': 4.783}, {'end': 1601.278, 'text': "So I'm going to take just these three lines here and cut those out.", 'start': 1595.715, 'duration': 5.563}], 'summary': 'Python program triggered server reboot; script working well; moving logic to handle non-200 response code.', 'duration': 29.618, 'max_score': 1571.66, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY1571660.jpg'}], 'start': 1242.54, 'title': 'Managing linode server and rebooting via python', 'summary': 'Covers managing linode server and environment variables, with focus on restarting the server, updating environment variables, connecting to linode via a python client, and rebooting the server using python, including checking server status and conditional actions based on website response codes.', 'chapters': [{'end': 1452.918, 'start': 1242.54, 'title': 'Managing linode server and environment variables', 'summary': 'Discusses the management of linode server and environment variables, including the process of restarting the server, updating environment variables, and connecting to linode through a python client, with emphasis on the importance of restarting to apply changes and using python to interact with linode servers.', 'duration': 210.378, 'highlights': ['The importance of restarting the server to apply changes, such as updating environment variables, is emphasized, with a demonstration of how a new token is obtained after restarting, resulting in a different token value.', "The process of connecting to Linode through a Python client is explained, including the use of the Linode token for authentication and retrieving information about Linode servers, with a demonstration of printing the server's label and ID.", 'The significance of activating the virtual environment and opening a new terminal to receive the updated token is highlighted, showcasing the need for proper environment setup to ensure the correct token value is obtained.', 'The demonstration of restarting a Linode server through Python is mentioned, with a plan to refine the logic after achieving successful server connection and interaction using Python.', "The process of printing information about the only active Linode server using a for loop to access the server's label and ID is shown, providing insight into retrieving server details through Python client interaction."]}, {'end': 1641.573, 'start': 1452.918, 'title': 'Rebooting linode server via python', 'summary': 'Demonstrates using python to connect to a linode server, retrieve its id, and reboot it, also showing the process of checking the server status and performing conditional actions based on website response codes.', 'duration': 188.655, 'highlights': ['The script successfully reboots the Linode server using the provided ID. The script demonstrates connecting to a Linode server, retrieving its ID, and initiating a reboot process, which is confirmed by checking the server status.', 'Conditional actions are implemented based on website response codes. The chapter illustrates moving the logic for rebooting the machine into a conditional statement for handling website response codes, demonstrating the integration of conditional actions within the Python script.', 'The process of connecting to the Linode server and importing necessary modules is explained. The transcript outlines the steps for connecting to the Linode server, importing required modules, and copying the server ID for further operations, providing a comprehensive guide to the initial setup process.']}], 'duration': 399.033, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY1242540.jpg', 'highlights': ['The script successfully reboots the Linode server using the provided ID.', 'Conditional actions are implemented based on website response codes.', 'The process of connecting to Linode through a Python client is explained, including the use of the Linode token for authentication and retrieving information about Linode servers.', 'The importance of restarting the server to apply changes, such as updating environment variables, is emphasized, with a demonstration of how a new token is obtained after restarting, resulting in a different token value.', 'The process of connecting to the Linode server and importing necessary modules is explained.']}, {'end': 1818.855, 'segs': [{'end': 1682.597, 'src': 'embed', 'start': 1641.973, 'weight': 0, 'content': [{'end': 1648.217, 'text': "So we're connecting to that Linode client, loading up the instance and rebooting that server.", 'start': 1641.973, 'duration': 6.244}, {'end': 1654.5, 'text': 'And that is all within the conditional of if our status code is not equal to 200.', 'start': 1648.337, 'duration': 6.163}, {'end': 1658.823, 'text': "Now, if you're wondering how I knew how to use the Linode Python library, really,", 'start': 1654.5, 'duration': 4.323}, {'end': 1662.085, 'text': 'you just have to take the time to read through the documentation on stuff like that.', 'start': 1658.823, 'duration': 3.262}, {'end': 1665.747, 'text': "There's a lot more that you can do with that API if you're interested.", 'start': 1662.765, 'duration': 2.982}, {'end': 1672.891, 'text': "Honestly, this is basically all that I've used that library for, so I'm interested in learning more about it myself.", 'start': 1666.407, 'duration': 6.484}, {'end': 1679.875, 'text': "Okay, so now we have a script that should send us an email and restart our server if our site doesn't respond with a 200 code.", 'start': 1673.331, 'duration': 6.544}, {'end': 1682.597, 'text': "So now let's test this out.", 'start': 1681.076, 'duration': 1.521}], 'summary': 'Using linode python library to automate server reboot if status code is not 200, aiming to send email and restart server.', 'duration': 40.624, 'max_score': 1641.973, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY1641973.jpg'}, {'end': 1828.118, 'src': 'embed', 'start': 1800.311, 'weight': 2, 'content': [{'end': 1804.432, 'text': "It's possible that request.get is going to throw an exception.", 'start': 1800.311, 'duration': 4.121}, {'end': 1811.494, 'text': "So for example, if it times out, it's going to throw an exception or if the server is down completely, then it's going to throw an exception.", 'start': 1804.752, 'duration': 6.742}, {'end': 1814.554, 'text': 'And we are not handling that right now.', 'start': 1812.374, 'duration': 2.18}, {'end': 1816.495, 'text': "So what we're going to do.", 'start': 1815.034, 'duration': 1.461}, {'end': 1818.855, 'text': "let's put in a try accept block to where.", 'start': 1816.495, 'duration': 2.36}, {'end': 1823.216, 'text': "if there's any exceptions, then we go ahead and send this email and restart the server.", 'start': 1818.855, 'duration': 4.361}, {'end': 1828.118, 'text': "And also, if we do get a response code, then we'll check if that is a 200 response or not.", 'start': 1823.636, 'duration': 4.482}], 'summary': 'Code needs exception handling for request.get, email notification, and server restart', 'duration': 27.807, 'max_score': 1800.311, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY1800311.jpg'}], 'start': 1641.973, 'title': 'Automated server monitoring and restart', 'summary': 'Discusses utilizing a python script to monitor website status codes, send email alerts, and reboot the server when the response is not 200, with successful tests resulting in email notifications and server reboots, and considerations for handling exceptions.', 'chapters': [{'end': 1818.855, 'start': 1641.973, 'title': 'Automated server monitoring and restart', 'summary': "Discusses using a python script to monitor a website's status code, send email alerts, and reboot the server if the response is not 200, with a successful test resulting in an email notification and server reboot, and considerations for handling exceptions.", 'duration': 176.882, 'highlights': ['The script sends an email and restarts the server if the site does not respond with a 200 code, as evidenced by receiving an email alert and observing the server rebooting. Email alert received, server reboot observed.', 'The Python script is used to monitor website status codes and automate server reboot, providing an effective means of server monitoring and maintenance. Effective monitoring and maintenance achieved.', 'Considerations for handling exceptions, such as timeouts or server downtime, are discussed, indicating a proactive approach to addressing potential issues. Proactive approach to addressing potential issues.']}], 'duration': 176.882, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY1641973.jpg', 'highlights': ['The script sends an email and restarts the server if the site does not respond with a 200 code, as evidenced by receiving an email alert and observing the server rebooting.', 'The Python script is used to monitor website status codes and automate server reboot, providing an effective means of server monitoring and maintenance.', 'Considerations for handling exceptions, such as timeouts or server downtime, are discussed, indicating a proactive approach to addressing potential issues.']}, {'end': 2101.397, 'segs': [{'end': 1845.454, 'src': 'embed', 'start': 1818.855, 'weight': 3, 'content': [{'end': 1823.216, 'text': "if there's any exceptions, then we go ahead and send this email and restart the server.", 'start': 1818.855, 'duration': 4.361}, {'end': 1828.118, 'text': "And also, if we do get a response code, then we'll check if that is a 200 response or not.", 'start': 1823.636, 'duration': 4.482}, {'end': 1838.907, 'text': 'So I think the best thing to do here is to move all of this functionality into a function so that we can run this in multiple scenarios.', 'start': 1830.038, 'duration': 8.869}, {'end': 1845.454, 'text': "So here at the top of my script, underneath my environment variables, I'm going to create two different functions here.", 'start': 1839.268, 'duration': 6.186}], 'summary': 'Create functions to handle email sending and server restart based on conditions.', 'duration': 26.599, 'max_score': 1818.855, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY1818855.jpg'}, {'end': 1937.985, 'src': 'embed', 'start': 1862.251, 'weight': 0, 'content': [{'end': 1867.197, 'text': "And I'm going to put all of that here within this notify user function.", 'start': 1862.251, 'duration': 4.946}, {'end': 1872.08, 'text': 'So now, and we could add arguments to this function if we wanted to.', 'start': 1867.757, 'duration': 4.323}, {'end': 1880.305, 'text': 'So for example, we could put a custom sender and receiver here for the email, something like that.', 'start': 1872.64, 'duration': 7.665}, {'end': 1884.247, 'text': 'All of this is just hard coded into this script for my personal example.', 'start': 1880.965, 'duration': 3.282}, {'end': 1886.249, 'text': "So I'm just going to leave it as is.", 'start': 1884.808, 'duration': 1.441}, {'end': 1893.233, 'text': 'But if you wanted to customize it and make this more customizable, then you could add those in here.', 'start': 1886.489, 'duration': 6.744}, {'end': 1902.735, 'text': "Okay, so I'm going to call that notify user and then I will create another function here and I will call this reboot server.", 'start': 1893.653, 'duration': 9.082}, {'end': 1911.917, 'text': "And again, I'm just going to take the code from there and put it into this function here.", 'start': 1903.295, 'duration': 8.622}, {'end': 1922.979, 'text': 'So now I can just say when our status code is not equal to 200, we want to notify the user and we want to reboot the server.', 'start': 1912.397, 'duration': 10.582}, {'end': 1931.882, 'text': 'and now that we have those in functions now, we can also check if we get an exception and do the same thing if we hit an exception here.', 'start': 1923.559, 'duration': 8.323}, {'end': 1935.444, 'text': "so I'm going to create a try and accept block here.", 'start': 1931.882, 'duration': 3.562}, {'end': 1937.985, 'text': "so I'll just do a basic try accept.", 'start': 1935.444, 'duration': 2.541}], 'summary': 'Creating functions to notify user and reboot server based on status code and exceptions.', 'duration': 75.734, 'max_score': 1862.251, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY1862251.jpg'}, {'end': 2003.428, 'src': 'embed', 'start': 1959.451, 'weight': 2, 'content': [{'end': 1966.313, 'text': "but I'm just going to say, if we hit any exception, then that means that our request wasn't successful.", 'start': 1959.451, 'duration': 6.862}, {'end': 1972.096, 'text': "So I'm going to want to notify myself and I'm going to go ahead and try to reboot my server anyways.", 'start': 1966.833, 'duration': 5.263}, {'end': 1975.538, 'text': "So again, what we're saying here is we're trying to make this request.", 'start': 1972.476, 'duration': 3.062}, {'end': 1979.139, 'text': 'If we get an exception, I want to send that email and reboot the server.', 'start': 1975.978, 'duration': 3.161}, {'end': 1984.182, 'text': "If that success, or if we did get a response, then we're checking.", 'start': 1979.88, 'duration': 4.302}, {'end': 1987.004, 'text': 'okay, is the response that we got a 200 response?', 'start': 1984.182, 'duration': 2.822}, {'end': 1991.965, 'text': 'If not, then I want you to also send that email and reboot the server.', 'start': 1987.264, 'duration': 4.701}, {'end': 2000.007, 'text': 'So to test this, let me actually log into my Linode and I will go ahead and just stop Apache completely.', 'start': 1992.405, 'duration': 7.602}, {'end': 2003.428, 'text': 'And that should cause us not to get a response at all.', 'start': 2000.507, 'duration': 2.921}], 'summary': 'Monitoring for exceptions, sending email, and rebooting server upon unsuccessful response.', 'duration': 43.977, 'max_score': 1959.451, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY1959451.jpg'}, {'end': 2109.982, 'src': 'embed', 'start': 2081.62, 'weight': 9, 'content': [{'end': 2089.388, 'text': 'The reason that it threw an error when that was located outside of the try accept block is because if this is an error right here,', 'start': 2081.62, 'duration': 7.768}, {'end': 2090.929, 'text': 'then that never gets set.', 'start': 2089.388, 'duration': 1.541}, {'end': 2092.871, 'text': 'That R variable never gets set.', 'start': 2091.13, 'duration': 1.741}, {'end': 2096.395, 'text': "So when we were trying to access it down here, it didn't know what it was.", 'start': 2093.192, 'duration': 3.203}, {'end': 2101.397, 'text': 'okay, so now let me try to save and run that script again now.', 'start': 2096.915, 'duration': 4.482}, {'end': 2109.982, 'text': 'it probably did send that email and it probably did reboot my server because it still hit that exception before it ran into that error.', 'start': 2101.397, 'duration': 8.585}], 'summary': 'Error occurred due to variable not being set, causing email send and server reboot.', 'duration': 28.362, 'max_score': 2081.62, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY2081620.jpg'}], 'start': 1818.855, 'title': 'Refactoring and customizing script functions', 'summary': 'Discusses refactoring email notification functionality for flexibility and reusability, customizing functions for notifying users and handling server reboot, and implementing exception handling to enhance maintainability and observe outcomes of handling exceptions.', 'chapters': [{'end': 1886.249, 'start': 1818.855, 'title': 'Refactoring script for email notification', 'summary': 'Discusses moving email notification functionality into a separate function in the script to allow for flexibility and reusability, without the need for hardcoded email details, in order to enhance maintainability and scalability.', 'duration': 67.394, 'highlights': ['Creating separate functions for email notification and server restart to improve maintainability and scalability', 'Moving email functionality into a function to enable usage in multiple scenarios', 'Discussing the possibility of adding arguments to the function for custom sender and receiver for the email']}, {'end': 1959.451, 'start': 1886.489, 'title': 'Customizing functions and exception handling', 'summary': 'Discusses customizing functions for notifying users and rebooting servers based on status codes, and implementing exception handling to handle different exceptions when making requests.', 'duration': 72.962, 'highlights': ['Creating functions for notifying users and rebooting servers based on status codes and handling exceptions when making requests.', 'Implementing try and accept blocks for handling exceptions when making requests.', 'Customizing functions to handle specific exceptions for more in-depth error handling.']}, {'end': 2101.397, 'start': 1959.451, 'title': 'Handling exceptions and server reboot', 'summary': 'Demonstrates handling exceptions in a code to send email notifications and reboot the server if the request is unsuccessful, as well as testing the process by intentionally causing an exception and observing the outcome.', 'duration': 141.946, 'highlights': ['The script handles exceptions by sending email notifications and rebooting the server if the request is unsuccessful.', 'The code checks for a 200 response, and if not received, it sends an email and reboots the server.', 'The process is tested by intentionally stopping the web server to cause an exception and observe the email notification and server reboot.', 'A mistake is identified in the code where a variable was not getting set, causing an error when trying to access it, which is resolved by placing the code within the try block.']}], 'duration': 282.542, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY1818855.jpg', 'highlights': ['Creating separate functions for email notification and server restart to improve maintainability and scalability', 'Creating functions for notifying users and rebooting servers based on status codes and handling exceptions when making requests', 'The script handles exceptions by sending email notifications and rebooting the server if the request is unsuccessful', 'Moving email functionality into a function to enable usage in multiple scenarios', 'Implementing try and accept blocks for handling exceptions when making requests', 'The process is tested by intentionally stopping the web server to cause an exception and observe the email notification and server reboot', 'Discussing the possibility of adding arguments to the function for custom sender and receiver for the email', 'Customizing functions to handle specific exceptions for more in-depth error handling', 'The code checks for a 200 response, and if not received, it sends an email and reboots the server', 'A mistake is identified in the code where a variable was not getting set, causing an error when trying to access it, which is resolved by placing the code within the try block']}, {'end': 2746.532, 'segs': [{'end': 2214.785, 'src': 'embed', 'start': 2183.929, 'weight': 1, 'content': [{'end': 2189.154, 'text': "I'm looking at my phone here and I just got an email that says that my site is down and that the server is restarting.", 'start': 2183.929, 'duration': 5.225}, {'end': 2192.115, 'text': 'So if we open this back up,', 'start': 2189.654, 'duration': 2.461}, {'end': 2201.537, 'text': 'we just got a notification that a few seconds ago that we scheduled a reboot and we can see that the machine is rebooting here and down here.', 'start': 2192.115, 'duration': 9.422}, {'end': 2208.059, 'text': 'I am getting this notification that I just got kicked out of my SSH session, and that is because the server is now down.', 'start': 2201.537, 'duration': 6.522}, {'end': 2214.785, 'text': 'But once that reboots, then our website will be working.', 'start': 2208.579, 'duration': 6.206}], 'summary': 'Server is down for reboot, site will be back up once rebooted.', 'duration': 30.856, 'max_score': 2183.929, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY2183929.jpg'}, {'end': 2299.973, 'src': 'embed', 'start': 2251.033, 'weight': 0, 'content': [{'end': 2260.283, 'text': "So we can see that's a nice feature there that if our Apache even shuts down for any reason whatsoever,", 'start': 2251.033, 'duration': 9.25}, {'end': 2263.507, 'text': "then it's just going to automatically try to restart.", 'start': 2260.283, 'duration': 3.224}, {'end': 2267.251, 'text': 'So I think that is a pretty nice feature that we added in there.', 'start': 2263.867, 'duration': 3.384}, {'end': 2271.073, 'text': 'Okay, so now I have a working script that I can run anytime,', 'start': 2267.671, 'duration': 3.402}, {'end': 2276.617, 'text': 'that I want to check the status of my website and it will perform those actions if there are any issues.', 'start': 2271.073, 'duration': 5.544}, {'end': 2283.221, 'text': 'But what if I want to run this script every 10 minutes or so, so that this process of checking the website is automated.', 'start': 2276.977, 'duration': 6.244}, {'end': 2288.365, 'text': "So I don't want to have to actually run this script manually every time I want to check my website.", 'start': 2283.462, 'duration': 4.903}, {'end': 2292.087, 'text': 'The point is that something is monitoring our website for us.', 'start': 2288.425, 'duration': 3.662}, {'end': 2297.451, 'text': "So in order to do this, we're going to need to use some sort of task scheduler.", 'start': 2292.448, 'duration': 5.003}, {'end': 2299.973, 'text': 'Now again, I am on Mac.', 'start': 2297.891, 'duration': 2.082}], 'summary': 'Script automatically restarts apache, task scheduler to automate website monitoring.', 'duration': 48.94, 'max_score': 2251.033, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY2251033.jpg'}, {'end': 2366.74, 'src': 'embed', 'start': 2340.246, 'weight': 3, 'content': [{'end': 2346.87, 'text': 'so that is the version of python that we need to run our script with so that it has access to those specific packages.', 'start': 2340.246, 'duration': 6.624}, {'end': 2351.893, 'text': "now we have our environment activated now, but if we don't have our environment activated,", 'start': 2346.87, 'duration': 5.023}, {'end': 2356.776, 'text': 'then we can simply run our script with the python executable from that environment.', 'start': 2351.893, 'duration': 4.883}, {'end': 2362.438, 'text': 'So to do this, we just need to specify the path to that Python version.', 'start': 2357.176, 'duration': 5.262}, {'end': 2366.74, 'text': 'So on my machine, that would look like this.', 'start': 2362.859, 'duration': 3.881}], 'summary': 'Activate the environment to run the script with specific python version.', 'duration': 26.494, 'max_score': 2340.246, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY2340246.jpg'}, {'end': 2411.548, 'src': 'embed', 'start': 2385.672, 'weight': 4, 'content': [{'end': 2390.796, 'text': 'And if I run that, then we can see that it just runs that version of Python.', 'start': 2385.672, 'duration': 5.124}, {'end': 2393.218, 'text': 'So I can, you know, import requests.', 'start': 2390.856, 'duration': 2.362}, {'end': 2399.384, 'text': 'And that should work because we have pip installed that inside that environment.', 'start': 2393.479, 'duration': 5.905}, {'end': 2402.325, 'text': "So that is the Python command that we're going to run.", 'start': 2400.044, 'duration': 2.281}, {'end': 2411.548, 'text': "And we're also going to want to specify the full path to the script as well, since we don't want to rely on it being from a relative directory.", 'start': 2402.945, 'duration': 8.603}], 'summary': 'Running specific python version with pip installed and importing requests.', 'duration': 25.876, 'max_score': 2385.672, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY2385672.jpg'}, {'end': 2612.226, 'src': 'embed', 'start': 2581.617, 'weight': 5, 'content': [{'end': 2587.022, 'text': "So that's our schedule, and this will run a command every 10 minutes.", 'start': 2581.617, 'duration': 5.405}, {'end': 2590.285, 'text': "So now let's tell it what command we want to run every 10 minutes.", 'start': 2587.362, 'duration': 2.923}, {'end': 2595.85, 'text': "So I copied that long command from my terminal from before, and I'm just going to paste this in here.", 'start': 2590.645, 'duration': 5.205}, {'end': 2598.833, 'text': 'Okay, and that is our entire cron schedule.', 'start': 2596.23, 'duration': 2.603}, {'end': 2600.955, 'text': 'So now I just want to save this.', 'start': 2599.153, 'duration': 1.802}, {'end': 2605.72, 'text': 'So in Vim to save, I can just press escape and that takes us out of insert mode.', 'start': 2601.115, 'duration': 4.605}, {'end': 2612.226, 'text': 'And now I can press colon WQ for whoops WQ for write and quit.', 'start': 2606.08, 'duration': 6.146}], 'summary': 'Setting a cron job to run a command every 10 minutes in vim', 'duration': 30.609, 'max_score': 2581.617, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY2581617.jpg'}, {'end': 2667.612, 'src': 'embed', 'start': 2643.715, 'weight': 6, 'content': [{'end': 2652.602, 'text': "So that's another reason why it would be a good idea to add some logging into that script so that we could occasionally check the logs and make sure that everything is running properly.", 'start': 2643.715, 'duration': 8.887}, {'end': 2658.386, 'text': 'You know, make sure that it goes out and makes the request and anytime it runs into errors or anything like that.', 'start': 2652.642, 'duration': 5.744}, {'end': 2661.428, 'text': "And there's probably a lot more that we could add to that script as well.", 'start': 2658.806, 'duration': 2.622}, {'end': 2664.33, 'text': "But I think I'm happy with what I have here for now.", 'start': 2661.768, 'duration': 2.562}, {'end': 2667.612, 'text': 'And if I need to add to it in the future, then we can build from there.', 'start': 2664.71, 'duration': 2.902}], 'summary': 'Suggests adding logging to script for error checking and future expansion.', 'duration': 23.897, 'max_score': 2643.715, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY2643715.jpg'}], 'start': 2101.397, 'title': 'Automating website monitoring with cron', 'summary': 'Demonstrates automating website monitoring using a script to check status, restart apache, and send email notifications, with details on setting up task scheduler and running website checks every 10 minutes using a python script scheduled with cron, including environment setup, path specification, cron scheduling, and logging implementation.', 'chapters': [{'end': 2321.711, 'start': 2101.397, 'title': 'Automatic website monitoring with cron', 'summary': "Demonstrates the process of automatically monitoring a website using a script that checks the website's status, restarts apache if necessary, and sends email notifications, ultimately setting up a task scheduler to automate the monitoring process.", 'duration': 220.314, 'highlights': ['The script automatically restarts Apache if it is stopped, ensuring the website is constantly running and accessible.', 'The email notification feature alerts the user when the website is down and when the server is scheduled for a reboot.', 'The process of setting up a task scheduler, such as Cron, is explored to automate the website monitoring script to run at regular intervals.']}, {'end': 2746.532, 'start': 2322.131, 'title': 'Running website check with cron', 'summary': 'Discusses running a website check every 10 minutes using a python script and scheduling it with cron, including details on setting up the environment, specifying the full path to the script, creating a cron schedule, and adding logging for feedback.', 'duration': 424.401, 'highlights': ['Setting up the environment involves activating the virtual environment and specifying the path to the Python version within the environment. Emphasizes the importance of using the correct Python version with access to specific packages, highlights the process of activating the virtual environment, and specifies the path to the Python version within the environment.', 'Specifying the full path to the script is essential to avoid relying on relative directories when running the command. Underlines the significance of specifying the full path to the script to avoid dependency on relative directories during command execution.', 'Creating a Cron schedule involves specifying the time intervals for executing the command and setting up the entire command to be run. Explains the process of creating a Cron schedule with specific time intervals for command execution and setting up the entire command to be run.', "Adding logging to the script is suggested to enable periodic checking of logs for monitoring the proper functioning of the script. Suggests the addition of logging to the script for periodic checks on the script's functionality and error handling."]}], 'duration': 645.135, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/yqm6MBt-yfY/pics/yqm6MBt-yfY2101397.jpg', 'highlights': ['The script automatically restarts Apache if it is stopped, ensuring the website is constantly running and accessible.', 'The email notification feature alerts the user when the website is down and when the server is scheduled for a reboot.', 'The process of setting up a task scheduler, such as Cron, is explored to automate the website monitoring script to run at regular intervals.', 'Setting up the environment involves activating the virtual environment and specifying the path to the Python version within the environment.', 'Specifying the full path to the script is essential to avoid relying on relative directories when running the command.', 'Creating a Cron schedule involves specifying the time intervals for executing the command and setting up the entire command to be run.', 'Adding logging to the script is suggested to enable periodic checking of logs for monitoring the proper functioning of the script.']}], 'highlights': ['Real-world problem solving using Python and Linode API.', 'Monitoring website, sending email, and automatic server restart.', 'Unstable server requiring update for stability.', 'Instability causing web process failures and website downtime.', "Installed Linode Python library using 'pip install Linode_API_4' to interact with Linode servers through Python.", "Installed request library using 'pip install requests' to check website response.", 'Setting a timeout of 5 seconds when making a request to the homepage to avoid indefinite waiting.', 'Checking for a 200 response status code and planning to send an email and restart the server if the response is not successful.', 'Explaining the process of setting up an SMTP connection to Gmail using Python.', 'Enabling access for Less Secure Apps in Google settings.', 'Creating a specific app password for two-factor authentication.', 'Importing smtplib module to establish the SMTP connection.', 'Constructing and sending a simple email.', 'The importance of restarting after setting environment variables It is emphasized that restarting is essential after setting an environment variable to ensure the changes take effect, as some people may overlook this and wonder why their variable is not visible.', 'Creating an API token for Linode account The process of creating an API token involves going to the profile, clicking on the tab for API tokens, adding a personal access token with specified label, expiration date, and access permissions, and copying the generated token for future use.', 'Setting environment variables for API token The speaker mentions setting an environment variable for the API token but opts not to show it on video due to email credentials being included, and directs viewers to related tutorial links for setting environment variables.', 'The script successfully reboots the Linode server using the provided ID.', 'Conditional actions are implemented based on website response codes.', 'The process of connecting to Linode through a Python client is explained, including the use of the Linode token for authentication and retrieving information about Linode servers.', 'The importance of restarting the server to apply changes, such as updating environment variables, is emphasized, with a demonstration of how a new token is obtained after restarting, resulting in a different token value.', 'The process of connecting to the Linode server and importing necessary modules is explained.', 'The script sends an email and restarts the server if the site does not respond with a 200 code, as evidenced by receiving an email alert and observing the server rebooting.', 'The Python script is used to monitor website status codes and automate server reboot, providing an effective means of server monitoring and maintenance.', 'Considerations for handling exceptions, such as timeouts or server downtime, are discussed, indicating a proactive approach to addressing potential issues.', 'Creating separate functions for email notification and server restart to improve maintainability and scalability.', 'Creating functions for notifying users and rebooting servers based on status codes and handling exceptions when making requests.', 'The script handles exceptions by sending email notifications and rebooting the server if the request is unsuccessful.', 'Moving email functionality into a function to enable usage in multiple scenarios.', 'Implementing try and accept blocks for handling exceptions when making requests.', 'The process is tested by intentionally stopping the web server to cause an exception and observe the email notification and server reboot.', 'Discussing the possibility of adding arguments to the function for custom sender and receiver for the email.', 'Customizing functions to handle specific exceptions for more in-depth error handling.', 'The code checks for a 200 response, and if not received, it sends an email and reboots the server.', 'A mistake is identified in the code where a variable was not getting set, causing an error when trying to access it, which is resolved by placing the code within the try block.', 'The script automatically restarts Apache if it is stopped, ensuring the website is constantly running and accessible.', 'The email notification feature alerts the user when the website is down and when the server is scheduled for a reboot.', 'The process of setting up a task scheduler, such as Cron, is explored to automate the website monitoring script to run at regular intervals.', 'Setting up the environment involves activating the virtual environment and specifying the path to the Python version within the environment.', 'Specifying the full path to the script is essential to avoid relying on relative directories when running the command.', 'Creating a Cron schedule involves specifying the time intervals for executing the command and setting up the entire command to be run.', 'Adding logging to the script is suggested to enable periodic checking of logs for monitoring the proper functioning of the script.']}