Skip to content

Commit 05e8287

Browse files
authored
Merge pull request #8 from ESA-PhiLab/0.1.12
2 parents cbc9726 + 276796c commit 05e8287

6 files changed

Lines changed: 328 additions & 1801 deletions

File tree

how_to_start.ipynb

Lines changed: 280 additions & 178 deletions
Large diffs are not rendered by default.

pdm.lock

Lines changed: 1 addition & 1598 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

phidown/downloader.py

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import yaml
1010
import argparse
1111
import getpass
12+
import sys
1213
from typing import Tuple
1314

1415

@@ -27,13 +28,24 @@ def load_credentials(file_name: str = 'secret.yml') -> Tuple[str, str]:
2728
yaml.YAMLError: If the YAML file is invalid or cannot be written properly.
2829
KeyError: If expected keys are missing in the YAML structure.
2930
"""
30-
script_dir = os.path.dirname(os.path.abspath(__file__))
31-
secrets_file_path = os.path.join(script_dir, file_name)
31+
# First, check for secret.yml in the current working directory
32+
cwd_secrets_file_path = os.path.join(os.getcwd(), file_name)
33+
if os.path.isfile(cwd_secrets_file_path):
34+
secrets_file_path = cwd_secrets_file_path
35+
else:
36+
# Fallback: check for secret.yml in the script directory
37+
script_dir = os.path.dirname(os.path.abspath(__file__))
38+
secrets_file_path = os.path.join(script_dir, file_name)
3239

40+
# Always prompt if not found, even in Jupyter or import context
3341
if not os.path.isfile(secrets_file_path):
34-
print(f"Secrets file not found: {secrets_file_path}")
35-
username = input("Enter username: ").strip()
36-
password = getpass.getpass("Enter password: ").strip()
42+
try:
43+
# For Jupyter, input and getpass work as expected
44+
print(f"Secrets file not found: {secrets_file_path}")
45+
username = input("Enter username: ").strip()
46+
password = getpass.getpass("Enter password: ").strip()
47+
except Exception as e:
48+
raise RuntimeError(f"Could not prompt for credentials: {e}")
3749

3850
secrets = {
3951
'credentials': {
@@ -111,7 +123,7 @@ def get_access_token(config, username, password):
111123
return access_token
112124
else:
113125
print(f"Failed to retrieve access token. Status code: {response.status_code}")
114-
exit(1)
126+
sys.exit(1)
115127

116128

117129
def get_eo_product_details(config, headers, eo_product_name):
@@ -125,7 +137,7 @@ def get_eo_product_details(config, headers, eo_product_name):
125137
return eo_product_data["Id"], eo_product_data["S3Path"]
126138
else:
127139
print(f"Failed to retrieve EO product details. Status code: {response.status_code}")
128-
exit(1)
140+
sys.exit(1)
129141

130142

131143
def get_temporary_s3_credentials(headers):
@@ -147,11 +159,11 @@ def get_temporary_s3_credentials(headers):
147159
else:
148160
print("Error: Access denied. Please check your permissions or access token.")
149161
print(f"Response Body: {credentials_response.text}")
150-
exit(1)
162+
sys.exit(1)
151163
else:
152164
print(f"Failed to create temporary S3 credentials. Status code: {credentials_response.status_code}")
153165
print(f"Response Body: {credentials_response.text}")
154-
exit(1)
166+
sys.exit(1)
155167

156168

157169
def format_filename(filename, length=40):
@@ -281,6 +293,7 @@ def pull_down(product_name=None, args=None):
281293
description="Script to download EO product using OData and S3 protocol.",
282294
epilog="Example usage: python script.py -u <username> -p <password> <eo_product_name>"
283295
)
296+
parser.add_argument('--init-secret', action='store_true', help='Prompt for credentials and create/overwrite secret.yml, then exit')
284297
# User credentials
285298
username, password = load_credentials()
286299
# Add command line arguments
@@ -289,10 +302,20 @@ def pull_down(product_name=None, args=None):
289302
parser.add_argument('-eo_product_name', type=str, help='Name of the Earth Observation product to be downloaded (required)')
290303
args = parser.parse_args()
291304

305+
if args.init_secret:
306+
# Force prompt and overwrite secret.yml using load_credentials
307+
try:
308+
username, password = load_credentials(file_name='secret.yml')
309+
print("Secrets file created/updated successfully.")
310+
except Exception as e:
311+
print(f"Error creating/updating secrets file: {e}")
312+
sys.exit(1)
313+
292314
# Prompt for missing credentials
293315
if not args.username:
294316
args.username = input("Enter username: ")
295317
if not args.password:
296318
args.password = input("Enter password: ")
297319

298320
pull_down(product_name=args.eo_product_name, args=args)
321+
sys.exit(0)

phidown/search.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -182,20 +182,20 @@ def _get_valid_product_types(self, collection_name):
182182
def _validate_product_type(self):
183183
"""
184184
Validates the provided product type against a list of valid product types.
185+
If the product type is None, the validation is skipped.
185186
186187
Raises:
187-
ValueError: If the product type is None, empty, or not in the list of valid product types.
188+
ValueError: If the product type is not in the list of valid product types.
188189
TypeError: If the product type is not a string.
189190
"""
190-
valid_product_types = self._get_valid_product_types(self.collection_name)
191-
if self.product_type is None:
192-
raise ValueError("Product type cannot be None")
193-
if not isinstance(self.product_type, str):
194-
raise TypeError("Product type must be a string")
195-
if not self.product_type:
196-
raise ValueError("Product type cannot be empty")
197-
if self.product_type not in valid_product_types:
198-
raise ValueError(f"Invalid product type: {self.product_type}. Must be one of: {', '.join(valid_product_types)}")
191+
if self.product_type is not None:
192+
valid_product_types = self._get_valid_product_types(self.collection_name)
193+
if not isinstance(self.product_type, str):
194+
raise TypeError("Product type must be a string")
195+
if not self.product_type:
196+
raise ValueError("Product type cannot be empty")
197+
if self.product_type not in valid_product_types:
198+
raise ValueError(f"Invalid product type: {self.product_type}. Must be one of: {', '.join(valid_product_types)}")
199199

200200
def _validate_order_by(self):
201201
"""

pyproject.toml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "phidown"
3-
version = "0.1.11"
3+
version = "0.1.12"
44
description = "A project using AWS services and dataset tools for Sentinel data"
55
authors = [
66
{ name = "Roberto Del Prete", email = "roberto.delprete@esa.int" }
@@ -10,11 +10,10 @@ dependencies = [
1010
"boto3>=1.37.34", # changed from exact to minimum version
1111
"numpy>=1.6", # changed from >1.6 (not typical) to >=1.6
1212
"pandas>=1.5.2", # keep as is, already minimum version
13-
"dataset-tools>=0.1.6", # changed from exact to minimum
1413
"supervisely>=6.73.338",# changed from exact to minimum
15-
"pyaml>=25.1.0", # keep as is
16-
"ipykernel>=6.29.5", # keep as is
17-
"zstandard>=0.23.0", # keep as is
14+
"pyaml>=25.1.0",
15+
"ipykernel>=6.29.5",
16+
"zstandard>=0.23.0",
1817
]
1918

2019
requires-python = ">=3.9"

readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ To authenticate with the Copernicus Data Space Ecosystem, you need to create a `
260260
2. Add the following content to the file, replacing `your_username` and `your_password` with your actual credentials:
261261

262262
```yaml
263-
# filepath: ./phidown/secret.yml
263+
# filepath: ./phidown/secret.yml or the current working directory where phidown is launched
264264
copernicus:
265265
username: <your_username>
266266
password: <your_password>

0 commit comments

Comments
 (0)