PyGeoFetch 2.0.8__tar.gz → 2.0.9__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/CHANGELOG.md +6 -6
  2. {pygeofetch-2.0.8/pygeofetch.egg-info → pygeofetch-2.0.9}/PKG-INFO +1 -1
  3. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/__init__.py +2 -2
  4. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/cli/main.py +2 -2
  5. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/insar/unwrap.py +39 -41
  6. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/meta.yaml +1 -1
  7. {pygeofetch-2.0.8 → pygeofetch-2.0.9/pygeofetch.egg-info}/PKG-INFO +1 -1
  8. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pyproject.toml +1 -1
  9. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/LICENSE +0 -0
  10. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/MANIFEST.in +0 -0
  11. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/README.md +0 -0
  12. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/cli/__init__.py +0 -0
  13. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/cli/auth_commands.py +0 -0
  14. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/cli/config_commands.py +0 -0
  15. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/cli/download_commands.py +0 -0
  16. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/cli/index_commands.py +0 -0
  17. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/cli/pipeline_process_commands.py +0 -0
  18. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/cli/postprocess_commands.py +0 -0
  19. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/cli/preprocess_commands.py +0 -0
  20. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/cli/sar_commands.py +0 -0
  21. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/cli/search_commands.py +0 -0
  22. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/config/__init__.py +0 -0
  23. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/config/defaults.yaml +0 -0
  24. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/config/settings.py +0 -0
  25. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/core/__init__.py +0 -0
  26. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/core/authenticator.py +0 -0
  27. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/core/cache_manager.py +0 -0
  28. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/core/downloader.py +0 -0
  29. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/core/engine.py +0 -0
  30. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/core/logging.py +0 -0
  31. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/core/orbits.py +0 -0
  32. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/core/scheduler.py +0 -0
  33. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/core/searcher.py +0 -0
  34. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/insar/__init__.py +0 -0
  35. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/insar/annotation.py +0 -0
  36. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/insar/atmosphere.py +0 -0
  37. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/insar/coregister.py +0 -0
  38. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/insar/deburst.py +0 -0
  39. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/insar/esd.py +0 -0
  40. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/insar/extraction.py +0 -0
  41. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/insar/flatearth.py +0 -0
  42. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/insar/geolocation.py +0 -0
  43. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/insar/gpu.py +0 -0
  44. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/insar/interferogram.py +0 -0
  45. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/insar/ionosphere.py +0 -0
  46. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/insar/splitspectrum_diagnostic.py +0 -0
  47. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/insar/stack_selection.py +0 -0
  48. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/insar/synthetic.py +0 -0
  49. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/insar/timeseries.py +0 -0
  50. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/insar/validate.py +0 -0
  51. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/insar/visualize.py +0 -0
  52. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/insar/workflow.py +0 -0
  53. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/models/__init__.py +0 -0
  54. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/models/download_task.py +0 -0
  55. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/models/satellite_data.py +0 -0
  56. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/models/search_query.py +0 -0
  57. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/models/user_auth.py +0 -0
  58. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/processing/__init__.py +0 -0
  59. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/processing/base.py +0 -0
  60. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/processing/batch.py +0 -0
  61. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/processing/indices.py +0 -0
  62. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/processing/pipeline.py +0 -0
  63. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/processing/postprocessor.py +0 -0
  64. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/processing/preprocessor.py +0 -0
  65. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/processing/sar.py +0 -0
  66. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/processor/__init__.py +0 -0
  67. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/processor/indices.py +0 -0
  68. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/processor/landsat.py +0 -0
  69. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/processor/loader.py +0 -0
  70. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/processor/stacker.py +0 -0
  71. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/processor/timeseries.py +0 -0
  72. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/providers/__init__.py +0 -0
  73. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/providers/airbus_oneatlas.py +0 -0
  74. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/providers/alaska_satellite_facility.py +0 -0
  75. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/providers/aws_earth.py +0 -0
  76. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/providers/base.py +0 -0
  77. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/providers/copernicus.py +0 -0
  78. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/providers/digitalglobe.py +0 -0
  79. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/providers/earth_explorer_additional.py +0 -0
  80. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/providers/element84.py +0 -0
  81. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/providers/eodag_provider.py +0 -0
  82. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/providers/esa_scihub.py +0 -0
  83. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/providers/geoserver_generic.py +0 -0
  84. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/providers/google_earth_engine.py +0 -0
  85. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/providers/inpe_cbers.py +0 -0
  86. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/providers/isro_bhuvan.py +0 -0
  87. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/providers/jaxa_earth.py +0 -0
  88. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/providers/maxar_gbdx.py +0 -0
  89. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/providers/nasa_earthdata.py +0 -0
  90. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/providers/nasa_earthdata_cloud.py +0 -0
  91. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/providers/noaa_big_data.py +0 -0
  92. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/providers/opentopography.py +0 -0
  93. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/providers/planet.py +0 -0
  94. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/providers/planetary_computer.py +0 -0
  95. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/providers/sentinel_hub.py +0 -0
  96. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/providers/terrabotics.py +0 -0
  97. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/providers/usgs.py +0 -0
  98. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/sar/__init__.py +0 -0
  99. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/sar/_native.py +0 -0
  100. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/sar/_ost.py +0 -0
  101. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/sar/_sarxarray.py +0 -0
  102. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/sar/extraction.py +0 -0
  103. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/sar/processor.py +0 -0
  104. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/utils/__init__.py +0 -0
  105. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/utils/file_utils.py +0 -0
  106. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/utils/gcp_recovery.py +0 -0
  107. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/utils/geo_utils.py +0 -0
  108. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/utils/logging_setup.py +0 -0
  109. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/utils/retry_handler.py +0 -0
  110. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/utils/validators.py +0 -0
  111. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/viz/__init__.py +0 -0
  112. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/viz/map.py +0 -0
  113. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch/viz/plot.py +0 -0
  114. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch.egg-info/SOURCES.txt +0 -0
  115. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch.egg-info/dependency_links.txt +0 -0
  116. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch.egg-info/entry_points.txt +0 -0
  117. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch.egg-info/not-zip-safe +0 -0
  118. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch.egg-info/requires.txt +0 -0
  119. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/pygeofetch.egg-info/top_level.txt +0 -0
  120. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/setup.cfg +0 -0
  121. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/tests/test_atmospheric_circular_regression (1).py +0 -0
  122. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/tests/test_atmospheric_circular_regression.py +0 -0
  123. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/tests/test_build_sbas_network.py +0 -0
  124. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/tests/test_burst_metadata.py +0 -0
  125. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/tests/test_burst_processing_integration.py +0 -0
  126. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/tests/test_coregister_integration.py +0 -0
  127. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/tests/test_coregister_upgrades.py +0 -0
  128. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/tests/test_era5_atmospheric_correction.py +0 -0
  129. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/tests/test_extraction.py +0 -0
  130. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/tests/test_flat_earth_phase.py +0 -0
  131. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/tests/test_gcp_reprojection.py +0 -0
  132. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/tests/test_insar.py +0 -0
  133. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/tests/test_ionosphere.py +0 -0
  134. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/tests/test_models.py +0 -0
  135. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/tests/test_pgv_integration_contract.py +0 -0
  136. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/tests/test_provider_geometry_audit (1).py +0 -0
  137. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/tests/test_provider_geometry_audit.py +0 -0
  138. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/tests/test_provider_scene_disambiguation.py +0 -0
  139. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/tests/test_providers.py +0 -0
  140. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/tests/test_raster_collocation_integration.py +0 -0
  141. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/tests/test_search_download.py +0 -0
  142. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/tests/test_splitspectrum_diagnostic.py +0 -0
  143. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/tests/test_utils.py +0 -0
  144. {pygeofetch-2.0.8 → pygeofetch-2.0.9}/tests/test_viz_plot.py +0 -0
@@ -1,9 +1,9 @@
1
1
  # Changelog
2
2
 
3
3
  All notable changes to PyGeoFetch are documented here.
4
- Format follows [Keep a Changelog](https://keepachangelog.com/en/2.0.8/).
4
+ Format follows [Keep a Changelog](https://keepachangelog.com/en/2.0.9/).
5
5
 
6
- ## [2.0.8] — 2026-07-29
6
+ ## [2.0.9] — 2026-07-29
7
7
 
8
8
  ### Added
9
9
  - Major SNAPHU unwrapping improvements for urban InSAR applications
@@ -51,7 +51,7 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/2.0.8/).
51
51
 
52
52
  ### Migration Guide
53
53
  ```python
54
- # Before (v2.0.8)
54
+ # Before (v2.0.9)
55
55
  unwrapper = PhaseUnwrapper(cost_mode="defo", init_method="mcf")
56
56
  unwrapped = unwrapper.unwrap(phase, coherence, nlooks=2.0)
57
57
 
@@ -72,7 +72,7 @@ unwrapped = unwrapper.unwrap(
72
72
 
73
73
  ---
74
74
 
75
- ## [2.0.8] — 2026-07-12
75
+ ## [2.0.9] — 2026-07-12
76
76
 
77
77
  ### Added
78
78
  - Federated search across 22+ satellite data providers
@@ -188,8 +188,8 @@ unwrapped = unwrapper.unwrap(
188
188
 
189
189
  | Version | Date | Key Changes |
190
190
  |---------|------------|-------------|
191
- | **2.0.8** | 2026-07-29 | SNAPHU unwrapping fixes, 87.1% reliable pixels |
192
- | **2.0.8** | 2026-07-12 | 22 providers, 17 indices, Sentinel-1C/D |
191
+ | **2.0.9** | 2026-07-29 | SNAPHU unwrapping fixes, 87.1% reliable pixels |
192
+ | **2.0.9** | 2026-07-12 | 22 providers, 17 indices, Sentinel-1C/D |
193
193
  | **1.9.2** | 2026-06-15 | Batch processing, parallel downloads |
194
194
  | **1.9.1** | 2026-05-20 | 3D terrain, SNAPHU integration, time series |
195
195
  | **1.9.0** | 2026-04-25 | Initial public release |
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pygeofetch
3
- Version: 2.0.8
3
+ Version: 2.0.9
4
4
  Summary: Universal satellite data pipeline + geospatial processing platform
5
5
  Author-email: Samuel Appiah Kubi <appiahkubis14@gmail.com>
6
6
  License: MIT License
@@ -1,5 +1,5 @@
1
1
  """
2
- PyGeoFetch v2.0.8 — Universal Satellite Data Pipeline.
2
+ PyGeoFetch v2.0.9 — Universal Satellite Data Pipeline.
3
3
 
4
4
  Unified access to 22+ satellite data providers with a consistent
5
5
  Python API and CLI. Supports authentication management, federated search,
@@ -30,7 +30,7 @@ CLI::
30
30
  pygeofetch doctor
31
31
  """
32
32
 
33
- __version__ = "2.0.8"
33
+ __version__ = "2.0.9"
34
34
  __author__ = "PyGeoFetch Contributors"
35
35
  __license__ = "MIT"
36
36
 
@@ -1,5 +1,5 @@
1
1
  """
2
- PyGeoFetch CLI v2.0.8 main entry point.
2
+ PyGeoFetch CLI v2.0.9 main entry point.
3
3
 
4
4
  Full command reference:
5
5
  pygeofetch auth — credential management
@@ -71,7 +71,7 @@ def cli(
71
71
  ) -> None:
72
72
  """
73
73
  \b
74
- PyGeoFetch v2.0.8 — Universal Satellite Data Pipeline
74
+ PyGeoFetch v2.0.9 — Universal Satellite Data Pipeline
75
75
  ===========================================================
76
76
  Unified access to 22+ satellite data providers.
77
77
 
@@ -523,12 +523,14 @@ class PhaseUnwrapper:
523
523
 
524
524
  def _ensure_msvc_runtime(self, bin_dir: Path):
525
525
  """
526
- Fixes the 0xC0000135 error by finding the required MSVC DLLs
527
- already present in the user's Python environment (e.g., from
528
- numpy/scipy wheels) and copying them next to snaphu.exe.
526
+ Fixes the 0xC0000135 (STATUS_DLL_NOT_FOUND) error by downloading
527
+ the required MSVC DLLs directly from NuGet (VCRuntime.140 package).
528
+ This requires ZERO admin rights and ZERO manual installation.
529
529
  """
530
- import sys
531
530
  import shutil
531
+ import zipfile
532
+ import io
533
+ import urllib.request
532
534
 
533
535
  required_dlls = ["vcruntime140.dll", "msvcp140.dll"]
534
536
  missing = [dll for dll in required_dlls if not (bin_dir / dll).exists()]
@@ -536,45 +538,41 @@ class PhaseUnwrapper:
536
538
  if not missing:
537
539
  return
538
540
 
539
- logger.info(f"SNAPHU requires {missing}. Searching local Python environment...")
541
+ logger.info(f"SNAPHU requires {missing}. Downloading directly from NuGet (no admin required)...")
540
542
 
541
- found = {}
542
- for path in sys.path:
543
- if not path or not Path(path).exists():
544
- continue
545
- try:
546
- p = Path(path)
547
- for dll in missing:
548
- if dll in found:
549
- continue
550
- # Check .libs folders first (where numpy/scipy put them)
551
- for libs_dir in p.glob("*.libs"):
552
- target = libs_dir / dll
553
- if target.exists():
554
- found[dll] = target
555
- break
556
- if dll in found:
557
- continue
558
- # Fallback to full rglob if not in .libs
559
- for target in p.rglob(dll):
560
- found[dll] = target
561
- break
562
- except Exception:
563
- continue
543
+ # NuGet packages are just zip files. We download the VCRuntime.140 package
544
+ # which contains the exact DLLs we need for x64 Windows.
545
+ nuget_url = "https://www.nuget.org/api/v2/package/VCRuntime.140"
546
+
547
+ try:
548
+ req = urllib.request.Request(nuget_url, headers={'User-Agent': 'PyGeoFetch'})
549
+ with urllib.request.urlopen(req, timeout=30) as response:
550
+ nupkg_data = response.read()
564
551
 
565
- if len(found) == len(missing):
566
- logger.info("Found MSVC DLLs in local Python environment. Copying to SNAPHU bin...")
567
- for dll, src in found.items():
568
- shutil.copy2(src, bin_dir / dll)
569
- return
570
-
571
- raise RuntimeError(
572
- f"SNAPHU requires the Microsoft Visual C++ Redistributable DLLs ({missing}), "
573
- "but they could not be found in your Python environment.\n"
574
- "Please install the Microsoft Visual C++ Redistributable manually from:\n"
575
- "https://aka.ms/vs/17/release/vc_redist.x64.exe\n"
576
- "Then restart your Jupyter kernel and try again."
577
- )
552
+ extracted = 0
553
+ with zipfile.ZipFile(io.BytesIO(nupkg_data)) as zf:
554
+ for name in zf.namelist():
555
+ # We only want the 64-bit native DLLs
556
+ if "win-x64/native/" in name and name.lower().endswith(".dll"):
557
+ dll_name = Path(name).name
558
+ if dll_name.lower() in [m.lower() for m in missing]:
559
+ with zf.open(name) as src, open(bin_dir / dll_name, "wb") as dst:
560
+ shutil.copyfileobj(src, dst)
561
+ extracted += 1
562
+
563
+ if extracted == len(missing):
564
+ logger.info(f"Successfully extracted {extracted} MSVC DLLs to {bin_dir}. Retrying SNAPHU...")
565
+ return
566
+ else:
567
+ raise RuntimeError(f"Could not find all required DLLs in the NuGet package. Found {extracted}/{len(missing)}")
568
+
569
+ except Exception as e:
570
+ raise RuntimeError(
571
+ f"Failed to download/extract MSVC runtime DLLs from NuGet: {e}\n"
572
+ "As a last resort, please install the Microsoft Visual C++ Redistributable manually from:\n"
573
+ "https://aka.ms/vs/17/release/vc_redist.x64.exe\n"
574
+ "Then restart your Jupyter kernel."
575
+ )
578
576
 
579
577
  def unwrap(
580
578
  self,
@@ -1,4 +1,4 @@
1
- {% set version = "2.0.8" %}
1
+ {% set version = "2.0.9" %}
2
2
 
3
3
  package:
4
4
  name: pygeofetch
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pygeofetch
3
- Version: 2.0.8
3
+ Version: 2.0.9
4
4
  Summary: Universal satellite data pipeline + geospatial processing platform
5
5
  Author-email: Samuel Appiah Kubi <appiahkubis14@gmail.com>
6
6
  License: MIT License
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pygeofetch"
7
- version = "2.0.8"
7
+ version = "2.0.9"
8
8
  description = "Universal satellite data pipeline + geospatial processing platform"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
File without changes
File without changes
File without changes
File without changes