Skip to content

Commit 8651d0b

Browse files
committed
Merge branch 'DEVX-10394-missing-transcription-fields'
2 parents 3c9ab73 + bb0738f commit 8651d0b

File tree

7 files changed

+355
-2
lines changed

7 files changed

+355
-2
lines changed

video/src/vonage_video/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '1.5.0'
1+
__version__ = '1.5.1'

video/src/vonage_video/models/archive.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,16 @@ class Transcription(BaseModel):
2929
Args:
3030
status (str, Optional): The status of the transcription.
3131
reason (str, Optional): May give a brief reason for the transcription status.
32+
url (str, Optional): The URL of the transcription file.
33+
primaryLanguageCode (str, Optional): The primary language code for transcription.
34+
hasSummary (bool, Optional): Whether the transcription includes a summary.
3235
"""
3336

3437
status: Optional[str] = None
3538
reason: Optional[str] = None
39+
url: Optional[str] = None
40+
primaryLanguageCode: Optional[str] = None
41+
hasSummary: Optional[bool] = None
3642

3743

3844
class Archive(BaseModel):
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"id": "5b1521e6-115f-4efd-bed9-e527b87f0699",
3+
"status": "available",
4+
"name": "archive with transcription",
5+
"reason": "session ended",
6+
"sessionId": "test_session_id",
7+
"applicationId": "test_application_id",
8+
"createdAt": 1727870434974,
9+
"size": 1048576,
10+
"duration": 180,
11+
"outputMode": "individual",
12+
"streamMode": "auto",
13+
"hasAudio": true,
14+
"hasVideo": true,
15+
"hasTranscription": true,
16+
"sha256sum": "abc123def456",
17+
"password": "",
18+
"updatedAt": 1727870634977,
19+
"multiArchiveTag": "",
20+
"event": "archive",
21+
"resolution": "1280x720",
22+
"url": "https://example.com/archive.mp4",
23+
"transcription": {
24+
"status": "completed",
25+
"reason": "transcription completed successfully",
26+
"url": "https://example.com/transcription.json",
27+
"primaryLanguageCode": "en-US",
28+
"hasSummary": true
29+
}
30+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
{
2+
"count": 3,
3+
"items": [
4+
{
5+
"id": "5b1521e6-115f-4efd-bed9-e527b87f0699",
6+
"status": "paused",
7+
"name": "archive without transcription",
8+
"reason": "",
9+
"sessionId": "test_session_id",
10+
"applicationId": "test_application_id",
11+
"createdAt": 1727870434974,
12+
"size": 0,
13+
"duration": 0,
14+
"outputMode": "composed",
15+
"streamMode": "auto",
16+
"hasAudio": true,
17+
"hasVideo": true,
18+
"hasTranscription": false,
19+
"sha256sum": "",
20+
"password": "",
21+
"updatedAt": 1727870434977,
22+
"multiArchiveTag": "",
23+
"event": "archive",
24+
"resolution": "1280x720",
25+
"url": null
26+
},
27+
{
28+
"id": "a9cdeb69-f6cf-408b-9197-6f99e6eac5aa",
29+
"status": "available",
30+
"name": "completed archive",
31+
"reason": "session ended",
32+
"sessionId": "test_session_id",
33+
"applicationId": "test_application_id",
34+
"createdAt": 1727870434974,
35+
"size": 1024000,
36+
"duration": 134,
37+
"outputMode": "composed",
38+
"streamMode": "auto",
39+
"hasAudio": true,
40+
"hasVideo": true,
41+
"hasTranscription": false,
42+
"sha256sum": "test_sha256_sum",
43+
"password": "",
44+
"updatedAt": 1727870634977,
45+
"multiArchiveTag": "",
46+
"event": "archive",
47+
"resolution": "1280x720",
48+
"url": "https://example.com/archive.mp4",
49+
"maxBitrate": 2000000
50+
},
51+
{
52+
"id": "c1d2e3f4-g5h6-i7j8-k9l0-m1n2o3p4q5r6",
53+
"status": "available",
54+
"name": "transcribed archive",
55+
"reason": "session ended",
56+
"sessionId": "test_session_id",
57+
"applicationId": "test_application_id",
58+
"createdAt": 1727870434974,
59+
"size": 2048000,
60+
"duration": 240,
61+
"outputMode": "individual",
62+
"streamMode": "auto",
63+
"hasAudio": true,
64+
"hasVideo": true,
65+
"hasTranscription": true,
66+
"sha256sum": "test_transcription_sha256",
67+
"password": "",
68+
"updatedAt": 1727870734977,
69+
"multiArchiveTag": "",
70+
"event": "archive",
71+
"resolution": "1280x720",
72+
"url": "https://example.com/transcribed_archive.mp4",
73+
"transcription": {
74+
"status": "completed",
75+
"reason": "transcription completed successfully",
76+
"url": "https://example.com/transcriptions/c1d2e3f4.json",
77+
"primaryLanguageCode": "es-ES",
78+
"hasSummary": true
79+
}
80+
}
81+
]
82+
}

video/tests/test_archive.py

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
LayoutStylesheetError,
2222
NoAudioOrVideoError,
2323
)
24+
from vonage_video.models.archive import Transcription
2425

2526
from testutils import build_response, get_mock_jwt_auth
2627

@@ -409,3 +410,228 @@ def test_change_archive_layout():
409410

410411
assert archive.id == '5b1521e6-115f-4efd-bed9-e527b87f0699'
411412
assert video.http_client.last_response.status_code == 200
413+
414+
415+
# Tests for new Transcription options
416+
def test_transcription_model_with_all_options():
417+
"""Test that the Transcription model can be created with all new options."""
418+
transcription = Transcription(
419+
status="completed",
420+
reason="transcription completed successfully",
421+
url="https://example.com/transcription.json",
422+
primaryLanguageCode="en-US",
423+
hasSummary=True,
424+
)
425+
426+
assert transcription.status == "completed"
427+
assert transcription.reason == "transcription completed successfully"
428+
assert transcription.url == "https://example.com/transcription.json"
429+
assert transcription.primaryLanguageCode == "en-US"
430+
assert transcription.hasSummary is True
431+
432+
433+
def test_transcription_model_with_partial_options():
434+
"""Test that the Transcription model can be created with only some new options."""
435+
transcription = Transcription(
436+
status="processing", url="https://example.com/transcription.json"
437+
)
438+
439+
assert transcription.status == "processing"
440+
assert transcription.url == "https://example.com/transcription.json"
441+
assert transcription.primaryLanguageCode is None
442+
assert transcription.hasSummary is None
443+
assert transcription.reason is None
444+
445+
446+
def test_transcription_model_with_url_only():
447+
"""Test that the Transcription model can be created with just the url option."""
448+
transcription = Transcription(url="https://example.com/transcription.json")
449+
450+
assert transcription.url == "https://example.com/transcription.json"
451+
assert transcription.status is None
452+
assert transcription.reason is None
453+
assert transcription.primaryLanguageCode is None
454+
assert transcription.hasSummary is None
455+
456+
457+
def test_transcription_model_with_primary_language_code_only():
458+
"""Test that the Transcription model can be created with just the primaryLanguageCode
459+
option."""
460+
transcription = Transcription(primaryLanguageCode="es-ES")
461+
462+
assert transcription.primaryLanguageCode == "es-ES"
463+
assert transcription.status is None
464+
assert transcription.reason is None
465+
assert transcription.url is None
466+
assert transcription.hasSummary is None
467+
468+
469+
def test_transcription_model_with_has_summary_only():
470+
"""Test that the Transcription model can be created with just the hasSummary
471+
option."""
472+
transcription = Transcription(hasSummary=False)
473+
474+
assert transcription.hasSummary is False
475+
assert transcription.status is None
476+
assert transcription.reason is None
477+
assert transcription.url is None
478+
assert transcription.primaryLanguageCode is None
479+
480+
481+
def test_transcription_model_empty():
482+
"""Test that the Transcription model can be created with no options set."""
483+
transcription = Transcription()
484+
485+
assert transcription.status is None
486+
assert transcription.reason is None
487+
assert transcription.url is None
488+
assert transcription.primaryLanguageCode is None
489+
assert transcription.hasSummary is None
490+
491+
492+
def test_transcription_model_serialization():
493+
"""Test that the Transcription model serializes correctly."""
494+
transcription = Transcription(
495+
status="completed",
496+
reason="success",
497+
url="https://example.com/transcription.json",
498+
primaryLanguageCode="en-US",
499+
hasSummary=True,
500+
)
501+
502+
serialized = transcription.model_dump()
503+
expected = {
504+
"status": "completed",
505+
"reason": "success",
506+
"url": "https://example.com/transcription.json",
507+
"primaryLanguageCode": "en-US",
508+
"hasSummary": True,
509+
}
510+
511+
assert serialized == expected
512+
513+
514+
def test_transcription_model_serialization_exclude_unset():
515+
"""Test that the Transcription model serializes correctly excluding unset values."""
516+
transcription = Transcription(
517+
url="https://example.com/transcription.json", hasSummary=True
518+
)
519+
520+
serialized = transcription.model_dump(exclude_unset=True)
521+
expected = {"url": "https://example.com/transcription.json", "hasSummary": True}
522+
523+
assert serialized == expected
524+
assert "status" not in serialized
525+
assert "reason" not in serialized
526+
assert "primaryLanguageCode" not in serialized
527+
528+
529+
def test_transcription_model_deserialization():
530+
"""Test that the Transcription model can be created from dictionary data."""
531+
data = {
532+
"status": "completed",
533+
"reason": "transcription finished",
534+
"url": "https://example.com/transcription.json",
535+
"primaryLanguageCode": "fr-FR",
536+
"hasSummary": True,
537+
}
538+
539+
transcription = Transcription(**data)
540+
541+
assert transcription.status == "completed"
542+
assert transcription.reason == "transcription finished"
543+
assert transcription.url == "https://example.com/transcription.json"
544+
assert transcription.primaryLanguageCode == "fr-FR"
545+
assert transcription.hasSummary is True
546+
547+
548+
def test_transcription_model_with_various_language_codes():
549+
"""Test that the Transcription model accepts various language codes."""
550+
test_cases = ["en-US", "es-ES", "fr-FR", "de-DE", "ja-JP", "zh-CN", "pt-BR"]
551+
552+
for lang_code in test_cases:
553+
transcription = Transcription(primaryLanguageCode=lang_code)
554+
assert transcription.primaryLanguageCode == lang_code
555+
556+
557+
def test_transcription_model_with_various_urls():
558+
"""Test that the Transcription model accepts various URL formats."""
559+
test_urls = [
560+
"https://example.com/transcription.json",
561+
"https://storage.googleapis.com/bucket/file.json",
562+
"https://s3.amazonaws.com/bucket/transcription.txt",
563+
"http://example.org/path/to/transcription",
564+
"https://vonage.example.com/transcriptions/12345",
565+
]
566+
567+
for url in test_urls:
568+
transcription = Transcription(url=url)
569+
assert transcription.url == url
570+
571+
572+
def test_transcription_model_boolean_has_summary():
573+
"""Test that hasSummary properly handles boolean values."""
574+
# Test True
575+
transcription_true = Transcription(hasSummary=True)
576+
assert transcription_true.hasSummary is True
577+
578+
# Test False
579+
transcription_false = Transcription(hasSummary=False)
580+
assert transcription_false.hasSummary is False
581+
582+
# Test None (default)
583+
transcription_none = Transcription()
584+
assert transcription_none.hasSummary is None
585+
586+
587+
@responses.activate
588+
def test_archive_with_transcription_options():
589+
"""Test that Archive model properly deserializes with transcription containing new
590+
options."""
591+
build_response(
592+
path,
593+
'GET',
594+
'https://video.api.vonage.com/v2/project/test_application_id/archive/5b1521e6-115f-4efd-bed9-e527b87f0699',
595+
'archive_with_transcription.json',
596+
)
597+
598+
archive = video.get_archive('5b1521e6-115f-4efd-bed9-e527b87f0699')
599+
600+
assert archive.id == '5b1521e6-115f-4efd-bed9-e527b87f0699'
601+
assert archive.has_transcription is True
602+
603+
# Test transcription object and its new properties
604+
assert archive.transcription is not None
605+
assert archive.transcription.status == "completed"
606+
assert archive.transcription.reason == "transcription completed successfully"
607+
assert archive.transcription.url == "https://example.com/transcription.json"
608+
assert archive.transcription.primaryLanguageCode == "en-US"
609+
assert archive.transcription.hasSummary is True
610+
611+
612+
@responses.activate
613+
def test_list_archives_with_transcription_options():
614+
"""Test that listing archives properly handles transcription with new options."""
615+
# Create a modified list response that includes transcription data
616+
build_response(
617+
path,
618+
'GET',
619+
'https://video.api.vonage.com/v2/project/test_application_id/archive',
620+
'list_archives_with_transcription.json',
621+
)
622+
623+
filter = ListArchivesFilter(session_id='test_session_id')
624+
archives, count, next_page = video.list_archives(filter)
625+
626+
# Find the archive with transcription
627+
transcribed_archive = None
628+
for archive in archives:
629+
if archive.has_transcription:
630+
transcribed_archive = archive
631+
break
632+
633+
assert transcribed_archive is not None
634+
assert transcribed_archive.transcription is not None
635+
assert transcribed_archive.transcription.url is not None
636+
assert transcribed_archive.transcription.primaryLanguageCode is not None
637+
assert transcribed_archive.transcription.hasSummary is not None

vonage/CHANGES.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
# 4.7.1
2+
- vonage-video: Added missing transcription values from archive responses
3+
4+
# 4.7.0
5+
- vonage-video: Added quantization parameter for video archives
6+
7+
# 4.6.0
8+
- vonage-video: Added bidirectional websocket flag
9+
110
# 4.5.0
211
- vonage-messages: add an optional "failover" property to `vonage_messages.Messages.send`
312

vonage/src/vonage/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '4.6.0'
1+
__version__ = '4.7.1'

0 commit comments

Comments
 (0)