[[PageOutline]] **NOTICE** GeniusWebPython is due for release on august 2, 2021 = GeniusWebPython = ''GeniusWeb'' is an open architecture for negotiation via the internet. The core of the architecture is a JSON based communication protocol that standardizes the communication messages comprising a negotiation. This project contains a c-python-3-based implementation of GeniusWeb core objects. It allows easy (de)serialization of many data structures needed for negotiation in GeniusWeb. Some data structures have not yet been implemented in GeniusWebPython, this will be done as needed. Please contact us if you need some missing classes. A specification and full reference implementation of the GeniusWeb core is available [https://tracinsy.ewi.tudelft.nl/pubtrac/GeniusWeb here] = Overview of the available core objects Most classes in the python core are explained in the java reference implementation: ||= class =||= wiki reference =|| ||issuevalue||see [https://tracinsy.ewi.tudelft.nl/pubtrac/GeniusWeb/wiki/WikiStart#issuevalue wiki issuevalue]|| ||inform||see [https://tracinsy.ewi.tudelft.nl/pubtrac/GeniusWeb/wiki/WikiStart#Inform wiki inform]|| ||actions||see [https://tracinsy.ewi.tudelft.nl/pubtrac/GeniusWeb/wiki/WikiStart#Actions wiki actions]|| ||deadline||see [https://tracinsy.ewi.tudelft.nl/pubtrac/GeniusWeb/wiki/WikiStart#Timeline wiki deadline]|| ||progress||see [https://tracinsy.ewi.tudelft.nl/pubtrac/GeniusWeb/wiki/WikiStart#Timeline wiki progress]|| ||connection||see [https://tracinsy.ewi.tudelft.nl/pubtrac/GeniusWeb/wiki/WikiStart#Connection wiki connection]|| = Example Parties Example parties can be found [source:/exampleparties here]. Many of these are also included with the basic [https://tracinsy.ewi.tudelft.nl/pubtrac/GeniusWebPythonPartiesServer parties server] to provide basic functionality. Below is a table showing the currently available example parties and their properties. Notice, "Supported profile types" gives the class names of all supported types, so for instance "PartialOrdering" means all subclasses of PartialOrdering which also includes all UtilitySpaces. ||= Party =||= Protocol =||= Supported profile types =||= Parameters (default value) =|| ||RandomParty||SAOP, Learn||LinearAdditive||minPower (2), maxPower (infinity). Used to control voting behaviour|| ||stupidparty||SAOP||LinearAdditive||-|| == Writing a party Example parties can be found [source:/exampleparties here]. You can easily clone a party with SVN using {{{svn co https://tracinsy.ewi.tudelft.nl/pub/svn/GeniusWebPython/exampleparties/randomparty/}}} (this clones randomparty, use a different name to fetch another example). After cloning, create your venv and install the requirements, eg {{{ python3 -m venv venv source venv/bin/activate pip install -r requirements.txt }}} You can now run the junit tests. You may have to take different or additional steps if you use an IDE like eclipse with pydev, or pycharm. A party is compiled with python. Compile with {{{python3 setup.py sdist}}}. This gives you a you get a {{{dist/yourparty-X.Y.Z.tar.gz}}} that can be copied into the pypartiesserver for deployment. The basic structure of a party that supports the SAOP behaviour looks like this {{{ class RandomParty (DefaultParty): """ Offers random bids until a bid with sufficient utility is offered """ def __init__(self): super().__init__() self.getReporter().log(logging.INFO,"party is initialized") self._profile = None self._lastReceivedBid:Bid = None def notifyChange(self, info: Inform): #self.getReporter().log(logging.INFO,"received info:"+str(info)) if isinstance(info,Settings) : settings:Settings=cast(Settings,info) self._me = settings.getID() self._protocol:str = str(settings.getProtocol().getURI()) self._progress = settings.getProgress() if "Learn" == self._protocol: self.getConnection().send(LearningDone(self._me)) else: self._profile = ProfileConnectionFactory.create(info.getProfile().getURI(), self.getReporter()) elif isinstance(info, ActionDone): action:Action=cast( ActionDone,info).getAction() if isinstance(action, Offer): self._lastReceivedBid = cast(Offer, action).getBid() elif isinstance(info, YourTurn): self._myTurn() if isinstance(self._progress, ProgressRounds) : self._progress = self._progress.advance() elif isinstance(info, Finished): self.terminate() else: self.getReporter().log(logging.WARNING, "Ignoring unknown info "+str(info)) def getCapabilities(self) -> Capabilities: return Capabilities( set([ "SAOP", "Learn"]), set(['geniusweb.profile.utilityspace.LinearAdditive'])) def getDescription(self) -> str: return "Offers random bids until a bid with sufficient utility is offered" def _myTurn(self): if self._lastReceivedBid != None and \ self._profile.getProfile().getUtility(self._lastReceivedBid) > 0.6: action = Accept(self._me, self._lastReceivedBid) else: for _attempt in range(20): bid = self._getRandomBid(self._profile.getProfile().getDomain()) if self._isGood(bid): break action = Offer(self._me, bid); self.getConnection().send(action) def _isGood(self, bid:Bid)->bool: profile = self._profile.getProfile() return profile.getUtility(bid) > 0.6 ... }}} The party must follow the behaviours that it promises. The example above folows the SAOP behaviour. Notice, above is slightly simplified code, for fully working code check the [source:/exampleparties/randomparty/src/main/java/geniusweb/exampleparties/randomparty/RandomParty.java source code]. === Throwing exceptions A special warning is in place regarding throwing exceptions from your implementation, particularly from notifyChange. In line with the general Listener interface, exceptions are only logged and your party usually is immediately disconnected if it throws any exception. Make sure that you free up any used resources to avoid memory leaks if you really need to throw an exception. === Preparing the jar file In order to put your party on the [https://tracinsy.ewi.tudelft.nl/pubtrac/GeniusWebPythonPartiesServer pypartiesserver] for running, you need a tar.gz file of your party. In contrast with java, python tar.gz files do not contain their dependent libraries. References to the dependent libraries are stored in the setup.py program inside the tar.gz file. The pypartiesserver runs a standard {{{pip install }}} to install your party for use. Your tar.gz file must contain a {{{party.py}}} program in the root of the project, defining a function party() that returns your main class, like this: {{{ from randomparty.RandomParty import RandomParty def party(): return RandomParty }}} Of course you should replace RandomParty with your party's main class name but the file name must stay {{{party.py}}}. == GeniusWeb sources === Downloading source code You can browse the GeniusWeb core sources directly using the browse button at the right top of this page. You can download the source code of this component using {{{ svn co https://tracinsy.ewi.tudelft.nl/pub/svn/GeniusWebPython }}} Normal developers that write new parties do not need to install the GeniusWeb source code. Even if you want to debug/trace into the GeniusWeb code -- for instance for debugging or understanding the inner workings of geniusWeb--, IDEs like Eclipse automatically allow this as the pip-installed libraries contain sources.