Skip to content

Commit

Permalink
Major restructuring to base and hierarchy. Added metaclassing for eas…
Browse files Browse the repository at this point in the history
…y model finds.
  • Loading branch information
lasley committed Dec 7, 2015
1 parent 790cd4b commit a40107d
Show file tree
Hide file tree
Showing 22 changed files with 503 additions and 27 deletions.
65 changes: 65 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Virtual Env
_venv/

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]

# C extensions
*.so

# Distribution / packaging
.Python
env/
bin/
build/
develop-eggs/
dist/
eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
*.eggs

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.cache
nosetests.xml
coverage.xml
_results/

# Translations
*.mo
*.pot

# Pycharm
.idea

# Django stuff:
*.log

# Mr Developer
.mr.developer.cfg
.project
.pydevproject

# Rope
.ropeproject

# Sphinx documentation
docs/_build/

# Backup files
*~
*.swp
22 changes: 22 additions & 0 deletions carepoint/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Author: Dave Lasley <[email protected]>
# Copyright: 2015 LasLabs, Inc [https://laslabs.com]
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from carepoint.db import Carepoint, Base, Meta, Struct
File renamed without changes.
File renamed without changes.
File renamed without changes.
26 changes: 26 additions & 0 deletions carepoint/db/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Author: Dave Lasley <[email protected]>
# Copyright: 2015 LasLabs, Inc [https://laslabs.com]
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from .base import Base
from .carepoint import Carepoint
from .meta import Meta
from .struct import Struct
from .db import Db
23 changes: 23 additions & 0 deletions carepoint/db/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Author: Dave Lasley <[email protected]>
# Copyright: 2015 LasLabs, Inc [https://laslabs.com]
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
43 changes: 43 additions & 0 deletions carepoint/db/carepoint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Author: Dave Lasley <[email protected]>
# Copyright: 2015 LasLabs, Inc [https://laslabs.com]
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from sqlalchemy import create_engine
from carepoint.conf.settings import Settings
from . import Db, Meta


class Carepoint(object):
''' Base CarePoint db connector object '''
__metaclass__ = Meta

def __init__(self, server, user, passwd):

self.settings = Settings()
params = {
'user': user,
'passwd': passwd,
'server': server,
'db': 'cph',
}
# @TODO: Lazy load, once other dbs needed
self.dbs = {
'cph': Db(**params)
}
30 changes: 7 additions & 23 deletions py_carepoint/models/base.py → carepoint/db/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,39 +19,23 @@
#
##############################################################################

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine
from py_carepoint.conf.settings import Settings


class Carepoint(object):
''' Base CarePoint db connector object '''
class Db(object):
''' Base db connector object '''

ODBC_DRIVER = 'SQL+Server+Native+Client+10.0'

def __init__(self, server, user, passwd):
self.Base = declaritive_base()
def __new__(self, server, user, passwd, db, port=1433, drv=ODBC_DRIVER):

params = {
'usr': user,
'pass': passwd,
'srv': server,
'driver': self.ODBC_DRIVER,
'driver': drv,
'db': db,
}
dsn = 'mssql+pyodbc://%(usr)s:%(pass)s@%(srv)s/%(db)?driver%(drv)s'

params['db'] = 'cph'
self.cph = create_engine(dsn % params)

# params['db'] = 'grx_master'
# self.grx_master = create_engine(dsn % params)
#
# params['db'] = 'medicaid'
# self.medicaid = create_engine(dsn % params)
#
# params['db'] = 'CpERx'
# self.cp_e_rx = create_engine(dsn % params)

settings = Settings()
carepoint = CarePoint(
**settings.DATABASE
)
return create_engine(dsn % params)
70 changes: 70 additions & 0 deletions carepoint/db/meta.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Author: Dave Lasley <[email protected]>
# Copyright: 2015 LasLabs, Inc [https://laslabs.com]
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

import os
from .db import Struct, Base


class Meta(type):
''' Metaclass to autodetect models '''

# Default path to search for models - change with register_model_dir
model_path = os.path.join(__file__, 'models')

def __init__(self, name, bases, attrs):
''' Initializing mount, or registering a model? '''
if not hasattr(self, 'models'):
self.models = Struct(Base)
else:
self.register_model(self)

def register_model(self, model):
''' Registration logic + append to models struct '''
self.models[model.__class__.__name__] = models

@staticmethod
def register_model_dir(model_path):
''' This function sets the model path to be searched '''
if os.path.isdir(model_path):
Base.model_path = model_path
else:
raise EnvironmentError('%s is not a directory' % model_path)

@staticmethod
def find_models():
''' Traverse registered model directory and import non-loaded modules '''

model_path = Base.model_path
if not os.path.isdir(model_path):
raise EnvironmentError('%s is not a directory' % model_path)

for dir_name, subdirs, files in os.walk(model_path):
for file_name in files:
if file_name.endswith('.py') and file_name != '__init__.py':
module = file_[:-3] #< Strip extension
mod_obj = globals().get(module)
if mod_obj is None:
f, filename, desc = imp.find_module(
module, [model_path]
)
globals()[module] = mod_obj = imp.load_module(
module, f, filename, desc
)
96 changes: 96 additions & 0 deletions carepoint/db/struct.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Author: Dave Lasley <[email protected]>
# Copyright: 2015 LasLabs, Inc [https://laslabs.com]
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

class Struct(dict):
'''
Subclass dict, re-implement __getitem__ to scan for models
if a requested key is missing
'''
def __init__(self, cls, *args, **kwargs):
'''
Init, set mount to PlugPyMount master instance
@param PlugPyMount cls
'''
self.mount = cls
super(Struct, self).__init__(*args,**kwargs)

def __getitem__(self, key, retry=True, default=False):
''' Re-implement __getitem__ to scan for models if key missing '''
try:
return super(Struct, self).__getitem__(key)
except KeyError:
if default != False:
return default
elif retry:
self.mount.find_models()
return self.__getitem__(key, False)
else:
raise KeyError(
'Plugin "%s" not found in model_dir "%s"' % (
key, self.mount.model_path
)
)

def set_iter_refresh(self, refresh=True):
'''
Toggle flag to search for new models before iteration
@param bool refresh Whether to refresh before iteration
'''
self.iter_refresh = refresh

def __refresh_models__(self, ):
if self.iter_refresh:
self.mount.find_models()

def __iter__(self):
''' Reimplement __iter__ to allow for optional model refresh '''
self.__refresh_models__()
return super(Struct, self).__iter__()

def values(self):
''' Reimplement values to allow for optional model refresh '''
self.__refresh_models__()
return super(Struct, self).values()

def keys(self):
''' Reimplement keys to allow for optional model refresh '''
self.__refresh_models__()
return super(Struct, self).keys()

def items(self):
''' Reimplement items to allow for optional model refresh '''
self.__refresh_models__()
return super(Struct, self).items()

def itervalues(self):
''' Reimplement itervalues to allow for optional model refresh '''
self.__refresh_models__()
return super(Struct, self).itervalues()

def iterkeys(self):
''' Reimplement iterkeys to allow for optional model refresh '''
self.__refresh_models__()
return super(Struct, self).iterkeys()

def iteritems(self):
''' Reimplement iteritems to allow for optional model refresh '''
self.__refresh_models__()
return super(Struct, self).iteritems()
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit a40107d

Please sign in to comment.