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
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: ""
- filename: tests/api/global_fields/test_global_fields_api.py
checksum: 1cd57383fcad33cfaddc03aec9a7ee3e85b27de35e4545462fca33e74768e812
- filename: tests/unit/global_fields/test_global_fields_unittest.py
checksum: 9bb05624cf1dadb770b3cf17fbfe915cf3133d622110da30a7dfebdeab0a315c
- filename: tests/api/global_fields/test_global_fields_api.py
checksum: ef69455a51168ea34d62a68caea0984504d3feeafb78010947fa99d7c54d9e9c
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
40 changes: 23 additions & 17 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_fields_data = self.read_file("create_global_fields.json")
read_mock_global_fields_data = json.loads(read_mock_global_fields_data)
response = self.client.stack(api_key).global_fields().create(read_mock_global_fields_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_fields_data = self.read_file("create_global_fields.json")
read_mock_global_fields_data = json.loads(read_mock_global_fields_data)
response = self.client.stack(api_key).global_fields(options={'api_version': 3.2}).create(read_mock_global_fields_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,19 +52,11 @@ 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")
read_mock_global_fileds_data = json.loads(read_mock_global_fileds_data)
response = self.client.stack(api_key).global_fields(global_field_uid).update(read_mock_global_fileds_data)
read_mock_global_fields_data = self.read_file("create_global_fields.json")
read_mock_global_fields_data = json.loads(read_mock_global_fields_data)
response = self.client.stack(api_key).global_fields(global_field_uid).update(read_mock_global_fields_data)
if response.status_code == 200:
self.assertEqual(response.status_code, 200)
else:
Expand Down
50 changes: 44 additions & 6 deletions tests/unit/global_fields/test_global_fields_unittest.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,17 @@ def test_get_all_global_fields(self):
self.assertEqual(response.request.body, None)

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)
read_mock_global_fields_data = self.read_file("create_global_fields.json")
read_mock_global_fields_data = json.loads(read_mock_global_fields_data)
response = self.client.stack(api_key).global_fields().create(read_mock_global_fields_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")

def test_update_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).update(read_mock_global_fileds_data)
read_mock_global_fields_data = self.read_file("create_global_fields.json")
read_mock_global_fields_data = json.loads(read_mock_global_fields_data)
response = self.client.stack(api_key).global_fields(global_field_uid).update(read_mock_global_fields_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["Content-Type"], "application/json")
Expand All @@ -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_fields_data = self.read_file("create_global_fields.json")
read_mock_global_fields_data = json.loads(read_mock_global_fields_data)
response = self.client.stack(api_key).global_fields(options={"api_version": 3.2}).create(read_mock_global_fields_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_fields_data = self.read_file("create_global_fields.json")
read_mock_global_fields_data = json.loads(read_mock_global_fields_data)
response = self.client.stack(api_key).global_fields(global_field_uid, options={"api_version": 3.2}).update(read_mock_global_fields_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