Skip to content

Commit a35426f

Browse files
Organized package structure
1 parent 6c82cc1 commit a35426f

File tree

13 files changed

+598
-0
lines changed

13 files changed

+598
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,4 @@ dmypy.json
127127

128128
# Pyre type checker
129129
.pyre/
130+
tests/config/default.yml

.talismanrc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
fileignoreconfig:
2+
- filename: tests/config/default.yml.enc
3+
checksum: f05423216fcfe17716c01932e7a87775a029ec4f1fb1314bfdf0697527e67038
4+
- filename: tests/test_contentstack.py
5+
checksum: 4aae839b0c4e408c6224df5ccdd090ea9d9b28cc9f37e1eadd2d7737bd5ca1ae
6+
- filename: contentstack_management/users/user.py
7+
checksum: a3e98d980282254e26b9fc1073bf297ea6fda3e30e3634d5c7df893cfcc92aa2
8+
- filename: contentstack_management/stack/stack.py
9+
checksum: 704f1cffd452d226e7447213fcb6a3fed7b01f0661aa27d4f7657b8a36eb3d28
10+
- filename: contentstack_management/core/client.py
11+
checksum: 7a1210ec269e05af414e7753758d8b261c157349e24df4fef047810fef8741c9
12+
version: ""
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
"""The __init__.py file that contains modules that need to import"""
2+
3+
from contentstack_management import contentstack
4+
5+
__title__ = 'contentstack-cms'
6+
__author__ = 'contentstack'
7+
__status__ = 'debug'
8+
__version__ = '0.0.1'
9+
__host__ = 'api.contentstack.io'
10+
__protocol__ = 'https://'
11+
__api_version__ = 'v3'
12+
__endpoint__ = 'https://api.contentstack.io/v3/'
13+
__email__ = 'mobile@contentstack.com'
14+
__issues__ = 'customer_care@contentstack.com'
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import platform
2+
3+
import contentstack_management
4+
from .core.client import ApiClient
5+
6+
7+
default_host = 'api.contentstack.io'
8+
default_endpoint = 'https://api.contentstack.io'
9+
default_api_version = 'v3'
10+
default_protocol = 'https://'
11+
default_timeout = 30
12+
default_max_request = 5
13+
14+
15+
def __platform():
16+
os_platform = platform.system()
17+
if os_platform == 'Darwin':
18+
os_platform = 'macOS'
19+
elif not os_platform or os_platform == 'Java':
20+
os_platform = None
21+
elif os_platform and os_platform not in ['macOS', 'Windows']:
22+
os_platform = 'Linux'
23+
os_platform = {'name': os_platform, 'version': platform.release()}
24+
return os_platform
25+
26+
27+
def user_agents(headers):
28+
headers.update({'sdk': dict(
29+
name=contentstack_management.__package__,
30+
version=contentstack_management.__version__
31+
), 'os': str(__platform())})
32+
package = f"contentstack-management-python/{contentstack_management.__version__}"
33+
return {'User-Agent': str(headers), "X-User-Agent": package, 'Content-Type': 'application/json' }
34+
35+
36+
def client(endpoint=None,
37+
host: str = None, authtoken: str = None, headers=None, authorization: str = None,
38+
timeout: int = None, failure_retry: int = 0, exceptions: bool = True,
39+
errors: bool = True, max_requests: int = default_max_request, retry_on_error: bool = True):
40+
"""
41+
:param endpoint: Optional API endpoint.
42+
:param host: Optional hostname for the API endpoint.
43+
:param authtoken: Optional authentication token for API requests
44+
:param headers: Optional headers to be included with API requests
45+
:param authorization: Optional authorization value for API requests
46+
:param timeout: Optional timeout value for API requests
47+
:param failure_retry: Optional number of retries for API requests that fail
48+
:param exceptions: Optional boolean value indicating whether to handle exceptions during API requests
49+
:param errors: Optional boolean value indicating whether to handle errors during API requests.
50+
:param max_requests:Optional maximum number of requests to be made
51+
:param retry_on_error: Optional boolean value indicating whether to retry API requests on error.
52+
:return: A client object for performing API operations.
53+
54+
:example:
55+
>>> from contentstack_management import contentstack
56+
>>> client = contentstack.client()
57+
"""
58+
if headers is None:
59+
headers = {}
60+
headers = user_agents(headers)
61+
if host is None:
62+
host = contentstack_management.__host__
63+
64+
if endpoint is None:
65+
endpoint = contentstack_management.__endpoint__
66+
if host is not None:
67+
endpoint = f'{contentstack_management.__protocol__}{host}/{contentstack_management.__api_version__}'
68+
69+
if timeout is None:
70+
timeout = default_timeout
71+
72+
return ApiClient(host=host, endpoint=endpoint, authtoken=authtoken,
73+
headers=headers, authorization=authorization,
74+
timeout=timeout, failure_retry=failure_retry, exceptions=exceptions, errors=errors,
75+
max_requests=max_requests, retry_on_error=retry_on_error)
76+
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
"""This class takes a base URL as an argument when it's initialized,
2+
which is the endpoint for the RESTFUL API that we'll be interacting with.
3+
The create(), read(), update(), and delete() methods each correspond to
4+
the CRUD operations that can be performed on the API """
5+
6+
import requests
7+
import json
8+
import logging
9+
10+
from ..organizations.organizations import Organization
11+
from ..users.user import User
12+
from ..stack.stack import Stack
13+
from ..user_session.user_session import UserSession
14+
15+
class ApiClient:
16+
"""
17+
This class takes a base URL as an argument when it's initialized,
18+
which is the endpoint for the RESTFUL API that
19+
we'll be interacting with. The create(), read(), update(), and delete()
20+
methods each correspond to the CRUD
21+
operations that can be performed on the API """
22+
23+
def __init__(self, endpoint, host, headers, authtoken, authorization, failure_retry, exceptions: bool,
24+
errors: bool, timeout: int, max_requests: int, retry_on_error: bool):
25+
self.authorization = authorization
26+
self.authtoken = authtoken
27+
self.headers = headers
28+
self.host = host
29+
self.endpoint = endpoint
30+
self.failure_retry = failure_retry
31+
self.exceptions = exceptions
32+
self.errors = errors
33+
self.timeout = timeout
34+
self.max_requests = max_requests
35+
self.retry_on_error = retry_on_error
36+
37+
38+
39+
def get(self, url, headers=None, params=None):
40+
"""
41+
Perform an HTTP GET request with the specified URL and parameters.
42+
43+
:param url: The URL to send the request to.
44+
:param headers: Optional dictionary of headers to include in the request.
45+
:param params: Optional dictionary of URL parameters to include in the request.
46+
:return: The response from the server.
47+
"""
48+
return self._call_request('GET', url, headers=headers, params=params)
49+
50+
def put(self, url, headers=None, params=None, data=None, json=None):
51+
"""
52+
Perform an HTTP PUT request with the specified URL and parameters.
53+
54+
:param url: The URL to send the request to.
55+
:param headers: Optional dictionary of headers to include in the request.
56+
:param params: Optional dictionary of URL parameters to include in the request.
57+
:param data: Optional dictionary, list of tuples, or bytes to include in the body of the request.
58+
:param json: Optional JSON data to include in the body of the request.
59+
:return: The response from the server.
60+
"""
61+
return self._call_request('PUT', url, headers=headers, params=params, data=data, json=json)
62+
63+
def post(self, url, headers=None, params=None, data=None, json=None):
64+
"""
65+
Perform an HTTP POST request with the specified URL and parameters.
66+
67+
:param url: The URL to send the request to.
68+
:param headers: Optional dictionary of headers to include in the request.
69+
:param params: Optional dictionary of URL parameters to include in the request.
70+
:param data: Optional dictionary, list of tuples, or bytes to include in the body of the request.
71+
:param json: Optional JSON data to include in the body of the request.
72+
:return: The response from the server.
73+
"""
74+
return self._call_request('POST', url, headers=headers, params=params, data=data, json=json)
75+
76+
def delete(self, url, headers=None, params=None):
77+
"""
78+
Perform an HTTP DELETE request with the specified URL and parameters.
79+
80+
:param url: The URL to send the request to.
81+
:param headers: Optional dictionary of headers to include in the request.
82+
:param params: Optional dictionary of URL parameters to include in the request.
83+
:return: The response from the server.
84+
"""
85+
return self._call_request('DELETE', url, headers=headers, params=params)
86+
87+
88+
89+
def _call_request(self, method, url_path, headers=None, params=None, data=None, json=None):
90+
url = f"{self.endpoint}/{url_path}"
91+
retries = self.failure_retry + 1
92+
93+
while retries > 0:
94+
try:
95+
response = requests.request(method, url, data=data, headers=headers, params=params, json=json)
96+
97+
if response.status_code >= 400:
98+
if self.errors:
99+
return (response)
100+
elif retries > 1:
101+
retries -= 1
102+
else:
103+
return None
104+
else:
105+
return response
106+
107+
except Exception as e:
108+
if self.exceptions:
109+
raise e
110+
elif retries > 1:
111+
retries -= 1
112+
else:
113+
return None
114+
115+
116+
def login(self, email=None, password=None):
117+
if email is None or email == '':
118+
raise PermissionError(
119+
'You are not permitted to the stack without valid email id')
120+
121+
if password is None or password == '':
122+
raise PermissionError(
123+
'You are not permitted to the stack without valid password')
124+
125+
url = "user-session"
126+
data = {
127+
"user": {
128+
"email": email,
129+
"password": password
130+
131+
}
132+
}
133+
data = json.dumps(data)
134+
self.api_client = ApiClient(
135+
host=self.host, endpoint=self.endpoint, authtoken=self.authtoken,
136+
headers=self.headers, authorization=self.authorization,
137+
timeout=self.timeout, failure_retry=self.failure_retry, exceptions=self.exceptions, errors=self.errors,
138+
max_requests=self.max_requests, retry_on_error=self.retry_on_error
139+
)
140+
141+
response = UserSession(url = url,headers = self.headers, data = data, api_client=self.api_client, endpoint=self.endpoint).login()
142+
if response.status_code == 200:
143+
self.auth_token = self.get_authtoken(response.json())
144+
return response
145+
return response.status_code
146+
147+
def logout(self):
148+
url = "user-session"
149+
self.headers['authtoken'] = self.auth_token
150+
response = UserSession(url = url,headers = self.headers, api_client = self.api_client, endpoint=self.endpoint).logout()
151+
return response
152+
153+
def get_authtoken(self, response):
154+
return response['user']['authtoken']
155+
156+
def user(self):
157+
return User(self.endpoint, self.auth_token, self.headers,self.api_client)
158+
159+
160+
def organizations(self):
161+
return Organization(self.endpoint, self.auth_token, self.headers,self.api_client)
162+
163+
def stack(self, api_key = None):
164+
if api_key is None or api_key == '':
165+
raise PermissionError(
166+
'You are not permitted to the stack without valid api key')
167+
return Stack(self.endpoint, self.auth_token, self.headers,self.api_client, api_key)
168+
169+
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import platform
2+
import os
3+
import contentstack_management
4+
5+
class Organization:
6+
"""
7+
This class takes a base URL as an argument when it's initialized,
8+
which is the endpoint for the RESTFUL API that
9+
we'll be interacting with. The create(), read(), update(), and delete()
10+
methods each correspond to the CRUD
11+
operations that can be performed on the API """
12+
13+
def __init__(self, endpoint, authtoken, headers, api_client):
14+
self.api_client = api_client
15+
self.endpoint = endpoint
16+
self.authtoken = authtoken
17+
self.headers = headers
18+
19+
20+
def get(self):
21+
url = "organizations"
22+
self.headers['authtoken'] = self.authtoken
23+
return self.api_client.get(url, headers = self.headers)
24+
25+
26+
def get_organization(self, organization_uid):
27+
url = f"organizations/{organization_uid}"
28+
self.headers['authtoken'] = self.authtoken
29+
return self.api_client.get(url, headers = self.headers)
30+
31+
def get_organization_roles(self, organization_uid):
32+
url = f"organizations/{organization_uid}/roles"
33+
self.headers['authtoken'] = self.authtoken
34+
return self.api_client.get(url, headers = self.headers)
35+
36+
def organization_add_users(self, organization_uid):
37+
url = f"organizations/{organization_uid}/share"
38+
self.headers['authtoken'] = self.authtoken
39+
return self.api_client.get(url, headers = self.headers)
40+
41+
def transfer_organizations_ownership(self, organization_uid, data):
42+
url = f"organizations/{organization_uid}/transfer-ownership"
43+
self.headers['authtoken'] = self.authtoken
44+
return self.api_client.post(url, headers = self.headers, data=data)
45+
46+
def organization_stacks(self, organization_uid):
47+
url = f"organizations/{organization_uid}/stacks"
48+
self.headers['authtoken'] = self.authtoken
49+
return self.api_client.get(url, headers = self.headers)
50+
51+
def organization_logs(self, organization_uid):
52+
url = f"organizations/{organization_uid}/logs"
53+
self.headers['authtoken'] = self.authtoken
54+
return self.api_client.get(url, headers = self.headers)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"""This class takes a base URL as an argument when it's initialized,
2+
which is the endpoint for the RESTFUL API that we'll be interacting with.
3+
The create(), read(), update(), and delete() methods each correspond to
4+
the CRUD operations that can be performed on the API """
5+
6+
import json
7+
from json import JSONDecodeError
8+
import requests
9+
from requests.adapters import HTTPAdapter
10+
from requests.exceptions import HTTPError, Timeout
11+
import contentstack_management
12+
13+
14+
class Stack:
15+
"""
16+
This class takes a base URL as an argument when it's initialized,
17+
which is the endpoint for the RESTFUL API that
18+
we'll be interacting with. The create(), read(), update(), and delete()
19+
methods each correspond to the CRUD
20+
operations that can be performed on the API """
21+
22+
def __init__(self, endpoint, authtoken, headers, api_client, api_key):
23+
self.api_client = api_client
24+
self.endpoint = endpoint
25+
self.authtoken = authtoken
26+
self.headers = headers
27+
self.api_key = api_key
28+
29+
def fetch(self):
30+
url = "stacks"
31+
self.headers['authtoken'] = self.authtoken
32+
self.headers['api_key'] = self.api_key
33+
return self.api_client.get(url, headers = self.headers)
34+
35+

0 commit comments

Comments
 (0)