From 65d0e1bbbadb1168f4c12ab89702d1099c3f306d Mon Sep 17 00:00:00 2001 From: Patrik Spiess Date: Wed, 1 Apr 2026 15:01:31 +0200 Subject: [PATCH 1/7] =?UTF-8?q?=F0=9F=94=87=20Remove=20confusing=20debug?= =?UTF-8?q?=20log?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fotoobo/fortinet/fortimanager.py | 1 - 1 file changed, 1 deletion(-) diff --git a/fotoobo/fortinet/fortimanager.py b/fotoobo/fortinet/fortimanager.py index 8d65c2f..b9be3be 100644 --- a/fotoobo/fortinet/fortimanager.py +++ b/fotoobo/fortinet/fortimanager.py @@ -818,7 +818,6 @@ def login(self) -> int: response = super().api("post", payload=payload) if response.status_code == 200: if "session" in response.json(): - log.debug("Storing session key") self.session_key = response.json()["session"] if self.session_path: From a0223e079b2937633fc52529c59f91ec285a59a4 Mon Sep 17 00:00:00 2001 From: Patrik Spiess Date: Sat, 4 Apr 2026 15:32:08 +0200 Subject: [PATCH 2/7] =?UTF-8?q?=F0=9F=93=9D=20Update=20documentation=20on?= =?UTF-8?q?=20how=20to=20use=20fotoobo=20as=20library?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- WHATSNEW.md | 2 + docs/source/usage/configuration.rst | 2 +- docs/source/usage/import_fotoobo.rst | 64 ++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/WHATSNEW.md b/WHATSNEW.md index 6b5dca8..d6e3080 100644 --- a/WHATSNEW.md +++ b/WHATSNEW.md @@ -1,5 +1,7 @@ ### Added +- Add more examples on how to use imported fotoobo + ### Changed ### Removed diff --git a/docs/source/usage/configuration.rst b/docs/source/usage/configuration.rst index b3c56a2..d6d7c50 100644 --- a/docs/source/usage/configuration.rst +++ b/docs/source/usage/configuration.rst @@ -74,7 +74,7 @@ Logging NOTE: The settings here apply the same to normal logging and audit logging. -If you configure a logging setting it is automatically enabled. Otherwise defaut logging will be +If you configure a logging setting it is automatically enabled. Otherwise default logging will be used. Default logging is set to log to **console** with log-level **WARNING**. .. _logging_level: diff --git a/docs/source/usage/import_fotoobo.rst b/docs/source/usage/import_fotoobo.rst index 5ad2bd6..a01f89b 100644 --- a/docs/source/usage/import_fotoobo.rst +++ b/docs/source/usage/import_fotoobo.rst @@ -62,3 +62,67 @@ FortiClient EMS print(ems.get_version()) ems.logout() +Using an inventory file +^^^^^^^^^^^^^^^^^^^^^^^ + +You can maintain an :ref:`inventory file` to load the assets from. This helps not having API tokens or username/passwords directly in the source code. + +Imagine you created the inventory file ``~/.config/inventory.yaml``: + +.. code-block:: yaml + + fmg-test: + hostname: myfortimanager.local + username: the_fortimanager_username + password: the_fortimanager_password + type: fortimanager + +With this inventory file you can use the asset ```fmg-test`` in your code: + +.. code-block:: python + + from fotoobo.inventory import Inventory + inventory = Inventory(Path("~/.config/inventory.yaml")) + fmg = inventory.get_item("fmg-test") + print(fmg.get_version()) + + +Using a configuration file +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You can read your fotoobo :ref:`configuration file`. This is useful if you wish to load and change settings like :ref:`inventory file`, :ref:`logging options` or a :ref:`vault configuration`. + +Use the inventory file ``~/.config/inventory.yaml`` with the string ``VAULT`` as the toke or password for your assets. + +.. code-block:: yaml + + fmg-test: + hostname: myfortimanager.local + username: the_fortimanager_username + password: VAULT + type: fortimanager + +Then you have to specify this inventory file and the vault configuration in the fotoobo configuration file ``~/.config/fotoobo.yaml``. + +.. code-block:: yaml + + inventory: ~/.config/inventory.yaml + vault: + url: https://vault.local + namespace: vault_namespace + data_path: /v1/kv/data/fotoobo + role_id: ... + secret_id: ... + token_file: ~/.cache/token.key + +With these preparations you can use the fotoobo configuration to access your assets. + +.. code-block:: python + + from fotoobo.helpers.config import config + from fotoobo.inventory import Inventory + config.load_configuration() + config.vault["ssl_verify"] = False + inventory = Inventory(config.inventory_file) + fmg = inventory.get_item("fmg-test") + print(fmg.get_version()) From 115c3a8570f9730f06baeacee92f6a411f26c6e6 Mon Sep 17 00:00:00 2001 From: Patrik Spiess Date: Wed, 15 Apr 2026 13:36:59 +0200 Subject: [PATCH 3/7] =?UTF-8?q?=F0=9F=8F=B7=EF=B8=8F=20Add=20typing=20info?= =?UTF-8?q?rmation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- WHATSNEW.md | 1 + fotoobo/py.typed | 0 pyproject.toml | 2 ++ 3 files changed, 3 insertions(+) create mode 100644 fotoobo/py.typed diff --git a/WHATSNEW.md b/WHATSNEW.md index d6e3080..87783bf 100644 --- a/WHATSNEW.md +++ b/WHATSNEW.md @@ -1,6 +1,7 @@ ### Added - Add more examples on how to use imported fotoobo +- Add typing information for fotoobo so that mypy is able to check types when importing fotoobo ### Changed diff --git a/fotoobo/py.typed b/fotoobo/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/pyproject.toml b/pyproject.toml index 05de8aa..5dc6533 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -91,6 +91,8 @@ disallow_untyped_decorators=false [tool.pytest.ini_options] addopts = "--basetemp=tests/temp/" +[tool.setuptools.package-data] +fotoobo = ["py.typed"] # here we define the tox settings # we do it inline because we don't want to have another tox.ini in the project root From 1582abbbaba70b093cbd97388b97319a01ba838b Mon Sep 17 00:00:00 2001 From: Patrik Spiess Date: Wed, 15 Apr 2026 13:39:39 +0200 Subject: [PATCH 4/7] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Upgrade=20pytest=20to?= =?UTF-8?q?=209.0.3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 9fecfb8..9f02510 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.1.4 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.3.2 and should not be changed by hand. [[package]] name = "alabaster" @@ -1126,15 +1126,15 @@ testing = ["covdefaults (>=2.3)", "pytest (>=8.4.2)", "pytest-cov (>=7)", "pytes [[package]] name = "pytest" -version = "9.0.2" +version = "9.0.3" description = "pytest: simple powerful testing with Python" optional = true python-versions = ">=3.10" groups = ["main"] markers = "extra == \"dev\"" files = [ - {file = "pytest-9.0.2-py3-none-any.whl", hash = "sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b"}, - {file = "pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11"}, + {file = "pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9"}, + {file = "pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c"}, ] [package.dependencies] From 8bf67c4fe756d69ca1d4d034077ae3914136e7e0 Mon Sep 17 00:00:00 2001 From: Patrik Spiess Date: Wed, 15 Apr 2026 13:57:55 +0200 Subject: [PATCH 5/7] =?UTF-8?q?=E2=9A=B0=EF=B8=8F=20No=20need=20to=20add?= =?UTF-8?q?=20py.typed=20to=20pyproject.toml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 5dc6533..e3f7d0c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -91,9 +91,6 @@ disallow_untyped_decorators=false [tool.pytest.ini_options] addopts = "--basetemp=tests/temp/" -[tool.setuptools.package-data] -fotoobo = ["py.typed"] - # here we define the tox settings # we do it inline because we don't want to have another tox.ini in the project root # package management is done as described in option 3 on the following FAQ From 841d2200a7ef86afecd434aaca043a8a714e8d9c Mon Sep 17 00:00:00 2001 From: Patrik Spiess Date: Thu, 16 Apr 2026 10:11:05 +0200 Subject: [PATCH 6/7] =?UTF-8?q?=F0=9F=8F=B7=EF=B8=8F=20Update=20types?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fotoobo/fortinet/forticlientems.py | 2 +- fotoobo/fortinet/forticloudasset.py | 2 +- fotoobo/fortinet/fortigate.py | 2 +- fotoobo/fortinet/fortimanager.py | 6 +++--- fotoobo/fortinet/fortinet.py | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/fotoobo/fortinet/forticlientems.py b/fotoobo/fortinet/forticlientems.py index 4944834..f5c1c1a 100644 --- a/fotoobo/fortinet/forticlientems.py +++ b/fotoobo/fortinet/forticlientems.py @@ -57,7 +57,7 @@ def api( # pylint: disable=too-many-arguments, too-many-positional-arguments params: dict[str, str] | None = None, payload: dict[str, Any] | None = None, timeout: float | None = None, - ) -> requests.models.Response: + ) -> requests.Response: """ API request to a FortiClientEMS device. diff --git a/fotoobo/fortinet/forticloudasset.py b/fotoobo/fortinet/forticloudasset.py index 4b84ed1..eed48be 100644 --- a/fotoobo/fortinet/forticloudasset.py +++ b/fotoobo/fortinet/forticloudasset.py @@ -54,7 +54,7 @@ def api( # pylint: disable=too-many-arguments, too-many-positional-arguments params: dict[str, str] | None = None, payload: dict[str, Any] | None = None, timeout: float | None = None, - ) -> requests.models.Response: + ) -> requests.Response: """ API request to a FortiManager device. diff --git a/fotoobo/fortinet/fortigate.py b/fotoobo/fortinet/fortigate.py index 5771246..c4547be 100644 --- a/fotoobo/fortinet/fortigate.py +++ b/fotoobo/fortinet/fortigate.py @@ -49,7 +49,7 @@ def api( # pylint: disable=too-many-arguments, too-many-positional-arguments params: dict[str, str] | None = None, payload: dict[str, Any] | None = None, timeout: float | None = None, - ) -> requests.models.Response: + ) -> requests.Response: """Native API request to a FortiGate. It uses the super.api method but it has to enrich the payload in post requests with the diff --git a/fotoobo/fortinet/fortimanager.py b/fotoobo/fortinet/fortimanager.py index b9be3be..ab11874 100644 --- a/fotoobo/fortinet/fortimanager.py +++ b/fotoobo/fortinet/fortimanager.py @@ -68,7 +68,7 @@ def __init__(self, hostname: str, username: str, password: str, **kwargs: Any) - "rootp", ] - def api_delete(self, url: str) -> requests.models.Response: + def api_delete(self, url: str) -> requests.Response: """DELETE method for API requests Args: @@ -85,7 +85,7 @@ def api_delete(self, url: str) -> requests.models.Response: def api_get( self, url: str, params: dict[str, Any] | None = None, timeout: float | None = None - ) -> requests.models.Response: + ) -> requests.Response: """GET method for API requests Args: @@ -114,7 +114,7 @@ def api( # pylint: disable=too-many-arguments, too-many-positional-arguments params: dict[str, str] | None = None, payload: dict[str, Any] | None = None, timeout: float | None = None, - ) -> requests.models.Response: + ) -> requests.Response: """ API request to a FortiManager device. diff --git a/fotoobo/fortinet/fortinet.py b/fotoobo/fortinet/fortinet.py index 3805c4f..d53749b 100644 --- a/fotoobo/fortinet/fortinet.py +++ b/fotoobo/fortinet/fortinet.py @@ -78,7 +78,7 @@ def api( # pylint: disable=too-many-arguments, too-many-positional-arguments params: dict[str, str] | None = None, payload: dict[str, Any] | None = None, timeout: float | None = None, - ) -> requests.models.Response: + ) -> requests.Response: """ API request to a Fortinet device. From fc1e7050951fa13418d7a2a13ab6e665116934e8 Mon Sep 17 00:00:00 2001 From: Patrik Spiess Date: Thu, 16 Apr 2026 10:26:17 +0200 Subject: [PATCH 7/7] =?UTF-8?q?=E2=9C=8F=EF=B8=8F=20Typo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/source/usage/import_fotoobo.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/usage/import_fotoobo.rst b/docs/source/usage/import_fotoobo.rst index a01f89b..a8d8ca3 100644 --- a/docs/source/usage/import_fotoobo.rst +++ b/docs/source/usage/import_fotoobo.rst @@ -92,7 +92,7 @@ Using a configuration file You can read your fotoobo :ref:`configuration file`. This is useful if you wish to load and change settings like :ref:`inventory file`, :ref:`logging options` or a :ref:`vault configuration`. -Use the inventory file ``~/.config/inventory.yaml`` with the string ``VAULT`` as the toke or password for your assets. +Use the inventory file ``~/.config/inventory.yaml`` with the string ``VAULT`` as the token or password for your assets. .. code-block:: yaml