From b204c42d6ba6fcab1c40829c248f9bccc6a2b47b Mon Sep 17 00:00:00 2001 From: Jerry Date: Tue, 19 Nov 2024 13:59:33 -0500 Subject: [PATCH] Pylint --- app/app.py | 5 ++-- app/auth/__init__.py | 11 --------- app/auth/auth_utils.py | 17 +++++++++----- app/auth/routes.py | 8 ++++--- app/models.py | 7 ++++-- app/scout/TBA.py | 29 +++++++++++++++++------ app/scout/__init__.py | 7 ------ app/scout/routes.py | 46 ++++++++++++++++++++++++++----------- app/scout/scouting_utils.py | 22 ++++++++++++------ 9 files changed, 93 insertions(+), 59 deletions(-) delete mode 100644 app/auth/__init__.py delete mode 100644 app/scout/__init__.py diff --git a/app/app.py b/app/app.py index f4be39d..9fcd816 100644 --- a/app/app.py +++ b/app/app.py @@ -1,4 +1,3 @@ -from bson import ObjectId from flask import Flask, render_template from flask_login import LoginManager from flask_pymongo import PyMongo @@ -21,7 +20,9 @@ def create_app(): SECRET_KEY=os.getenv("SECRET_KEY", "team334"), SESSION_COOKIE_HTTPONLY=True, SESSION_COOKIE_SECURE=True, - MONGO_URI=os.getenv("MONGO_URI", "mongodb://localhost:27017/scouting_app"), + MONGO_URI=os.getenv( + "MONGO_URI", "mongodb://localhost:27017/scouting_app" + ), ) mongo.init_app(app) diff --git a/app/auth/__init__.py b/app/auth/__init__.py deleted file mode 100644 index e6b7574..0000000 --- a/app/auth/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -from .auth_utils import * -from .routes import * - - -all = [ - "check_password_strength", - "require_admin", - "UserManager", - "init_auth_routes", - "auth_bp", -] diff --git a/app/auth/auth_utils.py b/app/auth/auth_utils.py index 86e3843..433d123 100644 --- a/app/auth/auth_utils.py +++ b/app/auth/auth_utils.py @@ -23,11 +23,12 @@ async def wrapper(*args, **kwargs): last_error = e if attempt < retries - 1: # don't sleep on last attempt logger.warning( - f"Attempt {attempt + 1} failed: {str(e)}. Retrying..." + f"Attempt {attempt + 1} failed: {str(e)}." ) time.sleep(delay) else: - logger.error(f"All {retries} attempts failed: {str(e)}") + logger.error( + f"All {retries} attempts failed: {str(e)}") raise last_error return wrapper @@ -56,7 +57,8 @@ def connect(self): """Establish connection to MongoDB with basic error handling""" try: if self.client is None: - self.client = MongoClient(self.mongo_uri, serverSelectionTimeoutMS=5000) + self.client = MongoClient( + self.mongo_uri, serverSelectionTimeoutMS=5000) # Test the connection self.client.server_info() self.db = self.client.get_default_database() @@ -79,11 +81,14 @@ def ensure_connected(self): # Test if connection is still alive self.client.server_info() except Exception: - logger.warning("Lost connection to MongoDB, attempting to reconnect...") + logger.warning( + "Lost connection to MongoDB, attempting to reconnect...") self.connect() @with_mongodb_retry(retries=3, delay=2) - async def create_user(self, email, username, password, team_number, role="user"): + async def create_user( + self, email, username, password, team_number, + role="user"): """Create a new user with retry mechanism""" self.ensure_connected() try: @@ -111,7 +116,7 @@ async def create_user(self, email, username, password, team_number, role="user") "last_login": None, } - result = self.db.users.insert_one(user_data) + self.db.users.insert_one(user_data) logger.info(f"Created new user: {username}") return True, "User created successfully" diff --git a/app/auth/routes.py b/app/auth/routes.py index c6919f1..7ed5404 100644 --- a/app/auth/routes.py +++ b/app/auth/routes.py @@ -1,6 +1,5 @@ from flask import ( Blueprint, - current_app, render_template, redirect, url_for, @@ -59,7 +58,8 @@ async def login(): return render_template("auth/login.html", form_data=form_data) try: - success, user = await user_manager.authenticate_user(login, password) + success, user = await user_manager.authenticate_user( + login, password) if success and user: login_user(user, remember=remember) next_page = request.args.get("next") @@ -89,7 +89,9 @@ async def register(): confirm_password = request.form.get("confirm_password", "").strip() team_number = request.form.get("teamNumber", 0) - form_data = {"email": email, "username": username, "team_number": team_number} + form_data = { + "email": email, "username": username, "team_number": team_number + } if not all([email, username, password, confirm_password]): flash("All fields are required", "error") diff --git a/app/models.py b/app/models.py index 69283e7..c588b62 100644 --- a/app/models.py +++ b/app/models.py @@ -18,7 +18,8 @@ def get_id(self): try: return str(self._id) except AttributeError as e: - raise NotImplementedError("No `_id` attribute - override `get_id`") from e + raise NotImplementedError( + "No `_id` attribute - override `get_id`") from e def is_authenticated(self): return True @@ -92,7 +93,9 @@ def create_from_db(data): data["_id"] = ObjectId(data["_id"]) # Ensure scouter_id is ObjectId - if "scouter_id" in data and not isinstance(data["scouter_id"], ObjectId): + if "scouter_id" in data and not isinstance( + data["scouter_id"], ObjectId + ): data["scouter_id"] = ObjectId(data["scouter_id"]) return TeamData(data) diff --git a/app/scout/TBA.py b/app/scout/TBA.py index ab77fb6..2007449 100644 --- a/app/scout/TBA.py +++ b/app/scout/TBA.py @@ -1,9 +1,16 @@ import aiohttp import asyncio +import os from typing import Optional, List, Dict from dataclasses import dataclass +from dotenv import load_dotenv -from flask import jsonify +load_dotenv() + +""" +Credits to PAWNAGERobitics for the original code: +https://github.com/PWNAGERobotics/ScoutingPASS/blob/main/resources/js/TBAInterface.js +""" @dataclass @@ -12,7 +19,7 @@ class TBAInterface: def __init__( self, - auth_key: str = "uTHeEfPigDp9huQCpLNkWK7FBQIb01Qrzvt4MAjh9z2WQDkrsvNE77ch6bOPvPb6", + auth_key: str = os.getenv("TBA_AUTH_KEY"), ): self.auth_key = auth_key self.base_url = "https://www.thebluealliance.com/api/v3" @@ -31,12 +38,15 @@ async def __aexit__(self, exc_type, exc_val, exc_tb): if self.session: await self.session.close() - async def get_teams_at_event(self, event_code: str) -> Optional[List[Dict]]: + async def get_teams_at_event( + self, event_code: str + ) -> Optional[List[Dict]]: """ Get list of teams in event Args: - event_code (str): The event code (i.e. 2020caln) to pull the team list + event_code (str): The event code (i.e. 2020caln) to pull + the team list Returns: Optional[List[Dict]]: List of team data or None if request fails @@ -63,7 +73,8 @@ async def get_schedule(self, event_code: str) -> Optional[List[Dict]]: Get schedule for event Args: - event_code (str): The event code (i.e. 2020caln) to pull the schedule + event_code (str): The event code (i.e. 2020caln) + to pull the schedule Returns: Optional[List[Dict]]: List of match data or None if request fails @@ -95,10 +106,14 @@ async def get_event_data( event_code (str): The event code (i.e. 2020caln) Returns: - tuple[Optional[List[Dict]], Optional[List[Dict]]]: Tuple of (teams, schedule) data + tuple[ + Optional[List[Dict]], + Optional[List[Dict]] + ]: Tuple of (teams, schedule) data """ async with self: - teams_task = asyncio.create_task(self.get_teams_at_event(event_code)) + teams_task = asyncio.create_task( + self.get_teams_at_event(event_code)) schedule_task = asyncio.create_task(self.get_schedule(event_code)) teams, schedule = await asyncio.gather(teams_task, schedule_task) diff --git a/app/scout/__init__.py b/app/scout/__init__.py deleted file mode 100644 index 0fa35eb..0000000 --- a/app/scout/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from .routes import * -from .TBA import * - -__all__ = [ - "scouting_bp", - "TBA", -] diff --git a/app/scout/routes.py b/app/scout/routes.py index f8642af..aba3dcd 100644 --- a/app/scout/routes.py +++ b/app/scout/routes.py @@ -1,9 +1,10 @@ import asyncio from functools import wraps import aiohttp -from flask import Blueprint, flash, render_template, request, redirect, url_for, jsonify +from flask import ( + Blueprint, flash, render_template, request, redirect, url_for, jsonify +) from flask_login import login_required, current_user -from datetime import datetime, timezone from scout.scouting_utils import ScoutingManager from .TBA import TBAInterface @@ -67,7 +68,8 @@ def edit_scouting_data(id): if not team_data: flash( - "Team data not found or you do not have permission to edit it", "error" + "Team data not found or you do not have permission to edit it", + "error" ) return redirect(url_for("scouting.list_scouting_data")) @@ -131,7 +133,8 @@ async def compare_teams(): async with aiohttp.ClientSession(headers=tba.headers) as session: async with session.get(url) as response: if response.status != 200: - return jsonify({"error": f"Team {team_num} not found"}), 404 + return jsonify( + {"error": f"Team {team_num} not found"}), 404 team = await response.json() # Fetch all scouting data for this team from MongoDB @@ -148,25 +151,39 @@ async def compare_teams(): {"$unwind": "$scouter"}, ] - team_scouting_data = list(scouting_manager.db.team_data.aggregate(pipeline)) + team_scouting_data = list( + scouting_manager.db.team_data.aggregate(pipeline)) # Calculate statistics - auto_points = [entry["auto_points"] for entry in team_scouting_data] - teleop_points = [entry["teleop_points"] for entry in team_scouting_data] - endgame_points = [entry["endgame_points"] for entry in team_scouting_data] - total_points = [entry["total_points"] for entry in team_scouting_data] + auto_points = [ + entry["auto_points"] for entry in team_scouting_data + ] + teleop_points = [ + entry["teleop_points"] for entry in team_scouting_data + ] + endgame_points = [ + entry["endgame_points"] for entry in team_scouting_data + ] + total_points = [ + entry["total_points"] for entry in team_scouting_data + ] stats = { "matches_played": len(team_scouting_data), - "avg_auto": (sum(auto_points) / len(auto_points) if auto_points else 0), + "avg_auto": ( + sum(auto_points) / len(auto_points) if auto_points else 0 + ), "avg_teleop": ( - sum(teleop_points) / len(teleop_points) if teleop_points else 0 + sum(teleop_points) / len(teleop_points) + if teleop_points else 0 ), "avg_endgame": ( - sum(endgame_points) / len(endgame_points) if endgame_points else 0 + sum(endgame_points) / len(endgame_points) + if endgame_points else 0 ), "avg_total": ( - sum(total_points) / len(total_points) if total_points else 0 + sum(total_points) / len(total_points) + if total_points else 0 ), "max_total": max(total_points, default=0), "min_total": min(total_points, default=0), @@ -243,7 +260,8 @@ async def search_teams(): {"$unwind": "$scouter"}, ] - team_scouting_data = list(scouting_manager.db.team_data.aggregate(pipeline)) + team_scouting_data = list( + scouting_manager.db.team_data.aggregate(pipeline)) scouting_entries = [ { diff --git a/app/scout/scouting_utils.py b/app/scout/scouting_utils.py index 44afe88..82d0eab 100644 --- a/app/scout/scouting_utils.py +++ b/app/scout/scouting_utils.py @@ -22,11 +22,12 @@ def wrapper(*args, **kwargs): last_error = e if attempt < retries - 1: logger.warning( - f"Attempt {attempt + 1} failed: {str(e)}. Retrying..." + f"Attempt {attempt + 1} failed: {str(e)}." ) time.sleep(delay) else: - logger.error(f"All {retries} attempts failed: {str(e)}") + logger.error( + f"All {retries} attempts failed: {str(e)}") raise last_error return wrapper @@ -45,7 +46,8 @@ def connect(self): """Establish connection to MongoDB with basic error handling""" try: if self.client is None: - self.client = MongoClient(self.mongo_uri, serverSelectionTimeoutMS=5000) + self.client = MongoClient(self.mongo_uri, + serverSelectionTimeoutMS=5000) # Test the connection self.client.server_info() self.db = self.client.get_default_database() @@ -71,7 +73,8 @@ def ensure_connected(self): # Test if connection is still alive self.client.server_info() except Exception: - logger.warning("Lost connection to MongoDB, attempting to reconnect...") + logger.warning( + "Lost connection to MongoDB, attempting to reconnect.") self.connect() @with_mongodb_retry(retries=3, delay=2) @@ -96,7 +99,7 @@ def add_scouting_data(self, data, scouter_id): "created_at": datetime.now(timezone.utc), } - result = self.db.team_data.insert_one(team_data) + self.db.team_data.insert_one(team_data) logger.info( f"Added new scouting data for team { data['team_number']}" @@ -120,7 +123,11 @@ def get_all_scouting_data(self): "as": "scouter", } }, - {"$unwind": {"path": "$scouter", "preserveNullAndEmptyArrays": True}}, + {"$unwind": + {"path": "$scouter", + "preserveNullAndEmptyArrays": True + } + }, ] team_data = list(self.db.team_data.aggregate(pipeline)) @@ -144,7 +151,8 @@ def get_team_data(self, team_id, scouter_id=None): # Add an is_owner field to the response data["is_owner"] = ( - str(data["scouter_id"]) == str(scouter_id) if scouter_id else False + str(data["scouter_id"]) == str(scouter_id) + if scouter_id else False ) return TeamData.create_from_db(data) except Exception as e: