Skip to content

Commit

Permalink
Merge pull request #947 from fetchai/develop
Browse files Browse the repository at this point in the history
Release v0.2.3
  • Loading branch information
DavidMinarsch authored Mar 19, 2020
2 parents bc4f65f + 64d97c2 commit 4404811
Show file tree
Hide file tree
Showing 117 changed files with 5,893 additions and 2,849 deletions.
1 change: 1 addition & 0 deletions AUTHORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ This is the official list of Fetch.AI authors for copyright purposes.
* Aristotelis Triantafyllidis <aristotelis.triantafyllidis@fetch.ai> [Totoual](https://github.com/Totoual)
* Diarmid Campbell <diarmid.campbell@fetch.ai> [dishmop](https://github.com/dishmop)
* Oleg Panasevych <oleg.panasevych@n-cube.co.uk> [Panasevychol](https://github.com/panasevychol)
* Kevin Chen <kevin.chen@fetch.ai> [Kevin-Chen0](https://github.com/Kevin-Chen0)
12 changes: 12 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Release History

## 0.2.3 (2020-03-19)

- Fixes stub connection file I/O
- Fixes OEF connection teardown
- Fixes CLI GUI subprocesses issues
- Adds support for URI based routing of envelopes
- Improves skill guide by adding a service provider agent
- Protocol generator bug fixes
- Add aea_version field to package yaml files for version management
- Multiple docs updates and restructuring
- Multiple additional minor fixes and changes

## 0.2.2 (2020-03-09)

- Fixes registry to only load registered packages
Expand Down
12 changes: 6 additions & 6 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,18 @@ bandit = "==1.6.2"
black = "==19.10b0"
bs4 = "==0.0.1"
colorlog = "==4.1.0"
docker = "==4.2.0"
fetch-p2p-api = {index = "https://test.pypi.org/simple/",version = "==0.0.2"}
flake8 = "==3.7.9"
flake8-bugbear = "==20.1.4"
flake8-docstrings = "==1.5.0"
flake8-import-order = "==0.18.1"
gym = "==0.15.6"
liccheck = "==0.4.0"
markdown = ">=3.2.1"
mkdocs = "==1.1"
mkdocs-material = "==4.6.3"
mkdocs-mermaid-plugin = {git = "https://github.com/pugong/mkdocs-mermaid-plugin.git"}
mypy = "==0.761"
numpy = "==1.18.1"
oef = "==0.8.1"
Expand All @@ -32,13 +36,9 @@ pymdown-extensions = "==6.3"
pytest = "==5.3.5"
pytest-asyncio = "==0.10.0"
pytest-cov = "==2.8.1"
tox = "==3.14.5"
safety = "==1.8.5"
liccheck = "==0.4.0"
docker = "*"
mkdocs-mermaid-plugin = {git = "https://github.com/pugong/mkdocs-mermaid-plugin.git"}
markdown = ">=3.2.1"
pytest-randomly = "==3.2.1"
safety = "==1.8.5"
tox = "==3.14.5"

[packages]
# we don't specify dependencies for the library here for intallation as per: https://pipenv-fork.readthedocs.io/en/latest/advanced.html#pipfile-vs-setuppy
2 changes: 1 addition & 1 deletion aea/__version__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
__title__ = "aea"
__description__ = "Autonomous Economic Agent framework"
__url__ = "https://github.com/fetchai/agents-aea.git"
__version__ = "0.2.2"
__version__ = "0.2.3"
__author__ = "Fetch.AI Limited"
__license__ = "Apache-2.0"
__copyright__ = "2019 Fetch.AI Limited"
2 changes: 1 addition & 1 deletion aea/aea.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ def _handle(self, envelope: Envelope) -> None:
logger.warning("Decoding error. Exception: {}".format(str(e)))
return

handlers = self.filter.get_active_handlers(protocol.id)
handlers = self.filter.get_active_handlers(protocol.id, envelope.context)
if len(handlers) == 0:
if error_handler is not None:
error_handler.send_unsupported_skill(envelope)
Expand Down
5 changes: 2 additions & 3 deletions aea/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ def start(self) -> None:
:return: None
"""
if not self.is_debug and not self.multiplexer.connection_status.is_connected:
if not self.is_debug:
self.multiplexer.connect()

logger.debug("[{}]: Calling setup method...".format(self.name))
Expand Down Expand Up @@ -206,8 +206,7 @@ def stop(self) -> None:
self.teardown()

logger.debug("[{}]: Stopping message processing...".format(self.name))
if self.multiplexer.connection_status.is_connected:
self.multiplexer.disconnect()
self.multiplexer.disconnect()

@abstractmethod
def setup(self) -> None:
Expand Down
18 changes: 10 additions & 8 deletions aea/cli/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,9 @@
AUTHOR = "author"
CLI_CONFIG_PATH = os.path.join(os.path.expanduser("~"), ".aea", "cli_config.yaml")
DEFAULT_VERSION = "0.1.0"
DEFAULT_CONNECTION = PublicId.from_str(
"fetchai/stub:" + DEFAULT_VERSION
) # type: PublicId
DEFAULT_SKILL = PublicId.from_str("fetchai/error:" + DEFAULT_VERSION) # type: PublicId
DEFAULT_CONNECTION = PublicId.from_str("fetchai/stub:" + DEFAULT_VERSION)
DEFAULT_PROTOCOL = PublicId.from_str("fetchai/default:" + DEFAULT_VERSION)
DEFAULT_SKILL = PublicId.from_str("fetchai/error:" + DEFAULT_VERSION)
DEFAULT_LEDGER = FETCHAI
DEFAULT_REGISTRY_PATH = str(Path("./", "packages"))
DEFAULT_LICENSE = "Apache-2.0"
Expand Down Expand Up @@ -431,7 +430,7 @@ def _is_validate_author_handle(author: str) -> bool:


def _try_get_item_source_path(
path: str, author_name: str, item_type_plural: str, item_name: str
path: str, author_name: Optional[str], item_type_plural: str, item_name: str
) -> str:
"""
Get the item source path.
Expand All @@ -443,15 +442,18 @@ def _try_get_item_source_path(
:return: the item source path
"""
source_path = os.path.join(path, author_name, item_type_plural, item_name)
if author_name is None:
source_path = os.path.join(path, item_type_plural, item_name)
else:
source_path = os.path.join(path, author_name, item_type_plural, item_name)
if not os.path.exists(source_path):
raise click.ClickException(
'Item "{}" not found in source folder.'.format(item_name)
)
return source_path


def _try_get_vendorized_item_target_path(
def _try_get_item_target_path(
path: str, author_name: str, item_type_plural: str, item_name: str
) -> str:
"""
Expand All @@ -464,7 +466,7 @@ def _try_get_vendorized_item_target_path(
:return: the item target path
"""
target_path = os.path.join(path, "vendor", author_name, item_type_plural, item_name)
target_path = os.path.join(path, author_name, item_type_plural, item_name)
if os.path.exists(target_path):
raise click.ClickException(
'Item "{}" already exists in target folder.'.format(item_name)
Expand Down
84 changes: 43 additions & 41 deletions aea/cli/launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@

"""Implementation of the 'aea launch' subcommand."""
import os
import subprocess # nosec
import sys
from collections import OrderedDict
from multiprocessing.context import Process
from pathlib import Path
from subprocess import Popen # nosec
from typing import List

import click
Expand All @@ -37,50 +38,51 @@ def _run_agent(click_context, agent_directory: str):
click_context.invoke(run)


@click.command()
@click.argument("agents", nargs=-1, type=AgentDirectory())
@pass_context
def launch(click_context, agents: List[str]):
"""Launch many agents."""
agents_directories = list(map(Path, list(OrderedDict.fromkeys(agents))))
agent_processes = [
Process(target=_run_agent, args=(click_context, agent_directory))
for agent_directory in agents_directories
]
def _launch_subprocesses(agents: List[Path]):
"""
Launch many agents using subprocesses.
:param agents: list of paths to agent projects.
:return: None
"""
processes = []
failed = 0
for agent_directory in agents:
process = Popen( # nosec
[sys.executable, "-m", "aea.cli", "run"], cwd=str(agent_directory)
)
logger.info("Agent {} started...".format(agent_directory.name))
processes.append(process)

try:
for agent_directory, agent_process in zip(agents_directories, agent_processes):
agent_process.start()
logger.info("Agent {} started...".format(agent_directory.name))
for agent_process in agent_processes:
agent_process.join()
failed |= (
agent_process.exitcode if agent_process.exitcode is not None else 1
)
for process in processes:
process.wait()
except KeyboardInterrupt:
# at this point, the keyboard interrupt has been propagated
# to all the child process, hence we just need to 'join' the processes.
for agent_directory, agent_process in zip(agents_directories, agent_processes):
logger.info("Keyboard interrupt detected.")
finally:
for agent_directory, process in zip(agents, processes):
result = process.poll()
if result is None:
try:
process.wait()
except (subprocess.TimeoutExpired, KeyboardInterrupt):
logger.info("Force shutdown {}...".format(agent_directory.name))
process.kill()

logger.info(
"Waiting for agent {} to shut down...".format(agent_directory.name)
)
agent_process.join(5.0)
if agent_process.is_alive():
logger.info("Killing agent {}...".format(agent_directory.name))
agent_process.kill()
failed = 1
else:
logger.info(
"Agent {} terminated with exit code {}".format(
agent_directory.name, agent_process.exitcode
)
"Agent {} terminated with exit code {}".format(
agent_directory.name, process.returncode
)
failed |= (
agent_process.exitcode if agent_process.exitcode is not None else 1
)
except Exception as e:
logger.exception(e)
sys.exit(1)
)
failed |= process.returncode if process.returncode is not None else -1

sys.exit(failed)

sys.exit(1) if failed else sys.exit(0)

@click.command()
@click.argument("agents", nargs=-1, type=AgentDirectory())
@pass_context
def launch(click_context, agents: List[str]):
"""Launch many agents."""
agents_directories = list(map(Path, list(OrderedDict.fromkeys(agents))))
_launch_subprocesses(agents_directories)
11 changes: 8 additions & 3 deletions aea/cli/publish.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@
from aea.cli.common import (
Context,
DEFAULT_AEA_CONFIG_FILE,
DEFAULT_CONNECTION,
DEFAULT_PROTOCOL,
DEFAULT_SKILL,
_try_get_item_source_path,
_try_get_vendorized_item_target_path,
_try_get_item_target_path,
pass_ctx,
try_to_load_agent_config,
)
Expand All @@ -43,9 +46,9 @@ def publish(ctx: Context, registry):
"""Publish Agent to Registry."""
try_to_load_agent_config(ctx)
if not registry:
# TODO: check agent dependencies are available in local packages dir.
_save_agent_locally(ctx)
else:
# TODO: check agent dependencies are available in local packages dir.
publish_agent(ctx)


Expand All @@ -72,6 +75,8 @@ def _save_agent_locally(ctx: Context) -> None:
for item_type_plural in ("connections", "protocols", "skills"):
dependencies = getattr(ctx.agent_config, item_type_plural)
for public_id in dependencies:
if public_id in [DEFAULT_CONNECTION, DEFAULT_PROTOCOL, DEFAULT_SKILL]:
continue
_check_is_item_in_local_registry(
PublicId.from_str(str(public_id)),
item_type_plural,
Expand All @@ -80,7 +85,7 @@ def _save_agent_locally(ctx: Context) -> None:

item_type_plural = "agents"

target_dir = _try_get_vendorized_item_target_path(
target_dir = _try_get_item_target_path(
ctx.agent_config.registry_path,
ctx.agent_config.author,
item_type_plural,
Expand Down
6 changes: 3 additions & 3 deletions aea/cli/push.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
PublicIdParameter,
_load_yaml,
_try_get_item_source_path,
_try_get_vendorized_item_target_path,
_try_get_item_target_path,
pass_ctx,
try_to_load_agent_config,
)
Expand Down Expand Up @@ -90,9 +90,9 @@ def _save_item_locally(ctx: Context, item_type: str, item_id: PublicId) -> None:
item_type_plural = item_type + "s"

source_path = _try_get_item_source_path(
ctx.cwd, item_id.author, item_type_plural, item_id.name
ctx.cwd, None, item_type_plural, item_id.name
)
target_path = _try_get_vendorized_item_target_path(
target_path = _try_get_item_target_path(
ctx.agent_config.registry_path,
ctx.agent_config.author,
item_type_plural,
Expand Down
Loading

0 comments on commit 4404811

Please sign in to comment.