Repository: holoviz/panel

Issue:
pn.template attribute not found when lazy loading panel
panel==1.3.8

As Panel takes ~2secs to import I would like to lazy load it in one of my packages. This package provides different utility functions. Only some are panel related.

Lazy loading of modules in Python is defined here https://docs.python.org/3/library/importlib.html#implementing-lazy-imports. When I use that I get an `AttributeError` because the attribute `template` is not defined on `panel`. Without lazy loading this works.

## Minimum reproducible example

`lazy_loader.py`

```python
import importlib.util
import sys

def lazy_import(name):
    spec = importlib.util.find_spec(name)
    loader = importlib.util.LazyLoader(spec.loader)
    spec.loader = loader
    module = importlib.util.module_from_spec(spec)
    sys.modules[name] = module
    loader.exec_module(module)
    return module

pn = lazy_import("panel")
# import panel as pn

def extension():
    return pn.extension()
```

`app.py`

```python
from lazy_loader import extension
import panel as pn

extension()

pn.template.FastListTemplate(title="Hello", main=["world"]).servable()
```

```bash
panel serve app.py --autoreload --index app
```

![image](https://github.com/holoviz/panel/assets/42288570/38eb6479-88ba-4e4e-a256-f817b9226ba5)
¨

```bash
AttributeError: module 'panel' has no attribute 'template'

Traceback (most recent call last):
  File "/home/jovyan/repos/aw-lib/.venv/lib/python3.11/site-packages/bokeh/application/handlers/code_runner.py", line 229, in run
    exec(self._code, module.__dict__)
  File "/home/jovyan/repos/aw-lib/app.py", line 6, in <module>
    pn.template.FastListTemplate(title="Hello", main=["world"]).servable()
    ^^^^^^^^^^^
AttributeError: module 'panel' has no attribute 'template'
```


Discussion:
What happens if you, do this?

``` python
from lazy_loader import extension, pn

extension()

pn.template.FastListTemplate(title="Hello", main=["world"]).servable()
The problem is that `template` is not imported in `__init__.py` :-) I'm working on a PR. But I need to figure out how to add test first.
> ```python
> from lazy_loader import extension, pn
> 
> extension()
> 
> pn.template.FastListTemplate(title="Hello", main=["world"]).servable()
> ```

The problem is still there.
This pytest will replicate issue

```python
import importlib.util
import sys

def lazy_import(name):
    spec = importlib.util.find_spec(name)
    loader = importlib.util.LazyLoader(spec.loader)
    spec.loader = loader
    module = importlib.util.module_from_spec(spec)
    sys.modules[name] = module
    loader.exec_module(module)
    return module

def test_pn_template():
    lazy_import("panel")
    import panel as pn
    assert hasattr(pn, "template")
```
## Additional Context: Also issue for static analysis

The cause is that `template` is not imported in `__init__`. This also means that static analysis cannot discover it and an error is highlighted like below.

![image](https://github.com/holoviz/panel/assets/42288570/6f9deace-28eb-42c0-83e9-3489d142fdef)


Resolving patch:
diff --git a/panel/__init__.py b/panel/__init__.py
--- a/panel/__init__.py
+++ b/panel/__init__.py
@@ -54,6 +54,7 @@
 from . import param  # noqa
 from . import pipeline  # noqa
 from . import reactive  # noqa
+from . import template  # noqa
 from . import viewable  # noqa
 from . import widgets  # noqa
 from .config import __version__, config, panel_extension as extension  # noqa
@@ -108,6 +109,7 @@
     "rx",
     "serve",
     "state",
+    "template",
     "viewable",
     "widgets",
     "widget"


Test patch: