Skip to content

Instantly share code, notes, and snippets.

@ashcrow
Last active February 6, 2017 20:51
Show Gist options
  • Save ashcrow/7a615eda9976188e8a1e902f9506be4c to your computer and use it in GitHub Desktop.
Save ashcrow/7a615eda9976188e8a1e902f9506be4c to your computer and use it in GitHub Desktop.
import os # for listing files
import sys # for finding current location
import importlib # Used to dynamically import modules
# object subclasses for 2.x support
# Path to the importable code. This is important when loading
# code from a directory. We need to know where the files will be located.
MODULE_PATH = os.path.sep.join([
os.path.dirname(os.path.abspath(
sys.modules[__name__].__file__)), 'client'])
class Project(object):
"""
Common stuff for project instances would be defined here.
"""
def common(self):
"""
Example function common between all versions.
"""
return "operations defined in this object"
class Openshift(object):
"""
Expected singleton instance. (IE: from project import openshift)
"""
def __getattribute__(self, name):
"""
Hook for instance.v#
"""
if name.startswith('v'):
return self._create_project(name)
else:
return object.__getattribute__(self, name)
def _create_project(self, version):
"""
Creates a project instance based off of the version provided. This
method lists the MODULE_DIR for files, imports the versioned items
and hangs them on a Project. It then returns an instance of the
versioned Project.
"""
internal_dict = {} # Holds the internal __dict__ for the new instance
for fname in os.listdir(MODULE_PATH): # list the client directory
# If it's python code and the file starts with the right version
if fname.endswith('.py') and fname.startswith(version):
# generate the right names, load the module and pull the
# callable off it. Then map it in the internal __dict__
name = fname.replace('{}_'.format(version), '')[:-3]
mod_name = '{}.client.{}'.format(__name__, fname[:-3])
mod = importlib.import_module(mod_name)
internal_dict[name] = getattr(mod, name)
# If we have data to inject into __dict__ it should be a valid
# versioned instance.
if len(internal_dict) > 0:
return type(
version.capitalize() + 'Project',
(Project, ),
internal_dict)
# Otherwise raise
raise Exception('That version does not exist ya dingus!')
#: Global instance
openshift = Openshift()

This is an example of loading code and dynamically creating a class based on the version requested.

Structure

project/init.py # in gist project/client/init.py # EMPTY project/client/v1_test.py # in gist project/client/v2_test.py # in gist

Example Output/Usage

In [1]: from project import openshift

In [3]: openshift.v1().common()
Out[3]: 'operations defined in this object'

In [4]: openshift.v2().common()
Out[4]: 'operations defined in this object'

In [5]: openshift.v1().test('hi')
Out[5]: 'v1 hi'

In [6]: openshift.v2().test('hi')
Out[6]: 'v2 hi'

In [7]: v2 = openshift.v2()

In [8]: v1 = openshift.v1()

In [9]: v2.test('2')
Out[9]: 'v2 2'

In [10]: v1.test('1')
Out[10]: 'v1 1'
# project/client/v1_test.py
def test(self, data):
return "v1 " + str(data)
# project/client/v2_test.py
def test(self, data):
return "v2 " + str(data)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment