Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
8 changes: 7 additions & 1 deletion .talismanrc
Original file line number Diff line number Diff line change
Expand Up @@ -354,4 +354,10 @@ fileignoreconfig:
checksum: c7323b95249759bc67c33d3a89d3d2e8b3ed3d146b944682d451ebebe22567c0
- filename: .github/workflows/secrets-scan.yml
checksum: d79ec3f3288964f7d117b9ad319a54c0ebc152e35f69be8fde95522034fdfb2a
version: ""
version: ""
fileignoreconfig:
- filename: tests/api/global_fields/test_global_fields_api.py
checksum: 1cd57383fcad33cfaddc03aec9a7ee3e85b27de35e4545462fca33e74768e812
- filename: tests/unit/global_fields/test_global_fields_unittest.py
checksum: 9bb05624cf1dadb770b3cf17fbfe915cf3133d622110da30a7dfebdeab0a315c
version: "1.0"
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

## Content Management SDK For Python
---
## v1.5.0

#### Date: 09 June 2025

- Added Nested Global fields support.
---
## v1.4.0

#### Date: 26 May 2025
Expand Down
2 changes: 1 addition & 1 deletion contentstack_management/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
__author__ = 'dev-ex'
__status__ = 'debug'
__region__ = 'na'
__version__ = '1.4.0'
__version__ = '1.5.0'
__host__ = 'api.contentstack.io'
__protocol__ = 'https://'
__api_version__ = 'v3'
Expand Down
54 changes: 46 additions & 8 deletions contentstack_management/global_fields/global_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@ class GlobalFields(Parameter):
methods each correspond to the CRUD
operations that can be performed on the API """

def __init__(self, client, global_field_uid=None):
def __init__(self, client, global_field_uid=None, options=None):
self.client = client
self.global_field_uid = global_field_uid
self.options = options
super().__init__(self.client)
if self.options and'api_version' in self.options:
Parameter.add_header(self, 'api_version', str(self.options['api_version']))

def find(self):
"""
Expand All @@ -34,7 +37,12 @@ def find(self):
>>> result = client.stack("api_key").global_fields('global_field_uid').find().json()
-------------------------------
"""
return self.client.get(_path, headers=self.client.headers, params = self.params)
response = self.client.get(_path, headers=self.client.headers, params = self.params)
# Remove the api_version header after request
if self.options and 'api_version' in self.options:
self.client.headers.pop('api_version', None)

return response

def fetch(self):
"""
Expand All @@ -50,7 +58,12 @@ def fetch(self):
-------------------------------
"""
url = f"{_path}/{self.global_field_uid}"
return self.client.get(url, headers=self.client.headers, params = self.params)
response = self.client.get(url, headers=self.client.headers, params = self.params)
# Remove the api_version header after request
if self.options and 'api_version' in self.options:
self.client.headers.pop('api_version', None)

return response

def create(self, data):
"""
Expand All @@ -74,7 +87,12 @@ def create(self, data):
-------------------------------
"""
data = json.dumps(data)
return self.client.post(_path, headers=self.client.headers, data=data, params = self.params)
response = self.client.post(_path, headers=self.client.headers, data=data, params = self.params)
# Remove the api_version header after request
if self.options and 'api_version' in self.options:
self.client.headers.pop('api_version', None)

return response

def update(self, data):
"""
Expand All @@ -99,7 +117,12 @@ def update(self, data):
"""
url = f"{_path}/{self.global_field_uid}"
data = json.dumps(data)
return self.client.put(url, headers=self.client.headers, params=self.params, data=data)
response = self.client.put(url, headers=self.client.headers, params=self.params, data=data)
# Remove the api_version header after request
if self.options and 'api_version' in self.options:
self.client.headers.pop('api_version', None)

return response

def delete(self):
"""
Expand All @@ -114,7 +137,12 @@ def delete(self):
-------------------------------
"""
url = f"{_path}/{self.global_field_uid}"
return self.client.delete(url, headers=self.client.headers, params=self.params)
response = self.client.delete(url, headers=self.client.headers, params=self.params)
# Remove the api_version header after request
if self.options and 'api_version' in self.options:
self.client.headers.pop('api_version', None)

return response

def imports(self, file_path):
"""
Expand All @@ -131,7 +159,12 @@ def imports(self, file_path):
"""
self.client.headers['Content-Type'] = "multipart/form-data"
files = {'global_field': open(f"{file_path}", 'rb')}
return self.client.post('global_fields/import', headers=self.client.headers, params=self.params, files=files)
response = self.client.post('global_fields/import', headers=self.client.headers, params=self.params, files=files)
# Remove the api_version header after request
if self.options and 'api_version' in self.options:
self.client.headers.pop('api_version', None)

return response

def export(self):
"""
Expand All @@ -148,4 +181,9 @@ def export(self):
if self.global_field_uid is None or '':
raise Exception('global_field_uid is required')
url = f"{_path}/{self.global_field_uid}/export"
return self.client.get(url, headers=self.client.headers, params=self.params)
response = self.client.get(url, headers=self.client.headers, params=self.params)
# Remove the api_version header after request
if self.options and 'api_version' in self.options:
self.client.headers.pop('api_version', None)

return response
6 changes: 2 additions & 4 deletions contentstack_management/stack/stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,10 +293,8 @@ def unshare(self, data):
data = json.dumps(data)
return self.client.post('stacks/unshare', headers=self.client.headers, params=self.params, data=data)

def global_fields(self, global_field_uid=None):
if 'api_key' not in self.client.headers:
raise Exception('api_key is required')
return GlobalFields(self.client, global_field_uid)
def global_fields(self, global_field_uid=None, options=None):
return GlobalFields(self.client, global_field_uid, options)

def branch(self, branch_uid=None):
return Branch(self.client, branch_uid)
Expand Down
34 changes: 20 additions & 14 deletions tests/api/global_fields/test_global_fields_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
password = credentials["password"]
host = credentials["host"]
api_key = credentials["api_key"]
global_field_uid = credentials["global_field_uid"]
global_field_uid = 'global_field_uid' # Replace with actual UID or fetch from response if available

class GlobalFieldsApiTests(unittest.TestCase):

Expand All @@ -23,13 +23,27 @@ def read_file(self, file_name):
infile.close()
return data


def test_create_global_fields(self):
read_mock_global_fileds_data = self.read_file("create_global_fields.json")
read_mock_global_fileds_data = json.loads(read_mock_global_fileds_data)
response = self.client.stack(api_key).global_fields().create(read_mock_global_fileds_data)
global_field_uid = response.data.get('uid', 'global_field_uid')
self.assertIsNotNone(global_field_uid, "Global field UID should not be None")
self.assertEqual(response.status_code, 201)

def test_create_nested_global_fields(self):
read_mock_global_fileds_data = self.read_file("create_global_fields.json")
read_mock_global_fileds_data = json.loads(read_mock_global_fileds_data)
response = self.client.stack(api_key).global_fields(options={'api_version': 3.2}).create(read_mock_global_fileds_data)
global_field_uid1 = response.data.get('uid', 'global_field_uid')
self.assertIsNotNone(global_field_uid1, "Global field UID should not be None")
self.assertEqual(response.status_code, 201)

def test_fetch_global_fields(self):
response = self.client.stack(api_key).global_fields(global_field_uid).fetch()
if response.status_code == 200:
self.assertEqual(response.status_code, 200)
else:
self.assertEqual(response.status_code, 422)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data.get('uid'), global_field_uid, "Fetched global field UID should match the provided UID")


def test_find_all_global_fields(self):
response = self.client.stack(api_key).global_fields().find()
Expand All @@ -38,14 +52,6 @@ def test_find_all_global_fields(self):
else:
self.assertEqual(response.status_code, 400)

def test_create_global_fields(self):
read_mock_global_fileds_data = self.read_file("create_global_fields.json")
read_mock_global_fileds_data = json.loads(read_mock_global_fileds_data)
response = self.client.stack(api_key).global_fields().create(read_mock_global_fileds_data)
if response.status_code == 200:
self.assertEqual(response.status_code, 200)
else:
self.assertEqual(response.status_code, 422)

def test_update_global_fields(self):
read_mock_global_fileds_data = self.read_file("create_global_fields.json")
Expand Down
38 changes: 38 additions & 0 deletions tests/unit/global_fields/test_global_fields_unittest.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,44 @@ def test_export_global_fields(self):
self.assertEqual(response.request.method, "GET")
self.assertEqual(response.request.headers["Content-Type"], "application/json")
self.assertEqual(response.request.body, None)

def test_create_nested_global_fields(self):
read_mock_global_fileds_data = self.read_file("create_global_fields.json")
read_mock_global_fileds_data = json.loads(read_mock_global_fileds_data)
response = self.client.stack(api_key).global_fields(options={"api_version": 3.2}).create(read_mock_global_fileds_data)
self.assertEqual(response.request.url, f"{self.client.endpoint}global_fields")
self.assertEqual(response.request.method, "POST")
self.assertEqual(response.request.headers["Content-Type"], "application/json")
self.assertEqual(response.request.headers["api_version"], "3.2")

def test_update_nested_global_fields(self):
read_mock_global_fileds_data = self.read_file("create_global_fields.json")
read_mock_global_fileds_data = json.loads(read_mock_global_fileds_data)
response = self.client.stack(api_key).global_fields(global_field_uid, options={"api_version": 3.2}).update(read_mock_global_fileds_data)
self.assertEqual(response.request.url, f"{self.client.endpoint}global_fields/{global_field_uid}")
self.assertEqual(response.request.method, "PUT")
self.assertEqual(response.request.headers["api_version"], "3.2")

def test_delete_nested_global_fields(self):
response= self.client.stack(api_key).global_fields(global_field_uid, options={"api_version": 3.2}).delete()
self.assertEqual(response.request.url, f"{self.client.endpoint}global_fields/{global_field_uid}")
self.assertEqual(response.request.method, "DELETE")
self.assertEqual(response.request.headers["api_version"], "3.2")

def test_get_nested_global_field(self):
response = self.client.stack(api_key).global_fields(global_field_uid, options={"api_version": 3.2}).fetch()
self.assertEqual(response.request.url, f"{self.client.endpoint}global_fields/{global_field_uid}")
self.assertEqual(response.request.method, "GET")
self.assertEqual(response.request.headers["Content-Type"], "application/json")
self.assertEqual(response.request.headers["api_version"], "3.2")
self.assertEqual(response.request.body, None)

def test_get_all_nested_global_fields(self):
response = self.client.stack(api_key).global_fields(options={"api_version": 3.2}).find()
self.assertEqual(response.request.url, f"{self.client.endpoint}global_fields")
self.assertEqual(response.request.method, "GET")
self.assertEqual(response.request.headers["Content-Type"], "application/json")
self.assertEqual(response.request.headers["api_version"], "3.2")



Expand Down