diff --git a/label_studio/core/utils/common.py b/label_studio/core/utils/common.py index db2567870edb..5ea6d644729f 100644 --- a/label_studio/core/utils/common.py +++ b/label_studio/core/utils/common.py @@ -5,6 +5,7 @@ import calendar import contextlib import copy +import importlib import logging import os import random @@ -18,11 +19,9 @@ from typing import Any, Callable, Generator, Iterable, Mapping, Optional import drf_yasg.openapi as openapi -import pkg_resources import pytz import requests import ujson as json -from boxing import boxing from colorama import Fore from core.utils.params import get_env from django.conf import settings @@ -49,7 +48,8 @@ from label_studio_sdk._extensions.label_studio_tools.core.utils.exceptions import ( LabelStudioXMLSyntaxErrorSentryIgnored, ) -from pkg_resources import parse_version +from packaging.version import parse as parse_version +from pyboxen import boxen from rest_framework import status from rest_framework.exceptions import ErrorDetail from rest_framework.views import Response, exception_handler @@ -350,11 +350,7 @@ def f_retry(*args, **kwargs): def get_app_version(): - version = pkg_resources.get_distribution('label-studio').version - if isinstance(version, str): - return version - elif isinstance(version, dict): - return version.get('version') or version.get('latest_version') + return importlib.metadata.version('label-studio') def get_latest_version(): @@ -397,13 +393,13 @@ def check_for_the_latest_version(print_message): outdated = latest_version and current_version_is_outdated(latest_version) def update_package_message(): - update_command = Fore.CYAN + 'pip install -U ' + label_studio.package_name + Fore.RESET - return boxing( + update_command = 'pip install -U ' + label_studio.package_name + return boxen( 'Update available {curr_version} → {latest_version}\nRun {command}'.format( curr_version=label_studio.__version__, latest_version=latest_version, command=update_command ), style='double', - ) + ).replace(update_command, Fore.CYAN + update_command + Fore.RESET) if outdated and print_message: print(update_package_message()) diff --git a/label_studio/core/utils/io.py b/label_studio/core/utils/io.py index 99e367e35712..309461e4d75e 100644 --- a/label_studio/core/utils/io.py +++ b/label_studio/core/utils/io.py @@ -1,6 +1,7 @@ """This file and its contents are licensed under the Apache License 2.0. Please see the included NOTICE for copyright information and LICENSE for a copy of the license. """ import glob +import importlib import io import ipaddress import itertools @@ -10,7 +11,6 @@ from contextlib import contextmanager from tempfile import mkdtemp, mkstemp -import pkg_resources import requests import ujson as json import yaml @@ -31,7 +31,7 @@ def good_path(path): def find_node(package_name, node_path, node_type): assert node_type in ('dir', 'file', 'any') - basedir = pkg_resources.resource_filename(package_name, '') + basedir = importlib.resources.files(package_name).joinpath('') node_path = os.path.join(*node_path.split('/')) # linux to windows compatibility search_by_path = '/' in node_path or '\\' in node_path diff --git a/poetry.lock b/poetry.lock index 3f496b6c1830..a4f1945c0976 100644 --- a/poetry.lock +++ b/poetry.lock @@ -257,18 +257,6 @@ urllib3 = ">=1.25.4,<1.27" [package.extras] crt = ["awscrt (==0.16.26)"] -[[package]] -name = "boxing" -version = "0.1.4" -description = "Draw boxes like never before!" -optional = false -python-versions = "*" -files = [ - {file = "boxing-0.1.4-py2-none-any.whl", hash = "sha256:707221c4d946b330d4ca885bdbf48ed46644fae0abf34246a0dcdd24e4faa628"}, - {file = "boxing-0.1.4-py3-none-any.whl", hash = "sha256:76fa658edab8344c0917db4b3d543c89340deca602c6736837c206f127ded296"}, - {file = "boxing-0.1.4.tar.gz", hash = "sha256:b9141bd02d0fb5ebda881e727e16ce7c89034773282b29b8ce938a8117e79d1b"}, -] - [[package]] name = "cachetools" version = "5.3.2" @@ -1543,13 +1531,13 @@ socks = ["socksio (==1.*)"] [[package]] name = "humansignal-drf-yasg" -version = "1.21.9" +version = "1.21.10.post1" description = "Automated generation of real Swagger/OpenAPI 2.0 schemas from Django Rest Framework code." optional = false python-versions = ">=3.6" files = [ - {file = "humansignal-drf-yasg-1.21.9.tar.gz", hash = "sha256:bc330542f5a5bf926f993fde3fa111ff45d8d6965fffb6c1d4c39f30edf844a4"}, - {file = "humansignal_drf_yasg-1.21.9-py3-none-any.whl", hash = "sha256:ee3c5b44daec634cc3a666952cf12ab1d5503b5e22786769de121e09505fc549"}, + {file = "humansignal-drf-yasg-1.21.10.post1.tar.gz", hash = "sha256:ed3cd9c6b305578e8f92afb05e229b1de39aa2da5b3737faf61ec066a1e7cbb4"}, + {file = "humansignal_drf_yasg-1.21.10.post1-py3-none-any.whl", hash = "sha256:aa6fdd504b727bcc6ef8c05540505b8c53922156058cf64da269cd90bdeed2d8"}, ] [package.dependencies] @@ -2959,6 +2947,20 @@ files = [ [package.dependencies] pyasn1 = ">=0.4.6,<0.6.0" +[[package]] +name = "pyboxen" +version = "1.3.0" +description = "Beautiful, customizable boxes in your terminal using Python" +optional = false +python-versions = ">=3.8.0,<4.0.0" +files = [ + {file = "pyboxen-1.3.0-py3-none-any.whl", hash = "sha256:ac799533bbdb0a4f4a7c3b8723607dbe3aed3d293d3863e178064027f8177c9c"}, + {file = "pyboxen-1.3.0.tar.gz", hash = "sha256:f12e6c656769f9d6aa1dd5d11688a62ed12da9dcebfa22a242103c610130b948"}, +] + +[package.dependencies] +rich = ">=12.5.1" + [[package]] name = "pycparser" version = "2.21" @@ -3389,7 +3391,6 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, @@ -3989,19 +3990,23 @@ tornado = ["tornado (>=6)"] [[package]] name = "setuptools" -version = "72.1.0" +version = "75.4.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-72.1.0-py3-none-any.whl", hash = "sha256:5a03e1860cf56bb6ef48ce186b0e557fdba433237481a9a625176c2831be15d1"}, - {file = "setuptools-72.1.0.tar.gz", hash = "sha256:8d243eff56d095e5817f796ede6ae32941278f542e0f941867cc05ae52b162ec"}, + {file = "setuptools-75.4.0-py3-none-any.whl", hash = "sha256:b3c5d862f98500b06ffdf7cc4499b48c46c317d8d56cb30b5c8bce4d88f5c216"}, + {file = "setuptools-75.4.0.tar.gz", hash = "sha256:1dc484f5cf56fd3fe7216d7b8df820802e7246cfb534a1db2aa64f14fcb9cdcb"}, ] [package.extras] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "ordered-set (>=3.1.1)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib-metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" @@ -4404,4 +4409,4 @@ mysql = ["mysqlclient"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<4" -content-hash = "7f38a9c091735af297f48d3a458240aa63ffeb626b4e52164e0460b4b73f71c3" +content-hash = "e115f5d2e9d9fb6a63ce658290abd96e8667ca62ce7c923df18391442e8a2e0b" diff --git a/pyproject.toml b/pyproject.toml index 59bb29cd835f..9d55e906debc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -169,7 +169,7 @@ django-ranged-fileresponse = ">=0.1.2" drf-dynamic-fields = "0.3.0" djangorestframework = "3.15.2" drf-flex-fields = "0.9.5" -humansignal-drf-yasg = ">=1.21.9" +humansignal-drf-yasg = ">=1.21.10.post1" drf-generators = "0.3.0" lockfile = ">=0.12.0" lxml = {extras = ["html_clean"], version = ">=4.9.4"} @@ -188,7 +188,7 @@ rules = "3.4" ujson = ">=3.0.0" xmljson = "0.2.1" colorama = ">=0.4.4" -boxing = ">=0.1.4" +pyboxen = ">=1.3.0" redis = "~=3.5" sentry-sdk = ">=2.16.0" launchdarkly-server-sdk = "8.2.1" @@ -199,6 +199,7 @@ mysqlclient = {version = "*", optional = true} django-csp = "3.7" openai = "^1.10.0" django-migration-linter = "^5.1.0" +setuptools = ">=75.4.0" # Humansignal repo dependencies label-studio-sdk = {url = "https://github.com/HumanSignal/label-studio-sdk/archive/ae9984e544732025caadf96d2d716c728dbbe014.zip"}