1- """Fetch PyHC Environment requirements ."""
1+ """Fetch PyHC Environment package and constraint files ."""
22
33from __future__ import annotations
44
55import re
66from pathlib import Path
7- from typing import TYPE_CHECKING
7+ from typing import Callable
88
99import requests
1010import yaml
1111
12- if TYPE_CHECKING :
13- pass
14-
12+ # Default URL to PyHC Environment packages.txt
13+ PYHC_PACKAGES_URL = (
14+ "https://raw.githubusercontent.com/heliophysicsPy/pyhc-docker-environment/"
15+ "main-v2/docker/pyhc-environment/contents/packages.txt"
16+ )
1517
16- # Default URL to PyHC Environment requirements .txt
17- PYHC_REQUIREMENTS_URL = (
18+ # Default URL to PyHC Environment constraints .txt
19+ PYHC_CONSTRAINTS_URL = (
1820 "https://raw.githubusercontent.com/heliophysicsPy/pyhc-docker-environment/"
19- "main/docker/pyhc-environment/contents/requirements .txt"
21+ "main-v2 /docker/pyhc-environment/contents/constraints .txt"
2022)
2123
2224# Default URL to PyHC Environment environment.yml (conda environment file)
2325PYHC_ENVIRONMENT_YML_URL = (
2426 "https://raw.githubusercontent.com/heliophysicsPy/pyhc-docker-environment/"
25- "main/docker/pyhc-environment/contents/environment.yml"
27+ "main-v2 /docker/pyhc-environment/contents/environment.yml"
2628)
2729
2830
29- def fetch_pyhc_requirements (url : str | None = None ) -> str :
30- """Fetch PyHC Environment requirements .txt content.
31+ def fetch_pyhc_packages (url : str | None = None ) -> str :
32+ """Fetch PyHC Environment packages .txt content.
3133
3234 Args:
3335 url: URL to fetch from (default: official GitHub raw URL)
3436
3537 Returns:
36- Contents of requirements .txt as string
38+ Contents of packages .txt as string
3739
3840 Raises:
3941 requests.RequestException: If fetch fails
4042 """
41- url = url or PYHC_REQUIREMENTS_URL
43+ url = url or PYHC_PACKAGES_URL
4244
4345 response = requests .get (url , timeout = 30 )
4446 response .raise_for_status ()
4547
4648 return response .text
4749
4850
49- def parse_requirements_for_uv (requirements_text : str ) -> list [str ]:
50- """Parse requirements.txt and return list suitable for uv.
51+ def fetch_pyhc_constraints (url : str | None = None ) -> str :
52+ """Fetch PyHC Environment constraints.txt content.
53+
54+ Args:
55+ url: URL to fetch from (default: official GitHub raw URL)
56+
57+ Returns:
58+ Contents of constraints.txt as string
59+
60+ Raises:
61+ requests.RequestException: If fetch fails
62+ """
63+ url = url or PYHC_CONSTRAINTS_URL
64+
65+ response = requests .get (url , timeout = 30 )
66+ response .raise_for_status ()
67+
68+ return response .text
69+
70+
71+ def parse_package_specs_for_uv (raw_text : str ) -> list [str ]:
72+ """Parse package-spec text and return entries suitable for uv.
5173
5274 Filters out comments, blank lines, and incompatible lines.
5375
5476 Args:
55- requirements_text : Raw requirements .txt content
77+ raw_text : Raw text from packages .txt or constraints.txt
5678
5779 Returns:
58- List of requirement strings
80+ List of package spec strings
5981 """
60- requirements = []
82+ package_specs = []
6183
62- for line in requirements_text .split ("\n " ):
84+ for line in raw_text .split ("\n " ):
6385 line = line .strip ()
6486
6587 # Skip empty lines and comments
@@ -74,39 +96,57 @@ def parse_requirements_for_uv(requirements_text: str) -> list[str]:
7496 if line .startswith ("." ) or line .startswith ("/" ):
7597 continue
7698
77- requirements .append (line )
99+ package_specs .append (line )
100+
101+ return package_specs
78102
79- return requirements
80103
104+ def _load_from_source (
105+ source : str | Path | None ,
106+ fetcher : Callable [[str | None ], str ],
107+ ) -> str :
108+ """Load text from URL or local file."""
109+ if source is None :
110+ return fetcher ()
81111
82- def load_pyhc_requirements (
83- source : str | Path | None = None ,
84- ) -> list [str ]:
85- """Load PyHC requirements from URL or local file.
112+ if isinstance (source , Path ) or (
113+ isinstance (source , str ) and not source .startswith ("http" )
114+ ):
115+ path = Path (source )
116+ with open (path ) as f :
117+ return f .read ()
118+
119+ return fetcher (str (source ))
120+
121+
122+ def load_pyhc_packages (source : str | Path | None = None ) -> list [str ]:
123+ """Load PyHC packages from URL or local file.
86124
87125 Args:
88- source: URL or path to requirements file (None uses default URL)
126+ source: URL or path to packages file (None uses default URL)
89127
90128 Returns:
91- List of requirement strings
129+ List of package spec strings
92130 """
93- if source is None :
94- # Fetch from default URL
95- text = fetch_pyhc_requirements ()
96- elif isinstance (source , Path ) or (isinstance (source , str ) and not source .startswith ("http" )):
97- # Load from local file
98- path = Path (source )
99- with open (path ) as f :
100- text = f .read ()
101- else :
102- # Fetch from URL
103- text = fetch_pyhc_requirements (str (source ))
131+ text = _load_from_source (source , fetch_pyhc_packages )
132+ return parse_package_specs_for_uv (text )
133+
134+
135+ def load_pyhc_constraints (source : str | Path | None = None ) -> list [str ]:
136+ """Load PyHC constraints from URL or local file.
104137
105- return parse_requirements_for_uv (text )
138+ Args:
139+ source: URL or path to constraints file (None uses default URL)
140+
141+ Returns:
142+ List of constraint spec strings
143+ """
144+ text = _load_from_source (source , fetch_pyhc_constraints )
145+ return parse_package_specs_for_uv (text )
106146
107147
108148def get_package_from_pyproject (pyproject_path : Path | str ) -> str :
109- """Get package directory path for use in requirements .
149+ """Get package directory path for local editable install specs .
110150
111151 Handles both file paths (pyproject.toml) and directory paths (for setup.py
112152 packages where main.py passes the project directory directly).
0 commit comments