Skip to content

Commit 1074689

Browse files
heliocastropombredanne
authored andcommitted
Create settings class based on pydantic-settings
Settings can now be defined through environment variables, .env local file or regular arguments to the script. All variables need to be prefixed by PYTHON_INSPECTOR_ to be recognized. Example: PYTHON_INSPECTOR_INDEX_URL="https://pypy1.org,https://foo.bar" will add this two repositories overriding the public repository. Raise the minimum python version to 3.9 as 3.8 is EOL. Adapt base code to use new settings class Adapt tests to use new settings class Signed-off-by: Helio Chissini de Castro <helio.chissini.de.castro@cariad.technology>
1 parent 1eef4b9 commit 1074689

File tree

12 files changed

+277
-157
lines changed

12 files changed

+277
-157
lines changed

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ packaging==21.3
1414
packvers==21.5
1515
pip-requirements-parser==32.0.1
1616
pkginfo2==30.0.0
17+
pydantic_settings >= 2.6.1
1718
pyparsing==3.0.9
1819
PyYAML==6.0
1920
requests==2.28.1

src/python_inspector/__init__.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,12 @@
77
# See https://aboutcode.org for more information about nexB OSS projects.
88
#
99

10-
DEFAULT_PYTHON_VERSION = "3.8"
10+
from pydantic import ValidationError
11+
12+
from python_inspector.settings import Settings
13+
14+
# Initialize global settings
15+
try:
16+
settings = Settings()
17+
except ValidationError as e:
18+
print(e)

src/python_inspector/api.py

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
from _packagedcode.pypi import PipRequirementsFileHandler
2727
from _packagedcode.pypi import PythonSetupPyHandler
2828
from _packagedcode.pypi import can_process_dependent_package
29-
from python_inspector import DEFAULT_PYTHON_VERSION
3029
from python_inspector import dependencies
30+
from python_inspector import settings
3131
from python_inspector import utils
3232
from python_inspector import utils_pypi
3333
from python_inspector.package_data import get_pypi_data_from_purl
@@ -40,8 +40,8 @@
4040
from python_inspector.resolution import get_reqs_insecurely
4141
from python_inspector.resolution import get_requirements_from_python_manifest
4242
from python_inspector.utils_pypi import PLATFORMS_BY_OS
43-
from python_inspector.utils_pypi import PYPI_SIMPLE_URL
4443
from python_inspector.utils_pypi import Environment
44+
from python_inspector.utils_pypi import PypiSimpleRepository
4545
from python_inspector.utils_pypi import valid_python_versions
4646

4747

@@ -79,7 +79,7 @@ def resolve_dependencies(
7979
specifiers=tuple(),
8080
python_version=None,
8181
operating_system=None,
82-
index_urls=tuple([PYPI_SIMPLE_URL]),
82+
index_urls: tuple[str, ...] = settings.INDEX_URL,
8383
pdt_output=None,
8484
netrc_file=None,
8585
max_rounds=200000,
@@ -106,15 +106,15 @@ def resolve_dependencies(
106106
"""
107107

108108
if not operating_system:
109-
raise Exception(f"No operating system provided.")
109+
raise Exception("No operating system provided.")
110110
if operating_system not in PLATFORMS_BY_OS:
111111
raise ValueError(
112112
f"Invalid operating system: {operating_system}. "
113113
f"Must be one of: {', '.join(PLATFORMS_BY_OS.keys())}"
114114
)
115115

116116
if not python_version:
117-
raise Exception(f"No python version provided.")
117+
raise Exception("No python version provided.")
118118
if python_version not in valid_python_versions:
119119
raise ValueError(
120120
f"Invalid python version: {python_version}. "
@@ -147,14 +147,13 @@ def resolve_dependencies(
147147

148148
files = []
149149

150-
if PYPI_SIMPLE_URL not in index_urls:
151-
index_urls = tuple([PYPI_SIMPLE_URL]) + tuple(index_urls)
152-
153150
# requirements
154151
for req_file in requirement_files:
155152
deps = dependencies.get_dependencies_from_requirements(
156153
requirements_file=req_file)
157-
for extra_data in dependencies.get_extra_data_from_requirements(requirements_file=req_file):
154+
for extra_data in dependencies.get_extra_data_from_requirements(
155+
requirements_file=req_file
156+
):
158157
index_urls = (
159158
*index_urls, *tuple(extra_data.get("extra_index_urls") or []))
160159
index_urls = (
@@ -260,10 +259,8 @@ def resolve_dependencies(
260259
# Collect PyPI repos
261260
for index_url in index_urls:
262261
index_url = index_url.strip("/")
263-
existing = utils_pypi.DEFAULT_PYPI_REPOS_BY_URL.get(index_url)
264-
if existing:
265-
existing.use_cached_index = use_cached_index
266-
repos.append(existing)
262+
if index_url in settings.INDEX_URL:
263+
repos.append(PypiSimpleRepository(index_url))
267264
else:
268265
credentials = None
269266
if parsed_netrc:
@@ -273,7 +270,7 @@ def resolve_dependencies(
273270
dict(login=login,
274271
password=password) if login and password else None
275272
)
276-
repo = utils_pypi.PypiSimpleRepository(
273+
repo = PypiSimpleRepository(
277274
index_url=index_url,
278275
use_cached_index=use_cached_index,
279276
credentials=credentials,
@@ -366,8 +363,8 @@ def resolve(
366363

367364
def get_resolved_dependencies(
368365
requirements: List[Requirement],
369-
environment: Environment = None,
370-
repos: Sequence[utils_pypi.PypiSimpleRepository] = tuple(),
366+
environment: Environment,
367+
repos: Sequence[PypiSimpleRepository] = tuple(),
371368
as_tree: bool = False,
372369
max_rounds: int = 200000,
373370
pdt_output: bool = False,
@@ -382,6 +379,7 @@ def get_resolved_dependencies(
382379
Used the provided ``repos`` list of PypiSimpleRepository.
383380
If empty, use instead the PyPI.org JSON API exclusively instead
384381
"""
382+
385383
resolver = Resolver(
386384
provider=PythonInputProvider(
387385
environment=environment,
@@ -391,9 +389,12 @@ def get_resolved_dependencies(
391389
),
392390
reporter=BaseReporter(),
393391
)
392+
394393
resolver_results = resolver.resolve(
395394
requirements=requirements, max_rounds=max_rounds)
395+
396396
package_list = get_package_list(results=resolver_results)
397+
397398
if pdt_output:
398399
return (format_pdt_tree(resolver_results), package_list)
399400
return (

src/python_inspector/package_data.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
# See https://aboutcode.org for more information about nexB OSS projects.
1010
#
1111

12+
from collections.abc import Generator
1213
from typing import List
1314

1415
from packageurl import PackageURL
@@ -25,7 +26,10 @@
2526

2627

2728
def get_pypi_data_from_purl(
28-
purl: str, environment: Environment, repos: List[PypiSimpleRepository], prefer_source: bool
29+
purl: str,
30+
environment: Environment,
31+
repos: list[PypiSimpleRepository],
32+
prefer_source: bool,
2933
) -> PackageData:
3034
"""
3135
Generate `Package` object from the `purl` string of pypi type
@@ -36,9 +40,9 @@ def get_pypi_data_from_purl(
3640
``prefer_source`` is a boolean value to prefer source distribution over wheel,
3741
if no source distribution is available then wheel is used
3842
"""
39-
purl = PackageURL.from_string(purl)
40-
name = purl.name
41-
version = purl.version
43+
packageurl: PackageURL = PackageURL.from_string(purl)
44+
name = packageurl.name
45+
version = packageurl.version
4246
if not version:
4347
raise Exception("Version is not specified in the purl")
4448
base_path = "https://pypi.org/pypi"
@@ -54,12 +58,13 @@ def get_pypi_data_from_purl(
5458
code_view_url = get_pypi_codeview_url(project_urls)
5559
bug_tracking_url = get_pypi_bugtracker_url(project_urls)
5660
python_version = get_python_version_from_env_tag(
57-
python_version=environment.python_version)
61+
python_version=environment.python_version
62+
)
5863
valid_distribution_urls = []
5964

6065
valid_distribution_urls.append(
6166
get_sdist_download_url(
62-
purl=purl,
67+
purl=packageurl,
6368
repos=repos,
6469
python_version=python_version,
6570
)
@@ -70,7 +75,7 @@ def get_pypi_data_from_purl(
7075
if not valid_distribution_urls or not prefer_source:
7176
wheel_urls = list(
7277
get_wheel_download_urls(
73-
purl=purl,
78+
purl=packageurl,
7479
repos=repos,
7580
environment=environment,
7681
python_version=python_version,
@@ -108,7 +113,7 @@ def get_pypi_data_from_purl(
108113
maintainer_key="maintainer",
109114
maintainer_email_key="maintainer_email",
110115
),
111-
**purl.to_dict(),
116+
**packageurl.to_dict(),
112117
)
113118

114119

@@ -144,7 +149,7 @@ def get_wheel_download_urls(
144149
repos: List[PypiSimpleRepository],
145150
environment: Environment,
146151
python_version: str,
147-
) -> List[str]:
152+
) -> Generator[str, None, None]:
148153
"""
149154
Return a list of download urls for the given purl.
150155
"""

0 commit comments

Comments
 (0)