-
Notifications
You must be signed in to change notification settings - Fork 8.3k
feat: Complete refactor of storage locations #11180
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughThis PR implements global storage settings management, enabling centralized AWS S3 and Google Drive credential configuration. A new v2 API endpoint manages settings with credential masking, while file components gain optional per-component storage overrides. Tests verify credential validation, masking, and fallback behavior. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Frontend
participant API as v2 API
participant SettingsService
rect rgb(220, 240, 255)
Note over User,SettingsService: GET Storage Settings Flow
User->>Frontend: Load Storage Settings page
Frontend->>API: GET /storage-settings
API->>SettingsService: Retrieve current settings
SettingsService-->>API: Return settings (secrets masked)
API-->>Frontend: StorageSettingsResponse (masked)
Frontend->>Frontend: Initialize form fields
Frontend-->>User: Display current settings
end
rect rgb(240, 255, 240)
Note over User,SettingsService: PATCH Storage Settings Flow
User->>Frontend: Update storage location & credentials
Frontend->>Frontend: Build update payload (omit masked secrets)
Frontend->>API: PATCH /storage-settings
API->>API: Determine selected storage location
API->>API: Validate required credentials
alt AWS selected
API->>API: Require Access Key ID, Secret, Bucket
else Google Drive selected
API->>API: Require Service Account Key
else Local selected
API->>API: No credentials required
end
API->>SettingsService: Update settings (selective fields only)
SettingsService-->>API: Return updated settings
API-->>Frontend: StorageSettingsResponse (masked)
Frontend->>Frontend: Show success alert
Frontend-->>User: Settings saved
end
sequenceDiagram
participant Component as File Component
participant SettingsService
participant Storage as AWS/GDrive
rect rgb(255, 240, 240)
Note over Component,Storage: Component Using Global Storage (use_custom_storage=False)
Component->>Component: use_custom_storage = False
Component->>Component: Get selected storage location
alt Default is AWS
Component->>SettingsService: Fetch global AWS credentials
SettingsService-->>Component: Access Key, Secret, Bucket, Region
Component->>Storage: Initialize with global credentials
else Default is Google Drive
Component->>SettingsService: Fetch global Google Drive key
SettingsService-->>Component: Service Account Key, Folder ID
Component->>Storage: Initialize with global credentials
else Default is Local
Component->>Storage: Use local file system
end
Component->>Storage: Read/Write file
Storage-->>Component: Success
end
rect rgb(240, 220, 255)
Note over Component,Storage: Component Using Custom Storage (use_custom_storage=True)
Component->>Component: use_custom_storage = True
Component->>Component: Validate component-level credentials
alt Component AWS configured
Component->>Component: Validate s3_file_key, credentials
Component->>Storage: Initialize with component credentials
else Component Google Drive configured
Component->>Component: Validate service_account_key, file_id
Component->>Storage: Initialize with component credentials
end
Component->>Storage: Read/Write file
Storage-->>Component: Success
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Pre-merge checks and finishing touchesImportant Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (1 error, 3 warnings)
✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
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. Comment |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #11180 +/- ##
==========================================
+ Coverage 34.03% 34.08% +0.04%
==========================================
Files 1407 1413 +6
Lines 66661 66989 +328
Branches 9839 9890 +51
==========================================
+ Hits 22689 22832 +143
- Misses 42787 42967 +180
- Partials 1185 1190 +5
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 8
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/lfx/src/lfx/components/files_and_knowledge/save_file.py (1)
614-681: AWS env fallback conflicts with validation helper and prior security posture.In
_save_to_aws:
- For
use_custom_storage=Trueyou fall back toAWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEYenv vars when component inputs are missing.- Later you call
validate_aws_credentials(self), which inspectsself.aws_access_key_id,self.aws_secret_access_key, andself.bucket_name, not the local variables.- In the env‑fallback path, those attributes are never updated, so
validate_aws_credentialscan still fail even when env vars are present.- Separately, prior AWS components in this repo have required explicit credentials rather than inheriting environment/machine credentials for security in hosted environments. Based on learnings, this fallback is inconsistent with that pattern and could accidentally bind flows to host‑level AWS creds.
You should either:
- Drop the env fallback and require explicit component/global credentials, or
- If you really want env fallback, set
self.aws_access_key_id,self.aws_secret_access_key, andself.bucket_namein the custom path before callingvalidate_aws_credentials, and document the intended behavior.Given the earlier security stance, option (1) is preferable.
[specify_refactor]
Safer, simpler option: remove env fallback
- if use_custom: - # Get from component inputs or fall back to environment variables - aws_access_key_id = getattr(self, "aws_access_key_id", None) - if aws_access_key_id and hasattr(aws_access_key_id, "get_secret_value"): - aws_access_key_id = aws_access_key_id.get_secret_value() - if not aws_access_key_id: - aws_access_key_id = os.getenv("AWS_ACCESS_KEY_ID") - - aws_secret_access_key = getattr(self, "aws_secret_access_key", None) - if aws_secret_access_key and hasattr(aws_secret_access_key, "get_secret_value"): - aws_secret_access_key = aws_secret_access_key.get_secret_value() - if not aws_secret_access_key: - aws_secret_access_key = os.getenv("AWS_SECRET_ACCESS_KEY") - - bucket_name = getattr(self, "bucket_name", None) - if not bucket_name: - bucket_name = settings.object_storage_bucket_name - - aws_region = getattr(self, "aws_region", None) + if use_custom: + # Use only explicit component inputs for credentials + aws_access_key_id = getattr(self, "aws_access_key_id", None) + if aws_access_key_id and hasattr(aws_access_key_id, "get_secret_value"): + aws_access_key_id = aws_access_key_id.get_secret_value() + + aws_secret_access_key = getattr(self, "aws_secret_access_key", None) + if aws_secret_access_key and hasattr(aws_secret_access_key, "get_secret_value"): + aws_secret_access_key = aws_secret_access_key.get_secret_value() + + bucket_name = getattr(self, "bucket_name", None) + + aws_region = getattr(self, "aws_region", None)This keeps
_save_to_awsin line with the rest of the AWS components’ “explicit credentials only” policy and avoids the attribute vs local variable mismatch withvalidate_aws_credentials(self). Based on learnings, ...src/backend/base/langflow/initial_setup/starter_projects/News Aggregator.json (1)
1640-1682: Starter flow now depends on global storage defaults; docs still assume Local.The embedded
SaveToFileComponentcode now delegates storage selection to:
- Global
default_storage_locationwhenuse_custom_storage=False.- Per‑node
storage_locationwhenuse_custom_storage=True.However, the News Aggregator note still tells users the file will be written locally to
news-aggregated.json. If an instance is configured with a non‑Local global storage (e.g., AWS or Google Drive), this starter will now save to that provider instead, and the doc string will be misleading.Consider:
- Updating the note to mention that the target storage is controlled by global Storage Settings (with an optional per‑node override), or
- Defaulting
use_custom_storagetoTrueandstorage_locationto Local in this starter if you want it to stay strictly local regardless of global defaults.
🧹 Nitpick comments (5)
src/backend/tests/unit/test_storage_settings.py (1)
1-6: Consider removing unusedosimport after fixing assertions.The
osimport is only used for the problematicos.getenv()calls in assertions. After fixing those to use hardcoded expected values, you can remove this import.src/lfx/src/lfx/components/files_and_knowledge/file.py (1)
648-684: Consider potential side effects from mutatingselfwith global credentials.When
use_custom_storageis False, the code sets credentials directly onself(lines 680-683). This mutates the component instance, which could cause issues if:
- The component is inspected after execution (credentials would be visible).
- The component is reused with different settings.
Consider using a local dictionary for the S3 client config instead of setting attributes on
self.Proposed approach
else: # Use global settings if not settings.component_aws_access_key_id: msg = "AWS Access Key ID not configured in global storage settings" raise ValueError(msg) if not settings.component_aws_secret_access_key: msg = "AWS Secret Access Key not configured in global storage settings" raise ValueError(msg) if not settings.component_aws_default_bucket: msg = "AWS Default Bucket not configured in global storage settings" raise ValueError(msg) if not getattr(self, "s3_file_key", None): msg = "S3 File Key is required" raise ValueError(msg) - # Temporarily set credentials on self for create_s3_client - self.aws_access_key_id = settings.component_aws_access_key_id - self.aws_secret_access_key = settings.component_aws_secret_access_key - self.bucket_name = settings.component_aws_default_bucket - self.aws_region = settings.component_aws_default_region - s3_client = create_s3_client(self) + # Create a credentials object for the S3 client + from types import SimpleNamespace + creds = SimpleNamespace( + aws_access_key_id=settings.component_aws_access_key_id, + aws_secret_access_key=settings.component_aws_secret_access_key, + aws_region=settings.component_aws_default_region, + ) + s3_client = create_s3_client(creds) + # Set bucket_name for download call + self.bucket_name = settings.component_aws_default_bucketNote: This would require
create_s3_clientto work with any object having the required attributes, which it already does based on the relevant code snippet.src/frontend/src/pages/SettingsPage/pages/StorageSettingsPage/index.tsx (1)
55-77: Use a typed payload instead ofanyforupdates.The
updatesobject is currentlyany, even though the hook is already typed withUpdateStorageSettingsParams. Using the concrete type here will:
- Catch payload/field mismatches at compile time.
- Keep the frontend aligned with backend API evolution.
Proposed typing tweak
- const handleSave = () => { - const updates: any = { + const handleSave = () => { + const updates: UpdateStorageSettingsParams = { default_storage_location: storageLocation, };(Import
UpdateStorageSettingsParamsfrom the storage‑settings query module or its shared types definition.)src/backend/tests/unit/api/v2/test_storage_settings_validation.py (1)
32-185: Good AWS validation coverage; consider aligning Google Drive validation with runtime needs.The AWS tests thoroughly exercise:
- Missing credentials when switching to AWS.
- Partial credentials (only key id).
- Missing bucket.
- Successful configuration and masking behavior.
- Updates when AWS is already configured or when only some fields change.
For Google Drive, you only assert on the presence/absence of the service account key:
test_validation_fails_when_switching_to_google_drive_without_credentialstest_validation_passes_when_switching_to_google_drive_with_credentialsHowever, the runtime Google Drive path in
SaveToFileComponent._save_to_google_drive(seesrc/lfx/src/lfx/components/files_and_knowledge/save_file.py) also requires a default folder ID when using global settings. Right now:
- The API allows
default_storage_location="Google Drive"with only a key configured.- SaveToFile will later fail with “Google Drive default folder ID not configured in global storage settings”.
It may be worth:
- Extending
update_storage_settingsto also validatecomponent_google_drive_default_folder_idwhen switching to Google Drive, and- Adding a corresponding failing test case here (and a passing one where both key and folder id are provided), so the API rejects incomplete Google Drive setups early instead of deferring to the component.
src/backend/base/langflow/api/v2/storage_settings.py (1)
65-133: PATCH handler’s AWS validation is solid; Google Drive could also validate folder id.For AWS,
update_storage_settings:
- Derives
final_storage_locationfrom update/default.- Computes effective key id, secret, and bucket from the patch or existing settings.
- Validates all three when
final_storage_location == "AWS", mirroring component‑level requirements.For Google Drive, it currently only:
- Computes
final_gdrive_keyfrom update or existing settings.- Validates that the key is present when
final_storage_location == "Google Drive".Given
_save_to_google_driveinSaveToFileComponentrequires both a service account key and a default folder id when using global settings, you may want to also require a non‑emptycomponent_google_drive_default_folder_idhere when the final storage location is Google Drive. Otherwise the API will accept a configuration that still cannot be used by the file component.Illustrative change for Google Drive validation
if final_storage_location == "Google Drive": # Check if we're updating credentials or if they already exist - final_gdrive_key = settings.component_google_drive_service_account_key + final_gdrive_key = settings.component_google_drive_service_account_key if settings_update.component_google_drive_service_account_key is not None and not all( c == "*" for c in settings_update.component_google_drive_service_account_key ): final_gdrive_key = settings_update.component_google_drive_service_account_key + + final_gdrive_folder = ( + settings_update.component_google_drive_default_folder_id + if settings_update.component_google_drive_default_folder_id is not None + else settings.component_google_drive_default_folder_id + ) # Validate required Google Drive fields if not final_gdrive_key: raise HTTPException( status_code=400, detail="Google Drive Service Account Key is required when Google Drive storage is selected", ) + if not final_gdrive_folder: + raise HTTPException( + status_code=400, + detail="Google Drive Default Folder ID is required when Google Drive storage is selected", + )
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (21)
src/backend/base/langflow/api/router.pysrc/backend/base/langflow/api/v2/__init__.pysrc/backend/base/langflow/api/v2/storage_settings.pysrc/backend/base/langflow/initial_setup/starter_projects/Document Q&A.jsonsrc/backend/base/langflow/initial_setup/starter_projects/News Aggregator.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Text Sentiment Analysis.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.jsonsrc/backend/tests/unit/api/v2/test_storage_settings_validation.pysrc/backend/tests/unit/components/files_and_knowledge/test_storage_settings_integration.pysrc/backend/tests/unit/test_storage_settings.pysrc/frontend/src/controllers/API/helpers/constants.tssrc/frontend/src/controllers/API/queries/storage-settings/index.tssrc/frontend/src/controllers/API/queries/storage-settings/use-get-storage-settings.tssrc/frontend/src/controllers/API/queries/storage-settings/use-update-storage-settings.tssrc/frontend/src/pages/SettingsPage/index.tsxsrc/frontend/src/pages/SettingsPage/pages/StorageSettingsPage/index.tsxsrc/frontend/src/routes.tsxsrc/lfx/src/lfx/components/files_and_knowledge/file.pysrc/lfx/src/lfx/components/files_and_knowledge/save_file.pysrc/lfx/src/lfx/services/settings/base.py
🧰 Additional context used
📓 Path-based instructions (7)
src/frontend/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/frontend_development.mdc)
src/frontend/src/**/*.{ts,tsx}: Use React 18 with TypeScript for frontend development
Use Zustand for state management
Files:
src/frontend/src/controllers/API/queries/storage-settings/use-update-storage-settings.tssrc/frontend/src/controllers/API/helpers/constants.tssrc/frontend/src/controllers/API/queries/storage-settings/use-get-storage-settings.tssrc/frontend/src/pages/SettingsPage/pages/StorageSettingsPage/index.tsxsrc/frontend/src/routes.tsxsrc/frontend/src/pages/SettingsPage/index.tsxsrc/frontend/src/controllers/API/queries/storage-settings/index.ts
src/backend/**/*.py
📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)
src/backend/**/*.py: Use FastAPI async patterns withawaitfor async operations in component execution methods
Useasyncio.create_task()for background tasks and implement proper cleanup with try/except forasyncio.CancelledError
Usequeue.put_nowait()for non-blocking queue operations andasyncio.wait_for()with timeouts for controlled get operations
Files:
src/backend/base/langflow/api/v2/__init__.pysrc/backend/base/langflow/api/v2/storage_settings.pysrc/backend/base/langflow/api/router.pysrc/backend/tests/unit/api/v2/test_storage_settings_validation.pysrc/backend/tests/unit/test_storage_settings.pysrc/backend/tests/unit/components/files_and_knowledge/test_storage_settings_integration.py
src/backend/base/langflow/api/**/*.py
📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)
Backend API endpoints should be organized by version (v1/, v2/) under
src/backend/base/langflow/api/with specific modules for features (chat.py, flows.py, users.py, etc.)
Files:
src/backend/base/langflow/api/v2/__init__.pysrc/backend/base/langflow/api/v2/storage_settings.pysrc/backend/base/langflow/api/router.py
src/frontend/src/**/*.{tsx,jsx,css,scss}
📄 CodeRabbit inference engine (.cursor/rules/frontend_development.mdc)
Use Tailwind CSS for styling
Files:
src/frontend/src/pages/SettingsPage/pages/StorageSettingsPage/index.tsxsrc/frontend/src/routes.tsxsrc/frontend/src/pages/SettingsPage/index.tsx
src/frontend/src/**/*.{tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/frontend_development.mdc)
src/frontend/src/**/*.{tsx,jsx}: Implement dark mode support using the useDarkMode hook and dark store
Use Lucide React for icon components in the application
Files:
src/frontend/src/pages/SettingsPage/pages/StorageSettingsPage/index.tsxsrc/frontend/src/routes.tsxsrc/frontend/src/pages/SettingsPage/index.tsx
src/backend/tests/**/*.py
📄 CodeRabbit inference engine (.cursor/rules/testing.mdc)
src/backend/tests/**/*.py: Place backend unit tests insrc/backend/tests/directory, component tests insrc/backend/tests/unit/components/organized by component subdirectory, and integration tests accessible viamake integration_tests
Use same filename as component with appropriate test prefix/suffix (e.g.,my_component.py→test_my_component.py)
Use theclientfixture (FastAPI Test Client) defined insrc/backend/tests/conftest.pyfor API tests; it provides an asynchttpx.AsyncClientwith automatic in-memory SQLite database and mocked environment variables. Skip client creation by marking test with@pytest.mark.noclient
Inherit from the correctComponentTestBasefamily class located insrc/backend/tests/base.pybased on API access needs:ComponentTestBase(no API),ComponentTestBaseWithClient(needs API), orComponentTestBaseWithoutClient(pure logic). Provide three required fixtures:component_class,default_kwargs, andfile_names_mapping
Create comprehensive unit tests for all new backend components. If unit tests are incomplete, create a corresponding Markdown file documenting manual testing steps and expected outcomes
Test both sync and async code paths, mock external dependencies appropriately, test error handling and edge cases, validate input/output behavior, and test component initialization and configuration
Use@pytest.mark.asynciodecorator for async component tests and ensure async methods are properly awaited
Test background tasks usingasyncio.create_task()and verify completion withasyncio.wait_for()with appropriate timeout constraints
Test queue operations using non-blockingqueue.put_nowait()andasyncio.wait_for(queue.get(), timeout=...)to verify queue processing without blocking
Use@pytest.mark.no_blockbustermarker to skip the blockbuster plugin in specific tests
For database tests that may fail in batch runs, run them sequentially usinguv run pytest src/backend/tests/unit/test_database.pyr...
Files:
src/backend/tests/unit/api/v2/test_storage_settings_validation.pysrc/backend/tests/unit/test_storage_settings.pysrc/backend/tests/unit/components/files_and_knowledge/test_storage_settings_integration.py
**/test_*.py
📄 CodeRabbit inference engine (Custom checks)
**/test_*.py: Review test files for excessive use of mocks that may indicate poor test design - check if tests have too many mock objects that obscure what's actually being tested
Warn when mocks are used instead of testing real behavior and interactions, and suggest using real objects or test doubles when mocks become excessive
Ensure mocks are used appropriately for external dependencies only, not for core logic
Backend test files should follow the naming convention test_*.py with proper pytest structure
Test files should have descriptive test function names that explain what is being tested
Tests should be organized logically with proper setup and teardown
Consider including edge cases and error conditions for comprehensive test coverage
Verify tests cover both positive and negative scenarios where appropriate
For async functions in backend tests, ensure proper async testing patterns are used with pytest
For API endpoints, verify both success and error response testing
Files:
src/backend/tests/unit/api/v2/test_storage_settings_validation.pysrc/backend/tests/unit/test_storage_settings.pysrc/backend/tests/unit/components/files_and_knowledge/test_storage_settings_integration.py
🧠 Learnings (21)
📚 Learning: 2025-11-24T19:46:45.790Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/frontend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:45.790Z
Learning: Applies to src/frontend/src/**/*.{tsx,jsx} : Implement dark mode support using the useDarkMode hook and dark store
Applied to files:
src/frontend/src/controllers/API/queries/storage-settings/use-update-storage-settings.tssrc/frontend/src/controllers/API/queries/storage-settings/use-get-storage-settings.ts
📚 Learning: 2025-11-24T19:46:45.790Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/frontend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:45.790Z
Learning: Applies to src/frontend/src/**/{hooks,services}/**/*.{ts,tsx} : Use the useApi hook for API calls with proper error handling, including loading state, error state, and exception throwing
Applied to files:
src/frontend/src/controllers/API/queries/storage-settings/use-get-storage-settings.ts
📚 Learning: 2025-09-21T09:46:44.276Z
Learnt from: iann0036
Repo: langflow-ai/langflow PR: 9935
File: src/lfx/src/lfx/components/amazon/aws_api_call.py:35-48
Timestamp: 2025-09-21T09:46:44.276Z
Learning: Amazon components in the Langflow bundle consistently require explicit AWS credentials (aws_access_key_id and aws_secret_access_key with required=True) rather than falling back to environment/machine credentials for security reasons in hosted environments.
Applied to files:
src/lfx/src/lfx/components/files_and_knowledge/save_file.py
📚 Learning: 2025-11-24T19:46:09.104Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:09.104Z
Learning: Applies to src/backend/base/langflow/api/**/*.py : Backend API endpoints should be organized by version (v1/, v2/) under `src/backend/base/langflow/api/` with specific modules for features (chat.py, flows.py, users.py, etc.)
Applied to files:
src/backend/base/langflow/api/v2/storage_settings.pysrc/backend/base/langflow/api/router.py
📚 Learning: 2025-11-24T19:46:45.790Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/frontend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:45.790Z
Learning: Applies to src/frontend/src/stores/**/*.{ts,tsx} : Store state management code in stores/ directory using Zustand with typed state interfaces
Applied to files:
src/frontend/src/routes.tsx
📚 Learning: 2025-11-24T19:46:45.790Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/frontend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:45.790Z
Learning: Applies to src/frontend/src/**/*.{ts,tsx} : Use Zustand for state management
Applied to files:
src/frontend/src/routes.tsx
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Test both sync and async code paths, mock external dependencies appropriately, test error handling and edge cases, validate input/output behavior, and test component initialization and configuration
Applied to files:
src/backend/tests/unit/api/v2/test_storage_settings_validation.pysrc/backend/tests/unit/components/files_and_knowledge/test_storage_settings_integration.py
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Create comprehensive unit tests for all new backend components. If unit tests are incomplete, create a corresponding Markdown file documenting manual testing steps and expected outcomes
Applied to files:
src/backend/tests/unit/api/v2/test_storage_settings_validation.pysrc/backend/tests/unit/components/files_and_knowledge/test_storage_settings_integration.py
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Use `aiofiles` and `anyio.Path` for async file operations in tests; create temporary test files using `tmp_path` fixture and verify file existence and content
Applied to files:
src/backend/tests/unit/api/v2/test_storage_settings_validation.py
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Place backend unit tests in `src/backend/tests/` directory, component tests in `src/backend/tests/unit/components/` organized by component subdirectory, and integration tests accessible via `make integration_tests`
Applied to files:
src/backend/tests/unit/api/v2/test_storage_settings_validation.pysrc/backend/tests/unit/components/files_and_knowledge/test_storage_settings_integration.py
📚 Learning: 2025-12-19T18:04:08.938Z
Learnt from: Jkavia
Repo: langflow-ai/langflow PR: 11111
File: src/backend/tests/unit/api/v2/test_workflow.py:10-11
Timestamp: 2025-12-19T18:04:08.938Z
Learning: In the langflow-ai/langflow repository, pytest-asyncio is configured with asyncio_mode = 'auto' in pyproject.toml. This means you do not need to decorate test functions or classes with pytest.mark.asyncio; async tests are auto-detected and run by pytest-asyncio. When reviewing tests, ensure they rely on this configuration (i.e., avoid unnecessary pytest.mark.asyncio decorators) and that tests living under any tests/ path (e.g., src/.../tests/**/*.py) follow this convention. If a test explicitly requires a different asyncio policy, document it and adjust the config accordingly.
Applied to files:
src/backend/tests/unit/api/v2/test_storage_settings_validation.pysrc/backend/tests/unit/test_storage_settings.pysrc/backend/tests/unit/components/files_and_knowledge/test_storage_settings_integration.py
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Test component versioning and backward compatibility using `file_names_mapping` fixture with `VersionComponentMapping` objects mapping component files across Langflow versions
Applied to files:
src/backend/tests/unit/components/files_and_knowledge/test_storage_settings_integration.py
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Inherit from the correct `ComponentTestBase` family class located in `src/backend/tests/base.py` based on API access needs: `ComponentTestBase` (no API), `ComponentTestBaseWithClient` (needs API), or `ComponentTestBaseWithoutClient` (pure logic). Provide three required fixtures: `component_class`, `default_kwargs`, and `file_names_mapping`
Applied to files:
src/backend/tests/unit/components/files_and_knowledge/test_storage_settings_integration.py
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Test component build config updates by calling `to_frontend_node()` to get the node template, then calling `update_build_config()` to apply configuration changes
Applied to files:
src/backend/tests/unit/components/files_and_knowledge/test_storage_settings_integration.py
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Use same filename as component with appropriate test prefix/suffix (e.g., `my_component.py` → `test_my_component.py`)
Applied to files:
src/backend/tests/unit/components/files_and_knowledge/test_storage_settings_integration.py
📚 Learning: 2025-08-05T22:51:27.961Z
Learnt from: edwinjosechittilappilly
Repo: langflow-ai/langflow PR: 0
File: :0-0
Timestamp: 2025-08-05T22:51:27.961Z
Learning: The TestComposioComponentAuth test in src/backend/tests/unit/components/bundles/composio/test_base_composio.py demonstrates proper integration testing patterns for external API components, including real API calls with mocking for OAuth completion, comprehensive resource cleanup, and proper environment variable handling with pytest.skip() fallbacks.
Applied to files:
src/backend/tests/unit/components/files_and_knowledge/test_storage_settings_integration.py
📚 Learning: 2025-11-24T19:46:09.104Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:09.104Z
Learning: Applies to tests/unit/components/**/*.py : Create unit tests in `src/backend/tests/unit/components/` mirroring the component directory structure, using `ComponentTestBaseWithClient` or `ComponentTestBaseWithoutClient` base classes
Applied to files:
src/backend/tests/unit/components/files_and_knowledge/test_storage_settings_integration.py
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: When adding a new component test, inherit from the correct `ComponentTestBase` class and provide the three required fixtures (`component_class`, `default_kwargs`, `file_names_mapping`) to greatly reduce boilerplate and enforce version compatibility
Applied to files:
src/backend/tests/unit/components/files_and_knowledge/test_storage_settings_integration.py
📚 Learning: 2025-11-24T19:46:45.790Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/frontend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:45.790Z
Learning: Applies to src/frontend/src/hooks/**/*.{ts,tsx} : Export hooks as custom hooks (useHookName) from the hooks/ directory
Applied to files:
src/frontend/src/controllers/API/queries/storage-settings/index.ts
📚 Learning: 2025-11-24T19:46:45.790Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/frontend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:45.790Z
Learning: Applies to src/frontend/src/utils/**/*.{ts,tsx} : Use named exports for utility functions in the utils/ directory
Applied to files:
src/frontend/src/controllers/API/queries/storage-settings/index.ts
📚 Learning: 2025-06-23T12:46:42.048Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/frontend_development.mdc:0-0
Timestamp: 2025-06-23T12:46:42.048Z
Learning: Use Zustand for state management in React components within the frontend; stores should expose both state and setter functions, and be imported via hooks (e.g., useMyStore).
Applied to files:
src/frontend/src/controllers/API/queries/storage-settings/index.ts
🧬 Code graph analysis (10)
src/frontend/src/controllers/API/queries/storage-settings/use-update-storage-settings.ts (4)
src/frontend/src/types/api/index.ts (1)
useMutationFunctionType(291-309)src/frontend/src/controllers/API/services/request-processor.ts (1)
UseRequestProcessor(14-54)src/frontend/src/controllers/API/queries/storage-settings/use-get-storage-settings.ts (1)
StorageSettings(7-15)src/frontend/src/controllers/API/helpers/constants.ts (1)
getURL(44-54)
src/frontend/src/controllers/API/queries/storage-settings/use-get-storage-settings.ts (3)
src/frontend/src/types/api/index.ts (1)
useQueryFunctionType(266-277)src/frontend/src/controllers/API/services/request-processor.ts (1)
UseRequestProcessor(14-54)src/frontend/src/controllers/API/helpers/constants.ts (1)
getURL(44-54)
src/frontend/src/pages/SettingsPage/pages/StorageSettingsPage/index.tsx (3)
src/frontend/src/controllers/API/queries/storage-settings/use-get-storage-settings.ts (1)
useGetStorageSettings(17-38)src/frontend/src/controllers/API/queries/storage-settings/use-update-storage-settings.ts (1)
useUpdateStorageSettings(18-44)src/frontend/src/components/common/genericIconComponent/index.tsx (1)
ForwardedIconComponent(23-170)
src/lfx/src/lfx/components/files_and_knowledge/save_file.py (3)
src/lfx/src/lfx/inputs/inputs.py (1)
BoolInput(533-546)src/lfx/src/lfx/services/interfaces.py (1)
settings(55-57)src/lfx/src/lfx/base/data/cloud_storage_utils.py (2)
validate_aws_credentials(13-30)create_google_drive_service(127-156)
src/backend/base/langflow/api/v2/storage_settings.py (2)
src/lfx/src/lfx/services/interfaces.py (1)
settings(55-57)src/backend/tests/unit/api/v2/test_storage_settings_validation.py (1)
settings_service(14-19)
src/frontend/src/routes.tsx (1)
src/frontend/src/pages/SettingsPage/pages/StorageSettingsPage/index.tsx (1)
StorageSettingsPage(20-244)
src/frontend/src/pages/SettingsPage/index.tsx (1)
src/frontend/src/components/common/genericIconComponent/index.tsx (1)
ForwardedIconComponent(23-170)
src/backend/tests/unit/api/v2/test_storage_settings_validation.py (1)
src/backend/base/langflow/api/v2/storage_settings.py (2)
StorageSettingsUpdate(25-34)update_storage_settings(66-179)
src/backend/tests/unit/test_storage_settings.py (1)
src/lfx/src/lfx/services/settings/base.py (1)
Settings(60-643)
src/lfx/src/lfx/components/files_and_knowledge/file.py (3)
src/lfx/src/lfx/inputs/inputs.py (1)
BoolInput(533-546)src/backend/base/langflow/services/deps.py (1)
get_settings_service(125-138)src/lfx/src/lfx/base/data/cloud_storage_utils.py (3)
validate_aws_credentials(13-30)create_s3_client(33-59)create_google_drive_service(127-156)
⏰ 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). (60)
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 39/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 44/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 48/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 32/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 49/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 47/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 43/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 24/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 45/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 37/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 42/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 27/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 28/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 41/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 15/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 35/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 29/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 23/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 22/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 26/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 40/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 46/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 34/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 21/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 50/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 38/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 10/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 30/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 31/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 36/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 25/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 1/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 33/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 3/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 14/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 11/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 9/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 7/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 20/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 19/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 8/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 18/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 17/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 13/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 16/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 12/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 5/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 2/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 4/50
- GitHub Check: Run Frontend Tests / Playwright Tests - Shard 6/50
- GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 1
- GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 4
- GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 3
- GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 5
- GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 2
- GitHub Check: Test Docker Images / Test docker images
- GitHub Check: Run Backend Tests / Integration Tests - Python 3.10
- GitHub Check: Test Starter Templates
- GitHub Check: Run Ruff Check and Format
- GitHub Check: test-starter-projects
🔇 Additional comments (22)
src/frontend/src/controllers/API/queries/storage-settings/use-update-storage-settings.ts (1)
18-29: LGTM!The hook signature, interface, and mutation function are well-structured and follow the existing patterns in the codebase.
src/lfx/src/lfx/components/files_and_knowledge/file.py (3)
384-405: LGTM!The
update_build_configlogic for theuse_custom_storagetoggle correctly shows/hides the storage location and related credential fields based on the toggle state.
586-605: LGTM!The
_get_selected_storage_locationmethod correctly differentiates between component-level and global settings, with appropriate fallback to "Local" when component storage location is not specified.
718-744: LGTM!The Google Drive credential handling correctly retrieves credentials from either component or global settings without unnecessary mutation of
self.src/backend/tests/unit/components/files_and_knowledge/test_storage_settings_integration.py (1)
12-37: LGTM!These tests correctly verify that
_get_selected_storage_locationrespects theuse_custom_storagetoggle and appropriately falls back to global settings or uses component-level overrides.src/frontend/src/routes.tsx (1)
140-140: LGTM!The storage settings route is correctly added under the settings path, following the same pattern as other settings pages like
global-variablesandapi-keys.Note: Unlike
GeneralPagewhich is wrapped inAuthSettingsGuard, this route has no guard. Please verify this is intentional - if storage settings should be restricted based on user permissions, consider adding the appropriate guard.src/frontend/src/pages/SettingsPage/index.tsx (1)
41-50: LGTM!The Storage sidebar navigation item is correctly added with appropriate icon and href, following the existing pattern for settings navigation items.
src/frontend/src/controllers/API/helpers/constants.ts (1)
39-39: LGTM!The
STORAGE_SETTINGSURL constant is correctly added and follows the existing naming conventions. The kebab-case value aligns with REST API best practices.src/frontend/src/controllers/API/queries/storage-settings/index.ts (1)
1-2: LGTM! Clean barrel export pattern.The barrel export pattern appropriately aggregates the storage settings hooks, making them accessible from a single import path. This follows the established codebase conventions.
src/backend/base/langflow/api/router.py (1)
30-30: LGTM! Consistent v2 router integration.The storage settings router is properly imported and registered following the established pattern for v2 API endpoints. The implementation aligns with the coding guidelines for organizing backend API endpoints by version.
Also applies to: 65-65
src/backend/base/langflow/api/v2/__init__.py (1)
4-4: LGTM! Proper public API export.The storage settings router is correctly imported and added to
__all__, following the established pattern for exposing v2 API routers. This ensures the router can be properly imported by consuming modules.Also applies to: 10-10
src/lfx/src/lfx/services/settings/base.py (1)
202-216: LGTM! Well-structured storage settings fields.The new global component storage settings are properly defined with clear naming, appropriate types, and helpful docstrings. The fields support both AWS S3 and Google Drive storage options with sensible defaults and nullable credentials.
Note: Sensitive fields like
component_aws_secret_access_keyandcomponent_google_drive_service_account_keyare stored as plain strings here, which is appropriate for a settings model that loads from environment variables. As per the PR summary, masking of these sensitive values is handled at the API endpoint level when returning settings to clients.src/frontend/src/controllers/API/queries/storage-settings/use-get-storage-settings.ts (2)
7-15: LGTM! Interface matches backend settings model.The
StorageSettingsinterface properly mirrors the backend Settings model fields introduced insrc/lfx/src/lfx/services/settings/base.py, with appropriate nullable types for optional credentials and a requireddefault_storage_locationfield.
17-38: LGTM! Well-implemented query hook following established patterns.The hook implementation properly follows the codebase conventions:
- Uses
UseRequestProcessorfor standardized query behavior with retry logic and error handling- Disables
refetchOnWindowFocus(appropriate for infrequently-changing settings)- Provides proper TypeScript typing throughout
- Allows caller customization via options spread
- Uses stable query key for effective caching
The hook depends on the
STORAGE_SETTINGSURL constant referenced in the AI summary as being added tosrc/frontend/src/controllers/API/helpers/constants.ts. TypeScript'skeyof typeof URLstype constraint ensures compile-time safety for this dependency.Based on learnings, the use of
UseRequestProcessorfor API calls with proper error handling, loading state, and retry logic aligns with frontend development best practices.src/lfx/src/lfx/components/files_and_knowledge/save_file.py (3)
55-187: Component/global storage override wiring looks consistent.The new
use_custom_storagetoggle plusupdate_build_configlogic cleanly separates:
- Global default behavior (
use_custom_storage=False→ hide storage‑specific fields, rely on SettingsService).- Per‑component overrides (
use_custom_storage=True→ show location + provider‑specific fields).Dynamic show/advanced flags for AWS and Google Drive fields match the storage choice and keep the UI constrained.
547-567: Global vs per‑component storage selection behavior is clear.
_get_selected_storage_locationcorrectly:
- Uses
storage_locationwhenuse_custom_storageis enabled.- Falls back to
get_settings_service().settings.default_storage_locationotherwise.This aligns SaveToFile with the new global storage settings, while preserving explicit per‑component overrides when requested.
724-813: Google Drive global/custom split and error messages look good.
_save_to_google_drive:
- Enforces both
service_account_keyandfolder_idforuse_custom_storage=True.- For global mode, requires
component_google_drive_service_account_keyandcomponent_google_drive_default_folder_idin settings before proceeding.- Reuses
create_google_drive_servicewith full Drive scope and builds clear error messages when folder access fails.This is consistent with the global storage model and provides helpful feedback when misconfigured.
src/backend/base/langflow/initial_setup/starter_projects/News Aggregator.json (1)
1663-2082: SaveToFile template and embedded code are aligned; added override input looks correct.Within the
SaveToFile-VVVVbnode:
metadata.code_hashpoints to the updatedSaveToFileComponentimplementation that includesuse_custom_storage.- The new
use_custom_storagefield is present intemplatewith matching name, display name, info, andreal_time_refresh=True.- Field ordering and options for
storage_location, formats, and credential fields are consistent with the Python component.This keeps the starter’s embedded component definition in sync with the runtime class and exposes the override toggle as expected.
src/backend/tests/unit/api/v2/test_storage_settings_validation.py (1)
13-30: SettingsService fixture and mock_user are appropriate for unit‑level API testing.The
settings_servicefixture isolates settings into a tmp config dir, andmock_useris a simpleMagicMockthat satisfies the dependency without over‑mocking. This is a good balance for these pure validation tests.src/backend/base/langflow/api/v2/storage_settings.py (3)
13-35: Models cleanly separate response vs update concerns.
StorageSettingsResponseandStorageSettingsUpdateprovide:
- A clear, minimal shape for what’s exposed to the client.
- Optional fields in the update model so PATCH can be truly partial.
This mirrors how the handler logic uses “is not None” to decide when to apply updates and keeps masking handled only at the response layer.
37-62: GET handler correctly masks secrets while exposing non‑sensitive fields.
get_storage_settings:
- Reads from
settings_service.settings.- Replaces non‑empty
component_aws_secret_access_key/component_google_drive_service_account_keywith"********"before returning.- Leaves non‑secret fields (location, bucket, region, folder id) intact.
This matches the masking strategy used in the PATCH response and avoids leaking real secrets through the API.
134-179: Partial update + masking flow is well‑implemented.The PATCH handler:
- Applies only fields where the update model sets a non‑
Nonevalue, allowing true partial updates.- Skips overwriting secrets when the client sends masked values (all
*s).- Recomputes the masked secrets for the response from the stored settings rather than echoing back input.
This keeps the API ergonomic for clients while maintaining secrecy of credential material.
src/backend/tests/unit/components/files_and_knowledge/test_storage_settings_integration.py
Show resolved
Hide resolved
src/backend/tests/unit/components/files_and_knowledge/test_storage_settings_integration.py
Show resolved
Hide resolved
src/backend/tests/unit/components/files_and_knowledge/test_storage_settings_integration.py
Show resolved
Hide resolved
src/frontend/src/controllers/API/queries/storage-settings/use-update-storage-settings.ts
Show resolved
Hide resolved
src/frontend/src/pages/SettingsPage/pages/StorageSettingsPage/index.tsx
Outdated
Show resolved
Hide resolved
…update-storage-settings.ts Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
…index.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Changes SummaryThis PR introduces a comprehensive global storage settings management system for Langflow file components. It adds a new API v2 endpoint ( Type: feature Components Affected: API v2 Storage Settings Router, Frontend Storage Settings Page, File Component (Read File), Save File Component (Write File), Settings Service Configuration, Storage Settings Mixin (new), Frontend API Queries/Mutations Files Changed
Architecture Impact
Risk Areas: Credential Security: Secret masking strategy (asterisks) could be bypassed if user re-sends masked value. Need validation to prevent sending masked-only credentials., Database Transaction Safety: Async session management in storage_settings.py with commit at end - potential for inconsistent state if update partially fails, Settings Source Priority Change: Modified settings_sources() tuple order could affect configuration loading precedence for all Settings fields, Field Visibility Toggle: Use_custom_storage field visibility toggle logic duplicated across file.py and save_file.py could cause inconsistencies, Credential Validation Logic: AWS and Google Drive credential validation happens both at API and component level - potential for inconsistent validation, Error Handling: HTTP 400 errors in PATCH endpoint for validation; no retry logic or detailed error reporting in frontend Suggestions
Full review in progress... | Powered by diffray |
Review Summary
No validation results Review ID: |
This pull request introduces a new API endpoint for managing global storage settings, specifically for file components, and integrates it into the existing API router structure. The main focus is to provide secure, validated access to storage configuration (such as AWS and Google Drive) via new
GETandPATCHendpoints. Additionally, the new router is registered with the API, and a code hash update is made in a starter project.API Enhancements:
storage_settings_routerto the API v2, exposing/storage-settingsendpoints for retrieving and updating global storage settings. This includes secure masking of sensitive fields and validation for required credentials based on the selected storage provider. (src/backend/base/langflow/api/v2/storage_settings.py)storage_settings_routerin the API v2 initialization and included it in the main API router, making the new endpoints accessible. (src/backend/base/langflow/api/v2/__init__.py,src/backend/base/langflow/api/router.py) [1] [2] [3]Other updates:
code_hashin the News Aggregator starter project metadata. (src/backend/base/langflow/initial_setup/starter_projects/News Aggregator.json)Summary by CodeRabbit
Release Notes
✏️ Tip: You can customize this high-level summary in your review settings.