Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# CHANGELOG

## _v2.5.0_

### **Date: 02-March-2026**

- Assets fields(DAM 2.0) support added
## _v2.4.1_

### **Date: 10-November-2025**
Expand Down
2 changes: 1 addition & 1 deletion contentstack/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
__title__ = 'contentstack-delivery-python'
__author__ = 'contentstack'
__status__ = 'debug'
__version__ = 'v2.4.1'
__version__ = 'v2.5.0'
__endpoint__ = 'cdn.contentstack.io'
__email__ = 'support@contentstack.com'
__developer_email__ = 'mobile@contentstack.com'
Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ Babel==2.14.0
pep517==0.13.1
tomli~=2.0.1
werkzeug~=3.1.5
Flask~=2.3.2
Flask~=3.1.3
click~=8.1.7
MarkupSafe==2.1.5
blinker~=1.8.2
blinker~=1.9.0
itsdangerous~=2.2.0
isort==5.13.2
pkginfo==1.11.1
Expand Down
81 changes: 72 additions & 9 deletions tests/test_assets.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@ def test_014_setting_retry_strategy_api(self):

def test_01_assets_query_initial_run(self):
result = self.asset_query.find()
if result is not None:
assets = result['assets']
for item in assets:
if item['title'] == 'if_icon-72-lightning_316154_(1).png':
global ASSET_UID
ASSET_UID = item['uid']
self.assertEqual(8, len(assets))
self.assertIsNotNone(result)
assets = result['assets']
for item in assets:
if item['title'] == 'if_icon-72-lightning_316154_(1).png':
global ASSET_UID
ASSET_UID = item['uid']
self.assertGreaterEqual(len(assets), 8)

def test_02_asset_method(self):
self.asset = self.stack.asset(uid=ASSET_UID)
Expand Down Expand Up @@ -117,14 +117,37 @@ def test_08_support_include_fallback(self):
self.assertEqual({'environment': 'development',
'include_fallback': 'true'}, asset_params)

def test_08a_asset_fields_single_asset(self):
"""Test single asset asset_fields sets asset_params"""
self.asset = self.stack.asset(uid=ASSET_UID or 'test_asset_uid')
self.asset.asset_fields('user_defined_fields', 'visual_markups')
self.assertEqual(['user_defined_fields', 'visual_markups'],
self.asset.asset_params['asset_fields[]'])

def test_08b_asset_fields_single_asset_chained_calls(self):
"""Test single asset asset_fields with chained calls"""
self.asset = self.stack.asset(uid=ASSET_UID or 'test_asset_uid')
self.asset.asset_fields('user_defined_fields').asset_fields('visual_markups')
self.assertEqual(['user_defined_fields', 'visual_markups'],
self.asset.asset_params['asset_fields[]'])

def test_08c_asset_fields_single_asset_all_supported_values(self):
"""Test single asset asset_fields with all supported values"""
self.asset = self.stack.asset(uid=ASSET_UID or 'test_asset_uid')
self.asset.asset_fields('user_defined_fields', 'embedded_metadata',
'ai_generated_metadata', 'visual_markups')
self.assertEqual(
['user_defined_fields', 'embedded_metadata', 'ai_generated_metadata', 'visual_markups'],
self.asset.asset_params['asset_fields[]'])

############################################
# ==== Asset Query ====
############################################

def test_09_assets_query(self):
result = self.asset_query.find()
if result is not None:
self.assertEqual(8, len(result['assets']))
self.assertIsNotNone(result)
self.assertGreaterEqual(len(result['assets']), 8)

def test_10_assets_base_query_where_exclude_title(self):
query = self.asset_query.where(
Expand Down Expand Up @@ -211,6 +234,46 @@ def test_25_include_metadata(self):
self.assertTrue(
self.asset_query.asset_query_params.__contains__('include_metadata'))

def test_25a_asset_query_asset_fields_single_field(self):
"""Test asset_query asset_fields with a single field"""
query = self.asset_query.asset_fields('user_defined_fields')
self.assertEqual(['user_defined_fields'],
query.asset_query_params['asset_fields[]'])

def test_25b_asset_query_asset_fields_multiple_fields(self):
"""Test asset_query asset_fields with multiple fields"""
query = self.asset_query.asset_fields('user_defined_fields', 'visual_markups')
self.assertEqual(['user_defined_fields', 'visual_markups'],
query.asset_query_params['asset_fields[]'])

def test_25c_asset_query_asset_fields_chained_calls(self):
"""Test asset_query asset_fields with chained calls"""
query = (self.asset_query
.asset_fields('user_defined_fields')
.asset_fields('visual_markups'))
self.assertEqual(['user_defined_fields', 'visual_markups'],
query.asset_query_params['asset_fields[]'])

def test_25d_asset_query_asset_fields_all_supported_values(self):
"""Test asset_query asset_fields with all supported values"""
query = (self.asset_query
.asset_fields('user_defined_fields', 'embedded_metadata',
'ai_generated_metadata', 'visual_markups'))
self.assertEqual(
['user_defined_fields', 'embedded_metadata', 'ai_generated_metadata', 'visual_markups'],
query.asset_query_params['asset_fields[]'])

def test_25e_asset_query_asset_fields_with_other_params(self):
"""Test asset_query asset_fields combined with include_metadata and locale"""
query = (self.asset_query
.asset_fields('user_defined_fields', 'visual_markups')
.include_metadata()
.locale('en-us'))
self.assertEqual(['user_defined_fields', 'visual_markups'],
query.asset_query_params['asset_fields[]'])
self.assertEqual('true', query.asset_query_params['include_metadata'])
self.assertEqual('en-us', query.asset_query_params['locale'])

def test_26_where_with_include_count_and_pagination(self):
"""Test combination of where, include_count, skip, and limit for assets"""
query = (self.asset_query
Expand Down
40 changes: 40 additions & 0 deletions tests/test_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,46 @@ def test_46_entry_all_queryable_methods_combined(self):
self.assertIn('include_reference_content_type_uid', entry.entry_queryable_param)
self.assertEqual('value', entry.entry_queryable_param['custom'])

def test_47_entry_asset_fields_single_field(self):
"""Test entry asset_fields with a single field"""
entry = self.stack.content_type('faq').entry(FAQ_UID).asset_fields('user_defined_fields')
self.assertEqual(['user_defined_fields'], entry.entry_queryable_param['asset_fields[]'])

def test_48_entry_asset_fields_multiple_fields(self):
"""Test entry asset_fields with multiple fields in one call"""
entry = (self.stack.content_type('faq')
.entry(FAQ_UID)
.asset_fields('user_defined_fields', 'visual_markups'))
self.assertEqual(['user_defined_fields', 'visual_markups'],
entry.entry_queryable_param['asset_fields[]'])

def test_49_entry_asset_fields_chained_calls(self):
"""Test entry asset_fields with chained calls"""
entry = (self.stack.content_type('faq')
.entry(FAQ_UID)
.asset_fields('user_defined_fields')
.asset_fields('visual_markups'))
self.assertEqual(['user_defined_fields', 'visual_markups'],
entry.entry_queryable_param['asset_fields[]'])

def test_50_entry_asset_fields_all_supported_values(self):
"""Test entry asset_fields with all supported values"""
entry = (self.stack.content_type('faq')
.entry(FAQ_UID)
.asset_fields('user_defined_fields', 'embedded_metadata',
'ai_generated_metadata', 'visual_markups'))
self.assertEqual(
['user_defined_fields', 'embedded_metadata', 'ai_generated_metadata', 'visual_markups'],
entry.entry_queryable_param['asset_fields[]'])

def test_51_query_asset_fields(self):
"""Test query asset_fields sets entry_queryable_param"""
query = (self.stack.content_type('faq')
.query()
.asset_fields('user_defined_fields', 'visual_markups'))
self.assertEqual(['user_defined_fields', 'visual_markups'],
query.entry_queryable_param['asset_fields[]'])


if __name__ == '__main__':
unittest.main()
Loading