Răsfoiți Sursa

Merge pull request #786 from Avaiga/feature/make-dependencies-optional

feat: make pymongo, boto and fastparquet optional packages
João André 1 an în urmă
părinte
comite
7f9ff08492

+ 31 - 0
taipy/core/common/_check_dependencies.py

@@ -0,0 +1,31 @@
+# Copyright 2021-2024 Avaiga Private Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+from importlib import util
+
+
+def _check_dependency_is_installed(module_name: str, package_name: str) -> None:
+    """
+        Check if a package is installed.
+
+        Args:
+            module_name: Name of the taipy module importing the package.
+            package_name: Name of the package.
+    .
+    """
+    extras = {
+        "boto3": "s3",
+        "pymongo": "mongo",
+    }
+    if not util.find_spec(package_name):
+        raise RuntimeError(
+            f"Cannot use {module_name} as {package_name} package is not installed. Please install it  "
+            f"using `pip install taipy[{extras.get(package_name)}]`."
+        )

+ 7 - 2
taipy/core/data/aws_s3.py

@@ -10,9 +10,13 @@
 # specific language governing permissions and limitations under the License.
 # specific language governing permissions and limitations under the License.
 
 
 from datetime import datetime, timedelta
 from datetime import datetime, timedelta
+from importlib import util
 from typing import Any, Dict, List, Optional, Set
 from typing import Any, Dict, List, Optional, Set
 
 
-import boto3
+from ..common._check_dependencies import _check_dependency_is_installed
+
+if util.find_spec("boto3"):
+    import boto3
 
 
 from taipy.config.common.scope import Scope
 from taipy.config.common.scope import Scope
 
 
@@ -94,6 +98,7 @@ class S3ObjectDataNode(DataNode):
         editor_expiration_date: Optional[datetime] = None,
         editor_expiration_date: Optional[datetime] = None,
         properties: Optional[Dict] = None,
         properties: Optional[Dict] = None,
     ):
     ):
+        _check_dependency_is_installed("S3 Data Node", "boto3")
         if properties is None:
         if properties is None:
             properties = {}
             properties = {}
         required = self._REQUIRED_PROPERTIES
         required = self._REQUIRED_PROPERTIES
@@ -123,7 +128,7 @@ class S3ObjectDataNode(DataNode):
             aws_secret_access_key=properties.get(self.__AWS_SECRET_ACCESS_KEY),
             aws_secret_access_key=properties.get(self.__AWS_SECRET_ACCESS_KEY),
         )
         )
 
 
-        if not self._last_edit_date:
+        if not self._last_edit_date:  # type: ignore
             self._last_edit_date = datetime.now()
             self._last_edit_date = datetime.now()
 
 
         self._TAIPY_PROPERTIES.update(
         self._TAIPY_PROPERTIES.update(

+ 8 - 2
taipy/core/data/mongo.py

@@ -10,13 +10,18 @@
 # specific language governing permissions and limitations under the License.
 # specific language governing permissions and limitations under the License.
 
 
 from datetime import datetime, timedelta
 from datetime import datetime, timedelta
+from importlib import util
 from inspect import isclass
 from inspect import isclass
 from typing import Any, Dict, List, Optional, Set, Tuple, Union
 from typing import Any, Dict, List, Optional, Set, Tuple, Union
 
 
 from taipy.config.common.scope import Scope
 from taipy.config.common.scope import Scope
 
 
 from .._version._version_manager_factory import _VersionManagerFactory
 from .._version._version_manager_factory import _VersionManagerFactory
-from ..common._mongo_connector import _connect_mongodb
+from ..common._check_dependencies import _check_dependency_is_installed
+
+if util.find_spec("pymongo"):
+    from ..common._mongo_connector import _connect_mongodb
+
 from ..data.operator import JoinOperator, Operator
 from ..data.operator import JoinOperator, Operator
 from ..exceptions.exceptions import InvalidCustomDocument, MissingRequiredProperty
 from ..exceptions.exceptions import InvalidCustomDocument, MissingRequiredProperty
 from .data_node import DataNode
 from .data_node import DataNode
@@ -99,6 +104,7 @@ class MongoCollectionDataNode(DataNode):
         editor_expiration_date: Optional[datetime] = None,
         editor_expiration_date: Optional[datetime] = None,
         properties: Dict = None,
         properties: Dict = None,
     ):
     ):
+        _check_dependency_is_installed("Mongo Data Node", "pymongo")
         if properties is None:
         if properties is None:
             properties = {}
             properties = {}
         required = self._REQUIRED_PROPERTIES
         required = self._REQUIRED_PROPERTIES
@@ -149,7 +155,7 @@ class MongoCollectionDataNode(DataNode):
         if callable(custom_encoder):
         if callable(custom_encoder):
             self._encoder = custom_encoder
             self._encoder = custom_encoder
 
 
-        if not self._last_edit_date:
+        if not self._last_edit_date:  # type: ignore
             self._last_edit_date = datetime.now()
             self._last_edit_date = datetime.now()
 
 
         self._TAIPY_PROPERTIES.update(
         self._TAIPY_PROPERTIES.update(

+ 3 - 0
taipy/core/setup.py

@@ -45,6 +45,9 @@ extras_require = {
     "mssql": ["pyodbc>=4,<4.1"],
     "mssql": ["pyodbc>=4,<4.1"],
     "mysql": ["pymysql>1,<1.1"],
     "mysql": ["pymysql>1,<1.1"],
     "postgresql": ["psycopg2>2.9,<2.10"],
     "postgresql": ["psycopg2>2.9,<2.10"],
+    "parquet": ["fastparquet==2022.11.0"],
+    "s3": ["boto3==1.29.1"],
+    "mongo": ["pymongo[srv]>=4.2.0,<5.0"],
 }
 }
 
 
 setup(
 setup(