def test_on_cfp(self, local): """ Test that an agent can send a CFP to another agent, with different types of queries. """ with setup_test_agents(2, local, prefix="on_cfp") as agents: for a in agents: a.connect() agent_0, agent_1 = agents # type: AgentTest, AgentTest agent_0.send_cfp(0, 0, agent_1.public_key, 0, None) agent_0.send_cfp(0, 1, agent_1.public_key, 0, b"hello") agent_0.send_cfp(0, 2, agent_1.public_key, 0, Query([Constraint("foo", Eq(0))])) asyncio.ensure_future(agent_1.async_run()) asyncio.get_event_loop().run_until_complete( asyncio.sleep(_ASYNCIO_DELAY)) expected_message_01 = (0, 0, agent_0.public_key, 0, None) expected_message_02 = (0, 1, agent_0.public_key, 0, b"hello") expected_message_03 = (0, 2, agent_0.public_key, 0, Query([Constraint("foo", Eq(0))])) assert 3 == len(agent_1.received_msg) assert expected_message_01 == agent_1.received_msg[0] assert expected_message_02 == agent_1.received_msg[1] assert expected_message_03 == agent_1.received_msg[2]
def test_on_search_result_agents(self, local): """ Test that an agent can do a search for agents. """ with setup_test_agents(3, local, prefix="search_agents") as agents: for a in agents: a.connect() agent_0, agent_1, agent_2 = agents foo_attr = AttributeSchema("foo", int, False, "A foo attribute.") bar_attr = AttributeSchema("bar", str, False, "A bar attribute.") dummy_datamodel = DataModel("dummy_datamodel", [foo_attr, bar_attr]) agent_1.register_agent( 0, Description({ "foo": 15, "bar": "BAR" }, dummy_datamodel)) agent_2.register_agent( 0, Description({ "foo": 5, "bar": "ABC" }, dummy_datamodel)) agent_0.search_agents( 0, Query([Constraint("foo", Eq(0))], dummy_datamodel)) agent_0.search_agents( 0, Query([ Constraint("foo", Gt(10)), Constraint("bar", Gt("B")), ], dummy_datamodel)) agent_0.search_agents( 0, Query([ Constraint("bar", Gt("A")), ], dummy_datamodel)) asyncio.ensure_future(agent_0.async_run()) asyncio.get_event_loop().run_until_complete( asyncio.sleep(_ASYNCIO_DELAY)) agent_1.unregister_agent(0) agent_2.unregister_agent(0) expected_message_01 = (0, []) expected_message_02 = (0, [agent_1.public_key]) expected_message_03 = (0, [agent_1.public_key, agent_2.public_key]) assert 3 == len(agent_0.received_msg) assert expected_message_01 == agent_0.received_msg[0] assert expected_message_02 == agent_0.received_msg[1] assert expected_message_03 == agent_0.received_msg[2]
def add_agent(data): # create and connect the agent print('Add agent: ' + data['name']) agent = TripAgent(data, str(randint(1, 1e9)).replace('0', 'A').replace('1', 'B'), oef_addr="185.91.52.11", oef_port=10000) agent.connect() time.sleep(2) query = Query([Constraint(PRICE_PER_KM.name, Eq(True))], JOURNEY_MODEL) agent.search_services(0, query) time.sleep(1) try: agent.run() time.sleep(3) except Exception as ex: print("EXCEPTION:", ex) finally: try: agent.stop() agent.disconnect() except: pass
def test_query_invalid_when_list_of_constraint_is_empty(self): """Test that we raise an exception when the list of query constraint is empty.""" with pytest.raises( ValueError, match="Invalid input value for type.*empty list of constraints. " "The number of constraints must be at least 1."): a_query = Query([])
def test_unregister_service(self, local): """ Test that the unregistration of services works correctly. """ with setup_test_agents(2, local, prefix="unregister_service") as agents: for a in agents: a.connect() agent_0, agent_1 = agents dummy_datamodel = DataModel("dummy_datamodel", [AttributeSchema("foo", int, False)]) dummy_service_description = Description({}, dummy_datamodel) agent_1.register_service(0, dummy_service_description) agent_1.unregister_service(0, dummy_service_description) agent_0.search_services( 0, Query([Constraint("foo", Eq(0))], dummy_datamodel)) asyncio.ensure_future(agent_0.async_run()) asyncio.get_event_loop().run_until_complete( asyncio.sleep(_ASYNCIO_DELAY)) assert 1 == len(agent_0.received_msg) assert (0, []) == agent_0.received_msg[0]
def search_parking(): #if request.method != 'POST': # return json.dumps({"status":"only POST requests are accepted"}) agent = DriverAgent("DriverAgent", oef_addr="127.0.0.1", oef_port=10000) agent.connect() time.sleep(2) query = Query([Constraint(PARKING_PRICE_PER_1HOUR.name, Eq(True))], PARKING_JOURNEY_MODEL) agent.search_services(0, query) time.sleep(1) try: agent.run() time.sleep(3) except Exception as ex: print("EXCEPTION:", ex) finally: try: agent.stop() agent.disconnect() except: pass return json.dumps({"status": "done"})
def build_query(good_pbks: Set[str], is_searching_for_sellers: bool) -> Query: """ Build buyer or seller search query. Specifically, build the search query - to look for sellers if the agent is a buyer, or - to look for buyers if the agent is a seller. In particular, if the agent is a buyer and the demanded good public keys are {'tac_good_0', 'tac_good_2', 'tac_good_3'}, the resulting constraint expression is: tac_good_0 >= 1 OR tac_good_2 >= 1 OR tac_good_3 >= 1 That is, the OEF will return all the sellers that have at least one of the good in the query (assuming that the sellers are registered with the data model specified). :param good_pbks: the good public keys to put in the query :param is_searching_for_sellers: Boolean indicating whether the query is for sellers (supply) or buyers (demand). :return: the query """ data_model = None if good_pbks is None else build_datamodel( list(good_pbks), is_supply=is_searching_for_sellers) constraints = [Constraint(good_pbk, GtEq(1)) for good_pbk in good_pbks] if len(good_pbks) > 1: constraints = [Or(constraints)] query = Query(constraints, model=data_model) return query
def test_from_pb(self, query: Query): """Test that Query objects are correctly unpacked from the associated protobuf type.""" expected_query = query query_pb = expected_query.to_pb() actual_query = Query.from_pb(query_pb) assert expected_query == actual_query
def test_query_invalid_when_constraint_attribute_name_not_in_data_model( self): """Test that we raise an exception when at least one constraint attribute name is not present in the data model.""" with pytest.raises(ValueError, match=""): a_query = Query([Constraint("an_attribute_name", Eq(0))], DataModel("a_data_model", []))
def test_query_invalid_when_constraint_attribute_name_different_type(self): """Test that we raise an exception when at least one constraint attribute name has a different type wrt the data model.""" with pytest.raises(ValueError, match=""): a_query = Query( [Constraint("an_attribute_name", Eq(0))], DataModel("a_data_model", [AttributeSchema("an_attribute_name", str, True)]))
async def loop(self, agent: AgentInterface) -> None: # noqa: C901 """ Event loop to wait for messages and to dispatch the arrived messages to the proper handler. :param agent: the implementation of the message handlers specified in AgentInterface. :return: ``None`` """ while True: try: data = await self._receive() except asyncio.CancelledError: logger.debug("Proxy {}: loop cancelled".format(self.public_key)) break msg = agent_pb2.Server.AgentMessage() msg.ParseFromString(data) case = msg.WhichOneof("payload") logger.debug("loop {0}".format(case)) if case == "agents": agent.on_search_result(msg.answer_id, msg.agents.agents) elif case == "oef_error": agent.on_oef_error(msg.answer_id, OEFErrorOperation(msg.oef_error.operation)) elif case == "dialogue_error": agent.on_dialogue_error(msg.answer_id, msg.dialogue_error.dialogue_id, msg.dialogue_error.origin) elif case == "content": content_case = msg.content.WhichOneof("payload") logger.debug("msg content {0}".format(content_case)) if content_case == "content": agent.on_message(msg.answer_id, msg.content.dialogue_id, msg.content.origin, msg.content.content) elif content_case == "fipa": fipa = msg.content.fipa fipa_case = fipa.WhichOneof("msg") if fipa_case == "cfp": cfp_case = fipa.cfp.WhichOneof("payload") if cfp_case == "nothing": query = None elif cfp_case == "content": query = fipa.cfp.content elif cfp_case == "query": query = Query.from_pb(fipa.cfp.query) else: raise Exception("Query type not valid.") agent.on_cfp(msg.answer_id, msg.content.dialogue_id, msg.content.origin, fipa.target, query) elif fipa_case == "propose": propose_case = fipa.propose.WhichOneof("payload") if propose_case == "content": proposals = fipa.propose.content else: proposals = [Description.from_pb(propose) for propose in fipa.propose.proposals.objects] agent.on_propose(msg.answer_id, msg.content.dialogue_id, msg.content.origin, fipa.target, proposals) elif fipa_case == "accept": agent.on_accept(msg.answer_id, msg.content.dialogue_id, msg.content.origin, fipa.target) elif fipa_case == "decline": agent.on_decline(msg.answer_id, msg.content.dialogue_id, msg.content.origin, fipa.target) else: logger.warning("Not implemented yet: fipa {0}".format(fipa_case))
def fetch_search(self, terms): # Reject any old proposals and reset for a new set of proposals self.try_respond_n(self.open_proposals, False) self.open_proposals = [] self.save_path = '' self.search = [] search_terms = terms.split(' ') self.search = search_terms query_array = [] for term in search_terms: query_array.append(Constraint(term, NotEq(''))) query = Query(query_array) self.search_services(0, query)
def search_passengers(self): print( "[{0}]: Transport: Searching for Passenger trips {1} with allowed distance {2}..." .format(self.public_key, self.data['location'].latitude, self.distance_allowed_area)) query = Query([ # Constraint(TRIP_DATAMODEL.FROM_LOCATION.name, Eq(self.data['location'])), # Distance(self.data['location'], self.distance_allowed_area)), # Constraint(TRIP_DATAMODEL.TO_LOCATION.name, Eq(self.data['location'])), # Distance(self.data['location'], self.distance_allowed_area)), ]) # query = Query([Constraint(TRIP_DATAMODEL.FROM_LOCATION.name, Distance(self.data['location'], self.distance_allowed_area)), # Constraint(TRIP_DATAMODEL.TO_LOCATION.name, Distance(self.data['location'], self.distance_allowed_area))]) self.search_services(0, query)
def queries(draw): # a proper data model for a valid query is either None or a non-empty Data Model (hence min_size=1) data_model = draw(one_of(none(), data_models(min_size=1))) # if the data model is not None: if data_model: # generate constraints from attributes name attributes = data_model.attribute_schemas else: attributes = None return Query( draw(lists(constraint_expressions(attributes), min_size=1, max_size=3)), data_model)
def search_for_tac(self) -> None: """ Search for active TAC Controller. We assume that the controller is registered as a service with the 'tac' data model and with an attribute version = 1. :return: None """ query = Query([Constraint("version", GtEq(1))]) search_id = self.game_instance.search.get_next_id() self.game_instance.search.ids_for_tac.add(search_id) self.out_box.out_queue.put( OutContainer(query=query, search_id=search_id))
def makeClient(number: int): #check if entity has already been created if (os.path.exists('./workdir/Agent_Auction/client/client' + str(number) + '_private.key')): #locate the agent account entity for interacting with the ledger. with open( './workdir/Agent_Auction/client/client' + str(number) + '_private.key', 'r') as private_key_file: client_agentID = Entity.load(private_key_file) else: #create new entity for the agent client_agentID = Entity() #store private key of newly formed entity with open( './workdir/Agent_Auction/client/client' + str(number) + '_private.key', 'w') as private_key_file: client_agentID.dump(private_key_file) #give the account starting tokens api.sync(api.tokens.wealth(client_agentID, 1000)) startBalance = api.tokens.balance(client_agentID) price = random.randint(25, 100) interval = random.randint(5, 20) # define an OEF Agent client = client_agent.ClientAgent(str(Address(client_agentID)), price, interval, client_agentID, oef_addr="127.0.0.1", oef_port=10000) print('Balance Before:', startBalance) # connect it to the OEF Node client.connect() # query OEF for DataService providers echo_query1 = Query( [Constraint("timezone", Eq(3)), Constraint("twentyfour", Eq(False))], TIME_AGENT()) client.search_services(0, echo_query1) client.run()
def test_group_dialogue_one_client_n_servers(self): with NetworkOEFNode(): client_proxy = OEFNetworkProxy("client", oef_addr="127.0.0.1", port=3333) client = ClientAgentGroupDialogueTest(client_proxy) client.connect() N = 10 server_proxies = [ OEFNetworkProxy("server_{:02d}".format(i), oef_addr="127.0.0.1", port=3333) for i in range(N) ] server_data_model = DataModel("server", [AttributeSchema("foo", bool, True)]) servers = [ ServerAgentTest(server_proxy, price=random.randint(10, 100)) for server_proxy in server_proxies ] for server in servers: server.connect() server.register_service( 0, Description({"foo": True}, server_data_model)) best_server = ServerAgentTest(OEFNetworkProxy("best_server", oef_addr="127.0.0.1", port=3333), price=5) best_server.connect() best_server.register_service( 0, Description({"foo": True}, server_data_model)) servers.append(best_server) asyncio.get_event_loop().run_until_complete( asyncio.sleep(_ASYNCIO_DELAY)) query = Query([Constraint("foo", Eq(True))], server_data_model) client.search_services(0, query) asyncio.get_event_loop().run_until_complete( asyncio.gather(client.async_run(), *[server.async_run() for server in servers])) assert "best_server" == client.group.best_agent assert 5 == client.group.best_price
def on_search_result(self, search_id: int, agents: List[str]): """For every agent returned in the service search, send a CFP to obtain resources from them.""" if len(agents) == 0: print("[{}]: No agent found. Stopping...".format(self.public_key)) self.stop() return print("[{0}]: Agent found: {1}".format(self.public_key, agents)) for agent in agents: print("[{0}]: Sending to agent {1}".format(self.public_key, agent)) # we send a 'None' query, meaning "give me all the resources you can propose." query = Query([Constraint("Date", Range( ("20/3/2019","21/3/2019") ))]) self.pending_cfp += 1 self.send_cfp(1, 0, agent, 0, query)
def makeAgent(preferences): OEF_Address = os.environ.get('OEF_ADDRESS') OEF_Port = os.environ.get('OEF_PORT') Agent_id = "Passenger{}".format(str(random.randint( 0, 9999999999999))).replace("0", "") print(Agent_id, OEF_Address, OEF_Port) client_agent = ClientAgent(str(Agent_id), oef_addr=OEF_Address, oef_port=OEF_Port, preferences=preferences) # connect it to the OEF Node client_agent.connect() # query OEF for DataService providers echo_query = Query([Constraint("timezone", Eq(2))], TIME_AGENT()) client_agent.QUERY = echo_query client_agent.search_services(0, echo_query) return client_agent, Agent_id
def search_agents(self, public_key: str, search_id: int, query: Query) -> None: """ Search the agents in the local Agent Directory, and send back the result. The provided query will be checked with every instance of the Agent Directory. :param public_key: the source of the search request. :param search_id: the search identifier associated with the search request. :param query: the query that constitutes the search. :return: ``None`` """ result = [] for agent_public_key, description in self.agents.items(): if query.check(description): result.append(agent_public_key) self._send_search_result(public_key, search_id, sorted(set(result)))
def search_drivers(self): print( "[{0}]: Transport: Searching for Passenger trips {1} with allowed distance {2}..." .format(self.public_key, self.data['location_latitude'], self.distance_allowed_area)) query = Query([ Constraint( TRIP_DATAMODEL.FROM_LOCATION_LONGITUDE.name, GtEq(self.data['location_longitude'] - self.distance_allowed_area)), Constraint( TRIP_DATAMODEL.FROM_LOCATION_LONGITUDE.name, LtEq(self.data['location_longitude'] + self.distance_allowed_area)), Constraint( TRIP_DATAMODEL.FROM_LOCATION_LATITUDE.name, GtEq(self.data['location_latitude'] - self.distance_allowed_area)), Constraint( TRIP_DATAMODEL.FROM_LOCATION_LATITUDE.name, LtEq(self.data['location_latitude'] + self.distance_allowed_area)) ]) self.search_services(randint(1, 1e9), query)
core.run_threaded() # create and connect the agent agent = WeatherClient("weatherCLient", oef_addr="127.0.0.1", oef_port=10000, core=core) agent.connect() # look for service agents registered as 'weather_station' that: # - provide measurements for temperature # - provide measurements for air pressure # - provide measurements for humidity query = Query([ Constraint(TEMPERATURE_ATTR.name, Eq(True)), Constraint(AIR_PRESSURE_ATTR.name, Eq(True)), Constraint(HUMIDITY_ATTR.name, Eq(True)) ], WEATHER_DATA_MODEL) agent.search_services(0, query) try: agent.run() time.sleep(3) except Exception as ex: print("EXCEPTION:", ex) finally: agent.stop() agent.disconnect() core.stop()
server_agent = GreetingsAgent(server_proxy) # connect the agents to the OEF client_agent.connect() server_agent.connect() # register the greetings service agent on the OEF say_hello = AttributeSchema("say_hello", bool, True, "The agent answers to 'hello' messages.") greetings_model = DataModel("greetings", [say_hello], "Greetings service.") greetings_description = Description({"say_hello": True}, greetings_model) server_agent.register_service(0, greetings_description) # the client executes the search for greetings services # we are looking for services that answers to "hello" messages query = Query([Constraint("say_hello", Eq(True))], greetings_model) print("[{}]: Search for 'greetings' services. search_id={}".format( client_agent.public_key, 0)) client_agent.search_services(0, query) # run the agents try: loop = asyncio.get_event_loop() asyncio.ensure_future(local_node.run()) loop.run_until_complete( asyncio.gather(client_agent.async_run(), server_agent.async_run())) finally: client_agent.stop() server_agent.stop()
else: #create new entity for the agent client_agentID = Entity() #store private key of newly formed entity with open('./workdir/Agent4/client/client_private.key', 'w') as private_key_file: client_agentID.dump(private_key_file) #give the account starting tokens api.sync(api.tokens.wealth(client_agentID, 2000)) startBalance = api.tokens.balance(client_agentID) # define an OEF Agent client_agent = ClientAgent(str(Address(client_agentID)), oef_addr="127.0.0.1", oef_port=10000) print('Balance Before:', startBalance) highest_price = 1700 if highest_price > api.tokens.balance(client_agentID): highest_price = api.tokens.balance(client_agentID) currentPrice = 0 # connect it to the OEF Node client_agent.connect() # query OEF for DataService providers echo_query1 = Query([Constraint("timezone", Eq(3)), Constraint("twentyfour", Eq(False))],TIME_AGENT()) client_agent.search_services(0, echo_query1) client_agent.run()
self.stop() if __name__ == "__main__": # create and connect the agent agent = RiderAgent("RiderAgent", oef_addr="127.0.0.1", oef_port=10000) agent.connect() time.sleep(2) # query = Query([Constraint(PRICE_PER_KM.name, Eq(1))], # JOURNEY_MODEL query = Query([Constraint(PRICE_KWH.name, Lt(56)), Constraint(CHARGER_AVAILABLE.name, Eq(True)), Constraint(CHARGER_BONUS.name, Gt(0)) ]) # query = Query([Constraint(CHARGER_LOCATION.name, Distance(Location(52.2057092, 0.1183431), 100.0))]) agent.search_services(0, query) time.sleep(1) try: agent.run() time.sleep(3) except Exception as ex: print("EXCEPTION:", ex) finally: try: agent.stop()
results = False class Searcher(OEFAgent): def on_search_result(self, search_id: int, agents: List[str]): with open('search_results.json', 'w') as outfile: json.dump(str(agents), outfile) self.stop() return if __name__ == '__main__': search_terms = sys.argv[1].split('_') net = sys.argv[2] oef = 'oef.economicagents.com' if net == 'test' else '127.0.0.1' query_array = [] for term in search_terms: query_array.append(Constraint(term, Eq(True))) query = Query(query_array) agent = Searcher('Searcher', oef_addr = oef, oef_port = 10000) agent.connect() agent.search_services(0, query) try: agent.run() finally: agent.stop() agent.disconnect()
# query OEF for DataService providers echo_query = Query([Constraint("timezone", Eq(2))], TIME_AGENT()) client_agent.QUERY = echo_query client_agent.search_services(0, echo_query) return client_agent, Agent_id # client_agent.run() if __name__ == '__main__': OEF_Address = os.environ.get('OEF_ADDRESS') OEF_Port = os.environ.get('OEF_PORT') # oef.economicagents.com, 3333 # define an OEF Agent Agent_id = base58.b58encode("Passenger{}".format( str(random.randint(0, 9999999999999))).replace("0", "")) print(Agent_id) client_agent = ClientAgent(Agent_id, oef_addr=OEF_Address, oef_port=OEF_Port) # connect it to the OEF Node client_agent.connect() # query OEF for DataService providers echo_query = Query([Constraint("timezone", Eq(2))], TIME_AGENT()) client_agent.search_services(0, echo_query) client_agent.run()
self.stop() if __name__ == '__main__': #define the ledger parameters api = LedgerApi('127.0.0.1', 8100) #locate the client account entity for interacting with the ledger. with open('./workdir/UberX/client_private.key', 'r') as private_key_file: client_agentID = Entity.load(private_key_file) # define an OEF Agent client_agent = ClientAgent(str(Address(client_agentID)), oef_addr="127.0.0.1", oef_port=10000) print('Balance Before:', api.tokens.balance(client_agentID)) # connect it to the OEF Node client_agent.connect() # query OEF for DataService providers (i.e. available drivers in the area) my_current_area = 3 # Ideally we would keep track of this and update accordingly echo_query1 = Query([ Constraint("area", Eq(my_current_area)), Constraint("available", Eq(True)) ], DRIVER_AGENT()) client_agent.search_services(0, echo_query1) client_agent.run()
self.stop() if __name__ == '__main__': # define an OEF Agent client_agent = EchoClientAgent("echo_client", oef_addr="oef-node", oef_port=10000, loop=asyncio.get_event_loop()) # connect it to the OEF Node client_agent.connect() # create a query for the echo data model echo_feature = AttributeSchema("does_echo", bool, True, "Whether the service agent can do echo.") echo_model = DataModel("echo", [echo_feature], "echo service.") echo_query = Query([Constraint("does_echo", Eq(True))], echo_model) print("[{}]: Make search to the OEF".format(client_agent.public_key)) client_agent.search_services(0, echo_query) # wait for events try: client_agent.run() finally: print("[{}]: Disconnecting...".format(client_agent.public_key)) client_agent.stop() client_agent.disconnect()
def test_not_equal_when_compared_with_different_type(self): a_query = Query([Constraint("foo", Eq(0))], DataModel("bar", [AttributeSchema("foo", int, True)])) not_a_query = tuple() assert a_query != not_a_query