Skip to content

Chore/refactor and rate limit - #14

Merged
sal94 merged 3 commits into
devfrom
chore/refactor-and-rate-limit
Dec 5, 2025
Merged

Chore/refactor and rate limit#14
sal94 merged 3 commits into
devfrom
chore/refactor-and-rate-limit

Conversation

@sal94

@sal94 sal94 commented Dec 5, 2025

Copy link
Copy Markdown
Owner
  • Rate limiting wiring: app/main.py, app/rate_limiter.py, app/api/deps.py—FastAPI-Limiter added on auth and protected routers. Identifier prefers request.state.user_id then IP. Check that startup/shutdown init/close is safe for all environments and
    that unauthenticated routes behave as expected.
    • Upload quota enforcement: app/services/assets.py—daily per-user byte cap via Redis incr/expire, keyed by date. Upload endpoint now passes user_id. Verify HTTP 429 behavior and that TTL reset logic is correct.
    • Redis test stubs: tests/conftest.py—in-memory Redis for caching + limiter with script_load/evalsha. Ensure it matches FastAPI-Limiter contract and doesn’t leak state across tests.
    • Config knobs: app/settings.py adds REQUEST_RATE_LIMIT_PER_MINUTE and DAILY_UPLOAD_LIMIT_BYTES. Confirm defaults/aliases fit prod/staging and README notes are consistent.
    • Docs: README.md—added Redis usage + limit knobs; confirm messaging aligns with intended behavior.
    • Deps: pyproject.toml/poetry.lock—new fastapi-limiter, fakeredis. Validate they’re acceptable and don’t bloat images.
    • Tests: tests/test_assets.py quota test plus existing suite. Tests pass locally (make db-up, make test-auto). If reviewing CI, ensure migrate still runs and limiter init doesn’t break no-Redis scenarios.

@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.

ℹ️ 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 app/services/assets.py
Comment on lines +116 to +119
if user_id is not None:
await self._enforce_daily_upload_quota(
user_id=user_id, bytes_added=len(data)
)

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 Roll back quota when upload fails

Daily upload quota is bumped before any storage or database work and never rolled back. _enforce_daily_upload_quota runs as soon as the file is read, but if write_bytes_async, the DB insert/commit, or downstream processing fails, the Redis counter remains incremented and the user loses daily quota even though no asset was stored. This can lock users out after transient upload errors; defer the increment until after successful persistence or wrap later steps in try/except to decrement on failure.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

@codex can you backup this expected edge case with a test to prove your point? Or will the redis stubs make it hard to do so?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Summary

  • Added rollback handling around asset upload persistence so daily upload quota counters are reversed if downstream storage or database work fails after incrementing the Redis counter. app/services/assets.pyL116-L336
  • Added regression test that simulates a storage failure and asserts the per-user upload quota is not consumed when the upload aborts. tests/test_assets.pyL42-L99

Testing

  • ⚠️ pytest tests/test_assets.py -q (fails: Postgres not running in container)

View task →

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

@codex That was a good call.
I had to copy the patch and propagate the failure with:
except Exception as exc:
if quota_charged and user_id is not None:
await self._rollback_daily_upload_quota(
user_id=user_id, bytes_removed=quota_bytes
)
if isinstance(exc, HTTPException):
raise
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Upload failed, please retry",
) from exc

Just as personal feedback. I am able to run tests in CI github environment by using simple commands that I have prepared like setting up the repo with poetry install --with dev and make db-up and make test-auto.
What is blocking you from doing that so that I can fix it?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Summary

  • Added quota rollback and database rollback around asset uploads so failed storage or database operations do not consume a user’s daily upload allowance and return a consistent 500 error. app/services/assets.pyL116-L211
  • Added a regression test that simulates a storage failure and verifies the upload quota remains available for a subsequent retry. tests/test_assets.pyL40-L101

Testing

  • ⚠️ pytest tests/test_assets.py::test_upload_rolls_back_quota_on_failure -q (fails: Postgres not running locally)

View task →

@sal94
sal94 merged commit c701f97 into dev Dec 5, 2025
2 checks passed
@sal94
sal94 deleted the chore/refactor-and-rate-limit branch December 5, 2025 17:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant