11"""This class takes a base URL as an argument when it's initialized,
22which is the endpoint for the RESTFUL API that we'll be interacting with.
3- The query(), create(), fetch(), delete(), update(), versions(), and includeVariants () methods each correspond to
3+ The query(), create(), fetch(), delete(), update(), versions(), includeVariants(), publish(), and unpublish () methods each correspond to
44the operations that can be performed on the API """
55
66import json
77from ..common import Parameter
88from .._errors import ArgumentException
9- from .._messages import ENTRY_VARIANT_CONTENT_TYPE_UID_REQUIRED , ENTRY_VARIANT_ENTRY_UID_REQUIRED , ENTRY_VARIANT_UID_REQUIRED
9+ from .._messages import (
10+ ENTRY_BODY_REQUIRED ,
11+ ENTRY_VARIANT_CONTENT_TYPE_UID_REQUIRED ,
12+ ENTRY_VARIANT_ENTRY_UID_REQUIRED ,
13+ ENTRY_VARIANT_UID_REQUIRED ,
14+ )
1015
1116class EntryVariants (Parameter ):
1217 """
1318 This class takes a base URL as an argument when it's initialized,
1419 which is the endpoint for the RESTFUL API that
15- we'll be interacting with. The query(), create(), fetch(), delete(), update(), versions(), and includeVariants()
16- methods each correspond to the operations that can be performed on the API """
20+ we'll be interacting with. The query(), create(), fetch(), delete(), update(), versions(),
21+ includeVariants(), publish(), and unpublish() methods each correspond to the operations that can be
22+ performed on the API. Optional ``branch`` scopes requests to a stack branch via the ``branch`` header. """
1723
18- def __init__ (self , client , content_type_uid : str , entry_uid : str , variant_uid : str = None ):
24+ def __init__ (
25+ self ,
26+ client ,
27+ content_type_uid : str ,
28+ entry_uid : str ,
29+ variant_uid : str = None ,
30+ branch : str = None ,
31+ ):
1932 self .client = client
2033 self .content_type_uid = content_type_uid
2134 self .entry_uid = entry_uid
2235 self .variant_uid = variant_uid
36+ self .branch = branch if branch else None
2337 super ().__init__ (self .client )
2438 self .path = f"content_types/{ content_type_uid } /entries/{ entry_uid } /variants"
2539
40+ def _headers (self ):
41+ """Merge optional branch into request headers without mutating the client."""
42+ if not self .branch :
43+ return self .client .headers
44+ headers = dict (self .client .headers )
45+ headers ["branch" ] = self .branch
46+ return headers
2647
2748 def find (self , params : dict = None ):
2849 """
@@ -47,7 +68,7 @@ def find(self, params: dict = None):
4768 self .validate_entry_uid ()
4869 if params is not None :
4970 self .params .update (params )
50- return self .client .get (self .path , headers = self .client . headers , params = self .params )
71+ return self .client .get (self .path , headers = self ._headers () , params = self .params )
5172
5273 def create (self , data : dict ):
5374 """
@@ -79,7 +100,7 @@ def create(self, data: dict):
79100 self .validate_content_type_uid ()
80101 self .validate_entry_uid ()
81102 data = json .dumps (data )
82- return self .client .post (self .path , headers = self .client . headers , data = data , params = self .params )
103+ return self .client .post (self .path , headers = self ._headers () , data = data , params = self .params )
83104
84105 def fetch (self , variant_uid : str = None , params : dict = None ):
85106 """
@@ -96,9 +117,11 @@ def fetch(self, variant_uid: str = None, params: dict = None):
96117
97118 >>> import contentstack_management
98119 >>> client = contentstack_management.Client(authtoken='your_authtoken')
99- >>> result = client.stack('api_key').content_types('content_type_uid').entry('entry_uid').variants('variant_uid' ).fetch().json()
120+ >>> result = client.stack('api_key').content_types('content_type_uid').entry('entry_uid').variants().fetch('variant_uid' ).json()
100121 >>> # With parameters
101- >>> result = client.stack('api_key').content_types('content_type_uid').entry('entry_uid').variants('variant_uid').fetch(params={'include_count': True}).json()
122+ >>> result = client.stack('api_key').content_types('content_type_uid').entry('entry_uid').variants().fetch('variant_uid', params={'include_count': True}).json()
123+ >>> # On a branch
124+ >>> result = client.stack('api_key').content_types('content_type_uid').entry('entry_uid').variants('variant_uid', 'branch_uid').fetch().json()
102125
103126 -------------------------------
104127 """
@@ -112,7 +135,7 @@ def fetch(self, variant_uid: str = None, params: dict = None):
112135 if params is not None :
113136 self .params .update (params )
114137 url = f"{ self .path } /{ self .variant_uid } "
115- return self .client .get (url , headers = self .client . headers , params = self .params )
138+ return self .client .get (url , headers = self ._headers () , params = self .params )
116139
117140 def delete (self , variant_uid : str = None ):
118141 """
@@ -128,7 +151,7 @@ def delete(self, variant_uid: str = None):
128151
129152 >>> import contentstack_management
130153 >>> client = contentstack_management.Client(authtoken='your_authtoken')
131- >>> result = client.stack('api_key').content_types('content_type_uid').entry('entry_uid').variants('variant_uid' ).delete().json()
154+ >>> result = client.stack('api_key').content_types('content_type_uid').entry('entry_uid').variants().delete('variant_uid' ).json()
132155
133156 -------------------------------
134157 """
@@ -138,7 +161,7 @@ def delete(self, variant_uid: str = None):
138161 self .validate_entry_uid ()
139162 self .validate_variant_uid ()
140163 url = f"{ self .path } /{ self .variant_uid } "
141- return self .client .delete (url , headers = self .client . headers , params = self .params )
164+ return self .client .delete (url , headers = self ._headers () , params = self .params )
142165
143166 def update (self , data : dict , variant_uid : str = None ):
144167 """
@@ -167,7 +190,7 @@ def update(self, data: dict, variant_uid: str = None):
167190 >>> }
168191 >>> import contentstack_management
169192 >>> client = contentstack_management.Client(authtoken='your_authtoken')
170- >>> result = client.stack('api_key').content_types('content_type_uid').entry('entry_uid').variants('variant_uid' ).update(data).json()
193+ >>> result = client.stack('api_key').content_types('content_type_uid').entry('entry_uid').variants().update(data, 'variant_uid' ).json()
171194
172195 -------------------------------
173196 """
@@ -178,7 +201,7 @@ def update(self, data: dict, variant_uid: str = None):
178201 self .validate_variant_uid ()
179202 url = f"{ self .path } /{ self .variant_uid } "
180203 data = json .dumps (data )
181- return self .client .put (url , headers = self .client . headers , data = data , params = self .params )
204+ return self .client .put (url , headers = self ._headers () , data = data , params = self .params )
182205
183206 def versions (self , variant_uid : str = None , params : dict = None ):
184207 """
@@ -195,9 +218,9 @@ def versions(self, variant_uid: str = None, params: dict = None):
195218
196219 >>> import contentstack_management
197220 >>> client = contentstack_management.Client(authtoken='your_authtoken')
198- >>> result = client.stack('api_key').content_types('content_type_uid').entry('entry_uid').variants('variant_uid' ).versions().json()
221+ >>> result = client.stack('api_key').content_types('content_type_uid').entry('entry_uid').variants().versions('variant_uid' ).json()
199222 >>> # With parameters
200- >>> result = client.stack('api_key').content_types('content_type_uid').entry('entry_uid').variants('variant_uid' ).versions(params={'limit': 10}).json()
223+ >>> result = client.stack('api_key').content_types('content_type_uid').entry('entry_uid').variants().versions('variant_uid', params={'limit': 10}).json()
201224
202225 -------------------------------
203226 """
@@ -209,7 +232,7 @@ def versions(self, variant_uid: str = None, params: dict = None):
209232 if params is not None :
210233 self .params .update (params )
211234 url = f"{ self .path } /{ self .variant_uid } /versions"
212- return self .client .get (url , headers = self .client . headers , params = self .params )
235+ return self .client .get (url , headers = self ._headers () , params = self .params )
213236
214237 def includeVariants (self , include_variants : str = 'true' , variant_uid : str = None , params : dict = None ):
215238 """
@@ -243,8 +266,85 @@ def includeVariants(self, include_variants: str = 'true', variant_uid: str = Non
243266 self .params .update (params )
244267 self .params ['include_variants' ] = include_variants
245268 url = f"content_types/{ self .content_type_uid } /entries/{ self .entry_uid } "
246- return self .client .get (url , headers = self .client . headers , params = self .params )
269+ return self .client .get (url , headers = self ._headers () , params = self .params )
247270
271+ def publish (self , data : dict ):
272+ """
273+ Publish the entry for this content type and entry UID (CMA ``.../entries/{entry_uid}/publish``).
274+
275+ For entry variants, the body typically includes ``entry.environments``, ``entry.locales``,
276+ ``entry.variants`` (list of ``{"uid", "version"}`` per variant), optional ``entry.variant_rules``,
277+ and top-level ``locale`` (and optional scheduling fields supported by the API).
278+
279+ :param data: Publish payload dict (serialized as JSON).
280+ :return: Response from the publish request.
281+ -------------------------------
282+ [Example:]
283+
284+ >>> data = {
285+ >>> "entry": {
286+ >>> "environments": ["production"],
287+ >>> "locales": ["en-us"],
288+ >>> "variants": [
289+ >>> {"uid": "variant_uid", "version": 1}
290+ >>> ],
291+ >>> "variant_rules": {
292+ >>> "publish_latest_base": False,
293+ >>> "publish_latest_base_conditionally": True
294+ >>> }
295+ >>> },
296+ >>> "locale": "en-us"
297+ >>> }
298+ >>> import contentstack_management
299+ >>> client = contentstack_management.Client(authtoken='your_authtoken')
300+ >>> result = client.stack('api_key').content_types('content_type_uid').entry('entry_uid').variants().publish(data).json()
301+
302+ -------------------------------
303+ """
304+ self .validate_content_type_uid ()
305+ self .validate_entry_uid ()
306+ if data is None :
307+ raise Exception (ENTRY_BODY_REQUIRED )
308+ url = f"content_types/{ self .content_type_uid } /entries/{ self .entry_uid } /publish"
309+ data = json .dumps (data )
310+ return self .client .post (url , headers = self ._headers (), data = data , params = self .params )
311+
312+ def unpublish (self , data : dict ):
313+ """
314+ Unpublish the entry for this content type and entry UID (CMA ``.../entries/{entry_uid}/unpublish``).
315+
316+ For entry variants, the body typically includes ``entry.environments``, ``entry.locales``,
317+ ``entry.variants`` (list of ``{"uid", "version"}`` per variant), and top-level ``locale``.
318+
319+ :param data: Unpublish payload dict (serialized as JSON).
320+ :return: Response from the unpublish request.
321+ -------------------------------
322+ [Example:]
323+
324+ >>> data = {
325+ >>> "entry": {
326+ >>> "environments": ["environment_uid"],
327+ >>> "locales": ["en-us"],
328+ >>> "variants": [
329+ >>> {"uid": "variant_uid", "version": 1}
330+ >>> ]
331+ >>> },
332+ >>> "locale": "en-us"
333+ >>> }
334+ >>> import contentstack_management
335+ >>> client = contentstack_management.Client(authtoken='your_authtoken')
336+ >>> result = client.stack('api_key').content_types('content_type_uid').entry('entry_uid').variants().unpublish(data).json()
337+
338+ -------------------------------
339+ """
340+ self .validate_content_type_uid ()
341+ self .validate_entry_uid ()
342+ if data is None :
343+ raise Exception (ENTRY_BODY_REQUIRED )
344+ url = f"content_types/{ self .content_type_uid } /entries/{ self .entry_uid } /unpublish"
345+ data = json .dumps (data )
346+ return self .client .post (url , headers = self ._headers (), data = data , params = self .params )
347+
248348 def validate_content_type_uid (self ):
249349 """
250350 The function checks if the content_type_uid is None or an empty string and raises an ArgumentException
0 commit comments