I wrote a Flask app to update MTG formats automatically. It’s supposed to update only once 14 days after a Standard-legal set release. I save the latest updated set in a JSON file and check both the last update timestamp and the latest set name before updating again.
I originally thought Flask’s auto-reloader was causing the updates to run multiple times, so I added this check to app.py:
if __name__ == "__main__" and os.environ.get("WERKZEUG_RUN_MAIN") == "true":
update_formats_if_needed()
Here’s the relevant part of my update logic:
import os
import json
import requests
import subprocess
from datetime import datetime, timezone, timedelta
from shared.configuration import LAST_UPDATED_FILE, WIS_SETS_API, UPDATE_THRESHOLD_DAYS
def fetch_sets_data():
response = requests.get(WIS_SETS_API)
response.raise_for_status()
return response.json()["sets"]
def load_saved_update(file_path=LAST_UPDATED_FILE):
"""Return a dict with 'updated_at' (datetime) and 'latest_set' (str)"""
if os.path.exists(file_path):
with open(file_path, "r") as f:
data = json.load(f)
updated_at = datetime.fromisoformat(data.get("updated_at"))
latest_set = data.get("latest_set")
return {"updated_at": updated_at, "latest_set": latest_set}
return {"updated_at": None, "latest_set": None}
def save_update(updated_at, latest_set, file_path=LAST_UPDATED_FILE):
with open(file_path, "w") as f:
json.dump({"updated_at": updated_at.isoformat(), "latest_set": latest_set}, f)
def check_for_update(latest_set_name, latest_updated_at, saved_data):
now = datetime.now(timezone.utc)
saved_updated_at = saved_data["updated_at"]
saved_set_name = saved_data["latest_set"]
# Update if no previous update
if saved_updated_at is None:
return True
# Update if set changed
if latest_set_name != saved_set_name:
return True
# Update if threshold of days exceeded
if now - saved_updated_at >= timedelta(days=UPDATE_THRESHOLD_DAYS):
return True
return False
def git_commit_push():
try:
subprocess.run(["git", "add", "."], check=True)
subprocess.run(["git", "commit", "-m", "Auto-update MTG formats"], check=True)
subprocess.run(["git", "push"], check=True)
print("Changes committed and pushed to remote.")
except subprocess.CalledProcessError:
print("No changes to commit or git error.")
def update_formats_if_needed():
now = datetime.now(timezone.utc)
sets = fetch_sets_data()
released_sets = [
s
for s in sets
if s.get("enterDate", {}).get("exact")
and datetime.fromisoformat(s["enterDate"]["exact"]).replace(tzinfo=timezone.utc)
<= now
]
if not released_sets:
print("No sets released yet")
return
latest_set = max(
released_sets,
key=lambda s: datetime.fromisoformat(s["enterDate"]["exact"]).replace(
tzinfo=timezone.utc
),
)
latest_updated_at = datetime.fromisoformat(
latest_set["enterDate"]["exact"]
).replace(tzinfo=timezone.utc)
saved_data = load_saved_update()
if check_for_update(latest_set["name"], latest_updated_at, saved_data):
print(f"Updating to latest released set: {latest_set['name']}")
os.system("python -m scripts.build_format_jsons")
os.system("python -m scripts.build_filtered_formats")
os.system("python -m scripts.build_heirloom_format")
save_update(latest_updated_at, latest_set["name"])
git_commit_push()
else:
print(f"No update needed. Latest applied set: {saved_data['latest_set']}")
if __name__ == "__main__":
update_formats_if_needed()
But whenever I run python app.py, the updates run again and again, even though the JSON file correctly stores the last updated set and timestamp.
Why might the app still update repeatedly instead of respecting the 14-day threshold? Could this be related to Flask’s debug mode or the way I’m calling these three similar scripts?
os.system("python -m scripts.build_format_jsons")
os.system("python -m scripts.build_filtered_formats")
os.system("python -m scripts.build_heirloom_format")
Thanks in advance!