Skip to content

Commit 91a4390

Browse files
Added users and organisations api methods
User Session Logging in/out Users Get User Update User Activate User Request Password Reset Password Organizations Get All Organizations Get Single Organization Organization Roles Organization Users Transfer Organization Ownership Organization Stacks Organization Logs
1 parent 6c82cc1 commit 91a4390

File tree

11 files changed

+693
-0
lines changed

11 files changed

+693
-0
lines changed

.talismanrc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
fileignoreconfig:
2+
- filename: contentstack_management/users/user.py
3+
checksum: 9fd02cdc5e1cd22cf3fcd9b3f2159a3e7680d19052c58ab7425bfca4bd675a4f
4+
- filename: tests/test_organizations.py
5+
checksum: a9ee8e15a00474ab16920da1a9cb7f96f9a0e40f945406506ed1e46030758025
6+
- filename: tests/test_users.py
7+
checksum: 55b60bc69e941184bf16697cec82f5e14369460259729bbbd62437e019e6ab60
8+
- filename: contentstack_management/core/client.py
9+
checksum: 1bec47304a29a7c482f530e3ac283e8ddd8fa96f99153833feac5a6513d726df
10+
version: ""
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
"""The __init__.py file that contains modules that need to import"""
2+
3+
4+
from .core.login import Login
5+
from .core.error import Error
6+
7+
from contentstack_management import contentstack
8+
9+
__title__ = 'contentstack-cms'
10+
__author__ = 'contentstack'
11+
__status__ = 'debug'
12+
__version__ = '0.0.1'
13+
__host__ = 'api.contentstack.io'
14+
__protocol__ = 'https://'
15+
__api_version__ = 'v3'
16+
__endpoint__ = 'https://api.contentstack.io/v3/'
17+
__email__ = 'mobile@contentstack.com'
18+
__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': __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: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
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+
9+
10+
from ..organizations.organizations import Organization
11+
from ..users.user import User
12+
from ..user_session.user_session import UserSession
13+
14+
class ApiClient:
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, host, headers, authtoken, authorization, failure_retry, exceptions: bool,
23+
errors: bool, timeout: int, max_requests: int, retry_on_error: bool):
24+
self.authorization = authorization
25+
self.authtoken = authtoken
26+
self.headers = headers
27+
self.host = host
28+
self.endpoint = endpoint
29+
self.failure_retry = failure_retry
30+
self.exceptions = exceptions
31+
self.errors = errors
32+
self.timeout = timeout
33+
self.max_requests = max_requests
34+
self.retry_on_error = retry_on_error
35+
36+
37+
38+
def get(self, url, headers=None, params=None):
39+
"""
40+
Perform an HTTP GET request with the specified URL and parameters.
41+
42+
:param url: The URL to send the request to.
43+
:param headers: Optional dictionary of headers to include in the request.
44+
:param params: Optional dictionary of URL parameters to include in the request.
45+
:return: The response from the server.
46+
"""
47+
return self._call_request('GET', url, headers=headers, params=params)
48+
49+
def put(self, url, headers=None, params=None, data=None, json=None):
50+
"""
51+
Perform an HTTP PUT request with the specified URL and parameters.
52+
53+
:param url: The URL to send the request to.
54+
:param headers: Optional dictionary of headers to include in the request.
55+
:param params: Optional dictionary of URL parameters to include in the request.
56+
:param data: Optional dictionary, list of tuples, or bytes to include in the body of the request.
57+
:param json: Optional JSON data to include in the body of the request.
58+
:return: The response from the server.
59+
"""
60+
return self._call_request('PUT', url, headers=headers, params=params, data=data, json=json)
61+
62+
def post(self, url, headers=None, params=None, data=None, json=None):
63+
"""
64+
Perform an HTTP POST request with the specified URL and parameters.
65+
66+
:param url: The URL to send the request to.
67+
:param headers: Optional dictionary of headers to include in the request.
68+
:param params: Optional dictionary of URL parameters to include in the request.
69+
:param data: Optional dictionary, list of tuples, or bytes to include in the body of the request.
70+
:param json: Optional JSON data to include in the body of the request.
71+
:return: The response from the server.
72+
"""
73+
return self._call_request('POST', url, headers=headers, params=params, data=data, json=json)
74+
75+
def delete(self, url, headers=None, params=None):
76+
"""
77+
Perform an HTTP DELETE request with the specified URL and parameters.
78+
79+
:param url: The URL to send the request to.
80+
:param headers: Optional dictionary of headers to include in the request.
81+
:param params: Optional dictionary of URL parameters to include in the request.
82+
:return: The response from the server.
83+
"""
84+
return self._call_request('DELETE', url, headers=headers, params=params)
85+
86+
87+
88+
def _call_request(self, method, url_path, headers=None, params=None, data=None, json=None):
89+
url = f"{self.endpoint}/{url_path}"
90+
retries = self.failure_retry + 1
91+
92+
while retries > 0:
93+
try:
94+
response = requests.request(method, url, data=data, headers=headers, params=params, json=json)
95+
96+
if response.status_code >= 400:
97+
if self.errors:
98+
raise Exception(f"API returned an error: {response.text}")
99+
elif retries > 1:
100+
retries -= 1
101+
else:
102+
return None
103+
else:
104+
return response
105+
106+
except Exception as e:
107+
if self.exceptions:
108+
raise e
109+
elif retries > 1:
110+
retries -= 1
111+
else:
112+
return None
113+
114+
def login(self, email, password):
115+
url = "user-session"
116+
data = {
117+
"user": {
118+
"email": email,
119+
"password": password
120+
121+
}
122+
}
123+
data = json.dumps(data)
124+
self.api_client = ApiClient(
125+
host=self.host, endpoint=self.endpoint, authtoken=self.authtoken,
126+
headers=self.headers, authorization=self.authorization,
127+
timeout=self.timeout, failure_retry=self.failure_retry, exceptions=self.exceptions, errors=self.errors,
128+
max_requests=self.max_requests, retry_on_error=self.retry_on_error
129+
)
130+
131+
response = UserSession(url = url,headers = self.headers, data = data, api_client=self.api_client, endpoint=self.endpoint).login()
132+
self.auth_token = self.get_authtoken(response)
133+
return response
134+
135+
def logout(self):
136+
url = "user-session"
137+
self.headers['authtoken'] = self.auth_token
138+
response = UserSession(url = url,headers = self.headers, api_client = self.api_client, endpoint=self.endpoint).logout()
139+
return response
140+
141+
def get_authtoken(self, response):
142+
return response['user']['authtoken']
143+
144+
145+
def get_user(self):
146+
return User(self.endpoint, self.auth_token, self.headers,self.api_client).get_user()
147+
148+
def update_user(self, user_data):
149+
return User(self.endpoint, self.auth_token, self.headers,self.api_client).update_user(user_data)
150+
151+
def active_user(self, user_activation_token, user_data):
152+
return User(self.endpoint, self.auth_token, self.headers,self.api_client).update_user(user_activation_token, user_data)
153+
154+
def request_password(self, user_data):
155+
return User(self.endpoint, self.auth_token, self.headers,self.api_client).request_password(user_data)
156+
157+
def reset_password(self, user_data):
158+
return User(self.endpoint, self.auth_token, self.headers,self.api_client).reset_password(user_data)
159+
160+
def get_organizations(self):
161+
return Organization(self.endpoint, self.auth_token, self.headers,self.api_client).get_organizations()
162+
163+
def get_organization(self, organization_uid):
164+
return Organization(self.endpoint, self.auth_token, self.headers,self.api_client).get_organizations(organization_uid)
165+
166+
def get_organization_roles(self, organization_uid):
167+
return Organization(self.endpoint, self.auth_token, self.headers,self.api_client).get_organization_roles(organization_uid)
168+
169+
def organization_add_users(self, organization_uid):
170+
return Organization(self.endpoint, self.auth_token, self.headers,self.api_client).organization_add_users(organization_uid)
171+
172+
def transfer_organizations_onership(self, organization_uid):
173+
return Organization(self.endpoint, self.auth_token, self.headers,self.api_client).transfer_organizations_onership(organization_uid)
174+
175+
def organization_stacks(self, organization_uid):
176+
return Organization(self.endpoint, self.auth_token, self.headers,self.api_client).organization_stacks(organization_uid)
177+
178+
def organization_logs(self, organization_uid):
179+
return Organization(self.endpoint, self.auth_token, self.headers,self.api_client).organization_logs(organization_uid)
180+
181+
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
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+
9+
10+
class HttpClient:
11+
"""
12+
This class takes a base URL as an argument when it's initialized,
13+
which is the endpoint for the RESTFUL API that
14+
we'll be interacting with. The create(), read(), update(), and delete()
15+
methods each correspond to the CRUD
16+
operations that can be performed on the API """
17+
18+
def __init__(self, endpoint):
19+
#init method
20+
self.url="user"
21+
self.endpoint = endpoint
22+
self.failure_retry = 0
23+
self.exceptions = True
24+
self.errors = True
25+
26+
27+
28+
def get(self, url, headers=None, params=None):
29+
"""
30+
Perform an HTTP GET request with the specified URL and parameters.
31+
32+
:param url: The URL to send the request to.
33+
:param headers: Optional dictionary of headers to include in the request.
34+
:param params: Optional dictionary of URL parameters to include in the request.
35+
:return: The response from the server.
36+
"""
37+
return self._call_request('GET', url, headers=headers, params=params)
38+
39+
def put(self, url, headers=None, params=None, data=None, json=None):
40+
"""
41+
Perform an HTTP PUT 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+
:param data: Optional dictionary, list of tuples, or bytes to include in the body of the request.
47+
:param json: Optional JSON data to include in the body of the request.
48+
:return: The response from the server.
49+
"""
50+
return self._call_request('PUT', url, headers=headers, params=params, data=data, json=json)
51+
52+
def post(self, url, headers=None, params=None, data=None, json=None):
53+
"""
54+
Perform an HTTP POST request with the specified URL and parameters.
55+
56+
:param url: The URL to send the request to.
57+
:param headers: Optional dictionary of headers to include in the request.
58+
:param params: Optional dictionary of URL parameters to include in the request.
59+
:param data: Optional dictionary, list of tuples, or bytes to include in the body of the request.
60+
:param json: Optional JSON data to include in the body of the request.
61+
:return: The response from the server.
62+
"""
63+
return self._call_request('POST', url, headers=headers, params=params, data=data, json=json)
64+
65+
def delete(self, url, headers=None, params=None):
66+
"""
67+
Perform an HTTP DELETE request with the specified URL and parameters.
68+
69+
:param url: The URL to send the request to.
70+
:param headers: Optional dictionary of headers to include in the request.
71+
:param params: Optional dictionary of URL parameters to include in the request.
72+
:return: The response from the server.
73+
"""
74+
return self._call_request('DELETE', url, headers=headers, params=params)
75+
76+
77+
78+
def _call_request(self, method, url_path, headers=None, params=None, data=None, json=None):
79+
url = f"{self.endpoint}/{url_path}"
80+
retries = self.failure_retry + 1
81+
82+
while retries > 0:
83+
try:
84+
response = requests.request(method, url, data=data, headers=headers, params=params, json=json)
85+
86+
if response.status_code >= 400:
87+
if self.errors:
88+
raise Exception(f"API returned an error: {response.text}")
89+
elif retries > 1:
90+
retries -= 1
91+
else:
92+
return None
93+
else:
94+
return response.json()
95+
96+
except Exception as e:
97+
if self.exceptions:
98+
raise e
99+
elif retries > 1:
100+
retries -= 1
101+
else:
102+
return None
103+
104+

0 commit comments

Comments
 (0)