192 lines
6.8 KiB
Python
192 lines
6.8 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Post new SbaPlayer records to production API
|
|
"""
|
|
|
|
import csv
|
|
import json
|
|
import requests
|
|
import logging
|
|
import os
|
|
import argparse
|
|
from typing import Dict, List, Optional
|
|
|
|
# Set up logging
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
|
handlers=[
|
|
logging.FileHandler('matching.log'),
|
|
logging.StreamHandler()
|
|
]
|
|
)
|
|
logger = logging.getLogger(f'{__name__}.post_new_sbaplayers')
|
|
|
|
# Production API configuration
|
|
API_BASE_URL = "https://api.sba.manticorum.com"
|
|
SBAPLAYERS_ENDPOINT = f"{API_BASE_URL}/sbaplayers"
|
|
|
|
def get_api_token(token_arg=None):
|
|
"""Get API token from argument, environment, or prompt user"""
|
|
if token_arg:
|
|
return token_arg
|
|
|
|
api_token = os.getenv('API_TOKEN')
|
|
if not api_token:
|
|
print("API_TOKEN environment variable not found.")
|
|
api_token = input("Please enter your API token: ").strip()
|
|
return api_token
|
|
|
|
def load_new_sbaplayers():
|
|
"""Load new SbaPlayer records from CSV file"""
|
|
new_players = []
|
|
|
|
logger.info("Loading new SbaPlayers from new_sbaplayers_to_insert.csv...")
|
|
|
|
with open('./new_sbaplayers_to_insert.csv', 'r') as f:
|
|
reader = csv.DictReader(f)
|
|
for row in reader:
|
|
# Convert CSV row to API format
|
|
player = {
|
|
"first_name": row['first_name'],
|
|
"last_name": row['last_name'],
|
|
"key_bbref": row['key_bbref'] if row['key_bbref'] else None,
|
|
"key_fangraphs": None, # We don't have fangraphs IDs
|
|
"key_mlbam": None, # We don't have MLBAM IDs
|
|
"key_retro": None # We don't have retro IDs
|
|
}
|
|
new_players.append(player)
|
|
|
|
logger.info(f"Loaded {len(new_players)} new SbaPlayer records")
|
|
return new_players
|
|
|
|
def post_sbaplayers_bulk(players: List[Dict], api_token: str) -> bool:
|
|
"""Post multiple SbaPlayers via bulk endpoint"""
|
|
|
|
payload = {
|
|
"players": players
|
|
}
|
|
|
|
headers = {
|
|
"Authorization": f"Bearer {api_token}",
|
|
"Content-Type": "application/json"
|
|
}
|
|
|
|
logger.info(f"Posting {len(players)} new SbaPlayers to {SBAPLAYERS_ENDPOINT}...")
|
|
|
|
try:
|
|
response = requests.post(SBAPLAYERS_ENDPOINT, json=payload, headers=headers, timeout=30)
|
|
|
|
if response.status_code == 200:
|
|
logger.info(f"✅ SUCCESS: {response.text}")
|
|
return True
|
|
else:
|
|
logger.error(f"❌ API Error {response.status_code}: {response.text}")
|
|
return False
|
|
|
|
except requests.exceptions.RequestException as e:
|
|
logger.error(f"❌ Request failed: {e}")
|
|
return False
|
|
|
|
def verify_posted_players(players: List[Dict], api_token: str):
|
|
"""Verify that the posted players exist in the database"""
|
|
|
|
headers = {
|
|
"Authorization": f"Bearer {api_token}",
|
|
"Content-Type": "application/json"
|
|
}
|
|
|
|
logger.info("Verifying posted players...")
|
|
|
|
for player in players:
|
|
full_name = f"{player['first_name']} {player['last_name']}"
|
|
|
|
# Search by full name
|
|
params = {"full_name": [full_name]}
|
|
|
|
try:
|
|
response = requests.get(SBAPLAYERS_ENDPOINT, params=params, headers=headers, timeout=10)
|
|
|
|
if response.status_code == 200:
|
|
data = response.json()
|
|
if data['count'] > 0:
|
|
sba_player = data['players'][0]
|
|
logger.info(f"✅ Verified: {full_name} -> SbaPlayer ID {sba_player['id']}")
|
|
else:
|
|
logger.warning(f"⚠️ Not found: {full_name}")
|
|
else:
|
|
logger.error(f"❌ Verification failed for {full_name}: {response.status_code}")
|
|
|
|
except requests.exceptions.RequestException as e:
|
|
logger.error(f"❌ Verification request failed for {full_name}: {e}")
|
|
|
|
def main():
|
|
"""Main execution function"""
|
|
parser = argparse.ArgumentParser(description='Post new SbaPlayer records to production API')
|
|
parser.add_argument('--token', help='API token for authentication')
|
|
parser.add_argument('--confirm', action='store_true', help='Skip confirmation prompt')
|
|
parser.add_argument('--dry-run', action='store_true', help='Show what would be posted without actually posting')
|
|
|
|
args = parser.parse_args()
|
|
|
|
logger.info("Starting SbaPlayer creation process...")
|
|
|
|
try:
|
|
# Load new players
|
|
new_players = load_new_sbaplayers()
|
|
|
|
if not new_players:
|
|
logger.warning("No new players to post. Exiting.")
|
|
return
|
|
|
|
# Show preview
|
|
print(f"\n📋 PREVIEW: About to create {len(new_players)} new SbaPlayer records:")
|
|
for i, player in enumerate(new_players, 1):
|
|
bbref_info = f" (bbref: {player['key_bbref']})" if player['key_bbref'] else ""
|
|
print(f" {i:2d}. {player['first_name']} {player['last_name']}{bbref_info}")
|
|
|
|
if args.dry_run:
|
|
print(f"\n🧪 DRY RUN: Would create {len(new_players)} new SbaPlayer records")
|
|
print("JSON payload preview:")
|
|
print(json.dumps({"players": new_players[:3]}, indent=2))
|
|
if len(new_players) > 3:
|
|
print(f"... and {len(new_players) - 3} more players")
|
|
return
|
|
|
|
# Get API token (only needed for actual posting)
|
|
api_token = get_api_token(args.token)
|
|
if not api_token:
|
|
logger.error("No API token provided. Exiting.")
|
|
return
|
|
|
|
# Confirm with user (unless --confirm flag is used)
|
|
if not args.confirm:
|
|
print(f"\n🚨 WARNING: This will create {len(new_players)} new records in the PRODUCTION database!")
|
|
confirm = input("Are you sure you want to proceed? (yes/no): ").strip().lower()
|
|
|
|
if confirm not in ['yes', 'y']:
|
|
logger.info("User cancelled. No records created.")
|
|
return
|
|
|
|
# Bulk insert
|
|
logger.info("Posting via bulk endpoint...")
|
|
success = post_sbaplayers_bulk(new_players, api_token)
|
|
|
|
if success:
|
|
logger.info("✅ Bulk insert completed successfully!")
|
|
|
|
# Verify the results
|
|
print(f"\n🔍 Verifying created players...")
|
|
verify_posted_players(new_players, api_token)
|
|
else:
|
|
logger.error("❌ Bulk insert failed. Check the error messages above.")
|
|
|
|
logger.info("✅ SbaPlayer creation process completed!")
|
|
print(f"\n🎉 Process completed! Check the logs above for results.")
|
|
|
|
except Exception as e:
|
|
logger.error(f"Unexpected error: {e}")
|
|
raise
|
|
|
|
if __name__ == "__main__":
|
|
main() |