This is an automated email from the ASF dual-hosted git repository. honahx pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/polaris.git
The following commit(s) were added to refs/heads/main by this push: new 97b6fe8aa Support sdist client distribution (#2557) 97b6fe8aa is described below commit 97b6fe8aa6886ad402f6945d43c5c44b682dc939 Author: Yong Zheng <yongzheng0...@gmail.com> AuthorDate: Mon Sep 15 09:32:27 2025 -0500 Support sdist client distribution (#2557) This PR addresses the binary distribution issue described in #2419 . The goal is to include only the files required for an end-user to build the client locally (the repository already supports wheel distribution). For the sdist build, this PR takes a slightly different approach than the symbolic link solution proposed in [#2419]. Instead of using symbolic links, it copies the necessary files from the project root into the client directory (if they do not already exist) and then uses that directory during sdist mode. This approach avoids errors caused by Poetry’s path checks, since symbolic links pointing outside the client directory fail validation. --- Makefile | 2 +- client/python/.gitignore | 3 ++ client/python/README.md | 6 +++- client/python/generate_clients.py | 44 ++++++++++++++++++++++---- client/python/pyproject.toml | 10 +++--- client/{ => python}/templates/header-cfg.txt | 0 client/{ => python}/templates/header-ini.txt | 0 client/{ => python}/templates/header-json5.txt | 0 client/{ => python}/templates/header-md.txt | 0 client/{ => python}/templates/header-py.txt | 0 client/{ => python}/templates/header-sh.txt | 0 client/{ => python}/templates/header-toml.txt | 0 client/{ => python}/templates/header-txt.txt | 0 client/{ => python}/templates/header-typed.txt | 0 client/{ => python}/templates/header-xml.txt | 0 client/{ => python}/templates/header-yaml.txt | 0 client/{ => python}/templates/header-yml.txt | 0 regtests/Dockerfile | 1 - 18 files changed, 53 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index 9b6563b2d..6f8e89942 100644 --- a/Makefile +++ b/Makefile @@ -165,7 +165,7 @@ client-integration-test: client-setup-env ## Run client integration tests .PHONY: client-build client-build: client-setup-env ## Build client distribution @echo "--- Building client distribution ---" - @$(ACTIVATE_AND_CD) && poetry build -f wheel + @$(ACTIVATE_AND_CD) && poetry build @echo "--- Client distribution build complete ---" .PHONY: client-cleanup diff --git a/client/python/.gitignore b/client/python/.gitignore index 43995bd42..d18b347c0 100644 --- a/client/python/.gitignore +++ b/client/python/.gitignore @@ -64,3 +64,6 @@ target/ #Ipython Notebook .ipynb_checkpoints + +# OpenAPI spec +spec/ \ No newline at end of file diff --git a/client/python/README.md b/client/python/README.md index b57e85bf9..14c0338a3 100644 --- a/client/python/README.md +++ b/client/python/README.md @@ -25,7 +25,6 @@ The Apache Polaris Python package provides a client for interacting with the Apa ### Prerequisites - Python 3.9 or later - poetry >= 2.1 -- Docker ### Installation First we need to generate the OpenAPI client code from the OpenAPI specification by running the following command **from the project root directory**: @@ -42,3 +41,8 @@ make client-lint ```bash make client-integration-test ``` + +### Generating client distributions +```bash +make client-build +``` diff --git a/client/python/generate_clients.py b/client/python/generate_clients.py index 42f6becf6..f3a8fed3e 100644 --- a/client/python/generate_clients.py +++ b/client/python/generate_clients.py @@ -31,12 +31,12 @@ from pathlib import Path import fnmatch import logging import argparse +import shutil # Paths CLIENT_DIR = Path(__file__).parent -PROJECT_ROOT = CLIENT_DIR.parent.parent -HEADER_DIR = CLIENT_DIR.parent / "templates" -SPEC_DIR = os.path.join(PROJECT_ROOT, "spec") +HEADER_DIR = os.path.join(CLIENT_DIR, "templates") +SPEC_DIR = os.path.join(CLIENT_DIR, "spec") POLARIS_MANAGEMENT_SPEC = os.path.join(SPEC_DIR, "polaris-management-service.yml") ICEBERG_CATALOG_SPEC = os.path.join(SPEC_DIR, "iceberg-rest-catalog-open-api.yaml") POLARIS_CATALOG_SPEC = os.path.join(SPEC_DIR, "polaris-catalog-service.yaml") @@ -83,6 +83,9 @@ EXCLUDE_PATHS = [ Path("generate_clients.py"), Path(".venv"), Path("dist/"), + Path("templates/"), + Path("spec/"), + Path("PKG-INFO"), ] EXCLUDE_EXTENSIONS = [ "json", @@ -120,7 +123,9 @@ def clean_old_tests() -> None: os.remove(init_py_to_delete) logger.debug(f"{init_py_to_delete.relative_to(CLIENT_DIR)}: removed") except OSError as e: - logger.error(f"Error removing {init_py_to_delete.relative_to(CLIENT_DIR)}: {e}") + logger.error( + f"Error removing {init_py_to_delete.relative_to(CLIENT_DIR)}: {e}" + ) logger.info("Old test deletion complete.") @@ -255,7 +260,9 @@ def prepend_licenses() -> None: logger.debug(f"{relative_file_path}: skipped (path excluded)") continue - header_file_path = HEADER_DIR / f"header-{file_extension}.txt" + header_file_path = Path( + os.path.join(HEADER_DIR, f"header-{file_extension}.txt") + ) if header_file_path.is_file(): _prepend_header_to_file(file_path, header_file_path) @@ -266,7 +273,32 @@ def prepend_licenses() -> None: logger.info("License fix complete.") +def prepare_spec_dir(): + logger.info("Preparing spec directory...") + spec_dir = Path(SPEC_DIR) + spec_source_dir = Path(os.path.join(CLIENT_DIR.parent.parent, "spec")) + + if spec_source_dir.is_dir(): + logger.info(f"Copying spec directory from {spec_source_dir} to {spec_dir}") + if spec_dir.exists(): + shutil.rmtree(spec_dir) + shutil.copytree(spec_source_dir, spec_dir) + logger.info("Spec directory copied to ensure it is up-to-date.") + elif not spec_dir.is_dir(): + # This will be hit during an sdist build if spec directory wasn't in the package, + # and we can't find the source to copy from. + logger.error( + "Fatal: spec directory is missing and the source to copy it from was not found." + ) + sys.exit(1) + else: + # This is the case for sdist where the spec dir is already there and we don't have + # the source to copy from. + logger.info("Source spec directory not found, using existing spec directory.") + + def build() -> None: + prepare_spec_dir() clean_old_tests() generate_polaris_management_client() generate_polaris_catalog_client() @@ -293,4 +325,4 @@ def main(): if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/client/python/pyproject.toml b/client/python/pyproject.toml index d01cec4b3..e5f6a8b99 100644 --- a/client/python/pyproject.toml +++ b/client/python/pyproject.toml @@ -19,7 +19,7 @@ [project] name = "polaris" -version = "1.0.0" +version = "1.1.0" description = "Apache Polaris" authors = [ {name = "Apache Software Foundation", email = "d...@polaris.apache.org"} @@ -47,8 +47,10 @@ polaris = "cli.polaris_cli:main" [tool.poetry] requires-poetry = "==2.1.4" include = [ - { path = "polaris/**", format = "wheel" }, - { path = "cli/**", format = "wheel" }, + { path = "polaris/**", format = ["sdist", "wheel"] }, + { path = "cli/**", format = ["sdist", "wheel"] }, + { path = "templates/**", format = "sdist" }, + { path = "spec/**", format = "sdist" }, ] [tool.poetry.group.dev.dependencies] @@ -63,7 +65,7 @@ pre-commit = "==4.3.0" openapi-generator-cli = "==7.11.0.post0" [build-system] -requires = ["poetry-core>=2.0.0,<3.0.0"] +requires = ["poetry-core>=2.0.0,<3.0.0", "openapi-generator-cli==7.11.0.post0"] build-backend = "poetry.core.masonry.api" [tool.poetry.build] diff --git a/client/templates/header-cfg.txt b/client/python/templates/header-cfg.txt similarity index 100% rename from client/templates/header-cfg.txt rename to client/python/templates/header-cfg.txt diff --git a/client/templates/header-ini.txt b/client/python/templates/header-ini.txt similarity index 100% rename from client/templates/header-ini.txt rename to client/python/templates/header-ini.txt diff --git a/client/templates/header-json5.txt b/client/python/templates/header-json5.txt similarity index 100% rename from client/templates/header-json5.txt rename to client/python/templates/header-json5.txt diff --git a/client/templates/header-md.txt b/client/python/templates/header-md.txt similarity index 100% rename from client/templates/header-md.txt rename to client/python/templates/header-md.txt diff --git a/client/templates/header-py.txt b/client/python/templates/header-py.txt similarity index 100% rename from client/templates/header-py.txt rename to client/python/templates/header-py.txt diff --git a/client/templates/header-sh.txt b/client/python/templates/header-sh.txt similarity index 100% rename from client/templates/header-sh.txt rename to client/python/templates/header-sh.txt diff --git a/client/templates/header-toml.txt b/client/python/templates/header-toml.txt similarity index 100% rename from client/templates/header-toml.txt rename to client/python/templates/header-toml.txt diff --git a/client/templates/header-txt.txt b/client/python/templates/header-txt.txt similarity index 100% rename from client/templates/header-txt.txt rename to client/python/templates/header-txt.txt diff --git a/client/templates/header-typed.txt b/client/python/templates/header-typed.txt similarity index 100% rename from client/templates/header-typed.txt rename to client/python/templates/header-typed.txt diff --git a/client/templates/header-xml.txt b/client/python/templates/header-xml.txt similarity index 100% rename from client/templates/header-xml.txt rename to client/python/templates/header-xml.txt diff --git a/client/templates/header-yaml.txt b/client/python/templates/header-yaml.txt similarity index 100% rename from client/templates/header-yaml.txt rename to client/python/templates/header-yaml.txt diff --git a/client/templates/header-yml.txt b/client/python/templates/header-yml.txt similarity index 100% rename from client/templates/header-yml.txt rename to client/python/templates/header-yml.txt diff --git a/regtests/Dockerfile b/regtests/Dockerfile index b75b5e2a7..88fa13dda 100644 --- a/regtests/Dockerfile +++ b/regtests/Dockerfile @@ -41,7 +41,6 @@ COPY --chown=spark ./regtests/setup.sh /home/spark/polaris/regtests/setup.sh COPY --chown=spark ./regtests/pyspark-setup.sh /home/spark/polaris/regtests/pyspark-setup.sh COPY --chown=spark ./client/python /home/spark/polaris/client/python COPY --chown=spark ./polaris /home/spark/polaris/polaris -COPY --chown=spark ./client/templates /home/spark/polaris/client/templates COPY --chown=spark ./spec /home/spark/polaris/spec COPY --chown=spark ./regtests/requirements.txt /tmp/