Skip to content

Commit

Permalink
Ianhelle/lazy-import-init-2023-09-26 (#717)
Browse files Browse the repository at this point in the history
* Switch init py modules to use lazy import function.

* Fixed doc string in lazy importer

* Fixing recursive import bug

* Fixing pylint and mypy errors

* Minor refactor of nbinit to clean up main init_notebook function

* removing commented out code
  • Loading branch information
ianhelle committed Oct 6, 2023
1 parent df22c8b commit 7ad1280
Show file tree
Hide file tree
Showing 30 changed files with 372 additions and 288 deletions.
81 changes: 18 additions & 63 deletions msticpy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@
)
from .common.utility import search_name as search
from .init.logging import set_logging_level, setup_logging
from .lazy_importer import lazy_import

__version__ = VERSION
__author__ = "Ian Hellen, Pete Bryan, Ashwin Patil"
Expand All @@ -144,71 +145,25 @@
if not os.environ.get("KQLMAGIC_EXTRAS_REQUIRES"):
os.environ["KQLMAGIC_EXTRAS_REQUIRES"] = "jupyter-basic"

_STATIC_ATTRIBS = list(locals().keys())

_DEFAULT_IMPORTS = {
"az_connect": "msticpy.auth.azure_auth",
"current_providers": "msticpy.init.nbinit",
"ContextLookup": "msticpy.context.contextlookup",
"GeoLiteLookup": "msticpy.context.geoip",
"init_notebook": "msticpy.init.nbinit",
"reset_ipython_exception_handler": "msticpy.init.nbinit",
"MicrosoftSentinel": "msticpy.context.azure",
"MpConfigEdit": "msticpy.config.mp_config_edit",
"MpConfigFile": "msticpy.config.mp_config_file",
"QueryProvider": "msticpy.data",
"TILookup": "msticpy.context.tilookup",
"TimeSpan": "msticpy.common.timespan",
"WorkspaceConfig": "msticpy.common.wsconfig",
"entities": "msticpy.datamodel",
"Pivot": "msticpy.init.pivot",
_LAZY_IMPORTS = {
"msticpy.auth.azure_auth.az_connect",
"msticpy.common.timespan.TimeSpan",
"msticpy.common.wsconfig.WorkspaceConfig",
"msticpy.config.mp_config_edit.MpConfigEdit",
"msticpy.config.mp_config_file.MpConfigFile",
"msticpy.context.azure.MicrosoftSentinel",
"msticpy.context.contextlookup.ContextLookup",
"msticpy.context.geoip.GeoLiteLookup",
"msticpy.context.tilookup.TILookup",
"msticpy.data.QueryProvider",
"msticpy.datamodel.entities",
"msticpy.init.nbinit.current_providers",
"msticpy.init.nbinit.init_notebook",
"msticpy.init.nbinit.reset_ipython_exception_handler",
"msticpy.init.pivot.Pivot",
}


def __getattr__(attrib: str) -> Any:
"""
Import and return an attribute of MSTICPy.
Parameters
----------
attrib : str
The attribute name
Returns
-------
Any
The attribute value.
Raises
------
AttributeError
No attribute found.
"""
if attrib in _DEFAULT_IMPORTS:
try:
return getattr(importlib.import_module(_DEFAULT_IMPORTS[attrib]), attrib)
except (MsticpyImportExtraError, MsticpyImportExtraError):
raise
except (ImportError, MsticpyException) as err:
warnings.warn(f"Unable to import module for 'msticpy.{attrib}'")
print(
f"WARNING. The msticpy attribute '{attrib}' is not loadable.",
"You may need to install one or more additional dependencies.\n",
"Please check the exception details below for more information.",
"\n".join(
traceback.format_exception(
type(err), value=err, tb=err.__traceback__
)
),
)
raise AttributeError(f"msticpy failed to load '{attrib}'") from err
raise AttributeError(f"msticpy has no attribute '{attrib}'")


def __dir__():
"""Return attribute list."""
return sorted(set(_STATIC_ATTRIBS + list(_DEFAULT_IMPORTS)))
module, __getattr__, __dir__ = lazy_import(__name__, _LAZY_IMPORTS)


def load_plugins(plugin_paths: Union[str, Iterable[str]]):
Expand Down
2 changes: 1 addition & 1 deletion msticpy/common/utility/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ def init_dir(static_attribs: List[str], dynamic_imports: Dict[str, str]):
return sorted(set(static_attribs + list(dynamic_imports)))


def lazy_import(module: str, attrib: str, call: bool = False):
def delayed_import(module: str, attrib: str, call: bool = False):
"""Import attribute from module on demand."""
attribute = None

Expand Down
21 changes: 6 additions & 15 deletions msticpy/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,12 @@
It use the ipywidgets package.
"""
from ..common.utility.package import init_dir, init_getattr
from ..lazy_importer import lazy_import

_STATIC_ATTRIBS = list(locals().keys())
_DEFAULT_IMPORTS = {
"MpConfigControls": "msticpy.config.mp_config_control",
"MpConfigEdit": "msticpy.config.mp_config_edit",
"MpConfigFile": "msticpy.config.mp_config_file",
_LAZY_IMPORTS = {
"msticpy.config.mp_config_control.MpConfigControls",
"msticpy.config.mp_config_edit.MpConfigEdit",
"msticpy.config.mp_config_file.MpConfigFile",
}


def __getattr__(attrib: str):
"""Import and a dynamic attribute of module."""
return init_getattr(__name__, _DEFAULT_IMPORTS, attrib)


def __dir__():
"""Return attribute list."""
return init_dir(_STATIC_ATTRIBS, _DEFAULT_IMPORTS)
module, __getattr__, __dir__ = lazy_import(__name__, _LAZY_IMPORTS)
4 changes: 2 additions & 2 deletions msticpy/config/ce_azure_sentinel.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import ipywidgets as widgets

from .._version import VERSION
from ..common.utility.package import lazy_import
from ..common.utility.package import delayed_import

# from ..context.azure.sentinel_core import MicrosoftSentinel
from .ce_common import (
Expand All @@ -24,7 +24,7 @@
__version__ = VERSION
__author__ = "Ian Hellen"

ms_sentinel = lazy_import("msticpy.context.azure.sentinel_core", "MicrosoftSentinel")
ms_sentinel = delayed_import("msticpy.context.azure.sentinel_core", "MicrosoftSentinel")


# pylint: disable=too-many-ancestors
Expand Down
3 changes: 2 additions & 1 deletion msticpy/config/ce_user_defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ def __init__(self, mp_controls: MpConfigControls):
"""
super().__init__(mp_controls)
from ..data import DataEnvironment # pylint: disable=import-outside-toplevel
# pylint: disable=import-outside-toplevel
from ..data.core.query_defns import DataEnvironment

self._data_env_enum = DataEnvironment

Expand Down
11 changes: 4 additions & 7 deletions msticpy/config/mp_config_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,13 @@
except ImportError:
_KEYVAULT = False

try:
from ..context.azure.sentinel_core import MicrosoftSentinel

_SENTINEL = True
except ImportError:
_SENTINEL = False
from ..common.pkg_config import current_config_path, refresh_config, validate_config
from ..common.utility.package import delayed_import
from .comp_edit import CompEditDisplayMixin, CompEditStatusMixin
from .file_browser import FileBrowser

ms_sentinel = delayed_import("msticpy.context.azure.sentinel_core", "MicrosoftSentinel")

__version__ = VERSION
__author__ = "Ian Hellen"

Expand Down Expand Up @@ -306,7 +303,7 @@ def get_workspace_from_url(url: str) -> Dict[str, Dict[str, str]]:
workspace.
"""
return MicrosoftSentinel.get_workspace_details_from_url(url)
return ms_sentinel().get_workspace_details_from_url(url)

def _show_sentinel_workspace(self, show: bool = True):
"""Fetch settings from Sentinel Portal URL."""
Expand Down
13 changes: 10 additions & 3 deletions msticpy/context/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@
"""Context Providers Subpackage."""
from typing import Any

# flake8: noqa: F403
from ..common.utility import ImportPlaceholder
from .geoip import GeoLiteLookup, IPStackLookup
from .tilookup import TILookup
from ..lazy_importer import lazy_import
from .vtlookupv3 import VT3_AVAILABLE

vtlookupv3: Any
Expand All @@ -20,3 +18,12 @@
vtlookupv3 = ImportPlaceholder( # type: ignore
"vtlookupv3", ["vt-py", "vt-graph-api", "nest_asyncio"]
)


_LAZY_IMPORTS = {
"msticpy.context.geoip.GeoLiteLookup",
"msticpy.context.geoip.IPStackLookup",
"msticpy.context.tilookup.TILookup",
}

module, __getattr__, __dir__ = lazy_import(__name__, _LAZY_IMPORTS)
11 changes: 8 additions & 3 deletions msticpy/context/azure/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
# --------------------------------------------------------------------------
"""Data provider sub-package."""

# flake8: noqa: F401
from .azure_data import AzureData
from .sentinel_core import MicrosoftSentinel
from ...lazy_importer import lazy_import

_LAZY_IMPORTS = {
"msticpy.context.azure.azure_data.AzureData",
"msticpy.context.azure.sentinel_core.MicrosoftSentinel",
}

module, __getattr__, __dir__ = lazy_import(__name__, _LAZY_IMPORTS)
2 changes: 1 addition & 1 deletion msticpy/context/azure/sentinel_dynamic_summary.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from ..._version import VERSION
from ...common.exceptions import MsticpyAzureConnectionError, MsticpyParameterError
from ...common.pkg_config import get_config, get_http_timeout
from ...data import QueryProvider
from ...data.core.data_providers import QueryProvider
from .azure_data import get_api_headers

# pylint: disable=unused-import
Expand Down
2 changes: 1 addition & 1 deletion msticpy/context/azure/sentinel_workspaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from ...common.data_utils import df_has_data
from ...common.pkg_config import get_http_timeout
from ...common.utility import mp_ua_header
from ...data import QueryProvider
from ...data.core.data_providers import QueryProvider

__version__ = VERSION
__author__ = "Ian Hellen"
Expand Down
2 changes: 1 addition & 1 deletion msticpy/context/tiproviders/kql_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from ...common.exceptions import MsticpyConfigError
from ...common.utility import export
from ...common.wsconfig import WorkspaceConfig
from ...data import QueryProvider
from ...data.core.data_providers import QueryProvider
from ..lookup_result import LookupStatus
from ..provider_base import generate_items
from .ti_provider_base import ResultSeverity, TIProvider
Expand Down
10 changes: 5 additions & 5 deletions msticpy/context/tiproviders/open_page_rank.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@

@export
class OPR(HttpTIProvider):
"""Open PageRank Lookup."""
"""
Open PageRank Lookup.
See https://www.domcop.com/openpagerank/what-is-openpagerank
"""

_BASE_URL = "https://openpagerank.com"

Expand All @@ -50,10 +54,6 @@ def __init__(self, **kwargs):
super().__init__(**kwargs)

self._provider_name = self.__class__.__name__
print(
"Using Open PageRank.",
"See https://www.domcop.com/openpagerank/what-is-openpagerank",
)

async def lookup_iocs_async(
self,
Expand Down
14 changes: 10 additions & 4 deletions msticpy/data/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,16 @@
"""
from .._version import VERSION
from ..common.exceptions import MsticpyImportExtraError

# flake8: noqa: F403
from .core.data_providers import QueryProvider
from .core.query_defns import DataEnvironment, DataFamily
# from ..common.exceptions import MsticpyImportExtraError
from ..lazy_importer import lazy_import

__version__ = VERSION

_LAZY_IMPORTS = {
"msticpy.data.core.data_providers.QueryProvider",
"msticpy.data.core.query_defns.DataEnvironment",
"msticpy.data.core.query_defns.DataFamily",
}

module, __getattr__, __dir__ = lazy_import(__name__, _LAZY_IMPORTS)
2 changes: 1 addition & 1 deletion msticpy/data/azure_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

# flake8: noqa: F403, F401
# pylint: disable=unused-import
from ..context.azure import AzureData
from ..context.azure.azure_data import AzureData

WARN_MSSG = (
"This module has moved to msticpy.context.azure.azure_data\n"
Expand Down
2 changes: 1 addition & 1 deletion msticpy/data/core/data_providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from ..._version import VERSION
from ...common.pkg_config import get_config
from ...common.utility import export, valid_pyname
from ...nbwidgets import QueryTime
from ...nbwidgets.query_time import QueryTime
from .. import drivers
from ..drivers.driver_base import DriverBase, DriverProps
from .param_extractor import extract_query_params
Expand Down
4 changes: 2 additions & 2 deletions msticpy/data/core/query_provider_utils_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from typing import Dict, Iterable, List, NamedTuple, Optional, Pattern, Protocol, Union

from ..._version import VERSION
from ...common.utility.package import lazy_import
from ...common.utility.package import delayed_import
from ..drivers.driver_base import DriverBase
from .query_defns import DataEnvironment
from .query_source import QuerySource
Expand All @@ -18,7 +18,7 @@
__version__ = VERSION
__author__ = "Ian Hellen"

query_browser = lazy_import("msticpy.vis.query_browser", "browse_queries")
query_browser = delayed_import("msticpy.vis.query_browser", "browse_queries")


# pylint: disable=too-few-public-methods
Expand Down

0 comments on commit 7ad1280

Please sign in to comment.