You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
perf(serverless): lazy-load boto3, fastapi, and pydantic to reduce cold start time (#466)
* perf(serverless): lazy-load boto3 to reduce cold start time
Move boto3 imports from module level to function level in rp_upload.py.
This defers loading ~50MB of boto3/botocore dependencies until S3 upload
functions are actually called, improving initial import time and memory
footprint for users who don't use S3 features.
Changes:
- Refactored get_boto_client() and bucket_upload() with lazy imports
- Added ImportError handling with helpful error messages
- Updated tests to mock boto3 modules directly
- Enhanced documentation to explain lazy-loading behavior
All upload functions maintain backward compatibility and graceful
fallback to local file storage when boto3 is unavailable.
* refactor(serverless): address PR review feedback for boto3 lazy-loading
Address Copilot review comments from PR #466:
1. Extract boto3 import logic into shared helper function
- Created _import_boto3_dependencies() to reduce duplication
- Used by both get_boto_client() and bucket_upload()
- Consistent error handling across all S3 upload functions
2. Add TransferConfig import to bucket_upload()
- Now imports all boto3 dependencies via shared helper
- Maintains consistency with get_boto_client()
3. Clarify documentation about fallback directories
- Documented that upload_image() uses simulated_uploaded/
- Documented that public API functions use local_upload/
- Added context about when fallback behavior occurs
All 358 tests pass with 97% coverage.
* refactor(serverless): replace print() with logger in upload fallback paths
Address Copilot review comment from PR #466:
Replace print() statements with logger.warning() for consistency with
the module's logging setup. This allows proper log level control and
maintains consistent logging behavior throughout the module.
Changes:
- upload_image(): Use logger.warning() instead of print()
- upload_file_to_bucket(): Use logger.warning() instead of print()
- upload_in_memory_object(): Use logger.warning() instead of print()
All fallback messages now use structured logging with single-line
format for better log parsing and filtering.
* refactor(serverless): extract local fallback logic into shared helper
Address Copilot review comment from PR #466:
Extract duplicated fallback logic from upload_file_to_bucket() and
upload_in_memory_object() into a shared _save_to_local_fallback() helper
function to reduce code duplication and ensure consistent behavior.
Changes:
- Created _save_to_local_fallback() helper function
- Handles both file-based (source_path) and in-memory (file_data) uploads
- Consolidated logging, directory creation, and file saving logic
- upload_file_to_bucket() now calls helper with source_path parameter
- upload_in_memory_object() now calls helper with file_data parameter
Test improvements:
- Added test_upload_file_to_bucket_fallback() for file-based fallback
- Added test_upload_in_memory_object_fallback() for in-memory fallback
- Added test_save_to_local_fallback_invalid_args() for error handling
- Added test_import_boto3_dependencies_missing() for ImportError path
- Achieved 100% test coverage for rp_upload.py module
Benefits:
- Reduced code duplication (removed 12 lines of duplicate code)
- Single source of truth for fallback behavior
- Easier to maintain and test
- Consistent error messages and logging
- Complete test coverage ensures reliability
All 10 upload tests pass with 100% module coverage.
* refactor(serverless): consolidate fallback logic across all upload functions
Address latest Copilot review comment from PR #466:
Eliminate remaining duplication by making upload_image() use the
_save_to_local_fallback() helper function. Added a 'directory' parameter
to the helper to support different fallback directories.
Changes:
- Added 'directory' parameter to _save_to_local_fallback() (default: 'local_upload')
- Updated upload_image() to use helper with directory='simulated_uploaded'
- Removed duplicate warning message and URL from upload_image()
- Consolidated all fallback logic into single helper function
Benefits:
- Complete elimination of code duplication
- Single source of truth for all fallback behavior
- Consistent warning messages across all upload functions
- Easier to maintain and update fallback logic
All 362 tests pass with 97% overall coverage, 100% coverage on rp_upload.py.
* refactor(serverless): restore type hints for boto3 lazy-loading
Use TYPE_CHECKING to import boto3 types only during static type checking,
maintaining proper type safety without runtime import cost.
Changes:
- Import BaseClient and TransferConfig under TYPE_CHECKING guard
- Restore get_boto_client() return type from Tuple[Any, Any] to
Tuple[Optional[BaseClient], Optional[TransferConfig]]
- Remove # pragma: no cover comment as it's no longer needed
This addresses PR review feedback about maintaining type safety while
preserving the lazy-loading optimization.
* perf(serverless): lazy-load FastAPI to reduce cold start time
Move FastAPI/Uvicorn/Pydantic imports from module-level to conditional
blocks where they're actually used. This stack is only needed when
--rp_serve_api flag is set (local dev) or realtime mode is enabled.
Performance Impact:
- Cold start: 480ms → 280-326ms (32-42% faster)
- Modules loaded: 841 → 640 (24% reduction, ~200 fewer)
- Production workers: Never load FastAPI/Uvicorn/Pydantic stack
- Dev mode: FastAPI loads on-demand when needed
Changes:
- Remove eager import of rp_fastapi from module level
- Add lazy import in start() when rp_serve_api flag is True
- Add lazy import in start() when realtime mode is enabled
All tests pass. No breaking changes.
* test(serverless): fix tests for lazy-loaded FastAPI
Update test mocks to use correct import path for lazy-loaded rp_fastapi module.
Since FastAPI is now imported on-demand inside start() function rather than
at module level, tests need to mock the actual module path.
Changes:
- Update test_local_api to mock runpod.serverless.modules.rp_fastapi.WorkerAPI
- Update test_start_does_not_set_excepthook to mock correct module path
All 362 tests pass with 96.76% coverage.
Copy file name to clipboardExpand all lines: docs/serverless/utils/rp_upload.md
+8Lines changed: 8 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,6 +4,14 @@ The upload utility provides functions to upload files and in-memory objects to a
4
4
5
5
*Note: The upload utility utilizes the Virtual-hosted-style URL with the bucket name in the host name. For example, `https: // bucket-name.s3.amazonaws.com`.*
6
6
7
+
## Requirements
8
+
9
+
The upload utility requires [boto3](https://pypi.org/project/boto3/) for S3 functionality. boto3 is lazy-loaded to minimize initial import time and memory footprint.
10
+
11
+
If you attempt to use S3 upload features without boto3 installed or S3 credentials are not configured, files will be saved to local disk instead:
12
+
-`upload_image()` saves to `simulated_uploaded/` directory
13
+
-`upload_file_to_bucket()` and `upload_in_memory_object()` save to `local_upload/` directory
14
+
7
15
## Bucket Credentials
8
16
9
17
You can set your S3 bucket credentials in the following ways:
0 commit comments