diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 68d4a018..7b5e7ece 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,9 +3,9 @@ name: CI # Run on all PR's and on pushes/merges to deploy and master on: pull_request: - branches: ['master', '!paper.md'] + branches: ['master', 'dev/*', '!paper.md'] push: - branches: ['master', '!paper.md'] + branches: ['master', 'dev/*', '!paper.md'] tags: ["v*"] jobs: @@ -24,7 +24,7 @@ jobs: steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 @@ -47,35 +47,26 @@ jobs: token: ${{ secrets.CODECOV_TOKEN }} fail_ci_if_error: false - black: - name: Run Black code quality check - + ruff: + name: Run Ruff code quality check runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: rickstaa/action-black@v1 + - uses: actions/checkout@v4 + - uses: rchartboost/ruff-action@v1 with: - black_args: "lightshow/ --check" - fail_on_error: "true" + src: './lightshow' flake8_py3: name: Run flake8 code quality check - runs-on: ubuntu-latest - steps: - - - uses: actions/checkout@v3 - + - uses: actions/checkout@v4 - name: Setup Python uses: actions/setup-python@v2 with: python-version: 3.9 - - - name: Install flake8 - run: pip install flake8 - + # - name: Install flake8 + # run: pip install flake8 - name: Run flake8 uses: suo/flake8-github-action@releases/v1 with: @@ -91,7 +82,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 ########################################################################### # Getting the tags like this is REQUIRED for the dynamic versioning @@ -132,7 +123,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Python 3.9 uses: actions/setup-python@v2 @@ -180,7 +171,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Python 3.9 uses: actions/setup-python@v2 diff --git a/.gitignore b/.gitignore index 378663f5..11b06e90 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .DS_Store +pyrightconfig.json *.pyc !build_sphinx.sh diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 07f1646a..3368238f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,10 +1,14 @@ default_language_version: python: python3 repos: - - repo: https://github.com/ambv/black - rev: 22.6.0 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.3.5 hooks: - - id: black + - id: ruff + types_or: [ python, pyi, jupyter ] + args: [ --fix ] + - id: ruff-format + types_or: [ python, pyi, jupyter ] - repo: https://github.com/pre-commit/pre-commit-hooks rev: v2.0.0 hooks: diff --git a/README.md b/README.md index 0da0aaa7..e4d36a05 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![image](https://github.com/AI-multimodal/Lightshow/actions/workflows/ci.yml/badge.svg)](https://github.com/AI-multimodal/Lightshow/actions/workflows/ci.yml) [![image](https://codecov.io/gh/AI-multimodal/Lightshow/branch/master/graph/badge.svg?token=CW7BMFA5O7)](https://codecov.io/gh/AI-multimodal/Lightshow) [![image](https://app.codacy.com/project/badge/Grade/d31a4e18672c4d71bbaafa719181c140)](https://www.codacy.com/gh/AI-multimodal/Lightshow/dashboard?utm_source=github.com&utm_medium=referral&utm_content=AI-multimodal/Lightshow&utm_campaign=Badge_Grade)
-[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) +[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) [![python](https://img.shields.io/badge/-Python_3.9+-blue?logo=python&logoColor=white)](https://github.com/pre-commit/pre-commit) [![Downloads](https://static.pepy.tech/badge/lightshow)](https://pepy.tech/project/lightshow) diff --git a/lightshow/__init__.py b/lightshow/__init__.py index 3ea11299..401111cb 100644 --- a/lightshow/__init__.py +++ b/lightshow/__init__.py @@ -1,6 +1,12 @@ from os import environ -from lightshow._version import __version__ # noqa +from lightshow._version import __version__ +from lightshow.database import Database +from lightshow.parameters.exciting import EXCITINGParameters +from lightshow.parameters.feff import FEFFParameters +from lightshow.parameters.ocean import OCEANParameters +from lightshow.parameters.vasp import VASPParameters +from lightshow.parameters.xspectra import XSpectraParameters def _get_API_key_from_environ(): @@ -63,14 +69,8 @@ def _get_SPECIES_DIRECTORY_from_environ(): return environ.get("SPECIES_DIRECTORY", None) -from lightshow.database import Database # noqa -from lightshow.parameters.exciting import EXCITINGParameters # noqa -from lightshow.parameters.feff import FEFFParameters # noqa -from lightshow.parameters.ocean import OCEANParameters # noqa -from lightshow.parameters.vasp import VASPParameters # noqa -from lightshow.parameters.xspectra import XSpectraParameters # noqa - __all__ = [ + "__version__", "Database", "EXCITINGParameters", "FEFFParameters", diff --git a/lightshow/database.py b/lightshow/database.py index 9aec6719..7692e499 100644 --- a/lightshow/database.py +++ b/lightshow/database.py @@ -24,18 +24,26 @@ def _get_api_key(api_key): raise ValueError(f"Invalid API key {api_key}") return api_key + def _get_method(method, mpr): - """Get all the available search methods; if the given method is not present, the search will be performed using mpr.materials.search""" - methods = [methods for methods in dir(mpr.materials) if methods is not callable and not methods.startswith('_')] + """Get all the available search methods; if the given method is not + present, the search will be performed using mpr.materials.search""" + + methods = [ + methods + for methods in dir(mpr.materials) + if methods is not callable and not methods.startswith("_") + ] if method is None: + print("Searching Materials Project with default method") + elif method not in methods: + warn( + f"Provided method={method} not in available methods {methods}", + "falling back on default search method.", + ) method = None - elif method in methods: - method = method - else: - print("Searching with default method") - method = None - + return method @@ -62,7 +70,8 @@ def from_files_molecule( The files to search for. Uses ``rglob`` to recursively find any files matching ``filename`` within the provided directory. lattice : list of floats, optional - Lattice parameter used to construct the crystal lattice. + Lattice parameter used to construct the crystal lattice. If not + provided, defaults to [20.0, 20.0, 20.0] Angstroms. pbar : bool, optional If True, will show a tqdm progress bar. @@ -127,7 +136,7 @@ def from_files(cls, root, filename="CONTCAR", pbar=True): return cls(structures=structures, metadata=metadata, supercells=dict()) @classmethod - def from_materials_project(cls, **kwargs): + def from_materials_project(cls, api_key=None, method=None, **kwargs): """Constructs the :class:`.Database` object by pulling structures and metadata directly from the Materials Project. This is a simple passthrough method which utilizes the MPRester.materials.search @@ -135,58 +144,40 @@ def from_materials_project(cls, **kwargs): Parameters ---------- - **kwargs - Description - - Examples - -------- - - Deleted Parameters - ------------------ - mpr_query_kwargs : dict - Direct passthrough to MPRester.materials.search. See - examples below. api_key : None, optional API key which can either be provided directly or is read from the MP_API_KEY environment variable. method : None, optional, str Keyword to get different information about materials' for e.g. 'thermo', 'xas', 'summary' etc. fetch information on - thermodynamic properties, computed XAS data, large amount of amalgated data - about the material, respectively. https://api.materialsproject.org/docs - + thermodynamic properties, computed XAS data, large amount of + amalgated data about the material, respectively. + See https://api.materialsproject.org/docs for more details. + **kwargs + Description + Returns ------- Database """ - api_key = _get_api_key(kwargs.get("api_key")) - - try: - kwargs.pop("api_key") - except KeyError: - pass + api_key = _get_api_key(api_key) + method = kwargs.get("method") with MPRester(api_key) as mpr: - method = _get_method(kwargs.get("method"), mpr=mpr) - try: - kwargs.pop("method") - except: - pass + method = _get_method(method, mpr=mpr) if method is not None: searched = getattr(mpr.materials, method).search(**kwargs) else: searched = mpr.materials.search(**kwargs) - structures = {s.material_id.string: s.structure if hasattr(s, "structure") else None for s in searched} + structures = { + s.material_id.string: s.structure + if hasattr(s, "structure") + else None + for s in searched + } metadata = {s.material_id.string: s.dict() for s in searched} - - - # with MPRester(api_key) as mpr: - # searched = mpr.materials.search(**kwargs) - - # structures = {s.material_id.string: s.structure for s in searched} - # metadata = {s.material_id.string: s.dict() for s in searched} return cls(structures=structures, metadata=metadata, supercells=dict()) diff --git a/lightshow/defaults.py b/lightshow/defaults.py index 9667d9ba..36e3f0e0 100644 --- a/lightshow/defaults.py +++ b/lightshow/defaults.py @@ -1,19 +1,22 @@ """Helper module for making the API a bit cleaner when dealing with default parameters.""" -# Note that pre-commit + .flake8 ignores this file since it's just a bunch of -# imports... - +from lightshow.parameters.exciting import EXCITING_DEFAULT_CARDS from lightshow.parameters.feff import FEFF_DEFAULT_CARDS - +from lightshow.parameters.ocean import OCEAN_DEFAULT_CARDS from lightshow.parameters.vasp import ( - VASP_INCAR_DEFAULT_NEUTRAL_POTENTIAL, VASP_INCAR_DEFAULT_COREHOLE_POTENTIAL, + VASP_INCAR_DEFAULT_NEUTRAL_POTENTIAL, VASP_POTCAR_DEFAULT_ELEMENT_MAPPING, ) - -from lightshow.parameters.ocean import OCEAN_DEFAULT_CARDS - from lightshow.parameters.xspectra import XSPECTRA_DEFAULT_CARDS -from lightshow.parameters.exciting import EXCITING_DEFAULT_CARDS +__all__ = [ + "FEFF_DEFAULT_CARDS", + "VASP_INCAR_DEFAULT_NEUTRAL_POTENTIAL", + "VASP_INCAR_DEFAULT_COREHOLE_POTENTIAL", + "VASP_POTCAR_DEFAULT_ELEMENT_MAPPING", + "OCEAN_DEFAULT_CARDS", + "XSPECTRA_DEFAULT_CARDS", + "EXCITING_DEFAULT_CARDS", +] diff --git a/pyproject.toml b/pyproject.toml index 5744ff61..419b40ff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,9 +55,9 @@ dynamic = ["version"] test = [ "coverage", "flake8", + "ruff", "pytest", "pytest-cov", - "black", "nbstripout", "pre-commit", ] @@ -77,20 +77,11 @@ build = [ [tool.setuptools] packages = ["lightshow"] -[tool.black] +[tool.ruff] line-length = 80 -include = '\.pyi?$' -exclude = ''' -/( - | \.git - | \.hg - | \.mypy_cache - | \.tox - | \.venv - | _build - | buck-out - | build - | dist - | docs/source/conf.py -)/ -''' + +[tool.ruff.format] +quote-style = "double" +indent-style = "space" +docstring-code-format = true +docstring-code-line-length = 60