diff --git a/.github/workflows/mkdocs-main.yml b/.github/workflows/mkdocs-main.yml index a77180fc5..b9a3be434 100644 --- a/.github/workflows/mkdocs-main.yml +++ b/.github/workflows/mkdocs-main.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: fetch-depth: 0 @@ -15,13 +15,13 @@ jobs: working-directory: ./java run: echo "DEV_VERSION=$(mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep -Ev 'Download|INFO|WARNING')" >> $GITHUB_ENV - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v5 with: - python-version: '3.8' + python-version: "3.10" - name: install deps working-directory: ./python - run: cp ../README.md . && pip3 install 'git+https://github.com/logicalclocks/feature-store-api@master#egg=hsfs[python]&subdirectory=python' && pip3 install -e .[dev,docs] + run: cp ../README.md . && pip3 install 'hsfs[python] @ git+https://github.com/logicalclocks/feature-store-api@master#subdirectory=python' && pip3 install -e .[dev,docs] - name: generate autodoc run: python3 auto_doc.py @@ -33,4 +33,3 @@ jobs: - name: mike deploy docs run: mike deploy ${{ env.DEV_VERSION }} dev -u - diff --git a/.github/workflows/mkdocs-release.yml b/.github/workflows/mkdocs-release.yml index 44c9e9080..8c4728d02 100644 --- a/.github/workflows/mkdocs-release.yml +++ b/.github/workflows/mkdocs-release.yml @@ -2,14 +2,14 @@ name: mkdocs-release on: push: - branches: [ branch-* ] + branches: [branch-*] jobs: publish-release: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: fetch-depth: 0 @@ -20,16 +20,13 @@ jobs: - name: set major/minor release version run: echo "MAJOR_VERSION=$(echo $RELEASE_VERSION | sed 's/^\([0-9]*\.[0-9]*\).*$/\1/')" >> $GITHUB_ENV - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v5 with: - python-version: '3.8' + python-version: "3.10" - name: install deps working-directory: ./python - run: cp ../README.md . && pip3 install pip==22.0.3 && pip3 install -e .[dev,docs] - - - name: use dev mike - run: pip3 uninstall -y mike && pip3 install git+'https://github.com/jimporter/mike.git' + run: cp ../README.md . && pip3 install -e .[dev,docs] - name: generate autodoc run: python3 auto_doc.py @@ -43,4 +40,3 @@ jobs: run: | mike deploy ${{ env.RELEASE_VERSION }} ${{ env.MAJOR_VERSION }} -u --push mike alias ${{ env.RELEASE_VERSION }} latest -u --push - diff --git a/.github/workflows/python-lint.yml b/.github/workflows/python-lint.yml index d21f04dc8..156847faf 100644 --- a/.github/workflows/python-lint.yml +++ b/.github/workflows/python-lint.yml @@ -11,21 +11,39 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 - with: - python-version: '3.8' - - name: install deps - run: pip install flake8==3.9.0 black==22.3.0 pre-commit-hooks==2.4.0 - - - name: black - run: black --check python + - uses: actions/checkout@v4 - - name: flake8 - run: flake8 --config python/.flake8 python + - uses: actions/setup-python@v5 + with: + python-version: "3.11" - - name: trailing-whitespace-fixer - run: trailing-whitespace-fixer $(find python -name "*.py" -type f) || exit 1 + - name: Get all changed files + id: get-changed-files + uses: tj-actions/changed-files@v44 + with: + files_yaml: | + src: + - 'python/**/*.py' + - '!python/tests/**/*.py' + test: + - 'python/tests/**/*.py' - - name: end-of-file-fixer - run: end-of-file-fixer $(find python -name "*.py" -type f) || exit 1 \ No newline at end of file + - name: install deps + run: pip install ruff==0.4.2 + + - name: ruff on python files + if: steps.get-changed-files.outputs.src_any_changed == 'true' + env: + SRC_ALL_CHANGED_FILES: ${{ steps.get-changed-files.outputs.src_all_changed_files }} + run: ruff check --output-format=github $SRC_ALL_CHANGED_FILES + + - name: ruff on test files + if: steps.get-changed-files.outputs.test_any_changed == 'true' + env: + TEST_ALL_CHANGED_FILES: ${{ steps.get-changed-files.outputs.test_all_changed_files }} + run: ruff check --output-format=github $TEST_ALL_CHANGED_FILES + + - name: ruff format --check $ALL_CHANGED_FILES + env: + ALL_CHANGED_FILES: ${{ steps.get-changed-files.outputs.all_changed_files }} + run: ruff format $ALL_CHANGED_FILES \ No newline at end of file diff --git a/.gitignore b/.gitignore index 084020b82..6e96d8144 100644 --- a/.gitignore +++ b/.gitignore @@ -50,6 +50,7 @@ coverage.xml *.cover .hypothesis/ .pytest_cache/ +.ruff_cache/ # Translations *.mo diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7e43c1936..58f07bfae 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -74,7 +74,7 @@ We use `mkdocs` together with `mike` ([for versioning](https://github.com/jimpor 1. Currently we are using our own version of `keras-autodoc` ```bash - pip install git+https://github.com/moritzmeister/keras-autodoc@split-tags-properties + pip install git+https://github.com/logicalclocks/keras-autodoc ``` 2. Install HOPSWORKS with `docs` extras: diff --git a/README.md b/README.md index 71106c9d7..162c95f97 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ src="https://img.shields.io/badge/docs-HOPSWORKS-orange" alt="Hopsworks Documentation" /> + python PyPiStatus - CodeStyleRuff

-*hopsworks* is the python API for interacting with a Hopsworks cluster. +*hopsworks* is the python API for interacting with a Hopsworks cluster. Don't have a Hopsworks cluster just yet? Register an account on [Hopsworks Serverless](https://app.hopsworks.ai/) and get started for free. Once connected to your project, you can: + - Insert dataframes into the online or offline Store, create training datasets or *serve real-time* feature vectors in the Feature Store via the [Feature Store API](https://github.com/logicalclocks/feature-store-api). Already have data somewhere you want to import, checkout our [Storage Connectors](https://docs.hopsworks.ai/latest/user_guides/fs/storage_connector/) documentation. + - register ML models in the model registry and *deploy* them via model serving via the [Machine Learning API](https://gitub.com/logicalclocks/machine-learning-api). + - manage environments, executions, kafka topics and more once you deploy your own Hopsworks cluster, either on-prem or in the cloud. Hopsworks is open-source and has its own [Community Edition](https://github.com/logicalclocks/hopsworks). -## Getting Started On Hopsworks +Our [tutorials](https://github.com/logicalclocks/hopsworks-tutorials) cover a wide range of use cases and example of what *you* can build using Hopsworks. -Instantiate a connection and get the project object -```python -import hopsworks +## Getting Started On Hopsworks -connection = hopsworks.connection() +Once you created a project on [Hopsworks Serverless](https://app.hopsworks.ai) and created a new [Api Key](https://docs.hopsworks.ai/latest/user_guides/projects/api_key/create_api_key/), just use your favourite virtualenv and package manager to install the library: -project = connection.get_project("my_project") +```bash +pip install hopsworks +``` +Fire up a notebook and connect to your project, you will be prompted to enter your newly created API key: +```python +import hopsworks +project = hopsworks.login() ``` -Create a new project +Access the Feature Store of your project to use as a central repository for your feature data. Use *your* favourite data engineering library (pandas, polars, Spark, etc...) to insert data into the Feature Store, create training datasets or serve real-time feature vectors. Want to predict likelyhood of e-scooter accidents in real-time? Here's how you can do it: + ```python -project = connection.create_project("my_project") +fs = project.get_feature_store() + +# Write to Feature Groups +bike_ride_fg = fs.get_or_create_feature_group( + name="bike_rides", + version=1, + primary_key=["ride_id"], + event_time="activation_time", + online_enabled=True, +) + +fg.insert(bike_rides_df) + +# Read from Feature Views +profile_fg = fs.get_feature_group("user_profile", version=1) + +bike_ride_fv = fs.get_or_create_feature_view( + name="bike_rides_view", + version=1, + query=bike_ride_fg.select_except(["ride_id"]).join(profile_fg.select(["age", "has_license"]), on="user_id") +) + +bike_rides_Q1_2021_df = bike_ride_fv.get_batch_data( + start_date="2021-01-01", + end_date="2021-01-31" +) + +# Create a training dataset +version, job = bike_ride_fv.create_train_test_split( + test_size=0.2, + description='Description of a dataset', + # you can have different data formats such as csv, tsv, tfrecord, parquet and others + data_format='csv' +) + +# Predict the probability of accident in real-time using new data + context data +bike_ride_fv.init_serving() + +while True: + new_ride_vector = poll_ride_queue() + feature_vector = bike_ride_fv.get_online_feature_vector( + {"user_id": new_ride_vector["user_id"]}, + passed_features=new_ride_vector + ) + accident_probability = model.predict(feature_vector) ``` -Upload data to a project +Or you can use the Machine Learning API to register models and deploy them for serving: ```python -dataset_api = project.get_dataset_api() - -dataset_api.upload("data.csv", "Resources") +mr = project.get_model_registry() +# or +ms = project.get_model_serving() ``` +## Tutorials - - - -You can find more examples on how to use the library in our [hops-examples](https://github.com/logicalclocks/hops-examples) repository. +Need more inspiration or want to learn more about the Hopsworks platform? Check out our [tutorials](https://github.com/logicalclocks/hopsworks-tutorials). ## Documentation diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 7e43c1936..58f07bfae 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -74,7 +74,7 @@ We use `mkdocs` together with `mike` ([for versioning](https://github.com/jimpor 1. Currently we are using our own version of `keras-autodoc` ```bash - pip install git+https://github.com/moritzmeister/keras-autodoc@split-tags-properties + pip install git+https://github.com/logicalclocks/keras-autodoc ``` 2. Install HOPSWORKS with `docs` extras: diff --git a/docs/css/custom.css b/docs/css/custom.css index a7bebfd8a..9f5e993fd 100644 --- a/docs/css/custom.css +++ b/docs/css/custom.css @@ -1,4 +1,4 @@ -:root { +[data-md-color-scheme="hopsworks"] { --md-primary-fg-color: #1EB382; --md-secondary-fg-color: #188a64; --md-tertiary-fg-color: #0d493550; @@ -24,6 +24,11 @@ box-shadow: 0 0 0 0; } +.md-tabs__item { + min-width: 2.25rem; + min-height: 1.5rem; +} + .md-tabs__item:hover { background-color: var(--md-tertiary-fg-color); transition: background-color 450ms; diff --git a/docs/css/dropdown.css b/docs/css/dropdown.css index 6791f1788..efc38a775 100644 --- a/docs/css/dropdown.css +++ b/docs/css/dropdown.css @@ -1,5 +1,5 @@ /* Style The Dropdown Button */ -.dropbtn-api { +.dropbtn { color: white; border: none; cursor: pointer; @@ -9,20 +9,17 @@ contain: inherit; } .md-tabs { -overflow: inherit; -} -.md-header { - z-index: 1000 !important; + overflow: inherit; } /* The container
- needed to position the dropdown content */ -.dropdown-api { - position: relative; +.dropdown { + position: absolute; display: inline-block; } /* Dropdown Content (Hidden by Default) */ -.dropdown-content-api { +.dropdown-content { display:none; font-size: 13px; position: absolute; @@ -35,7 +32,7 @@ overflow: inherit; } /* Links inside the dropdown */ -.dropdown-content-api a { +.dropdown-content a { color: black; padding: 12px 16px; text-decoration: none; @@ -43,13 +40,13 @@ overflow: inherit; } /* Change color of dropdown links on hover */ -.dropdown-content-api a:hover {background-color: #f1f1f1} +.dropdown-content a:hover {background-color: #f1f1f1} /* Show the dropdown menu on hover */ -.dropdown-api:hover .dropdown-content-api { +.dropdown:hover .dropdown-content { display: block; } /* Change the background color of the dropdown button when the dropdown content is shown */ -.dropdown-api:hover .dropbtn-api { +.dropdown:hover .dropbtn { } diff --git a/docs/js/dropdown.js b/docs/js/dropdown.js new file mode 100644 index 000000000..2618e0ce7 --- /dev/null +++ b/docs/js/dropdown.js @@ -0,0 +1,2 @@ +document.getElementsByClassName("md-tabs__link")[7].style.display = "none"; +document.getElementsByClassName("md-tabs__link")[9].style.display = "none"; diff --git a/docs/js/inject-api-links.js b/docs/js/inject-api-links.js index c49eb2b93..6c8a4a3b3 100644 --- a/docs/js/inject-api-links.js +++ b/docs/js/inject-api-links.js @@ -1,14 +1,19 @@ window.addEventListener("DOMContentLoaded", function () { var windowPathNameSplits = window.location.pathname.split("/"); var majorVersionRegex = new RegExp("(\\d+[.]\\d+)") + var latestRegex = new RegExp("latest"); if (majorVersionRegex.test(windowPathNameSplits[1])) { // On landing page docs.hopsworks.api/3.0 - URL contains major version // Version API dropdown document.getElementById("hopsworks_api_link").href = "https://docs.hopsworks.ai/hopsworks-api/" + windowPathNameSplits[1] + "/generated/api/login/"; document.getElementById("hsfs_api_link").href = "https://docs.hopsworks.ai/feature-store-api/" + windowPathNameSplits[1] + "/generated/api/connection_api/"; document.getElementById("hsml_api_link").href = "https://docs.hopsworks.ai/machine-learning-api/" + windowPathNameSplits[1] + "/generated/connection_api/"; } else { // on docs.hopsworks.api/feature-store-api/3.0 / docs.hopsworks.api/hopsworks-api/3.0 / docs.hopsworks.api/machine-learning-api/3.0 - var apiVersion = windowPathNameSplits[2]; - var majorVersion = apiVersion.match(majorVersionRegex)[0]; + if (latestRegex.test(windowPathNameSplits[2]) || latestRegex.test(windowPathNameSplits[1])) { + var majorVersion = "latest"; + } else { + var apiVersion = windowPathNameSplits[2]; + var majorVersion = apiVersion.match(majorVersionRegex)[0]; + } // Version main navigation document.getElementsByClassName("md-tabs__link")[0].href = "https://docs.hopsworks.ai/" + majorVersion; document.getElementsByClassName("md-tabs__link")[1].href = "https://colab.research.google.com/github/logicalclocks/hopsworks-tutorials/blob/master/quickstart.ipynb"; diff --git a/docs/js/version-select.js b/docs/js/version-select.js index bbb25ca17..053d47c53 100644 --- a/docs/js/version-select.js +++ b/docs/js/version-select.js @@ -29,6 +29,15 @@ window.addEventListener("DOMContentLoaded", function() { return i.version === CURRENT_VERSION || i.aliases.includes(CURRENT_VERSION); }).version; + var latestVersion = versions.find(function(i) { + return i.aliases.includes("latest"); + }).version; + let outdated_banner = document.querySelector('div[data-md-color-scheme="default"][data-md-component="outdated"]'); + if (realVersion !== latestVersion) { + outdated_banner.removeAttribute("hidden"); + } else { + outdated_banner.setAttribute("hidden", ""); + } var select = makeSelect(versions.map(function(i) { var allowedAliases = ["dev", "latest"] diff --git a/docs/overrides/main.html b/docs/overrides/main.html new file mode 100644 index 000000000..30b2f34c3 --- /dev/null +++ b/docs/overrides/main.html @@ -0,0 +1,8 @@ +{% extends "base.html" %} + +{% block outdated %} +You're not viewing the latest version of the documentation. + + Click here to go to latest. + +{% endblock %} \ No newline at end of file diff --git a/docs/overrides/partials/tabs-item.html b/docs/overrides/partials/tabs-item.html deleted file mode 100644 index 2df2ced8b..000000000 --- a/docs/overrides/partials/tabs-item.html +++ /dev/null @@ -1,63 +0,0 @@ - - - -{% if not class %} -{% set class = "md-tabs__link" %} -{% if nav_item.active %} -{% set class = class ~ " md-tabs__link--active" %} -{% endif %} -{% endif %} - - -{% if nav_item.children %} -{% set title = title | d(nav_item.title) %} -{% set nav_item = nav_item.children | first %} - - -{% if nav_item.children %} -{% include "partials/tabs-item.html" %} - - -{% elif title == "API" %} - - -{% else %} -
  • - - {{ title }} - -
  • -{% endif %} - - -{% else %} -
  • - - {{ nav_item.title }} - -
  • -{% endif %} diff --git a/mkdocs.yml b/mkdocs.yml index b0d1a4fa3..e825f7a3b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -16,7 +16,7 @@ nav: - Guides: https://docs.hopsworks.ai/ - Setup and Installation: https://docs.hopsworks.ai/ - Administration: https://docs.hopsworks.ai/ - - API: + - API: - API Reference: - Login: generated/api/login.md - Connection: generated/api/connection.md @@ -33,11 +33,16 @@ nav: - KafkaSchema: generated/api/kafka_schema.md - Secrets: generated/api/secrets.md - OpenSearch: generated/api/opensearch.md + # Added to allow navigation using the side drawer + - Hopsworks API: https://docs.hopsworks.ai/hopsworks-api/latest/ + - MLOps API: https://docs.hopsworks.ai/machine-learning-api/latest/ + - Feature Store JavaDoc: https://docs.hopsworks.ai/feature-store-javadoc/latest/ - Contributing: CONTRIBUTING.md - Community ↗: https://community.hopsworks.ai/ theme: name: material + custom_dir: docs/overrides favicon: assets/images/favicon.ico logo: assets/images/hops-logo.png icon: @@ -47,18 +52,22 @@ theme: code: "IBM Plex Mono" palette: accent: teal + scheme: hopsworks features: - navigation.tabs - navigation.tabs.sticky - navigation.sections - navigation.indexes - custom_dir: docs/overrides + extra: analytics: provider: google property: G-64FEEXPSDN generator: false + version: + - provider: mike + - default: latest social: - icon: fontawesome/brands/twitter link: https://twitter.com/hopsworks @@ -78,9 +87,16 @@ extra_css: extra_javascript: - js/version-select.js - js/inject-api-links.js + - js/dropdown.js plugins: - search + - minify: + minify_html: true + minify_css: true + minify_js: true + - mike: + canonical_version: latest markdown_extensions: - admonition diff --git a/python/.flake8 b/python/.flake8 deleted file mode 100644 index 5376b8ae3..000000000 --- a/python/.flake8 +++ /dev/null @@ -1,4 +0,0 @@ -[flake8] -max-line-length = 80 -select = C,E,F,W,B,B950 -ignore = E203, E501, W503 diff --git a/python/.pre-commit-config.yaml b/python/.pre-commit-config.yaml index 4249fcb96..8c774780d 100644 --- a/python/.pre-commit-config.yaml +++ b/python/.pre-commit-config.yaml @@ -1,18 +1,8 @@ exclude: setup.py repos: -- repo: https://github.com/psf/black - rev: 22.3.0 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.4.2 hooks: - - id: black - language_version: python3 -- repo: https://gitlab.com/pycqa/flake8 - rev: 3.8.3 - hooks: - - id: flake8 - language_version: python3 - args: [--config=python/.flake8] -- repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.4.0 - hooks: - - id: trailing-whitespace - - id: end-of-file-fixer + - id: ruff + args: [--fix] + - id: ruff-format diff --git a/python/MANIFEST.in b/python/MANIFEST.in deleted file mode 100644 index ceaf0aac9..000000000 --- a/python/MANIFEST.in +++ /dev/null @@ -1,2 +0,0 @@ -include ../README.md -include ../LICENSE diff --git a/python/pyproject.toml b/python/pyproject.toml new file mode 100644 index 000000000..3bb6985d6 --- /dev/null +++ b/python/pyproject.toml @@ -0,0 +1,144 @@ +[project] +name = "hopsworks" +dynamic = ["version"] +requires-python = ">=3.8,<=3.12" +readme = "README.md" +description = "Hopsworks Python SDK to interact with Hopsworks Platform, Feature Store, Model Registry and Model Serving" +keywords = ["Hopsworks", "Feature Store", "Spark", "Machine Learning", "MLOps", "DataOps"] + +authors = [{ name = "Hopsworks AB", email = "robin@hopsworks.ai" }] +license = { text = "Apache-2.0" } +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Topic :: Utilities", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Intended Audience :: Developers", +] + +dependencies = [ + "hsfs[python] @ git+https://git@github.com/logicalclocks/feature-store-api@master#subdirectory=python", + "hsml @ git+https://git@github.com/logicalclocks/machine-learning-api@main#subdirectory=python", + "pyhumps==1.6.1", + "requests", + "furl", + "boto3", + "pyjks", + "mock", + "tqdm", +] + +[project.optional-dependencies] +dev = [ "ruff", "pytest"] +docs = [ + "mkdocs==1.5.3", + "mkdocs-material==9.5.17", + "mike==2.0.0", + "sphinx==7.2.6", + "keras_autodoc @ git+https://git@github.com/logicalclocks/keras-autodoc", + "markdown-include==0.8.1", + "markdown==3.6", + "pymdown-extensions==10.7.1", + "mkdocs-macros-plugin==1.0.4", + "mkdocs-minify-plugin>=0.2.0", +] + +[build-system] +requires = ["setuptools", "wheel"] +build-backend = "setuptools.build_meta" + +[tool.setuptools.packages.find] +exclude = ["tests*"] +include = ["../Readme.md", "../LICENSE", "hopsworks"] + +[tool.setuptools.dynamic] +version = { attr = "hopsworks.version.__version__" } + + +[project.urls] +Documentation = "https://docs.hopsworks.ai/latest" +Repository = "https://github.com/logicalclocks/hopsworks-api" +Homepage = "https://www.hopsworks.ai" +Community = "https://community.hopsworks.ai" + +[tool.ruff] +# Exclude a variety of commonly ignored directories. +exclude = [ + ".bzr", + ".direnv", + ".eggs", + ".git", + ".git-rewrite", + ".hg", + ".ipynb_checkpoints", + ".mypy_cache", + ".nox", + ".pants.d", + ".pyenv", + ".pytest_cache", + ".pytype", + ".ruff_cache", + ".svn", + ".tox", + ".venv", + ".vscode", + "__pypackages__", + "_build", + "buck-out", + "build", + "dist", + "node_modules", + "site-packages", + "venv", + "java", +] + +# Same as Black. +line-length = 88 +indent-width = 4 + +# Assume Python 3.8+ syntax. +target-version = "py38" + +[tool.ruff.lint] +# 1. Enable flake8-bugbear (`B`) rules, in addition to the defaults. +select = ["E4", "E7", "E9", "F", "B", "I", "W"] #, "ANN"] +ignore = [ + "B905", # zip has no strict kwarg until Python 3.10 + "ANN101", # Missing type annotation for self in method + "ANN102", # Missing type annotation for cls in classmethod + "ANN003", # Missing type annotation for **kwarg in function + "ANN002", # Missing type annotation for *args in function + "ANN401", # Allow Any in type annotations + "W505", # Doc line too long +] + +# Allow fix for all enabled rules (when `--fix`) is provided. +fixable = ["ALL"] +unfixable = [] + +# Allow unused variables when underscore-prefixed. +dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" + +[tool.ruff.lint.isort] +lines-after-imports = 2 +known-third-party = ["hopsworks", "hsfs", "hsml"] + + +[tool.ruff.format] +# Like Black, use double quotes for strings. +quote-style = "double" + +# Like Black, indent with spaces, rather than tabs. +indent-style = "space" + +# Like Black, respect magic trailing commas. +skip-magic-trailing-comma = false + +# Like Black, automatically detect the appropriate line ending. +line-ending = "auto" diff --git a/python/setup.py b/python/setup.py index b609d9bf0..b024da80e 100644 --- a/python/setup.py +++ b/python/setup.py @@ -1,62 +1,4 @@ -import os -from importlib.machinery import SourceFileLoader -from setuptools import setup, find_packages +from setuptools import setup -__version__ = ( - SourceFileLoader("hopsworks.version", os.path.join("hopsworks", "version.py")) - .load_module() - .__version__ -) - - -def read(fname): - return open(os.path.join(os.path.dirname(__file__), fname)).read() - - -setup( - name="hopsworks", - version=__version__, - install_requires=[ - "hsfs @ git+https://git@github.com/logicalclocks/feature-store-api@master#egg=hsfs[python]&subdirectory=python", - "hsml @ git+https://git@github.com/logicalclocks/machine-learning-api@main#egg=hsml&subdirectory=python", - "pyhumps==1.6.1", - "requests", - "furl", - "boto3", - "pyjks", - "mock", - "tqdm", - ], - extras_require={ - "dev": ["pytest", "flake8", "black"], - "docs": [ - "mkdocs==1.3.0", - "mkdocs-material==8.2.8", - "mike==1.1.2", - "sphinx==3.5.4", - "keras_autodoc @ git+https://git@github.com/moritzmeister/keras-autodoc@split-tags-properties", - "markdown-include", - "markdown==3.3.7", - "pymdown-extensions", - ], - }, - author="Logical Clocks AB", - author_email="robin@logicalclocks.com", - description="HOPSWORKS: An environment independent client to interact with the Hopsworks API", - license="Apache License 2.0", - keywords="Hopsworks, Feature Store, Spark, Machine Learning, MLOps, DataOps", - url="https://github.com/logicalclocks/hopsworks-api", - download_url="https://github.com/logicalclocks/hopsworks-api/releases/tag/" - + __version__, - packages=find_packages(), - long_description=read("../README.md"), - long_description_content_type="text/markdown", - classifiers=[ - "Development Status :: 5 - Production/Stable", - "Topic :: Utilities", - "License :: OSI Approved :: Apache Software License", - "Programming Language :: Python :: 3", - "Intended Audience :: Developers", - ], -) +setup()