Skip to content

Commit 46ea231

Browse files
mshaileshr@gmail.commshaileshr@gmail.com
authored andcommitted
entry.py, entryqueryable.py, basequery.py and related testcases updated.
1 parent c862b9c commit 46ea231

File tree

5 files changed

+255
-36
lines changed

5 files changed

+255
-36
lines changed

contentstack/assetquery.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -97,22 +97,6 @@ def relative_url(self):
9797
self.__query_params["relative_urls"] = "true"
9898
return self
9999

100-
def include_count(self):
101-
"""
102-
include count provides asset count
103-
:return: AssetQuery: so we can chain the call
104-
105-
-----------------------------
106-
[Example]:
107-
108-
>>> import contentstack
109-
>>> stack = contentstack.Stack('api_key', 'delivery_token', 'environment')
110-
>>> result = stack.asset_query().include_count().find()
111-
------------------------------
112-
"""
113-
self.__query_params["include_count"] = "true"
114-
return self
115-
116100
def find(self):
117101
"""
118102
This call fetches the list of all the assets of a particular stack.

contentstack/basequery.py

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class BaseQuery:
4343

4444
def __init__(self):
4545
self.parameters = {}
46-
self.__query_params = {}
46+
self.query_params = {}
4747

4848
def where(self, field_uid: str, query_operation: QueryOperation, fields=None):
4949
"""
@@ -59,14 +59,31 @@ def where(self, field_uid: str, query_operation: QueryOperation, fields=None):
5959
self.parameters[field_uid] = result
6060
return self
6161

62+
def include_count(self):
63+
"""Retrieve count and data of objects in result
64+
Returns:
65+
[Query] -- Query object, so you can chain this call.
66+
==============================
67+
[Example:]
68+
>>> import contentstack
69+
>>> stack = contentstack.Stack('api_key', 'access_token', 'environment')
70+
>>> content_type = stack.content_type('content_type_uid')
71+
>>> query = content_type.query()
72+
>>> query = query.include_count()
73+
>>> result = query.find()
74+
==============================
75+
"""
76+
self.query_params["include_count"] = 'true'
77+
return self
78+
6279
def skip(self, skip_count: int):
6380
"""
6481
The number of objects to skip before returning any.
6582
skip_count No of objects to skip from returned objects
6683
:param skip_count:
6784
:return: self
6885
"""
69-
self.__query_params["skip"] = str(skip_count)
86+
self.query_params["skip"] = str(skip_count)
7087
return self
7188

7289
def limit(self, limit_count: int):
@@ -75,7 +92,7 @@ def limit(self, limit_count: int):
7592
:param limit_count:
7693
:return: self
7794
"""
78-
self.__query_params["skip"] = str(limit_count)
95+
self.query_params["skip"] = str(limit_count)
7996
return self
8097

8198
def order_by_ascending(self, key: str):
@@ -86,7 +103,7 @@ def order_by_ascending(self, key: str):
86103
:param key: key on which ascending order to be implemented
87104
:return: self
88105
"""
89-
self.__query_params["asc"] = str(key)
106+
self.query_params["asc"] = str(key)
90107
return self
91108

92109
def order_by_descending(self, key: str):
@@ -96,7 +113,7 @@ def order_by_descending(self, key: str):
96113
:param key: key on which descending order to be implemented
97114
:return: self - Class instance, So that method chaining can be performed
98115
"""
99-
self.__query_params["desc"] = str(key)
116+
self.query_params["desc"] = str(key)
100117
return self
101118

102119
def param(self, key: str, value):
@@ -127,37 +144,54 @@ def param(self, key: str, value):
127144
"""
128145
if None in (key, value):
129146
raise KeyError('Invalid key or value')
130-
self.__query_params[key] = str(value)
147+
self.query_params[key] = str(value)
131148
return self
132149

133150
def add_params(self, param: dict):
134151
"""
135152
Adds Parameters to the to the request
136-
137153
Arguments:
138-
param {dict} -- paramters
139-
154+
param {dict} -- parameters
140155
Returns:
141156
[self] -- Class instance, So that method chaining can be performed
142157
"""
143-
self.__query_params.update(param)
158+
self.query_params.update(param)
144159
return self
145160

146161
def query(self, key: str, value):
147162
"""
148163
Adds key value pairs to the to the query parameters
149-
150164
Arguments:
151165
key {[str]} -- key of the query param
152166
value {[type]} -- value of query param
153-
154167
Raises:
155168
KeyError: when key or value found None
156-
157169
Returns:
158-
[self] -- Class instance, So that method chaining can be performed]
170+
self-- Class instance, So that method chaining can be performed
159171
"""
160172
if None in (key, value):
161173
raise KeyError('Invalid key or value')
162174
self.parameters[key] = str(value)
163175
return self
176+
177+
def remove_param(self, key: str):
178+
"""
179+
Remove provided query key from custom query if exist.
180+
:param key {str} -- The key to be constrained
181+
:return: self -- So that method chaining can be performed
182+
183+
----------------------------------
184+
[Example]:
185+
>>> import contentstack
186+
>>> stack = contentstack.Stack('api_key', 'delivery_token', 'environment')
187+
>>> content_type = stack.content_type('content_type_uid')
188+
>>> query = content_type.query()
189+
>>> query = query.remove_query("query_key")
190+
>>> result = query.find()
191+
----------------------------------
192+
"""
193+
if key is None:
194+
raise ValueError('Kindly provide valid key')
195+
if key in self.query_params:
196+
self.query_params.pop(key, None)
197+
return self

contentstack/contenttype.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,24 @@ def __init__(self, http_instance, content_type_uid):
2727
self.__content_type_uid = content_type_uid
2828
self.local_param = {}
2929

30-
def entry(self, uid):
30+
def entry(self, entry_uid: str):
3131
r"""
3232
An entry is the actual piece of content created using one of the defined content types.
33-
:param uid: {str} -- uid of the entry
33+
:param entry_uid: {str} -- unique ID of the entry that you wish to fetch
3434
:return: Entry -- Returns the Entry class object so we can chain the entry functions
35+
3536
--------------------------------
36-
[Example:]
3737
38+
[Example:]
3839
>>> import contentstack
3940
>>> stack = contentstack.Stack('api_key', 'delivery_token', 'environment')
4041
>>> content_type = stack.content_type('content_type_uid')
4142
>>> entry = content_type.entry(uid='entry_uid')
4243
--------------------------------
4344
"""
44-
entry = Entry(self.http_instance, self.__content_type_uid, entry_uid=uid)
45+
if None in (self.__content_type_uid, entry_uid):
46+
raise KeyError('Please provide valid content_type_uid and entry uid')
47+
entry = Entry(self.http_instance, self.__content_type_uid, entry_uid=entry_uid)
4548
return entry
4649

4750
def query(self):
@@ -57,8 +60,9 @@ def query(self):
5760
>>> query = content_type.query()
5861
------------------------------
5962
"""
60-
query = Query(self.__content_type_uid)
61-
return query
63+
if self.__content_type_uid is None:
64+
raise PermissionError('Kindly provide content_type_uid')
65+
return Query(self.http_instance, self.__content_type_uid)
6266

6367
def fetch(self):
6468
"""

contentstack/entryqueryable.py

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
import enum
2+
3+
4+
class Include(enum.Enum):
5+
"""
6+
Include is enum that Provides Options to perform operation to query the result.
7+
8+
Available Options for QueryOperation are below.
9+
DEFAULT, ONLY, EXCEPT
10+
11+
Arguments:
12+
enum {Include} -- Type of IncludeReference
13+
"""
14+
EXCEPT = 'except'
15+
ONLY = 'only'
16+
DEFAULT = ''
17+
18+
19+
class EntryQueryable:
20+
"""
21+
This class is base class for the Entry and Query class that shares common functions
22+
"""
23+
def __init__(self):
24+
self.entry_queryable_param = {}
25+
26+
def locale(self, locale: str):
27+
"""
28+
Language code of which the entries needs to be included.
29+
Only the entries published in this locale will be displayed
30+
31+
Arguments:
32+
locale {str} -- locale_code of the language of which the entries needs to be included.
33+
Only the entries published in this locale will be displayed
34+
35+
:return: self: so you can chain this call.
36+
37+
Example (locale for Entry):
38+
>>> import contentstack
39+
>>> stack = contentstack.Stack('api_key', 'delivery_token', 'environment')
40+
>>> content_type = stack.content_type('content_type_uid')
41+
>>> entry = content_type.entry(uid='entry_uid')
42+
>>> entry.locale('en-us')
43+
>>> result = entry.fetch()
44+
45+
Example (locale for Query):
46+
>>> import contentstack
47+
>>> stack = contentstack.Stack('api_key', 'delivery_token', 'environment')
48+
>>> content_type = stack.content_type('content_type_uid')
49+
>>> query = content_type.query()
50+
>>> query.locale('en-us')
51+
>>> result = query.find()
52+
"""
53+
self.entry_queryable_param['locale'] = locale
54+
return self
55+
56+
def only(self, field_uid):
57+
"""
58+
Specifies an array of only keys in BASE object that would be included in the response.
59+
It refers to the top-level fields of the schema
60+
:param field_uid: Array of the only reference keys to be included in response
61+
Returns:
62+
self -- so you can chain this call.
63+
"""
64+
if field_uid is not None:
65+
self.entry_queryable_param['only[BASE][]'] = field_uid
66+
return self
67+
68+
def excepts(self, field_uid):
69+
"""
70+
Specifies list of field_uid that would be excluded from the response.
71+
It refers to the top-level fields of the schema
72+
:param field_uid: to be excluded from the response.
73+
:return: self -- so you can chain this call.
74+
"""
75+
if field_uid is not None:
76+
self.entry_queryable_param['except[BASE][]'] = field_uid
77+
return self
78+
79+
def include_reference(self, include_reference_type: Include, reference_field_uid: str, field_uid=None):
80+
"""
81+
**Include Reference:**
82+
When you fetch an entry of a content type that has a reference field,
83+
by default, the content of the referred entry is not fetched.
84+
It only fetches the UID of the referred entry, along with the content of
85+
the specified entry.
86+
87+
Arguments:
88+
reference_field_uid {str} -- Key who has reference to some other class object.
89+
Array of the only reference keys to be included in response
90+
include_type {Include} -- Provides three options, none, only and except
91+
i.e accepts list of field_uid
92+
field_uid {list} -- list of field_uid on which include operation to perform
93+
94+
Returns:
95+
self -- So you can chain this call.
96+
"""
97+
container = {}
98+
if reference_field_uid is None:
99+
raise KeyError("reference_field_uid can't be None")
100+
if include_reference_type.name == 'DEFAULT':
101+
self.entry_queryable_param["include[]"] = reference_field_uid
102+
else:
103+
container[reference_field_uid] = field_uid
104+
self.entry_queryable_param["include[]"] = {include_reference_type.value: container}
105+
return self
106+
107+
def include_content_type(self):
108+
"""
109+
This method also includes the ContentType in the entry
110+
:return: self: so you can chain this call.
111+
112+
-------------------------------
113+
114+
[Example: for Entry]
115+
116+
>>> import contentstack
117+
>>> stack = contentstack.Stack('api_key', 'delivery_token', 'environment')
118+
>>> content_type = stack.content_type('content_type_uid')
119+
>>> entry = content_type.entry('uid')
120+
>>> entry.include_content_type()
121+
>>> result = entry.fetch()
122+
123+
-------------------------------
124+
125+
[Example: for Query:]
126+
127+
>>> import contentstack
128+
>>> stack = contentstack.Stack('api_key', 'delivery_token', 'environment')
129+
>>> content_type = stack.content_type('content_type_uid')
130+
>>> query = content_type.query()
131+
>>> query.include_content_type()
132+
>>> result = query.find()
133+
-------------------------------
134+
"""
135+
self.entry_queryable_param['include_content_type'] = 'true'
136+
self.entry_queryable_param['include_global_field_schema'] = 'true'
137+
return self
138+
139+
def include_reference_content_type_uid(self):
140+
"""
141+
This method also includes the content type UIDs
142+
of the referenced entries returned in the response
143+
Returns:
144+
:return: self: so you can chain this call.
145+
146+
[Example for Query]
147+
>>> import contentstack
148+
>>> stack = contentstack.Stack('api_key', 'delivery_token', 'environment')
149+
>>> content_type = stack.content_type('content_type_uid')
150+
>>> query = content_type.query()
151+
>>> query = query.include_reference_content_type_uid()
152+
>>> result = query.find()
153+
154+
[Example for Entry]
155+
>>> import contentstack
156+
>>> stack = contentstack.Stack('api_key', 'delivery_token', 'environment')
157+
>>> entry = stack.content_type('content_type_uid').entry('entry_uid')
158+
>>> entry = entry.include_reference_content_type_uid()
159+
>>> result = entry.fetch()
160+
"""
161+
self.entry_queryable_param['include_reference_content_type_uid'] = 'true'
162+
return self
163+
164+
def add_param(self, key: str, value: str):
165+
"""
166+
This method adds key and value to an Entry.
167+
:param key: The key as string which needs to be added to an Entry
168+
:param value: The value as string which needs to be added to an Entry
169+
:return: self: object, so you can chain this call.
170+
171+
Example: Call from Query =>
172+
>>> import contentstack
173+
>>> stack = contentstack.Stack('api_key', 'delivery_token', 'environment')
174+
>>> query = stack.content_type('content_type_uid').query()
175+
>>> query = query.include_reference_content_type_uid()
176+
>>> result = query.find()
177+
178+
Example: Call from Entry =>
179+
>>> import contentstack
180+
>>> stack = contentstack.Stack('api_key', 'delivery_token', 'environment')
181+
>>> entry = stack.content_type('content_type_uid').entry('entry_uid')
182+
>>> entry = entry.include_reference_content_type_uid()
183+
>>> result = entry.fetch()
184+
185+
"""
186+
if None not in (key, value):
187+
self.entry_queryable_param[key] = value

0 commit comments

Comments
 (0)