Menu

EVEFetch

Dave Drouin

This project accesses the EVE API for kill log info. To do so, a simple library module was created that uses the incredibly fast and versatile lxml package. Only new style custom keys are supported.

The available API methods, scopes and masks are defined in a configuration file that's very easy to read and maintain as it's in yaml instead of xml. If you don't want to install the entire pykb package and its depenencies you can just do the following:

Install PyYaml and lxml. Just get the latest versions via pip:

sudo pip install lxml
sudo pip install PyYaml

Grab the code and use it in your project. There's only three small python scripts and a yaml file required. You can put them all in the same directory if you want and it'll work so no need to keep the directory format as used in pykb.

pykb-code/pykb/lib/evefetch.py
pykb-code/pykb/lib/errors.py
pykb-code/pykb/lib/util.py
pykb-code/pykb/lib/evemeta.yml
https://sourceforge.net/p/pykb/code

from lib.evefetch import EVEFetch
from lxml import etree # Just need this for pretty printing later on

# Lets lets try something easy - getting the server status
eve = EVEFetch()
results = eve.server.ServerStatus()
root = results.getroot()
print(etree.tostring(root, pretty_print=True))
<eveapi version="2">
  <currentTime>2012-03-29 20:57:30</currentTime>
  <result>
    <serverOpen>True</serverOpen>
    <onlinePlayers>40837</onlinePlayers>
  </result>
  <cachedUntil>2012-03-29 20:58:13</cachedUntil>
</eveapi>
# You can access the data in a variety of ways, for example via xpath
print root.xpath("/eveapi/result/onlinePlayers")[0].text
40837

# Here we get an attribute value
print root.attrib["version"]
2

# There's also an object oriented interface to let you use the familiar dot
# notation to access data.  Lets try that with an API Key (fake one).
eve.id = 156565
eve.verification_code = "HJASHAKSJHSKAHSk12e91472e87a6xs87yayxashkaghckayc"
eve.objectify_results = True
results = eve.account.APIKeyInfo()

# The call fails of course since the both key id and verification code are bogus
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "lib/evefetch.py", line 49, in call
    elem.attrib["code"], elem.text))
lib.exceptions.APIError: Error code: 203, Description: Authentication failure.
# Lets imagine a valid pair was used and the call succeeded since I won't reveal my API key info publicly naturally.
results = eve.account.APIKeyInfo()
root = results.getroot()
print(etree.tostring(root, pretty_print=True))
<eveapi version="2">
  <currentTime>2012-03-29 21:19:56</currentTime>
  <result>
    <key accessMask="256" type="Corporation" expires="">
      <rowset name="characters" key="characterID" columns="characterID,characterName,corporationID,corporationName">
        <row characterID="283117029" characterName="Khorkrak" corporationID="98091379" corporationName="War Tribe"/>
      </rowset>
    </key>
  </result>
  <cachedUntil>2012-03-29 21:24:56</cachedUntil>
</eveapi>
# Since we told the EVEFetch instance to objectify the results we can now do this:
print root.result.key.rowset.row.attrib["characterName"]
'Khorkrak'

# You can instantiate an EVEFetch instance with the key info as well 
# The parameters are in the same order as they appear on the API keys page.
eve = EVEFetch(156565,
               "HJASHAKSJHSKAHSk12e91472e87a6xs87yayxashkaghckayc",
               "Corporation", 256, True)

# Alternatively using keyword arguments:
eve = EVEFetch(id=156565,
               verification_code="HJASHAKSJHSKAHSk12e91472e87a6xs87yayxashkaghckayc",
               type="Corporation", access_mask=256, objectify_results=True)

# Sanity checks are made to the extent possible prior to reaching out to CCP
results = eve.char.Killlog()

# Fails before hitting the EVE API since the key was declared as being a 
# Corporate key and the call tried to access a char method.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "lib/evefetch.py", line 112, in __call__
    return self.evefetch.call(self.scope, self.method)
  File "lib/evefetch.py", line 52, in call
    self._verify_access(scope, method)
  File "lib/evefetch.py", line 100, in _verify_access
    scope, self.type))
lib.errors.ScopeKeyTypeMismatch: Scope: char, Type: Corporation
# Fixing the above into a valid call...
results = eve.corp.Killlog()

# By the way you can call the api more directly, skipping a few object
# instantiations if desired for speed, by doing this:
results = eve.call("corp", "Killlog")
root = results.getroot()
victim = root.xpath('/eveapi/result/rowset/row[@killID="22968669"]/victim')
print victim[0].attrib["characterName"]
'Khorkrak'
# Or using dot notation since we said to objectify_results during instantiation.
root.result.rowset.row.victim.attrib["characterName"]
'Khorkrak'
# I cheated here in that I knew the first row was the one I wanted.  I don't 
# know if there's a declarative way to find the particular row desired based
# on an attribute value while using dot notation.  So you'll probably have to 
# iterate over the results which will probably be a bit slow.  Using
# ObjectPath would speed that up some.

Refer to the lxml docs for more example and info
http://lxml.de/objectify.html


Related

Wiki: Home

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.