diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..33a3b7f --- /dev/null +++ b/Makefile @@ -0,0 +1,44 @@ +# Note: use tabs +# actions which are virtual, i.e. not a script +.PHONY: install install-for-dev install-deps install-flexmeasures-entsoe test freeze-deps upgrade-deps + + +# ---- Development --- + +test: + make install-for-dev + pytest + +# ---- Installation --- + +install: install-deps install-flexmeasures-entsoe + +install-for-dev: + make freeze-deps + pip-sync requirements/app.txt requirements/dev.txt requirements/test.txt + make install-flexmeasures-entsoe + pre-commit install + +install-deps: + make install-pip-tools + make freeze-deps + pip-sync requirements/app.txt + +install-flexmeasures-entsoe: + python setup.py develop + +install-pip-tools: + pip3 install -q "pip-tools>=6.2" + +freeze-deps: + make install-pip-tools + pip-compile -o requirements/app.txt requirements/app.in + pip-compile -o requirements/test.txt requirements/test.in + pip-compile -o requirements/dev.txt requirements/dev.in + +upgrade-deps: + make install-pip-tools + pip-compile --upgrade -o requirements/app.txt requirements/app.in + pip-compile --upgrade -o requirements/test.txt requirements/test.in + pip-compile --upgrade -o requirements/dev.txt requirements/dev.in + make test diff --git a/README.md b/README.md index 9a02d33..41a821a 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,7 @@ Use ``--help`` to learn more usage details. First of all, this is a FlexMeasures plugin. Consult the FlexMeasures documentation for setup. -1. Add the path to this directory to your FlexMeasures (>v0.4.0) config file, -using the `FLEXMEASURES_PLUGINS` setting. +1. Add the plugin to [the `FLEXMEASURES_PLUGINS` setting](https://flexmeasures.readthedocs.io/en/latest/configuration.html#plugin-config). Either use `/path/to/flexmeasures-entsoe/flexmeasures_entsoe` or `flexmeasures_entsoe` if you installed this as a package locally (see below). 2. Add `ENTSOE_AUTH_TOKEN` to your FlexMeasures config (e.g. ~/.flexmeasures.cfg). You can generate this token after you made an account at ENTSO-E, read more [here](https://transparency.entsoe.eu/content/static_content/Static%20content/web%20api/Guide.html#_authentication_and_authorisation). @@ -41,7 +40,7 @@ You can generate this token after you made an account at ENTSO-E, read more [her The `ENTSOE_DERIVED_DATA_SOURCE` option is used to name the source of data that this plugin derives from ENTSO-E data, like a CO₂ signal. Original ENTSO-E data is reported as being sourced by `"ENTSO-E"`. -3. `pip install entsoe-py` +3. To install this plugin locally as a package, try `pip install .`. ## Testing @@ -61,4 +60,11 @@ To keep our code quality high, we use pre-commit: pip install pre-commit black flake8 mypy pre-commit install + +or: + + make install-for-dev + +Try it: + pre-commit run --all-files --show-diff-on-failure diff --git a/__init__.py b/flexmeasures_entsoe/__init__.py similarity index 100% rename from __init__.py rename to flexmeasures_entsoe/__init__.py diff --git a/flexmeasures_entsoe/generation/__init__.py b/flexmeasures_entsoe/generation/__init__.py new file mode 100644 index 0000000..8362b36 --- /dev/null +++ b/flexmeasures_entsoe/generation/__init__.py @@ -0,0 +1,10 @@ +from datetime import timedelta + +# sensor_name, unit, event_resolution, data sourced directly by ENTSO-E or not (i.e. derived) +generation_sensors = ( + ("Scheduled generation", "MW", timedelta(minutes=15), True), + ("Solar", "MW", timedelta(hours=1), True), + ("Wind Onshore", "MW", timedelta(hours=1), True), + ("Wind Offshore", "MW", timedelta(hours=1), True), + ("CO₂ intensity", "kg/MWh", timedelta(minutes=15), False), +) diff --git a/generation/day_ahead.py b/flexmeasures_entsoe/generation/day_ahead.py similarity index 96% rename from generation/day_ahead.py rename to flexmeasures_entsoe/generation/day_ahead.py index ca7d9fa..d4ce3d6 100644 --- a/generation/day_ahead.py +++ b/flexmeasures_entsoe/generation/day_ahead.py @@ -4,8 +4,6 @@ import click from flask.cli import with_appcontext from flask import current_app -import entsoe -from entsoe import EntsoePandasClient # from entsoe.entsoe import URL import pandas as pd @@ -13,8 +11,6 @@ from .. import ( entsoe_data_bp, - DEFAULT_COUNTRY_CODE, - DEFAULT_COUNTRY_TIMEZONE, ) # noqa: E402 from . import generation_sensors from ..utils import ( @@ -22,7 +18,6 @@ ensure_country_code_and_timezone, ensure_data_source, ensure_data_source_for_derived_data, - get_auth_token_from_config_and_set_server_url, abort_if_data_empty, parse_from_and_to_dates_default_today_and_tomorrow, save_entsoe_series, @@ -100,11 +95,12 @@ def import_day_ahead_generation( when tomorrow's prices are announced. """ # Set up FlexMeasures data structure - country_code, country_timezone = ensure_country_code_and_timezone(country_code, country_timezone) + country_code, country_timezone = ensure_country_code_and_timezone( + country_code, country_timezone + ) entsoe_data_source = ensure_data_source() derived_data_source = ensure_data_source_for_derived_data() sensors = ensure_sensors(generation_sensors, country_code, country_timezone) - # Parse CLI options (or set defaults) from_time, until_time = parse_from_and_to_dates_default_today_and_tomorrow( from_date, to_date, country_timezone @@ -112,7 +108,9 @@ def import_day_ahead_generation( # Start import client = create_entsoe_client() - log, now = start_import_log("day-ahead generation", from_time, until_time, country_code, country_timezone) + log, now = start_import_log( + "day-ahead generation", from_time, until_time, country_code, country_timezone + ) log.info("Getting scheduled generation ...") # We assume that the green (solar & wind) generation is not included in this (it is not scheduled) diff --git a/generation/utils.py b/flexmeasures_entsoe/generation/utils.py similarity index 100% rename from generation/utils.py rename to flexmeasures_entsoe/generation/utils.py diff --git a/prices/__init__.py b/flexmeasures_entsoe/prices/__init__.py similarity index 100% rename from prices/__init__.py rename to flexmeasures_entsoe/prices/__init__.py diff --git a/prices/day_ahead.py b/flexmeasures_entsoe/prices/day_ahead.py similarity index 89% rename from prices/day_ahead.py rename to flexmeasures_entsoe/prices/day_ahead.py index 211705e..154fa1b 100644 --- a/prices/day_ahead.py +++ b/flexmeasures_entsoe/prices/day_ahead.py @@ -3,12 +3,9 @@ import click from flask.cli import with_appcontext -from flask import current_app import pandas as pd from flexmeasures import Source, Sensor -import entsoe -from entsoe import EntsoePandasClient from flexmeasures.data.transactional import task_with_status_report from flexmeasures.data.schemas import ( @@ -20,8 +17,6 @@ from . import pricing_sensors from .. import ( entsoe_data_bp, - DEFAULT_COUNTRY_CODE, - DEFAULT_COUNTRY_TIMEZONE, ) # noqa: E402 from ..utils import ( create_entsoe_client, @@ -30,7 +25,6 @@ parse_from_and_to_dates_default_today_and_tomorrow, ensure_sensors, save_entsoe_series, - get_auth_token_from_config_and_set_server_url, abort_if_data_empty, start_import_log, ) @@ -97,7 +91,9 @@ def import_day_ahead_prices( when tomorrow's prices are announced. """ # Set up FlexMeasures data structure - country_code, country_timezone = ensure_country_code_and_timezone(country_code, country_timezone) + country_code, country_timezone = ensure_country_code_and_timezone( + country_code, country_timezone + ) if source is None: entsoe_data_source = ensure_data_source() @@ -119,7 +115,9 @@ def import_day_ahead_prices( # Start import client = create_entsoe_client() - log, now = start_import_log("day-ahead price", from_time, until_time, country_code, country_timezone) + log, now = start_import_log( + "day-ahead price", from_time, until_time, country_code, country_timezone + ) log.info("Getting prices ...") prices: pd.Series = client.query_day_ahead_prices( @@ -131,4 +129,6 @@ def import_day_ahead_prices( if not dryrun: log.info(f"Saving {len(prices)} beliefs for Sensor {pricing_sensor.name} ...") prices.name = "event_value" # required by timely_beliefs, TODO: check if that still is the case, see https://github.com/SeitaBV/timely-beliefs/issues/64 - save_entsoe_series(prices, pricing_sensor, entsoe_data_source, country_timezone, now) + save_entsoe_series( + prices, pricing_sensor, entsoe_data_source, country_timezone, now + ) diff --git a/utils.py b/flexmeasures_entsoe/utils.py similarity index 100% rename from utils.py rename to flexmeasures_entsoe/utils.py diff --git a/generation/__init__.py b/generation/__init__.py deleted file mode 100644 index 4696c2a..0000000 --- a/generation/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -from datetime import timedelta - -# sensor_name, unit, event_resolution, data sourced directly by ENTSO-E or not (i.e. derived) -generation_sensors = ( - ("Scheduled generation", "MW", timedelta(minutes=15), True), - ("Solar", "MW", timedelta(hours=1), True), - ("Wind Onshore", "MW", timedelta(hours=1), True), - ("Wind Offshore", "MW", timedelta(hours=1), True), - ("CO₂ intensity", "kg/MWh", timedelta(minutes=15), False), -) diff --git a/requirements/Readme.md b/requirements/Readme.md new file mode 100644 index 0000000..4550b13 --- /dev/null +++ b/requirements/Readme.md @@ -0,0 +1,21 @@ +# Requirements + +All FlexMeasures requirements are specified in this directory. +We separate by use case: + +- app: All requirements for running the FlexMeasures platform +- test: Additional requirements used for running automated tests +- dev: Additional requirements used for developers (this includes testing) + +Also note the following distinction: + + +## .in files + +Here, we describe the requirements. We give the name of a requirement or even a range (e.g. `>=1.0.`). + +## .txt files + +These files are not to be edited by hand. They are created by `pip-compile` (or `make freeze-deps`). + +Each requirement is pinned to a specific version in these files. The great benefit is reproducibility across environments (local dev as well as staging or production). diff --git a/requirements/app.in b/requirements/app.in new file mode 100644 index 0000000..b0a9744 --- /dev/null +++ b/requirements/app.in @@ -0,0 +1,2 @@ +flexmeasures>=0.9.3 +entsoe-py diff --git a/requirements/app.txt b/requirements/app.txt new file mode 100644 index 0000000..274fa82 --- /dev/null +++ b/requirements/app.txt @@ -0,0 +1,381 @@ +# +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: +# +# pip-compile --output-file=requirements/app.txt requirements/app.in +# +alembic==1.11.1 + # via flask-migrate +altair==5.0.1 + # via flexmeasures +annotated-types==0.5.0 + # via pydantic +arrow==1.2.3 + # via rq-dashboard +async-timeout==4.0.2 + # via redis +attrs==23.1.0 + # via + # jsonschema + # referencing +babel==2.12.1 + # via py-moneyed +bcrypt==4.0.1 + # via flexmeasures +beautifulsoup4==4.12.2 + # via entsoe-py +blinker==1.6.2 + # via + # flask-mail + # flask-principal + # flask-security-too + # sentry-sdk +certifi==2023.7.22 + # via + # requests + # sentry-sdk +charset-normalizer==3.2.0 + # via requests +click==8.1.6 + # via + # click-default-group + # flask + # flexmeasures + # rq +click-default-group==1.2.2 + # via flexmeasures +colour==0.1.5 + # via flexmeasures +contourpy==1.1.0 + # via matplotlib +convertdate==2.4.0 + # via workalendar +cycler==0.11.0 + # via matplotlib +deprecated==1.2.14 + # via sktime +dill==0.3.7 + # via openturns +dnspython==2.4.1 + # via email-validator +email-validator==2.0.0.post2 + # via + # flask-security-too + # flexmeasures +entsoe-py==0.5.10 + # via -r requirements/app.in +filelock==3.12.2 + # via tldextract +flask==2.1.2 + # via + # flask-classful + # flask-cors + # flask-json + # flask-login + # flask-mail + # flask-marshmallow + # flask-migrate + # flask-principal + # flask-security-too + # flask-sqlalchemy + # flask-sslify + # flask-wtf + # flexmeasures + # rq-dashboard + # sentry-sdk +flask-classful==0.14.2 + # via flexmeasures +flask-cors==4.0.0 + # via flexmeasures +flask-json==0.3.5 + # via flexmeasures +flask-login==0.6.1 + # via + # flask-security-too + # flexmeasures +flask-mail==0.9.1 + # via flexmeasures +flask-marshmallow==0.15.0 + # via flexmeasures +flask-migrate==4.0.4 + # via flexmeasures +flask-principal==0.4.0 + # via flask-security-too +flask-security-too==5.1.2 + # via flexmeasures +flask-sqlalchemy==2.5.1 + # via + # flask-migrate + # flexmeasures +flask-sslify==0.1.5 + # via flexmeasures +flask-wtf==1.1.1 + # via + # flask-security-too + # flexmeasures +flexmeasures==0.14.2 + # via -r requirements/app.in +fonttools==4.41.1 + # via matplotlib +greenlet==2.0.2 + # via sqlalchemy +humanize==4.7.0 + # via flexmeasures +idna==3.4 + # via + # email-validator + # requests + # tldextract +importlib-metadata==6.8.0 + # via + # flexmeasures + # timely-beliefs +inflect==7.0.0 + # via flexmeasures +inflection==0.5.1 + # via flexmeasures +iso8601==2.0.0 + # via flexmeasures +isodate==0.6.1 + # via + # flexmeasures + # timely-beliefs +itsdangerous==2.1.2 + # via + # flask + # flask-security-too + # flask-wtf +jinja2==3.1.2 + # via + # altair + # flask +joblib==1.3.1 + # via scikit-learn +jsonschema==4.18.4 + # via altair +jsonschema-specifications==2023.7.1 + # via jsonschema +kiwisolver==1.4.4 + # via matplotlib +lunardate==0.2.0 + # via workalendar +mako==1.2.4 + # via alembic +markupsafe==2.1.3 + # via + # jinja2 + # mako + # sentry-sdk + # wtforms +marshmallow==3.20.1 + # via + # flask-marshmallow + # flexmeasures + # marshmallow-polyfield + # marshmallow-sqlalchemy + # webargs +marshmallow-polyfield==5.11 + # via flexmeasures +marshmallow-sqlalchemy==0.29.0 + # via flexmeasures +matplotlib==3.7.2 + # via timetomodel +numpy==1.23.5 + # via + # altair + # contourpy + # flexmeasures + # matplotlib + # pandas + # patsy + # properscoring + # scikit-learn + # scipy + # sktime + # statsmodels + # timely-beliefs + # timetomodel + # uniplot +openturns==1.21 + # via timely-beliefs +packaging==23.1 + # via + # flask-marshmallow + # marshmallow + # marshmallow-sqlalchemy + # matplotlib + # sktime + # statsmodels + # webargs +pandas==2.0.3 + # via + # altair + # entsoe-py + # flexmeasures + # sktime + # statsmodels + # timely-beliefs + # timetomodel +passlib==1.7.4 + # via flask-security-too +patsy==0.5.3 + # via statsmodels +pillow==10.0.0 + # via matplotlib +pint==0.22 + # via flexmeasures +ply==3.11 + # via pyomo +properscoring==0.1 + # via timely-beliefs +pscript==0.7.7 + # via flexmeasures +psutil==5.9.5 + # via openturns +psycopg2-binary==2.9.6 + # via + # flexmeasures + # timely-beliefs +py-moneyed==3.0 + # via flexmeasures +pydantic==2.1.1 + # via inflect +pydantic-core==2.4.0 + # via pydantic +pyluach==2.2.0 + # via workalendar +pymeeus==0.5.12 + # via convertdate +pyomo==6.6.1 + # via flexmeasures +pyparsing==3.0.9 + # via matplotlib +python-dateutil==2.8.2 + # via + # arrow + # matplotlib + # pandas + # timetomodel + # workalendar +python-dotenv==1.0.0 + # via flexmeasures +pytz==2023.3 + # via + # entsoe-py + # flexmeasures + # pandas + # timely-beliefs + # timetomodel +redis==4.6.0 + # via + # flexmeasures + # rq + # rq-dashboard +referencing==0.30.0 + # via + # jsonschema + # jsonschema-specifications +requests==2.31.0 + # via + # entsoe-py + # requests-file + # tldextract +requests-file==1.5.1 + # via tldextract +rpds-py==0.9.2 + # via + # jsonschema + # referencing +rq==1.15.1 + # via + # flexmeasures + # rq-dashboard +rq-dashboard==0.6.1 + # via flexmeasures +scikit-base==0.5.0 + # via sktime +scikit-learn==1.3.0 + # via + # sktime + # timetomodel +scipy==1.11.1 + # via + # properscoring + # scikit-learn + # sktime + # statsmodels + # timely-beliefs + # timetomodel +sentry-sdk[flask]==1.29.2 + # via flexmeasures +six==1.16.0 + # via + # isodate + # patsy + # python-dateutil + # requests-file +sktime==0.21.0 + # via timely-beliefs +soupsieve==2.4.1 + # via beautifulsoup4 +sqlalchemy==1.4.49 + # via + # alembic + # flask-sqlalchemy + # flexmeasures + # marshmallow-sqlalchemy + # timely-beliefs + # timetomodel +statsmodels==0.14.0 + # via timetomodel +tabulate==0.9.0 + # via flexmeasures +threadpoolctl==3.2.0 + # via scikit-learn +timely-beliefs[forecast]==1.21.0 + # via flexmeasures +timetomodel==0.7.3 + # via flexmeasures +tldextract==3.4.4 + # via flexmeasures +toolz==0.12.0 + # via altair +typing-extensions==4.7.1 + # via + # alembic + # altair + # inflect + # pint + # py-moneyed + # pydantic + # pydantic-core +tzdata==2023.3 + # via pandas +uniplot==0.10.0 + # via flexmeasures +urllib3==2.0.4 + # via + # requests + # sentry-sdk +webargs==8.3.0 + # via flexmeasures +werkzeug==2.0.3 + # via + # flask + # flask-login + # flexmeasures +workalendar==17.0.0 + # via flexmeasures +wrapt==1.15.0 + # via deprecated +wtforms==3.0.1 + # via + # flask-security-too + # flask-wtf +xlrd==2.0.1 + # via flexmeasures +zipp==3.16.2 + # via importlib-metadata + +# The following packages are considered to be unsafe in a requirements file: +# setuptools diff --git a/requirements/dev.in b/requirements/dev.in new file mode 100644 index 0000000..5527d55 --- /dev/null +++ b/requirements/dev.in @@ -0,0 +1,12 @@ +-c app.txt +-c test.txt + +pre-commit +black +flake8 +flake8-blind-except +mypy +pytest-runner +types-pytz +setuptools_scm +watchdog \ No newline at end of file diff --git a/requirements/dev.txt b/requirements/dev.txt new file mode 100644 index 0000000..c737781 --- /dev/null +++ b/requirements/dev.txt @@ -0,0 +1,81 @@ +# +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: +# +# pip-compile --output-file=requirements/dev.txt requirements/dev.in +# +black==23.7.0 + # via -r requirements/dev.in +cfgv==3.3.1 + # via pre-commit +click==8.1.6 + # via + # -c requirements/app.txt + # -c requirements/test.txt + # black +distlib==0.3.7 + # via virtualenv +filelock==3.12.2 + # via + # -c requirements/app.txt + # virtualenv +flake8==6.1.0 + # via -r requirements/dev.in +flake8-blind-except==0.2.1 + # via -r requirements/dev.in +identify==2.5.26 + # via pre-commit +mccabe==0.7.0 + # via flake8 +mypy==1.4.1 + # via -r requirements/dev.in +mypy-extensions==1.0.0 + # via + # black + # mypy +nodeenv==1.8.0 + # via pre-commit +packaging==23.1 + # via + # -c requirements/app.txt + # -c requirements/test.txt + # black + # setuptools-scm +pathspec==0.11.2 + # via black +platformdirs==3.10.0 + # via + # black + # virtualenv +pre-commit==3.3.3 + # via -r requirements/dev.in +pycodestyle==2.11.0 + # via flake8 +pyflakes==3.1.0 + # via flake8 +pytest-runner==6.0.0 + # via -r requirements/dev.in +pyyaml==6.0.1 + # via pre-commit +setuptools-scm==7.1.0 + # via -r requirements/dev.in +tomli==2.0.1 + # via + # -c requirements/test.txt + # black + # mypy + # setuptools-scm +types-pytz==2023.3.0.0 + # via -r requirements/dev.in +typing-extensions==4.7.1 + # via + # -c requirements/app.txt + # mypy + # setuptools-scm +virtualenv==20.24.2 + # via pre-commit +watchdog==3.0.0 + # via -r requirements/dev.in + +# The following packages are considered to be unsafe in a requirements file: +# setuptools diff --git a/requirements/test.in b/requirements/test.in new file mode 100644 index 0000000..c2b2bcc --- /dev/null +++ b/requirements/test.in @@ -0,0 +1,6 @@ +-c app.txt + +pytest +pytest-flask +pytest-sugar +pytest-cov \ No newline at end of file diff --git a/requirements/test.txt b/requirements/test.txt new file mode 100644 index 0000000..8ebc037 --- /dev/null +++ b/requirements/test.txt @@ -0,0 +1,62 @@ +# +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: +# +# pip-compile --output-file=requirements/test.txt requirements/test.in +# +click==8.1.6 + # via + # -c requirements/app.txt + # flask +coverage[toml]==7.2.7 + # via pytest-cov +exceptiongroup==1.1.2 + # via pytest +flask==2.1.2 + # via + # -c requirements/app.txt + # pytest-flask +iniconfig==2.0.0 + # via pytest +itsdangerous==2.1.2 + # via + # -c requirements/app.txt + # flask +jinja2==3.1.2 + # via + # -c requirements/app.txt + # flask +markupsafe==2.1.3 + # via + # -c requirements/app.txt + # jinja2 +packaging==23.1 + # via + # -c requirements/app.txt + # pytest + # pytest-sugar +pluggy==1.2.0 + # via pytest +pytest==7.4.0 + # via + # -r requirements/test.in + # pytest-cov + # pytest-flask + # pytest-sugar +pytest-cov==4.1.0 + # via -r requirements/test.in +pytest-flask==1.2.0 + # via -r requirements/test.in +pytest-sugar==0.9.7 + # via -r requirements/test.in +termcolor==2.3.0 + # via pytest-sugar +tomli==2.0.1 + # via + # coverage + # pytest +werkzeug==2.0.3 + # via + # -c requirements/app.txt + # flask + # pytest-flask diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..1a6aebd --- /dev/null +++ b/setup.cfg @@ -0,0 +1,10 @@ +[aliases] +test = pytest +flake8 = flake8 + +[flake8] +exclude = .git,__pycache__,documentation +max-line-length = 160 +max-complexity = 13 +select = B,C,E,F,W,B9 +ignore = E501, W503, E203 diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..89abb45 --- /dev/null +++ b/setup.py @@ -0,0 +1,47 @@ +from setuptools import setup, find_packages + + +def load_requirements(use_case): + """ + Loading range requirements. + Packaging should be used for installing the package into existing stacks. + We therefore read the .in file for the use case. + .txt files include the exact pins, and are useful for deployments with + exactly comparable environments. + """ + reqs = [] + with open("requirements/%s.in" % use_case, "r") as f: + reqs = [ + req + for req in f.read().splitlines() + if not req.strip() == "" + and not req.strip().startswith("#") + and not req.strip().startswith("-c") + and not req.strip().startswith("--find-links") + ] + return reqs + + +setup( + name="flexmeasures-entsoe", + description="Integrating FlexMeasures with ENTSO-E", + author="Seita Energy Flexibility BV", + author_email="nicolas@seita.nl", + url="https://github.com/SeitaBV/flexmeasures-entsoe", + keywords=["flexmeasures", "energy flexibility"], + install_requires=load_requirements("app"), + tests_require=load_requirements("test"), + setup_requires=["pytest-runner", "setuptools_scm"], + use_scm_version={"local_scheme": "no-local-version"}, # handled by setuptools_scm + packages=find_packages(), + include_package_data=True, # setuptools_scm takes care of adding the files in SCM + classifiers=[ + "Programming Language :: Python", + "Programming Language :: Python :: 3.9", + "Development Status :: 3 - Alpha", + "License :: OSI Approved :: Apache Software License", + "Operating System :: OS Independent", + ], + long_description="""\ +""", +)