Skip to content

feat(file-service): add model management API (metadata + access control)#6869

Draft
tanishqgandhi1908 wants to merge 22 commits into
apache:mainfrom
tanishqgandhi1908:feat/model-management-api
Draft

feat(file-service): add model management API (metadata + access control)#6869
tanishqgandhi1908 wants to merge 22 commits into
apache:mainfrom
tanishqgandhi1908:feat/model-management-api

Conversation

@tanishqgandhi1908

Copy link
Copy Markdown
Contributor

What changes were proposed in this PR?

Adds the metadata + access-control half of the model management API. Model version upload and PyTorch
file validation follow in a separate PR.

  • Schema: model_user_access table in texera_ddl.sql + idempotent migration sql/updates/31.sql (changeSet 31).

  • ModelResource (@Path("/model"))

Method Path Description
POST /create Create a model; provisions LakeFS repo model-{mid}, rolls the DB row back if repo init fails, grants the owner WRITE. Stores framework (defaults pytorch) and format.
DELETE /{mid} Delete a model (owner-only): removes the LakeFS repo, the S3 directory, and the row.
POST /update/name Rename (write access; validates name; rejects duplicate).
POST /update/description Update description (write access).
POST /{mid}/update/publicity Toggle is_public (write access).
POST /{mid}/update/downloadable Toggle is_downloadable (owner-only).
GET /list Models the user can access, plus public models.
GET /{mid} Get a model the user can read.
GET /public/{mid} Get a public model (unauthenticated).

ModelAccessResource (@Path("/access/model")) — owner/{mid}, list/{mid}, grant/{mid}/{email}/{privilege}, revoke/{mid}/{email} (all write-access-guarded), backed by model_user_access.

  • Both registered in FileService; storage/util layer reused unchanged.

Stacked on #6860 (#6497) → #6502 (#6495); its diff shows their commits until they
merge.

Any related issues, documentation, discussions?

Part of #6498, umbrella #6494.

How was this PR tested?

New tests: ModelResourceSpec (22 — create/get/list/delete/update/toggle, incl. access filtering, duplicate-name and forbidden paths, LakeFS-404 → 404) and ModelAccessResourceSpec (28 — privilege helpers + grant/list/revoke). Run: sbt "FileService/testOnly *ModelResourceSpec *ModelAccessResourceSpec" — all green; scalafixAll + scalafmtAll clean.

Was this PR authored or co-authored using generative AI tooling?

Generated-by: Claude Code (Claude Opus 4.8)

aicam and others added 22 commits July 1, 2026 13:57
… tests

Review fixes on apache#5911: use dataset owner email in retrieveLatestDatasetVersion,
replace brittle Option.get/.head with headOption, strip datasets prefix on
selection-modal reopen, clarify FileResolver docs; add FileResolver/DatasetFileNode
and frontend path-helper tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The datasets logical-path prefix strips four leading segments
(datasets/owner/dataset/version); update the cover-image test's input
path to include the prefix so the extracted relative path is the file
name, not an empty string.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Now that models are coming as a separate resource/table, the leading
resource-type segment is what selects the backing table, so an unprefixed
path can no longer be routed unambiguously. Make the "datasets" prefix
required instead of a tolerated fallback, and migrate existing data.

- FileResolver: a dataset path must start with the "datasets" segment;
  unprefixed paths are no longer treated as dataset paths.
- pytexera DatasetFileDocument: same rule, mirroring the backend.
- FileListerSourceOpExec: parse the now-prefixed datasetVersionPath
  (skip the "datasets" segment); extracted into a testable helper.
- Migration (sql/updates/29.sql): prepend "datasets/" to legacy paths
  stored in workflow.content and workflow_version.content, covering both
  the fileName (scan sources) and datasetVersionPath (file lister)
  operator properties. Only values whose first two segments match an
  existing (user.email, dataset.name) are rewritten, so local paths and
  URLs are left untouched; email format is irrelevant (owner may be a
  username without "@"). Uses create_missing=false and is idempotent.
- Example workflows: use datasets-prefixed paths.

Tests: FileResolverSpec and WorkflowExecutionsResourceSpec updated;
test_dataset_file_document.py updated; new FileListerSourceOpExecSpec.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…l-path-prefix

# Conflicts:
#	frontend/src/app/common/type/datasetVersionFileTree.spec.ts
…format python test

- dataset-selection-modal.component.spec.ts: expect the datasets-prefixed
  selectedPath in version (non-file) mode, matching the emitted path.
- test_dataset_file_document.py: apply ruff format (wrap an over-length line)
  so `ruff format --check` passes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The cover-image endpoints resolve a dataset path built as
{owner}/{name}/{coverImage}. With the prefix now required by FileResolver,
these must carry the datasets/ segment; add it in the set-cover,
get-cover redirect, and cover-url handlers so cover images resolve again.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rage

# Conflicts:
#	common/workflow-core/src/test/scala/org/apache/texera/amber/core/storage/DocumentFactorySpec.scala
@github-actions github-actions Bot added feature engine ddl-change Changes to the TexeraDB DDL pyamber frontend Changes related to the frontend GUI infra common labels Jul 24, 2026
@github-actions github-actions Bot added the platform Non-amber Scala service paths label Jul 24, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Automated Reviewer Suggestions

Based on the git blame history of the changed files, we recommend the following reviewers:

  • Contributors with relevant context: @Ma77Ball, @aglinxinyuan, @Yicong-Huang
    You can notify them by mentioning @Ma77Ball, @aglinxinyuan, @Yicong-Huang in a comment.

@codecov-commenter

codecov-commenter commented Jul 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 82.05128% with 21 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.15%. Comparing base (a351f44) to head (e3347c1).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
...apache/texera/service/resource/ModelResource.scala 81.53% 8 Missing and 4 partials ⚠️
...ache/texera/service/resource/DatasetResource.scala 0.00% 4 Missing ⚠️
.../texera/service/resource/ModelAccessResource.scala 91.89% 1 Missing and 2 partials ⚠️
.../scala/org/apache/texera/service/FileService.scala 0.00% 2 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main    #6869      +/-   ##
============================================
+ Coverage     77.30%   83.15%   +5.85%     
+ Complexity     3524      168    -3356     
============================================
  Files          1161      157    -1004     
  Lines         45922     5950   -39972     
  Branches       5101      207    -4894     
============================================
- Hits          35501     4948   -30553     
+ Misses         8840      911    -7929     
+ Partials       1581       91    -1490     
Flag Coverage Δ
access-control-service 70.00% <ø> (ø)
agent-service ?
amber ?
computing-unit-managing-service 20.49% <ø> (ø)
config-service 66.66% <ø> (ø)
file-service 69.86% <80.55%> (+2.65%) ⬆️
frontend ?
notebook-migration-service 78.94% <ø> (ø)
pyamber 92.11% <100.00%> (-0.04%) ⬇️
workflow-compiling-service 55.14% <ø> (ø)

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Benchmark changes need a look

🟢 0 better · 🔴 7 worse · ⚪ 8 noise (<±5%) · 0 without baseline

Compared against main eae4f21 benchmarked on this same runner, so the delta is largely free of cross-runner hardware noise. The "7d avg" column still reflects the gh-pages dashboard. Treat <±5% as noise unless repeated.

Dashboard · Run

config throughput MB/s latency max Δ latest / 7d
🔴 bs=10 sw=10 sl=64 557 0.34 17,058/26,642/26,642 us 🔴 +16.3% / 🔴 +60.6%
🔴 bs=100 sw=10 sl=64 1,079 0.659 89,933/126,966/126,966 us 🔴 +7.0% / 🔴 +16.4%
bs=1000 sw=10 sl=64 1,344 0.821 743,233/764,917/764,917 us ⚪ within ±5% / 🟢 +34.0%
Baseline details

Latest main eae4f21 from same runner

config metric PR latest main 7d avg Δ latest Δ 7d
bs=10 sw=10 sl=64 throughput 557 tuples/sec 581 tuples/sec 754.55 tuples/sec -4.1% -26.2%
bs=10 sw=10 sl=64 MB/s 0.34 MB/s 0.355 MB/s 0.461 MB/s -4.2% -26.2%
bs=10 sw=10 sl=64 p50 17,058 us 17,740 us 12,816 us -3.8% +33.1%
bs=10 sw=10 sl=64 p95 26,642 us 22,901 us 16,594 us +16.3% +60.6%
bs=10 sw=10 sl=64 p99 26,642 us 22,901 us 19,806 us +16.3% +34.5%
bs=100 sw=10 sl=64 throughput 1,079 tuples/sec 1,158 tuples/sec 969.38 tuples/sec -6.8% +11.3%
bs=100 sw=10 sl=64 MB/s 0.659 MB/s 0.707 MB/s 0.592 MB/s -6.8% +11.4%
bs=100 sw=10 sl=64 p50 89,933 us 84,046 us 103,584 us +7.0% -13.2%
bs=100 sw=10 sl=64 p95 126,966 us 120,711 us 109,097 us +5.2% +16.4%
bs=100 sw=10 sl=64 p99 126,966 us 120,711 us 117,304 us +5.2% +8.2%
bs=1000 sw=10 sl=64 throughput 1,344 tuples/sec 1,359 tuples/sec 1,004 tuples/sec -1.1% +33.9%
bs=1000 sw=10 sl=64 MB/s 0.821 MB/s 0.83 MB/s 0.613 MB/s -1.1% +34.0%
bs=1000 sw=10 sl=64 p50 743,233 us 738,094 us 1,002,357 us +0.7% -25.9%
bs=1000 sw=10 sl=64 p95 764,917 us 759,955 us 1,046,463 us +0.7% -26.9%
bs=1000 sw=10 sl=64 p99 764,917 us 759,955 us 1,073,661 us +0.7% -28.8%
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,358.80,200,128000,557,0.340,17057.77,26642.10,26642.10
1,100,10,64,20,1853.16,2000,1280000,1079,0.659,89933.02,126966.30,126966.30
2,1000,10,64,20,14876.90,20000,12800000,1344,0.821,743233.16,764917.14,764917.14

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

common ddl-change Changes to the TexeraDB DDL engine feature frontend Changes related to the frontend GUI infra platform Non-amber Scala service paths pyamber

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants