Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 10 additions & 13 deletions py2store/persisters/_arangodb_in_progress.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,22 +57,19 @@ class ArangoDbPersister(Persister):

def __init__(
self,
user='root',
password='root',
url='http://127.0.0.1:8529',
db_name='py2store',
collection_name='test',
uri, # Example dict(
# user='root',
# password='root',
# url='http://127.0.0.1:8529',
# db_name='py2store',
# )
collection='test',
key_fields=('key',), # _id, _key and _rev are reserved by db
key_fields_separator='::',
):
self._connection = Connection(
arangoURL=url,
username=user,
password=password,
)

self._db_name = db_name
self._collection_name = collection_name
self._db_name = uri.pop('db_name')
self._connection = Connection(**uri)
self._collection_name = collection

# If DB not created:
if not self._connection.hasDatabase(self._db_name):
Expand Down
Empty file.
23 changes: 8 additions & 15 deletions py2store/persisters/couchdb_w_couchdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,27 +65,20 @@ def clear(self):

def __init__(
self,
user='admin',
password='admin',
url='http://127.0.0.1:5984',
db_name='py2store',
uri, # Example: "https://username:password@example.com:5984/"
collection='py2store',
key_fields=('_id',),
couchdb_client_kwargs=None
):
if couchdb_client_kwargs is None:
couchdb_client_kwargs = {}
if user and password:
# put credentials in url if provided like https://username:password@example.com:5984/
if '//' in url: # if scheme present
url = f'{url.split("//")[0]}//{user}:{password}@{url.split("//")[1]}'
else:
url = f'http//{user}:{password}@{url}'
self._couchdb_server = Server(url=url, **couchdb_client_kwargs)
self._db_name = db_name

self._couchdb_server = Server(url=uri, **couchdb_client_kwargs)
self._db_name = collection
# if db not created
if db_name not in self._couchdb_server:
self._couchdb_server.create(db_name)
self._cdb = self._couchdb_server[db_name]
if collection not in self._couchdb_server:
self._couchdb_server.create(collection)
self._cdb = self._couchdb_server[collection]
if isinstance(key_fields, str):
key_fields = (key_fields,)

Expand Down
12 changes: 9 additions & 3 deletions py2store/persisters/dropbox_w_dropbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,15 @@ class DropboxPersister(Persister):
>>> del s['/py2store_data/test/_can_remove']
"""

def __init__(self, rootdir, oauth2_access_token,
connection_kwargs=None, files_upload_kwargs=None,
files_list_folder_kwargs=None, rev=None):
def __init__(
self,
rootdir,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rootdir? Or uri?

oauth2_access_token,
connection_kwargs=None,
files_upload_kwargs=None,
files_list_folder_kwargs=None,
rev=None,
):

if connection_kwargs is None:
connection_kwargs = {}
Expand Down
12 changes: 6 additions & 6 deletions py2store/persisters/dropbox_w_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
class DropboxFolderCopyReader(Reader):
"""Makes a full local copy of the folder (by default, to a local temp folder) and gives access to it.
"""
def __init__(self, url, path=tempfile.gettempdir()):
self.url = url
self.path = path
def __init__(self, uri, collection=tempfile.gettempdir()):
self.url = uri
self.path = collection

os.makedirs(self.path, exist_ok=True)
self._zip_filepath = os.path.join(self.path, 'shared_folder.zip')
Expand Down Expand Up @@ -51,9 +51,9 @@ def _unzip(self):


class DropboxFileCopyReader(Reader):
def __init__(self, url, path=None):
self.url = url
self.path = path or self._get_filename_from_url()
def __init__(self, uri, collection=None):
self.url = uri
self.path = collection or self._get_filename_from_url()

download_from_dropbox(self.url, self.path, as_zip=False)
self.file = open(self.path, 'r')
Expand Down
29 changes: 17 additions & 12 deletions py2store/persisters/ftp_persister.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from py2store.base import Persister
from ftplib import FTP, all_errors
import os.path
from io import BytesIO
from io import BytesIO


def remote_mkdir(ftp, remote_directory):
"""
Expand All @@ -16,7 +17,7 @@ def remote_mkdir(ftp, remote_directory):
# top-level relative directory must exist
return False
try:
ftp.cwd(remote_directory) # sub-directory exists
ftp.cwd(remote_directory) # sub-directory exists
except all_errors:
dirname, basename = os.path.split(remote_directory.rstrip('/'))
remote_mkdir(ftp, dirname) # make parent directories
Expand Down Expand Up @@ -58,15 +59,19 @@ class FtpPersister(Persister):
0
"""

def __init__(self,
user='dlpuser@dlptest.com',
password='fLDScD4Ynth0p4OJ6bW6qCxjh',
url='ftp.dlptest.com',
rootdir='./py2store',
encoding='utf8'
):
self._ftp = FTP(host=url, user=user, passwd=password)
self._rootdir = rootdir
def __init__(
self,
uri,
# Example dict(
# user='dlpuser@dlptest.com',
# password='fLDScD4Ynth0p4OJ6bW6qCxjh',
# url='ftp.dlptest.com',
# )
collection='./py2store',
encoding='utf8'
):
self._ftp = FTP(**uri)
self._rootdir = collection
self._encoding = encoding
self._ftp.encoding = encoding
remote_mkdir(self._ftp, self._rootdir)
Expand Down Expand Up @@ -114,4 +119,4 @@ def __del__(self):
"""
Close ssh session when an object is deleted
"""
self._ftp.close()
self._ftp.close()
23 changes: 12 additions & 11 deletions py2store/persisters/mongo_w_pymongo.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,18 @@ class MongoPersister(Persister):
{'first': 'Vitalik', 'last': 'Buterin'} --> {'yob': 1994, 'proj': 'ethereum', 'bdfl': True}
"""

def clear(self):
raise NotImplementedError("clear is disabled by default, for your own protection! "
"Loop and delete if you really want to.")

def __init__(self, db_name='py2store', collection_name='test', key_fields=('_id',), data_fields=None,
mongo_client_kwargs=None):
if mongo_client_kwargs is None:
mongo_client_kwargs = {}
self._mongo_client = MongoClient(**mongo_client_kwargs)
def __init__(
self,
uri,
collection='test',
key_fields=('_id',),
data_fields=None,
):
db_name = uri.pop('db_name')
self._mongo_client = MongoClient(**uri)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like old interface is broken with this. Need to either change all usages of MongoPersister, or handle the case where uri is db_name. I'll look into this myself, but note this effect for other persisters you take care of.

self._db_name = db_name
self._collection_name = collection_name
self._mgc = self._mongo_client[db_name][collection_name]
self._collection_name = collection
self._mgc = self._mongo_client[db_name][collection]
if isinstance(key_fields, str):
key_fields = (key_fields,)
if data_fields is None:
Expand All @@ -81,6 +81,7 @@ def __init__(self, db_name='py2store', collection_name='test', key_fields=('_id'
data_fields = {k: True for k in data_fields}
if '_id' not in data_fields:
data_fields['_id'] = False

self._data_fields = data_fields
self._key_fields = key_fields

Expand Down
52 changes: 29 additions & 23 deletions py2store/persisters/sql_w_odbc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,40 @@
import subprocess
from collections.abc import MutableMapping

from py2store.util import ModuleNotFoundErrorNiceMessage

with ModuleNotFoundErrorNiceMessage():
import pyodbc

class SQLServerPersister(MutableMapping):
def __init__(self, conn_protocol='tcp', host='localhost', port='1433', db_username='SA', db_pass='Admin123x',
db_name='py2store', table_name='person', primary_key='id', data_fields=('name',)):

class SQLServerPersister(MutableMapping):
def __init__(
self,
uri,
# Example: dict(
# conn_protocol='tcp',
# host='localhost',
# port='1433',
# db_username='SA',
# db_pass='Admin123x',
# db_name='py2store',
# )
collection='py2store_default_table',
primary_key='id',
data_fields=('name',)
):
self.__check_dependencies()
self._sql_server_client = pyodbc.connect('DRIVER={{ODBC Driver 17 for SQL Server}};'
'SERVER={}:{},{};'
'DATABASE={};'
'UID={};'
'PWD={}'
.format(conn_protocol, host, port, db_name, db_username, db_pass))
self._sql_server_client = pyodbc.connect(
'DRIVER={{ODBC Driver 17 for SQL Server}};'
'SERVER={conn_protocol}:{host},{port};'
'DATABASE={db_name};'
'UID={db_username};'
'PWD={db_pass}'
.format(**uri)
)

self._cursor = self._sql_server_client.cursor()
self._table_name = table_name
self._table_name = collection
self._primary_key = primary_key

self._select_all_query = "SELECT * from {table};".format(table=self._table_name)
Expand All @@ -28,16 +47,6 @@ def __init__(self, conn_protocol='tcp', host='localhost', port='1433', db_userna

@staticmethod
def __check_dependencies():
import pkg_resources
installed_packages = [pkg.project_name for pkg in pkg_resources.working_set]
if 'pyodbc' not in installed_packages:
raise ModuleNotFoundError("'SQLServerPersister' depends on the module 'pyodbc' which is not installed. "
"Try installing dependency using 'pip install pyodbc'.")

# import pyodbc globally
global pyodbc
import pyodbc

if 'ubuntu' in platform.platform().lower():
result = subprocess.Popen(["dpkg", "-s", "msodbcsql17"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = result.communicate()
Expand Down Expand Up @@ -115,6 +124,3 @@ def test_sqlserver_persister():

print("Getting the length")
print(len(sql_server_persister))


test_sqlserver_persister()
16 changes: 8 additions & 8 deletions py2store/persisters/sql_w_sqlalchemy.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ class SQLAlchemyPersister(Persister):

def __init__(
self,
db_uri='sqlite:///my_sqlite.db',
collection_name='py2store_default_table',
uri='sqlite:///my_sqlite.db',
collection='py2store_default_table',
key_fields=('id',),
data_fields=('data',),
autocommit=True,
**db_kwargs
):
"""
:param db_uri: Uniform Resource Identifier of a database you would like to use.
:param uri: Uniform Resource Identifier of a database you would like to use.
Unix/Mac (note the four leading slashes)
sqlite:////absolute/path/to/foo.db

Expand All @@ -41,7 +41,7 @@ def __init__(
I.e. in general:
dialect+driver://username:password@host:port/database

:param collection_name: name of the table to use, i.e. "my_table".
:param collection: name of the table to use, i.e. "my_table".
:param key_fields: indexed keys columns names.
:param data_fields: non-indexed data columns names.
:param autocommit: whether each data change should be instantly commited, or not.
Expand All @@ -57,15 +57,15 @@ def __init__(
self.table = None
self.session = None

self.setup(db_uri, collection_name, **db_kwargs)
self.setup(uri, collection, **db_kwargs)

def setup(self, db_uri, collection_name, **db_kwargs):
def setup(self, uri, collection, **db_kwargs):
# Setup connection to our DB:
engine = create_engine(db_uri, **db_kwargs)
engine = create_engine(uri, **db_kwargs)
self.connection = engine.connect()

# Create a table:
self.table = self._create_table(collection_name, engine)
self.table = self._create_table(collection, engine)

# Open ORM session:
self.session = sessionmaker(bind=engine)()
Expand Down
35 changes: 27 additions & 8 deletions py2store/persisters/ssh_persister.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,36 @@ class SshPersister(Persister):

def __init__(
self,
user='stud',
password='stud',
url='10.1.103.201',
rootdir='./py2store',
encoding='utf8'
):
uri, # Example: dict(url='10.1.103.201', user='stud', password='stud')
collection='./py2store',
encoding='utf8',
):
"""
:param uri: A dict of the following key-values:
:param str hostname: the server to connect to, REQUIRED, others are optional
:param int port: the server port to connect to
:param str username:
the username to authenticate as (defaults to the current local
username)
:param str password:
Used for password authentication; is also used for private key
decryption if ``passphrase`` is not given.
:param str passphrase:
Used for decrypting private keys.
:param .PKey pkey: an optional private key to use for authentication
:param str key_filename:
the filename, or list of filenames, of optional private key(s)
and/or certs to try for authentication
:param float timeout:
an optional timeout (in
:param collection: root direction
:param encoding:
"""
self._ssh = paramiko.SSHClient()
self._ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self._ssh.connect(url, username=user, password=password)
self._ssh.connect(**uri)
self._sftp = self._ssh.open_sftp()
self._rootdir = rootdir
self._rootdir = collection
self._encoding = encoding
remote_mkdir(self._sftp, self._rootdir)

Expand Down
4 changes: 2 additions & 2 deletions tests/test_dropbox_w_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
def shared_folder_persister():
path = 'tests/data/path'
persister = DropboxFolderCopyReader(
url=SHARED_FOLDER_URL,
path=path,
uri=SHARED_FOLDER_URL,
collection=path,
)
yield persister
try:
Expand Down
Loading