4. Developer Guide¶
4.1. Naming convention¶
To add a web services in BioServices, decide on a name for the python module. By convention we have the module name in lower case. Internally, class uses standard Python convention (Upper case for first letter).
The module name (e.g. uniprot) should be use to name the module (uniprot.py).
It will also be used to add a test or the continuous integration
4.2. Creating a service class (REST case)¶
You can test directly a SOAP/WSDL or REST service in a few lines. For instance, to access to the biomart REST service, type:
>>> s = REST("BioMart" ,"http://www.biomart.org/biomart/martservice")
The first parameter is compulsary but can be any word. You can retrieve the base URL by typing:
>>> s.url 'http://www.biomart.org/biomart/martservice'
and then send a request to retrieve registry information for instance (see www.biomart.org.martservice.html for valid request:
>>> s.http_get("?type=registry") <bioservices.xmltools.easyXML at 0x3b7a4d0>
The request method available from RESTService class concatenates the url and the parameter provided so it request the “http://www.biomart.org.biomart/martservice” URL.
As a developer, you should ease the life of the user by wrapping up the previous commands. An example of a BioMart class with a unique method dedicated to the registry would look like:
>>> class BioMart(REST): ... def __init__(self): ... url = "http://www.biomart.org/biomart/martservice" ... super(BioMart, self).__init__("BioMart", url=url) ... def registry(self): ... ret = self.request("?type=registry") ... return ret
and you would use it as follows:
>>> s = BioMart() >>> s.registry() <bioservices.xmltools.easyXML at 0x3b7a4d0>
4.3. Creating a service class (WSDL case)¶
If a web service interface is not provided within bioservices, you can still
easily access its functionalities. As an example, let us look at the
Ontology Lookup service, which provides a
WSDL service. In order to easily access this service, use the
WSDLService class as follows:
>>> from bioservices import WSDLService >>> ols = WSDLService("OLS", "http://www.ebi.ac.uk/ontology-lookup/OntologyQuery.wsdl")
You can now see which methods are available:
and call one (getVersion) using the
You can then look at something more complex and extract relevant information:
>>> [x.value for x in ols.serv.getOntologyNames()]
Of course, you can add new methods to ease the access to any functionalities:
>>> ols.getOnlogyNames() # returns the values
Similarly to the previous case using REST, you can wrap this example into a proper class.
When wrapper a WSDL services, it may be difficult to know what parameters to provide if the API doc is not clear. This can be known as follows using the suds factory. In this previous examples, we could use:
>>> ols.suds.factory.resolver.find('getTermById') <Element:0xa848b50 name="getTermById" />
For eutils, this was more difficult:
m1 = list(e.suds.wsdl.services.ports.methods.values()) m1.soap.input.body.parts the service is in m1.soap.input.body.parts check for the element in the root attribute
4.5. suds and client auth¶
4.6. How to include tests ?¶
We use pytest. There are many web services included in BioServices. Consequently there are many tests. It is common to have failed tests on Travis and the continuous integration.
Some tests are known to be long or failing from time to time (e.g. service is down).
When a test is known to fail sometimes, we can add this decorator:
On travis we allows 8 failures.
For long tests, we allows 60s at most. You can mark a tests if you knw it will fail on travis (e.g. too long):
Finally, we skip some tests for some conditions:
skiptravis = pytest.mark.skipif( "TRAVIS_PYTHON_VERSION" in os.environ, reason="On travis") @skiptravis def test(): ...
4.7. Continuous integration¶
- add a test in ./test/webservices/test_**yourmodule**.py
2. add a continous integration file named after yourmodule.yml. See example in .github/workflows/template.txt and replace __name__ by your module name