0
# Media Asset Warehouse
1
2
Comprehensive media asset management with AI-powered analysis, indexing, search, and collection organization. The Warehouse service provides enterprise-scale capabilities for storing, analyzing, and discovering video content with sophisticated search and metadata management.
3
4
## Capabilities
5
6
### Asset Management
7
8
Create, upload, analyze, and manage media assets with comprehensive metadata and AI-powered content understanding.
9
10
```python { .api }
11
def create_asset(self, parent: str, asset: Asset, asset_id: str = None) -> Asset:
12
"""
13
Creates a new media asset in a corpus.
14
15
Args:
16
parent (str): Required. Corpus resource path
17
asset (Asset): Required. Asset configuration and metadata
18
asset_id (str): Optional. ID for the new asset (auto-generated if not provided)
19
20
Returns:
21
Asset: Created asset with metadata and system-assigned fields
22
"""
23
24
def get_asset(self, name: str) -> Asset:
25
"""
26
Retrieves asset details and metadata.
27
28
Args:
29
name (str): Required. Asset resource path
30
"projects/{project}/locations/{location}/corpora/{corpus}/assets/{asset}"
31
32
Returns:
33
Asset: The asset resource with full metadata
34
"""
35
36
def list_assets(self, parent: str, page_size: int = None, page_token: str = None, filter: str = None) -> ListAssetsResponse:
37
"""
38
Lists assets in a corpus.
39
40
Args:
41
parent (str): Required. Corpus resource path
42
page_size (int): Maximum number of assets to return
43
page_token (str): Token for pagination
44
filter (str): Filter expression for assets
45
46
Returns:
47
ListAssetsResponse: Response with assets and pagination
48
"""
49
50
def update_asset(self, asset: Asset, update_mask: FieldMask = None) -> Asset:
51
"""
52
Updates asset metadata and configuration.
53
54
Args:
55
asset (Asset): Required. Updated asset configuration
56
update_mask (FieldMask): Fields to update
57
58
Returns:
59
Asset: Updated asset resource
60
"""
61
62
def delete_asset(self, name: str) -> Operation:
63
"""
64
Deletes an asset and associated data.
65
66
Args:
67
name (str): Required. Asset resource path to delete
68
69
Returns:
70
Operation: Long-running operation for asset deletion
71
"""
72
73
def upload_asset(self, requests: Iterator[UploadAssetRequest]) -> Operation:
74
"""
75
Uploads asset content via streaming.
76
77
Args:
78
requests (Iterator[UploadAssetRequest]): Stream of upload requests with metadata and content
79
80
Returns:
81
Operation: Long-running operation for upload completion
82
"""
83
84
def generate_retrieval_url(self, name: str) -> GenerateRetrievalUrlResponse:
85
"""
86
Generates URL for downloading asset content.
87
88
Args:
89
name (str): Required. Asset resource path
90
91
Returns:
92
GenerateRetrievalUrlResponse: Download URL with expiration
93
"""
94
95
def analyze_asset(self, name: str) -> Operation:
96
"""
97
Analyzes asset content with AI for metadata extraction.
98
99
Args:
100
name (str): Required. Asset resource path to analyze
101
102
Returns:
103
Operation: Long-running operation for analysis completion
104
"""
105
106
def ingest_asset(self, requests: Iterator[IngestAssetRequest]) -> Iterator[IngestAssetResponse]:
107
"""
108
Ingests asset into warehouse via streaming.
109
110
Args:
111
requests (Iterator[IngestAssetRequest]): Stream of ingest requests
112
113
Yields:
114
IngestAssetResponse: Streaming responses with ingestion status
115
"""
116
117
def clip_asset(self, name: str, temporal_partition: Partition) -> ClipAssetResponse:
118
"""
119
Creates clips from video assets based on temporal partitions.
120
121
Args:
122
name (str): Required. Asset resource path
123
temporal_partition (Partition): Temporal boundaries for clip creation
124
125
Returns:
126
ClipAssetResponse: Information about created clips
127
"""
128
129
def generate_hls_uri(self, name: str, temporal_partitions: List[Partition] = None, live_view_enabled: bool = None) -> GenerateHlsUriResponse:
130
"""
131
Generates HLS streaming URI for asset playback.
132
133
Args:
134
name (str): Required. Asset resource path
135
temporal_partitions (List[Partition]): Specific time ranges to include
136
live_view_enabled (bool): Enable live view for streaming assets
137
138
Returns:
139
GenerateHlsUriResponse: HLS streaming URI and metadata
140
"""
141
142
def import_assets(self, parent: str, assets_gcs_uri: str) -> Operation:
143
"""
144
Bulk imports assets from Google Cloud Storage.
145
146
Args:
147
parent (str): Required. Corpus resource path
148
assets_gcs_uri (str): Required. GCS URI containing assets to import
149
150
Returns:
151
Operation: Long-running operation for bulk import
152
"""
153
```
154
155
### Search and Indexing
156
157
Create and manage search indexes, perform content-based searches, and organize searchable content.
158
159
```python { .api }
160
def create_index(self, parent: str, index: Index, index_id: str = None) -> Operation:
161
"""
162
Creates a search index for asset discovery.
163
164
Args:
165
parent (str): Required. Corpus resource path
166
index (Index): Required. Index configuration
167
index_id (str): Optional. ID for the new index
168
169
Returns:
170
Operation: Long-running operation for index creation
171
"""
172
173
def get_index(self, name: str) -> Index:
174
"""
175
Retrieves index details and configuration.
176
177
Args:
178
name (str): Required. Index resource path
179
"projects/{project}/locations/{location}/corpora/{corpus}/indexes/{index}"
180
181
Returns:
182
Index: The index resource with configuration
183
"""
184
185
def list_indexes(self, parent: str, page_size: int = None, page_token: str = None) -> ListIndexesResponse:
186
"""
187
Lists indexes in a corpus.
188
189
Args:
190
parent (str): Required. Corpus resource path
191
page_size (int): Maximum number of indexes to return
192
page_token (str): Token for pagination
193
194
Returns:
195
ListIndexesResponse: Response with indexes and pagination
196
"""
197
198
def update_index(self, index: Index, update_mask: FieldMask = None) -> Operation:
199
"""
200
Updates index configuration.
201
202
Args:
203
index (Index): Required. Updated index configuration
204
update_mask (FieldMask): Fields to update
205
206
Returns:
207
Operation: Long-running operation for index update
208
"""
209
210
def delete_index(self, name: str) -> Operation:
211
"""
212
Deletes a search index.
213
214
Args:
215
name (str): Required. Index resource path to delete
216
217
Returns:
218
Operation: Long-running operation for index deletion
219
"""
220
221
def index_asset(self, name: str, index: str) -> Operation:
222
"""
223
Adds asset to search index for discoverability.
224
225
Args:
226
name (str): Required. Asset resource path
227
index (str): Required. Index resource path
228
229
Returns:
230
Operation: Long-running operation for asset indexing
231
"""
232
233
def remove_index_asset(self, name: str, index: str) -> Operation:
234
"""
235
Removes asset from search index.
236
237
Args:
238
name (str): Required. Asset resource path
239
index (str): Required. Index resource path
240
241
Returns:
242
Operation: Long-running operation for asset removal
243
"""
244
245
def view_indexed_assets(self, index: str, page_size: int = None, page_token: str = None, filter: str = None) -> ViewIndexedAssetsResponse:
246
"""
247
Views assets in a search index.
248
249
Args:
250
index (str): Required. Index resource path
251
page_size (int): Maximum number of assets to return
252
page_token (str): Token for pagination
253
filter (str): Filter expression for indexed assets
254
255
Returns:
256
ViewIndexedAssetsResponse: Response with indexed assets
257
"""
258
259
def search_assets(self, corpus: str, criteria: List[Criteria] = None, facet_selections: List[FacetGroup] = None, result_annotation_keys: List[str] = None, search_query: str = None, page_size: int = None, page_token: str = None) -> SearchAssetsResponse:
260
"""
261
Searches assets using various criteria and queries.
262
263
Args:
264
corpus (str): Required. Corpus resource path to search
265
criteria (List[Criteria]): Search criteria and filters
266
facet_selections (List[FacetGroup]): Faceted search selections
267
result_annotation_keys (List[str]): Annotation keys to include in results
268
search_query (str): Text-based search query
269
page_size (int): Maximum number of results to return
270
page_token (str): Token for pagination
271
272
Returns:
273
SearchAssetsResponse: Search results with assets and metadata
274
"""
275
276
def search_index_endpoint(self, index_endpoint: str, criteria: List[Criteria] = None, exclusion_criteria: List[Criteria] = None, page_size: int = None, page_token: str = None) -> SearchIndexEndpointResponse:
277
"""
278
Searches using deployed index endpoint.
279
280
Args:
281
index_endpoint (str): Required. Index endpoint resource path
282
criteria (List[Criteria]): Search criteria
283
exclusion_criteria (List[Criteria]): Exclusion criteria
284
page_size (int): Maximum number of results
285
page_token (str): Token for pagination
286
287
Returns:
288
SearchIndexEndpointResponse: Search results from index endpoint
289
"""
290
```
291
292
### Corpus Management
293
294
Create and manage corpora as containers for related assets with shared access policies and organization.
295
296
```python { .api }
297
def create_corpus(self, parent: str, corpus: Corpus) -> Operation:
298
"""
299
Creates a corpus for organizing related assets.
300
301
Args:
302
parent (str): Required. Parent resource path "projects/{project}/locations/{location}"
303
corpus (Corpus): Required. Corpus configuration
304
305
Returns:
306
Operation: Long-running operation for corpus creation
307
"""
308
309
def get_corpus(self, name: str) -> Corpus:
310
"""
311
Retrieves corpus details and configuration.
312
313
Args:
314
name (str): Required. Corpus resource path
315
"projects/{project}/locations/{location}/corpora/{corpus}"
316
317
Returns:
318
Corpus: The corpus resource with configuration
319
"""
320
321
def update_corpus(self, corpus: Corpus, update_mask: FieldMask = None) -> Corpus:
322
"""
323
Updates corpus configuration.
324
325
Args:
326
corpus (Corpus): Required. Updated corpus configuration
327
update_mask (FieldMask): Fields to update
328
329
Returns:
330
Corpus: Updated corpus resource
331
"""
332
333
def list_corpora(self, parent: str, page_size: int = None, page_token: str = None) -> ListCorporaResponse:
334
"""
335
Lists corpora in a project and location.
336
337
Args:
338
parent (str): Required. Parent resource path "projects/{project}/locations/{location}"
339
page_size (int): Maximum number of corpora to return
340
page_token (str): Token for pagination
341
342
Returns:
343
ListCorporaResponse: Response with corpora and pagination
344
"""
345
346
def delete_corpus(self, name: str) -> Corpus:
347
"""
348
Deletes a corpus and all contained assets.
349
350
Args:
351
name (str): Required. Corpus resource path to delete
352
353
Returns:
354
Corpus: Deleted corpus resource
355
"""
356
357
def analyze_corpus(self, name: str) -> Operation:
358
"""
359
Analyzes entire corpus with AI for insights and metadata.
360
361
Args:
362
name (str): Required. Corpus resource path to analyze
363
364
Returns:
365
Operation: Long-running operation for corpus analysis
366
"""
367
```
368
369
### Collection Management
370
371
Organize assets into curated collections for easier discovery and management.
372
373
```python { .api }
374
def create_collection(self, parent: str, collection: Collection, collection_id: str) -> Operation:
375
"""
376
Creates a collection for organizing assets.
377
378
Args:
379
parent (str): Required. Corpus resource path
380
collection (Collection): Required. Collection configuration
381
collection_id (str): Required. ID for the new collection
382
383
Returns:
384
Operation: Long-running operation for collection creation
385
"""
386
387
def get_collection(self, name: str) -> Collection:
388
"""
389
Retrieves collection details and metadata.
390
391
Args:
392
name (str): Required. Collection resource path
393
394
Returns:
395
Collection: The collection resource with metadata
396
"""
397
398
def update_collection(self, collection: Collection, update_mask: FieldMask = None) -> Collection:
399
"""
400
Updates collection configuration.
401
402
Args:
403
collection (Collection): Required. Updated collection configuration
404
update_mask (FieldMask): Fields to update
405
406
Returns:
407
Collection: Updated collection resource
408
"""
409
410
def list_collections(self, parent: str, page_size: int = None, page_token: str = None) -> ListCollectionsResponse:
411
"""
412
Lists collections in a corpus.
413
414
Args:
415
parent (str): Required. Corpus resource path
416
page_size (int): Maximum number of collections to return
417
page_token (str): Token for pagination
418
419
Returns:
420
ListCollectionsResponse: Response with collections and pagination
421
"""
422
423
def delete_collection(self, name: str) -> Operation:
424
"""
425
Deletes a collection (assets remain in corpus).
426
427
Args:
428
name (str): Required. Collection resource path to delete
429
430
Returns:
431
Operation: Long-running operation for collection deletion
432
"""
433
434
def add_collection_item(self, item: CollectionItem) -> AddCollectionItemResponse:
435
"""
436
Adds asset to a collection.
437
438
Args:
439
item (CollectionItem): Required. Collection item to add
440
441
Returns:
442
AddCollectionItemResponse: Confirmation of item addition
443
"""
444
445
def remove_collection_item(self, item: CollectionItem) -> RemoveCollectionItemResponse:
446
"""
447
Removes asset from a collection.
448
449
Args:
450
item (CollectionItem): Required. Collection item to remove
451
452
Returns:
453
RemoveCollectionItemResponse: Confirmation of item removal
454
"""
455
456
def view_collection_items(self, collection: str, page_size: int = None, page_token: str = None) -> ViewCollectionItemsResponse:
457
"""
458
Views assets in a collection.
459
460
Args:
461
collection (str): Required. Collection resource path
462
page_size (int): Maximum number of items to return
463
page_token (str): Token for pagination
464
465
Returns:
466
ViewCollectionItemsResponse: Response with collection items
467
"""
468
```
469
470
### Annotation Management
471
472
Create, manage, and organize annotations for assets with structured metadata schemas.
473
474
```python { .api }
475
def create_annotation(self, parent: str, annotation: Annotation, annotation_id: str = None) -> Annotation:
476
"""
477
Creates annotation for an asset.
478
479
Args:
480
parent (str): Required. Asset resource path
481
annotation (Annotation): Required. Annotation data and metadata
482
annotation_id (str): Optional. ID for the new annotation
483
484
Returns:
485
Annotation: Created annotation with system-assigned fields
486
"""
487
488
def get_annotation(self, name: str) -> Annotation:
489
"""
490
Retrieves annotation details and data.
491
492
Args:
493
name (str): Required. Annotation resource path
494
495
Returns:
496
Annotation: The annotation resource with data
497
"""
498
499
def list_annotations(self, parent: str, page_size: int = None, page_token: str = None, filter: str = None) -> ListAnnotationsResponse:
500
"""
501
Lists annotations for an asset.
502
503
Args:
504
parent (str): Required. Asset resource path
505
page_size (int): Maximum number of annotations to return
506
page_token (str): Token for pagination
507
filter (str): Filter expression for annotations
508
509
Returns:
510
ListAnnotationsResponse: Response with annotations and pagination
511
"""
512
513
def update_annotation(self, annotation: Annotation, update_mask: FieldMask = None) -> Annotation:
514
"""
515
Updates annotation data and metadata.
516
517
Args:
518
annotation (Annotation): Required. Updated annotation
519
update_mask (FieldMask): Fields to update
520
521
Returns:
522
Annotation: Updated annotation resource
523
"""
524
525
def delete_annotation(self, name: str) -> Empty:
526
"""
527
Deletes an annotation.
528
529
Args:
530
name (str): Required. Annotation resource path to delete
531
532
Returns:
533
Empty: Empty response confirming deletion
534
"""
535
```
536
537
## Types
538
539
### Asset Resources
540
541
```python { .api }
542
class Asset:
543
"""Media asset with metadata and content references."""
544
name: str # Resource name
545
ttl: Duration # Time-to-live for asset
546
asset_gcs_source: AssetSource # Asset source location
547
create_time: Timestamp # Creation timestamp
548
update_time: Timestamp # Last update timestamp
549
labels: Dict[str, str] # Resource labels
550
551
class AssetSource:
552
"""Source location for asset content."""
553
# Union field oneof source:
554
asset_gcs_source: GcsSource # Google Cloud Storage source
555
asset_content_data: bytes # Direct content data
556
557
class GcsSource:
558
"""Google Cloud Storage source configuration."""
559
uris: List[str] # GCS URIs for asset content
560
561
class Corpus:
562
"""Container for related assets."""
563
name: str # Resource name
564
display_name: str # Human-readable name
565
description: str # Corpus description
566
default_ttl: Duration # Default TTL for assets
567
create_time: Timestamp # Creation timestamp
568
update_time: Timestamp # Last update timestamp
569
570
class Collection:
571
"""Curated collection of assets."""
572
name: str # Resource name
573
display_name: str # Human-readable name
574
description: str # Collection description
575
create_time: Timestamp # Creation timestamp
576
update_time: Timestamp # Last update timestamp
577
578
class CollectionItem:
579
"""Item within a collection."""
580
collection: str # Collection resource path
581
type: CollectionItemType # Type of collection item
582
# Union field oneof item:
583
asset: str # Asset resource path
584
585
class CollectionItemType(Enum):
586
"""Types of collection items."""
587
COLLECTION_ITEM_TYPE_UNSPECIFIED = 0
588
ASSET = 1 # Asset item
589
```
590
591
### Search and Index Resources
592
593
```python { .api }
594
class Index:
595
"""Search index configuration."""
596
name: str # Resource name
597
display_name: str # Human-readable name
598
description: str # Index description
599
state: IndexState # Current index state
600
create_time: Timestamp # Creation timestamp
601
update_time: Timestamp # Last update timestamp
602
603
class IndexState(Enum):
604
"""Index operational states."""
605
STATE_UNSPECIFIED = 0
606
CREATING = 1 # Index being created
607
CREATED = 2 # Index created and ready
608
UPDATING = 3 # Index being updated
609
DELETING = 4 # Index being deleted
610
ERROR = 5 # Index in error state
611
612
class Criteria:
613
"""Search criteria specification."""
614
# Union field oneof criteria:
615
field_criteria: FieldCriteria # Field-based criteria
616
text_criteria: TextCriteria # Text-based criteria
617
date_time_range_criteria: DateTimeRangeCriteria # Time range criteria
618
float_range_criteria: FloatRangeCriteria # Numeric range criteria
619
boolean_criteria: BooleanCriteria # Boolean criteria
620
feature_criteria: FeatureCriteria # Feature-based criteria
621
622
class FieldCriteria:
623
"""Field-based search criteria."""
624
field: str # Field name to search
625
# Union field oneof value:
626
text_array: StringArray # Text values
627
int_array: IntArray # Integer values
628
float_array: FloatArray # Float values
629
630
class TextCriteria:
631
"""Text-based search criteria."""
632
text_query: str # Text query string
633
634
class DateTimeRangeCriteria:
635
"""Date/time range search criteria."""
636
date_time_ranges: List[DateTimeRange] # Time ranges to search
637
638
class SearchResultItem:
639
"""Individual search result."""
640
asset: str # Asset resource path
641
segments: List[Segment] # Matching segments within asset
642
relevance_score: float # Relevance score for result
643
644
class Segment:
645
"""Segment within search result."""
646
start_time_offset: Duration # Start time of segment
647
end_time_offset: Duration # End time of segment
648
confidence: float # Confidence score for segment
649
```
650
651
### Annotation Resources
652
653
```python { .api }
654
class Annotation:
655
"""Annotation data for assets."""
656
name: str # Resource name
657
user_specified_annotation: UserSpecifiedAnnotation # User-created annotation
658
create_time: Timestamp # Creation timestamp
659
update_time: Timestamp # Last update timestamp
660
661
class UserSpecifiedAnnotation:
662
"""User-specified annotation data."""
663
key: str # Annotation key/identifier
664
# Union field oneof value:
665
partition: Partition # Temporal or spatial partition
666
classification_annotation: ClassificationAnnotation # Classification data
667
# Additional annotation value types...
668
669
class Partition:
670
"""Temporal or spatial partition specification."""
671
# Union field oneof partition_dimension:
672
temporal_partition: TemporalPartition # Time-based partition
673
spatial_partition: SpatialPartition # Space-based partition
674
relative_temporal_partition: RelativeTemporalPartition # Relative time partition
675
676
class TemporalPartition:
677
"""Time-based partition."""
678
start_time: Timestamp # Start time
679
end_time: Timestamp # End time
680
681
class SpatialPartition:
682
"""Space-based partition."""
683
# Union field oneof region:
684
circle_area: CircleArea # Circular area
685
686
class CircleArea:
687
"""Circular spatial area."""
688
latitude: float # Center latitude
689
longitude: float # Center longitude
690
radius_meter: float # Radius in meters
691
```
692
693
## Usage Examples
694
695
### Complete Asset Management Workflow
696
697
```python
698
from google.cloud import visionai_v1
699
700
# Create client
701
client = visionai_v1.WarehouseClient()
702
703
# Step 1: Create corpus
704
parent = "projects/my-project/locations/us-central1"
705
706
corpus = visionai_v1.Corpus(
707
display_name="Security Videos Corpus",
708
description="Repository for security camera footage",
709
default_ttl={"seconds": 86400 * 30} # 30 days retention
710
)
711
712
create_corpus_op = client.create_corpus(parent=parent, corpus=corpus)
713
corpus_result = create_corpus_op.result()
714
corpus_path = corpus_result.name
715
716
print(f"Created corpus: {corpus_path}")
717
718
# Step 2: Upload and create asset
719
asset = visionai_v1.Asset(
720
asset_gcs_source=visionai_v1.AssetSource(
721
asset_gcs_source=visionai_v1.GcsSource(
722
uris=["gs://my-bucket/security-footage/camera1-20240910.mp4"]
723
)
724
),
725
labels={
726
"camera_id": "camera-001",
727
"location": "main-entrance"
728
}
729
)
730
731
created_asset = client.create_asset(
732
parent=corpus_path,
733
asset=asset,
734
asset_id="camera1-footage-20240910"
735
)
736
737
asset_path = created_asset.name
738
print(f"Created asset: {asset_path}")
739
740
# Step 3: Analyze asset with AI
741
analyze_op = client.analyze_asset(name=asset_path)
742
analyze_result = analyze_op.result()
743
print(f"Asset analysis completed")
744
745
# Step 4: Create search index
746
index = visionai_v1.Index(
747
display_name="Security Footage Index",
748
description="Index for searching security camera footage"
749
)
750
751
create_index_op = client.create_index(
752
parent=corpus_path,
753
index=index,
754
index_id="security-footage-index"
755
)
756
757
index_result = create_index_op.result()
758
index_path = index_result.name
759
print(f"Created index: {index_path}")
760
761
# Step 5: Add asset to index
762
index_asset_op = client.index_asset(
763
name=asset_path,
764
index=index_path
765
)
766
index_asset_op.result()
767
print(f"Asset indexed successfully")
768
```
769
770
### Advanced Search Operations
771
772
```python
773
def search_security_footage():
774
"""Example of advanced search operations."""
775
776
client = visionai_v1.WarehouseClient()
777
corpus_path = "projects/my-project/locations/us-central1/corpora/security-videos"
778
779
# Multi-criteria search
780
search_criteria = [
781
# Search for specific time range
782
visionai_v1.Criteria(
783
date_time_range_criteria=visionai_v1.DateTimeRangeCriteria(
784
date_time_ranges=[
785
visionai_v1.DateTimeRange(
786
start_datetime={"seconds": 1725926400}, # Sept 10, 2024 00:00
787
end_datetime={"seconds": 1725940800} # Sept 10, 2024 04:00
788
)
789
]
790
)
791
),
792
# Search for specific camera
793
visionai_v1.Criteria(
794
field_criteria=visionai_v1.FieldCriteria(
795
field="labels.camera_id",
796
text_array=visionai_v1.StringArray(txt_values=["camera-001", "camera-002"])
797
)
798
),
799
# Text-based search for motion events
800
visionai_v1.Criteria(
801
text_criteria=visionai_v1.TextCriteria(
802
text_query="motion detected person walking"
803
)
804
)
805
]
806
807
# Perform search
808
search_response = client.search_assets(
809
corpus=corpus_path,
810
criteria=search_criteria,
811
result_annotation_keys=["motion_detection", "person_detection"],
812
page_size=50
813
)
814
815
# Process search results
816
for result in search_response.search_result_items:
817
print(f"Found asset: {result.asset}")
818
print(f"Relevance score: {result.relevance_score}")
819
820
for segment in result.segments:
821
print(f" Matching segment: {segment.start_time_offset} - {segment.end_time_offset}")
822
print(f" Confidence: {segment.confidence}")
823
824
def manage_collections():
825
"""Example of collection management."""
826
827
client = visionai_v1.WarehouseClient()
828
corpus_path = "projects/my-project/locations/us-central1/corpora/security-videos"
829
830
# Create collection for high-priority incidents
831
collection = visionai_v1.Collection(
832
display_name="High Priority Incidents",
833
description="Critical security incidents requiring review"
834
)
835
836
create_collection_op = client.create_collection(
837
parent=corpus_path,
838
collection=collection,
839
collection_id="high-priority-incidents"
840
)
841
842
collection_result = create_collection_op.result()
843
collection_path = collection_result.name
844
845
# Add assets to collection
846
asset_paths = [
847
f"{corpus_path}/assets/incident-001",
848
f"{corpus_path}/assets/incident-002",
849
f"{corpus_path}/assets/incident-003"
850
]
851
852
for asset_path in asset_paths:
853
collection_item = visionai_v1.CollectionItem(
854
collection=collection_path,
855
type=visionai_v1.CollectionItemType.ASSET,
856
asset=asset_path
857
)
858
859
client.add_collection_item(item=collection_item)
860
print(f"Added asset to collection: {asset_path}")
861
862
# View collection items
863
items_response = client.view_collection_items(collection=collection_path)
864
print(f"Collection contains {len(items_response.items)} items")
865
866
def create_detailed_annotations():
867
"""Example of creating detailed annotations."""
868
869
client = visionai_v1.WarehouseClient()
870
asset_path = "projects/my-project/locations/us-central1/corpora/security-videos/assets/incident-001"
871
872
# Create temporal annotation for person detection
873
person_detection_annotation = visionai_v1.Annotation(
874
user_specified_annotation=visionai_v1.UserSpecifiedAnnotation(
875
key="person_detection",
876
partition=visionai_v1.Partition(
877
temporal_partition=visionai_v1.TemporalPartition(
878
start_time={"seconds": 1725928200}, # 00:30:00
879
end_time={"seconds": 1725928320} # 00:32:00
880
)
881
)
882
)
883
)
884
885
created_annotation = client.create_annotation(
886
parent=asset_path,
887
annotation=person_detection_annotation
888
)
889
print(f"Created annotation: {created_annotation.name}")
890
891
# Create spatial annotation for motion area
892
motion_area_annotation = visionai_v1.Annotation(
893
user_specified_annotation=visionai_v1.UserSpecifiedAnnotation(
894
key="motion_area",
895
partition=visionai_v1.Partition(
896
spatial_partition=visionai_v1.SpatialPartition(
897
circle_area=visionai_v1.CircleArea(
898
latitude=37.4219999,
899
longitude=-122.0840575,
900
radius_meter=50.0
901
)
902
)
903
)
904
)
905
)
906
907
spatial_annotation = client.create_annotation(
908
parent=asset_path,
909
annotation=motion_area_annotation
910
)
911
print(f"Created spatial annotation: {spatial_annotation.name}")
912
```