From 15d2b25efbe982a19ef7a7cf419f6bc894987a8b Mon Sep 17 00:00:00 2001 From: Christian Jensen Date: Mon, 23 Oct 2017 13:59:20 -0700 Subject: [PATCH] Update to get everything working --- agent/agent.py | 4 +- agent/alice_config.yml | 12 ++++ agent/bob_config.yml | 23 ++++++++ agent/demo/document_summarizer/__init__.py | 50 +++++++++++++++-- agent/demo/text_summarizer/__init__.py | 5 +- agent/sn_agent/agent/base.py | 20 +------ agent/sn_agent/agent/settings.py | 2 - agent/sn_agent/agent/test.py | 3 - agent/sn_agent/api/__init__.py | 23 +++++--- agent/sn_agent/api/job.py | 1 + .../sn_agent/examples/document_summarizer.py | 23 -------- agent/sn_agent/job/job_descriptor.py | 28 +++++++--- agent/sn_agent/network/dht.py | 4 +- agent/sn_agent/network/provider.py | 40 ------------- agent/sn_agent/network/settings.py | 4 +- agent/sn_agent/ontology/service_descriptor.py | 2 +- agent/sn_agent/service_adapter/__init__.py | 2 +- agent/sn_agent/service_adapter/base.py | 11 ++-- .../service_adapter/external_adapter.py | 56 +++++++++++++++++++ agent/sn_agent/service_adapter/manager.py | 18 +++++- agent/sn_agent/ui/templates/index.jinja2 | 14 ++++- docker-compose.yml | 10 ++-- 22 files changed, 228 insertions(+), 127 deletions(-) create mode 100644 agent/alice_config.yml create mode 100644 agent/bob_config.yml delete mode 100644 agent/sn_agent/examples/document_summarizer.py delete mode 100644 agent/sn_agent/network/provider.py create mode 100644 agent/sn_agent/service_adapter/external_adapter.py diff --git a/agent/agent.py b/agent/agent.py index 92c7433..574ff4a 100644 --- a/agent/agent.py +++ b/agent/agent.py @@ -6,6 +6,8 @@ import logging +from sn_agent.network import NetworkSettings + logger = logging.getLogger(__name__) app = create_app() @@ -16,7 +18,7 @@ # TODO Make the port configurable from the ENV # web.run_app(app, port=8000, ssl_context=sslcontext) -settings = AgentSettings() +settings = NetworkSettings() logger.info('Host setting: %s', settings.WEB_HOST) diff --git a/agent/alice_config.yml b/agent/alice_config.yml new file mode 100644 index 0000000..5801ce3 --- /dev/null +++ b/agent/alice_config.yml @@ -0,0 +1,12 @@ +--- + +modules: +- module: + ontology_node_id: deadbeef-aaaa-bbbb-cccc-000000000001 + name: demo.document_summarizer.DocumentSummarizer + required_ontology_node_ids: + - deadbeef-aaaa-bbbb-cccc-000000000002 + - deadbeef-aaaa-bbbb-cccc-000000000003 + - deadbeef-aaaa-bbbb-cccc-000000000004 + - deadbeef-aaaa-bbbb-cccc-000000000005 + - deadbeef-aaaa-bbbb-cccc-000000000006 diff --git a/agent/bob_config.yml b/agent/bob_config.yml new file mode 100644 index 0000000..5cf31a5 --- /dev/null +++ b/agent/bob_config.yml @@ -0,0 +1,23 @@ +--- + +modules: + +- module: + ontology_node_id: deadbeef-aaaa-bbbb-cccc-000000000002 + name: demo.word_sense_disambiguater.WordSenseDisambiguater + +- module: + ontology_node_id: deadbeef-aaaa-bbbb-cccc-000000000003 + name: demo.face_recognizer.FaceRecognizer + +- module: + ontology_node_id: deadbeef-aaaa-bbbb-cccc-000000000004 + name: demo.text_summarizer.TextSummarizer + +- module: + ontology_node_id: deadbeef-aaaa-bbbb-cccc-000000000005 + name: demo.video_summarizer.VideoSummarizer + +- module: + ontology_node_id: deadbeef-aaaa-bbbb-cccc-000000000006 + name: demo.entity_extracter.EntityExtracter diff --git a/agent/demo/document_summarizer/__init__.py b/agent/demo/document_summarizer/__init__.py index 4f00aed..9a01fcd 100644 --- a/agent/demo/document_summarizer/__init__.py +++ b/agent/demo/document_summarizer/__init__.py @@ -7,7 +7,7 @@ # from demo.document_summarizer.settings import DocumentSummarizerSettings from sn_agent.job.job_descriptor import JobDescriptor -from sn_agent.service_adapter.base import ModuleServiceAdapterABC +from sn_agent.service_adapter.base import ModuleServiceAdapterABC, ServiceAdapterABC from sn_agent.service_adapter.manager import ServiceManager from sn_agent.ontology.service_descriptor import ServiceDescriptor from sn_agent import ontology @@ -27,7 +27,14 @@ def __init__(self, app, service_ontology_node, required_service_nodes, name: str self.app = app self.settings = DocumentSummarizerSettings() + self.word_sense_disambiguater = None + self.face_recognizer = None + self.text_summarizer = None + self.video_summarizer = None + self.entity_extracter = None + def post_load_initialize(self, service_manager: ServiceManager): + super().post_load_initialize(service_manager) self.word_sense_disambiguater = service_manager.get_service_adapter_for_id(ontology.WORD_SENSE_DISAMBIGUATER_ID) self.face_recognizer = service_manager.get_service_adapter_for_id(ontology.FACE_RECOGNIZER_ID) self.text_summarizer = service_manager.get_service_adapter_for_id(ontology.TEXT_SUMMARIZER_ID) @@ -43,8 +50,8 @@ def transform_output_url(self, tag: str, item_count: int, output_url: str): sub_adapter_url = os.path.join(self.settings.TEST_OUTPUT_DIRECTORY, sub_adapter_output) return sub_adapter_url - def sub_adapter_job(self, tag: str, sub_adapter: ModuleServiceAdapterABC, job: JobDescriptor): - new_service_descriptor = ServiceDescriptor(sub_adapter.service) + def sub_adapter_job(self, tag: str, sub_adapter: ServiceAdapterABC, job: JobDescriptor): + new_service_descriptor = ServiceDescriptor(sub_adapter.service.node_id) new_job = JobDescriptor(new_service_descriptor) item_count = 0 for job_item in job: @@ -91,6 +98,41 @@ def perform(self, job: JobDescriptor): video_job = self.sub_adapter_job('video', self.video_summarizer, job) entity_job = self.sub_adapter_job('entity', self.entity_extracter, job) + self.word_sense_disambiguater.perform(word_job) + self.face_recognizer.perform(face_job) + self.text_summarizer.perform(text_job) + self.video_summarizer.perform(video_job) + self.entity_extracter.perform(entity_job) + + # Now copy the outputs of each of the sub-jobs... + item_count = 0 + for job_item in job: + output_file_name = self.transform_output_url('document', item_count, job_item['output_url']) + + with open(output_file_name, "w") as output_file: + self.copy_adapter_output(output_file, word_job[item_count]['output_url'], 'word') + self.copy_adapter_output(output_file, face_job[item_count]['output_url'], 'face') + self.copy_adapter_output(output_file, text_job[item_count]['output_url'], 'text') + self.copy_adapter_output(output_file, video_job[item_count]['output_url'], 'video') + self.copy_adapter_output(output_file, entity_job[item_count]['output_url'], 'entity') + + item_count += 1 + + def perform_async(self, job: JobDescriptor): + log.debug(" summarizing document") + + # Make sure we have a directory. + directory = self.settings.TEST_OUTPUT_DIRECTORY + if not os.path.exists(directory): + os.mkdir(directory) + + # Create new job descriptors for the sub-services... + word_job = self.sub_adapter_job('word', self.word_sense_disambiguater, job) + face_job = self.sub_adapter_job('face', self.face_recognizer, job) + text_job = self.sub_adapter_job('text', self.text_summarizer, job) + video_job = self.sub_adapter_job('video', self.video_summarizer, job) + entity_job = self.sub_adapter_job('entity', self.entity_extracter, job) + async def disambiguate_words(): self.word_sense_disambiguater.perform(word_job) @@ -116,7 +158,7 @@ async def extract_entities(): asyncio.ensure_future(extract_entities(), loop=loop)] # Wait until the sub-service tasks all complete. - loop.run_until_complete(asyncio.gather(*sub_services)) + results = asyncio.gather(*sub_services) # Now copy the outputs of each of the sub-jobs... item_count = 0 diff --git a/agent/demo/text_summarizer/__init__.py b/agent/demo/text_summarizer/__init__.py index 8d7b01b..fdfdcae 100644 --- a/agent/demo/text_summarizer/__init__.py +++ b/agent/demo/text_summarizer/__init__.py @@ -6,15 +6,14 @@ # Distributed under the MIT software license, see LICENSE file. # -from typing import List +import logging from sn_agent.job.job_descriptor import JobDescriptor from sn_agent.service_adapter.base import ModuleServiceAdapterABC -import logging - log = logging.getLogger(__name__) + class TextSummarizer(ModuleServiceAdapterABC): type_name = "TextSummarizer" diff --git a/agent/sn_agent/agent/base.py b/agent/sn_agent/agent/base.py index 7ab88dd..fe387d5 100644 --- a/agent/sn_agent/agent/base.py +++ b/agent/sn_agent/agent/base.py @@ -7,14 +7,10 @@ # # Distributed under the MIT software license, see LICENSE file. # - -from sn_agent.network.enum import NetworkStatus -from sn_agent.ontology.service_descriptor import ServiceDescriptor -from enum import Enum - import logging from abc import abstractmethod, ABC +from sn_agent.job.job_descriptor import JobDescriptor from sn_agent.ontology.service_descriptor import ServiceDescriptor logger = logging.getLogger(__name__) @@ -34,18 +30,8 @@ def can_perform(self, service: ServiceDescriptor) -> bool: pass @abstractmethod - def perform(self, agent_id, service: ServiceDescriptor): - """ - :param service: the service to perform - """ - pass - - @abstractmethod - def list_providers(self, service: ServiceDescriptor) -> list: + def perform(self, job: JobDescriptor): """ - This is used for creating the tree of subprovider services behind a given service - - :param service: the service for which to list sub-providers. - :return: + :param job: the service to perform """ pass diff --git a/agent/sn_agent/agent/settings.py b/agent/sn_agent/agent/settings.py index d354ff9..c8deb21 100644 --- a/agent/sn_agent/agent/settings.py +++ b/agent/sn_agent/agent/settings.py @@ -8,6 +8,4 @@ def __init__(self, **custom_settings): self._ENV_PREFIX = 'SN_AGENT_' self.CLASS = 'sn_agent.agent.test.TestAgent' self.ID = Required(uuid.UUID) - self.WEB_HOST = "0.0.0.0" - self.WEB_PORT = 8000 super().__init__(**custom_settings) diff --git a/agent/sn_agent/agent/test.py b/agent/sn_agent/agent/test.py index b475fd4..95f23a2 100644 --- a/agent/sn_agent/agent/test.py +++ b/agent/sn_agent/agent/test.py @@ -31,6 +31,3 @@ def can_perform(self, service: ServiceDescriptor) -> bool: def perform(self, service: ServiceDescriptor) -> bool: pass - - def list_providers(self, service: ServiceDescriptor) -> list: - pass diff --git a/agent/sn_agent/api/__init__.py b/agent/sn_agent/api/__init__.py index 800a05b..714353c 100644 --- a/agent/sn_agent/api/__init__.py +++ b/agent/sn_agent/api/__init__.py @@ -1,5 +1,6 @@ import logging import os + from aiohttp import web, WSMsgType from aiohttp.web_response import Response from jsonrpcserver.aio import methods @@ -13,24 +14,32 @@ WS_FILE = os.path.join(os.path.dirname(__file__), 'websocket.html') + @methods.add -async def can_perform(meaning_of_life=None, context=None): +async def can_perform(service_node_id=None, context=None): # figure out what we are being asked to perform and answer - service = ServiceDescriptor(ontology.DOCUMENT_SUMMARIZER_ID) + service = ServiceDescriptor(service_node_id) app = context return await can_perform_service(app, service) @methods.add -async def perform(request, context): - job = JobDescriptor() +async def perform(service_node_id=None, job_params=None, context=None): + service_descriptor = ServiceDescriptor(service_node_id) + + job = JobDescriptor(service_descriptor, job_params) app = context - return await perform_job(app, job) + + result = await perform_job(app, job) + logging.debug('Result of perform was %s', result) + return result async def http_handler(request): - request = await request.text() - response = await methods.dispatch(request) + app = request.app + request_text = await request.text() + + response = await methods.dispatch(request_text, app) if response.is_notification: return web.Response() else: diff --git a/agent/sn_agent/api/job.py b/agent/sn_agent/api/job.py index b003928..23a53a1 100644 --- a/agent/sn_agent/api/job.py +++ b/agent/sn_agent/api/job.py @@ -31,3 +31,4 @@ async def perform_job(app, job_descriptor: JobDescriptor): raise Exception('Service not available') return service_adapter.perform(job_descriptor) + diff --git a/agent/sn_agent/examples/document_summarizer.py b/agent/sn_agent/examples/document_summarizer.py deleted file mode 100644 index 10535f2..0000000 --- a/agent/sn_agent/examples/document_summarizer.py +++ /dev/null @@ -1,23 +0,0 @@ -# -# sn_agent/document_summarizer.py - a toy example document summaraizer. -# -# The examples in the sn_agent/examples are here to illustrate how a complex set -# of agents can interact together to deilver a service through SingulartyNET. -# -# Copyright (c) 2017 SingularityNET -# -# Distributed under the MIT software license, see LICENSE file. -# - -from sn_agent.service_adapter.base import ServiceAdapterABC - -class DocumentSummarizer(ServiceAdapterABC): - type_name = "DocumentSummarizer" - - def __init__(self, app): - super().__init__(app) - self.host = host - self.port = port - - def perform(self, *args, **kwargs): - pass diff --git a/agent/sn_agent/job/job_descriptor.py b/agent/sn_agent/job/job_descriptor.py index 9739ed8..4cfb7f1 100644 --- a/agent/sn_agent/job/job_descriptor.py +++ b/agent/sn_agent/job/job_descriptor.py @@ -13,11 +13,13 @@ class JobDescriptor(object): - def __init__(self, service: ServiceDescriptor, job_parameters: dict = None): + def __init__(self, service: ServiceDescriptor, job_parameters: list = None): self.service = service - self.job_parameters = [] - if not job_parameters is None: - self.job_parameters.append(job_parameters) + + if job_parameters is None: + job_parameters = [] + + self.job_parameters = job_parameters def __eq__(self, other): return self.__dict__ == other.__dict__ @@ -60,15 +62,25 @@ def init_test_jobs(): test_jobs[ontology.VIDEO_SUMMARIZER_ID] = [] test_jobs[ontology.ENTITY_EXTRACTER_ID] = [] - job_parameters = {'input_type': 'file', + job_parameters = [ + { + 'input_type': 'file', 'input_url': 'http://test.com/inputs/test_input.txt', 'output_type': 'file_url_put', - 'output_url': 'test_output.txt'} - job_parameters_2 = {'input_type': 'file', + 'output_url': 'test_output.txt' + } + ] + + job_parameters_2 = [ + { + 'input_type': 'file', 'input_url': 'http://test.com/inputs/test_input_2.txt', 'output_type': 'file_url_put', - 'output_url': 'test_output_2.txt'} + 'output_url': 'test_output_2.txt' + } + ] + #TODO: These need to be fixed so that we can test for single and multiple jobs service_id = ontology.DOCUMENT_SUMMARIZER_ID job = JobDescriptor(ServiceDescriptor(service_id), job_parameters) test_jobs[service_id].append(job) diff --git a/agent/sn_agent/network/dht.py b/agent/sn_agent/network/dht.py index a5fb29f..3a0d552 100644 --- a/agent/sn_agent/network/dht.py +++ b/agent/sn_agent/network/dht.py @@ -44,8 +44,8 @@ def get(self, key): # Deserialize from BSON - another serializer could be used but BSON works well here for d in data_bin: - data = bson.loads(d.data) - data.append(data) + loaded_data = bson.loads(d.data) + data.append(loaded_data) logger.debug('Key Value info: %s', data) return data diff --git a/agent/sn_agent/network/provider.py b/agent/sn_agent/network/provider.py deleted file mode 100644 index 95e2762..0000000 --- a/agent/sn_agent/network/provider.py +++ /dev/null @@ -1,40 +0,0 @@ -# -# sn_agent/provider.py - implementation of wrapper for external service provider agents. -# ExternalServiceProviders use the network to connect with other Agents to have them -# perform service sub-services required for this agent to implement a service. -# -# For example, a machine learning agent that processes large amounts of data might -# use an AWS-centered service provider to store input and output files. So one of -# the services required to perform a service is to obtain input and output URLs -# which can be used for performing this agent's service. The Singnet agent -# will keep a reference to this external provider -# -# Copyright (c) 2017 SingularityNET -# -# Distributed under the MIT software license, see LICENSE file. -# - -from sn_agent.agent.base import AgentABC -from sn_agent.ontology.service_descriptor import ServiceDescriptor - - -class ExternalServiceProvider(AgentABC): - def __init__(self, net, agent_id, service: ServiceDescriptor): - self.net = net - self.agent_id = agent_id - self.service = service - - def can_perform(self, service: ServiceDescriptor) -> bool: - return self.net.ask_agent_if_can_perform(self.agent_id, self.service) - - def perform(self, service: ServiceDescriptor): - return self.net.ask_agent_to_perform(self.agent_id, self.service) - - def list_providers(self, service: ServiceDescriptor) -> list: - """ - External providers do not list their sub-providers by default. - - :param service: - :return: - """ - pass diff --git a/agent/sn_agent/network/settings.py b/agent/sn_agent/network/settings.py index f4808a2..ac39f49 100644 --- a/agent/sn_agent/network/settings.py +++ b/agent/sn_agent/network/settings.py @@ -15,8 +15,10 @@ def __init__(self, **custom_settings): self.BOOT_HOST = 'bootstrap.ring.cx' self.BOOT_PORT = "4222" + self.WEB_HOST = "0.0.0.0" + self.WEB_PORT = 8000 super().__init__(**custom_settings) # Must place after the init so as to pick up the proper gateway value - self.WEB_URL = Url(scheme='http', host=self.GATEWAY, port=8000, path='/api').url + self.WEB_URL = Url(scheme='http', host=self.GATEWAY, port=self.WEB_PORT, path='/api').url diff --git a/agent/sn_agent/ontology/service_descriptor.py b/agent/sn_agent/ontology/service_descriptor.py index 5cd5681..b13d0f6 100644 --- a/agent/sn_agent/ontology/service_descriptor.py +++ b/agent/sn_agent/ontology/service_descriptor.py @@ -38,4 +38,4 @@ def name(self): def __str__(self): name = self.name() - return "".format(self.ontology_node_id, name, id(self)) + return "" % (self.ontology_node_id, name, id(self)) diff --git a/agent/sn_agent/service_adapter/__init__.py b/agent/sn_agent/service_adapter/__init__.py index fd19d83..8f56a31 100644 --- a/agent/sn_agent/service_adapter/__init__.py +++ b/agent/sn_agent/service_adapter/__init__.py @@ -67,6 +67,6 @@ def setup_service_manager(app): else: raise RuntimeError('Unknown service adapter type specified: %s' % section) - service_manager = ServiceManager(service_adapters) + service_manager = ServiceManager(app, service_adapters) service_manager.post_load_initialize() app['service_manager'] = service_manager diff --git a/agent/sn_agent/service_adapter/base.py b/agent/sn_agent/service_adapter/base.py index aded682..56d65e7 100644 --- a/agent/sn_agent/service_adapter/base.py +++ b/agent/sn_agent/service_adapter/base.py @@ -2,8 +2,8 @@ from abc import ABC, abstractmethod from typing import List -from sn_agent.ontology import Ontology, Service from sn_agent.job.job_descriptor import JobDescriptor +from sn_agent.ontology import Service from sn_agent.service_adapter.manager import ServiceManager logger = logging.getLogger(__name__) @@ -16,7 +16,7 @@ class ServiceAdapterABC(ABC): type_name = "Base" - def __init__(self, app, service: Service, required_service_node_ids) -> None: + def __init__(self, app, service: Service, required_service_node_ids=None) -> None: self.app = app self.service = service self.required_service_node_ids = required_service_node_ids @@ -24,7 +24,7 @@ def __init__(self, app, service: Service, required_service_node_ids) -> None: self.requirements_met = False self.available = False - def post_load_initialize(self, service_manager : ServiceManager): + def post_load_initialize(self, service_manager: ServiceManager): """ This will hunt out all the agents required to fulfill the required ontology ids @@ -71,11 +71,11 @@ def can_perform(self) -> bool: An answer of no can be because it is offline, or perhaps it is too busy. :return: """ - return self.requirements_met and self.available and all_required_agents_can_perform() + return self.requirements_met and self.available and self.all_required_agents_can_perform() def all_required_agents_can_perform(self): - if self.required_ontology_node_ids is None: + if self.required_service_node_ids is None: return True for required_service_adapter in self.required_service_adapters: @@ -93,6 +93,7 @@ def perform(self, job: JobDescriptor): """ pass + class ModuleServiceAdapterABC(ServiceAdapterABC): """ This is the service adapter base, all other service adapters are based on it. diff --git a/agent/sn_agent/service_adapter/external_adapter.py b/agent/sn_agent/service_adapter/external_adapter.py new file mode 100644 index 0000000..5b3cb27 --- /dev/null +++ b/agent/sn_agent/service_adapter/external_adapter.py @@ -0,0 +1,56 @@ +# +# sn_agent/provider.py - implementation of wrapper for external service provider agents. +# ExternalServiceProviders use the network to connect with other Agents to have them +# perform service sub-services required for this agent to implement a service. +# +# For example, a machine learning agent that processes large amounts of data might +# use an AWS-centered service provider to store input and output files. So one of +# the services required to perform a service is to obtain input and output URLs +# which can be used for performing this agent's service. The Singnet agent +# will keep a reference to this external provider +# +# Copyright (c) 2017 SingularityNET +# +# Distributed under the MIT software license, see LICENSE file. +# + +import jsonrpcclient + +from sn_agent.job.job_descriptor import JobDescriptor +from sn_agent.ontology import Service +from sn_agent.service_adapter.base import ServiceAdapterABC + + +class ExternalServiceAdapter(ServiceAdapterABC): + def __init__(self, app, agent_id, service: Service): + super().__init__(app, service) + self.app = app + self.agent_id = agent_id + + # go to the DHT and get the URL for the agent + network = self.app['network'] + # This is a hack, we should never really get more than 1 URL per agent + agent_urls = network.dht.get(agent_id) + self.agent_url = agent_urls[0]['url'] + + def has_all_requirements(self): + return True + + def can_perform(self) -> bool: + result = jsonrpcclient.request( + self.agent_url, 'can_perform', + { + "service_node_id": self.service.node_id + } + ) + return result + + def perform(self, job: JobDescriptor): + result = jsonrpcclient.request( + self.agent_url, 'perform', + { + "service_node_id": self.service.node_id, + "job_params": job.job_parameters + } + ) + return result diff --git a/agent/sn_agent/service_adapter/manager.py b/agent/sn_agent/service_adapter/manager.py index 6ec646c..5a8518e 100644 --- a/agent/sn_agent/service_adapter/manager.py +++ b/agent/sn_agent/service_adapter/manager.py @@ -7,10 +7,14 @@ # import logging -log = logging.getLogger(__name__) + + +logger = logging.getLogger(__name__) + class ServiceManager: - def __init__(self, service_adapters): + def __init__(self, app, service_adapters): + self.app = app self.services_by_id = {} self.service_adapters = service_adapters for service_adapter in service_adapters: @@ -19,7 +23,9 @@ def __init__(self, service_adapters): def post_load_initialize(self): for service_adapter in self.service_adapters: + logger.debug("Calling post load initialization for %s", service_adapter) service_adapter.post_load_initialize(self) + service_adapter.start() def start(self, service_node_id): # Find the service adapters for a given service descriptor and enable them @@ -33,4 +39,12 @@ def stop(self, service_node_id): def get_service_adapter_for_id(self, service_node_id): service_adapter = self.services_by_id.get(service_node_id) + if service_adapter is None: + from sn_agent.service_adapter.external_adapter import ExternalServiceAdapter + + # go to the blockchain and get the agent + agent_id = 'c545478a-971a-48ec-bc56-aaaaaaaaaaaa' + service = self.app['ontology'].get_service(service_node_id) + service_adapter = ExternalServiceAdapter(self.app, agent_id, service) + self.services_by_id[service_node_id] = service_adapter return service_adapter diff --git a/agent/sn_agent/ui/templates/index.jinja2 b/agent/sn_agent/ui/templates/index.jinja2 index 908d833..c98f4f9 100644 --- a/agent/sn_agent/ui/templates/index.jinja2 +++ b/agent/sn_agent/ui/templates/index.jinja2 @@ -4,7 +4,8 @@ - + + Back to basics diff --git a/docker-compose.yml b/docker-compose.yml index 687f23b..fbad96c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,22 +7,24 @@ services: build: agent environment: - SN_AGENT_ID=b545478a-971a-48ec-bc56-4b9b7176799c - - SN_AGENT_WEB_PORT=8000 - - SN_SERVICE_ADAPTER_CONFIG_FILE=service_adapter_config_example.yml + - SN_NETWORK_WEB_PORT=8000 + - SN_SERVICE_ADAPTER_CONFIG_FILE=alice_config.yml - PYTHONPATH=/code + - SN_DS_TEST_OUTPUT_DIRECTORY=/data ports: - "8000:8000" volumes: - ./agent-data:/data links: - testrpc +# - bob bob: build: agent environment: - SN_AGENT_ID=c545478a-971a-48ec-bc56-aaaaaaaaaaaa - - SN_AGENT_WEB_PORT=8001 - - SN_SERVICE_ADAPTER_CONFIG_FILE=service_adapter_config_example.yml + - SN_NETWORK_WEB_PORT=8001 + - SN_SERVICE_ADAPTER_CONFIG_FILE=bob_config.yml - PYTHONPATH=/code ports: - "8001:8001"