0

I have got azure cosmos db emulator installed and running on windows 10. I'm successful in performing operations on db using .net sdk on windows(Visual Studio) (Used windows certificate manager (certmgr.msc) for authorization).

The issue is, I want to access cosmosdb emulator from a python script which is running on ubuntu 16.04. Initially my script threw SSl certificate verification failed error. I solved it using below commands

sudo cp documentdbemulatorcert.pem /usr/local/share/ca-certificates/documentdbemulatorcert.crt
sudo update-ca-certificates 

and added below code in my python script

os.environ['REQUESTS_CA_BUNDLE'] = os.path.join(

        '/usr/local/share/ca-certificates',

        'documentdbemulatorcert.crt')

Now the ssl error is not coming so certificates maybe verified, But when I call find collection method it gives me below error

Top level Error: args:([],), message:[]

Below is full python script which I've used from samples of python documentdb sdk

import pydocumentdb.documents as documents
import pydocumentdb.document_client as document_client
import pydocumentdb.errors as errors
import os
import config as cfg
try:

    os.environ['REQUESTS_CA_BUNDLE'] = os.path.join(

        '/usr/local/share/ca-certificates',

        'documentdbemulatorcert.crt')

except Exception as error:

    print "****os**",error
# ----------------------------------------------------------------------------------------------------------
# Prerequistes - 
# 
# 1. An Azure Cosmos DB account - 
#    https://azure.microsoft.com/en-us/documentation/articles/documentdb-create-account/
#
# 2. Microsoft Azure DocumentDB PyPi package - 
#    https://pypi.python.org/pypi/pydocumentdb/
# ----------------------------------------------------------------------------------------------------------
# Sample - demonstrates the basic CRUD operations on a Collection resource for Azure Cosmos DB
# 
# 1. Query for Collection
#  
# 2. Create Collection
#    2.1 - Basic Create
#    2.2 - Create collection with custom IndexPolicy
#    2.3 - Create collection with offerType set
#
# 3. Manage Collection OfferType
#    3.1 - Get Collection performance tier
#    3.2 - Change performance tier
#
# 4. Get a Collection by its Id property
#
# 5. List all Collection resources in a Database
#
# 6. Delete Collection
# ----------------------------------------------------------------------------------------------------------
# Note - 
# 
# Running this sample will create (and delete) multiple DocumentCollections on your account. 
# Each time a DocumentCollection is created the account will be billed for 1 hour of usage based on
# the performance tier of that account. 
# ----------------------------------------------------------------------------------------------------------

HOST = cfg.settings['host']
MASTER_KEY = cfg.settings['master_key']
DATABASE_ID = cfg.settings['database_id']
COLLECTION_ID = cfg.settings['collection_id']

database_link = 'dbs/' + DATABASE_ID

class IDisposable:
    """ A context manager to automatically close an object with a close method
    in a with statement. """

    def __init__(self, obj):
        self.obj = obj

    def __enter__(self):
        return self.obj # bound to target

    def __exit__(self, exception_type, exception_val, trace):
        # extra cleanup in here
        self = None

class CollectionManagement:

@staticmethod def find_collection(client, id): print('1. Query for Collection')

        collections = list(client.QueryCollections(
            database_link,
            {
                "query": "SELECT * FROM r WHERE r.id=@id",
                "parameters": [
                    { "name":"@id", "value": id }
                ]
            }
        ))

        if len(collections) > 0:
            print('Collection with id \'{0}\' was found'.format(id))
        else:
            print('No collection with id \'{0}\' was found'. format(id))
    @staticmethod
    def create_collection(client, id):
        """ Execute the most basic Create of collection. 
        This will create a collection with OfferType = S1 and default indexing policy """

        print("\n2.1 Create Collection - Basic")

        try:
            client.CreateCollection(database_link, {"id": id})
            print('Collection with id \'{0}\' created'.format(id))

        except errors.DocumentDBError as e:
            if e.status_code == 409:
               print('A collection with id \'{0}\' already exists'.format(id))
            else: 
                raise errors.HTTPFailure(e.status_code)               

        print("\n2.2 Create Collection - With custom index policy")

        try:
            coll = {
                "id": "collection_custom_index_policy",
                "indexingPolicy": {
                    "indexingMode": "lazy",
                    "automatic": False
                }
            }

            collection = client.CreateCollection(database_link, coll)
            print('Collection with id \'{0}\' created'.format(collection['id']))
            print('IndexPolicy Mode - \'{0}\''.format(collection['indexingPolicy']['indexingMode']))
            print('IndexPolicy Automatic - \'{0}\''.format(collection['indexingPolicy']['automatic']))

        except errors.DocumentDBError as e:
            if e.status_code == 409:
               print('A collection with id \'{0}\' already exists'.format(collection['id']))
            else: 
                raise errors.HTTPFailure(e.status_code) 


        print("\n2.3 Create Collection - With custom offerType")

        try:
            coll = {"id": "collection_custom_offertype"}

            collection = client.CreateCollection(database_link, coll, {'offerType': 'S2'} )
            print('Collection with id \'{0}\' created'.format(collection['id']))

        except errors.DocumentDBError as e:
            if e.status_code == 409:
               print('A collection with id \'{0}\' already exists'.format(collection['id']))
            else: 
                raise errors.HTTPFailure(e.status_code) 

    @staticmethod
    def manage_offertype(client, id):
        print("\n3.1 Get Collection Performance tier")

        #Collections have offers which are of type S1, S2, or S3. 
        #Each of these determine the performance throughput of a collection. 
        #A Collection is loosely coupled to Offer through the Offer's offerResourceId
        #Offer.offerResourceId == Collection._rid
        #Offer.resource == Collection._self

        try:
            # read the collection, so we can get its _self
            collection_link = database_link + '/colls/{0}'.format(id)
            collection = client.ReadCollection(collection_link)

            # now use its _self to query for Offers
            offer = list(client.QueryOffers('SELECT * FROM c WHERE c.resource = \'{0}\''.format(collection['_self'])))[0]

            print('Found Offer \'{0}\' for Collection \'{1}\' and its offerType is \'{2}\''.format(offer['id'], collection['_self'], offer['offerType']))

        except errors.DocumentDBError as e:
            if e.status_code == 404:
                print('A collection with id \'{0}\' does not exist'.format(id))
            else: 
                raise errors.HTTPFailure(e.status_code)

        print("\n3.2 Change OfferType of Collection")

        #The OfferType of a collection controls the throughput allocated to the Collection
        #To increase (or decrease) the throughput of any Collection you need to adjust the Offer.offerType
        #of the Offer record linked to the Collection

        #setting it S1, doesn't do anything because by default Collections are created with S1 Offer.offerType
        #just doing it in the sample to demonstrate how to do it and not create resources (and incur costs) we don't need
        #valid values for offerType are (currently) S1, S2 or S3
        offer['offerType'] = 'S2'
        offer = client.ReplaceOffer(offer['_self'], offer)

        print('Replaced Offer. OfferType is now \'{0}\''.format(offer['offerType']))

    @staticmethod
    def read_collection(client, id):
        print("\n4. Get a Collection by id")

        try:
            # All Azure Cosmos DB resources are addressable via a link
            # This link is constructed from a combination of resource hierachy and 
            # the resource id. 
            # Eg. The link for collection with an id of Bar in database Foo would be dbs/Foo/colls/Bar
            collection_link = database_link + '/colls/{0}'.format(id)

            collection = client.ReadCollection(collection_link)
            print('Collection with id \'{0}\' was found, it\'s _self is {1}'.format(collection['id'], collection['_self']))

        except errors.DocumentDBError as e:
            if e.status_code == 404:
               print('A collection with id \'{0}\' does not exist'.format(id))
            else: 
                raise errors.HTTPFailure(e.status_code)    

    @staticmethod
    def list_collections(client):
        print("\n5. List all Collection in a Database")

        print('Collections:')

        collections = list(client.ReadCollections(database_link))

        if not collections:
            return

        for collection in collections:
            print(collection['id'])          

    @staticmethod
    def delete_collection(client, id):
        print("\n6. Delete Collection")

        try:
           collection_link = database_link + '/colls/{0}'.format(id)
           client.DeleteCollection(collection_link)

           print('Collection with id \'{0}\' was deleted'.format(id))

        except errors.DocumentDBError as e:
            if e.status_code == 404:
               print('A collection with id \'{0}\' does not exist'.format(id))
            else: 
                raise errors.HTTPFailure(e.status_code)   

def run_sample():

    with IDisposable(document_client.DocumentClient(HOST, {'masterKey': MASTER_KEY} )) as client:
        try:
            # setup database for this sample
            try:
                #client.CreateDatabase({"id": DATABASE_ID})
                CollectionManagement.list_collections(client)

            except errors.DocumentDBError as e:
                if e.status_code == 409:
                   pass
                else: 
                    raise errors.HTTPFailure(e.status_code)

            # query for a collection            
            # CollectionManagement.find_collection(client, COLLECTION_ID)

            # # create a collection
            # CollectionManagement.create_collection(client, COLLECTION_ID)

            # # get & change OfferType of collection
            # CollectionManagement.manage_offertype(client, COLLECTION_ID)

            # # get a collection using its id
            # CollectionManagement.read_collection(client, COLLECTION_ID)

            # # list all collection on an account
            # CollectionManagement.list_collections(client)

            # # delete collection by id
            # CollectionManagement.delete_collection(client, COLLECTION_ID)

            # # cleanup database after sample
            # try:
            #     client.DeleteDatabase(database_link)

            # except errors.DocumentDBError as e:
            #     if e.status_code == 404:
            #        pass
            #     else: 
            #         raise errors.HTTPFailure(e.status_code)

        except errors.HTTPFailure as e:
            print('\nrun_sample has caught an error. {0}'.format(e.message))

        finally:
            print("\nrun_sample done")

if __name__ == '__main__':
    try:
        run_sample()

    except Exception as e:
            print("Top level Error: args:{0}, message:{1}".format(e.args,e.message))

The blockquoted code in the above snippet is a method which I'm trying to call.

Thanks a lot for reading !!!

1
  • Hi,any updates now? Try other methods also see the same error? Commented Jan 25, 2018 at 1:57

1 Answer 1

1

I tried to use Ubuntu Subsystem on my Windows System to run python documentdb SDK and it works for me.

My sample code hello.py:

import pydocumentdb.document_client as document_client

config = {
    'ENDPOINT': 'https://localhost:8081',
    'MASTERKEY': 'C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==',
    'DOCUMENTDB_DATABASE': 'test',
    'DOCUMENTDB_COLLECTION': 'testcoll'
};

def find_collection(client, id):
    collections = list(client.QueryCollections(
        "dbs/test",
        {
            "query": "SELECT * FROM r WHERE r.id=@id",
            "parameters": [
                {"name": "@id", "value": id}
            ]
        }
    ))
    if len(collections) > 0:
        print('Collection with id \'{0}\' was found'.format(id))
    else:
        print('No collection with id \'{0}\' was found'. format(id))


client = document_client.DocumentClient(config['ENDPOINT'], {'masterKey': config['MASTERKEY']})
find_collection(client,'testcoll')
print ("done........")

Output:

enter image description here

Depending on the error trace you provided, I can only know that an exception was caught and thrown but I cannot determine the specific cause. I suggest you check if the transmission parameters are correctly, and try other methods except QueryCollection method.

Any concern ,please let me know.

Sign up to request clarification or add additional context in comments.

6 Comments

I have tried same method but still it is not working.I also tried list collections method but it is also not working.When I call any method it will return <pydocumentdb.query_iterable.QueryIterable object > and I try to convert it into list or find length of it.It will give error.Can you please give pydocumentdb version which you have used and this snippet work?
@user6782126 I just used latest version 2.3.1. what's the error when you find the length of the result list?
Thank you for giving answer.I will call list collection method using collections = (client.ReadCollections("dbs/test")) then it working fine but when i try to call collections = list(client.ReadCollections("dbs/test")) it will throw exception like `File "/usr/local/lib/python2.7/dist-packages/pydocumentdb/query_iterable.py", line 116, in next return self.__next__() OpenSSL.SSL.Error: [] ```
@user6782126 I searched for the errpr :OpenSSL.SSL.Error:[]. It seems that caused by the certification issue. However the two methods you tested are all REST requests actually , they should be crashed into the same error. Any other method crashed into the SSL error?
Not yet, I started using my python script on windows so windows certificate manager is taking care of SSL connection. I'll update you once I'll get time and will work on ubuntu... Thank a lot for your time Jay !!!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.