Skip to content

Commit 68ea55d

Browse files
Merge pull request #1520 from fetchai/develop
Release 0.5.2
2 parents b59aa24 + 59f66e2 commit 68ea55d

333 files changed

Lines changed: 10228 additions & 6784 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

HISTORY.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Release History
22

3+
## 0.5.2 (2020-07-21)
4+
5+
- Transitions demos to agent-land test network, P2P and SOEF connections
6+
- Adds full test coverage for helpers modules
7+
- Adds full test coverage for core modules
8+
- Adds CLI functionality to upload README.md files with packages
9+
- Adds full test coverage for registries module
10+
- Multiple docs updates
11+
- Multiple additional tests and test stability fixes
12+
313
## 0.5.1 (2020-07-14)
414

515
- Adds support for agent name being appended to all log statements

MANIFEST.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
include README.md LICENSE HISTORY.md AUTHORS.md SECURITY.md CODE_OF_CONDUCT.md Pipfile mkdocs.yml tox.ini pytest.ini strategy.ini
22

3-
recursive-include aea *.json *.yaml *.proto
3+
recursive-include aea *.json *.yaml *.proto *.ico *png *.html *.js *.css
44
recursive-include docs *
55
recursive-include examples *
66
recursive-include packages *

Pipfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ openapi-spec-validator = "==0.2.8"
3939
pexpect = "==4.8.0"
4040
psutil = "==5.7.0"
4141
pydocstyle = "==3.0.0"
42-
pydoc-markdown = "==3.1.0"
42+
pydoc-markdown = "==3.3.0"
4343
pygments = "==2.5.2"
4444
pylint = "==2.5.2"
4545
pymdown-extensions = "==6.3"

aea/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
__title__ = "aea"
2323
__description__ = "Autonomous Economic Agent framework"
2424
__url__ = "https://github.com/fetchai/agents-aea.git"
25-
__version__ = "0.5.1"
25+
__version__ = "0.5.2"
2626
__author__ = "Fetch.AI Limited"
2727
__license__ = "Apache-2.0"
2828
__copyright__ = "2019 Fetch.AI Limited"

aea/aea.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def __init__(
7575
default_connection: Optional[PublicId] = None,
7676
default_routing: Optional[Dict[PublicId, PublicId]] = None,
7777
connection_ids: Optional[Collection[PublicId]] = None,
78-
search_service_address: str = "oef",
78+
search_service_address: str = "fetchai/soef:*",
7979
**kwargs,
8080
) -> None:
8181
"""
@@ -164,7 +164,7 @@ def task_manager(self) -> TaskManager:
164164
return self._task_manager
165165

166166
def setup_multiplexer(self) -> None:
167-
"""Set up the multiplexer"""
167+
"""Set up the multiplexer."""
168168
connections = self.resources.get_all_connections()
169169
if self._connection_ids is not None:
170170
connections = [
@@ -245,6 +245,10 @@ def _react_one(self) -> None:
245245
if envelope is not None:
246246
self._handle(envelope)
247247

248+
def _get_error_handler(self) -> Optional[Handler]:
249+
"""Get error hadnler."""
250+
return self.resources.get_handler(DefaultMessage.protocol_id, DEFAULT_SKILL)
251+
248252
def _handle(self, envelope: Envelope) -> None:
249253
"""
250254
Handle an envelope.
@@ -256,9 +260,7 @@ def _handle(self, envelope: Envelope) -> None:
256260
protocol = self.resources.get_protocol(envelope.protocol_id)
257261

258262
# TODO specify error handler in config and make this work for different skill/protocol versions.
259-
error_handler = self.resources.get_handler(
260-
DefaultMessage.protocol_id, DEFAULT_SKILL
261-
)
263+
error_handler = self._get_error_handler()
262264

263265
if error_handler is None:
264266
logger.warning("ErrorHandler not initialized. Stopping AEA!")
@@ -285,6 +287,7 @@ def _handle(self, envelope: Envelope) -> None:
285287
handlers = self.filter.get_active_handlers(
286288
protocol.public_id, envelope.skill_id
287289
)
290+
288291
if len(handlers) == 0:
289292
error_handler.send_unsupported_skill(envelope)
290293
return
@@ -366,7 +369,7 @@ def update(self) -> None:
366369
367370
:return None
368371
"""
369-
self.filter.handle_internal_messages()
372+
self.filter.handle_internal_messages() # pragma: nocover
370373

371374
def teardown(self) -> None:
372375
"""
@@ -388,7 +391,7 @@ def teardown(self) -> None:
388391
ExecTimeoutThreadGuard.stop()
389392

390393
def _setup_loggers(self):
391-
"""Setup logger with agent name. """
394+
"""Set up logger with agent name."""
392395
for element in [
393396
self.main_loop,
394397
self.multiplexer,

aea/aea_builder.py

Lines changed: 32 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
)
6666
from aea.configurations.constants import (
6767
DEFAULT_CONNECTION,
68+
DEFAULT_LEDGER,
6869
DEFAULT_PROTOCOL,
6970
DEFAULT_SKILL,
7071
)
@@ -208,6 +209,7 @@ def remove_component(self, component_id: ComponentId):
208209
component = self._dependencies.pop(component_id)
209210
# remove from the index of all dependencies grouped by type
210211
self._all_dependencies_by_type[component_id.component_type].pop(component_id)
212+
211213
if len(self._all_dependencies_by_type[component_id.component_type]) == 0:
212214
self._all_dependencies_by_type.pop(component_id.component_type)
213215
# remove from prefix to id index
@@ -236,14 +238,6 @@ def pypi_dependencies(self) -> Dependencies:
236238
)
237239
return all_pypi_dependencies
238240

239-
@staticmethod
240-
def _build_dotted_part(component, relative_import_path) -> str:
241-
"""Given a component, build a dotted path for import."""
242-
if relative_import_path == "":
243-
return component.prefix_import_path
244-
else:
245-
return component.prefix_import_path + "." + relative_import_path
246-
247241

248242
class AEABuilder:
249243
"""
@@ -302,7 +296,7 @@ class AEABuilder:
302296
DEFAULT_SKILL_EXCEPTION_POLICY = ExceptionPolicyEnum.propagate
303297
DEFAULT_LOOP_MODE = "async"
304298
DEFAULT_RUNTIME_MODE = "threaded"
305-
DEFAULT_SEARCH_SERVICE_ADDRESS = "oef"
299+
DEFAULT_SEARCH_SERVICE_ADDRESS = "fetchai/soef:*"
306300

307301
# pylint: disable=attribute-defined-outside-init
308302

@@ -352,10 +346,7 @@ def _reset(self, is_full_reset: bool = False) -> None:
352346
self._build_called: bool = False
353347
if not is_full_reset:
354348
return
355-
self._ledger_apis_configs = {} # type: Dict[str, Dict[str, Union[str, int]]]
356-
self._default_ledger = (
357-
"fetchai" # set by the user, or instantiate a default one.
358-
)
349+
self._default_ledger = DEFAULT_LEDGER
359350
self._default_connection: PublicId = DEFAULT_CONNECTION
360351
self._context_namespace = {} # type: Dict[str, Any]
361352
self._timeout: Optional[float] = None
@@ -430,7 +421,7 @@ def set_decision_maker_handler(
430421
try:
431422
_class = getattr(module, class_name)
432423
self._decision_maker_handler_class = _class
433-
except Exception as e:
424+
except Exception as e: # pragma: nocover
434425
logger.error(
435426
"Could not locate decision maker handler for dotted path '{}', class name '{}' and file path '{}'. Error message: {}".format(
436427
dotted_path, class_name, file_path, e
@@ -442,7 +433,7 @@ def set_decision_maker_handler(
442433

443434
def set_skill_exception_policy(
444435
self, skill_exception_policy: Optional[ExceptionPolicyEnum]
445-
) -> "AEABuilder":
436+
) -> "AEABuilder": # pragma: nocover
446437
"""
447438
Set skill exception policy.
448439
@@ -465,10 +456,12 @@ def set_default_routing(
465456
466457
:return: self
467458
"""
468-
self._default_routing = default_routing
459+
self._default_routing = default_routing # pragma: nocover
469460
return self
470461

471-
def set_loop_mode(self, loop_mode: Optional[str]) -> "AEABuilder":
462+
def set_loop_mode(
463+
self, loop_mode: Optional[str]
464+
) -> "AEABuilder": # pragma: nocover
472465
"""
473466
Set the loop mode.
474467
@@ -478,7 +471,9 @@ def set_loop_mode(self, loop_mode: Optional[str]) -> "AEABuilder":
478471
self._loop_mode = loop_mode
479472
return self
480473

481-
def set_runtime_mode(self, runtime_mode: Optional[str]) -> "AEABuilder":
474+
def set_runtime_mode(
475+
self, runtime_mode: Optional[str]
476+
) -> "AEABuilder": # pragma: nocover
482477
"""
483478
Set the runtime mode.
484479
@@ -488,7 +483,9 @@ def set_runtime_mode(self, runtime_mode: Optional[str]) -> "AEABuilder":
488483
self._runtime_mode = runtime_mode
489484
return self
490485

491-
def set_search_service_address(self, search_service_address: str) -> "AEABuilder":
486+
def set_search_service_address(
487+
self, search_service_address: str
488+
) -> "AEABuilder": # pragma: nocover
492489
"""
493490
Set the search service address.
494491
@@ -533,7 +530,7 @@ def _check_can_add(self, configuration: ComponentConfiguration) -> None:
533530
self._check_package_dependencies(configuration)
534531
self._check_pypi_dependencies(configuration)
535532

536-
def set_name(self, name: str) -> "AEABuilder":
533+
def set_name(self, name: str) -> "AEABuilder": # pragma: nocover
537534
"""
538535
Set the name of the agent.
539536
@@ -543,7 +540,9 @@ def set_name(self, name: str) -> "AEABuilder":
543540
self._name = name
544541
return self
545542

546-
def set_default_connection(self, public_id: PublicId) -> "AEABuilder":
543+
def set_default_connection(
544+
self, public_id: PublicId
545+
) -> "AEABuilder": # pragma: nocover
547546
"""
548547
Set the default connection.
549548
@@ -606,33 +605,7 @@ def connection_private_key_paths(self) -> Dict[str, Optional[str]]:
606605
"""Get the connection private key paths."""
607606
return self._connection_private_key_paths
608607

609-
def add_ledger_api_config(self, identifier: str, config: Dict) -> "AEABuilder":
610-
"""
611-
Add a configuration for a ledger API to be supported by the agent.
612-
613-
:param identifier: the identifier of the ledger api
614-
:param config: the configuration of the ledger api
615-
:return: the AEABuilder
616-
"""
617-
self._ledger_apis_configs[identifier] = config
618-
return self
619-
620-
def remove_ledger_api_config(self, identifier: str) -> "AEABuilder":
621-
"""
622-
Remove a ledger API configuration.
623-
624-
:param identifier: the identifier of the ledger api
625-
:return: the AEABuilder
626-
"""
627-
self._ledger_apis_configs.pop(identifier, None)
628-
return self
629-
630-
@property
631-
def ledger_apis_config(self) -> Dict[str, Dict[str, Union[str, int]]]:
632-
"""Get the ledger api configurations."""
633-
return self._ledger_apis_configs
634-
635-
def set_default_ledger(self, identifier: str) -> "AEABuilder":
608+
def set_default_ledger(self, identifier: str) -> "AEABuilder": # pragma: nocover
636609
"""
637610
Set a default ledger API to use.
638611
@@ -689,7 +662,9 @@ def add_component_instance(self, component: Component) -> "AEABuilder":
689662
] = component
690663
return self
691664

692-
def set_context_namespace(self, context_namespace: Dict[str, Any]) -> "AEABuilder":
665+
def set_context_namespace(
666+
self, context_namespace: Dict[str, Any]
667+
) -> "AEABuilder": # pragma: nocover
693668
"""Set the context namespace."""
694669
self._context_namespace = context_namespace
695670
return self
@@ -1123,13 +1098,13 @@ def _try_to_load_agent_configuration_file(aea_project_path: Path) -> None:
11231098
loader = ConfigLoader.from_configuration_type(PackageType.AGENT)
11241099
agent_configuration = loader.load(fp)
11251100
logging.config.dictConfig(agent_configuration.logging_config) # type: ignore
1126-
except FileNotFoundError:
1101+
except FileNotFoundError: # pragma: nocover
11271102
raise Exception(
11281103
"Agent configuration file '{}' not found in the current directory.".format(
11291104
DEFAULT_AEA_CONFIG_FILE
11301105
)
11311106
)
1132-
except jsonschema.exceptions.ValidationError:
1107+
except jsonschema.exceptions.ValidationError: # pragma: nocover
11331108
raise Exception(
11341109
"Agent configuration file '{}' is invalid. Please check the documentation.".format(
11351110
DEFAULT_AEA_CONFIG_FILE
@@ -1198,13 +1173,6 @@ def set_from_configuration(
11981173
ledger_identifier, private_key_path, is_connection=True
11991174
)
12001175

1201-
# load ledger API configurations
1202-
for (
1203-
ledger_identifier,
1204-
ledger_api_conf,
1205-
) in agent_configuration.ledger_apis_dict.items():
1206-
self.add_ledger_api_config(ledger_identifier, ledger_api_conf)
1207-
12081176
component_ids = itertools.chain(
12091177
[
12101178
ComponentId(ComponentType.PROTOCOL, p_id)
@@ -1284,6 +1252,7 @@ def _find_import_order(
12841252

12851253
if len(configuration.skills) != 0:
12861254
roots.remove(skill_id)
1255+
12871256
depends_on[skill_id].update(
12881257
[
12891258
ComponentId(ComponentType.SKILL, skill)
@@ -1300,7 +1269,9 @@ def _find_import_order(
13001269
while len(queue) > 0:
13011270
current = queue.pop()
13021271
order.append(current)
1303-
for node in supports[current]:
1272+
for node in supports[
1273+
current
1274+
]: # pragma: nocover # TODO: extract method and test properly
13041275
depends_on[node].discard(current)
13051276
if len(depends_on[node]) == 0:
13061277
queue.append(node)
@@ -1405,7 +1376,7 @@ def _populate_contract_registry(self):
14051376
class_kwargs={"contract_interface": contract_interface},
14061377
contract_config=configuration, # TODO: resolve configuration being applied globally
14071378
)
1408-
except AEAException as e:
1379+
except AEAException as e: # pragma: nocover
14091380
if "Cannot re-register id:" in str(e):
14101381
logger.warning(
14111382
"Already registered: {}".format(configuration.class_name)
@@ -1452,7 +1423,7 @@ def _verify_or_create_private_keys(aea_project_path: Path) -> None:
14521423

14531424
for identifier, _value in agent_configuration.private_key_paths.read_all():
14541425
if identifier not in crypto_registry.supported_ids:
1455-
ValueError("Unsupported identifier in private key paths.")
1426+
raise ValueError(f"Item not registered with id '{identifier}'.")
14561427

14571428
for identifier, private_key_path in IDENTIFIER_TO_KEY_FILES.items():
14581429
config_private_key_path = agent_configuration.private_key_paths.read(identifier)

aea/agent_loop.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ async def _gather_tasks(self) -> None:
9696
await asyncio.gather(*self._tasks, loop=self._loop)
9797

9898
@abstractmethod
99-
def _set_tasks(self) -> None:
99+
def _set_tasks(self) -> None: # pragma: nocover
100100
"""Set run loop tasks."""
101101
raise NotImplementedError
102102

@@ -219,7 +219,7 @@ def _unregister_behaviour(self, behaviour: Behaviour) -> None:
219219
:return: None
220220
"""
221221
periodic_caller = self._behaviours_registry.pop(behaviour, None)
222-
if periodic_caller is None:
222+
if periodic_caller is None: # pragma: nocover
223223
return
224224
periodic_caller.stop()
225225

@@ -260,13 +260,9 @@ def _create_tasks(self) -> List[Task]:
260260
async def _task_process_inbox(self) -> None:
261261
"""Process incoming messages."""
262262
inbox: InBox = self._agent.inbox
263-
self.logger.info("[{}]: Start processing messages...".format(self._agent.name))
263+
self.logger.info("Start processing messages...")
264264
while self.is_running:
265265
await inbox.async_wait()
266-
267-
if not self.is_running: # make it close faster
268-
return
269-
270266
self._agent.react()
271267

272268
async def _task_process_internal_messages(self) -> None:

0 commit comments

Comments
 (0)