Skip to main content

Python Autoload Module

Project description

autoload_module

PyPI version Test Downloads MIT License image

This library will give you comfortable Python metaprogramming.
The following is a plain example.

  • Directory
project/
 ├ example.py
 └ validator/
   ├ validator_a.py
   ├ validator_b.py
   └ validator_c.py
  • example.py
from autoload import ModuleLoader

input = "foo bar baz"
loader = ModuleLoader()

# Automatically import modules and return class objects
validator_classes = loader.load_classes("validator")
try:
    # initialize and execute method
    [clazz().validate(input) for clazz in validator_classes]
except:
    print("input is invalid!!")

Install

pip install autoload-module

Usage

Constructor

ModuleLoader(
  base_path: Optional[str] = None,
  strict: bool = False
)

The ModuleLoader can be generated with no parameters. In that case, the instance has the absolute path where it was initialized.

  • Directory
/usr/local/src/project/
  ├ example.py
  └ validator/
    ├ validator_a.py
    ├ validator_b.py
    └ validator_c.py
  • example.py
from autoload import ModuleLoader

# The instance has '/usr/local/src/project/'
loader = ModuleLoader()

# load modules in the directory; '/usr/local/src/project/validator/'
validator_classes = loader.load_classes("validator")

If you want to change the base path, you must generate the ModuleLoader with an absolute path parameter.

loader = ModuleLoader('/user/local/src/custom')

About strict parameter, please see here .

You can also create global setting and initialize singleton object.

from autoload import ModuleLoader
import os

# global setting
ModuleLoader.set_setting(base_path=os.getcwd(), strict=True)

loader_a = ModuleLoader()
loader_b = ModuleLoader()

print(loader_a.base_path)
# -> /Users/user1/abc
print(loader_b.base_path)
# -> /Users/user1/abc

# singleton setting
ModuleLoader.set_setting(singleton=True)

loader_c = ModuleLoader()
loader_d = ModuleLoader()
loader_e = ModuleLoader('/test')

assert loader_c is loader_d # OK
assert loader_c is loader_e # OK

# The base_path is '/Users/user1/abc'
assert loader_c.base_path is loader_e.base_path # OK

Methods

load_classes

load_classes(
    src: str,
    excludes: Iterable[str] = (),
    recursive: bool = False,
) -> Tuple[Type, ...]:

This method read the Python package or module and return the tuple of class objects.

  • Directory
pkg/
 ├ example.py
 ├ __init__.py
 ├ config.yaml
 └ main/
     ├ validator_a.py
     ├ validator_b.py
     ├ validator_c.py
     └ sub/
        ├ validator_d.py
        └ validator_e.py
  • validator_a.py
class ValidatorA:
    def validate(self):
        print("validateA!!")
  • example.py
loader = ModuleLoader()

# Automatically read modules without '__init__.py', not py file, and this file.
# return the tuple of ValidateA, ValidatorB, and ValidatorC class objects
validator_classes = loader.load_classes("main")

# initialize and execute method
[clazz().validate() for clazz in validator_classes]
# -> validateA!!
# -> validateB!!
# -> validateC!!

You can also load only specific modules using excludes variable or load_config decorator as below.

# Pattern1: 'excludes'
# 'excludes' is a iterable object like tuple, list.
# You must specify module names in 'excludes'.
validator_classes = loader.load_classes("main", ["validator_a"])

[clazz().validate() for clazz in validator_classes]
# -> validateB!!
# -> validateC!!

# Pattern2: 'load_config'
from autoload import load_config

@load_config(load=False)
class ValidatorA:
  def validate(self):
    print("validateA!!")

validator_classes = loader.load_classes("main")

[clazz().validate() for clazz in validator_classes]
# -> validateB!!
# -> validateC!!

This function will check directory structure recursively if you specify recursive=True.

# 'recursive=False' is default.
# In this case, the loader will also check 'pkg/main/sub/'.
validator_classes = loader.load_classes("main", recursive=True)

[clazz().validate() for clazz in validator_classes]
# -> validateA!!
# -> validateB!!
# -> validateC!!
# -> validateD!!
# -> validateE!!

You can specify src as below.

loader.load_classes("main/validator_a.py")
loader.load_classes("main.validator_a")
loader.load_classes("./main/validator_a")
loader.load_classes(".main.validator_a")
loader.load_classes("main.sub.validator_d")
loader.load_classes("./main/sub/validator_d")
loader.load_classes("../otherpkg")
loader.load_classes("..otherpkg")

load_functions

load_functions(
    src: str,
    excludes: Iterable[str] = (),
    recursive: bool = False,
) -> Tuple[Callable, ...]:

This method read the Python package or module and return the tuple of functions. The usage is the same as load_classes.

NOTE
  • To search class or function, You must match the name of file, and the one of class or function. For example, if you named the file test_module.py, you must name the class TestModule or the function test_module. When you want to customize their name, use @load_config decorator.

    • validator_a.py
    from autoload import load_config
    
    @load_config()
    class CustomValidator:
        def validate(self):
            print("validateA!!")
    
  • You can also control the order of loaded class objects using @load_config decorator.

    • validator_a.py
    from autoload import load_config
    
    # sort in ascending order
    @load_config(order=1)
    class ValidatorA:
        def validate(self):
            print("validateA!!")
    
  • If you decorate some classes or functions with @load_config, the loader will load them. However, initialized strict=True, the loader denies multiple loading as below.

    • pkg/validator_a.py
    from autoload import load_config
    
    # This will be loaded because of name's rule.
    class ValidatorA:
      def validate(self):
          print("validateA!!")
    
    # Anything goes.
    @load_config(order=2)
    class Foo:
      pass
    
    • main.py
    from autoload import ModuleLoader
    from autoload.exception import LoaderStrictModeError
    
    loader = ModuleLoader()
    # return ValidatorA and Foo class objects.
    classes = loader.load_classes("pkg")
    
    # ModuleLoader strictly try to load a class or function object
    # per a Python module on a basis of its name.
    strict_loader = ModuleLoader(strict=True)
    try:
      classes = strict_loader.load_classes("pkg")
    except LoaderStrictModeError as e:
      print(e)
    # -> Loader can only load a 'ValidatorA' class in validator_a module.
    # -> Please check 'Foo' in validator_a module.
    

load_class

load_class(file_name: str)

This method read the Python file and return the class object.

  • Directory
project/
  ├ example.py
  └ validator.py
  • validator.py
class Validator:
    def validate(self):
        print("validate!!")
  • example.py
loader = ModuleLoader()
clazz = loader.load_class("validator")
clazz().validate()
# -> validate!!

How to specify file_name is the same as that of load_classes.

load_function

load_function(file_name: str)

This method read the Python file and return a function object. The usage is the same as load_class.

License

Released under the MIT license.

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

autoload_module-2.0.0.tar.gz (10.1 kB view details)

Uploaded Source

Built Distribution

autoload_module-2.0.0-py3-none-any.whl (10.4 kB view details)

Uploaded Python 3

File details

Details for the file autoload_module-2.0.0.tar.gz.

File metadata

  • Download URL: autoload_module-2.0.0.tar.gz
  • Upload date:
  • Size: 10.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.5.1 CPython/3.10.6 Linux/5.15.0-1039-azure

File hashes

Hashes for autoload_module-2.0.0.tar.gz
Algorithm Hash digest
SHA256 d911d5a11aee02bb09ad7c0966458b8a215ebd657c788779097db7195e21d865
MD5 1d72cb5f3a26467f59d54976f82503c2
BLAKE2b-256 d2c7e23a010c86b0072ee801d093fc7d72a87dac1be6f36834c0412f8bbb7009

See more details on using hashes here.

File details

Details for the file autoload_module-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: autoload_module-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 10.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.5.1 CPython/3.10.6 Linux/5.15.0-1039-azure

File hashes

Hashes for autoload_module-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b26e25c2b4981926669909571bbb92aa64cb96cec90d5f41af7513647be63203
MD5 879d969cc5316b6836f6081d27a4a3be
BLAKE2b-256 aca2a83984002c05196eab9eb6be6228ad040427a3d098f3e0b0dd1880fb29b4

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