Skip to content

Commit

Permalink
Merge pull request #46 from scrambldchannel/feat/login_conf_file_type
Browse files Browse the repository at this point in the history
feat: login conf file type and release
  • Loading branch information
scrambldchannel authored Nov 7, 2022
2 parents e57c396 + f8864d5 commit 42314a3
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 2 deletions.
2 changes: 1 addition & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
project = "TM1 File Tools"
copyright = "2022, Alexander Sutcliffe"
author = "Alexander Sutcliffe"
release = "0.3.2"
release = "0.3.3"

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
Expand Down
6 changes: 6 additions & 0 deletions docs/source/history.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
Release history
===============

Version 0.3.3
-------------

- Added experimental support for login credentials saved as config files
- Better docs

Version 0.3.2
-------------

Expand Down
2 changes: 1 addition & 1 deletion src/tm1filetools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

from .tools import TM1FileTool # noqa

__version__ = "0.3.2" # noqa
__version__ = "0.3.3" # noqa
79 changes: 79 additions & 0 deletions src/tm1filetools/files/text/other.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import configparser
from pathlib import Path

from .text import TM1TextFile


class TM1LoginCfgFile(TM1TextFile):
"""
A class representation of a config.in file often used in TM1py examples
"""

def __init__(self, path: Path, section: str):

# list of valid params

self._valid_params = [
"address",
"port",
"user",
"password",
"ssl",
]

super().__init__(path)

self.config = configparser.ConfigParser()
self.config.read(path, encoding=self.encoding)

self._section = section

self._params = {}
self._set_params()

def get_parameter(self, param: str) -> str:

return self.config.get(section=self._section, option=param, fallback=None)

def set_parameter(self, param: str, value: str) -> None:

# if we have a list of valid options, we could warn when an invalid option set
# do I need to care about the section in this file?
self.config[self._section][param] = value

with open(self._path, "w") as f:
self.config.write(f)

def is_valid(self):
# check file has the necessary sections and mandatory params

return (
self.config.has_section(self._section)
and self._params.get("address") is not None # noqa
and self._params.get("port") is not None # noqa
and self._params.get("user") is not None # noqa
and self._params.get("password") is not None # noqa
)

def _set_params(self):

for p in self._valid_params:
self._params[p] = self.get_parameter(param=p)

def get_login_kwargs(self):
"""
Return a dict object suitable for as keyword arguments to create a TM1py service object
"""

# this is very naive for now and is really only meant for local testing with
# username/password authentication
# note it will return all valid params found
# it doesn't do much validation

if self.is_valid():
kwargs = {}
for p, v in self._params.items():
if v is not None:
kwargs[p] = v
return kwargs
44 changes: 44 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,3 +226,47 @@ def test_folder(tmp_path_factory):

# return the path
return d


@pytest.fixture(scope="function")
def login_config_folder(tmp_path_factory):
"""
Create a folder with with a sample login config file
"""

d = tmp_path_factory.mktemp("login")

f = d / "good_login.ini"

cfg = r"""[local]
address = 192.168.0.111
port = 18081
user = admin
password = apple
"""

f.write_text(cfg)

f = d / "bad_login.ini"

cfg = r"""[local]
address = 192.168.0.111
user = admin
password = apple
"""

f.write_text(cfg)

f = d / "messy_login.ini"

cfg = r"""[messy]
address = 192.168.0.111
port = 18081
user = admin
password = apple
irrelevant = koala
"""

f.write_text(cfg)

return d
69 changes: 69 additions & 0 deletions tests/test_files/test_text/test_other.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
from pathlib import Path

from tm1filetools.files.text.other import TM1LoginCfgFile


def test_read_and_write(test_folder):

f = TM1LoginCfgFile(Path.joinpath(test_folder, "auth.cfg"), section="local")

# need to create the section
f.config.add_section(f._section)

param = "address"

assert f.get_parameter(param) is None

value = "192.168.0.111"

f.set_parameter(param, value)

assert f.get_parameter(param) == value

# also re-open file to check it's been written to disk

f2 = TM1LoginCfgFile(Path.joinpath(test_folder, "auth.cfg"), section="local")

assert f2.get_parameter(param) == value


def test_is_valid(login_config_folder):

f = TM1LoginCfgFile(Path.joinpath(login_config_folder, "good_login.ini"), section="local")

assert f.is_valid()

f = TM1LoginCfgFile(Path.joinpath(login_config_folder, "vad_login.ini"), section="local")

assert not f.is_valid()


def test_get_kwargs(login_config_folder):

f = TM1LoginCfgFile(Path.joinpath(login_config_folder, "good_login.ini"), section="local")

login_kwargs = f.get_login_kwargs()

assert login_kwargs["address"] == "192.168.0.111"
assert login_kwargs["port"] == "18081"
assert login_kwargs["user"] == "admin"
assert login_kwargs["password"] == "apple"

assert login_kwargs.get("ssl") is None
assert login_kwargs.get("irrelevant") is None

f = TM1LoginCfgFile(Path.joinpath(login_config_folder, "messy_login.ini"), section="messy")

login_kwargs = f.get_login_kwargs()

assert login_kwargs["address"] == "192.168.0.111"
assert login_kwargs["port"] == "18081"
assert login_kwargs["user"] == "admin"
assert login_kwargs["password"] == "apple"

assert login_kwargs.get("ssl") is None
assert login_kwargs.get("irrelevant") is None

f = TM1LoginCfgFile(Path.joinpath(login_config_folder, "bad_login.ini"), section="local")

assert f.get_login_kwargs() is None

0 comments on commit 42314a3

Please sign in to comment.