Skip to content

Conversation

@mihow
Copy link
Collaborator

@mihow mihow commented Oct 1, 2025

Summary

Previously we omitted the region parameter for simplicity because the S3 implementations in the university compute clouds do not use regions and the default region worked for existing AWS S3 users. Now we have some users in Europe that need to specify the S3 region in order for the storage backend to sync, to display source images in the UI, and to processes source images.

List of Changes

  • Adds a region field to the S3StorageSource model
  • Passes region field to necessary functions
  • Fixes some existing type annotation errors

How to Test the Changes

.

Screenshots

If applicable, add screenshots to help explain this PR (ex. Before and after for UI changes).

Deployment Notes

.

Checklist

  • I have tested these changes appropriately.
  • I have added and/or modified relevant tests.
  • I updated relevant documentation or comments.
  • I have verified that this PR follows the project's coding standards.
  • Any dependent changes have already been merged to main.

Summary by CodeRabbit

  • New Features
    • Added optional S3 region configuration. Users can now specify which AWS region their S3 storage sources are located in, enabling seamless multi-region deployment support.

✏️ Tip: You can customize this high-level summary in your review settings.

@mihow mihow marked this pull request as ready for review October 1, 2025 12:16
@netlify
Copy link

netlify bot commented Oct 1, 2025

Deploy Preview for antenna-preview canceled.

Name Link
🔨 Latest commit 9ae07f1
🔍 Latest deploy log https://app.netlify.com/projects/antenna-preview/deploys/694c316b13d5850007fd3b0a

Copilot AI review requested due to automatic review settings October 1, 2025 12:16
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds support for S3 regions to enable users in different AWS regions (particularly Europe) to properly configure their S3 storage backends. Previously, the region parameter was omitted for simplicity as university clouds didn't require it and the default region worked for existing AWS users.

  • Adds optional region field to the S3StorageSource model and corresponding configuration
  • Updates S3 client initialization to properly handle region configuration
  • Fixes existing type annotation issues in S3 utility functions

Reviewed Changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
ami/main/models.py Adds nullable region field to S3StorageSource model and includes it in the config property
ami/main/migrations/0075_s3storagesource_region.py Database migration to add the region field to existing S3 storage sources
ami/utils/s3.py Updates S3 client/session initialization to use region and fixes type annotations
ami/tests/fixtures/storage.py Updates test fixture to include region parameter
config/settings/base.py Adds S3_TEST_REGION environment variable configuration

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.


import boto3
import boto3.resources.base
import boto3.session
Copy link

Copilot AI Oct 1, 2025

Choose a reason for hiding this comment

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

The import boto3.session is not used in this file. The code uses boto3.Session which is available through the main boto3 import. This import should be removed.

Suggested change
import boto3.session

Copilot uses AI. Check for mistakes.
endpoint_url=config.endpoint_url,
# api_version="s3v4",
)
s3 = typing.cast(S3ServiceResource, s3)
Copy link

Copilot AI Oct 1, 2025

Choose a reason for hiding this comment

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

This type cast is unnecessary. The session.resource() method already returns the correct type. Remove this line to simplify the code.

Suggested change
s3 = typing.cast(S3ServiceResource, s3)

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I does not detect the correct type without this

@mihow mihow force-pushed the fix/add-s3-region branch from aff251a to 15a4edd Compare December 6, 2025 00:59
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 6, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

A new optional region field is added to S3 storage configuration across the system. The region parameter is introduced to the S3StorageSource model, S3Config dataclass, and boto3 session/client initialization. A Django migration creates the database field, and test fixtures and settings are updated to support the new configuration.

Changes

Cohort / File(s) Summary
S3 Configuration & boto3 Integration
ami/utils/s3.py, config/settings/base.py
Added optional region field to S3Config dataclass; updated boto3 session creation to pass region_name from config; applied Signature Version 4 consistently across client creation; extracted streaming body handling in image reading logic; added type casts for S3Client and S3ServiceResource; added S3_TEST_REGION setting with default None.
Model & Migration
ami/main/models.py, ami/main/migrations/0079_s3storagesource_region.py
Added public region field to S3StorageSource model as optional CharField; updated config method to pass region=self.region to S3Config; created migration 0079 to add the field with blank=True, null=True, max_length=255.
Test Fixtures
ami/tests/fixtures/storage.py
Updated S3Config instantiation to pass region=settings.S3_TEST_REGION.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • boto3 integration changes (ami/utils/s3.py): Verify region is correctly propagated in all session/client creation paths (both endpoint and non-endpoint branches) and that type casts are properly applied.
  • Migration and model updates: Confirm migration depends on correct predecessor and field constraints are appropriate.
  • Consistency across config layers: Ensure region flows correctly from model → config → boto3 without breaks or inconsistencies.

Poem

🐰 A region hops in, from config to session,
Through boto3's pathways with quiet precision,
The storage now knows where to roam,
From S3 to home, it finds its way home! 🌍

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add support for S3 regions' clearly and concisely summarizes the main change—adding region support to S3 configuration.
Description check ✅ Passed The description covers the summary, list of changes, and includes deployment/testing notes, but 'How to Test the Changes' and 'Deployment Notes' sections contain only placeholders ('.').
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/add-s3-region

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 15a4edd and e2e3705.

📒 Files selected for processing (1)
  • ami/main/migrations/0079_s3storagesource_region.py (1 hunks)
🧰 Additional context used
🪛 Ruff (0.14.7)
ami/main/migrations/0079_s3storagesource_region.py

7-9: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


11-17: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test
🔇 Additional comments (1)
ami/main/migrations/0079_s3storagesource_region.py (1)

11-17: Migration for S3StorageSource.region is correct and complete

The added optional region CharField and its placement in operations look standard and aligned with the PR intent; no changes needed.


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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
ami/tests/fixtures/storage.py (1)

25-39: Consider passing region to S3StorageSource defaults.

The S3_TEST_CONFIG now includes region, but create_storage_source doesn't pass it to the S3StorageSource.objects.get_or_create defaults. This could lead to inconsistency where the test config has a region but the created storage source doesn't.

         defaults=dict(
             bucket=S3_TEST_CONFIG.bucket_name,
             prefix=prefix,
             endpoint_url=S3_TEST_CONFIG.endpoint_url,
             access_key=S3_TEST_CONFIG.access_key_id,
             secret_key=S3_TEST_CONFIG.secret_access_key,
             public_base_url=S3_TEST_CONFIG.public_base_url,
+            region=S3_TEST_CONFIG.region,
         ),
ami/utils/s3.py (1)

131-139: Consider passing region_name and config to the resource for consistency.

Unlike get_s3_client, this function doesn't explicitly pass region_name or the botocore.config.Config with signature version. While the session inherits the region from get_session(), explicitly passing these parameters would ensure consistent behavior and make the code more explicit.

 def get_resource(config: S3Config) -> S3ServiceResource:
     session = get_session(config)
+    boto_config = botocore.config.Config(signature_version="s3v4")
     s3 = session.resource(
         "s3",
         endpoint_url=config.endpoint_url,
-        # api_version="s3v4",
+        region_name=config.region,
+        config=boto_config,
     )
     s3 = typing.cast(S3ServiceResource, s3)
     return s3
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f899482 and 15a4edd.

📒 Files selected for processing (5)
  • ami/main/migrations/0075_s3storagesource_region.py (1 hunks)
  • ami/main/models.py (2 hunks)
  • ami/tests/fixtures/storage.py (1 hunks)
  • ami/utils/s3.py (6 hunks)
  • config/settings/base.py (1 hunks)
🧰 Additional context used
🪛 Ruff (0.14.7)
ami/main/migrations/0075_s3storagesource_region.py

7-9: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


11-17: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test
🔇 Additional comments (9)
config/settings/base.py (1)

448-452: LGTM!

The new S3_TEST_REGION setting follows the established pattern for S3 test configuration and appropriately defaults to None for backward compatibility with existing setups that don't require region specification.

ami/main/models.py (1)

1389-1423: LGTM!

The region field is properly added to S3StorageSource and correctly propagated to S3Config in the config property. The nullable design appropriately maintains backward compatibility for existing storage sources and S3-compatible backends that don't require region specification.

ami/main/migrations/0075_s3storagesource_region.py (1)

1-17: LGTM!

Standard Django migration for adding the nullable region field. The static analysis hints about ClassVar annotations are false positives — Django migrations conventionally define dependencies and operations as class attributes without type annotations.

ami/utils/s3.py (6)

13-13: The boto3.session import is used.

Contrary to the previous review comment, this import is used for the return type annotation on line 94: def get_session(config: S3Config) -> boto3.session.Session. The import should be retained.


33-41: LGTM!

The region field is properly added to the S3Config dataclass with an appropriate None default for backward compatibility.


94-100: LGTM!

The session now correctly receives region_name from the config, ensuring region-aware S3 operations.


103-128: LGTM! The client now consistently uses Signature Version 4 and the region parameter.

Minor note: The credentials are passed to both the session (via get_session) and the client. This redundancy is harmless—the client parameters take precedence—but could be simplified in a future refactor.


599-601: LGTM!

Good improvement extracting Body to a separate variable. The StreamingBody is file-like but type checkers don't recognize it, so the type: ignore comment is appropriate.


684-695: LGTM!

The test function is properly updated with the region=None parameter to match the updated S3Config signature.

@netlify
Copy link

netlify bot commented Dec 24, 2025

Deploy Preview for antenna-ssec canceled.

Name Link
🔨 Latest commit 9ae07f1
🔍 Latest deploy log https://app.netlify.com/projects/antenna-ssec/deploys/694c316b4156c10008a54b33

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.

2 participants