diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 561cc40d8..366ed9e82 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [ "3.8", "3.9", "3.10" ] + python-version: ["3.9", "3.10", "3.11"] steps: - uses: actions/checkout@v3 @@ -22,21 +22,12 @@ jobs: run: | sudo apt-get update && sudo apt-get install -y libglpk-dev glpk-utils coinor-cbc python -m pip install --upgrade pip - pip install scikit-learn - pip install -r requirements.txt - - name: Install package - run: | - python setup.py install + pip install ".[develop]" - name: Create env file run: | touch .env # echo NREL_API_KEY=${{ secrets.NREL_API_KEY }} >> .env # cat .env - - name: Install test dependencies - run: | - pip install pytest - pip install pytest-subtests - pip install responses - name: Run tests run: | PYTHONPATH=. pytest tests diff --git a/.github/workflows/conda_build.yml b/.github/workflows/conda_build.yml index a7246a8bb..aa01d2813 100644 --- a/.github/workflows/conda_build.yml +++ b/.github/workflows/conda_build.yml @@ -9,11 +9,11 @@ jobs: name: Conda runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: conda-incubator/setup-miniconda@v2 + - uses: actions/checkout@v4 + - uses: conda-incubator/setup-miniconda@v3 with: auto-update-conda: true - python-version: 3.7 + python-version: 3.9 - name: Build and upload conda package shell: bash -l {0} env: diff --git a/.github/workflows/publish_to_pypi.yml b/.github/workflows/publish_to_pypi.yml index a9f773336..5da98e7bf 100644 --- a/.github/workflows/publish_to_pypi.yml +++ b/.github/workflows/publish_to_pypi.yml @@ -8,11 +8,11 @@ jobs: deploy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: - python-version: 3.8 + python-version: 3.9 - name: Install dependencies run: | python -m pip install --upgrade pip @@ -22,5 +22,6 @@ jobs: TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} run: | - python setup.py sdist bdist_wheel + python -m build + twine check --strict dist/* twine upload dist/* diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 3a5e0eb42..6210d47ee 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -9,7 +9,7 @@ version: 2 build: os: ubuntu-22.04 tools: - python: "3.8" + python: "3.9" # You can also specify other tool versions: # nodejs: "19" # rust: "1.64" @@ -26,6 +26,8 @@ sphinx: # Optionally declare the Python requirements required to build your docs python: - install: - - requirements: requirements.txt - - requirements: requirements-dev.txt + install: + - method: pip + path: . + extra_requirements: + - develop diff --git a/README.md b/README.md index 93f431cf7..4c7c5c916 100644 --- a/README.md +++ b/README.md @@ -7,73 +7,84 @@ software assesses optimal designs for the deployment of utility-scale hybrid ene solar and storage. ## Software requirements -- Python version 3.8, 3.9, 3.10 64-bit -- Other versions may still work, but have not been extensively tested at this time + +- Python version 3.9, 3.10, and 3.11 only (PySAM 4.2 is incompatible with 3.12) ## Installing from Package Repositories + 1. HOPP is available as a PyPi package: - ``` + ```bash pip install HOPP ``` ## Installing from Source + 1. Using Git, navigate to a local target directory and clone repository: - ``` + + ```bash git clone https://github.com/NREL/HOPP.git ``` 2. Navigate to `HOPP` - ``` + + ```bash cd HOPP ``` 3. Create a new virtual environment and change to it. Using Conda and naming it 'hopp': - ``` + + ```bash conda create --name hopp python=3.8 -y conda activate hopp ``` -4. Install dependencies: - ``` - conda install -c conda-forge coin-or-cbc=2.10.8 -y - conda install -c conda-forge glpk -y - pip install -r requirements.txt - ``` +4. Install HOPP and its dependencies: - Note if you are on Windows, you will have to manually install Cbc: https://github.com/coin-or/Cbc - - If you also want development dependencies for running tests and building docs: - - ``` - pip install -r requirements-dev.txt + ```bash + conda install -y -c conda-forge coin-or-cbc=2.10.8 glpk ``` -5. Install HOPP: - ``` - pip install -e . - ``` - -6. The functions which download resource data require an NREL API key. Obtain a key from: + Note if you are on Windows, you will have to manually install Cbc: https://github.com/coin-or/Cbc. - [https://developer.nrel.gov/signup/](https://developer.nrel.gov/signup/) + - If you want to just use HOPP: + + ```bash + pip install . + ``` + + - If you want to work with the examples: + + ```bash + pip install ".[examples]" + ``` + + - If you also want development dependencies for running tests and building docs: + + ```bash + pip install -e ".[develop]" + ``` + +5. The functions which download resource data require an NREL API key. Obtain a key from: + [https://developer.nrel.gov/signup/](https://developer.nrel.gov/signup/) -7. To set up the `NREL_API_KEY` and `NREL_API_EMAIL` required for resource downloads, you can create Environment Variables called `NREL_API_KEY` and `NREL_API_EMAIL`. Otherwise, you can keep the key in a new file called ".env" in the root directory of this project. +6. To set up the `NREL_API_KEY` and `NREL_API_EMAIL` required for resource downloads, you can create Environment Variables called `NREL_API_KEY` and `NREL_API_EMAIL`. Otherwise, you can keep the key in a new file called ".env" in the root directory of this project. Create a file ".env" that contains the single line: - ``` + + ```bash NREL_API_KEY=key NREL_API_EMAIL=your.name@email.com ``` -8. Verify setup by running tests: - ``` +7. Verify setup by running tests: + + ```bash pytest tests/hopp ``` - -2. To set up `NREL_API_KEY` for resource downloads, first refer to section 7 and 8 above. But for the `.env` file method, +8. To set up `NREL_API_KEY` for resource downloads, first refer to section 6 and 7 above. But for the `.env` file method, the file should go in the working directory of your Python project, e.g. directory from where you run `python`. ## Getting Started diff --git a/hopp/__init__.py b/hopp/__init__.py index 1c17dad09..bb24154a4 100644 --- a/hopp/__init__.py +++ b/hopp/__init__.py @@ -1,8 +1,7 @@ from pathlib import Path -with open(Path(__file__).parent / "version.py") as _version_file: - __version__ = _version_file.read().strip() +__version__ = "2.2.0" ROOT_DIR = Path(__file__).resolve().parent diff --git a/hopp/version.py b/hopp/version.py deleted file mode 100644 index ccbccc3dc..000000000 --- a/hopp/version.py +++ /dev/null @@ -1 +0,0 @@ -2.2.0 diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..48d25c760 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,144 @@ +[build-system] +requires = ["setuptools", "setuptools-scm"] +build-backend = "setuptools.build_meta" + +[project] +name = "HOPP" +dynamic = ["version"] +authors = [{name = "NREL", email = "dguittet@nrel.gov"}] +readme = {file = "README.md", content-type = "text/markdown"} +description = "Hybrid Systems Optimization and Performance Platform." +requires-python = ">=3.9, <3.12" +license = {file = "LICENSE"} +dependencies = [ + "Cython", + "NREL-PySAM==4.2.0", + "Pillow", + "Pyomo>=6.1.2", + "diskcache", + "fastkml", + "floris", + "future", + "global_land_mask", + "humpday", + "hybridbosse", + "lcoe", + "lxml", + "matplotlib", + "multiprocessing-on-dill", + "nevergrad", + "numpy", + "numpy-financial", + "optuna", + "pandas>=2.0.3", + "pint", + "pvmismatch", + "pyDOE2", + "pymoo", + "pyproj", + "pysolar", + "pysot", + "python-dotenv", + "python-rapidjson", + "pytz", + "rainflow", + "requests", + "scikit-learn", + "scikit-optimize", + "scipy", + "shapely>=1.8.5,<2.0.0", + "setuptools", + "timezonefinder", + "urllib3", + "openpyxl", + "CoolProp", + "attrs", + "utm", + "pyyaml-include", +] +keywords = [ + "python3", + "wind-energy", + "operations", + "operational-analysis", + "operational-assessement", + "turbine-performance", + "wind-plant-performance", +] +classifiers = [ # https://pypi.org/classifiers/ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Intended Audience :: Science/Research", + "Intended Audience :: Other Audience", + "License :: OSI Approved :: BSD License", + "Natural Language :: English", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Topic :: Scientific/Engineering", + "Topic :: Software Development :: Libraries :: Python Modules", +] + +[project.urls] +source = "https://github.com/NREL/HOPP" +documentation = "https://hopp.readthedocs.io/" +issues = "https://github.com/NREL/HOPP/issues" +changelog = "https://github.com/NREL/HOPP/blob/main/RELEASE.md" + +[project.optional-dependencies] +develop = [ + "pytest", + "pytest-subtests", + "responses", + "sphinx", + "sphinx-rtd-theme", + "sphinx-copybutton", +] +examples = ["jupyterlab"] +all = ["openoa[develop,examples]"] + +[tool.setuptools] +include-package-data = true + +[tool.setuptools.packages.find] +include = [ + "hopp/hydrogen/h2_storage/pressure_vessel/compressed_gas_storage_model_20221021/Tankinator.xlsx", + "hydrogen/h2_transport/data_tables/*.csv", + "tools/analysis/bos/BOSLookup.csv", + "simulation/technologies/layout/flicker_data/*shadow.txt", + "simulation/technologies/layout/flicker_data/*flicker.txt", + "simulation/technologies/csp/pySSC_daotk/libs/*", + "simulation/technologies/csp/pySSC_daotk/tower_data/*", + "simulation/technologies/csp/pySSC_daotk/trough_data/*", + "simulation/technologies/dispatch/cbc_solver/cbc-win64/*", + "simulation/resource_files/*", + "simulation/resource_files/*/*", +] + +[tool.setuptools.dynamic] +version = {attr = "hopp.__version__"} + +[tool.coverage.report] +exclude_lines = ["# pragma: no cover"] + +[tool.coverage.run] +# Coverage.py configuration file +# https://coverage.readthedocs.io/en/latest/config.html +branch = true +source = ["hopp/*"] +omit = [ + "setup.py", + "tests/*" +] + +[tool.pytest.ini_options] +python_files = [ + "tests/*.py", +] +testpaths = [ + "test/hopp/*.py", + "test/greenheart/*.py", +] diff --git a/requirements-dev.txt b/requirements-dev.txt deleted file mode 100644 index d0019162e..000000000 --- a/requirements-dev.txt +++ /dev/null @@ -1,6 +0,0 @@ -pytest -pytest-subtests -responses -sphinx -sphinx-rtd-theme -sphinx-copybutton \ No newline at end of file diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index c93029223..000000000 --- a/requirements.txt +++ /dev/null @@ -1,44 +0,0 @@ -Cython -NREL-PySAM==4.2.0 -Pillow -Pyomo>=6.1.2 -diskcache -fastkml -floris -future -global_land_mask -humpday -hybridbosse -lcoe -lxml -matplotlib -multiprocessing-on-dill -nevergrad -numpy -numpy-financial -optuna -pandas>=2.0.3 -pint -pvmismatch -pyDOE2 -pymoo -pyproj -pysolar -pysot -python-dotenv -python-rapidjson -pytz -rainflow -requests -scikit-learn -scikit-optimize -scipy -shapely>=1.8.5,<2.0.0 -setuptools -timezonefinder -urllib3 -openpyxl -CoolProp -attrs -utm -pyyaml-include diff --git a/setup.py b/setup.py deleted file mode 100644 index e692c5f10..000000000 --- a/setup.py +++ /dev/null @@ -1,54 +0,0 @@ -from pathlib import Path -from setuptools import setup, find_packages -import re - - -# Package meta-data. -NAME = "HOPP" -DESCRIPTION = "Hybrid Systems Optimization and Performance Platform." -URL = "https://github.com/NREL/HOPP" -EMAIL = "dguittet@nrel.gov" -AUTHOR = "NREL" -REQUIRES_PYTHON = ">=3.8.0" - -ROOT = Path(__file__).parent -with open(ROOT / "hopp" / "version.py") as version_file: - VERSION = version_file.read().strip() - -# Get package data -base_path = Path("hopp") -package_data_files = [ - base_path / "hydrogen" / "h2_storage" / "pressure_vessel" / "compressed_gas_storage_model_20221021" / "Tankinator.xlsx", - *base_path.glob("hydrogen/h2_transport/data_tables/*.csv"), - *base_path.glob("tools/analysis/bos/BOSLookup.csv"), - *base_path.glob("simulation/technologies/layout/flicker_data/*shadow.txt"), - *base_path.glob("simulation/technologies/layout/flicker_data/*flicker.txt"), - *base_path.glob("simulation/technologies/csp/pySSC_daotk/libs/*"), - *base_path.glob("simulation/technologies/csp/pySSC_daotk/tower_data/*"), - *base_path.glob("simulation/technologies/csp/pySSC_daotk/trough_data/*"), - *base_path.glob("simulation/technologies/dispatch/cbc_solver/cbc-win64/*"), - *base_path.glob("simulation/resource_files/*"), - *base_path.glob("simulation/resource_files/*/*") -] - -package_data = { - "hopp": [str(file.relative_to(base_path)) for file in package_data_files] -} - -setup( - name=NAME, - version=VERSION, - url=URL, - description=DESCRIPTION, - long_description=(base_path.parent / "RELEASE.md").read_text(), - long_description_content_type='text/markdown', - license='BSD 3-Clause', - author=AUTHOR, - author_email=EMAIL, - python_requires=REQUIRES_PYTHON, - packages=find_packages(), - package_data=package_data, - include_package_data=True, - install_requires=(base_path.parent / "requirements.txt").read_text().splitlines(), - tests_require=['pytest', 'pytest-subtests', 'responses'] -)