From 5b3928ce797289978f8c4e60d78eb6769d477dfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C4=93teris=20Caune?= Date: Fri, 26 Jun 2020 10:11:08 +0300 Subject: [PATCH] render_docs --- templates/docs/api.html | 88 +++++++++---------- templates/docs/attaching_logs.html | 12 +-- templates/docs/bash.html | 16 ++-- templates/docs/cloning_checks.html | 6 +- templates/docs/csharp.html | 4 +- templates/docs/http_api.html | 36 ++++---- templates/docs/javascript.html | 8 +- templates/docs/measuring_script_run_time.html | 6 +- templates/docs/monitoring_cron_jobs.html | 12 +-- templates/docs/php.html | 4 +- templates/docs/powershell.html | 12 +-- templates/docs/python.html | 16 ++-- templates/docs/ruby.html | 4 +- templates/docs/signalling_failures.html | 12 +-- 14 files changed, 118 insertions(+), 118 deletions(-) diff --git a/templates/docs/api.html b/templates/docs/api.html index 8583b8ee..3c3d2554 100644 --- a/templates/docs/api.html +++ b/templates/docs/api.html @@ -113,12 +113,12 @@ specified value.

The API key is either missing or invalid.

Example Request

-
curl --header "X-Api-Key: your-api-key" SITE_ROOT/api/v1/checks/
-
+
curl --header "X-Api-Key: your-api-key" SITE_ROOT/api/v1/checks/
+

Example Response

-
{
+
{
   "checks": [
     {
       "name": "Filesystem Backup",
@@ -155,13 +155,13 @@ specified value.

} ] } -
+

When using the read-only API key, the following fields are omitted: ping_url, update_url, pause_url, channels. An extra unique_key field is added which can be used to GET a check in place of the UUID. The unique_key identifier is stable across API calls. Example:

-
{
+
{
   "checks": [
     {
       "name": "Filesystem Backup",
@@ -192,7 +192,7 @@ is added which can be used to GET a check
     }
   ]
 }
-
+

Get a Single Check

@@ -213,12 +213,12 @@ using the read-only API key) as an identifier.

The specified check does not exist.

Example Request

-
curl --header "X-Api-Key: your-api-key" SITE_ROOT/api/v1/checks/<uuid>
-
+
curl --header "X-Api-Key: your-api-key" SITE_ROOT/api/v1/checks/<uuid>
+

Example Response

-
{
+
{
   "name": "Database Backup",
   "tags": "production db",
   "desc": "Runs ~/db-backup.sh",
@@ -235,7 +235,7 @@ using the read-only API key) as an identifier.

"schedule": "15 5 * * *", "tz": "UTC" } -
+

Example Read-Only Response

@@ -245,7 +245,7 @@ added. This identifier is stable across API calls.

Note: the ping_url, update_url and pause_url fields, although omitted, are not really secret. The client already knows the check's unique UUID and so can easily construct these URLs by itself.

-
{
+
{
   "name": "Database Backup",
   "tags": "production db",
   "desc": "Runs ~/db-backup.sh",
@@ -259,7 +259,7 @@ construct these URLs by itself.

"schedule": "15 5 * * *", "tz": "UTC" } -
+

Create a Check

@@ -371,20 +371,20 @@ field values. the limit is 20 checks per account.

Example Request

-
curl SITE_ROOT/api/v1/checks/ \
+
curl SITE_ROOT/api/v1/checks/ \
     --header "X-Api-Key: your-api-key" \
     --data '{"name": "Backups", "tags": "prod www", "timeout": 3600, "grace": 60}'
-
+

Or, alternatively:

-
curl SITE_ROOT/api/v1/checks/ \
+
curl SITE_ROOT/api/v1/checks/ \
     --data '{"api_key": "your-api-key", "name": "Backups", "tags": "prod www", "timeout": 3600, "grace": 60}'
-
+

Example Response

-
{
+
{
   "channels": "",
   "desc": "",
   "grace": 60,
@@ -400,7 +400,7 @@ the limit is 20 checks per account.
   "timeout": 3600,
   "update_url": "SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc",
 }
-
+

Update an Existing Check

@@ -495,20 +495,20 @@ field values.
The specified check does not exist.

Example Request

-
curl SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc \
+
curl SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc \
     --header "X-Api-Key: your-api-key" \
     --data '{"name": "Backups", "tags": "prod www", "timeout": 3600, "grace": 60}'
-
+

Or, alternatively:

-
curl SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc \
+
curl SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc \
     --data '{"api_key": "your-api-key", "name": "Backups", "tags": "prod www", "timeout": 3600, "grace": 60}'
-
+

Example Response

-
{
+
{
   "channels": "",
   "desc": "",
   "grace": 60,
@@ -524,7 +524,7 @@ field values.
   "timeout": 3600,
   "update_url": "SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc",
 }
-
+

Pause Monitoring of a Check

@@ -544,16 +544,16 @@ state. You can resume monitoring of the check by pinging it.

The specified check does not exist.

Example Request

-
curl SITE_ROOT/api/v1/checks/0c8983c9-9d73-446f-adb5-0641fdacc9d4/pause \
+
curl SITE_ROOT/api/v1/checks/0c8983c9-9d73-446f-adb5-0641fdacc9d4/pause \
     --request POST --header "X-Api-Key: your-api-key" --data ""
-
+

Note: the --data "" argument forces curl to send a Content-Length request header even though the request body is empty. For HTTP POST requests, the Content-Length header is sometimes required by some network proxies and web servers.

Example Response

-
{
+
{
   "channels": "",
   "desc": "",
   "grace": 60,
@@ -569,7 +569,7 @@ header is sometimes required by some network proxies and web servers.

"timeout": 3600, "update_url": "SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc" } -
+

Delete Check

@@ -589,13 +589,13 @@ check that was just deleted.

The specified check does not exist.

Example Request

-
curl SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc \
+
curl SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc \
     --request DELETE --header "X-Api-Key: your-api-key"
-
+

Example Response

-
{
+
{
   "channels": "",
   "desc": "",
   "grace": 60,
@@ -611,7 +611,7 @@ check that was just deleted.

"timeout": 3600, "update_url": "SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc", } -
+

Get a list of check's logged pings

@@ -632,13 +632,13 @@ number of returned pings depends on account's billing plan: 100 for free account
The specified check does not exist.

Example Request

-
curl SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc/pings/ \
+
curl SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc/pings/ \
     --header "X-Api-Key: your-api-key"
-
+

Example Response

-
{
+
{
   "pings": [
     {
       "type": "success",
@@ -680,7 +680,7 @@ number of returned pings depends on account's billing plan: 100 for free account
     }
   ]
 }
-
+

Get a list of check's status changes

@@ -723,13 +723,13 @@ number of returned pings depends on account's billing plan: 100 for free account
The specified check does not exist.

Example Request

-
curl SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc/flips/ \
+
curl SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc/flips/ \
     --header "X-Api-Key: your-api-key"
-
+

Example Response

-
[
+
[
     {
       "timestamp": "2020-03-23T10:18:23+00:00",
       "up": 1
@@ -743,7 +743,7 @@ number of returned pings depends on account's billing plan: 100 for free account
       "up": 1
     }
 ]
-
+

Get a List of Existing Integrations

@@ -757,12 +757,12 @@ number of returned pings depends on account's billing plan: 100 for free account
The API key is either missing or invalid.

Example Request

-
curl --header "X-Api-Key: your-api-key" SITE_ROOT/api/v1/channels/
-
+
curl --header "X-Api-Key: your-api-key" SITE_ROOT/api/v1/channels/
+

Example Response

-
{
+
{
   "channels": [
     {
       "id": "4ec5a071-2d08-4baa-898a-eb4eb3cd6941",
@@ -776,4 +776,4 @@ number of returned pings depends on account's billing plan: 100 for free account
     }
   ]
 }
-
\ No newline at end of file +
\ No newline at end of file diff --git a/templates/docs/attaching_logs.html b/templates/docs/attaching_logs.html index 65dd7b2a..75e8876b 100644 --- a/templates/docs/attaching_logs.html +++ b/templates/docs/attaching_logs.html @@ -6,17 +6,17 @@ the request body, so you can inspect it later.

Logging Command Output

In this example, we run certbot renew, capture its output, and submit the captured output to SITE_NAME:

-
#!/bin/sh
+
#!/bin/sh
 
 m=$(/usr/bin/certbot renew 2>&1)
 curl -fsS --retry 3 --data-raw "$m" PING_URL
-
+

In Combination with the /fail Endpoint

We can extend the previous example and signal either success or failure depending on the exit code:

-
#!/bin/sh
+
#!/bin/sh
 
 url=PING_URL
 
@@ -24,11 +24,11 @@ depending on the exit code:

if [ $? -ne 0 ]; then url=$url/fail; fi curl -fsS --retry 3 --data-raw "$m" $url -
+

All in One Line

Finally, all of the above can be packaged in a single line. The one-line version can be put directly in crontab, without using a wrapper script.

-
m=$(/usr/bin/certbot renew 2>&1); curl -fsS --data-raw "$m" "PING_URL$([ $? -ne 0 ] && echo -n /fail)"
-
\ No newline at end of file +
m=$(/usr/bin/certbot renew 2>&1); curl -fsS --data-raw "$m" "PING_URL$([ $? -ne 0 ] && echo -n /fail)"
+
\ No newline at end of file diff --git a/templates/docs/bash.html b/templates/docs/bash.html index 4c41a2bc..6d31cd7b 100644 --- a/templates/docs/bash.html +++ b/templates/docs/bash.html @@ -4,7 +4,7 @@ have to do is make a HTTP request at the end of the script. curl and wget are two common command line HTTP clients you can use.

-
# Sending a HTTP GET request with curl:
+
# Sending a HTTP GET request with curl:
 curl --retry 3 PING_URL
 
 # Silent version (no stdout/stderr output unless curl hits an error):
@@ -12,7 +12,7 @@ curl -fsS --retry 3 PING_URL
 
 # Sending a HTTP GET request with wget:
 wget PING_URL -O /dev/null
-
+

Signalling Failure from Shell Scripts

@@ -23,13 +23,13 @@ signal a failure. The below example:

  • if the certbot command is successful (exit code 0), send HTTP GET to PING_URL
  • otherwise, send HTTP GET to PING_URL/fail
  • -
    #!/bin/sh
    +
    #!/bin/sh
     
     # Payload here:
     /usr/bin/certbot renew
     # Ping SITE_NAME
     curl --retry 3 "PING_URL$([ $? -ne 0 ] && echo -n /fail)"
    -
    +

    Logging Command Output

    @@ -37,11 +37,11 @@ curl --retry 3 "PING_URL

    In the below example, certbot's output is captured and submitted via HTTP POST:

    -
    #!/bin/sh
    +
    #!/bin/sh
     
     m=$(/usr/bin/certbot renew 2>&1)
     curl -fsS --retry 3 --data-raw "$m" PING_URL
    -
    +

    Auto-provisioning New Checks

    @@ -49,7 +49,7 @@ curl -fsS --retry 3 --data-raw " -
    #!/bin/bash
    +
    #!/bin/bash
     
     API_KEY=your-api-key-here
     
    @@ -62,4 +62,4 @@ register with SITE_NAME the first time they run.

    # Finally, send a ping: curl --retry 3 $URL -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/templates/docs/cloning_checks.html b/templates/docs/cloning_checks.html index 83598075..8206e999 100644 --- a/templates/docs/cloning_checks.html +++ b/templates/docs/cloning_checks.html @@ -16,7 +16,7 @@ an existing deployment in a new region. The SITE_NAME web interface does not have a function to clone an entire project, but this can be done relatively easily using the Management API calls. Below is an example using Python and the requests library:

    -
    import requests
    +
    import requests
     
     API_URL = "SITE_ROOT/api/v1/checks/"
     SOURCE_PROJECT_READONLY_KEY = "..."
    @@ -24,6 +24,6 @@ and the requests library:

    r = requests.get(API_URL, headers={"X-Api-Key": SOURCE_PROJECT_READONLY_KEY}) for check in r.json()["checks"]: - print("Cloning %s" % check["name"]) + print("Cloning %s" % check["name"]) requests.post(API_URL, json=check, headers={"X-Api-Key": TARGET_PROJECT_KEY}) -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/templates/docs/csharp.html b/templates/docs/csharp.html index ebfb87c6..270612a2 100644 --- a/templates/docs/csharp.html +++ b/templates/docs/csharp.html @@ -1,7 +1,7 @@

    C

    Below is an example of making a HTTP request to SITE_NAME from C#.

    -
    using (var client = new System.Net.WebClient())
    +
    using (var client = new System.Net.WebClient())
     {
            client.DownloadString("PING_URL");
     }
    -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/templates/docs/http_api.html b/templates/docs/http_api.html index 40625c65..59550d10 100644 --- a/templates/docs/http_api.html +++ b/templates/docs/http_api.html @@ -15,20 +15,20 @@ If the request body looks like a UTF-8 string, SITE_NAME stores the request body

    Successful responses will have the "200 OK" HTTP response status code and a short and simple string "OK" in the response body.

    Signal Success ("ping")

    -
    HEAD|GET|POST PING_ENDPOINT{uuid}
    -
    +
    HEAD|GET|POST PING_ENDPOINT{uuid}
    +

    Signals to SITE_NAME that the job has completed successfully (or, for continuously running processes, is still running and healthy). The uuid parameter is unique for each check.

    Example

    -
    GET /5bf66975-d4c7-4bf5-bcc8-b8d8a82ea278 HTTP/1.0
    +
    GET /5bf66975-d4c7-4bf5-bcc8-b8d8a82ea278 HTTP/1.0
     Host: hc-ping.com
    -
    +
    -
    HTTP/1.1 200 OK
    +
    HTTP/1.1 200 OK
     Server: nginx
     Date: Wed, 29 Jan 2020 09:58:23 GMT
     Content-Type: text/plain; charset=utf-8
    @@ -37,23 +37,23 @@ is unique for each check.

    Access-Control-Allow-Origin: * OK -
    +

    Signal Failure

    -
    HEAD|GET|POST PING_ENDPOINT{uuid}/fail
    -
    +
    HEAD|GET|POST PING_ENDPOINT{uuid}/fail
    +

    Signals to SITE_NAME that the job has failed. Actively signalling a failure minimizes the delay from your monitored service failing to you receiving an alert.

    Example

    -
    GET /5bf66975-d4c7-4bf5-bcc8-b8d8a82ea278/fail HTTP/1.0
    +
    GET /5bf66975-d4c7-4bf5-bcc8-b8d8a82ea278/fail HTTP/1.0
     Host: hc-ping.com
    -
    +
    -
    HTTP/1.1 200 OK
    +
    HTTP/1.1 200 OK
     Server: nginx
     Date: Wed, 29 Jan 2020 09:58:23 GMT
     Content-Type: text/plain; charset=utf-8
    @@ -62,12 +62,12 @@ minimizes the delay from your monitored service failing to you receiving an aler
     Access-Control-Allow-Origin: *
     
     OK
    -
    +

    Signal a Start

    -
    HEAD|GET|POST PING_ENDPOINT{uuid}/start
    -
    +
    HEAD|GET|POST PING_ENDPOINT{uuid}/start
    +

    Sends a "job has started!" message to SITE_NAME. This is @@ -77,12 +77,12 @@ optional but enables a few extra features:

  • SITE_NAME will detect if the job runs longer than its configured grace time
  • Example

    -
    GET /5bf66975-d4c7-4bf5-bcc8-b8d8a82ea278/start HTTP/1.0
    +
    GET /5bf66975-d4c7-4bf5-bcc8-b8d8a82ea278/start HTTP/1.0
     Host: hc-ping.com
    -
    +
    -
    HTTP/1.1 200 OK
    +
    HTTP/1.1 200 OK
     Server: nginx
     Date: Wed, 29 Jan 2020 09:58:23 GMT
     Content-Type: text/plain; charset=utf-8
    @@ -91,4 +91,4 @@ optional but enables a few extra features:

    Access-Control-Allow-Origin: * OK -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/templates/docs/javascript.html b/templates/docs/javascript.html index 2dd7ee40..4e0e1c3c 100644 --- a/templates/docs/javascript.html +++ b/templates/docs/javascript.html @@ -1,13 +1,13 @@

    Javascript

    Below is an example of making a HTTP request to SITE_NAME from Node.js.

    -
    var https = require('https');
    +
    var https = require('https');
     https.get("PING_URL");
    -
    +

    You can also send pings from a browser environment. SITE_NAME sets the Access-Control-Allow-Origin:* CORS header, so cross-domain AJAX requests work.

    -
    var xhr = new XMLHttpRequest();
    +
    var xhr = new XMLHttpRequest();
     xhr.open('GET', 'PING_URL', true);
     xhr.send(null);
    -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/templates/docs/measuring_script_run_time.html b/templates/docs/measuring_script_run_time.html index a957de54..5217d455 100644 --- a/templates/docs/measuring_script_run_time.html +++ b/templates/docs/measuring_script_run_time.html @@ -7,7 +7,7 @@

    Signalling a start kicks off a separate timer: the job now must signal a success within its configured "Grace Time", or it will get marked as "down".

    Below is a code example in Python:

    -
    import requests
    +
    import requests
     URL = "PING_URL"
     
     
    @@ -23,11 +23,11 @@ success within its configured "Grace Time", or it will get marked as "down".

    # TODO: run the job here fib = lambda n: n if n < 2 else fib(n - 1) + fib(n - 2) -print("F(42) = %d" % fib(42)) +print("F(42) = %d" % fib(42)) # Signal success: requests.get(URL) -
    +

    Viewing Measured Run Times

    diff --git a/templates/docs/monitoring_cron_jobs.html b/templates/docs/monitoring_cron_jobs.html index ba63c2c7..c2051859 100644 --- a/templates/docs/monitoring_cron_jobs.html +++ b/templates/docs/monitoring_cron_jobs.html @@ -3,10 +3,10 @@ update your cron job command to send a HTTP request to SITE_NAME after a job completes.

    Let's look at an example:

    -
    $ crontab -l
    +
    $ crontab -l
     # m h dom mon dow command
       8 6 * * * /home/user/backup.sh
    -
    +

    The above job runs /home/user/backup.sh every day at 6:08. The backup @@ -40,10 +40,10 @@ increasingly important as you add more checks to your account.

    Finally, edit your cron job definition and append a curl or wget call after the command:

    -
    $ crontab -e
    +
    $ crontab -e
     # m h dom mon dow command
       8 6 * * * /home/user/backup.sh && curl -fsS --retry 3 -o /dev/null PING_URL
    -
    +

    Now, each time your cron job runs, it will send a HTTP request to the ping URL. @@ -101,7 +101,7 @@ there is an error. Feel free to adjust the curl options to suit your needs.

    Looking up Your Machine's Time Zone

    On modern GNU/Linux systems, you can look up the time zone using the timedatectl status command and looking for "Time zone" in its output:

    -
    $ timedatectl status
    +
    $ timedatectl status
     
                    Local time: C  2020-01-23 12:35:50 EET
                Universal time: C  2020-01-23 10:35:50 UTC
    @@ -110,4 +110,4 @@ there is an error. Feel free to adjust the curl options to suit your needs.

    System clock synchronized: yes NTP service: active RTC in local TZ: no -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/templates/docs/php.html b/templates/docs/php.html index 0901a278..b7c3bfbe 100644 --- a/templates/docs/php.html +++ b/templates/docs/php.html @@ -1,4 +1,4 @@

    PHP

    Below is an example of making a HTTP request to SITE_NAME from PHP.

    -
    file_get_contents('https://hc-ping.com/your-uuid-here');
    -
    \ No newline at end of file +
    file_get_contents('https://hc-ping.com/your-uuid-here');
    +
    \ No newline at end of file diff --git a/templates/docs/powershell.html b/templates/docs/powershell.html index f14dfe4b..65156c33 100644 --- a/templates/docs/powershell.html +++ b/templates/docs/powershell.html @@ -5,19 +5,19 @@

    Here is a simple PowerShell script that pings SITE_NAME. When scheduled to run with Task Scheduler, it will essentially just send regular "I'm alive" messages. You can of course extend it to do more things.

    -
    # inside a PowerShell script:
    +
    # inside a PowerShell script:
     Invoke-RestMethod PING_URL
    -
    +

    Save the above to e.g. C:\Scripts\healthchecks.ps1. Then use the following command in a Scheduled Task to run the script:

    -
    powershell.exe -ExecutionPolicy bypass -File C:\Scripts\healthchecks.ps1
    -
    +
    powershell.exe -ExecutionPolicy bypass -File C:\Scripts\healthchecks.ps1
    +

    In simple cases, you can also pass the script to PowerShell directly, using the "-command" argument:

    -
    # Without an underlying script, passing the command to PowerShell directly:
    +
    # Without an underlying script, passing the command to PowerShell directly:
     powershell.exe -command &{Invoke-RestMethod PING_URL}
    -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/templates/docs/python.html b/templates/docs/python.html index f5ff16b1..be16fdc0 100644 --- a/templates/docs/python.html +++ b/templates/docs/python.html @@ -1,26 +1,26 @@

    Python

    If you are already using the requests library, it's convenient to also use it here:

    -
    # using requests:
    +
    # using requests:
     import requests
     requests.get("PING_URL")
    -
    +

    Otherwise, you can use the urllib standard module.

    -
    # urllib with python 3.x:
    +
    # urllib with python 3.x:
     import urllib.request
     urllib.request.urlopen("PING_URL")
    -
    +
    -
    # urllib with python 2.x:
    +
    # urllib with python 2.x:
     import urllib
     urllib.urlopen("PING_URL")
    -
    +

    You can include additional diagnostic information in the in the request body (for POST requests):

    -
    # Passing diagnostic information in the POST body:
    +
    # Passing diagnostic information in the POST body:
     import requests
     requests.post("PING_URL", data="temperature=-7")
    -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/templates/docs/ruby.html b/templates/docs/ruby.html index e73e6b57..25070483 100644 --- a/templates/docs/ruby.html +++ b/templates/docs/ruby.html @@ -1,7 +1,7 @@

    Ruby

    Below is an example of making a HTTP request to SITE_NAME from Ruby.

    -
    require 'net/http'
    +
    require 'net/http'
     require 'uri'
     
     Net::HTTP.get(URI.parse('PING_URL'))
    -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/templates/docs/signalling_failures.html b/templates/docs/signalling_failures.html index fdd9a180..f5161d74 100644 --- a/templates/docs/signalling_failures.html +++ b/templates/docs/signalling_failures.html @@ -6,7 +6,7 @@ to you getting a notification.

    Shell Scripts

    The below shell script sends either a "success" or "failure" ping depending on command's (certbot in this example) exit code:

    -
    #!/bin/sh
    +
    #!/bin/sh
     
     url=PING_URL
     
    @@ -14,26 +14,26 @@ command's (certbot in this example) exit code:

    if [ $? -ne 0 ]; then url=$url/fail; fi curl --retry 3 $url -
    +

    Python

    Below is a skeleton code example in Python which signals a failure when the work function returns an unexpected value or throws an exception:

    -
    import requests
    +
    import requests
     URL = "PING_URL"
     
     def do_work():
         # Do your number crunching, backup dumping, newsletter sending work here.
         # Return a truthy value on success.
         # Return a falsy value or throw an exception on failure.
    -    return True
    +    return True
     
    -success = False
    +success = False
     try:
         success = do_work()
     finally:
         # On success, requests PING_URL
         # On failure, requests PING_URL/fail
         requests.get(URL if success else URL + "/fail")
    -
    \ No newline at end of file +
    \ No newline at end of file