Repository: FlexMeasures/flexmeasures (language: python)

Issue:
Plugins can import most commonly used FlexMeasures classes from a central place
Expose our most commonly used classes in a more central place, like: `from flexmeasures import Sensor`, similar to how we do it in https://github.com/SeitaBV/timely-beliefs/blob/main/timely_beliefs/__init__.py. We can then recommend plugins to import classes like that, and give ourselves some more flexibility in refactoring the location of each class (or even its name, which may be useful for renaming the `GenericAsset` class later).

_Originally posted by @Flix6x in https://github.com/FlexMeasures/flexmeasures/pull/343#discussion_r797391858_

> What are the crucial models?

- Sensor
- Asset (-> GenericAsset)
- DataSource
- User
- Account

_Originally posted by @nhoening in https://github.com/FlexMeasures/flexmeasures/pull/343#discussion_r797410773_

I'd add AccountRole to that list, for service plugins.


Discussion / hints:

Fix patch:
diff --git a/documentation/changelog.rst b/documentation/changelog.rst
index 1f0e990b5..bd5b4bcf0 100644
--- a/documentation/changelog.rst
+++ b/documentation/changelog.rst
@@ -20,6 +20,7 @@ Bugfixes
 
 Infrastructure / Support
 ----------------------
+* Plugins can import common FlexMeasures classes (like ``Asset`` and ``Sensor``) from a central place, using ``from flexmeasures import Asset, Sensor`` [see `PR #354 <http://www.github.com/FlexMeasures/flexmeasures/pull/354>`_]
 
 
 v0.8.0 | January 24, 2022
diff --git a/flexmeasures/__init__.py b/flexmeasures/__init__.py
index 52dea79f6..1322fb24f 100644
--- a/flexmeasures/__init__.py
+++ b/flexmeasures/__init__.py
@@ -1,5 +1,14 @@
 from importlib_metadata import version, PackageNotFoundError
 
+from flexmeasures.data.models.annotations import Annotation  # noqa F401
+from flexmeasures.data.models.user import Account, AccountRole, User  # noqa F401
+from flexmeasures.data.models.data_sources import DataSource as Source  # noqa F401
+from flexmeasures.data.models.generic_assets import (  # noqa F401
+    GenericAsset as Asset,
+    GenericAssetType as AssetType,
+)
+from flexmeasures.data.models.time_series import Sensor  # noqa F401
+
 
 __version__ = "Unknown"
 
diff --git a/flexmeasures/config/__init__.py b/flexmeasures/config/__init__.py
new file mode 100644
index 000000000..e69de29bb


Test patch:
diff --git a/flexmeasures/config/tests/__init__.py b/flexmeasures/config/tests/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/flexmeasures/config/tests/test_package.py b/flexmeasures/config/tests/test_package.py
new file mode 100644
index 000000000..5c8b5facd
--- /dev/null
+++ b/flexmeasures/config/tests/test_package.py
@@ -0,0 +1,19 @@
+import pytest
+
+
+@pytest.mark.parametrize(
+    "class_name",
+    [
+        "Account",
+        "AccountRole",
+        "Asset",
+        "Sensor",
+        "Source",
+        "User",
+    ],
+)
+def test_class_imports(class_name: str):
+    """Make sure that plugins can import these classes as `from flexmeasures import <class_name>`."""
+    import flexmeasures as fm
+
+    assert hasattr(fm, class_name)