Skip to content

Commit

Permalink
Merge pull request #5 from mattdonders/layers-triggers-invoke
Browse files Browse the repository at this point in the history
Version 1.1 - Cron & Logging Fixes
  • Loading branch information
mattdonders authored Sep 23, 2019
2 parents cad610f + d86553f commit 81b2201
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 56 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ ipython_config.py

# VSCode
.vscode
*.code-workspace

# pyenv
.python-version
Expand Down Expand Up @@ -125,3 +126,6 @@ dmypy.json

# Pyre type checker
.pyre/

# Config File (only commit sample)
config.yml
5 changes: 5 additions & 0 deletions config-sample.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
script:
scheduler_log_file: NHLShotmapsScheduler
trigger_log_file: NHLShotmapsLambda
slack_webhook:
aws_lambda_arn:
113 changes: 68 additions & 45 deletions lambda_trigger.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,24 @@
import argparse
import json
import logging
import os
import sys
import time
from datetime import datetime

import boto3
import dateutil.parser
import requests
import yaml
from crontab import CronTab
from dateutil import tz

SLEEP_TIME = 60
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
CONFIG_PATH = os.path.join(PROJECT_ROOT, "config.yml")
LOGS_PATH = os.path.join(PROJECT_ROOT, "logs")
LAMBDA_ARN = ""

# Setup basic logging functionality
logging.basicConfig(
level=logging.INFO,
datefmt="%Y-%m-%d %H:%M:%S",
format="%(asctime)s - %(module)s - %(levelname)s - %(message)s",
)


def parse_arguments():
parser = argparse.ArgumentParser()
parser.add_argument("--gameid", help="the nhl game id to check", action="store", required=True)
Expand All @@ -45,12 +42,12 @@ def get_intermission_info(livefeed):
return is_intermission, intermission_info


def trigger_lambda(game_id):
def trigger_lambda(game_id, lambda_arn):
logging.info("Triggering the AWS Shotmaps Lambda now!")
lambda_client = boto3.client("lambda")
payload = {"game_id": game_id, "testing": False}
invoke_response = lambda_client.invoke(
FunctionName=LAMBDA_ARN, InvocationType="RequestResponse", Payload=json.dumps(payload)
FunctionName=lambda_arn, InvocationType="RequestResponse", Payload=json.dumps(payload)
)

return invoke_response
Expand All @@ -60,41 +57,67 @@ def trigger_lambda(game_id):
args = parse_arguments()
game_id = args.gameid

# Load Configuration File
with open(CONFIG_PATH) as ymlfile:
config = yaml.load(ymlfile, Loader=yaml.FullLoader)

LAMBDA_ARN = config["script"]["aws_lambda_arn"]

# Setup basic logging functionality
log_file_name = datetime.now().strftime(config["script"]["trigger_log_file"] + "-" + game_id + ".log")
log_file = os.path.join(LOGS_PATH, log_file_name)
logging.basicConfig(
filename=log_file,
level=logging.INFO,
datefmt="%Y-%m-%d %H:%M:%S",
format="%(asctime)s - %(module)s - %(levelname)s - %(message)s",
)

# Loop over this until the game ends and we use sys.exit to complete.
while True:
# Get the livefeed & intermission information
livefeed = get_livefeed(game_id)

# Check game status
game_state = livefeed["gameData"]["status"]["abstractGameState"]

if game_state == "Final":
logging.info("Game is now final - send one final (end of game) shotmap & exit.")
lambda_response = trigger_lambda(game_id)
logging.info(lambda_response)
sys.exit()

period = livefeed["liveData"]["linescore"]["currentPeriod"]
period_ordinal = livefeed["liveData"]["linescore"]["currentPeriodOrdinal"]
period_remain = livefeed["liveData"]["linescore"]["currentPeriodTimeRemaining"]

is_intermission, intermission_info = get_intermission_info(livefeed)
if is_intermission:
lambda_response = trigger_lambda(game_id)
logging.info(lambda_response)

logging.info(
"Game is currently in intermission. Add 60 seconds to intermission time to avoid a re-trigger."
)
sleep_time = intermission_info["intermissionTimeRemaining"] + 60
logging.info("Sleeping for %s seconds now.", sleep_time)
time.sleep(sleep_time)
else:
logging.info(
"Not currently in intermission - %s remaining in the %s period.",
period_remain,
period_ordinal,
)

logging.info("-" * 60)
try:
# Get the livefeed & intermission information
livefeed = get_livefeed(game_id)

# Check game status
game_state = livefeed["gameData"]["status"]["abstractGameState"]

if game_state == "Final":
logging.info("Game is now final - send one final (end of game) shotmap & exit.")
lambda_response = trigger_lambda(game_id=game_id, lambda_arn=LAMBDA_ARN)
logging.info(lambda_response)
sys.exit()

if game_state == "Preview":
logging.info("Game is in Preview - sleep for designated game time before looping.")
time.sleep(SLEEP_TIME)
continue

period = livefeed["liveData"]["linescore"]["currentPeriod"]
period_ordinal = livefeed["liveData"]["linescore"]["currentPeriodOrdinal"]
period_remain = livefeed["liveData"]["linescore"]["currentPeriodTimeRemaining"]

is_intermission, intermission_info = get_intermission_info(livefeed)
if is_intermission:
lambda_response = trigger_lambda(game_id=game_id, lambda_arn=LAMBDA_ARN)
logging.info(lambda_response)

logging.info(
"Game is currently in intermission. Add 60 seconds to intermission time to avoid a re-trigger."
)
sleep_time = intermission_info["intermissionTimeRemaining"] + 60
logging.info("Sleeping for %s seconds now.", sleep_time)
time.sleep(sleep_time)
else:
logging.info(
"Not currently in intermission - %s remaining in the %s period.",
period_remain,
period_ordinal,
)

logging.info("-" * 60)
time.sleep(SLEEP_TIME)
except Exception as e:
logging.warning("Ran into an exception during this loop iteration - sleep & try again.")
logging.warning(e)
time.sleep(SLEEP_TIME)
43 changes: 32 additions & 11 deletions schedule_checker.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import json
import logging
import os
import sys
from datetime import datetime

import dateutil.parser
import requests
import yaml
from crontab import CronTab
from dateutil import tz

# Setup basic logging functionality
logging.basicConfig(
level=logging.INFO,
datefmt="%Y-%m-%d %H:%M:%S",
format="%(asctime)s - %(module)s - %(levelname)s - %(message)s",
)
PYTHON_EXEC = sys.executable
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
CONFIG_PATH = os.path.join(PROJECT_ROOT, "config.yml")
LOGS_PATH = os.path.join(PROJECT_ROOT, "logs")
from crontab import CronTab
from dateutil import tz

# Set UTZ & Local Timezones
from_zone = tz.tzutc()
Expand All @@ -27,12 +29,11 @@
cron.remove_all(comment="Lambda Shotmap Trigger")


def slack_webhook(icon, msg):
slack_url = ""
def slack_webhook(webhook_url, icon, msg):
slack_data = {"username": "shotmap cron scheduler", "icon_emoji": icon, "text": msg}

response = requests.post(
slack_url, data=json.dumps(slack_data), headers={"Content-Type": "application/json"}
webhook_url, data=json.dumps(slack_data), headers={"Content-Type": "application/json"}
)

if response.status_code != 200:
Expand All @@ -58,6 +59,21 @@ def is_game_today():


if __name__ == "__main__":

# Load Configuration File
with open(CONFIG_PATH) as ymlfile:
config = yaml.load(ymlfile, Loader=yaml.FullLoader)

# Setup basic logging functionality
log_file_name = datetime.now().strftime(config["script"]["scheduler_log_file"] + "-%Y%m%d%H%M%s.log")
log_file = os.path.join(LOGS_PATH, log_file_name)
logging.basicConfig(
filename=log_file,
level=logging.INFO,
datefmt="%Y-%m-%d %H:%M:%S",
format="%(asctime)s - %(module)s - %(levelname)s - %(message)s",
)

game_today, games = is_game_today()
if not game_today:
logging.info("No games scheduled today - nothing to setup via cron. Exiting now.")
Expand Down Expand Up @@ -85,12 +101,17 @@ def is_game_today():
game_id,
game_date_local_str,
)
cmd = f"python lambda_trigger.py --gameId={game_id}"

cmd = f"{PYTHON_EXEC} {PROJECT_ROOT}/lambda_trigger.py --gameid={game_id}"
job = cron.new(command=cmd, comment="Lambda Shotmap Trigger")
job.minute.on(minute)
job.hour.on(hour)
logging.info("CRON JOB: %s", job)

# print(cron)
slack_webhook(icon=":alarm_clock:", msg=f"Scheduling the following shotmap cron jobs today:\n{cron}")
slack_webhook(
webhook_url=config["script"]["slack_webhook"],
icon=":alarm_clock:",
msg=f"Scheduling the following shotmap cron jobs today:\n{cron}",
)
cron.write()

0 comments on commit 81b2201

Please sign in to comment.