Skip to content

Commit

Permalink
Merge pull request #4 from adehecq/info
Browse files Browse the repository at this point in the history
add the info command
  • Loading branch information
adehecq authored Aug 6, 2024
2 parents 370fdc5 + ffb96a0 commit 595b7e3
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 19 deletions.
60 changes: 41 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,16 @@ Options:
--help Show this message and exit.
Commands:
download Download scenes with their entity ids provided in the textfile.
download Download scenes with their entity ids provided in the textfile.
download-browse Download browse images of a vector data file localy.
search Search scenes in a dataset with filters.
info Display information on available datasets and filters.
search Search scenes in a dataset with filters.
```

### Credentials

Credentials for the Earth Explorer portal can be obtained [here](https://ers.cr.usgs.gov/register/).
Credentials for the Earth Explorer portal can be obtained [here](https://ers.cr.usgs.gov/register/). Note that you need to specify specifically all datasets you plan to access through the API.

Either one of the password or token must be provided.

`--username` and `--token` or `--password` can be provided as command-line options or as environment variables:
Expand Down Expand Up @@ -103,7 +105,7 @@ Options:
--help Show this message and exit.
```

If the `--output` is not provided, the command will print entity ids of scenes found. Else if the `--output` is provided it will save results in the file. There is 5 availables format for the results:
If the `--output` is not provided, the command will print the entity ids of scenes found. Else if `--output` is provided it will save the results in the given file. Five formats are currently supported for the output:
- **text file (.txt)** : Each line is an entity id and the first line contain the dataset ex: `#dataset=landsat_tm_c2_l1`. This file can then be used to download the images.
- **json file (.json)** : json file containing the results of the search.
- **vector data (.gpkg, .shp, .geojson)** : save the results in a vector file, useful to visualise the geographic location of the results in a GIS.
Expand All @@ -124,21 +126,7 @@ usgsxplore search declassii --filter "camera=KH-9 Lower Resolution Mapping Camer
# select scenes from the Hexagon KH-9 satellites if they are downloadable
usgsxplore search declassii --filter "camera=L & DOWNLOAD_AVAILABLE=Y"
```

**Note**: If you don't know what filters are available, they will be printed to screen when typing any (wrong) value. For example,
```bash
usgsxplore search declassii -f "whatever=?"
```
will print all metadata filters that can be used for the "declassii" dataset.

<img width="439" alt="image" src="https://github.com/user-attachments/assets/e3fc1fdc-9ee2-4ddb-a9a4-863c5884a1d3">

```bash
usgsxplore search declassii -f "camera=?"
```
will print all possible values for the filter "camera".

<img width="391" alt="image" src="https://github.com/user-attachments/assets/bcdedad7-39b0-44de-bf8c-fc7e4ca5f1ee">
**Note**: To know which filters are available, check the command `usgsxplore info` below.

### Downloading

Expand Down Expand Up @@ -182,3 +170,37 @@ Options:
--pbar Display a progress bar.
--help Show this message and exit.
```

### Info: datasets and filters

Information on available datasets and filters can be printed on screen with the command `usgsxplore info`
```bash
usgsxplore info --help
```
```
Usage: usgsxplore info [OPTIONS] COMMAND [ARGS]...
Display information on available datasets and filters.
Options:
--help Show this message and exit.
Commands:
dataset Display the list of available datasets in the API.
filters Display a list of available filter fields for a dataset.
```

**Hints**: When using `usgsxplore search`, filters will be printed to screen when typing any (wrong) value. For example,
```bash
usgsxplore search declassii -f "whatever=?"
```
will print all metadata filters that can be used for the "declassii" dataset.

<img width="439" alt="image" src="https://github.com/user-attachments/assets/e3fc1fdc-9ee2-4ddb-a9a4-863c5884a1d3">

```bash
usgsxplore search declassii -f "camera=?"
```
will print all possible values for the filter "camera".

<img width="391" alt="image" src="https://github.com/user-attachments/assets/bcdedad7-39b0-44de-bf8c-fc7e4ca5f1ee">
14 changes: 14 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,17 @@ def test_download():

assert result.exit_code == 0
assert "LT05_L1TP_038037_20120505_20200820_02_T1.tar" in os.listdir(tmpdir)


def test_info():
"""Test the info command with each subcommand: dataset, filters"""
runner = CliRunner()

# Test the dataset subcommand
result = runner.invoke(cli, ["info", "dataset"])
assert result.exit_code == 0
assert len(result.output) == 7260 # Possibly to be updated in the future

# Test the filters subcommand
result = runner.invoke(cli, ["info", "filters", "declassii"])
assert result.exit_code == 0
52 changes: 52 additions & 0 deletions usgsxplore/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from usgsxplore.filter import SceneFilter
from usgsxplore.utils import (
download_browse_img,
format_table,
read_textfile,
save_in_gfile,
sort_strings_by_similarity,
Expand Down Expand Up @@ -276,9 +277,60 @@ def download_browse(vector_file: str, output_dir: str, pbar: bool) -> None:
save_in_gfile(gdf, vector_file)


@click.group()
def info() -> None:
"""
Display some informations.
"""


@click.command()
@click.option("-u", "--username", type=click.STRING, help="EarthExplorer username.", envvar="USGS_USERNAME")
@click.option(
"-p", "--password", type=click.STRING, help="EarthExplorer password.", required=False, envvar="USGS_PASSWORD"
)
@click.option("-t", "--token", type=click.STRING, help="EarthExplorer token.", required=False, envvar="USGS_TOKEN")
@click.option("-a", "--all", is_flag=True, help="display also all event dataset")
def dataset(username: str, password: str | None, token: str | None, all: bool) -> None:
"""
Display the list of available dataset in the API.
"""
api = API(username, password, token)
if all:
click.echo(api.dataset_names())
else:
dataset_list = [dataset for dataset in api.dataset_names() if not dataset.startswith("event")]
click.echo(dataset_list)
api.logout()


@click.command()
@click.option("-u", "--username", type=click.STRING, help="EarthExplorer username.", envvar="USGS_USERNAME")
@click.option(
"-p", "--password", type=click.STRING, help="EarthExplorer password.", required=False, envvar="USGS_PASSWORD"
)
@click.option("-t", "--token", type=click.STRING, help="EarthExplorer token.", required=False, envvar="USGS_TOKEN")
@click.argument("dataset", type=click.STRING)
def filters(username: str, password: str | None, token: str | None, dataset: str) -> None:
"""
Display a list of available filter field for a dataset.
"""
api = API(username, password, token)
dataset_filters = api.dataset_filters(dataset)
table = [["field id", "field lbl", "field sql"]]
for i, filt in enumerate(dataset_filters):
table.append([filt["id"], filt["fieldLabel"], filt["searchSql"].split(" ", maxsplit=1)[0]])
click.echo(format_table(table))

api.logout()


cli.add_command(search)
cli.add_command(download)
cli.add_command(download_browse)
cli.add_command(info)
info.add_command(dataset)
info.add_command(filters)


if __name__ == "__main__":
Expand Down
21 changes: 21 additions & 0 deletions usgsxplore/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,4 +172,25 @@ def update_gdf_browse(gdf: gpd.GeoDataFrame, output_dir: str) -> gpd.GeoDataFram
return gdf


def format_table(data: list[list]) -> str:
"""
Return a string reprentation of a 2 dimensional table
:param data: 2 dimensional table
:return: string representation
"""
table_str = ""
col_widths = [max(len(str(item)) for item in col) for col in zip(*data)]

# consider the first line like a header
header = " ".join(f"{str(item):<{col_widths[i]}}" for i, item in enumerate(data[0])) + "\n"
table_str += header

# construct other line
for row in data[1:]:
table_str += " | ".join(f"{str(item):<{col_widths[i]}}" for i, item in enumerate(row)) + "\n"

return table_str


# End-of-file (EOF)

0 comments on commit 595b7e3

Please sign in to comment.