autodiscover - Django-Components" > autodiscover - Django-Components" >
Skip to content

autodiscover ¤

autodiscover ¤

autodiscover(map_module: Optional[Callable[[str], str]] = None) -> List[str]

Search for component files and import them. Returns a list of module paths of imported files.

Autodiscover searches in the locations as defined by Loader.get_dirs.

You can map the module paths with map_module function. This serves as an escape hatch for when you need to use this function in tests.

Source code in src/django_components/autodiscover.py
def autodiscover(
    map_module: Optional[Callable[[str], str]] = None,
) -> List[str]:
    """
    Search for component files and import them. Returns a list of module
    paths of imported files.

    Autodiscover searches in the locations as defined by `Loader.get_dirs`.

    You can map the module paths with `map_module` function. This serves
    as an escape hatch for when you need to use this function in tests.
    """
    dirs = get_dirs(include_apps=False)
    component_filepaths = search_dirs(dirs, "**/*.py")
    logger.debug(f"Autodiscover found {len(component_filepaths)} files in component directories.")

    if hasattr(settings, "BASE_DIR") and settings.BASE_DIR:
        project_root = str(settings.BASE_DIR)
    else:
        # Fallback for getting the root dir, see https://stackoverflow.com/a/16413955/9788634
        project_root = os.path.abspath(os.path.dirname(__name__))

    modules: List[str] = []

    # We handle dirs from `COMPONENTS.dirs` and from individual apps separately.
    #
    # Because for dirs in `COMPONENTS.dirs`, we assume they will be nested under `BASE_DIR`,
    # and that `BASE_DIR` is the current working dir (CWD). So the path relatively to `BASE_DIR`
    # is ALSO the python import path.
    for filepath in component_filepaths:
        module_path = _filepath_to_python_module(filepath, project_root, None)
        # Ignore files starting with dot `.` or files in dirs that start with dot.
        #
        # If any of the parts of the path start with a dot, e.g. the filesystem path
        # is `./abc/.def`, then this gets converted to python module as `abc..def`
        #
        # NOTE: This approach also ignores files:
        #   - with two dots in the middle (ab..cd.py)
        #   - an extra dot at the end (abcd..py)
        #   - files outside of the parent component (../abcd.py).
        # But all these are NOT valid python modules so that's fine.
        if ".." in module_path:
            continue

        modules.append(module_path)

    # For for apps, the directories may be outside of the project, e.g. in case of third party
    # apps. So we have to resolve the python import path relative to the package name / the root
    # import path for the app.
    # See https://github.com/EmilStenstrom/django-components/issues/669
    for conf in apps.get_app_configs():
        for app_dir in app_settings.APP_DIRS:
            comps_path = Path(conf.path).joinpath(app_dir)
            if not comps_path.exists():
                continue
            app_component_filepaths = search_dirs([comps_path], "**/*.py")
            for filepath in app_component_filepaths:
                app_component_module = _filepath_to_python_module(filepath, conf.path, conf.name)
                modules.append(app_component_module)

    return _import_modules(modules, map_module)

import_libraries ¤

import_libraries(map_module: Optional[Callable[[str], str]] = None) -> List[str]

Import modules set in COMPONENTS.libraries setting.

You can map the module paths with map_module function. This serves as an escape hatch for when you need to use this function in tests.

Source code in src/django_components/autodiscover.py
def import_libraries(
    map_module: Optional[Callable[[str], str]] = None,
) -> List[str]:
    """
    Import modules set in `COMPONENTS.libraries` setting.

    You can map the module paths with `map_module` function. This serves
    as an escape hatch for when you need to use this function in tests.
    """
    from django_components.app_settings import app_settings

    return _import_modules(app_settings.LIBRARIES, map_module)

search_dirs ¤

search_dirs(dirs: List[Path], search_glob: str) -> List[Path]

Search the directories for the given glob pattern. Glob search results are returned as a flattened list.

Source code in src/django_components/autodiscover.py
def search_dirs(dirs: List[Path], search_glob: str) -> List[Path]:
    """
    Search the directories for the given glob pattern. Glob search results are returned
    as a flattened list.
    """
    matched_files: List[Path] = []
    for directory in dirs:
        for path in glob.iglob(str(Path(directory) / search_glob), recursive=True):
            matched_files.append(Path(path))

    return matched_files