Skip to content

Commit 9bc3c6a

Browse files
Merge pull request #95 from contentstack/enh/dx-3048
Added nested global fields support
2 parents e297b6f + 6ceff15 commit 9bc3c6a

File tree

7 files changed

+129
-37
lines changed

7 files changed

+129
-37
lines changed

.talismanrc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,4 +354,10 @@ fileignoreconfig:
354354
checksum: c7323b95249759bc67c33d3a89d3d2e8b3ed3d146b944682d451ebebe22567c0
355355
- filename: .github/workflows/secrets-scan.yml
356356
checksum: d79ec3f3288964f7d117b9ad319a54c0ebc152e35f69be8fde95522034fdfb2a
357-
version: ""
357+
- filename: tests/api/global_fields/test_global_fields_api.py
358+
checksum: 1cd57383fcad33cfaddc03aec9a7ee3e85b27de35e4545462fca33e74768e812
359+
- filename: tests/unit/global_fields/test_global_fields_unittest.py
360+
checksum: 9bb05624cf1dadb770b3cf17fbfe915cf3133d622110da30a7dfebdeab0a315c
361+
- filename: tests/api/global_fields/test_global_fields_api.py
362+
checksum: ef69455a51168ea34d62a68caea0984504d3feeafb78010947fa99d7c54d9e9c
363+
version: "1.0"

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
## Content Management SDK For Python
44
---
5+
## v1.5.0
6+
7+
#### Date: 09 June 2025
8+
9+
- Added Nested Global fields support.
10+
---
511
## v1.4.0
612

713
#### Date: 26 May 2025

contentstack_management/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
__author__ = 'dev-ex'
7373
__status__ = 'debug'
7474
__region__ = 'na'
75-
__version__ = '1.4.0'
75+
__version__ = '1.5.0'
7676
__host__ = 'api.contentstack.io'
7777
__protocol__ = 'https://'
7878
__api_version__ = 'v3'

contentstack_management/global_fields/global_fields.py

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,13 @@ class GlobalFields(Parameter):
1818
methods each correspond to the CRUD
1919
operations that can be performed on the API """
2020

21-
def __init__(self, client, global_field_uid=None):
21+
def __init__(self, client, global_field_uid=None, options=None):
2222
self.client = client
2323
self.global_field_uid = global_field_uid
24+
self.options = options
2425
super().__init__(self.client)
26+
if self.options and 'api_version' in self.options:
27+
Parameter.add_header(self, 'api_version', str(self.options['api_version']))
2528

2629
def find(self):
2730
"""
@@ -34,7 +37,12 @@ def find(self):
3437
>>> result = client.stack("api_key").global_fields('global_field_uid').find().json()
3538
-------------------------------
3639
"""
37-
return self.client.get(_path, headers=self.client.headers, params = self.params)
40+
response = self.client.get(_path, headers=self.client.headers, params = self.params)
41+
# Remove the api_version header after request
42+
if self.options and 'api_version' in self.options:
43+
self.client.headers.pop('api_version', None)
44+
45+
return response
3846

3947
def fetch(self):
4048
"""
@@ -50,7 +58,12 @@ def fetch(self):
5058
-------------------------------
5159
"""
5260
url = f"{_path}/{self.global_field_uid}"
53-
return self.client.get(url, headers=self.client.headers, params = self.params)
61+
response = self.client.get(url, headers=self.client.headers, params = self.params)
62+
# Remove the api_version header after request
63+
if self.options and 'api_version' in self.options:
64+
self.client.headers.pop('api_version', None)
65+
66+
return response
5467

5568
def create(self, data):
5669
"""
@@ -74,7 +87,12 @@ def create(self, data):
7487
-------------------------------
7588
"""
7689
data = json.dumps(data)
77-
return self.client.post(_path, headers=self.client.headers, data=data, params = self.params)
90+
response = self.client.post(_path, headers=self.client.headers, data=data, params = self.params)
91+
# Remove the api_version header after request
92+
if self.options and 'api_version' in self.options:
93+
self.client.headers.pop('api_version', None)
94+
95+
return response
7896

7997
def update(self, data):
8098
"""
@@ -99,7 +117,12 @@ def update(self, data):
99117
"""
100118
url = f"{_path}/{self.global_field_uid}"
101119
data = json.dumps(data)
102-
return self.client.put(url, headers=self.client.headers, params=self.params, data=data)
120+
response = self.client.put(url, headers=self.client.headers, params=self.params, data=data)
121+
# Remove the api_version header after request
122+
if self.options and 'api_version' in self.options:
123+
self.client.headers.pop('api_version', None)
124+
125+
return response
103126

104127
def delete(self):
105128
"""
@@ -114,7 +137,12 @@ def delete(self):
114137
-------------------------------
115138
"""
116139
url = f"{_path}/{self.global_field_uid}"
117-
return self.client.delete(url, headers=self.client.headers, params=self.params)
140+
response = self.client.delete(url, headers=self.client.headers, params=self.params)
141+
# Remove the api_version header after request
142+
if self.options and 'api_version' in self.options:
143+
self.client.headers.pop('api_version', None)
144+
145+
return response
118146

119147
def imports(self, file_path):
120148
"""
@@ -131,7 +159,12 @@ def imports(self, file_path):
131159
"""
132160
self.client.headers['Content-Type'] = "multipart/form-data"
133161
files = {'global_field': open(f"{file_path}", 'rb')}
134-
return self.client.post('global_fields/import', headers=self.client.headers, params=self.params, files=files)
162+
response = self.client.post('global_fields/import', headers=self.client.headers, params=self.params, files=files)
163+
# Remove the api_version header after request
164+
if self.options and 'api_version' in self.options:
165+
self.client.headers.pop('api_version', None)
166+
167+
return response
135168

136169
def export(self):
137170
"""
@@ -148,4 +181,9 @@ def export(self):
148181
if self.global_field_uid is None or '':
149182
raise Exception('global_field_uid is required')
150183
url = f"{_path}/{self.global_field_uid}/export"
151-
return self.client.get(url, headers=self.client.headers, params=self.params)
184+
response = self.client.get(url, headers=self.client.headers, params=self.params)
185+
# Remove the api_version header after request
186+
if self.options and 'api_version' in self.options:
187+
self.client.headers.pop('api_version', None)
188+
189+
return response

contentstack_management/stack/stack.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -293,10 +293,8 @@ def unshare(self, data):
293293
data = json.dumps(data)
294294
return self.client.post('stacks/unshare', headers=self.client.headers, params=self.params, data=data)
295295

296-
def global_fields(self, global_field_uid=None):
297-
if 'api_key' not in self.client.headers:
298-
raise Exception('api_key is required')
299-
return GlobalFields(self.client, global_field_uid)
296+
def global_fields(self, global_field_uid=None, options=None):
297+
return GlobalFields(self.client, global_field_uid, options)
300298

301299
def branch(self, branch_uid=None):
302300
return Branch(self.client, branch_uid)

tests/api/global_fields/test_global_fields_api.py

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
password = credentials["password"]
99
host = credentials["host"]
1010
api_key = credentials["api_key"]
11-
global_field_uid = credentials["global_field_uid"]
11+
global_field_uid = 'global_field_uid' # Replace with actual UID or fetch from response if available
1212

1313
class GlobalFieldsApiTests(unittest.TestCase):
1414

@@ -23,13 +23,27 @@ def read_file(self, file_name):
2323
infile.close()
2424
return data
2525

26-
26+
def test_create_global_fields(self):
27+
read_mock_global_fields_data = self.read_file("create_global_fields.json")
28+
read_mock_global_fields_data = json.loads(read_mock_global_fields_data)
29+
response = self.client.stack(api_key).global_fields().create(read_mock_global_fields_data)
30+
global_field_uid = response.data.get('uid', 'global_field_uid')
31+
self.assertIsNotNone(global_field_uid, "Global field UID should not be None")
32+
self.assertEqual(response.status_code, 201)
33+
34+
def test_create_nested_global_fields(self):
35+
read_mock_global_fields_data = self.read_file("create_global_fields.json")
36+
read_mock_global_fields_data = json.loads(read_mock_global_fields_data)
37+
response = self.client.stack(api_key).global_fields(options={'api_version': 3.2}).create(read_mock_global_fields_data)
38+
global_field_uid1 = response.data.get('uid', 'global_field_uid')
39+
self.assertIsNotNone(global_field_uid1, "Global field UID should not be None")
40+
self.assertEqual(response.status_code, 201)
41+
2742
def test_fetch_global_fields(self):
2843
response = self.client.stack(api_key).global_fields(global_field_uid).fetch()
29-
if response.status_code == 200:
30-
self.assertEqual(response.status_code, 200)
31-
else:
32-
self.assertEqual(response.status_code, 422)
44+
self.assertEqual(response.status_code, 200)
45+
self.assertEqual(response.data.get('uid'), global_field_uid, "Fetched global field UID should match the provided UID")
46+
3347

3448
def test_find_all_global_fields(self):
3549
response = self.client.stack(api_key).global_fields().find()
@@ -38,19 +52,11 @@ def test_find_all_global_fields(self):
3852
else:
3953
self.assertEqual(response.status_code, 400)
4054

41-
def test_create_global_fields(self):
42-
read_mock_global_fileds_data = self.read_file("create_global_fields.json")
43-
read_mock_global_fileds_data = json.loads(read_mock_global_fileds_data)
44-
response = self.client.stack(api_key).global_fields().create(read_mock_global_fileds_data)
45-
if response.status_code == 200:
46-
self.assertEqual(response.status_code, 200)
47-
else:
48-
self.assertEqual(response.status_code, 422)
4955

5056
def test_update_global_fields(self):
51-
read_mock_global_fileds_data = self.read_file("create_global_fields.json")
52-
read_mock_global_fileds_data = json.loads(read_mock_global_fileds_data)
53-
response = self.client.stack(api_key).global_fields(global_field_uid).update(read_mock_global_fileds_data)
57+
read_mock_global_fields_data = self.read_file("create_global_fields.json")
58+
read_mock_global_fields_data = json.loads(read_mock_global_fields_data)
59+
response = self.client.stack(api_key).global_fields(global_field_uid).update(read_mock_global_fields_data)
5460
if response.status_code == 200:
5561
self.assertEqual(response.status_code, 200)
5662
else:

tests/unit/global_fields/test_global_fields_unittest.py

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,17 @@ def test_get_all_global_fields(self):
3939
self.assertEqual(response.request.body, None)
4040

4141
def test_create_global_fields(self):
42-
read_mock_global_fileds_data = self.read_file("create_global_fields.json")
43-
read_mock_global_fileds_data = json.loads(read_mock_global_fileds_data)
44-
response = self.client.stack(api_key).global_fields().create(read_mock_global_fileds_data)
42+
read_mock_global_fields_data = self.read_file("create_global_fields.json")
43+
read_mock_global_fields_data = json.loads(read_mock_global_fields_data)
44+
response = self.client.stack(api_key).global_fields().create(read_mock_global_fields_data)
4545
self.assertEqual(response.request.url, f"{self.client.endpoint}global_fields")
4646
self.assertEqual(response.request.method, "POST")
4747
self.assertEqual(response.request.headers["Content-Type"], "application/json")
4848

4949
def test_update_global_fields(self):
50-
read_mock_global_fileds_data = self.read_file("create_global_fields.json")
51-
read_mock_global_fileds_data = json.loads(read_mock_global_fileds_data)
52-
response = self.client.stack(api_key).global_fields(global_field_uid).update(read_mock_global_fileds_data)
50+
read_mock_global_fields_data = self.read_file("create_global_fields.json")
51+
read_mock_global_fields_data = json.loads(read_mock_global_fields_data)
52+
response = self.client.stack(api_key).global_fields(global_field_uid).update(read_mock_global_fields_data)
5353
self.assertEqual(response.request.url, f"{self.client.endpoint}global_fields/{global_field_uid}")
5454
self.assertEqual(response.request.method, "PUT")
5555
self.assertEqual(response.request.headers["Content-Type"], "application/json")
@@ -73,6 +73,44 @@ def test_export_global_fields(self):
7373
self.assertEqual(response.request.method, "GET")
7474
self.assertEqual(response.request.headers["Content-Type"], "application/json")
7575
self.assertEqual(response.request.body, None)
76+
77+
def test_create_nested_global_fields(self):
78+
read_mock_global_fields_data = self.read_file("create_global_fields.json")
79+
read_mock_global_fields_data = json.loads(read_mock_global_fields_data)
80+
response = self.client.stack(api_key).global_fields(options={"api_version": 3.2}).create(read_mock_global_fields_data)
81+
self.assertEqual(response.request.url, f"{self.client.endpoint}global_fields")
82+
self.assertEqual(response.request.method, "POST")
83+
self.assertEqual(response.request.headers["Content-Type"], "application/json")
84+
self.assertEqual(response.request.headers["api_version"], "3.2")
85+
86+
def test_update_nested_global_fields(self):
87+
read_mock_global_fields_data = self.read_file("create_global_fields.json")
88+
read_mock_global_fields_data = json.loads(read_mock_global_fields_data)
89+
response = self.client.stack(api_key).global_fields(global_field_uid, options={"api_version": 3.2}).update(read_mock_global_fields_data)
90+
self.assertEqual(response.request.url, f"{self.client.endpoint}global_fields/{global_field_uid}")
91+
self.assertEqual(response.request.method, "PUT")
92+
self.assertEqual(response.request.headers["api_version"], "3.2")
93+
94+
def test_delete_nested_global_fields(self):
95+
response= self.client.stack(api_key).global_fields(global_field_uid, options={"api_version": 3.2}).delete()
96+
self.assertEqual(response.request.url, f"{self.client.endpoint}global_fields/{global_field_uid}")
97+
self.assertEqual(response.request.method, "DELETE")
98+
self.assertEqual(response.request.headers["api_version"], "3.2")
99+
100+
def test_get_nested_global_field(self):
101+
response = self.client.stack(api_key).global_fields(global_field_uid, options={"api_version": 3.2}).fetch()
102+
self.assertEqual(response.request.url, f"{self.client.endpoint}global_fields/{global_field_uid}")
103+
self.assertEqual(response.request.method, "GET")
104+
self.assertEqual(response.request.headers["Content-Type"], "application/json")
105+
self.assertEqual(response.request.headers["api_version"], "3.2")
106+
self.assertEqual(response.request.body, None)
107+
108+
def test_get_all_nested_global_fields(self):
109+
response = self.client.stack(api_key).global_fields(options={"api_version": 3.2}).find()
110+
self.assertEqual(response.request.url, f"{self.client.endpoint}global_fields")
111+
self.assertEqual(response.request.method, "GET")
112+
self.assertEqual(response.request.headers["Content-Type"], "application/json")
113+
self.assertEqual(response.request.headers["api_version"], "3.2")
76114

77115

78116

0 commit comments

Comments
 (0)