Skip to content

fix#13

Merged
Bender1011001 merged 2 commits into
codex/set-up-github-pages-for-project-showcasefrom
master
Oct 15, 2025
Merged

fix#13
Bender1011001 merged 2 commits into
codex/set-up-github-pages-for-project-showcasefrom
master

Conversation

@Bender1011001

Copy link
Copy Markdown
Owner

No description provided.

…or-project-showcase

Add GitHub Pages-ready interactive void viewer
@Bender1011001 Bender1011001 merged commit a2691a4 into codex/set-up-github-pages-for-project-showcase Oct 15, 2025
5 of 10 checks passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting

Comment thread utils/error_handling.py
Comment on lines +170 to +189
def retry_with_backoff(
max_retries: int = 3,
base_delay: float = 1.0,
backoff_factor: float = 2.0,
jitter: bool = True,
raise_on_permanent: bool = True,
expected_exceptions: tuple = (RequestException,),
circuit_breaker: Optional[CircuitBreaker] = None,
) -> Callable:
"""Decorator for exponential backoff retry with jitter and error categorization."""

def decorator(func: Callable) -> Callable:
@functools.wraps(func)
def wrapper(*args, **kwargs) -> Any:
last_exception = None
for attempt in range(max_retries + 1):
try:
if circuit_breaker:
return circuit_breaker.call(func, *args, **kwargs)
return func(*args, **kwargs)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Allow retry decorator to resolve callable parameters

The decorator assumes max_retries, base_delay, and circuit_breaker are numeric values, iterating with range(max_retries + 1) and calling circuit_breaker.call(...) directly. However, download_with_retry registers the decorator with lambdas to read instance attributes, so at runtime max_retries and circuit_breaker are callable objects rather than numbers or a CircuitBreaker. The first call to the wrapper will raise TypeError: unsupported operand type(s) for +: 'function' and 'int' and never reach the download logic. The decorator needs to evaluate callables per invocation (e.g., value = max_retries(self) when callable) before using them.

Useful? React with 👍 / 👎.

Comment thread utils/error_handling.py
Comment on lines +155 to +161
def ensure_dns(hosts: list[str], timeout: int = 5, max_retries: int = 3) -> None:
"""Preflight DNS resolution check for hosts."""
for host in hosts:
for attempt in range(max_retries):
try:
socket.getaddrinfo(host, 443, timeout=timeout)
logger.info(f"✓ DNS OK: {host}")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Remove unsupported argument from DNS check

ensure_dns calls socket.getaddrinfo(host, 443, timeout=timeout). The stdlib function does not accept a timeout keyword, so the very first host immediately raises TypeError: getaddrinfo() got an unexpected keyword argument 'timeout', preventing any DNS preflight or retry logic from executing. The call should use socket.setdefaulttimeout or wrap socket.getaddrinfo in socket.create_connection rather than passing a non‑existent keyword.

Useful? React with 👍 / 👎.

Comment thread utils/error_handling.py
Comment on lines +343 to +379
output_path: Path,
desc: str = None,
auth_service: Optional[str] = None,
chunk_size: int = 8192,
expected_size: Optional[int] = None,
checksum: Optional[str] = None,
) -> bool:
"""Download with full resilience features."""
try:
headers = self._get_headers(auth_service)
resp = self.session.get(
url,
headers=headers,
stream=True,
timeout=self.timeout,
allow_redirects=True,
)
resp.raise_for_status()

total_size = int(resp.headers.get("content-length", 0))
if expected_size and total_size != expected_size:
logger.warning(f"Size mismatch: expected {expected_size}, got {total_size}")

output_path.parent.mkdir(parents=True, exist_ok=True)
if output_path.exists():
logger.info(f"File exists, skipping: {output_path}")
return self._validate_file(output_path, checksum)

start_time = time.time()
downloaded = 0
last_throttle_time = start_time
throttle_interval = chunk_size / self.bandwidth_throttle if self.bandwidth_throttle else 0

with open(output_path, "wb") as f, tqdm(
total=total_size,
unit="B",
unit_scale=True,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Import modules used by download validation helpers

download_with_retry and _validate_file reference Path (type hints and path operations), tqdm (progress bar) and hashlib (checksum) but the module only imports functools, logging, etc. Without importing pathlib.Path, tqdm or hashlib, importing this module or calling these functions will raise NameError before any download happens. Add the missing imports so the resilient downloader can be used.

Useful? React with 👍 / 👎.

Comment thread utils/snap_templates.py
Comment on lines +239 to +251
def generate_graph(self, template_params: Dict, output_path: str) -> str:
"""
Generate SNAP graph with substituted parameters.

:param template_params: Dict of params to substitute (e.g., {'SUBSWATH': 'IW1'}).
:param output_path: Output XML path.
:return: Path to generated graph.
"""
# Map to template keys (upper case with _)
subst_dict = {k.upper(): str(v) for k, v in template_params.items()}
subst_dict['MASTER'] = template_params.get('input_file', '${master}')
subst_dict['SLAVE'] = template_params.get('input_file', '${slave}') # Update for slave in full process
subst_dict['OUTPUT'] = f"{template_params.get('output_paths', 'interferogram')}.tif"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Use distinct master and slave inputs when generating SNAP graphs

generate_graph substitutes both ${MASTER} and ${SLAVE} with template_params.get('input_file', ...), so when process_interferogram passes parameters derived only from the master scene the generated graph contains the same SAFE path for both nodes. Even though the GPT command later passes -Pslave=..., the graph file already hardcodes the master file twice, causing the interferogram to use identical inputs and produce invalid results. The substitution should accept separate master and slave paths (e.g., parameters master_safe/slave_safe).

Useful? React with 👍 / 👎.

Comment thread utils/snap_templates.py
Comment on lines +286 to +294
# Run via GPT (assume gpt in PATH; add snap install check if needed)
cmd = [
'gpt', str(graph_path),
'-Pmaster=' + master_safe,
'-Pslave=' + slave_safe,
'-Poutput=' + str(output_dir / f"{params['output_paths']}.tif")
]
try:
result = subprocess.run(cmd, capture_output=True, text=True, check=True)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Import subprocess before invoking GPT

process_interferogram builds the command list and executes subprocess.run(...), but the module never imports subprocess. Any call to this helper therefore crashes with NameError: name 'subprocess' is not defined before SNAP can be launched. Add import subprocess near the other imports.

Useful? React with 👍 / 👎.

Bender1011001 added a commit that referenced this pull request Oct 15, 2025
…or-project-showcase

Merge pull request #13 from Bender1011001/master
Bender1011001 added a commit that referenced this pull request Dec 5, 2025
Bender1011001 added a commit that referenced this pull request Dec 5, 2025
…or-project-showcase

Merge pull request #13 from Bender1011001/master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant