|
39 | 39 | from user_management_module.utils.user_utils import get_current_user |
40 | 40 | from plugins_module.services.dynamic_query_service import DynamicQueryService |
41 | 41 | from db_repo_module.cache.cache_manager import CacheManager |
42 | | -from ..utils.helper import generate_cache_key, validate_yaml_query |
| 42 | +from ..utils.helper import ( |
| 43 | + generate_cache_key, |
| 44 | + generate_export_filename_hash, |
| 45 | + validate_yaml_query, |
| 46 | +) |
43 | 47 | import csv |
44 | 48 | import io |
45 | 49 | import yaml |
@@ -765,9 +769,8 @@ async def export_dynamic_query_csv( |
765 | 769 | cloud_manager: CloudStorageManager = Depends( |
766 | 770 | Provide[PluginsContainer.cloud_manager] |
767 | 771 | ), |
768 | | - config: PluginsContainer.config.provided = Depends( |
769 | | - Provide[PluginsContainer.config] |
770 | | - ), |
| 772 | + config: dict = Depends(Provide[PluginsContainer.config]), |
| 773 | + force_fetch: int = Query(0), |
771 | 774 | ): |
772 | 775 | """Execute the dynamic query and return results as a downloadable CSV file.""" |
773 | 776 | role_id, user_id, _ = get_current_user(request) |
@@ -804,6 +807,41 @@ async def export_dynamic_query_csv( |
804 | 807 | rls_filters = fetch_data_filters(rls_filters) |
805 | 808 | rls_filter_str = f"{ ' $and '.join(rls_filters)}" |
806 | 809 |
|
| 810 | + # Bucket and filename: hash of $filter, limit, offset, dynamic_query_params |
| 811 | + provider = config['cloud_config']['cloud_provider'] |
| 812 | + bucket_name = ( |
| 813 | + config['aws']['aws_asset_storage_bucket'] |
| 814 | + if provider == 'aws' |
| 815 | + else config['gcp']['gcp_asset_storage_bucket'] |
| 816 | + ) |
| 817 | + export_hash = generate_export_filename_hash( |
| 818 | + filter=filter, |
| 819 | + limit=limit, |
| 820 | + offset=offset, |
| 821 | + params=dynamic_query_params.params if dynamic_query_params else None, |
| 822 | + ) |
| 823 | + filename = f'export_{query_id}_{export_hash}.csv' |
| 824 | + file_key = f'dynamic_query_exports/{filename}' |
| 825 | + |
| 826 | + # If not force_fetch, return existing file from bucket if present |
| 827 | + if not force_fetch: |
| 828 | + existing_keys, _ = cloud_manager.list_files( |
| 829 | + bucket_name=bucket_name, |
| 830 | + prefix=file_key, |
| 831 | + page_size=1, |
| 832 | + page_number=1, |
| 833 | + ) |
| 834 | + if existing_keys and existing_keys[0] == file_key: |
| 835 | + signed_url = cloud_manager.generate_presigned_url( |
| 836 | + bucket_name=bucket_name, key=file_key, type='GET' |
| 837 | + ) |
| 838 | + return JSONResponse( |
| 839 | + status_code=status.HTTP_200_OK, |
| 840 | + content=response_formatter.buildSuccessResponse( |
| 841 | + {'export_url': signed_url} |
| 842 | + ), |
| 843 | + ) |
| 844 | + |
807 | 845 | datasource_plugin = DatasourcePlugin(datasource_type, datasource_config) |
808 | 846 | res: Dict[str, Any] = await datasource_plugin.execute_dynamic_query( |
809 | 847 | yaml_query, |
@@ -833,30 +871,15 @@ async def export_dynamic_query_csv( |
833 | 871 |
|
834 | 872 | serialized_res = serialize_values(res[first_key]['result']) |
835 | 873 |
|
836 | | - # Convert rows to CSV bytes |
| 874 | + # Convert rows to CSV bytes and store in bucket |
837 | 875 | csv_bytes = _serialized_rows_to_csv(serialized_res) |
838 | | - filename = f'export_{query_id}.csv' |
839 | | - |
840 | | - # Store CSV in main application bucket under dynamic_query_updates folder |
841 | | - # and return a signed URL to the file |
842 | | - provider = config.cloud_config.cloud_provider |
843 | | - bucket_name = ( |
844 | | - config.aws.aws_asset_storage_bucket |
845 | | - if provider == 'aws' |
846 | | - else config.gcp.gcp_asset_storage_bucket |
847 | | - ) |
848 | | - |
849 | | - file_key = f'dynamic_query_updates/{filename}' |
850 | | - |
851 | | - # Save the CSV to cloud storage |
852 | 876 | cloud_manager.save_small_file( |
853 | 877 | file_content=csv_bytes, |
854 | 878 | bucket_name=bucket_name, |
855 | 879 | key=file_key, |
856 | 880 | content_type='text/csv', |
857 | 881 | ) |
858 | 882 |
|
859 | | - # Generate a signed URL for downloading the file |
860 | 883 | signed_url = cloud_manager.generate_presigned_url( |
861 | 884 | bucket_name=bucket_name, key=file_key, type='GET' |
862 | 885 | ) |
|
0 commit comments