0
# Search API
1
2
Advanced asset discovery with filtering, sorting, and aggregation capabilities for finding specific resources in your Cloudinary account.
3
4
## Capabilities
5
6
### Search Class
7
8
Main search interface for building and executing search queries.
9
10
```python { .api }
11
class Search:
12
"""Search for resources using various criteria and expressions.
13
14
Provides a fluent interface for building complex search queries with filtering,
15
sorting, aggregation, and pagination capabilities.
16
"""
17
18
def __init__(self):
19
"""Initialize a new search query."""
20
21
def expression(self, value):
22
"""Set the search expression to filter resources.
23
24
Args:
25
value (str): Search expression using Cloudinary search syntax.
26
Examples:
27
- "cat AND tags:kitten"
28
- "resource_type:image AND format:jpg"
29
- "created_at>1d AND bytes>1mb"
30
- "folder:products/* AND width>500"
31
32
Returns:
33
Search: Self for method chaining
34
"""
35
36
def max_results(self, value):
37
"""Set maximum number of results to return.
38
39
Args:
40
value (int): Maximum results (1-500, default: 50)
41
42
Returns:
43
Search: Self for method chaining
44
"""
45
46
def next_cursor(self, value):
47
"""Set cursor for pagination.
48
49
Args:
50
value (str): Cursor token from previous search result
51
52
Returns:
53
Search: Self for method chaining
54
"""
55
56
def sort_by(self, field, direction="desc"):
57
"""Add sort criteria to the search.
58
59
Args:
60
field (str): Field to sort by ('created_at', 'uploaded_at', 'public_id', 'filename', 'format', 'resource_type', 'type', 'bytes', 'width', 'height', 'aspect_ratio', 'pixels', 'duration', 'bit_rate', 'frame_rate')
61
direction (str, optional): Sort direction ('asc', 'desc', default: 'desc')
62
63
Returns:
64
Search: Self for method chaining
65
"""
66
67
def aggregate(self, value):
68
"""Add aggregation to the search results.
69
70
Args:
71
value (str): Aggregation field ('resource_type', 'type', 'format', 'bytes', 'width', 'height', 'aspect_ratio', 'pixels', 'created_at', 'uploaded_at', 'tags', 'context', 'metadata')
72
73
Returns:
74
Search: Self for method chaining
75
"""
76
77
def with_field(self, value):
78
"""Include additional fields in search results.
79
80
Args:
81
value (str): Field to include ('context', 'metadata', 'tags', 'image_analysis', 'asset_folder', 'display_name')
82
83
Returns:
84
Search: Self for method chaining
85
"""
86
87
def execute(self, **options):
88
"""Execute the search query.
89
90
Args:
91
**options: Additional search options
92
93
Returns:
94
dict: Search results containing:
95
- total_count (int): Total number of matching resources
96
- time (int): Search execution time in milliseconds
97
- aggregations (dict): Aggregation results (if requested)
98
- resources (list): List of matching resources
99
- next_cursor (str): Cursor for next page (if more results exist)
100
- rate_limit_allowed (int): Rate limit quota
101
- rate_limit_reset_at (str): Rate limit reset time
102
- rate_limit_remaining (int): Remaining rate limit quota
103
"""
104
```
105
106
### Folder Search
107
108
Specialized search for folder structures, inheriting all capabilities from the Search class.
109
110
```python { .api }
111
class SearchFolders(Search):
112
"""Search for folders in your Cloudinary account.
113
114
Provides folder-specific search capabilities with hierarchical filtering.
115
Inherits all methods from the Search class but targets the folders endpoint.
116
"""
117
118
def __init__(self):
119
"""Initialize a new folder search query.
120
121
Automatically sets the search endpoint to 'folders' instead of 'resources'.
122
"""
123
124
def expression(self, value):
125
"""Set the folder search expression.
126
127
Args:
128
value (str): Search expression for folders using folder-specific criteria.
129
Examples:
130
- "name:product*" (folders starting with 'product')
131
- "path:images/products/*" (folders in specific path)
132
- "created_at:>30d" (folders created in last 30 days)
133
134
Returns:
135
SearchFolders: Self for method chaining
136
"""
137
138
def max_results(self, value):
139
"""Set maximum number of folder results to return.
140
141
Args:
142
value (int): Maximum results (1-500, default: 50)
143
144
Returns:
145
SearchFolders: Self for method chaining
146
"""
147
148
def next_cursor(self, value):
149
"""Set cursor for folder pagination.
150
151
Args:
152
value (str): Cursor token from previous search result
153
154
Returns:
155
SearchFolders: Self for method chaining
156
"""
157
158
def sort_by(self, field, direction="desc"):
159
"""Add sort criteria for folders.
160
161
Args:
162
field (str): Field to sort by ('name', 'created_at', 'path', 'external_id')
163
direction (str, optional): Sort direction ('asc', 'desc', default: 'desc')
164
165
Returns:
166
SearchFolders: Self for method chaining
167
"""
168
169
def aggregate(self, value):
170
"""Add aggregation to folder search results.
171
172
Args:
173
value (str): Aggregation field for folders ('name', 'path', 'created_at')
174
175
Returns:
176
SearchFolders: Self for method chaining
177
"""
178
179
def with_field(self, value):
180
"""Include additional fields in folder search results.
181
182
Args:
183
value (str): Field to include ('external_id', 'metadata')
184
185
Returns:
186
SearchFolders: Self for method chaining
187
"""
188
189
def fields(self, value):
190
"""Request specific fields to return in the folder result set.
191
192
Args:
193
value (str): Comma-separated list of fields to include in results
194
195
Returns:
196
SearchFolders: Self for method chaining
197
"""
198
199
def ttl(self, ttl):
200
"""Set the time to live of the search URL.
201
202
Args:
203
ttl (int): The time to live in seconds
204
205
Returns:
206
SearchFolders: Self for method chaining
207
"""
208
209
def to_url(self, ttl=None, next_cursor=None, **options):
210
"""Create a signed Search URL for folders that can be used on the client side.
211
212
Args:
213
ttl (int, optional): The time to live in seconds
214
next_cursor (str, optional): Starting position
215
**options: Additional url delivery options including api_secret
216
217
Returns:
218
str: The resulting folder search URL
219
"""
220
221
def to_json(self):
222
"""Convert the folder search query to JSON string.
223
224
Returns:
225
str: JSON representation of the search query
226
"""
227
228
def as_dict(self):
229
"""Convert the folder search query to dictionary format.
230
231
Returns:
232
dict: Dictionary representation of the search query
233
"""
234
235
def execute(self, **options):
236
"""Execute the folder search query.
237
238
Args:
239
**options: Additional search options
240
241
Returns:
242
dict: Folder search results containing:
243
- total_count (int): Total number of matching folders
244
- time (int): Search execution time in milliseconds
245
- aggregations (dict): Aggregation results (if requested)
246
- folders (list): List of matching folders with properties:
247
- name (str): Folder name
248
- path (str): Full folder path
249
- external_id (str): External identifier (if set)
250
- created_at (str): Creation timestamp
251
- next_cursor (str): Cursor for next page (if more results exist)
252
- rate_limit_allowed (int): Rate limit quota
253
- rate_limit_reset_at (str): Rate limit reset time
254
- rate_limit_remaining (int): Remaining rate limit quota
255
"""
256
```
257
258
### Search Utility Functions
259
260
Helper functions for search operations.
261
262
```python { .api }
263
def Search():
264
"""Create a new Search instance.
265
266
Returns:
267
Search: New search query builder
268
"""
269
270
def SearchFolders():
271
"""Create a new SearchFolders instance.
272
273
The SearchFolders class inherits from Search but automatically targets
274
the folders endpoint for searching folder structures instead of assets.
275
276
Returns:
277
SearchFolders: New folder search query builder
278
"""
279
```
280
281
## Search Expression Syntax
282
283
The search expression supports a rich query language for filtering resources:
284
285
### Basic Syntax
286
- **Field matching**: `field:value` (e.g., `format:jpg`, `width:>500`)
287
- **Text search**: `text` (searches in filename, public_id, and tags)
288
- **Boolean operators**: `AND`, `OR`, `NOT`
289
- **Grouping**: Use parentheses `(expression)`
290
291
### Field Types
292
- **String fields**: `public_id`, `filename`, `format`, `resource_type`, `type`
293
- **Numeric fields**: `width`, `height`, `bytes`, `duration`, `aspect_ratio`, `pixels`
294
- **Date fields**: `created_at`, `uploaded_at`
295
- **Array fields**: `tags`, `context`, `metadata`
296
297
### Operators
298
- **Equality**: `field:value`
299
- **Comparison**: `field:>value`, `field:>=value`, `field:<value`, `field:<=value`
300
- **Range**: `field:[min TO max]`
301
- **Wildcard**: `field:value*` (prefix matching)
302
- **Existence**: `field:*` (field exists)
303
304
### Time Expressions
305
- **Relative**: `1d` (1 day ago), `2w` (2 weeks ago), `3m` (3 months ago), `1y` (1 year ago)
306
- **Absolute**: `2023-01-01` (specific date)
307
308
### Folder Search Expression Syntax
309
310
Folder search uses a similar syntax but with folder-specific fields:
311
312
#### Folder-Specific Fields
313
- **name**: Folder name (string)
314
- **path**: Full folder path (string)
315
- **external_id**: External identifier if set (string)
316
- **created_at**: Folder creation timestamp (date)
317
318
#### Folder Search Examples
319
- **By name**: `name:products`, `name:temp*` (wildcard matching)
320
- **By path**: `path:images/products/*`, `path:*/uploads`
321
- **By creation date**: `created_at:>30d`, `created_at:[2023-01-01 TO 2023-12-31]`
322
- **Complex queries**: `name:temp* AND created_at:<7d`, `path:*/archive OR name:old*`
323
- **Match all folders**: `*` (returns all folders)
324
325
## Usage Examples
326
327
### Basic Search
328
329
```python
330
from cloudinary.search import Search
331
332
# Create and execute a simple search
333
search = Search()
334
result = search.expression("cat").execute()
335
print(f"Found {result['total_count']} resources with 'cat'")
336
337
# Method chaining
338
result = Search() \
339
.expression("resource_type:image AND format:jpg") \
340
.max_results(100) \
341
.sort_by("created_at", "asc") \
342
.execute()
343
344
# Search with multiple criteria
345
result = Search() \
346
.expression("tags:product AND bytes:>1mb AND width:>800") \
347
.max_results(50) \
348
.execute()
349
```
350
351
### Advanced Filtering
352
353
```python
354
# Search by date range
355
result = Search() \
356
.expression("created_at:[2023-01-01 TO 2023-12-31]") \
357
.sort_by("created_at", "desc") \
358
.execute()
359
360
# Search with complex boolean logic
361
result = Search() \
362
.expression("(tags:summer OR tags:beach) AND format:jpg AND bytes:<5mb") \
363
.execute()
364
365
# Search by folder and metadata
366
result = Search() \
367
.expression("folder:products/* AND metadata.category:electronics") \
368
.with_field("metadata") \
369
.execute()
370
371
# Search recent large images
372
result = Search() \
373
.expression("resource_type:image AND created_at:>7d AND bytes:>2mb") \
374
.sort_by("bytes", "desc") \
375
.execute()
376
```
377
378
### Aggregations and Analytics
379
380
```python
381
# Get format distribution
382
result = Search() \
383
.expression("resource_type:image") \
384
.aggregate("format") \
385
.max_results(0) \
386
.execute()
387
388
format_counts = result['aggregations']['format']
389
for format_info in format_counts:
390
print(f"{format_info['value']}: {format_info['count']} images")
391
392
# Multiple aggregations
393
result = Search() \
394
.expression("tags:product") \
395
.aggregate("format") \
396
.aggregate("resource_type") \
397
.aggregate("bytes") \
398
.max_results(0) \
399
.execute()
400
401
# Tag analysis
402
result = Search() \
403
.expression("created_at:>30d") \
404
.aggregate("tags") \
405
.max_results(0) \
406
.execute()
407
```
408
409
### Pagination
410
411
```python
412
# Paginate through search results
413
all_resources = []
414
next_cursor = None
415
416
while True:
417
search = Search() \
418
.expression("resource_type:image AND tags:product") \
419
.max_results(500) \
420
.sort_by("created_at", "desc")
421
422
if next_cursor:
423
search.next_cursor(next_cursor)
424
425
result = search.execute()
426
all_resources.extend(result['resources'])
427
428
next_cursor = result.get('next_cursor')
429
if not next_cursor:
430
break
431
432
print(f"Total resources found: {len(all_resources)}")
433
```
434
435
### Folder Search Examples
436
437
```python
438
from cloudinary.search_folders import SearchFolders
439
440
# Basic folder search by name pattern
441
result = SearchFolders() \
442
.expression("name:product*") \
443
.max_results(100) \
444
.sort_by("name", "asc") \
445
.execute()
446
447
print(f"Found {result['total_count']} folders")
448
for folder in result['folders']:
449
print(f"Folder: {folder['name']} (path: {folder['path']})")
450
451
# Search folders by creation date
452
result = SearchFolders() \
453
.expression("created_at:>30d") \
454
.sort_by("created_at", "desc") \
455
.execute()
456
457
# Search folders by path prefix
458
result = SearchFolders() \
459
.expression("path:images/products/*") \
460
.with_field("external_id") \
461
.execute()
462
463
# Search with aggregation to analyze folder structure
464
result = SearchFolders() \
465
.expression("created_at:>90d") \
466
.aggregate("path") \
467
.max_results(0) \
468
.execute()
469
470
# Get folder distribution by creation date
471
for agg_item in result['aggregations']['path']:
472
print(f"Path: {agg_item['value']}, Count: {agg_item['count']}")
473
474
# Complex folder search with multiple criteria
475
result = SearchFolders() \
476
.expression("name:temp* OR path:*/temp/* AND created_at:<7d") \
477
.sort_by("path", "asc") \
478
.max_results(50) \
479
.execute()
480
481
# Paginate through all folders
482
all_folders = []
483
next_cursor = None
484
485
while True:
486
search = SearchFolders() \
487
.expression("*") \
488
.max_results(500) \
489
.sort_by("name", "asc")
490
491
if next_cursor:
492
search.next_cursor(next_cursor)
493
494
result = search.execute()
495
all_folders.extend(result['folders'])
496
497
next_cursor = result.get('next_cursor')
498
if not next_cursor:
499
break
500
501
print(f"Total folders: {len(all_folders)}")
502
503
# Generate a signed URL for folder search (client-side usage)
504
search_url = SearchFolders() \
505
.expression("name:upload*") \
506
.max_results(100) \
507
.to_url(ttl=3600, api_secret="your_api_secret")
508
509
print(f"Folder search URL: {search_url}")
510
```
511
512
### Detailed Results with Metadata
513
514
```python
515
# Include all available metadata in results
516
result = Search() \
517
.expression("tags:featured") \
518
.with_field("context") \
519
.with_field("metadata") \
520
.with_field("tags") \
521
.with_field("image_analysis") \
522
.max_results(10) \
523
.execute()
524
525
for resource in result['resources']:
526
print(f"Public ID: {resource['public_id']}")
527
print(f" Tags: {resource.get('tags', [])}")
528
print(f" Context: {resource.get('context', {})}")
529
print(f" Metadata: {resource.get('metadata', {})}")
530
if 'image_analysis' in resource:
531
print(f" Colors: {resource['image_analysis'].get('colors', [])}")
532
```
533
534
### Performance Optimization
535
536
```python
537
# Search without fetching resources (aggregation only)
538
result = Search() \
539
.expression("resource_type:image") \
540
.aggregate("format") \
541
.aggregate("bytes") \
542
.max_results(0) \
543
.execute()
544
545
# Efficient search with minimal fields
546
result = Search() \
547
.expression("tags:thumbnail") \
548
.sort_by("created_at", "desc") \
549
.max_results(100) \
550
.execute()
551
552
# Only get public_id and basic info
553
for resource in result['resources']:
554
public_id = resource['public_id']
555
format = resource['format']
556
bytes_size = resource['bytes']
557
print(f"{public_id}.{format} ({bytes_size} bytes)")
558
```