Skip to content

Commit 5c2456d

Browse files
Added variants support in Python CDA SDK
1 parent bbf9bef commit 5c2456d

File tree

5 files changed

+70
-2
lines changed

5 files changed

+70
-2
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# CHANGELOG
22

3+
## _v2.2.0_
4+
5+
### **Date: 14-July-2025**
6+
7+
- Variants Support Added.
8+
39
## _v2.1.1_
410

511
### **Date: 07-July-2025**

contentstack/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
__title__ = 'contentstack-delivery-python'
2323
__author__ = 'contentstack'
2424
__status__ = 'debug'
25-
__version__ = 'v2.1.1'
25+
__version__ = 'v2.2.0'
2626
__endpoint__ = 'cdn.contentstack.io'
2727
__email__ = 'support@contentstack.com'
2828
__developer_email__ = 'mobile@contentstack.com'

contentstack/contenttype.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,23 @@ def find(self, params=None):
118118
url = f'{endpoint}/content_types?{encoded_params}'
119119
result = self.http_instance.get(url)
120120
return result
121+
122+
def variants(self, variant_uid: str | list[str], params: dict = None):
123+
"""
124+
Fetches the variants of the content type
125+
:param variant_uid: {str} -- variant_uid
126+
:return: Entry, so you can chain this call.
127+
"""
128+
if isinstance(variant_uid, str):
129+
self.http_instance.headers['x-cs-variant-uid'] = variant_uid
130+
elif isinstance(variant_uid, list):
131+
self.http_instance.headers['x-cs-variant-uid'] = ','.join(variant_uid)
132+
133+
if params is not None:
134+
self.local_param.update(params)
135+
136+
encoded_params = parse.urlencode(self.local_param)
137+
endpoint = self.http_instance.endpoint
138+
url = f'{endpoint}/content_types/{self.__content_type_uid}/entries?{encoded_params}'
139+
result = self.http_instance.get(url)
140+
return result

contentstack/entry.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,26 @@ def _merged_response(self):
222222
merged_response = DeepMergeMixin(entry_response, lp_entry).to_dict() # Convert to dictionary
223223
return merged_response # Now correctly returns a dictionary
224224
raise ValueError("Missing required keys in live_preview data")
225+
226+
def variants(self, variant_uid: str | list[str], params: dict = None):
227+
"""
228+
Fetches the variants of the entry
229+
:param variant_uid: {str} -- variant_uid
230+
:return: Entry, so you can chain this call.
231+
"""
232+
if isinstance(variant_uid, str):
233+
self.http_instance.headers['x-cs-variant-uid'] = variant_uid
234+
elif isinstance(variant_uid, list):
235+
self.http_instance.headers['x-cs-variant-uid'] = ','.join(variant_uid)
236+
237+
if params is not None:
238+
self.entry_param.update(params)
239+
encoded_params = parse.urlencode(self.entry_param)
240+
endpoint = self.http_instance.endpoint
241+
url = f'{endpoint}/content_types/{self.content_type_id}/entries/{self.entry_uid}?{encoded_params}'
242+
result = self.http_instance.get(url)
243+
return result
244+
225245

226246

227247

tests/test_entry.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
ENVIRONMENT = config.ENVIRONMENT
99
HOST = config.HOST
1010
FAQ_UID = config.FAQ_UID # Add this in your config.py
11-
11+
VARIANT_UID = config.VARIANT_UID
1212

1313
class TestEntry(unittest.TestCase):
1414

@@ -134,6 +134,28 @@ def test_22_entry_include_metadata(self):
134134
content_type = self.stack.content_type('faq')
135135
entry = content_type.entry("878783238783").include_metadata()
136136
self.assertEqual({'include_metadata': 'true'}, entry.entry_queryable_param)
137+
138+
def test_23_content_type_variants(self):
139+
content_type = self.stack.content_type('faq')
140+
entry = content_type.variants(VARIANT_UID)
141+
self.assertIn('variants', entry['entries'][0]['publish_details'])
142+
143+
def test_24_entry_variants(self):
144+
content_type = self.stack.content_type('faq')
145+
entry = content_type.entry(FAQ_UID).variants(VARIANT_UID)
146+
self.assertIn('variants', entry['entry']['publish_details'])
147+
148+
def test_25_content_type_variants_with_has_hash_variant(self):
149+
content_type = self.stack.content_type('faq')
150+
entry = content_type.variants([VARIANT_UID])
151+
self.assertIn('variants', entry['entries'][0]['publish_details'])
152+
153+
def test_25_content_type_entry_variants_with_has_hash_variant(self):
154+
content_type = self.stack.content_type('faq').entry(FAQ_UID)
155+
entry = content_type.variants([VARIANT_UID])
156+
self.assertIn('variants', entry['entry']['publish_details'])
157+
158+
137159

138160

139161
if __name__ == '__main__':

0 commit comments

Comments
 (0)