Skip to content

Comments

feat: updated dependencies including FastAPI last performance improvement#381

Merged
TeKrop merged 2 commits intomainfrom
feature/update-dependencies
Feb 23, 2026
Merged

feat: updated dependencies including FastAPI last performance improvement#381
TeKrop merged 2 commits intomainfrom
feature/update-dependencies

Conversation

@TeKrop
Copy link
Owner

@TeKrop TeKrop commented Feb 23, 2026

Summary by Sourcery

Update URL parsing helpers and logging safety while bumping core dependencies and tooling versions.

Bug Fixes:

  • Harden URL-derived value parsing for ranks, endorsements, roles, tiers, and Blizzard IDs to better handle malformed or partial URLs.
  • Prevent logger frame-walking from crashing when no previous frame is available.
  • Ensure role parsing tolerates missing role icon URLs without failing.

Enhancements:

  • Simplify conditional assignment when storing player profile summaries.
  • Align string-splitting helpers with more robust path and extension handling across the codebase.

Build:

  • Bump runtime dependencies including FastAPI, aiosqlite, prometheus-client, pydantic-settings, sentry-sdk, and related packages.
  • Update Docker build to use a newer uv binary version.
  • Refresh uv.lock to reflect updated dependency versions.

CI:

  • Update ruff pre-commit hook to a newer release.

@TeKrop TeKrop self-assigned this Feb 23, 2026
@TeKrop TeKrop added the enhancement New feature or request label Feb 23, 2026
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Feb 23, 2026

Reviewer's Guide

Updates core dependencies (notably FastAPI, aiosqlite, prometheus-client, pydantic-settings, sentry-sdk, fakeredis, uv) and tightens several URL-parsing helpers and robustness checks to be more precise and defensive, plus minor code-style and logging safety tweaks.

Flow diagram for updated URL parsing helpers in players and roles modules

flowchart TD
    subgraph RankDivisionParsing
        A1["Input rank_url"] --> B1["Extract last path segment using rsplit('/', 1)"]
        B1 --> C1["Take part before first '-' using split('-', 1)"]
        C1 --> D1["Take part after last '_' using rsplit('_', 1)"]
        D1 --> E1["Remove last 4 characters (e.g. '.png') and lower()"]
        E1 --> F1["Construct CompetitiveDivision from normalized division name"]
    end

    subgraph EndorsementParsing
        A2["Input frame_url"] --> B2["Extract last path segment using rsplit('/', 1)"]
        B2 --> C2["Take part before first '-' using split('-', 1)"]
        C2 --> D2["Convert to int"]
        D2 -->|success| E2["Return endorsement level"]
        D2 -->|ValueError| F2["Return 0 as fallback"]
    end

    subgraph RoleKeyParsing
        A3["Input icon_url"] --> B3["Extract last path segment using rsplit('/', 1)"]
        B3 --> C3["Take part before first '-' using split('-', 1)"]
        C3 --> D3["Uppercase key"]
        D3 --> E3["Map OFFENSE to CompetitiveRole.DAMAGE"]
        D3 --> F3["Map TANK to CompetitiveRole.TANK"]
        D3 --> G3["Otherwise CompetitiveRole.SUPPORT"]
    end

    subgraph TierParsing
        A4["Input tier_url"] --> B4["Check if tier_url is None; if None return 0"]
        B4 -->|not None| C4["tier_url.split('/')[-1]"]
        C4 --> D4["Take part before first '-' using split('-', 1)"]
        D4 --> E4["Take part after last '_' using split('_')[-1]"]
        E4 --> F4["Convert to int"]
        F4 -->|success| G4["Return tier value"]
        F4 -->|IndexError or ValueError| H4["Return 0 as fallback"]
    end

    subgraph RoleIconHelper
        A5["Input role icon URL"] --> B5["Extract last path segment using rsplit('/', 1)"]
        B5 --> C5["Take part before first '.' using split('.', 1)"]
        C5 --> D5["Lowercase key"]
        D5 --> E5["Return role key name"]
    end
Loading

Flow diagram for updated roles HTML parsing with safer icon handling

flowchart TD
    A["parse_roles_html(html)"] --> B["Parse HTML document"]
    B --> C["Locate role headers and role icon URLs list roles_icons"]
    C --> D["For each role_index in headers"]

    D --> E["Select icon candidate: roles_icons[role_index] or ''"]
    E --> F["Call get_role_from_icon_url with non-None string"]
    F --> G["get_role_from_icon_url uses rsplit and split to extract key and lower()"]
    G --> H["Return role key"]

    D --> I["Extract role name from header h3 and capitalize"]
    D --> J["Extract role description div text"]
    D --> K["Read raw icon URL from roles_icons[role_index]"]

    H --> L["Build role dict: { key, name, icon, description }"]
    I --> L
    J --> L
    K --> L
    L --> M["Append role dict to roles list"]
    M --> N["After loop, return roles list"]
Loading

File-Level Changes

Change Details Files
Harden URL/asset parsing helpers to be more robust and precise.
  • Use rsplit with maxsplit=1 when extracting the last path segment from URLs to avoid over-splitting on earlier delimiters.
  • Tighten parsing of division, endorsement, and role keys from icon URLs using more explicit split boundaries and case handling.
  • Change string falsiness checks in parsers to pass empty strings safely into helper functions instead of None where needed.
app/players/helpers.py
app/adapters/blizzard/parsers/roles.py
app/roles/helpers.py
Relax grouped exception handling syntax to be compatible with Python 3.14 / updated tooling expectations.
  • Replace tuple-style multi-except clauses with comma-separated exception lists in several helpers and storage components.
  • Keep existing fallback behaviors (returning 0/None or logging a warning) unchanged while adjusting syntax.
app/players/helpers.py
app/adapters/blizzard/parsers/utils.py
app/adapters/storage/sqlite_storage.py
Improve robustness of logging stack-frame traversal.
  • Guard the logging frame traversal loop against None to avoid potential AttributeError when walking back the stack frames.
app/overfast_logger.py
Simplify truthiness-based value selection in player profile cache update.
  • Use the or operator to set the summary field to None when player_summary is falsy, preserving the previous behavior more idiomatically.
app/domain/services/player_service.py
Upgrade Python tooling and runtime dependencies, including FastAPI and build tooling.
  • Bump core runtime libraries: aiosqlite, fastapi, prometheus-client, pydantic-settings, sentry-sdk.
  • Update dev/test dependencies such as fakeredis to the latest compatible minor versions.
  • Update pre-commit ruff hook version and fix indentation style for default_language_version.
  • Update Dockerfile to use a newer uv binary version and refresh the uv.lock file accordingly.
pyproject.toml
.pre-commit-config.yaml
Dockerfile
uv.lock

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 3 issues, and left some high level feedback:

  • The changes from except (IndexError, ValueError):/except (OSError, sqlite3.Error): to except IndexError, ValueError: and except OSError, sqlite3.Error: introduce invalid Python 3 syntax; these should remain as a single tuple in one except clause or be split into two separate except blocks.
  • If the goal of the updated rsplit(..., maxsplit=1) usages is to make URL parsing more robust, consider applying the same pattern in get_tier_from_icon, which still uses chained split() calls that are more brittle than the revised helpers around it.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The changes from `except (IndexError, ValueError):`/`except (OSError, sqlite3.Error):` to `except IndexError, ValueError:` and `except OSError, sqlite3.Error:` introduce invalid Python 3 syntax; these should remain as a single tuple in one `except` clause or be split into two separate `except` blocks.
- If the goal of the updated `rsplit(..., maxsplit=1)` usages is to make URL parsing more robust, consider applying the same pattern in `get_tier_from_icon`, which still uses chained `split()` calls that are more brittle than the revised helpers around it.

## Individual Comments

### Comment 1
<location> `app/players/helpers.py:146` </location>
<code_context>
         if not blizzard_id:
             return None
-    except (IndexError, ValueError):
+    except IndexError, ValueError:
         logger.warning(f"Failed to extract Blizzard ID from URL: {url}")
         return None
</code_context>

<issue_to_address>
**issue (bug_risk):** The `except IndexError, ValueError` syntax is invalid in modern Python and will cause a `SyntaxError`.

In Python 3, multiple exceptions must be wrapped in a tuple. This should be `except (IndexError, ValueError):`; the current syntax raises a `SyntaxError` and will prevent the module from importing.
</issue_to_address>

### Comment 2
<location> `app/adapters/blizzard/parsers/utils.py:113` </location>
<code_context>
         if not blizzard_id:
             return None
-    except (IndexError, ValueError):
+    except IndexError, ValueError:
         logger.warning(f"Failed to extract Blizzard ID from URL: {url}")
         return None
</code_context>

<issue_to_address>
**issue (bug_risk):** The updated exception handler uses Python 2 style syntax and will not parse in Python 3.

Please revert to `except (IndexError, ValueError):`; the current syntax is invalid in Python 3 and will prevent this module from importing.
</issue_to_address>

### Comment 3
<location> `app/adapters/storage/sqlite_storage.py:135` </location>
<code_context>
                 replacement = await self._create_connection()
                 await self._pool.put(replacement)
-            except (OSError, sqlite3.Error):
+            except OSError, sqlite3.Error:
                 # Replacement failed — tombstone keeps the slot so the queue
                 # never blocks permanently; _acquire_connection will retry.
</code_context>

<issue_to_address>
**issue (bug_risk):** Catching multiple exceptions with commas is invalid syntax in Python 3.

Change this to `except (OSError, sqlite3.Error):`; the current form is invalid in Python 3 and will raise a `SyntaxError`, breaking the storage layer.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@sonarqubecloud
Copy link

@TeKrop TeKrop merged commit 6f97f1b into main Feb 23, 2026
5 checks passed
@TeKrop TeKrop deleted the feature/update-dependencies branch February 23, 2026 13:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant