Commit 48141b0d by Gustav Arngården

Merge pull request #1 from quantopian/master

setup.py, robustness, user-friendliness
parents 26c9333d 9d3c77b5
...@@ -2,22 +2,30 @@ ...@@ -2,22 +2,30 @@
import time import time
import pymongo import pymongo
EXECUTABLE_MONGO_METHODS = set([typ for typ in dir(pymongo.collection.Collection) if not typ.startswith('_')]) def get_methods(obj):
EXECUTABLE_MONGO_METHODS.update(set([typ for typ in dir(pymongo.Connection) if not typ.startswith('_')])) attrs = (attr for attr in dir(obj))
EXECUTABLE_MONGO_METHODS.update(set([typ for typ in dir(pymongo) if not typ.startswith('_')])) attrs = (attr for attr in attrs if not attr.startswith('_'))
return set([attr for attr in attrs if hasattr(getattr(obj, attr), '__call__')])
EXECUTABLE_MONGO_METHODS = get_methods(pymongo.collection.Collection)
EXECUTABLE_MONGO_METHODS.update(get_methods(pymongo.Connection))
EXECUTABLE_MONGO_METHODS.update(get_methods(pymongo))
def safe_mongocall(call): def safe_mongocall(call):
""" Decorator for automatic handling of AutoReconnect-exceptions. """ Decorator for automatic handling of AutoReconnect-exceptions.
""" """
def _safe_mongocall(*args, **kwargs): def _safe_mongocall(*args, **kwargs):
for i in xrange(5): for i in xrange(4):
try: try:
return call(*args, **kwargs) return call(*args, **kwargs)
except pymongo.errors.AutoReconnect: except pymongo.errors.AutoReconnect:
print 'AutoReconnecting, try', i print 'AutoReconnecting, try %d' % i
time.sleep(pow(2, i)) time.sleep(pow(2, i))
print 'Error: Failed operation!' # Try one more time, but this time, if it fails, let the
# exception bubble up to the caller.
return call(*args, **kwargs)
return _safe_mongocall return _safe_mongocall
...@@ -33,6 +41,14 @@ class Executable: ...@@ -33,6 +41,14 @@ class Executable:
def __call__(self, *args, **kwargs): def __call__(self, *args, **kwargs):
return self.method(*args, **kwargs) return self.method(*args, **kwargs)
def __dir__(self):
return dir(self.method)
def __str__(self):
return self.method.__str__()
def __repr__(self):
return self.method.__repr__()
class MongoProxy: class MongoProxy:
""" Proxy for MongoDB connection. """ Proxy for MongoDB connection.
...@@ -51,17 +67,22 @@ class MongoProxy: ...@@ -51,17 +67,22 @@ class MongoProxy:
named "key". named "key".
""" """
return MongoProxy(getattr(self.conn, key)) item = self.conn[key]
if hasattr(item, '__call__'):
return MongoProxy(item)
return item
def __getattr__(self, key): def __getattr__(self, key):
""" If key is the name of an executable method in the MongoDB connection, """ If key is the name of an executable method in the MongoDB connection,
for instance find or insert, wrap this method in Executable-class that for instance find or insert, wrap this method in Executable-class that
handles AutoReconnect-Exception. handles AutoReconnect-Exception.
""" """
if key in EXECUTABLE_MONGO_METHODS:
return Executable(getattr(self.conn, key)) attr = getattr(self.conn, key)
return self[key] if hasattr(attr, '__call__') and key in EXECUTABLE_MONGO_METHODS:
return Executable(attr)
return attr
def __call__(self, *args, **kwargs): def __call__(self, *args, **kwargs):
return self.conn(*args, **kwargs) return self.conn(*args, **kwargs)
...@@ -69,6 +90,9 @@ class MongoProxy: ...@@ -69,6 +90,9 @@ class MongoProxy:
def __dir__(self): def __dir__(self):
return dir(self.conn) return dir(self.conn)
def __str__(self):
return self.conn.__str__()
def __repr__(self): def __repr__(self):
return self.conn.__repr__() return self.conn.__repr__()
......
from setuptools import setup, find_packages
LONG_DESCRIPTION = None
README_MARKDOWN = None
with open('README.md') as markdown_source:
README_MARKDOWN = markdown_source.read()
try:
import pandoc
pandoc.core.PANDOC_PATH = 'pandoc'
# Converts the README.md file to ReST, since PyPI uses ReST for formatting,
# This allows to have one canonical README file, being the README.md
doc = pandoc.Document()
doc.markdown = README_MARKDOWN
LONG_DESCRIPTION = doc.rst
except ImportError:
# If pandoc isn't installed, e.g. when downloading from pip,
# just use the regular README.
LONG_DESCRIPTION = README_MARKDOWN
setup(
name='MongoDBProxy',
py_modules=['mongodb_proxy'],
# version='',
description='Proxy around MongoDB connection that automatically handles AutoReconnect exceptions.',
# author='',
# author_email='',
long_description=LONG_DESCRIPTION,
# license='',
# classifiers=[
# ],
setup_requires=['pyandoc'],
install_requires=['pymongo'],
url="https://github.com/arngarden/MongoDBProxy"
)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment