add volcengine OSS support

This commit is contained in:
2026-08-30 06:52:14 +08:00
parent 6de1d4a3d0
commit 856aa38026
9 changed files with 339 additions and 10 deletions

View File

@@ -5,6 +5,9 @@ from fastapi.testclient import TestClient
from sentence_api.main import create_app
from sentence_api.config import Settings
from sentence_api.oss import VolcanoOSSUploader
from sentence_api.models import SentenceBoundary, SentenceBoundaryDocument
from sentence_api.processing import VideoProcessor
from sentence_api.repository import VideoRepository
from sentence_api.store import BoundaryStore
@@ -68,3 +71,120 @@ def test_invalid_hash_is_rejected(tmp_path):
response = client.get("/api/v1/videos/not-a-sha256/sentence-boundaries")
assert response.status_code == 422
def test_oss_video_url_is_used_for_catalog_and_content(tmp_path):
index_path = tmp_path / "boundaries.json"
index_path.write_text("{}", encoding="utf-8")
settings = replace(
Settings.from_env(),
data_dir=tmp_path / "data",
legacy_boundaries_file=index_path,
)
settings.ensure_directories()
repository = VideoRepository(settings.database_path)
repository.upsert_upload(
video_hash=VIDEO_HASH,
title="OSS lesson",
filename="lesson.mp4",
stored_filename=f"{VIDEO_HASH}.mp4",
content_type="video/mp4",
size_bytes=1,
language=None,
)
remote_url = f"https://course-media.example.com/videos/{VIDEO_HASH}.mp4"
repository.mark_oss_uploaded(VIDEO_HASH, remote_url)
client = TestClient(
create_app(
BoundaryStore(index_path),
settings=settings,
repository=repository,
)
)
catalog = client.get("/api/v1/videos")
stream = client.get(f"/api/v1/videos/{VIDEO_HASH}/content", follow_redirects=False)
assert catalog.status_code == 200
assert catalog.json()["videos"][0]["stream_url"] == remote_url
assert stream.status_code == 307
assert stream.headers["location"] == remote_url
def test_volcano_oss_object_key_and_public_url(tmp_path):
settings = replace(
Settings.from_env(),
volcano_oss_access_key="ak",
volcano_oss_secret_key="sk",
volcano_oss_bucket="course-media",
volcano_oss_endpoint="tos-cn-beijing.volces.com",
volcano_oss_region="cn-beijing",
volcano_oss_key_prefix="lessons/videos/",
)
uploader = VolcanoOSSUploader(settings)
key = uploader.object_key(VIDEO_HASH, f"{VIDEO_HASH}.mp4")
assert settings.volcano_oss_enabled is True
assert key == f"lessons/videos/{VIDEO_HASH}.mp4"
assert uploader.public_url(key) == (
f"https://course-media.tos-cn-beijing.volces.com/"
f"lessons/videos/{VIDEO_HASH}.mp4"
)
def test_processor_marks_ready_only_after_oss_upload(tmp_path, monkeypatch):
settings = replace(Settings.from_env(), data_dir=tmp_path / "data")
settings.ensure_directories()
media_path = settings.videos_dir / f"{VIDEO_HASH}.mp4"
media_path.write_bytes(b"video")
repository = VideoRepository(settings.database_path)
repository.upsert_upload(
video_hash=VIDEO_HASH,
title="OSS lesson",
filename="lesson.mp4",
stored_filename=f"{VIDEO_HASH}.mp4",
content_type="video/mp4",
size_bytes=5,
language=None,
)
document = SentenceBoundaryDocument(
video_hash=VIDEO_HASH,
duration_ms=1000,
algorithm_version="test",
sentences=[SentenceBoundary(index=0, start_ms=0, end_ms=1000)],
)
uploads = []
class EnabledUploader:
enabled = True
def upload(self, **kwargs):
uploads.append(kwargs)
return "https://media.example.com/lesson.mp4"
class UnavailableTranscriber:
available = False
monkeypatch.setattr(
"sentence_api.processing.make_entry",
lambda *args, **kwargs: (
{
"duration_ms": 1000,
"sentences": [{"index": 0, "start_ms": 0, "end_ms": 1000}],
},
{},
),
)
processor = VideoProcessor(
settings,
repository,
UnavailableTranscriber(),
EnabledUploader(),
)
processor.process(VIDEO_HASH)
video = repository.get_video(VIDEO_HASH)
assert uploads[0]["stored_filename"] == f"{VIDEO_HASH}.mp4"
assert video["status"] == "ready"
assert video["remote_url"] == "https://media.example.com/lesson.mp4"