Skip to content

Commit

Permalink
fix: network filtering
Browse files Browse the repository at this point in the history
  • Loading branch information
antazoey committed Oct 26, 2023
1 parent e97d2bd commit 7195a46
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 22 deletions.
22 changes: 20 additions & 2 deletions src/ape/api/networks.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
from functools import partial
from pathlib import Path
from tempfile import mkdtemp
from typing import TYPE_CHECKING, Any, Dict, Iterator, List, Optional, Tuple, Type, Union
from typing import (
TYPE_CHECKING,
Any,
Collection,
Dict,
Iterator,
List,
Optional,
Tuple,
Type,
Union,
)

from eth_account import Account as EthAccount
from eth_account._utils.legacy_transactions import (
Expand Down Expand Up @@ -430,7 +441,9 @@ def get_network(self, network_name: str) -> "NetworkAPI":

raise NetworkNotFoundError(network_name, ecosystem=self.name, options=self.networks)

def get_network_data(self, network_name: str) -> Dict:
def get_network_data(
self, network_name: str, provider_filter: Optional[Collection[str]] = None
) -> Dict:
"""
Get a dictionary of data about providers in the network.
Expand All @@ -439,6 +452,8 @@ def get_network_data(self, network_name: str) -> Dict:
Args:
network_name (str): The name of the network to get provider data from.
provider_filter (Optional[Collection[str]]): Optional filter the providers
by name.
Returns:
dict: A dictionary containing the providers in a network.
Expand All @@ -456,6 +471,9 @@ def get_network_data(self, network_name: str) -> Dict:
data["explorer"] = str(network.explorer.name)

for provider_name in network.providers:
if provider_filter and provider_name not in provider_filter:
continue

provider_data: Dict = {"name": str(provider_name)}

# Only add isDefault key when True
Expand Down
31 changes: 27 additions & 4 deletions src/ape/managers/networks.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import json
from functools import cached_property
from typing import Dict, Iterator, List, Optional, Set, Union
from typing import Collection, Dict, Iterator, List, Optional, Set, Union

import yaml

Expand Down Expand Up @@ -500,15 +500,33 @@ def network_data(self) -> Dict:
Returns:
dict
"""
return self.get_network_data()

def get_network_data(
self,
ecosystem_filter: Optional[Collection[str]] = None,
network_filter: Optional[Collection[str]] = None,
provider_filter: Optional[Collection[str]] = None,
):
data: Dict = {"ecosystems": []}

for ecosystem_name in self:
ecosystem_data = self._get_ecosystem_data(ecosystem_name)
if ecosystem_filter and ecosystem_name not in ecosystem_filter:
continue

ecosystem_data = self._get_ecosystem_data(
ecosystem_name, network_filter=network_filter, provider_filter=provider_filter
)
data["ecosystems"].append(ecosystem_data)

return data

def _get_ecosystem_data(self, ecosystem_name: str) -> Dict:
def _get_ecosystem_data(
self,
ecosystem_name: str,
network_filter: Optional[Collection[str]] = None,
provider_filter: Optional[Collection[str]] = None,
) -> Dict:
ecosystem = self[ecosystem_name]
ecosystem_data: Dict = {"name": str(ecosystem_name)}

Expand All @@ -519,16 +537,21 @@ def _get_ecosystem_data(self, ecosystem_name: str) -> Dict:
ecosystem_data["networks"] = []

for network_name in getattr(self, ecosystem_name).networks:
network_data = ecosystem.get_network_data(network_name)
if network_filter and network_name not in network_filter:
continue

network_data = ecosystem.get_network_data(network_name, provider_filter=provider_filter)
ecosystem_data["networks"].append(network_data)

return ecosystem_data

@property
# TODO: Remove in 0.7
def networks_yaml(self) -> str:
"""
Get a ``yaml`` ``str`` representing all the networks
in all the ecosystems.
**NOTE**: Deprecated.
View the result via CLI command ``ape networks list --format yaml``.
Expand Down
45 changes: 29 additions & 16 deletions src/ape_networks/_cli.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import json
from typing import Callable, Dict

import click
import yaml
from rich import print as echo_rich_text
from rich.tree import Tree

Expand All @@ -9,6 +11,7 @@
from ape.cli import ape_cli_context, network_option
from ape.cli.choices import OutputFormat
from ape.cli.options import output_format_option
from ape.exceptions import NetworkError
from ape.logging import LogLevel
from ape.types import _LazySequence

Expand Down Expand Up @@ -45,10 +48,16 @@ def gen():
@_filter_option("network", _lazy_get("network"))
@_filter_option("provider", _lazy_get("provider"))
def _list(cli_ctx, output_format, ecosystem_filter, network_filter, provider_filter):
network_data = cli_ctx.network_manager.get_network_data(
ecosystem_filter=ecosystem_filter,
network_filter=network_filter,
provider_filter=provider_filter,
)

if output_format == OutputFormat.TREE:
default_suffix = "[dim default] (default)"
ecosystems = {e["name"]: e for e in cli_ctx.network_manager.network_data["ecosystems"]}
ecosystems = {n: ecosystems[n] for n in sorted(ecosystems)}
ecosystems = network_data["ecosystems"]
ecosystems = sorted(ecosystems, key=lambda e: e["name"])

def make_sub_tree(data: Dict, create_tree: Callable) -> Tree:
name = f"[bold green]{data['name']}"
Expand All @@ -58,24 +67,12 @@ def make_sub_tree(data: Dict, create_tree: Callable) -> Tree:
sub_tree = create_tree(name)
return sub_tree

for ecosystem_name, ecosystem in ecosystems.items():
if ecosystem_filter and ecosystem["name"] not in ecosystem_filter:
continue

for ecosystem in ecosystems:
ecosystem_tree = make_sub_tree(ecosystem, Tree)
_networks = {n["name"]: n for n in ecosystem["networks"]}
_networks = {n: _networks[n] for n in sorted(_networks)}
if network_filter:
_networks = {n: v for n, v in _networks.items() if n in network_filter}

for network_name, network in _networks.items():
if network_filter and network_name not in network_filter:
continue

providers = network["providers"]
if provider_filter:
providers = [p for p in providers if p["name"] in provider_filter]

if providers:
network_tree = make_sub_tree(network, ecosystem_tree.add)
providers = sorted(providers, key=lambda p: p["name"])
Expand All @@ -86,7 +83,23 @@ def make_sub_tree(data: Dict, create_tree: Callable) -> Tree:
echo_rich_text(ecosystem_tree)

elif output_format == OutputFormat.YAML:
click.echo(cli_ctx.network_manager.networks_yaml.strip())
if not isinstance(network_data, dict):
raise TypeError(
f"Unexpected network data type: {type(network_data)}. "
f"Expecting dict. YAML dump will fail."
)

try:
click.echo(yaml.dump(network_data, sort_keys=True).strip())
except ValueError as err:
try:
data_str = json.dumps(network_data)
except Exception:
data_str = str(network_data)

raise NetworkError(
f"Network data did not dump to YAML: {data_str}\nActual err: {err}"
) from err


@cli.command()
Expand Down
8 changes: 8 additions & 0 deletions tests/integration/cli/test_networks.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,14 @@ def test_list_yaml(ape_cli, runner):
# Skip these lines in case test-runner has installed providers
continue

if (
expected_line.lstrip().startswith("- name:")
and expected_line not in result.output
and "explorer:" in result.output
):
# May have explorers installed - ignore that.
expected_line = expected_line.lstrip(" -")

assert expected_line in result.output, result.output


Expand Down

0 comments on commit 7195a46

Please sign in to comment.