Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[flake8]
max-line-length = 120
extend-ignore = E402,F541,E203
exclude = env,venv,dist,build,__pycache__,*.pyc
1 change: 1 addition & 0 deletions .github/workflows/python-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ jobs:
SUPABASE_URL: "https://test.supabase.co"
SUPABASE_KEY: "test_key"
API_KEY: "test_api_key"
PYTHONPATH: "src"
run: |
pip install pytest pytest-mock
pytest src/tests/ --maxfail=3 --disable-warnings -v
23 changes: 23 additions & 0 deletions .github/workflows/weekly-database-refresh.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4

# Validate required repository secrets are available
- name: Validate required secrets
run: |
echo "Checking required repository secrets..."
if [ -z "${{ secrets.SUPABASE_URL }}" ] || [ -z "${{ secrets.SUPABASE_KEY }}" ] || [ -z "${{ secrets.API_KEY }}" ]; then
echo "ERROR: One or more required secrets are missing."
echo "Please add the following repository secrets: SUPABASE_URL, SUPABASE_KEY, API_KEY"
exit 1
fi

# Set up Python
- name: Set up Python
uses: actions/setup-python@v5
Expand Down Expand Up @@ -115,6 +125,19 @@ jobs:
print('⚠️ Database credentials not available for logging')
"

# Run unit tests to validate the codebase after refresh
- name: Run tests
env:
SUPABASE_URL: ${{ secrets.SUPABASE_URL }}
SUPABASE_KEY: ${{ secrets.SUPABASE_KEY }}
API_KEY: ${{ secrets.API_KEY }}
run: |
echo "Installing test dependencies..."
python -m pip install --upgrade pip
pip install pytest pytest-mock
echo "Running pytest..."
pytest src/tests/ --maxfail=1 -q

# Create success summary with timestamp
- name: Create success summary
if: success()
Expand Down
38 changes: 19 additions & 19 deletions check_weekly_refresh.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
def check_refresh_status():
"""Check the status of the weekly database refresh."""

print("🔍 Weekly Database Refresh Status Check")
print("Weekly Database Refresh Status Check")
print("=" * 50)

# 1. Check database refresh logs
Expand Down Expand Up @@ -53,16 +53,16 @@ def check_refresh_status():
status = log.get("status", "Unknown")
refresh_type = log.get("refresh_type", "Unknown")

status_icon = "" if status == "completed" else ""
print(f" {status_icon} {timestamp} - {refresh_type} - {status}")
status_label = "COMPLETED" if status == "completed" else "FAILED"
print(f" {status_label} {timestamp} - {refresh_type} - {status}")
else:
print(" ℹ️ No recent refresh logs found")
print(" INFO: No recent refresh logs found")

except Exception as e:
print(f" ⚠️ Could not fetch refresh logs: {e}")

# 2. Check data freshness
print("\n📅 Data Freshness Check:")
print("\nData Freshness Check:")
try:
# Check latest player performance data
latest_perf = (
Expand All @@ -75,7 +75,7 @@ def check_refresh_status():

if latest_perf.data:
latest_time = latest_perf.data[0]["created_at"]
print(f" 📈 Latest performance data: {latest_time}")
print(f" Latest performance data: {latest_time}")

# Check if data is recent (within last 3 days)
latest_dt = datetime.fromisoformat(latest_time.replace("Z", "+00:00"))
Expand All @@ -84,27 +84,27 @@ def check_refresh_status():
).days

if days_old <= 3:
print(f" Data is fresh ({days_old} days old)")
print(f" Data is fresh ({days_old} days old)")
else:
print(f" ⚠️ Data may be stale ({days_old} days old)")
print(f" WARNING: Data may be stale ({days_old} days old)")
else:
print(" No performance data found")
print(" ERROR: No performance data found")

except Exception as e:
print(f" ⚠️ Could not check data freshness: {e}")

# 3. Check current gameweek data
print("\n🎮 Current Gameweek Check:")
print("\nCurrent Gameweek Check:")
try:
current_gw = (
supabase.table("players").select("current_gameweek").limit(1).execute()
)

if current_gw.data and current_gw.data[0].get("current_gameweek"):
gw = current_gw.data[0]["current_gameweek"]
print(f" 🎯 Current gameweek: {gw}")
print(f" Current gameweek: {gw}")
else:
print(" ℹ️ Gameweek data not available")
print(" INFO: Gameweek data not available")

except Exception as e:
print(f" ⚠️ Could not check gameweek: {e}")
Expand All @@ -114,19 +114,19 @@ def check_refresh_status():
return False

# 4. Manual verification instructions
print("\n🔗 Manual Verification:")
print("\nManual Verification:")
print(
" 1. GitHub Actions: https://github.com/ritvikiscool9/fpl-predictor/actions"
)
print(" 2. Look for 'Weekly Database Refresh' workflows")
print(" 3. Check for green checkmarks ✅ indicating success")
print(" 4. Review logs if any runs show red X ❌")
print(" 3. Check for successful runs indicating success")
print(" 4. Review logs if any runs show failures")

print("\n💡 Next Steps:")
print(" If no recent refresh: Check GitHub Actions for failures")
print(" If data is stale: Run manual refresh with:")
print("\nNext Steps:")
print(" - If no recent refresh: Check GitHub Actions for failures")
print(" - If data is stale: Run manual refresh with:")
print(" python src/database/fast_performance_refresh.py")
print(" If errors persist: Check Supabase credentials and API limits")
print(" - If errors persist: Check Supabase credentials and API limits")

return True

Expand Down
14 changes: 8 additions & 6 deletions src/ai/data_loader.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import pandas as pd
import numpy as np
from typing import Dict, List, Tuple
from supabase import create_client, Client
from typing import List, Tuple
from supabase import create_client
from dotenv import load_dotenv
import os

Expand Down Expand Up @@ -251,9 +250,12 @@ def load_current_team_stats(self) -> pd.DataFrame:
def test_connection(self):
"""Test supabase connection"""
try:
response = self.supabase.table("players").select("*").limit(1).execute()
print("connected to supabase")
return True
resp = self.supabase.table("players").select("*").limit(1).execute()
if resp and getattr(resp, "data", None):
print("connected to supabase")
return True
print("No response from supabase test query")
return False
except Exception as e:
print(f"Connection failed: {e}")
return False
Expand Down
2 changes: 0 additions & 2 deletions src/ai/feature_engineering.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
"""

import pandas as pd
import numpy as np
from typing import List, Dict
import sys
import os

Expand Down
44 changes: 22 additions & 22 deletions src/database/analyze_performance_gaps.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@

def analyze_player_performances_gaps():
"""Analyze what gameweeks are missing in player_performances"""
print("🔍 Analyzing player_performances data gaps...")
print("Analyzing player_performances data gaps...")
print("=" * 60)

try:
# Get all player performances
result = supabase.table("player_performances").select("gameweek_id").execute()

if not result.data:
print(" No player_performances data found!")
print("ERROR: No player_performances data found!")
return

df = pd.DataFrame(result.data)
Expand All @@ -33,12 +33,12 @@ def analyze_player_performances_gaps():
gameweeks_present = sorted(df["gameweek_id"].unique())
total_records = len(df)

print(f"📊 Total records: {total_records:,}")
print(f"🎯 Gameweeks with data: {gameweeks_present}")
print(f"Total records: {total_records:,}")
print(f"Gameweeks with data: {gameweeks_present}")

# Count records per gameweek
gw_counts = df["gameweek_id"].value_counts().sort_index()
print(f"\n📈 Records per gameweek:")
print(f"\nRecords per gameweek:")
for gw, count in gw_counts.items():
print(f" GW {gw}: {count:,} records")

Expand All @@ -48,9 +48,9 @@ def analyze_player_performances_gaps():
missing_gws = [gw for gw in expected_gws if gw not in gameweeks_present]

if missing_gws:
print(f"\n⚠️ Missing gameweeks: {missing_gws}")
print(f"\nMissing gameweeks: {missing_gws}")
else:
print(f"\n✅ All gameweeks 1-{max(gameweeks_present)} are present")
print(f"\nAll gameweeks 1-{max(gameweeks_present)} are present")

# Check for consistency
if len(gw_counts) > 1:
Expand All @@ -62,21 +62,21 @@ def analyze_player_performances_gaps():
inconsistent_gws.append(f"GW{gw}({count})")

if inconsistent_gws:
print(f"\n⚠️ Gameweeks with low record counts: {inconsistent_gws}")
print(f"\nGameweeks with low record counts: {inconsistent_gws}")
print(f" Average records per GW: {avg_records:.0f}")

return gameweeks_present, gw_counts.to_dict()

except Exception as e:
print(f" Error analyzing data: {e}")
print(f"ERROR: Error analyzing data: {e}")
return None, None


def check_fpl_api_availability():
"""Check what gameweeks are available from FPL API"""
import requests

print(f"\n🌐 Checking FPL API availability...")
print(f"\nChecking FPL API availability...")

try:
# Get current season info
Expand All @@ -91,8 +91,8 @@ def check_fpl_api_availability():
(gw["id"] for gw in data["events"] if gw.get("is_current", False)), None
)

print(f"Finished gameweeks available: {finished_gws}")
print(f"📍 Current gameweek: {current_gw}")
print(f"Finished gameweeks available: {finished_gws}")
print(f"Current gameweek: {current_gw}")

# Test API access for a specific gameweek
if finished_gws:
Expand All @@ -104,22 +104,22 @@ def check_fpl_api_availability():
test_data = test_response.json()
player_count = len(test_data.get("elements", []))
print(
f"API test successful - GW{test_gw} has {player_count} player records"
f"API test successful - GW{test_gw} has {player_count} player records"
)
else:
print(
f"⚠️ API test failed for GW{test_gw}: HTTP {test_response.status_code}"
f"API test failed for GW{test_gw}: HTTP {test_response.status_code}"
)

return finished_gws, current_gw

except Exception as e:
print(f" Error checking FPL API: {e}")
print(f"ERROR: Error checking FPL API: {e}")
return None, None


def main():
print("🏆 FPL Database - Player Performances Gap Analysis")
print("FPL Database - Player Performances Gap Analysis")
print("=" * 70)

# Analyze current database
Expand All @@ -132,17 +132,17 @@ def main():
if db_gameweeks and api_gameweeks:
missing_from_db = [gw for gw in api_gameweeks if gw not in db_gameweeks]

print(f"\n🎯 RECOMMENDATION:")
print(f"\nRECOMMENDATION:")
if missing_from_db:
print(f" ⚠️ Your database is missing data for: {missing_from_db}")
print(f" 💡 Run: echo 3 | python database_refresh.py")
print(f" Your database is missing data for: {missing_from_db}")
print(f" TIP: Run: echo 3 | python database_refresh.py")
print(f" This will populate all missing gameweeks")
else:
print(f" Your database has all available gameweeks!")
print(f" Your database has all available gameweeks!")

if db_counts and len(set(db_counts.values())) > 1:
print(f" ⚠️ Some gameweeks have inconsistent record counts")
print(f" 💡 Consider refreshing to ensure data quality")
print(f" Some gameweeks have inconsistent record counts")
print(f" TIP: Consider refreshing to ensure data quality")


if __name__ == "__main__":
Expand Down
Loading
Loading