Skip to content

Harden runtime configuration, improve prediction safety, and align packaging/Docker best practices - #15

Closed
ThomasBury wants to merge 1 commit into
mainfrom
codex/conduct-in-depth-code-review-for-best-practices
Closed

Harden runtime configuration, improve prediction safety, and align packaging/Docker best practices#15
ThomasBury wants to merge 1 commit into
mainfrom
codex/conduct-in-depth-code-review-for-best-practices

Conversation

@ThomasBury

@ThomasBury ThomasBury commented Mar 3, 2026

Copy link
Copy Markdown
Owner

Motivation

  • Provide safe defaults and validations so the app can bootstrap in common dev/test environments without missing env vars causing startup failures.
  • Normalize model outputs and fail early on missing matches to avoid surprising runtime errors and to make API responses predictable.
  • Align packaging and Docker image steps with best practices for runtime-only installs and proper package discovery.

Description

  • Added new configurable settings in AppSettings with defaults and validators: ACEBET_ENV, ACEBET_LOG_LEVEL, ACEBET_LOG_FILE, ACEBET_DEFAULT_RATE_LIMIT, and ACEBET_LOGIN_RATE_LIMIT, plus a redacted() view for safe startup logging in src/acebet/app/config.py.
  • Validated ACEBET_ACCESS_TOKEN_EXPIRE_MINUTES and ACEBET_LOG_LEVEL, and require ACEBET_SECRET_KEY in non-dev environments; kept a dev-default secret fallback for local use.
  • Fixed FastAPI bootstrap by importing settings in src/acebet/app/main.py, tightened middleware typing to Callable[[Request], Awaitable[Response]], and used settings values for limiter and logging configuration.
  • Hardened prediction flow in src/acebet/app/dependencies/predict_winner.py by raising on empty query results and keeping function return typing; normalized prob and class_ in src/acebet/app/main.py to scalar float/int before serializing the PredictionResponse and removed unused current_user usage.
  • Corrected package discovery glob in pyproject.toml from data* to acebet* so the package is discovered correctly.
  • Updated Dockerfile to set PYTHONDONTWRITEBYTECODE/PYTHONUNBUFFERED, use uv sync --no-dev for runtime-only installs, and explicitly EXPOSE 80 for the service port.
  • Added small doc/package hygiene changes: .env.example now documents new env vars, deployment docs updated to reference ACEBET_LOG_LEVEL, and package __init__.py docstrings were added to satisfy linters.
  • Ran ruff --fix style cleanups and wrapped long lines to satisfy project lint rules.

Testing

  • Ran linters with uv run ruff check src tests which completed with All checks passed!.
  • Executed the test suite with uv run pytest -q which succeeded (4 passed) and emitted only upstream deprecation/warning messages (FastAPI on_event deprecation and LightGBM/scikit-learn tag warnings).

Codex Task

Summary by CodeRabbit

  • New Features

    • Added configurable rate limiting for default and login endpoints
    • Introduced logging level configuration with file path settings
  • Bug Fixes

    • Added error handling when historical match data is unavailable for predictions
  • Chores

    • Updated environment variable naming from ACEBET_DEBUG to ACEBET_LOG_LEVEL
    • Optimized Docker build process and runtime configuration
    • Enhanced code documentation and type annotations

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the application's operational robustness and maintainability by refining its configuration management, improving the reliability of its prediction services, and aligning its deployment artifacts with modern best practices. The changes ensure a more stable startup, predictable API behavior, and efficient Docker image builds, contributing to a more resilient and developer-friendly system.

Highlights

  • Hardened Runtime Configuration: Introduced new configurable settings in AppSettings with safe defaults and robust validators for environment variables like ACEBET_ENV, ACEBET_LOG_LEVEL, ACEBET_DEFAULT_RATE_LIMIT, and ACEBET_LOGIN_RATE_LIMIT. A redacted() method was added for secure logging of configuration, and ACEBET_SECRET_KEY is now required in non-development environments.
  • Improved Prediction Safety and Predictability: The prediction flow was hardened to raise errors on empty query results, ensuring early failure and preventing unexpected runtime issues. Model outputs (prob and class_) are now explicitly normalized to scalar float and int types before serialization, making API responses more predictable.
  • Aligned Packaging and Docker Best Practices: Corrected the package discovery glob in pyproject.toml from data* to acebet* to ensure proper package identification. The Dockerfile was updated to include PYTHONDONTWRITEBYTECODE and PYTHONUNBUFFERED environment variables, use uv sync --no-dev for runtime-only dependency installs, and explicitly EXPOSE 80 for the service port.
  • FastAPI Bootstrap and Middleware Enhancements: Fixed the FastAPI application bootstrap by correctly importing settings and tightened the typing for the HTTP middleware to Callable[[Request], Awaitable[Response]]. Configuration values from settings are now used for limiter and logging setup.
  • Documentation and Code Hygiene: Updated .env.example to document new environment variables and revised deployment documentation to reference ACEBET_LOG_LEVEL. Docstrings were added to package __init__.py files to satisfy linters, and ruff --fix was run for general style cleanups and line wrapping.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • .env.example
    • Added new environment variables for default rate limit, login rate limit, and log file path.
  • Dockerfile
    • Added PYTHONDONTWRITEBYTECODE and PYTHONUNBUFFERED environment variables.
    • Moved WORKDIR /app before COPY . /app.
    • Modified uv sync command to use --no-dev for runtime-only dependencies.
    • Explicitly exposed port 80.
  • docs/deployment/docker-and-github-actions.md
    • Replaced references to ACEBET_DEBUG with ACEBET_LOG_LEVEL in example .env and deployment table.
    • Updated deployment step to use ACEBET_LOG_LEVEL.
  • pyproject.toml
    • Corrected the package discovery glob from data* to acebet*.
  • src/acebet/app/init.py
    • Added a module docstring.
  • src/acebet/app/config.py
    • Added default values for acebet_env, log_level, log_file, default_rate_limit, and login_rate_limit.
    • Added a field_validator for log_level to ensure it's a valid Python logging level.
    • Implemented a redacted() method to return non-sensitive configuration values for logging.
  • src/acebet/app/dependencies/auth.py
    • Reordered imports for datetime and os.
    • Wrapped long lines in jwt.encode and jwt.decode calls for better readability.
  • src/acebet/app/dependencies/predict_winner.py
    • Added a check to raise a ValueError if the input DataFrame for prediction is empty.
    • Added a return type hint -> tuple[Any, Any, str] to the make_prediction function.
  • src/acebet/app/main.py
    • Imported Awaitable and Callable from collections.abc.
    • Imported settings from acebet.app.config.
    • Tightened the type hint for call_next in user_logging_middleware.
    • Removed unused current_user variable in predict_match_outcome.
    • Ensured prob and class_ are normalized to scalar float and int types respectively before returning PredictionResponse.
  • src/acebet/data/init.py
    • Added a module docstring.
  • src/acebet/dataprep/init.py
    • Added a module docstring.
  • src/acebet/train/init.py
    • Added a module docstring.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai

coderabbitai Bot commented Mar 3, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The changes add rate limiting and logging configuration fields to the application settings, enhance Docker runtime optimizations, replace debug flags with log level configuration, improve type safety with explicit annotations, add input validation guards, and include module-level documentation across the codebase.

Changes

Cohort / File(s) Summary
Configuration & Environment Setup
.env.example, src/acebet/app/config.py
Added three new configuration fields (log_level, log_file, default_rate_limit, login_rate_limit) with environment variable aliases, defaults, and log level validation. Environment template updated to reflect new rate limiting and logging configuration.
Deployment & Runtime
Dockerfile, docs/deployment/docker-and-github-actions.md
Dockerfile optimized with Python runtime flags (bytecode/buffering disabled), explicit WORKDIR, port exposure, and dependency installation strategy. Documentation updated to replace ACEBET_DEBUG with ACEBET_LOG_LEVEL across examples and GitHub Actions secrets mapping.
Project Configuration
pyproject.toml
Updated package discovery glob from data* to acebet* for more explicit package inclusion.
Type Safety & Request Handling
src/acebet/app/main.py, src/acebet/app/dependencies/auth.py
Added explicit type annotations for middleware handler parameters (Callable[[Request], Awaitable[Response]]). Imported required types from collections.abc. Added cleanup logic for current_user before result processing.
Prediction & Validation Logic
src/acebet/app/dependencies/predict_winner.py
Added return type annotation to make_prediction and introduced guard condition in predict to raise ValueError when input DataFrame is empty, preventing inference on missing historical data.
Package Metadata
src/acebet/app/__init__.py, src/acebet/data/__init__.py, src/acebet/dataprep/__init__.py, src/acebet/train/__init__.py
Added module-level docstrings to four package __init__.py files for documentation purposes without functional changes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • PR #9: Extends the same AppSettings configuration module and integrates settings into auth and startup flows with new rate limiting and logging fields.
  • PR #14: Modifies src/acebet/app/config.py with identical log_level and log_file additions and wires these settings into main.py and auth dependencies.

Suggested labels

enhancement

Poem

🐰 With whiskers twitching at each config line,
Rate limits set and logs aligned,
Docker optimized, types now precise,
Validation guards—a rabbit's delight!
Hoppy improvements all the way. 🎉

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main objectives of the changeset: hardening runtime configuration, improving prediction safety, and aligning with Docker/packaging best practices.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/conduct-in-depth-code-review-for-best-practices

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a solid set of improvements, hardening the application's runtime configuration, improving prediction safety, and aligning packaging and Docker practices with modern standards. The changes are well-executed and clearly beneficial. I have one suggestion regarding the Dockerfile to further optimize the build process by improving layer caching.

Comment thread Dockerfile
Comment on lines 11 to +14
COPY . /app

# Install the application dependencies.
WORKDIR /app
RUN uv sync --frozen --no-cache
# Install runtime dependencies only.
RUN uv sync --frozen --no-cache --no-dev

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

To better leverage Docker's layer caching, it's a good practice to copy only the dependency manifests (pyproject.toml, uv.lock), install dependencies, and then copy the rest of the application source code. This separation ensures that the dependency layer is only rebuilt when dependencies change, not on every code change, leading to faster builds.

COPY pyproject.toml uv.lock ./
# Install runtime dependencies only.
RUN uv sync --frozen --no-cache --no-dev
COPY . .

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b55a0bcf43

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/acebet/app/config.py
model_config = SettingsConfigDict(extra="ignore")

acebet_env: str = Field(alias="ACEBET_ENV")
acebet_env: str = Field(default="development", alias="ACEBET_ENV")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Require explicit environment before applying dev mode defaults

Defaulting ACEBET_ENV to development makes a missing environment variable silently opt into development behavior, which bypasses validate_secret_key_in_non_dev and allows the app to run with the known fallback JWT secret (ACEBET_SECRET_KEY in config.py). In any production/staging deployment where ACEBET_ENV is accidentally omitted, tokens can be forged with that default key instead of failing fast at startup as before.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/acebet/app/dependencies/predict_winner.py (1)

132-133: ⚠️ Potential issue | 🟡 Minor

ValueError from predict() not translated to HTTP error in endpoint.

When query_data returns an empty DataFrame, predict() raises a ValueError. However, in main.py, make_prediction() is called without catching this error, so it will propagate as a 500 Internal Server Error rather than a more appropriate 404 or 400 response.

Consider handling this in the /predict/ endpoint to return a user-friendly HTTP error.

🛡️ Suggested handling in main.py

In src/acebet/app/main.py, wrap the call to handle the ValueError:

try:
    prob, class_, player_1 = make_prediction(
        data_file=data_file,
        model_path=model_path,
        p1_name=p1_name,
        p2_name=p2_name,
        date=date,
    )
except ValueError as exc:
    raise HTTPException(
        status_code=status.HTTP_404_NOT_FOUND,
        detail=str(exc),
    ) from exc
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/acebet/app/dependencies/predict_winner.py` around lines 132 - 133, The
endpoint calling make_prediction should catch the ValueError raised when
query_data returns an empty DataFrame (which bubbles up from predict) and
translate it into an HTTP error; update the /predict handler in main.py where
make_prediction(...) is invoked to wrap the call in a try/except ValueError
block and raise fastapi.HTTPException (e.g., status.HTTP_404_NOT_FOUND or
status.HTTP_400_BAD_REQUEST) with the ValueError message as detail, preserving
the original exception via "from exc".
🧹 Nitpick comments (4)
src/acebet/app/main.py (2)

228-228: Unnecessary del current_user - Python handles garbage collection automatically.

The del current_user statement is not needed. The current_user variable goes out of scope when the function returns, and Python's garbage collector handles cleanup. This pattern may suggest an intent to prevent accidental usage, but it's unconventional and adds noise.

If the intent is to signal that current_user is only used for endpoint protection, consider renaming to _current_user to indicate it's intentionally unused.

✨ Suggested alternative
 `@app.post`("/predict/", response_model=PredictionResponse)
 def predict_match_outcome(
-    request: PredictionRequest, current_user: UserInDB = Depends(get_current_user)
+    request: PredictionRequest, _current_user: UserInDB = Depends(get_current_user)
 ) -> PredictionResponse:

Then remove line 228:

-    del current_user
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/acebet/app/main.py` at line 228, Remove the unnecessary del current_user
statement: either delete the line "del current_user" (preferred) or, if you want
to indicate the variable is intentionally unused, rename the variable to
_current_user where it's defined (e.g., in the endpoint function's parameter or
local binding) so you avoid the explicit deletion while conveying intent; update
any references accordingly (look for current_user in the endpoint function
surrounding the del to locate the change).

50-53: Redundant validation at startup - configuration already validated at module load.

The settings = AppSettings() at module level in config.py (line 77) already validates configuration when the module is imported. Calling validate_config() again at startup creates a second AppSettings() instance that re-reads environment variables and re-runs validators. This is redundant and could cause confusion if environment variables change between import time and startup (unlikely but possible in edge cases).

Consider whether this double validation is intentional. If the goal is to surface errors clearly at startup, the existing import-time validation already achieves this. If you want explicit startup validation, consider making settings lazy-loaded instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/acebet/app/main.py` around lines 50 - 53, The startup hook
validate_startup_config() is causing a second AppSettings() instantiation via
validate_config(), so either remove the `@app.on_event`("startup")
validate_startup_config() function entirely to rely on the module-level settings
in config.py, or modify validate_config() to reuse the existing singleton
settings object (e.g., import and use config.settings) instead of creating a new
AppSettings(); target symbols: validate_startup_config, validate_config,
AppSettings, and settings in config.py.
src/acebet/app/config.py (2)

84-89: validate_config() creates a duplicate settings instance.

This function instantiates a new AppSettings() every time it's called, which re-reads environment variables. Since settings = AppSettings() is already created at module level (line 77) and validation happens there, this function may return success even if the actual settings singleton was created with different values (edge case).

If the intent is to validate at startup, consider reusing the existing singleton or making this function return the validated instance.

✨ Suggested improvement
 def validate_config() -> None:
     """Validate startup configuration and raise clear runtime errors when invalid."""
-    try:
-        AppSettings()
-    except ValidationError as exc:
-        raise RuntimeError(f"Invalid application configuration: {exc}") from exc
+    # Settings already validated at module load; this ensures errors surface clearly.
+    if settings is None:
+        raise RuntimeError("Configuration failed to load.")

Or simply document that this function is a no-op safety check since validation happens at import time.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/acebet/app/config.py` around lines 84 - 89, The function validate_config
currently instantiates a fresh AppSettings(), which re-reads env and can diverge
from the module-level singleton settings; change validate_config to reuse and
return the existing module-level settings variable instead of constructing a new
AppSettings() (i.e., reference settings, optionally wrapping access in a
try/except for ValidationError to raise a RuntimeError), or make it explicitly a
no-op that returns settings so callers get the validated singleton.

21-26: Add validation for rate limit format strings.

The default_rate_limit and login_rate_limit fields accept arbitrary strings without validation. slowapi expects specific formats like "60/minute", "5/second", or multiple limits like "1/second;5/minute;20/hour". Invalid formats will cause runtime errors when the limiter is instantiated.

Add a field validator to ensure the rate limit strings match the expected pattern.

✨ Suggested validator
import re

`@field_validator`("default_rate_limit", "login_rate_limit")
`@classmethod`
def validate_rate_limit(cls, value: str) -> str:
    """Ensure rate limit matches slowapi expected format."""
    pattern = r"^\d+/(second|minute|hour|day)(?:;\d+/(second|minute|hour|day))*$"
    if not re.match(pattern, value.strip()):
        raise ValueError(
            f"Rate limit '{value}' must match format like '60/minute' or '1/second;5/minute;20/hour'."
        )
    return value.strip()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/acebet/app/config.py` around lines 21 - 26, The rate limit fields
default_rate_limit and login_rate_limit currently accept any string and need
validation to prevent runtime errors; add a class field validator (e.g., def
validate_rate_limit) using pydantic's `@field_validator` for "default_rate_limit"
and "login_rate_limit", import re, apply a regex like
^\d+/(second|minute|hour|day)(?:;\d+/(second|minute|hour|day))*$ to validate and
strip the value, raise ValueError with a clear message on mismatch, and return
the cleaned string so the limiter receives only properly formatted rate strings.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.env.example:
- Around line 29-30: Update the comment above the ACEBET_LOGIN_RATE_LIMIT
variable to reflect that this value configures the rate limit for login attempts
or the login endpoint (not a generic /limit demo); mention the expected format
(e.g., "10/minute") and scope (login attempts/session) so env users clearly
understand ACEBET_LOGIN_RATE_LIMIT's intent and usage.

---

Outside diff comments:
In `@src/acebet/app/dependencies/predict_winner.py`:
- Around line 132-133: The endpoint calling make_prediction should catch the
ValueError raised when query_data returns an empty DataFrame (which bubbles up
from predict) and translate it into an HTTP error; update the /predict handler
in main.py where make_prediction(...) is invoked to wrap the call in a
try/except ValueError block and raise fastapi.HTTPException (e.g.,
status.HTTP_404_NOT_FOUND or status.HTTP_400_BAD_REQUEST) with the ValueError
message as detail, preserving the original exception via "from exc".

---

Nitpick comments:
In `@src/acebet/app/config.py`:
- Around line 84-89: The function validate_config currently instantiates a fresh
AppSettings(), which re-reads env and can diverge from the module-level
singleton settings; change validate_config to reuse and return the existing
module-level settings variable instead of constructing a new AppSettings()
(i.e., reference settings, optionally wrapping access in a try/except for
ValidationError to raise a RuntimeError), or make it explicitly a no-op that
returns settings so callers get the validated singleton.
- Around line 21-26: The rate limit fields default_rate_limit and
login_rate_limit currently accept any string and need validation to prevent
runtime errors; add a class field validator (e.g., def validate_rate_limit)
using pydantic's `@field_validator` for "default_rate_limit" and
"login_rate_limit", import re, apply a regex like
^\d+/(second|minute|hour|day)(?:;\d+/(second|minute|hour|day))*$ to validate and
strip the value, raise ValueError with a clear message on mismatch, and return
the cleaned string so the limiter receives only properly formatted rate strings.

In `@src/acebet/app/main.py`:
- Line 228: Remove the unnecessary del current_user statement: either delete the
line "del current_user" (preferred) or, if you want to indicate the variable is
intentionally unused, rename the variable to _current_user where it's defined
(e.g., in the endpoint function's parameter or local binding) so you avoid the
explicit deletion while conveying intent; update any references accordingly
(look for current_user in the endpoint function surrounding the del to locate
the change).
- Around line 50-53: The startup hook validate_startup_config() is causing a
second AppSettings() instantiation via validate_config(), so either remove the
`@app.on_event`("startup") validate_startup_config() function entirely to rely on
the module-level settings in config.py, or modify validate_config() to reuse the
existing singleton settings object (e.g., import and use config.settings)
instead of creating a new AppSettings(); target symbols:
validate_startup_config, validate_config, AppSettings, and settings in
config.py.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7a5dcf1 and b55a0bc.

📒 Files selected for processing (12)
  • .env.example
  • Dockerfile
  • docs/deployment/docker-and-github-actions.md
  • pyproject.toml
  • src/acebet/app/__init__.py
  • src/acebet/app/config.py
  • src/acebet/app/dependencies/auth.py
  • src/acebet/app/dependencies/predict_winner.py
  • src/acebet/app/main.py
  • src/acebet/data/__init__.py
  • src/acebet/dataprep/__init__.py
  • src/acebet/train/__init__.py

Comment thread .env.example
Comment on lines +29 to +30
# Rate limit for the /limit endpoint demo.
ACEBET_LOGIN_RATE_LIMIT=10/minute

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Clarify ACEBET_LOGIN_RATE_LIMIT comment to match variable intent.

The current wording mentions a /limit demo endpoint, which conflicts with the LOGIN-scoped variable name and can confuse runtime configuration.

💡 Proposed doc fix
-# Rate limit for the /limit endpoint demo.
+# Rate limit for authentication/login endpoint requests.
 ACEBET_LOGIN_RATE_LIMIT=10/minute
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Rate limit for the /limit endpoint demo.
ACEBET_LOGIN_RATE_LIMIT=10/minute
# Rate limit for authentication/login endpoint requests.
ACEBET_LOGIN_RATE_LIMIT=10/minute
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.env.example around lines 29 - 30, Update the comment above the
ACEBET_LOGIN_RATE_LIMIT variable to reflect that this value configures the rate
limit for login attempts or the login endpoint (not a generic /limit demo);
mention the expected format (e.g., "10/minute") and scope (login
attempts/session) so env users clearly understand ACEBET_LOGIN_RATE_LIMIT's
intent and usage.

@ThomasBury ThomasBury closed this Mar 3, 2026
@ThomasBury
ThomasBury deleted the codex/conduct-in-depth-code-review-for-best-practices branch April 29, 2026 15:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant