diff --git a/.github/scripts/update_version.py b/.github/scripts/update_version.py new file mode 100644 index 000000000..a677b862f --- /dev/null +++ b/.github/scripts/update_version.py @@ -0,0 +1,88 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +import json +import os +import re +import sys +import urllib.request +from packaging.version import Version + +PACKAGE_NAME = "graphar" +FILE_PATH = "python/pyproject.toml" +URL_TIMEOUT_SECONDS = int(os.getenv("GRAPHAR_VERSION_FETCH_TIMEOUT", "10")) + +def get_next_version(): + versions = [] + urls = [ + f"https://pypi.org/pypi/{PACKAGE_NAME}/json", + f"https://test.pypi.org/pypi/{PACKAGE_NAME}/json" + ] + + print(f"Fetching versions for {PACKAGE_NAME}...") + for url in urls: + try: + with urllib.request.urlopen(url, timeout=URL_TIMEOUT_SECONDS) as r: + data = json.load(r) + versions.extend(data.get("releases", {}).keys()) + except Exception as e: + print( + f"Warning: Failed to fetch versions from {url}: {type(e).__name__}: {e}", + file=sys.stderr, + ) + + if not versions: + return "0.0.1.dev1" + + latest = max([Version(v) for v in versions]) + print(f"Latest version found: {latest}") + + if latest.is_devrelease: + dev_number = latest.dev if latest.dev is not None else 0 + return f"{latest.major}.{latest.minor}.{latest.micro}.dev{dev_number + 1}" + else: + return f"{latest.major}.{latest.minor}.{latest.micro + 1}.dev1" + +def main(): + new_ver = get_next_version() + print(f"Target version: {new_ver}") + + try: + with open(FILE_PATH, "r", encoding="utf-8") as f: + content = f.read() + + new_content, count = re.subn( + r'(version\s*=\s*")([^"]+)(")', + rf'\g<1>{new_ver}\g<3>', + content + ) + + if count == 0: + print(f"Error: Could not find 'version' key in {FILE_PATH}") + sys.exit(1) + + with open(FILE_PATH, "w", encoding="utf-8") as f: + f.write(new_content) + + print(f"Successfully updated {FILE_PATH} to {new_ver}") + + except FileNotFoundError: + print(f"Error: File {FILE_PATH} not found.") + sys.exit(1) + +if __name__ == "__main__": + main() diff --git a/.github/workflows/python-wheel-workflow.yml b/.github/workflows/python-wheel-workflow.yml new file mode 100644 index 000000000..cdbe07025 --- /dev/null +++ b/.github/workflows/python-wheel-workflow.yml @@ -0,0 +1,286 @@ + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +name: Build Python Wheels + +concurrency: + group: python-wheel-${{ github.ref }} + cancel-in-progress: false + +on: + # Trigger the workflow on push or pull request, + # but only for the main branch + push: + branches: + - "main" + paths: + - 'cpp/**' + - 'python/**' + - '.github/workflows/python-wheel-workflow.yml' + - '.github/scripts/update_version.py' + pull_request: + branches: + - "main" + paths: + - 'cpp/**' + - 'python/**' + - '.github/workflows/python-wheel-workflow.yml' + - '.github/scripts/update_version.py' + workflow_dispatch: + inputs: + publish_pypi: + description: "Publish to PyPI (manual runs only)" + required: true + default: false + type: boolean + +jobs: + build_sdist: + name: Build source distribution + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install build twine + - name: update pyproject version + if: github.event_name != 'workflow_dispatch' || github.event.inputs.publish_pypi != 'true' + run: | + python .github/scripts/update_version.py + - name: Build sdist + run: | + # Bundle C++ sources into python/ so the sdist contains them. + rm -rf python/_bundled_cpp + cp -a cpp python/_bundled_cpp + cd python + python -m build --sdist + - name: Store artifacts + uses: actions/upload-artifact@v4 + with: + name: sdist + path: python/dist/* + + build_wheels: + name: Build wheels on ${{ matrix.runner }} + runs-on: ${{ matrix.runner }} + needs: build_sdist + strategy: + matrix: + include: + # Job 1: Native x86_64 build + - platform: x86_64 + runner: ubuntu-latest # This is the standard x86_64 runner + os: linux + manylinux: _2_28 + deployment-target: '' + + # Job 2: Native aarch64 build + - platform: aarch64 + runner: ubuntu-22.04-arm # This is a native ARM64 runner + os: linux + manylinux: _2_28 + deployment-target: '' + + # Job 3: macOS arm64 build + - platform: arm64 + runner: macos-latest + os: macos + deployment-target: '11.0' + + + env: + CIBW_PLATFORM: ${{ matrix.os }} + CIBW_BUILD: "cp39-* cp310-* cp311-* cp312-* cp313-*" + CIBW_SKIP: "*-musllinux_*" + # Pin arch to the matrix platform + CIBW_ARCHS: ${{ matrix.platform }} + CIBW_MANYLINUX_X86_64_IMAGE: ${{ matrix.os == 'linux' && format('manylinux{0}', matrix.manylinux) || '' }} + CIBW_MANYLINUX_AARCH64_IMAGE: ${{ matrix.os == 'linux' && format('manylinux{0}', matrix.manylinux) || '' }} + CIBW_ENVIRONMENT_WINDOWS: DISTUTILS_USE_SDK=1 MSSdk=1 + CIBW_ENVIRONMENT_MACOS: ${{ matrix.os == 'macos' && format('MACOSX_DEPLOYMENT_TARGET={0} CMAKE_OSX_DEPLOYMENT_TARGET={0} CFLAGS=-mmacosx-version-min={0} CXXFLAGS=-mmacosx-version-min={0} LDFLAGS=-mmacosx-version-min={0}', matrix.deployment-target) || '' }} + CIBW_BEFORE_BUILD_LINUX: | + set -eux + if [ -f /etc/system-release-cpe ]; then + ALMA_MAJOR="$(cut -d: -f5 /etc/system-release-cpe | cut -d. -f1)" + else + . /etc/os-release + ALMA_MAJOR="${VERSION_ID%%.*}" + fi + dnf install -y 'dnf-command(config-manager)' || dnf install -y dnf-plugins-core || true + # Follow official Apache Arrow install instructions for AlmaLinux/RHEL-family + dnf install -y epel-release || \ + dnf install -y oracle-epel-release-el${ALMA_MAJOR} || \ + dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-${ALMA_MAJOR}.noarch.rpm + dnf install -y https://packages.apache.org/artifactory/arrow/almalinux/${ALMA_MAJOR}/apache-arrow-release-latest.rpm + dnf config-manager --set-enabled epel || : + dnf config-manager --set-enabled powertools || : + dnf config-manager --set-enabled crb || : + dnf config-manager --set-enabled ol${ALMA_MAJOR}_codeready_builder || : + dnf config-manager --set-enabled codeready-builder-for-rhel-${ALMA_MAJOR}-rhui-rpms || : + subscription-manager repos --enable codeready-builder-for-rhel-${ALMA_MAJOR}-$(arch)-rpms || : + # manylinux images may carry older Arrow packages (e.g. arrow1700-*) which + # conflict with the newer packages from the Apache Arrow repo (e.g. arrow2200-*). + # Remove any preinstalled Arrow/Parquet RPMs so we install a consistent set. + dnf remove -y 'arrow*' 'parquet*' || true + # Required for GraphAr C++ build via Arrow CMake packages + dnf install -y --allowerasing \ + arrow-devel \ + arrow-dataset-devel \ + arrow-acero-devel \ + parquet-devel \ + libcurl-devel re2-devel ccache + steps: + - name: Checkout (needed for some tooling) + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Set up Miniconda (macOS/Windows) + if: matrix.os == 'windows' || matrix.os == 'macos' + uses: conda-incubator/setup-miniconda@v3 + with: + auto-activate-base: true + miniforge-version: latest + use-mamba: true + + - name: Install Arrow (macOS) + if: matrix.os == 'macos' + shell: bash + run: | + set -euxo pipefail + mamba install -y -c conda-forge arrow-cpp + # Note: CONDA_PREFIX may be unset unless conda is activated in this shell. + # setup-miniconda exports CONDA (base install prefix), which is sufficient here. + echo "CMAKE_PREFIX_PATH=$CONDA" >> "$GITHUB_ENV" + # Optional sanity check: ensure Arrow dylib isn't built for a newer macOS than deployment target. + if command -v otool >/dev/null 2>&1; then + ls -lah "$CONDA/lib" || true + if [ -f "$CONDA/lib/libarrow.dylib" ]; then + otool -l "$CONDA/lib/libarrow.dylib" | (grep -A3 -E 'LC_BUILD_VERSION|LC_VERSION_MIN_MACOSX' || true) + fi + fi + - name: Install Arrow (Windows) + if: matrix.os == 'windows' + shell: pwsh + run: | + mamba install -y -c conda-forge arrow-cpp + Add-Content $env:GITHUB_ENV "CMAKE_PREFIX_PATH=$env:CONDA_PREFIX\\Library" + Add-Content $env:GITHUB_ENV "PATH=$env:CONDA_PREFIX\\Library\\bin;$env:PATH" + - name: Download sdist artifact + uses: actions/download-artifact@v4 + with: + name: sdist + path: sdist + + - name: Extract sdist + shell: bash + run: | + set -euxo pipefail + ls -lah sdist + SDIST_FILE="" + for f in sdist/*.tar.gz sdist/*.zip; do + if [ -f "$f" ]; then + SDIST_FILE="$f" + break + fi + done + if [ -z "$SDIST_FILE" ]; then + echo "No sdist file found in sdist/" >&2 + exit 1 + fi + mkdir -p sdist_pkg + case "$SDIST_FILE" in + *.tar.gz) tar -xzf "$SDIST_FILE" -C sdist_pkg ;; + *.zip) unzip -q "$SDIST_FILE" -d sdist_pkg ;; + esac + PKGDIR="$(find sdist_pkg -mindepth 1 -maxdepth 1 -type d | head -n 1)" + if [ -z "$PKGDIR" ]; then + echo "Failed to locate extracted sdist directory" >&2 + exit 1 + fi + echo "PKGDIR=$PKGDIR" >> "$GITHUB_ENV" + - name: Build wheels + shell: bash + run: | + set -euxo pipefail + python -m pip install --upgrade pip + python -m pip install packaging cibuildwheel + mkdir -p python/dist + python -m cibuildwheel --output-dir python/dist "$PKGDIR" + - name: Store artifacts + uses: actions/upload-artifact@v4 + with: + name: wheels-${{ matrix.os }}-${{ matrix.platform }} + path: python/dist/* + + upload_test_pypi: + name: Publish to TestPyPI (auto) + needs: [build_wheels, build_sdist] + runs-on: ubuntu-22.04 + if: github.event_name == 'push' + permissions: + contents: read + id-token: write + steps: + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + path: dist + + - name: Move artifacts to correct location + run: | + mkdir -p python/dist + find dist -name "*" -type f -exec mv {} python/dist/ \; + - name: Publish to Test PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + repository-url: https://test.pypi.org/legacy/ + packages-dir: python/dist/ + + upload_pypi: + name: Publish (manual) + needs: [build_wheels, build_sdist] + runs-on: ubuntu-22.04 + if: github.event_name == 'workflow_dispatch' && inputs.publish_pypi + permissions: + contents: read + id-token: write + steps: + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + path: dist + + - name: Move artifacts to correct location + run: | + mkdir -p python/dist + find dist -name "*" -type f -exec mv {} python/dist/ \; + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: python/dist/ \ No newline at end of file diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index be080cd8a..2d4e477b9 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -102,12 +102,17 @@ if(NOT (CMAKE_CXX_COMPILER_LAUNCHER MATCHES "ccache") AND NOT (CMAKE_C_COMPILER_ endif(ccache_EXECUTABLE) endif() -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall") +if(MSVC) + # Avoid GCC/Clang-specific flags on MSVC. + # C++17 is already enforced via CMAKE_CXX_STANDARD/target features. +else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall") +endif() if (APPLE) - set(CMAKE_MACOSX_RPATH ON) -else () - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath,$ORIGIN") + set(CMAKE_MACOSX_RPATH ON) +elseif(UNIX) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath,$ORIGIN") endif () set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -g -fno-omit-frame-pointer -fsanitize=address") @@ -290,6 +295,22 @@ macro(build_graphar) ArrowDataset::arrow_dataset_shared ArrowAcero::arrow_acero_shared) endif() + elseif(MSVC) + # MSVC doesn't support GNU ld-style -Wl flags. For shared libraries we + # don't need whole-archive semantics. + if(USE_STATIC_ARROW) + target_link_libraries(graphar PRIVATE + Arrow::arrow_static + Parquet::parquet_static + ArrowDataset::arrow_dataset_static + ArrowAcero::arrow_acero_static) + else() + target_link_libraries(graphar PRIVATE + Arrow::arrow_shared + Parquet::parquet_shared + ArrowDataset::arrow_dataset_shared + ArrowAcero::arrow_acero_shared) + endif() else() if(USE_STATIC_ARROW) target_link_libraries(graphar PRIVATE -Wl,--exclude-libs,ALL -Wl,--whole-archive @@ -350,6 +371,9 @@ macro(build_graphar_with_arrow_bundled) graphar_bundled_dependencies "-framework CoreFoundation" "-framework Security") + elseif(MSVC) + # MSVC doesn't support GNU ld-style -Wl flags. + target_link_libraries(graphar PRIVATE graphar_bundled_dependencies) else() target_link_libraries(graphar PRIVATE -Wl,--exclude-libs,ALL graphar_bundled_dependencies) diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 7938fea03..e4bd63b60 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -27,7 +27,27 @@ project( LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../cpp ${CMAKE_BINARY_DIR}/graphar) + +# The Python wheel build (e.g. via cibuildwheel) may run from an isolated copy of +# the `python/` directory, where `../cpp` doesn't exist. In CI we bundle `cpp/` +# into the project directory as `_bundled_cpp/`. +if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/_bundled_cpp/CMakeLists.txt") + set(GRAPHAR_CPP_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/_bundled_cpp") +elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../cpp/CMakeLists.txt") + set(GRAPHAR_CPP_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../cpp") +else() + message(FATAL_ERROR "GraphAr C++ sources not found. Expected either '_bundled_cpp/' or '../cpp/'.") +endif() + +# Verify that the expected subdirectories exist before adding the C++ sources. +if(NOT EXISTS "${GRAPHAR_CPP_SOURCE_DIR}/src") + message(FATAL_ERROR "GraphAr C++ sources are missing the 'src' directory under '${GRAPHAR_CPP_SOURCE_DIR}'.") +endif() +if(NOT EXISTS "${GRAPHAR_CPP_SOURCE_DIR}/thirdparty") + message(FATAL_ERROR "GraphAr C++ sources are missing the 'thirdparty' directory under '${GRAPHAR_CPP_SOURCE_DIR}'.") +endif() + +add_subdirectory(${GRAPHAR_CPP_SOURCE_DIR} ${CMAKE_BINARY_DIR}/graphar) # Find the module development requirements (requires FindPython from 3.17 or # scikit-build-core's built-in backport) @@ -37,6 +57,29 @@ find_package(Arrow REQUIRED) find_package(ArrowDataset REQUIRED) find_package(ArrowAcero REQUIRED) find_package(Parquet REQUIRED) + +if(APPLE) + # cibuildwheel uses delocate to bundle external dylibs into the wheel. + # delocate needs to be able to resolve @rpath dependencies (e.g. + # @rpath/libarrow.1300.dylib). We add the imported Arrow/Parquet library + # directories to LC_RPATH so delocate can find and copy them. + set(_graphar_macos_rpaths "") + + foreach(_tgt IN ITEMS Arrow::arrow_shared ArrowDataset::arrow_dataset_shared ArrowAcero::arrow_acero_shared Parquet::parquet_shared) + if(TARGET ${_tgt}) + get_target_property(_loc ${_tgt} IMPORTED_LOCATION_RELEASE) + if(NOT _loc) + get_target_property(_loc ${_tgt} IMPORTED_LOCATION) + endif() + if(_loc) + get_filename_component(_libdir "${_loc}" DIRECTORY) + list(APPEND _graphar_macos_rpaths "${_libdir}") + endif() + endif() + endforeach() + + list(REMOVE_DUPLICATES _graphar_macos_rpaths) +endif() # Check if ORC is enabled. if (NOT ${ARROW_ORC}) message(WARNING "apache-arrow is built without ORC extension, ORC related functionalities will be disabled.") @@ -57,18 +100,32 @@ target_link_libraries(_core PRIVATE pybind11::headers graphar Arrow::arrow_share ArrowAcero::arrow_acero_shared ) target_include_directories(_core PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) -target_include_directories(_core PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../cpp/src) -target_include_directories(_core PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../cpp/thirdparty) +target_include_directories(_core PRIVATE ${GRAPHAR_CPP_SOURCE_DIR}/src) +target_include_directories(_core PRIVATE ${GRAPHAR_CPP_SOURCE_DIR}/thirdparty) # This is passing in the version as a define just as an example target_compile_definitions(_core PRIVATE VERSION_INFO=${PROJECT_VERSION}) -# The install directory is the output (wheel) directory +# The install directory is the output (wheel) directory. # Use platform-appropriate rpath so the Python extension can find the # packaged libgraphar at runtime inside the wheel. if(APPLE) - # macOS uses @loader_path to find libraries relative to the module - set_target_properties(_core PROPERTIES INSTALL_RPATH "@loader_path") + # Keep @loader_path for runtime inside the wheel, and add Arrow/Parquet + # library dirs so delocate can resolve @rpath dependencies during repair. + set(_core_rpath "@loader_path") + if(_graphar_macos_rpaths) + list(JOIN _graphar_macos_rpaths ";" _graphar_macos_rpaths_joined) + set(_core_rpath "${_core_rpath};${_graphar_macos_rpaths_joined}") + endif() + set_target_properties(_core PROPERTIES BUILD_WITH_INSTALL_RPATH ON) + set_target_properties(_core PROPERTIES INSTALL_RPATH "${_core_rpath}") + + if(TARGET graphar) + set_target_properties(graphar PROPERTIES BUILD_WITH_INSTALL_RPATH ON) + if(_graphar_macos_rpaths) + set_target_properties(graphar PROPERTIES INSTALL_RPATH "${_graphar_macos_rpaths_joined}") + endif() + endif() else() # On Linux and other Unix, use $ORIGIN (escaped so CMake preserves the $) set_target_properties(_core PROPERTIES INSTALL_RPATH "\$ORIGIN") diff --git a/python/README.md b/python/README.md index 227d5a47f..c6a5e8ff5 100644 --- a/python/README.md +++ b/python/README.md @@ -11,6 +11,13 @@ GraphAr Python SDK provides Python bindings for the GraphAr C++ library, allowin - CMake >= 3.15 (for building from source) - Apache Arrow >= 12.0 (for building from source) +### Install from Pypi +Install the latest released version from PyPI: + +```bash +pip install -U graphar +``` + ### Install from Source Clone the repository and install the Python package: diff --git a/python/poetry.lock b/python/poetry.lock index f040da77c..2a24329dc 100644 --- a/python/poetry.lock +++ b/python/poetry.lock @@ -108,7 +108,7 @@ version = "3.1.6" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" -groups = ["docs"] +groups = ["main", "docs"] files = [ {file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"}, {file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"}, @@ -177,7 +177,7 @@ version = "2.5.4" description = "A fast and complete Python implementation of Markdown" optional = false python-versions = "<4,>=3.9" -groups = ["docs"] +groups = ["main", "docs"] markers = "python_version == \"3.11\"" files = [ {file = "markdown2-2.5.4-py3-none-any.whl", hash = "sha256:3c4b2934e677be7fec0e6f2de4410e116681f4ad50ec8e5ba7557be506d3f439"}, @@ -196,7 +196,7 @@ version = "3.0.3" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.9" -groups = ["docs"] +groups = ["main", "docs"] files = [ {file = "markupsafe-3.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2f981d352f04553a7171b8e44369f2af4055f888dfb147d55e42d29e29e74559"}, {file = "markupsafe-3.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e1c1493fb6e50ab01d20a22826e57520f1284df32f2d8601fdd90b6304601419"}, @@ -561,7 +561,7 @@ version = "15.0.4" description = "API Documentation for Python Projects" optional = false python-versions = ">=3.9" -groups = ["docs"] +groups = ["main", "docs"] markers = "python_version < \"3.11\" or python_version >= \"3.12\"" files = [ {file = "pdoc-15.0.4-py3-none-any.whl", hash = "sha256:f9028e85e7bb8475b054e69bde1f6d26fc4693d25d9fa1b1ce9009bec7f7a5c4"}, @@ -579,7 +579,7 @@ version = "16.0.0" description = "API Documentation for Python Projects" optional = false python-versions = ">=3.10" -groups = ["docs"] +groups = ["main", "docs"] markers = "python_version == \"3.11\"" files = [ {file = "pdoc-16.0.0-py3-none-any.whl", hash = "sha256:070b51de2743b9b1a4e0ab193a06c9e6c12cf4151cf9137656eebb16e8556628"}, @@ -1048,9 +1048,10 @@ files = [ ] [extras] +docs = ["pdoc"] test = ["pandas", "typing_extensions"] [metadata] lock-version = "2.1" python-versions = ">=3.9" -content-hash = "7c0d5b634b473bab1d16f5587ef80a0db3ff4fcc969ad15bd585b5c5c854d134" +content-hash = "6cc0ac1c9c1fc1c375be6f187e8e20a932a0a6daf0a30a2fc6574567feb30948" diff --git a/python/pyproject.toml b/python/pyproject.toml index a09e68d48..5f3c6e969 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -16,18 +16,28 @@ # under the License. [build-system] -requires = ["scikit-build-core>=0.3.3", "pybind11", "ninja ~= 1.11"] +requires = ["scikit-build-core>=0.8.3", "pybind11", "ninja ~= 1.11"] build-backend = "scikit_build_core.build" [project] name = "graphar" -version = "0.13.0" -description = "GraphAr command line tool" +version = "0.13.0-dev" +description = "An open source, standard data file format for graph data storage and retrieval." readme = "README.md" authors = [{ name = "GraphAr community", email = "dev@graphar.apache.org" }] requires-python = ">=3.9" dependencies = ["typer ~= 0.1", "pydantic ~= 2.0, < 2.12", "pyyaml ~= 6.0", "pytest ~= 7.2"] +license = {text = "Apache-2.0"} +classifiers = [ + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", +] [tool.poetry.group.docs] optional = true @@ -35,12 +45,21 @@ optional = true [tool.poetry.group.docs.dependencies] pdoc = "*" -[project.optional-dependencies] -test = ["pandas ~= 2.0", "typing_extensions ~= 4.0"] - [tool.scikit-build] build-dir = "build" +[tool.scikit-build.sdist] +include = [ + "../cpp/**", + "../CMakeLists.txt", + "../LICENSE", + "../NOTICE", +] + +[project.optional-dependencies] +test = ["pandas ~= 2.0", "typing_extensions ~= 4.0"] +docs = ["pdoc"] + [project.scripts] graphar = "cli.graphar_cli:main" diff --git a/python/src/cli/README.md b/python/src/cli/README.md index 22e68b1d0..e5f784265 100644 --- a/python/src/cli/README.md +++ b/python/src/cli/README.md @@ -21,6 +21,15 @@ And using Python in conda or venv is a good choice. ## Installation +### Install from Pypi +Install the latest released version from PyPI: + +```bash +pip install -U graphar +``` + +### Install from Source + - Clone this repository - `pip install ./python` or set verbose level `pip install -v ./python`