diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..090cb31 --- /dev/null +++ b/.flake8 @@ -0,0 +1,4 @@ +[flake8] +max-line-length = 80 +ignore = E121,E125,W504 +statistics = true diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..664a605 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,27 @@ +name: Build and Publish Client to PyPI +on: + release: + types: [published] +jobs: + build-and-publish-client: + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/dicomweb-client + permissions: + id-token: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Install uv + uses: astral-sh/setup-uv@v6 + with: + version: "0.7.2" + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version-file: "pyproject.toml" + - name: Build wheel and sdist + run: uv build + - name: Publish package distributions to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.github/workflows/run_unit_tests.yml b/.github/workflows/run_unit_tests.yml index 1f27534..04da15f 100644 --- a/.github/workflows/run_unit_tests.yml +++ b/.github/workflows/run_unit_tests.yml @@ -28,18 +28,16 @@ jobs: - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: - python-version: ${{ matrix.python-version }} + python-version: ${{ matrix.python-version }} + - name: Install uv + uses: astral-sh/setup-uv@v6 + with: + version: "0.7.2" - name: Install dependencies - run: | - python -m pip install --upgrade pip setuptools - pip install '.[test]' - pip install . + run: uv sync - name: Lint with flake8 - run: | - flake8 --exclude='bin,build,.eggs' + run: uv run flake8 src tests --exclude=.venv,build,.eggs - name: Check type hints with mypy - run: | - mypy src tests + run: uv run mypy src tests - name: Test with pytest - run: | - pytest --cov=dicomweb_client --cov-fail-under=65 tests + run: uv run pytest --cov=dicomweb_client --cov-fail-under=65 tests diff --git a/.gitignore b/.gitignore index 5fee395..a4736c6 100644 --- a/.gitignore +++ b/.gitignore @@ -105,3 +105,6 @@ venv.bak/ # pytest .pytest_cache + +# lock files +*.lock diff --git a/pyproject.toml b/pyproject.toml index ffa4d87..eceacd1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,16 +1,10 @@ -[build-system] -requires = ["setuptools>=64"] -build-backend = "setuptools.build_meta" - [project] name = "dicomweb-client" -version = "0.59.3" +dynamic = ["version"] description = "Client for DICOMweb RESTful services." readme = "README.md" -requires-python = ">=3.6" -authors = [ - { name = "Markus D. Herrmann" }, -] +requires-python = ">=3.9" +authors = [{ name = "Markus D. Herrmann" }] maintainers = [ { name = "Markus D. Herrmann" }, { name = "Christopher P. Bridge" }, @@ -28,9 +22,6 @@ classifiers = [ "Topic :: Multimedia :: Graphics", "Topic :: Scientific/Engineering :: Information Analysis", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", @@ -47,12 +38,12 @@ dependencies = [ ] [project.optional-dependencies] -gcp = [ - "dataclasses>=0.8; python_version=='3.6'", - "google-auth>=1.6", -] +gcp = ["dataclasses>=0.8; python_version=='3.6'", "google-auth>=1.6"] + +[dependency-groups] test = [ "mypy==0.982", + "flake8==6.1.0", "pytest==7.1.3", "pytest-cov==3.0.0", "pytest-flake8==1.1.3", @@ -68,6 +59,9 @@ docs = [ "sphinx-autodoc-typehints==1.12.0", ] +[tool.uv] +default-groups = "all" + [project.scripts] dicomweb_client = "dicomweb_client.cli:_main" @@ -98,3 +92,10 @@ ignore_missing_imports = true [[tool.mypy.overrides]] module = "retrying.*" ignore_missing_imports = true + +[tool.hatch.version] +source = "uv-dynamic-versioning" + +[build-system] +requires = ["hatchling", "uv-dynamic-versioning"] +build-backend = "hatchling.build" diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 1340c5f..0000000 --- a/setup.cfg +++ /dev/null @@ -1,7 +0,0 @@ -[aliases] -test=pytest - -[flake8] -max_line_length = 80 -ignore = E121 E125 W504 -statistics = True diff --git a/setup.py b/setup.py deleted file mode 100644 index 97811ab..0000000 --- a/setup.py +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -import io -import re - -import setuptools -from pathlib import Path - -root_directory = Path(__file__).parent -readme_filepath = root_directory.joinpath('README.md') -long_description = readme_filepath.read_text() - -with io.open('src/dicomweb_client/__init__.py', 'rt', encoding='utf8') as f: - version = re.search(r'__version__ = \'(.*?)\'', f.read()).group(1) - - -setuptools.setup( - name='dicomweb-client', - version=version, - description='Client for DICOMweb RESTful services.', - long_description=long_description, - long_description_content_type='text/markdown', - author='Markus D. Herrmann', - maintainer='Markus D. Herrmann', - url='https://github.com/ImagingDataCommons/dicomweb-client', - license='MIT', - platforms=['Linux', 'MacOS', 'Windows'], - classifiers=[ - 'Environment :: Web Environment', - 'License :: OSI Approved :: MIT License', - 'Operating System :: MacOS', - 'Operating System :: Microsoft :: Windows', - 'Operating System :: POSIX :: Linux', - 'Intended Audience :: Science/Research', - 'Topic :: Internet :: WWW/HTTP', - 'Topic :: Multimedia :: Graphics', - 'Topic :: Scientific/Engineering :: Information Analysis', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Development Status :: 4 - Beta', - ], - entry_points={ - 'console_scripts': ['dicomweb_client = dicomweb_client.cli:_main'], - }, - include_package_data=True, - packages=setuptools.find_packages('src'), - package_dir={'': 'src'}, - extras_require={ - 'gcp': [ - 'dataclasses>=0.8; python_version=="3.6"', - 'google-auth>=1.6', - ], - }, - python_requires='>=3.6', - install_requires=[ - 'numpy>=1.19', - 'requests>=2.18', - 'retrying>=1.3.3', - 'Pillow>=8.3', - 'pydicom>=2.2', - 'typing-extensions>=4.0; python_version < "3.8.0"' - ] -) diff --git a/src/dicomweb_client/__init__.py b/src/dicomweb_client/__init__.py index c47651c..bbd97fe 100644 --- a/src/dicomweb_client/__init__.py +++ b/src/dicomweb_client/__init__.py @@ -1,9 +1,14 @@ -__version__ = '0.59.3' +import importlib.metadata from dicomweb_client.api import DICOMwebClient, DICOMfileClient from dicomweb_client.protocol import DICOMClient from dicomweb_client.uri import URI, URISuffix, URIType +try: + __version__ = importlib.metadata.version(__name__) +except importlib.metadata.PackageNotFoundError: + __version__ = '0.0.0' + __all__ = [ 'DICOMClient', 'DICOMfileClient',