feat: Added backend routes to export workflows + datasets to google drive#6447
feat: Added backend routes to export workflows + datasets to google drive#6447Sentiaus wants to merge 6 commits into
Conversation
- Add getDriveApiKey endpoint to GoogleAuthResource - Add exportDatasetToDrive and exportFileToDrive endpoints with session URI validation to prevent SSRF - Add googleApiKey field to UserSystemConfig - Add unit tests for Drive export validation logic Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Required by UserSystemConfig for the Drive export endpoints. Configure via USER_SYS_GOOGLE_CLIENT_SECRET and USER_SYS_GOOGLE_API_KEY environment variables or set values directly in a local override. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Validates session URI, checks read access, fetches workflow JSON from DB, and PUTs to the Drive session URI — consistent with DatasetResource export. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Automated Reviewer SuggestionsBased on the
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #6447 +/- ##
============================================
+ Coverage 55.27% 58.79% +3.51%
- Complexity 2991 3385 +394
============================================
Files 1117 1120 +3
Lines 43258 43595 +337
Branches 4668 4713 +45
============================================
+ Hits 23912 25630 +1718
+ Misses 17938 16542 -1396
- Partials 1408 1423 +15
*This pull request uses carry forward flags. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
| config | throughput | MB/s | latency | max Δ latest / 7d | |
|---|---|---|---|---|---|
| 🔴 | bs=10 sw=10 sl=64 | 412 | 0.251 | 22,744/35,085/35,085 us | 🔴 +14.2% / 🔴 +147.9% |
| 🔴 | bs=100 sw=10 sl=64 | 914 | 0.558 | 107,059/134,537/134,537 us | 🔴 +20.4% / 🔴 +37.6% |
| ⚪ | bs=1000 sw=10 sl=64 | 1,102 | 0.673 | 902,472/1,012,393/1,012,393 us | ⚪ within ±5% / 🔴 +7.5% |
Baseline details
Latest main c7473a1 from same runner
| config | metric | PR | latest main | 7d avg | Δ latest | Δ 7d |
|---|---|---|---|---|---|---|
| bs=10 sw=10 sl=64 | throughput | 412 tuples/sec | 455 tuples/sec | 847.3 tuples/sec | -9.5% | -51.4% |
| bs=10 sw=10 sl=64 | MB/s | 0.251 MB/s | 0.278 MB/s | 0.517 MB/s | -9.7% | -51.5% |
| bs=10 sw=10 sl=64 | p50 | 22,744 us | 19,911 us | 11,621 us | +14.2% | +95.7% |
| bs=10 sw=10 sl=64 | p95 | 35,085 us | 33,454 us | 14,154 us | +4.9% | +147.9% |
| bs=10 sw=10 sl=64 | p99 | 35,085 us | 33,454 us | 19,069 us | +4.9% | +84.0% |
| bs=100 sw=10 sl=64 | throughput | 914 tuples/sec | 1,003 tuples/sec | 1,104 tuples/sec | -8.9% | -17.2% |
| bs=100 sw=10 sl=64 | MB/s | 0.558 MB/s | 0.612 MB/s | 0.674 MB/s | -8.8% | -17.2% |
| bs=100 sw=10 sl=64 | p50 | 107,059 us | 98,330 us | 91,279 us | +8.9% | +17.3% |
| bs=100 sw=10 sl=64 | p95 | 134,537 us | 111,747 us | 97,771 us | +20.4% | +37.6% |
| bs=100 sw=10 sl=64 | p99 | 134,537 us | 111,747 us | 107,798 us | +20.4% | +24.8% |
| bs=1000 sw=10 sl=64 | throughput | 1,102 tuples/sec | 1,103 tuples/sec | 1,127 tuples/sec | -0.1% | -2.2% |
| bs=1000 sw=10 sl=64 | MB/s | 0.673 MB/s | 0.673 MB/s | 0.688 MB/s | 0.0% | -2.2% |
| bs=1000 sw=10 sl=64 | p50 | 902,472 us | 908,979 us | 902,553 us | -0.7% | -0.0% |
| bs=1000 sw=10 sl=64 | p95 | 1,012,393 us | 1,026,081 us | 941,491 us | -1.3% | +7.5% |
| bs=1000 sw=10 sl=64 | p99 | 1,012,393 us | 1,026,081 us | 979,025 us | -1.3% | +3.4% |
Raw CSV
config_idx,batch_size,schema_width,string_len,num_batches,total_ms,total_tuples,total_bytes,tuples_per_sec,mb_per_sec,lat_p50_us,lat_p95_us,lat_p99_us
0,10,10,64,20,486.00,200,128000,412,0.251,22743.66,35085.16,35085.16
1,100,10,64,20,2188.24,2000,1280000,914,0.558,107058.69,134537.09,134537.09
2,1000,10,64,20,18144.75,20000,12800000,1102,0.673,902472.17,1012392.81,1012392.81|
Hi @Sentiaus, could you please make the PR title more informative? Also I am lack of context, there is no issue or discussion linked in the PR description, could you please add that and hopefully that can make the description shorter? |
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@Yicong-Huang sorry, I was making a last revision to the PR. Added the discussion and previous PR that I just closed. This is related to the google drive export discussion. |
What changes were proposed in this PR?
This PR adds server-side Google Drive export endpoints for datasets and workflows.
This PR relates to
New endpoints:
POST /dataset/{did}/drive-export— Exports a dataset version (specified bydvidorlatest=true) as a zip archive directly to a Google Drive resumable upload session URI.POST /dataset/drive-export/file— Exports a single file from a dataset version to Drive.POST /workflow/{wid}/export/drive— Exports a workflow's JSON content to Drive.Security:
https://www.googleapis.com/upload/drive/before making any outbound connection, preventing SSRF.isDownloadableflag before streaming data.WorkflowAccessResource.Size limits:
DRIVE_EXPORT_MAX_DATASET_BYTES). The zip is built in memory before the PUT to Drive; this limit will be lifted once chunked/streaming resumable upload is implemented.DRIVE_EXPORT_MAX_FILE_BYTES) — Google Drive's resumable upload ceiling.DRIVE_EXPORT_MAX_BYTES) since the JSON content is read into a byte array before upload.Config (
user-system.conf):clientSecretandapiKeyfields (empty by default, overridable viaUSER_SYS_GOOGLE_CLIENT_SECRET/USER_SYS_GOOGLE_API_KEYenv vars) so the frontend can fetch them fromGoogleAuthResource.GoogleAuthResource:GET /auth/google/drive/apikeyendpoint returningUserSystemConfig.googleApiKeyso the frontend can initialize the Google Picker without embedding credentials in the build.Any related issues, documentation, discussions?
Part of the Google Drive export feature. The frontend PR (stacked on this one) wires up the UI.
#4240
#5721 (old PR. Decided to close as this is much cleaner)
How was this PR tested?
DatasetResourceSpec— new integration tests (usingMockTexeraDB+MockLakeFStestcontainers) cover:400 Bad Request)403when the dataset is not downloadable400when bothdvidandlatestare provided (or neither)WorkflowResourceendpoint tested manually (recompile + restart required to pick up the new route).https://www.googleapis.com/upload/drive/URI returns400.Was this PR authored or co-authored using generative AI tooling?
Generated-by: Claude Sonnet 4.6