@@ -608,6 +608,32 @@ def __getitem__(self, key):
608608 else :
609609 raise KeyError (key )
610610
611+ def __contains__ (self , key ):
612+ """
613+ Overrides dictionary __contains__ behavior to check if a document
614+ by key exists in the current cached or remote database.
615+
616+ For example:
617+
618+ .. code-block:: python
619+
620+ if key in database:
621+ doc = database[key]
622+ # Do something with doc
623+
624+ :param str key: Document id used to check if it exists in the database.
625+
626+ :returns: True if the document exists in the local or remote
627+ database, otherwise False.
628+ """
629+ if key in list (self .keys ()):
630+ return True
631+ if key .startswith ('_design/' ):
632+ doc = DesignDocument (self , key )
633+ else :
634+ doc = Document (self , key )
635+ return doc .exists ()
636+
611637 def __iter__ (self , remote = True ):
612638 """
613639 Overrides dictionary __iter__ behavior to provide iterable Document
@@ -921,131 +947,6 @@ def update_handler_result(self, ddoc_id, handler_name, doc_id=None, data=None, *
921947 resp .raise_for_status ()
922948 return resp .text
923949
924- class CloudantDatabase (CouchDatabase ):
925- """
926- Encapsulates a Cloudant database. A CloudantDatabase object is
927- instantiated with a reference to a client/session.
928- It supports accessing the documents, and various database
929- features such as the document indexes, changes feed, design documents, etc.
930-
931- :param Cloudant client: Client instance used by the database.
932- :param str database_name: Database name used to reference the database.
933- :param int fetch_limit: Optional fetch limit used to set the max number of
934- documents to fetch per query during iteration cycles. Defaults to 100.
935- """
936- def __init__ (self , client , database_name , fetch_limit = 100 ):
937- super (CloudantDatabase , self ).__init__ (
938- client ,
939- database_name ,
940- fetch_limit = fetch_limit
941- )
942-
943- def security_document (self ):
944- """
945- Retrieves the security document for the current database
946- containing information about the users that the database
947- is shared with.
948-
949- :returns: Security document as a ``dict``
950- """
951- return dict (self .get_security_document ())
952-
953- @property
954- def security_url (self ):
955- """
956- Constructs and returns the security document URL.
957-
958- :returns: Security document URL
959- """
960- url = '/' .join ((self ._database_host , '_api' , 'v2' , 'db' ,
961- self .database_name , '_security' ))
962- return url
963-
964- def share_database (self , username , roles = None ):
965- """
966- Shares the current remote database with the username provided.
967- You can grant varying degrees of access rights,
968- default is to share read-only, but additional
969- roles can be added by providing the specific roles as a
970- ``list`` argument. If the user already has this database shared with
971- them then it will modify/overwrite the existing permissions.
972-
973- :param str username: Cloudant user to share the database with.
974- :param list roles: A list of
975- `roles
976- <https://console.bluemix.net/docs/services/Cloudant/api/authorization.html#roles>`_
977- to grant to the named user.
978-
979- :returns: Share database status in JSON format
980- """
981- if roles is None :
982- roles = ['_reader' ]
983- valid_roles = [
984- '_reader' ,
985- '_writer' ,
986- '_admin' ,
987- '_replicator' ,
988- '_db_updates' ,
989- '_design' ,
990- '_shards' ,
991- '_security'
992- ]
993- doc = self .security_document ()
994- data = doc .get ('cloudant' , {})
995- perms = []
996- if all (role in valid_roles for role in roles ):
997- perms = list (set (roles ))
998-
999- if not perms :
1000- raise CloudantArgumentError (102 , roles , valid_roles )
1001-
1002- data [username ] = perms
1003- doc ['cloudant' ] = data
1004- resp = self .r_session .put (
1005- self .security_url ,
1006- data = json .dumps (doc , cls = self .client .encoder ),
1007- headers = {'Content-Type' : 'application/json' }
1008- )
1009- resp .raise_for_status ()
1010- return resp .json ()
1011-
1012- def unshare_database (self , username ):
1013- """
1014- Removes all sharing with the named user for the current remote database.
1015- This will remove the entry for the user from the security document.
1016- To modify permissions, use the
1017- :func:`~cloudant.database.CloudantDatabase.share_database` method
1018- instead.
1019-
1020- :param str username: Cloudant user to unshare the database from.
1021-
1022- :returns: Unshare database status in JSON format
1023- """
1024- doc = self .security_document ()
1025- data = doc .get ('cloudant' , {})
1026- if username in data :
1027- del data [username ]
1028- doc ['cloudant' ] = data
1029- resp = self .r_session .put (
1030- self .security_url ,
1031- data = json .dumps (doc , cls = self .client .encoder ),
1032- headers = {'Content-Type' : 'application/json' }
1033- )
1034- resp .raise_for_status ()
1035- return resp .json ()
1036-
1037- def shards (self ):
1038- """
1039- Retrieves information about the shards in the current remote database.
1040-
1041- :returns: Shard information retrieval status in JSON format
1042- """
1043- url = '/' .join ((self .database_url , '_shards' ))
1044- resp = self .r_session .get (url )
1045- resp .raise_for_status ()
1046-
1047- return resp .json ()
1048-
1049950 def get_query_indexes (self , raw_result = False ):
1050951 """
1051952 Retrieves query indexes from the remote database.
@@ -1242,6 +1143,132 @@ def get_query_result(self, selector, fields=None, raw_result=False,
12421143
12431144 return query .result
12441145
1146+
1147+ class CloudantDatabase (CouchDatabase ):
1148+ """
1149+ Encapsulates a Cloudant database. A CloudantDatabase object is
1150+ instantiated with a reference to a client/session.
1151+ It supports accessing the documents, and various database
1152+ features such as the document indexes, changes feed, design documents, etc.
1153+
1154+ :param Cloudant client: Client instance used by the database.
1155+ :param str database_name: Database name used to reference the database.
1156+ :param int fetch_limit: Optional fetch limit used to set the max number of
1157+ documents to fetch per query during iteration cycles. Defaults to 100.
1158+ """
1159+ def __init__ (self , client , database_name , fetch_limit = 100 ):
1160+ super (CloudantDatabase , self ).__init__ (
1161+ client ,
1162+ database_name ,
1163+ fetch_limit = fetch_limit
1164+ )
1165+
1166+ def security_document (self ):
1167+ """
1168+ Retrieves the security document for the current database
1169+ containing information about the users that the database
1170+ is shared with.
1171+
1172+ :returns: Security document as a ``dict``
1173+ """
1174+ return dict (self .get_security_document ())
1175+
1176+ @property
1177+ def security_url (self ):
1178+ """
1179+ Constructs and returns the security document URL.
1180+
1181+ :returns: Security document URL
1182+ """
1183+ url = '/' .join ((self ._database_host , '_api' , 'v2' , 'db' ,
1184+ self .database_name , '_security' ))
1185+ return url
1186+
1187+ def share_database (self , username , roles = None ):
1188+ """
1189+ Shares the current remote database with the username provided.
1190+ You can grant varying degrees of access rights,
1191+ default is to share read-only, but additional
1192+ roles can be added by providing the specific roles as a
1193+ ``list`` argument. If the user already has this database shared with
1194+ them then it will modify/overwrite the existing permissions.
1195+
1196+ :param str username: Cloudant user to share the database with.
1197+ :param list roles: A list of
1198+ `roles
1199+ <https://console.bluemix.net/docs/services/Cloudant/api/authorization.html#roles>`_
1200+ to grant to the named user.
1201+
1202+ :returns: Share database status in JSON format
1203+ """
1204+ if roles is None :
1205+ roles = ['_reader' ]
1206+ valid_roles = [
1207+ '_reader' ,
1208+ '_writer' ,
1209+ '_admin' ,
1210+ '_replicator' ,
1211+ '_db_updates' ,
1212+ '_design' ,
1213+ '_shards' ,
1214+ '_security'
1215+ ]
1216+ doc = self .security_document ()
1217+ data = doc .get ('cloudant' , {})
1218+ perms = []
1219+ if all (role in valid_roles for role in roles ):
1220+ perms = list (set (roles ))
1221+
1222+ if not perms :
1223+ raise CloudantArgumentError (102 , roles , valid_roles )
1224+
1225+ data [username ] = perms
1226+ doc ['cloudant' ] = data
1227+ resp = self .r_session .put (
1228+ self .security_url ,
1229+ data = json .dumps (doc , cls = self .client .encoder ),
1230+ headers = {'Content-Type' : 'application/json' }
1231+ )
1232+ resp .raise_for_status ()
1233+ return resp .json ()
1234+
1235+ def unshare_database (self , username ):
1236+ """
1237+ Removes all sharing with the named user for the current remote database.
1238+ This will remove the entry for the user from the security document.
1239+ To modify permissions, use the
1240+ :func:`~cloudant.database.CloudantDatabase.share_database` method
1241+ instead.
1242+
1243+ :param str username: Cloudant user to unshare the database from.
1244+
1245+ :returns: Unshare database status in JSON format
1246+ """
1247+ doc = self .security_document ()
1248+ data = doc .get ('cloudant' , {})
1249+ if username in data :
1250+ del data [username ]
1251+ doc ['cloudant' ] = data
1252+ resp = self .r_session .put (
1253+ self .security_url ,
1254+ data = json .dumps (doc , cls = self .client .encoder ),
1255+ headers = {'Content-Type' : 'application/json' }
1256+ )
1257+ resp .raise_for_status ()
1258+ return resp .json ()
1259+
1260+ def shards (self ):
1261+ """
1262+ Retrieves information about the shards in the current remote database.
1263+
1264+ :returns: Shard information retrieval status in JSON format
1265+ """
1266+ url = '/' .join ((self .database_url , '_shards' ))
1267+ resp = self .r_session .get (url )
1268+ resp .raise_for_status ()
1269+
1270+ return resp .json ()
1271+
12451272 def get_search_result (self , ddoc_id , index_name , ** query_params ):
12461273 """
12471274 Retrieves the raw JSON content from the remote database based on the
0 commit comments