How can I write eve to different databases based on different url parameters and query values?

I am trying to create a REST API that selects the appropriate mongo database to write along with the correct collection. How can I select a database with the same name as the parameter and also a collection?

+3


source to share


2 answers


With the upcoming v0.6, Eve will support multiple Mongo instances.

New: Support for multiple MongoDB databases and / or servers.

You can have separate API endpoints served by different Mongo instances:

mongo_prefix

the resource parameter allows you to override the default MONGO prefix used when extracting MongoDB settings from configuration. For example, set the mongo_prefix resource in MONGO2 to read / write from the database configured with this prefix in your settings file (MONGO2_HOST, MONGO2_DBNAME, etc.).

And / or you can use a different Mongo instance depending on how the user hit the database:

set_mongo_prefix()

and get_mongo_prefix()

have been added to the BasicAuth class and derivatives. They can be used to randomly set the target database depending on the token / client making the request.



A (very) naive implementation of custom instances taken from the docs :

from eve.auth import BasicAuth

class MyBasicAuth(BasicAuth):
    def check_auth(self, username, password, allowed_roles, resource, method):
        if username == 'user1':
            self.set_mongo_prefix('MONGO1')
        elif username == 'user2':
            self.set_mongo_prefix('MONGO2')
        else:
            # serve all other users from the default db.
            self.set_mongo_prefix(None)
        return username is not None and password == 'secret'

app = Eve(auth=MyBasicAuth)
app.run()

      

also:

Database connections are cached to maintain performance. Also, this change only affects the MongoDB engine, so extensions that are currently targeting other databases do not need to be updated (they will not inherit this functionality.)

Hope this covers your needs. It is currently on a branch development

, so you can experiment / play with it already.

+2


source


Let's say you have parameters "dbname" and "collection name" and a global MongoClient instance named "client":

collection = client[dbname][collectionname]

      

The PyMongo client supports the "[]" syntax to get a database with a given name, and the PyMongo database supports "[]" to get a collection.



Here's a more complete example with Flask:

client = MongoClient()

@app.route('/<dbname>/<collection_name>')
def find_something(dbname, collection_name):
    return client[dbname][collection_name].find_one()

      

The good thing about my example is reusing the same MongoClient, so you get optimal performance and pooling. The bad thing, of course, is that you allow your users to access any database and any collection, so you need to secure it somehow.

+1


source







All Articles