Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor global state #486

Merged
merged 117 commits into from
Nov 12, 2021
Merged
Show file tree
Hide file tree
Changes from 107 commits
Commits
Show all changes
117 commits
Select commit Hold shift + click to select a range
d57d519
Make promises about Settings
liamhuber Oct 20, 2021
2781496
Fix typo
liamhuber Oct 20, 2021
6cce1db
Test the promises
liamhuber Oct 21, 2021
76e491b
Slide the code for non-core responsibilities down to the bottom
liamhuber Oct 21, 2021
8384c2a
Touch up docstrings
liamhuber Oct 21, 2021
6399ebb
Hide conversion method
liamhuber Oct 21, 2021
a206c9d
Try to debug issue on windows
liamhuber Oct 22, 2021
045c72a
Resolve pycharm nits
liamhuber Oct 22, 2021
00ccf05
Remove debug print
liamhuber Oct 22, 2021
a12423b
Add debug print for new windows problem
liamhuber Oct 22, 2021
63c50e6
Pyiron internally converts to something like posix so try using that …
liamhuber Oct 22, 2021
2259c70
Remove debug prints
liamhuber Oct 22, 2021
10a29c0
Remove unused imports
liamhuber Oct 22, 2021
a4b6407
Merge branch 'master' into settings_promises
liamhuber Oct 22, 2021
647f10b
Test both cases for top_dir
liamhuber Oct 22, 2021
2f4aba6
Remove extra jazz on top of singleton and delete old tests
liamhuber Oct 22, 2021
7bf1b68
In fact, just remove the argument altogether
liamhuber Oct 22, 2021
b39f099
Make backup restoration more robust
liamhuber Oct 22, 2021
b90be96
Merge branch 'settings_promises' into refactor_ide
liamhuber Oct 22, 2021
fa73255
Update docstring
liamhuber Oct 22, 2021
25bbf70
Crown one true king
liamhuber Oct 22, 2021
2578166
Refactor rename: settings now live under IDE
liamhuber Oct 22, 2021
0752f4d
Use IDE as one key point of access
liamhuber Oct 22, 2021
e66ace5
Resolve deprecation warning
liamhuber Oct 23, 2021
cea0fda
Force the script job to ignore project checks
liamhuber Oct 23, 2021
fa46622
Remove unused imports
liamhuber Oct 23, 2021
b52bdf4
Be more explicit with names
liamhuber Oct 23, 2021
6df5d76
Allow access directly from the class
liamhuber Oct 23, 2021
8cfead8
Also convert paths coming from system environment variables
liamhuber Oct 23, 2021
b1c3956
Oops, don't convert non-path items
liamhuber Oct 23, 2021
a997b1c
Use fstring
liamhuber Oct 23, 2021
80916e7
Be more explicit in error message
liamhuber Oct 23, 2021
a2f022c
Access via IDE
liamhuber Oct 23, 2021
e174ebd
Derp, avoid circular import
liamhuber Oct 23, 2021
ac6630e
Refactor path splitting and only convert once at the end
liamhuber Oct 23, 2021
866f835
Desperate windows debug print
liamhuber Oct 23, 2021
a6a32ab
Keep revising path parsing
liamhuber Oct 23, 2021
b1bf0de
Hail Mary
liamhuber Oct 23, 2021
23551db
Make one liner
liamhuber Oct 24, 2021
8b5fbd9
Directly convert paths passed into top_path
liamhuber Oct 24, 2021
75b7bae
Remove unnecessary conversion
liamhuber Oct 24, 2021
30231d9
Use IDE
liamhuber Oct 24, 2021
998ec3b
Wrap where we manually assign to project_paths
liamhuber Oct 24, 2021
2ce392c
Print the object ID to check if we're getting multiple instances somehow
liamhuber Oct 24, 2021
a91332a
It worked but...
liamhuber Oct 24, 2021
7ef14dd
Use new singleton instances throughout base
liamhuber Oct 24, 2021
9b4b63f
Decouple logger and add tests
liamhuber Oct 24, 2021
a9309fc
Accommodate running more tests
liamhuber Oct 24, 2021
125c98e
Retain any existing log file
liamhuber Oct 24, 2021
021b67f
Use the new logger in the ide
liamhuber Oct 24, 2021
d1dfdbc
Update copyright year
liamhuber Oct 24, 2021
33a6dcc
Refactor the queue adapter out
liamhuber Oct 24, 2021
f2ff4ea
Improve docstring and trailing newline
liamhuber Oct 24, 2021
ac04e34
Accommodate method binding and deprecate
liamhuber Oct 24, 2021
8651c34
Add test
liamhuber Oct 24, 2021
e9168b9
Be more specific in docstring
liamhuber Oct 24, 2021
ed4076f
Remove unused import
liamhuber Oct 24, 2021
d8315b4
Extract publications
liamhuber Oct 24, 2021
46e3ce6
Deprecate calls on settings that are now handled by the IDE
liamhuber Oct 24, 2021
fa05ac3
Revert deprecation warnings
liamhuber Oct 24, 2021
43a00dd
Move the IDE object upstream
liamhuber Oct 24, 2021
1459a45
Obfuscate object names
liamhuber Oct 24, 2021
c3943ed
Move singleton back where it came from
liamhuber Oct 24, 2021
867a646
Add a note to convey intent
liamhuber Oct 24, 2021
f5b9f96
Merge branch 'master' into refactor_ide
liamhuber Oct 26, 2021
48320a9
Merge branch 'master' into refactor_ide
liamhuber Oct 26, 2021
ea14eab
Clean up empty files
liamhuber Oct 26, 2021
075c0cd
Rename IDE to state
liamhuber Oct 26, 2021
0813c60
Make state object more boring and order attributes by import hierarchy
liamhuber Oct 26, 2021
270dfa2
Add docs to state
liamhuber Oct 26, 2021
c45c972
Rationalize settings update and reintroduce user arg
liamhuber Oct 26, 2021
46644d0
Refactor slide and rename
liamhuber Oct 26, 2021
254c982
Refactor rename test submodule
liamhuber Oct 26, 2021
950d61a
Shorten conversion
liamhuber Oct 26, 2021
07bbbdb
Be explicit
liamhuber Oct 26, 2021
2988b10
Be explicit, don't sneak a database somewhere
liamhuber Oct 26, 2021
4a1bb8e
Rely on the conversion done in the update
liamhuber Oct 26, 2021
fc58740
Oneline stuff that fits
liamhuber Oct 26, 2021
1784157
Wipe and reset all config elements
liamhuber Oct 27, 2021
3a9a3b3
rename test
liamhuber Oct 27, 2021
2d9ddaf
Clean standard config for each test
liamhuber Oct 27, 2021
387f132
Test validation
liamhuber Oct 29, 2021
ce02d38
Test other validation
liamhuber Oct 29, 2021
b767d24
Test env reading
liamhuber Oct 29, 2021
96c32ac
Test file reading
liamhuber Oct 29, 2021
80f87a2
Test comment in file
liamhuber Oct 29, 2021
bd54c64
Test path list conversion
liamhuber Oct 29, 2021
feca361
Construct adapters from scratch
liamhuber Oct 29, 2021
0b421bd
Add update to database manager
liamhuber Oct 29, 2021
dbc0ca0
Add update alias for queue adapter
liamhuber Oct 29, 2021
a7c0698
Add global update to state module
liamhuber Oct 29, 2021
9708b14
Be more precise with wording
liamhuber Oct 29, 2021
cdeffac
Refactor getting conda resources
liamhuber Nov 2, 2021
e82b47a
Relocate weird snippet
liamhuber Nov 2, 2021
3b409f9
Centralize and test SQLite config input
liamhuber Nov 2, 2021
0f54f6d
Move all the sql connecting string parsing over to database
liamhuber Nov 2, 2021
9af4e06
Fix typo
liamhuber Nov 2, 2021
e50b29f
Decouple input validation and input transformation
liamhuber Nov 2, 2021
97aef1a
Exploit state for database manager calls
liamhuber Nov 2, 2021
0cee352
Update deprecation message
niklassiemer Nov 3, 2021
f8d1fa3
Settings docstrings
liamhuber Nov 3, 2021
f2a52bf
Don't use protected variable name
liamhuber Nov 3, 2021
d91b70e
Finish settings type hints
liamhuber Nov 3, 2021
25ee04f
Polish state docs and hinting
liamhuber Nov 3, 2021
121c802
Polish publications docs and hinting
liamhuber Nov 3, 2021
5e5801d
Polish queue adapters docs and hinting
liamhuber Nov 3, 2021
f183ff2
Merge branch 'master' into refactor_ide
liamhuber Nov 3, 2021
2fe44ac
Use converted values from database manager
liamhuber Nov 4, 2021
ddeba69
Use consistent nomenclature
max-hassani Nov 4, 2021
242046e
Update the adapters not the single instance
liamhuber Nov 5, 2021
1673a21
Actually use the validation guys!
liamhuber Nov 8, 2021
054fe49
Merge branch 'master' into refactor_ide
liamhuber Nov 10, 2021
9e7eded
Get the logger importing first
liamhuber Nov 10, 2021
7d18f54
Remove unimported guys
liamhuber Nov 10, 2021
a8a918c
Fix old doc
liamhuber Nov 10, 2021
eae2485
Merge remote-tracking branch 'origin/master' into refactor_ide
liamhuber Nov 12, 2021
ad66b2a
Update pyiron_base/project/generic.py
liamhuber Nov 12, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions pyiron_base/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
# Copyright (c) Max-Planck-Institut für Eisenforschung GmbH - Computational Materials Design (CM) Department
# Distributed under the terms of "New BSD License", see the LICENSE file.

# API of the pyiron_base module - in alphabetical order
# API of the pyiron_base module - in alphabetical order
from pyiron_base.generic.factory import PyironFactory
from pyiron_base.generic.flattenedstorage import FlattenedStorage
from pyiron_base.generic.hdfio import FileHDFio, ProjectHDFio
from pyiron_base.generic.datacontainer import DataContainer
from pyiron_base.generic.inputlist import InputList
from pyiron_base.generic.parameters import GenericParameters
from pyiron_base.generic.util import deprecate, deprecate_soon, ImportAlarm
from pyiron_base.state import state
from pyiron_base.job.executable import Executable
from pyiron_base.job.external import Notebook
from pyiron_base.job.generic import GenericJob
Expand All @@ -27,8 +28,8 @@
from pyiron_base.project.generic import Project, Creator
from pyiron_base.pyio.parser import Logstatus, extract_data_from_file
from pyiron_base.server.queuestatus import validate_que_request
from pyiron_base.settings.generic import Settings
from pyiron_base.settings.install import install_dialog
from pyiron_base.state.settings import Settings
from pyiron_base.state.install import install_dialog
from pyiron_base.table.datamining import PyironTable, TableJob
from pyiron_base.generic.object import HasDatabase, HasStorage, PyironObject
from pyiron_base.database.performance import get_database_statistics
Expand Down
2 changes: 1 addition & 1 deletion pyiron_base/_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def test_docstrings(self):
with StringIO() as buf, redirect_stdout(buf):
result = doctest.testmod(self.docstring_module)
output = buf.getvalue()
self.failIf(result.failed > 0, msg=output)
self.assertFalse(result.failed > 0, msg=output)


class TestWithProject(PyironTestCase, ABC):
Expand Down
7 changes: 2 additions & 5 deletions pyiron_base/archiving/import_archive.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@
from distutils.dir_util import copy_tree
import tarfile
from pyiron_base.generic.util import static_isinstance
from pyiron_base.settings.generic import Settings


s = Settings()
from pyiron_base.state import state


def getdir(path):
Expand Down Expand Up @@ -96,7 +93,7 @@ def import_jobs(
if 'timestop' in entry:
entry["timestop"] = pandas.to_datetime(entry["timestop"])
if 'username' not in entry:
entry["username"] = s.login_user
entry["username"] = state.settings.login_user
job_id = pr_import.db.add_item_dict(par_dict=entry)
job_id_lst.append(job_id)

Expand Down
2 changes: 1 addition & 1 deletion pyiron_base/cli/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
Install pyiron config and resources for the first time.
"""

from pyiron_base.settings.install import install_pyiron
from pyiron_base.state.install import install_pyiron

__author__ = "Marvin Poul"
__copyright__ = (
Expand Down
7 changes: 2 additions & 5 deletions pyiron_base/cli/reloadfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@
import h5py
import shutil
from pyiron_base import Project
from pyiron_base.database.manager import DatabaseManager


dbm = DatabaseManager()
from pyiron_base.state import state


def register(parser):
Expand All @@ -29,7 +26,7 @@ def main(args):
file = os.path.basename(project_path)
job_name = os.path.splitext(file)[0]

db_project_path = dbm.top_path(project_path)
db_project_path = state.database.top_path(project_path)
project = os.path.dirname(project_path)
db_project = (project + "/")
if db_project_path is not None:
Expand Down
9 changes: 3 additions & 6 deletions pyiron_base/database/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
DatabaseAccess class deals with accessing the database
"""

import pyiron_base.settings.logger
from pyiron_base.state.logger import logger
from abc import ABC, abstractmethod
import warnings
import numpy as np
Expand Down Expand Up @@ -332,7 +332,7 @@ def __init__(self, engine, timeout=60):
self._conn = None
self._lock = Lock()
self._watchdog = None
self._logger = pyiron_base.settings.logger.get_logger()
self._logger = logger
self._timeout = timeout

def execute(self, *args, **kwargs):
Expand Down Expand Up @@ -527,10 +527,7 @@ def _job_dict(
if element_lst is not None:
dict_clause["element_lst"] = element_lst

# HACK: breaks circular dependency of Settings on DatabaseAccess
from pyiron_base.settings.generic import Settings
s = Settings()
s.logger.debug("sql_query: %s", str(dict_clause))
logger.debug("sql_query: %s", str(dict_clause))
return self.get_items_dict(dict_clause)

def _get_job_table(
Expand Down
4 changes: 0 additions & 4 deletions pyiron_base/database/jobtable.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
The Jobtable module provides a set of top level functions to interact with the database.
"""

import pandas
import numpy as np
from pyiron_base.settings.generic import Settings
from pyiron_base.database.filetable import FileTable

__author__ = "Jan Janssen"
Expand All @@ -21,8 +19,6 @@
__status__ = "production"
__date__ = "Sep 1, 2017"

s = Settings()


def get_jobs(database, sql_query, user, project_path, recursive=True, columns=None):
"""
Expand Down
100 changes: 80 additions & 20 deletions pyiron_base/database/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@
"""

from pyiron_base.generic.util import Singleton
from pyiron_base.settings.generic import Settings
from pyiron_base.state.settings import settings as s
from pyiron_base.database.generic import DatabaseAccess
import os

s = Settings()

__author__ = "Jan Janssen, Liam Huber"
__copyright__ = (
"Copyright 2020, Max-Planck-Institut für Eisenforschung GmbH"
Expand Down Expand Up @@ -63,16 +61,67 @@ def connection_timeout(self):
def connection_timeout(self, val):
s.configuration["connection_timeout"] = val

@staticmethod
def _sqlalchemy_string(prefix, user, key, host, database):
return f"{prefix}://{user}:{key}@{host}/{database}"

def _credentialed_sqalchemy_string(self, prefix):
return self._sqlalchemy_string(
prefix,
s.configuration["user"],
s.configuration["sql_user_key"],
s.configuration["sql_host"],
s.configuration["sql_database"]
)

@property
def sql_connection_string(self):
sql_type = s.configuration["sql_type"]
if sql_type == "Postgres":
return self._credentialed_sqalchemy_string("postgresql")
elif sql_type == "MySQL":
return self._credentialed_sqalchemy_string("mysql+pymysql")
elif sql_type == "SQLalchemy":
return s.configuration["sql_connection_string"]
elif sql_type == "SQLite":
return "sqlite:///" + s.configuration["sql_file"].replace("\\", "/")
else:
raise ValueError(
f"Invalid SQL type {sql_type} -- This should have been caught at input processing, please contact the "
f"developers"
)

@property
def sql_view_connection_string(self):
if s.configuration["sql_view_user"] is None:
return None
else:
return self._sqlalchemy_string(
"postgresql",
s.configuration["sql_view_user"],
s.configuration["sql_view_user_key"],
s.configuration["sql_host"],
s.configuration["sql_database"]
)

@property
def sql_table_name(self):
return s.configuration["sql_table_name"]

@property
def sql_view_table_name(self):
return s.configuration["sql_view_table_name"]

def open_connection(self):
"""
Internal function to open the connection to the database. Only after this function is called the database is
accessable.
"""
if self._database is None and not self.database_is_disabled:
self._database = DatabaseAccess(
s.configuration["sql_connection_string"],
s.configuration["sql_table_name"],
timeout=s.configuration["connection_timeout"]
self.sql_connection_string,
self.sql_table_name,
timeout=self.connection_timeout
)

def switch_to_local_database(self, file_name="pyiron.db", cwd=None):
Expand All @@ -94,7 +143,7 @@ def switch_to_local_database(self, file_name="pyiron.db", cwd=None):
self.open_local_sqlite_connection(connection_string="sqlite:///" + file_name)

def open_local_sqlite_connection(self, connection_string):
self._database = DatabaseAccess(connection_string, s.configuration["sql_table_name"])
self._database = DatabaseAccess(connection_string, self.sql_table_name)
self._use_local_database = True
self._database_is_disabled = False

Expand All @@ -109,8 +158,8 @@ def switch_to_central_database(self):
self._database = None
else:
self._database = DatabaseAccess(
s.configuration["sql_connection_string"],
s.configuration["sql_table_name"],
self.sql_connection_string,
self.sql_table_name,
)

self._use_local_database = False
Expand All @@ -121,14 +170,14 @@ def switch_to_viewer_mode(self):
"""
Switch from user mode to viewer mode - if view_mode is enable pyiron has read only access to the database.
"""
if s.configuration["sql_view_connection_string"] is not None and not self.database_is_disabled:
if self.sql_view_connection_string is not None and not self.database_is_disabled:
if self._database.view_mode:
s.logger.log("Database is already in viewer mode!")
else:
self.close_connection()
self._database = DatabaseAccess(
s.configuration["sql_view_connection_string"],
s.configuration["sql_view_table_name"],
self.sql_view_connection_string,
self.sql_view_table_name,
)
self._database.view_mode = True

Expand All @@ -143,10 +192,10 @@ def switch_to_user_mode(self):
if self._database.view_mode:
self.close_connection()
self._database = DatabaseAccess(
s.configuration["sql_connection_string"],
s.configuration["sql_table_name"],
self.sql_connection_string,
self.sql_table_name,
)
self._database.view_mode = True
self._database.view_mode = False
liamhuber marked this conversation as resolved.
Show resolved Hide resolved
else:
s.logger.log("Database is already in user mode!")
else:
Expand All @@ -170,17 +219,28 @@ def top_path(self, full_path):
Returns:
str: path
"""
if full_path[-1] != "/":
full_path += "/"
full_path = full_path if full_path.endswith("/") else full_path + "/"

if not self.project_check_enabled:
return None

for path in s.configuration["project_paths"]:
if path in full_path:
return path

raise ValueError(
"the current path {0} is not included in the .pyiron configuration. {1}".format(
full_path, s.configuration["project_paths"]
)
f"the current path {full_path} is not included in the .pyiron configuration 'project_paths': "
f"{s.configuration['project_paths']}"
)

def update(self):
"""
Warning: Database interaction does not have written spec. This method does a thing. It might not be the thing
you want.
"""
self.close_connection()
self._use_local_database = False
self._database_is_disabled = s.configuration["disable_database"]


database = DatabaseManager()
8 changes: 3 additions & 5 deletions pyiron_base/database/performance.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@
or_,
false,
)
from pyiron_base.settings.generic import Settings

from pyiron_base.state import state

__author__ = "Muhammad Hassani"
__version__ = "1.0"
Expand Down Expand Up @@ -79,9 +78,8 @@ class DatabaseStatistics:
"""

def __init__(self):
s = Settings()
connection_string = s._configuration['sql_connection_string']
self._job_table = s._configuration['sql_view_table_name']
connection_string = state.settings.configuration['sql_connection_string']
max-hassani marked this conversation as resolved.
Show resolved Hide resolved
self._job_table = state.settings.configuration['sql_view_table_name']
if "postgresql" not in connection_string:
raise RuntimeError(
"""
Expand Down
10 changes: 4 additions & 6 deletions pyiron_base/generic/object.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from pyiron_base.generic.datacontainer import DataContainer
from pyiron_base.interfaces.has_hdf import HasHDF
from pyiron_base.generic.hdfio import ProjectHDFio
from pyiron_base.database.manager import DatabaseManager
from pyiron_base.state import state

__author__ = "Liam Huber"
__copyright__ = (
Expand All @@ -23,8 +23,6 @@
__status__ = "development"
__date__ = "Mar 23, 2021"

dbm = DatabaseManager()


class HasStorage(HasHDF, ABC):
"""
Expand Down Expand Up @@ -53,9 +51,9 @@ class HasDatabase(ABC):
"""

def __init__(self, *args, **kwargs):
if not dbm.database_is_disabled:
dbm.open_connection()
self._database = dbm.database
if not state.database.database_is_disabled:
state.database.open_connection()
self._database = state.database.database
else:
raise NotImplementedError("WIP. For now only allowed with a database")

Expand Down
8 changes: 3 additions & 5 deletions pyiron_base/generic/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import posixpath
import warnings
from ast import literal_eval
from pyiron_base.settings.generic import Settings
from pyiron_base.state import state

__author__ = "Joerg Neugebauer"
__copyright__ = (
Expand All @@ -25,8 +25,6 @@
__status__ = "production"
__date__ = "Sep 1, 2017"

s = Settings()


class GenericParameters:
"""
Expand Down Expand Up @@ -322,7 +320,7 @@ def read_input(self, file_name, ignore_trigger=None):
file_name (str): absolute path to the input file
ignore_trigger (str): trigger for lines to be ignored
"""
Settings().logger.debug("file: %s %s", file_name, os.path.isfile(file_name))
state.logger.debug("file: %s %s", file_name, os.path.isfile(file_name))
if not os.path.isfile(file_name):
raise ValueError("file does not exist: " + file_name)
with open(file_name, "r") as f:
Expand Down Expand Up @@ -829,7 +827,7 @@ def _append_line_in_block(self, parameter_name, value):
)
return True
else:
s.logger.warning(
state.logger.warning(
"Unknown parameter (does not exist in block_dict): {}".format(
parameter_name
)
Expand Down
Loading