Skip to content
This repository was archived by the owner on Aug 30, 2024. It is now read-only.

Commit 74a2784

Browse files
authored
Merge pull request #314 from cloudant/313-bluemix-client-constructor
Implement Cloudant.bluemix client class method
2 parents 19104ec + 17d8c63 commit 74a2784

File tree

3 files changed

+139
-1
lines changed

3 files changed

+139
-1
lines changed

CHANGES.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
2.6.0 (Unreleased)
22
==================
3+
- [NEW] Added ``Cloudant.bluemix()`` class method to the Cloudant client allowing service credentials to be passed using the CloudFoundry VCAP_SERVICES environment variable.
34
- [FIXED] Fixed client construction in ``cloudant_bluemix`` context manager.
45
- [FIXED] Fixed validation for feed options to accept zero as a valid value.
56

src/cloudant/client.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131
USER_AGENT,
3232
append_response_error_content,
3333
InfiniteSession,
34-
ClientSession)
34+
ClientSession,
35+
CloudFoundryService)
3536

3637

3738
class CouchDB(dict):
@@ -764,3 +765,31 @@ def _write_cors_configuration(self, config):
764765
resp.raise_for_status()
765766

766767
return resp.json()
768+
769+
@classmethod
770+
def bluemix(cls, vcap_services, instance_name=None, **kwargs):
771+
"""
772+
Create a Cloudant session using a VCAP_SERVICES environment variable.
773+
774+
:param vcap_services: VCAP_SERVICES environment variable
775+
:type vcap_services: dict or str
776+
:param str instance_name: Optional Bluemix instance name. Only required
777+
if multiple Cloudant instances are available.
778+
779+
Example usage:
780+
781+
.. code-block:: python
782+
783+
import os
784+
from cloudant.client import Cloudant
785+
786+
client = Cloudant.bluemix(os.getenv('VCAP_SERVICES'),
787+
'Cloudant NoSQL DB')
788+
789+
print client.all_dbs()
790+
"""
791+
service = CloudFoundryService(vcap_services, instance_name)
792+
return Cloudant(service.username,
793+
service.password,
794+
url=service.url,
795+
**kwargs)

tests/unit/client_tests.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,114 @@ def test_constructor_with_account(self):
539539
'https://{0}.cloudant.com'.format(self.account)
540540
)
541541

542+
def test_bluemix_constructor(self):
543+
"""
544+
Test instantiating a client object using a VCAP_SERVICES environment
545+
variable.
546+
"""
547+
instance_name = 'Cloudant NoSQL DB-lv'
548+
vcap_services = {'cloudantNoSQLDB': [{
549+
'credentials': {
550+
'username': self.user,
551+
'password': self.pwd,
552+
'host': '{0}.cloudant.com'.format(self.account),
553+
'port': 443,
554+
'url': self.url
555+
},
556+
'name': instance_name
557+
}]}
558+
559+
# create Cloudant Bluemix client
560+
c = Cloudant.bluemix(vcap_services)
561+
562+
try:
563+
c.connect()
564+
self.assertIsInstance(c, Cloudant)
565+
self.assertIsInstance(c.r_session, requests.Session)
566+
self.assertEquals(c.session()['userCtx']['name'], self.user)
567+
568+
except Exception as err:
569+
self.fail('Exception {0} was raised.'.format(str(err)))
570+
571+
finally:
572+
c.disconnect()
573+
574+
def test_bluemix_constructor_specify_instance_name(self):
575+
"""
576+
Test instantiating a client object using a VCAP_SERVICES environment
577+
variable and specifying which instance name to use.
578+
"""
579+
instance_name = 'Cloudant NoSQL DB-lv'
580+
vcap_services = {'cloudantNoSQLDB': [{
581+
'credentials': {
582+
'username': self.user,
583+
'password': self.pwd,
584+
'host': '{0}.cloudant.com'.format(self.account),
585+
'port': 443,
586+
'url': self.url
587+
},
588+
'name': instance_name
589+
}]}
590+
591+
# create Cloudant Bluemix client
592+
c = Cloudant.bluemix(vcap_services, instance_name=instance_name)
593+
594+
try:
595+
c.connect()
596+
self.assertIsInstance(c, Cloudant)
597+
self.assertIsInstance(c.r_session, requests.Session)
598+
self.assertEquals(c.session()['userCtx']['name'], self.user)
599+
600+
except Exception as err:
601+
self.fail('Exception {0} was raised.'.format(str(err)))
602+
603+
finally:
604+
c.disconnect()
605+
606+
def test_bluemix_constructor_with_multiple_services(self):
607+
"""
608+
Test instantiating a client object using a VCAP_SERVICES environment
609+
variable that contains multiple services.
610+
"""
611+
instance_name = 'Cloudant NoSQL DB-lv'
612+
vcap_services = {'cloudantNoSQLDB': [
613+
{
614+
'credentials': {
615+
'username': self.user,
616+
'password': self.pwd,
617+
'host': '{0}.cloudant.com'.format(self.account),
618+
'port': 443,
619+
'url': self.url
620+
},
621+
'name': instance_name
622+
},
623+
{
624+
'credentials': {
625+
'username': 'foo',
626+
'password': 'bar',
627+
'host': 'baz.com',
628+
'port': 1234,
629+
'url': 'https://foo:[email protected]:1234'
630+
},
631+
'name': 'Cloudant NoSQL DB-yu'
632+
}
633+
]}
634+
635+
# create Cloudant Bluemix client
636+
c = Cloudant.bluemix(vcap_services, instance_name=instance_name)
637+
638+
try:
639+
c.connect()
640+
self.assertIsInstance(c, Cloudant)
641+
self.assertIsInstance(c.r_session, requests.Session)
642+
self.assertEquals(c.session()['userCtx']['name'], self.user)
643+
644+
except Exception as err:
645+
self.fail('Exception {0} was raised.'.format(str(err)))
646+
647+
finally:
648+
c.disconnect()
649+
542650
def test_connect_headers(self):
543651
"""
544652
Test that the appropriate request headers are set

0 commit comments

Comments
 (0)