Skip to main content

Wrapper classes with an application for Mongo

Project description

# Mongodec

# Overview
Mongodec provides a generalizable wrapper class that can be extended to any python class and allows for easy overwrites and wrapping of methods. In this repo this has been used to implement an extension of `Pymongo` objects which covers a common use case of wishing to apply a filter to all database accesses.

# Setup
The easiest way to install Mongodec would be to use pip: `pip install mongodec`. Though this repo can be cloned and you can build from source if you like.

# Example Usage
In this section, I'll briefly provide an example for how to use the `FilterMongo*` clasess to automatically apply filters to mongo queries.
## Connecting to Mongo
It is recommended that frequent accesses to mongo databases do so through the provided `MongoConfig` classes
```
from mongodec import MongoConfig
import pymongo # just used for the assert
config = MongoConfig(user='dev',
password='foobar',
host='some-host-example.mongodb.net',
database='dbname',
port=27017)
mongo_db_obj = config.db()
assert isinstance(mongo_db_obj, pymongo.database.Database)
```
## Building a filtered database
All classes that extend Changeling take an instance of the object they're replicating as the instantiating argument, with potentially other arguments. Suppose we want to look at documents matching the filter `{'name': 'foobar', 'value': {'$gt': 10}}`. Then we can take a pymongo database object and build the filtered database:
```
from mongodec import FilterMongoDB
mongo_db = ... #Some instance of pymongo.database.Database
q_filter = {'name': 'foo', 'value': {'$gt': 10}}
filter_mongo_obj = FilterMongoDB(mongo_db, q_filter)

# Examples -- insert some dummy data using pymongo's classes
real_collection = mongo_db.collection_name
real_collection.insert([{'name': 'foo', 'value': 4},
{'name': 'foo', 'value': 12},
{'name': 'bar', 'value': 100}])

# access the collection
filter_collection = filter_mongo_obj['collection_name']
filter_collection_2 = filter_mongo_obj.collection_name
filter_collection_3 = filter_mongo_obj.get_collection('collection_name')
assert filter_collection == filter_collection_2
assert filter_collection == filter_collection_3

# operate as if filter_collection were a real collection
assert filter_collection.count() == 1
assert (filter_collection.find_one({}, {'_id': 0}}) ==
{'name': 'foo', 'value': 12})
filter_collection.delete_many()
assert real_collection.count() == 2
assert filter_collection.count() == 0

# can turn off the filter with the 'no_changeling' kwarg
assert filter_collection.count(no_changeling=True) == 2
```
All applicable methods are wrapped appropriately, and we offer support for BulkOperations as well.

# Extending your own Changeling classes
I'll attach some brief documentation about how the `Changeling` class works, but more info is contained in mongodec/changeling.py and one can view the implementation of the `FilterMongo*` classes in mongodec/filter_mongo.py

Any class C that extends Changeling should be viewed as a wrapper for another class B. Any instance of C should then take an instance of B as an instantiating argument. The instance of B inside C is known as the 'base object' and accessible through `C_instance.base_object`.

Internally, each Changeling object keeps track of the wrapping methods with its property `cdict`. To wrap the `funky` method of class `Down2Get`, with the method `ultraFunky` then the `cdict` should look like this:
```
{'Down2Get_methods': {'funky': ultraFunky}}
```

If we want to wrap _every_ method of `Down2Get` with a method, say, `andTurnt`, the cdict will look like
```
{
'Down2Get_methods': {'funky': ultraFunky},
'Down2Get_wrap_all': andTurnt
}
```

Any method that is tricky to wrap and should be overwritten directly can be done in class definition of `C`.

Each wrapper method takes 3 arguments: func, cdict, and callargs.
func is the function that is being wrapped. cdict is the cdict of the changeling instance, and callargs is a dictionary with _all_ arguments that func takes explicitly named.

## Examples to help you with your own extensions
A simple extension that demonstrates wrapping of individual methods and all methods is the test method 'test_changeling' in mongodec/tests/test_changeling.py

A simple extension that demonstrates how to overwrite the methods of the base object is the `FilterMongoBulkOperationBuilder` located in mongodec/filter_mongo.py

A more complicated example that encapsulates all the features of `Changeling` is the `FilterMongoCollection` class in mongodec/filter_mongo.py


Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mongodec-1.0.16.tar.gz (11.8 kB view details)

Uploaded Source

Built Distribution

mongodec-1.0.16-py2-none-any.whl (16.0 kB view details)

Uploaded Python 2

File details

Details for the file mongodec-1.0.16.tar.gz.

File metadata

  • Download URL: mongodec-1.0.16.tar.gz
  • Upload date:
  • Size: 11.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for mongodec-1.0.16.tar.gz
Algorithm Hash digest
SHA256 dcecce8a13fbc8f028c45b21ab1933ff7b48e56d0da71744d80e6cfc28879f92
MD5 db470255ec3f50640e7e2f1d2cdb7135
BLAKE2b-256 b2538ce36b7664aafeeec9ee1fe603d038eb315eb81db1566ebc5e01382d2025

See more details on using hashes here.

File details

Details for the file mongodec-1.0.16-py2-none-any.whl.

File metadata

File hashes

Hashes for mongodec-1.0.16-py2-none-any.whl
Algorithm Hash digest
SHA256 6b30b7f633b71318360fa7aa07b09807b06fdefe8c7cc8f1cd6ceaf0d6408f7f
MD5 9ff4fdfcc18542d934df32c330c0aa5a
BLAKE2b-256 f7fe85de17baccd0a9fd9ab04697b10f41bc65e9a47129ab4fd0e92a03ccd8ae

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page