Browse Source

Merge branch 'dev', v0.5.2

Adding the test suite has been holding the release too long

bfc41e5 - bump to v0.5.2
24ac0da - added http_timeout parameter
816c5f7 - remove doc() call when building docstrings
7f57b8e - param name being shortened on non-array parms
5b79abd - rm py3.2 in travis; dropped support in coverage
b07f059 - fix #4; method failing when format=vdf
ba30094 - reorginized the code in webapi
1063165 - setup vcr cassette for webapi test suite
2d24284 - add test suite for SteamID + enabled travis/cover
pull/6/head
Rossen Georgiev 10 years ago
parent
commit
1d50e7278b
  1. 12
      .travis.yml
  2. 2
      Makefile
  3. 11
      README.rst
  4. 6
      requirements.txt
  5. 2
      steam/__init__.py
  6. 81
      steam/steamid.py
  7. 193
      steam/webapi.py
  8. 0
      tests/__init__.py
  9. 245
      tests/test_steamid.py
  10. 14
      tests/test_webapi.py
  11. 49
      vcr/webapi_getserverinfo.json
  12. 49
      vcr/webapi_init.json
  13. 49
      vcr/webapi_resolovevanityurl.json

12
.travis.yml

@ -0,0 +1,12 @@
language: python
python:
- "2.7"
- "3.3"
- "3.4"
install:
- make init
- pip install coveralls
script:
- make test
after_success:
- coveralls

2
Makefile

@ -18,7 +18,7 @@ init:
test: test:
rm -f .coverage steam/*.pyc tests/*.pyc rm -f .coverage steam/*.pyc tests/*.pyc
PYTHONHASHSEED=0 nosetests --verbosity 2 --with-coverage --cover-package=steam PYTHONHASHSEED=0 nosetests --verbosity 1 --with-coverage --cover-package=steam
pylint: pylint:
pylint -r n -f colorized steam || true pylint -r n -f colorized steam || true

11
README.rst

@ -1,4 +1,4 @@
|pypi| |license| |pypi| |license| |coverage| |master_build|
Module for interacting with various Steam_ features Module for interacting with various Steam_ features
@ -104,7 +104,6 @@ SteamID
'https://steamcommunity.com/gid/103582791429521412' 'https://steamcommunity.com/gid/103582791429521412'
.. _Steam: https://store.steampowered.com/ .. _Steam: https://store.steampowered.com/
.. _Steam Web API: https://developer.valvesoftware.com/wiki/Steam_Web_API .. _Steam Web API: https://developer.valvesoftware.com/wiki/Steam_Web_API
.. _API Key: http://steamcommunity.com/dev/apikey .. _API Key: http://steamcommunity.com/dev/apikey
@ -117,3 +116,11 @@ SteamID
.. |license| image:: https://img.shields.io/pypi/l/steam.svg?style=flat&label=license .. |license| image:: https://img.shields.io/pypi/l/steam.svg?style=flat&label=license
:target: https://pypi.python.org/pypi/steam :target: https://pypi.python.org/pypi/steam
:alt: MIT License :alt: MIT License
.. |coverage| image:: https://img.shields.io/coveralls/ValvePython/steam/master.svg?style=flat
:target: https://coveralls.io/r/ValvePython/steam?branch=master
:alt: Test coverage
.. |master_build| image:: https://img.shields.io/travis/ValvePython/steam/master.svg?style=flat&label=master
:target: http://travis-ci.org/ValvePython/steam
:alt: Build status of master branch

6
requirements.txt

@ -0,0 +1,6 @@
nose
coverage
mock
requests
enum34
vcrpy

2
steam/__init__.py

@ -1,4 +1,4 @@
__version__ = "0.5.1" __version__ = "0.5.2"
__author__ = "Rossen Georgiev" __author__ = "Rossen Georgiev"
from steam.steamid import SteamID from steam.steamid import SteamID

81
steam/steamid.py

@ -1,6 +1,6 @@
import re import re
import requests import requests
from .enums import EType, EUniverse from steam.enums import EType, EUniverse
class SteamID(object): class SteamID(object):
@ -44,12 +44,11 @@ class SteamID(object):
""" """
largs = len(args) largs = len(args)
lkwargs = len(kwargs)
if largs == 0 and lkwargs == 0: if largs == 0 and len(kwargs) == 0:
self.id = 0 self.id = 0
self.type = EType.Invalid self.type = EType.Invalid
self.universe = EType.Invalid self.universe = EUniverse.Invalid
self.instance = 0 self.instance = 0
elif largs > 0: elif largs > 0:
if largs > 1: if largs > 1:
@ -71,15 +70,15 @@ class SteamID(object):
value = match.group('value') value = match.group('value')
# numeric input # numeric input
if value.isdigit(): if value.isdigit() or (value.startswith('-') and value[1:].isdigit()):
value = int(value) value = int(value)
if 0 > value: if 0 > value:
raise ValueError("Expected positive int, got %d" % value) raise ValueError("Expected positive int, got %d" % value)
if value > 2**64-1: if value >= 2**64:
raise ValueError("Expected a 32/64 bit int") raise ValueError("Expected a 32/64 bit int")
# 32 bit account id # 32 bit account id
if value < 2**32-1: if value < 2**32:
self.id = value self.id = value
self.type = EType.Individual self.type = EType.Individual
self.universe = EUniverse.Public self.universe = EUniverse.Public
@ -94,14 +93,14 @@ class SteamID(object):
# textual input e.g. [g:1:4] # textual input e.g. [g:1:4]
else: else:
# try steam2 # try steam2
match = re.match(r"^STEAM_(?P<universe>\d+)" match = re.match(r"^STEAM_(?P<universe>[01])"
r":(?P<reminder>[0-1])" r":(?P<reminder>[0-1])"
r":(?P<id>\d+)$", value r":(?P<id>\d+)$", value
) )
if match: if match:
self.id = (int(match.group('id')) << 1) | int(match.group('reminder')) self.id = (int(match.group('id')) << 1) | int(match.group('reminder'))
self.universe = EUniverse(int(match.group('universe'))) self.universe = EUniverse(1)
self.type = EType(1) self.type = EType(1)
self.instance = 1 self.instance = 1
return return
@ -134,35 +133,36 @@ class SteamID(object):
" (e.g. [g:1:4], STEAM_0:1:1234), got %s" % repr(value) " (e.g. [g:1:4], STEAM_0:1:1234), got %s" % repr(value)
) )
elif lkwargs > 0: elif len(kwargs):
if 'id' not in kwargs: if 'id' not in kwargs:
raise ValueError("Expected at least 'id' kwarg") raise ValueError("Expected at least 'id' kwarg")
self.id = int(kwargs['id']) self.id = int(kwargs['id'])
assert self.id <= 0xffffFFFF, "id larger than 32bits"
value = kwargs.get('type', 0)
if type(value) in (int, EType):
self.type = EType(value)
else:
self.type = EType[value.lower().capitalize()]
for kwname in 'type', 'universe': value = kwargs.get('universe', 0)
if kwname in kwargs: if type(value) in (int, EUniverse):
value = kwargs[kwname] self.universe = EUniverse(value)
kwenum = getattr(self, "E%s" % kwname.capitalize())
resolved = getattr(kwenum, value, None)
if resolved is None:
try:
resolved = kwenum(value)
except ValueError:
raise ValueError(
"Invalid value for kwarg '%s', see SteamID.E%s" %
(kwname, kwname.capitalize())
)
setattr(self, kwname, resolved)
if self.type in (EType.Individual, EType.GameServer):
self.instance = 1
else: else:
self.instance = 0 self.universe = EUniverse[value.lower().capitalize()]
if 'instance' in kwargs:
self.instance = kwargs['instance']
assert self.instance <= 0xffffF, "instance larger than 20bits"
else:
if self.type in (EType.Individual, EType.GameServer):
self.instance = 1
else:
self.instance = 0
def __repr__(self): def __repr__(self):
return "%s(id=%s, type=%s, universe=%s, instance=%s)" % ( return "<%s(id=%s, type=%s, universe=%s, instance=%s)>" % (
self.__class__.__name__, self.__class__.__name__,
self.id, self.id,
repr(self.type.name), repr(self.type.name),
@ -175,19 +175,26 @@ class SteamID(object):
@property @property
def as_steam2(self): def as_steam2(self):
return "STEAM_%s:%s:%s" % ( return "STEAM_0:%s:%s" % (
self.universe.value,
self.id % 2, self.id % 2,
self.id >> 1, self.id >> 1,
) )
@property @property
def as_steam3(self): def as_steam3(self):
return "[%s:%s:%s]" % ( if self.type is EType.AnonGameServer:
self.ETypeChar[self.type.value], return "[%s:%s:%s:%s]" % (
self.universe.value, self.ETypeChar[self.type.value],
self.id, self.universe.value,
) self.id,
self.instance
)
else:
return "[%s:%s:%s]" % (
self.ETypeChar[self.type.value],
self.universe.value,
self.id,
)
@property @property
def as_64(self): def as_64(self):

193
steam/webapi.py

@ -1,6 +1,63 @@
from __future__ import print_function from __future__ import print_function
import requests import requests
DEFAULT_PARAMS = {
# api parameters
'key': None,
'format': 'json',
# internal
'https': True,
'http_timeout': 30,
'raw': False,
}
def webapi_request(path, method='GET', caller=None, params={}):
"""
Low level function for calling Steam's WebAPI
"""
if method not in ('GET', 'POST'):
raise NotImplemented("HTTP method: %s" % repr(self.method))
onetime = {}
for param in DEFAULT_PARAMS:
params[param] = onetime[param] = params.get(param,
DEFAULT_PARAMS[param],
)
path = "%s://api.steampowered.com/%s" % ('https' if params.get('https', True) else 'http',
path)
del params['raw']
del params['https']
del params['http_timeout']
if onetime['format'] not in ('json', 'vdf', 'xml'):
raise ValueError("Expected format to be json,vdf or xml; got %s" % onetime['format'])
# move params to data, if data is not specified for POST
# simplifies code calling this method
kwargs = {'params': params} if method == "GET" else {'data': params}
f = getattr(requests, method.lower())
resp = f(path, stream=True, timeout=onetime['http_timeout'], **kwargs)
if caller is not None:
caller.last_response = resp
if not resp.ok:
raise requests.exceptions.HTTPError("%s %s" % (resp.status_code, resp.reason))
if onetime['raw']:
return resp.content
if onetime['format'] == 'json':
return resp.json()
elif onetime['format'] == 'xml':
import lxml.etree
return lxml.etree.parse(resp.raw)
elif onetime['format'] == 'vdf':
import vdf
return vdf.loads(resp.text)
class WebAPI(object): class WebAPI(object):
""" """
@ -12,13 +69,15 @@ class WebAPI(object):
More: https://developer.valvesoftware.com/wiki/Steam_Web_API More: https://developer.valvesoftware.com/wiki/Steam_Web_API
""" """
def __init__(self, key, format='json', raw=False, https=True): def __init__(self, key, format='json', raw=False, https=True, http_timeout=30, auto_load_interfaces=True):
""" """
Optain apikey at https://steamcommunity.com/dev/apikey Optain apikey at https://steamcommunity.com/dev/apikey
key - apikey key - apikey
format - output format (json, vdf, xml) format - output format (json, vdf, xml)
raw - whenver to deserialize the response raw - whenver to deserialize the response
https - whenever to use https or not
auto_load_interfaces - should we load interfaces upon initialization
These can be specified per method call for one off calls These can be specified per method call for one off calls
""" """
@ -27,8 +86,11 @@ class WebAPI(object):
self.format = format self.format = format
self.raw = raw self.raw = raw
self.https = https self.https = https
self.http_timeout = http_timeout
self.interfaces = [] self.interfaces = []
self.load_interfaces()
if auto_load_interfaces:
self.load_interfaces(self.fetch_interfaces())
def __repr__(self): def __repr__(self):
return "%s(key=%s, https=%s)" % ( return "%s(key=%s, https=%s)" % (
@ -37,22 +99,30 @@ class WebAPI(object):
repr(self.https), repr(self.https),
) )
def load_interfaces(self): def fetch_interfaces(self):
""" """
Fetches the available interfaces from the API itself and then Returns a dict with the response from GetSupportedAPIList
populates the name space under the instance
This is then feeded into WebAPI.load_interfaces(reponse)
The reponse could be cached/save and used to load interfaces
""" """
result = self._api_request( return webapi_request(
None,
"GET",
"ISteamWebAPIUtil/GetSupportedAPIList/v1/", "ISteamWebAPIUtil/GetSupportedAPIList/v1/",
params={'format': 'json'}, method="GET",
caller=None,
params={'format': 'json',
'key': self.key,
},
) )
if result.get('apilist', {}).get('interfaces', None) is None: def load_interfaces(self, interfaces_dict):
"""
Populates the namespace under the instance
"""
if interfaces_dict.get('apilist', {}).get('interfaces', None) is None:
raise ValueError("Invalid response for GetSupportedAPIList") raise ValueError("Invalid response for GetSupportedAPIList")
interfaces = result['apilist']['interfaces'] interfaces = interfaces_dict['apilist']['interfaces']
if len(interfaces) == 0: if len(interfaces) == 0:
raise ValueError("API returned not interfaces; probably using invalid key") raise ValueError("API returned not interfaces; probably using invalid key")
@ -77,52 +147,6 @@ class WebAPI(object):
interface, method = method_path.split('.', 1) interface, method = method_path.split('.', 1)
return getattr(getattr(self, interface), method)(**kwargs) return getattr(getattr(self, interface), method)(**kwargs)
@property
def _url_base(self):
return "%s://api.steampowered.com/" % ('https' if self.https else 'http')
def _api_request(self, caller, method, path, **kwargs):
if method not in ('GET', 'POST'):
raise NotImplemented("HTTP method: %s" % repr(self.method))
if 'params' not in kwargs:
kwargs['params'] = {}
onetime = {}
for param in ('key', 'format', 'raw'):
kwargs['params'][param] = onetime[param] = kwargs['params'].get(param,
getattr(self, param)
)
del kwargs['params']['raw']
if onetime['format'] not in ('json', 'vdf', 'xml'):
raise ValueError("Expected format to be json,vdf or xml; got %s" % onetime['format'])
# move params to data, if data is not specified for POST
# simplifies code calling this method
if method == 'POST' and 'data' not in kwargs:
kwargs['data'] = kwargs['params']
del kwargs['params']
f = getattr(requests, method.lower())
resp = f(self._url_base + path, stream=True, **kwargs)
if caller is not None:
caller.last_response = resp
if not resp.ok:
raise requests.exceptions.HTTPError("%s %s" % (resp.status_code, resp.reason))
if onetime['raw']:
return resp.content
if onetime['format'] == 'json':
return resp.json()
elif onetime['format'] == 'xml':
import lxml.etree
return lxml.etree.parse(resp.raw)
elif onetime['format'] == 'vdf':
import vdf
return vdf.load(resp.raw)
def doc(self): def doc(self):
print(self.__doc__) print(self.__doc__)
@ -131,7 +155,7 @@ class WebAPI(object):
def __doc__(self): def __doc__(self):
doc = "Steam Web API - List of all interfaces\n\n" doc = "Steam Web API - List of all interfaces\n\n"
for interface in self.interfaces: for interface in self.interfaces:
doc += interface.doc() doc += interface.__doc__
return doc return doc
@ -140,7 +164,7 @@ class WebAPIInterface(object):
Steam Web API Interface Steam Web API Interface
""" """
def __init__(self, interface_dict, parent=None): def __init__(self, interface_dict, parent):
self._parent = parent self._parent = parent
self.name = interface_dict['name'] self.name = interface_dict['name']
self.methods = [] self.methods = []
@ -167,10 +191,26 @@ class WebAPIInterface(object):
def __iter__(self): def __iter__(self):
return iter(self.methods) return iter(self.methods)
@property
def key(self):
return self._parent.key
@property @property
def https(self): def https(self):
return self._parent.https return self._parent.https
@property
def http_timeout(self):
return self._parent.http_timeout
@property
def format(self):
return self._parent.format
@property
def raw(self):
return self._parent.raw
def doc(self): def doc(self):
print(self.__doc__) print(self.__doc__)
@ -178,7 +218,7 @@ class WebAPIInterface(object):
def __doc__(self): def __doc__(self):
doc = "%s\n%s\n" % (self.name, '-'*len(self.name)) doc = "%s\n%s\n" % (self.name, '-'*len(self.name))
for method in self.methods: for method in self.methods:
doc += " %s\n" % method.doc().replace("\n", "\n ") doc += " %s\n" % method.__doc__.replace("\n", "\n ")
return doc return doc
@ -187,7 +227,7 @@ class WebAPIMethod(object):
Steam Web API Interface Method Steam Web API Interface Method
""" """
def __init__(self, method_dict, parent=None): def __init__(self, method_dict, parent):
self.last_response = None self.last_response = None
self._parent = parent self._parent = parent
self._dict = method_dict self._dict = method_dict
@ -197,8 +237,9 @@ class WebAPIMethod(object):
for param in params: for param in params:
# add property indicating param can be a list # add property indicating param can be a list
param['_array'] = param['name'].endswith('[0]') param['_array'] = param['name'].endswith('[0]')
# fix name # remove array suffix
param['name'] = param['name'].rstrip('[0]') if param['_array']:
param['name'] = param['name'][:-3]
# turn params from a list to a dict # turn params from a list to a dict
self._dict['parameters'][param['name']] = param self._dict['parameters'][param['name']] = param
@ -213,17 +254,19 @@ class WebAPIMethod(object):
) )
def __call__(self, **kwargs): def __call__(self, **kwargs):
possible_kwargs = set(self._dict['parameters'].keys()) | set(['key', 'format', 'raw']) possible_kwargs = set(self._dict['parameters'].keys()) | set(DEFAULT_PARAMS.keys())
unrecognized = set(kwargs.keys()).difference(possible_kwargs) unrecognized = set(kwargs.keys()).difference(possible_kwargs)
if unrecognized: if unrecognized:
raise ValueError("Unrecognized parameter %s" % repr(unrecognized.pop())) raise ValueError("Unrecognized parameter %s" % repr(unrecognized.pop()))
params = {} params = {}
# process special case kwargs # process special case kwargs
for param in ('key', 'format', 'raw'): for param in DEFAULT_PARAMS.keys():
if param in kwargs: if param in kwargs:
params[param] = kwargs[param] params[param] = kwargs[param]
del kwargs[param] del kwargs[param]
else:
params[param] = getattr(self._parent, param)
# process method parameters # process method parameters
for param in self.parameters.values(): for param in self.parameters.values():
@ -252,10 +295,10 @@ class WebAPIMethod(object):
params[name] = kwargs[name] params[name] = kwargs[name]
# make the request # make the request
return self._api_request( return webapi_request(
self,
self.method,
"%s/%s/v%s/" % (self._parent.name, self.name, self.version), "%s/%s/v%s/" % (self._parent.name, self.name, self.version),
method=self.method,
caller=self,
params=params, params=params,
) )
@ -271,18 +314,10 @@ class WebAPIMethod(object):
def parameters(self): def parameters(self):
return self._dict['parameters'] return self._dict['parameters']
@property
def _api_request(self):
return self._parent._parent._api_request
@property @property
def name(self): def name(self):
return self._dict['name'] return self._dict['name']
@property
def https(self):
return self._parent.https
def doc(self): def doc(self):
print(self.__doc__) print(self.__doc__)

0
tests/__init__.py

245
tests/test_steamid.py

@ -0,0 +1,245 @@
import unittest
import mock
from steam.steamid import SteamID, requests
from steam.enums import EType, EUniverse
class SteamID_initialization(unittest.TestCase):
def compare(self, obj, test_list):
self.assertEqual(obj.id, test_list[0])
self.assertEqual(obj.type, test_list[1])
self.assertEqual(obj.universe, test_list[2])
self.assertEqual(obj.instance, test_list[3])
def test_arg_toomany(self):
with self.assertRaises(ValueError):
SteamID(1, 2)
with self.assertRaises(ValueError):
SteamID(1, 2, 3)
with self.assertRaises(ValueError):
SteamID(1, 2, 3, 4)
######################################################
# 1 ARG
######################################################
@mock.patch.object(requests, "get")
def test_arg_community_url_id(self, mock_requests_get):
ResponseMock = mock.Mock()
ResponseMock.content = 'var asd = {"steamid":"76580280500085312","key":5123}'
mock_requests_get.return_value = ResponseMock
# http
self.compare(SteamID("http://steamcommunity.com/id/testvanity"),
[123456, EType.Individual, EUniverse.Public, 4444]
)
mock_requests_get.assert_called_with("http://steamcommunity.com/id/testvanity")
# https
self.compare(SteamID("https://steamcommunity.com/id/testvanity"),
[123456, EType.Individual, EUniverse.Public, 4444]
)
mock_requests_get.assert_called_with("https://steamcommunity.com/id/testvanity")
# raise
ResponseMock.content = "no steamid json :("
with self.assertRaises(ValueError):
self.compare(SteamID("https://steamcommunity.com/id/testvanity"),
[123456, EType.Individual, EUniverse.Public, 4444]
)
def test_arg_community_url_profiles(self):
# http
self.compare(SteamID("http://steamcommunity.com/profiles/76580280500085312"),
[123456, EType.Individual, EUniverse.Public, 4444]
)
# https
self.compare(SteamID("https://steamcommunity.com/profiles/76580280500085312"),
[123456, EType.Individual, EUniverse.Public, 4444]
)
def test_arg_number_out_of_range(self):
self.assertRaises(ValueError, SteamID, -1)
self.assertRaises(ValueError, SteamID, '-1')
self.assertRaises(ValueError, SteamID, -5555555)
self.assertRaises(ValueError, SteamID, '-5555555')
self.assertRaises(ValueError, SteamID, 2**64)
self.assertRaises(ValueError, SteamID, str(2**64))
self.assertRaises(ValueError, SteamID, 2**128)
self.assertRaises(ValueError, SteamID, str(2**128))
def test_arg_steam32(self):
self.compare(SteamID(1),
[1, EType.Individual, EUniverse.Public, 1])
self.compare(SteamID('1'),
[1, EType.Individual, EUniverse.Public, 1])
self.compare(SteamID(12),
[12, EType.Individual, EUniverse.Public, 1])
self.compare(SteamID('12'),
[12, EType.Individual, EUniverse.Public, 1])
self.compare(SteamID(123),
[123, EType.Individual, EUniverse.Public, 1])
self.compare(SteamID('123'),
[123, EType.Individual, EUniverse.Public, 1])
self.compare(SteamID(12345678),
[12345678, EType.Individual, EUniverse.Public, 1])
self.compare(SteamID('12345678'),
[12345678, EType.Individual, EUniverse.Public, 1])
self.compare(SteamID(0xffffFFFF),
[0xffffFFFF, EType.Individual, EUniverse.Public, 1])
self.compare(SteamID(str(0xffffFFFF)),
[0xffffFFFF, EType.Individual, EUniverse.Public, 1])
def test_arg_steam64(self):
self.compare(SteamID(76580280500085312),
[123456, EType.Individual, EUniverse.Public, 4444]
)
self.compare(SteamID('76580280500085312'),
[123456, EType.Individual, EUniverse.Public, 4444]
)
self.compare(SteamID(103582791429521412),
[4, EType.Clan, EUniverse.Public, 0]
)
self.compare(SteamID('103582791429521412'),
[4, EType.Clan, EUniverse.Public, 0]
)
######################################################
# 1 arg - steam2/steam3 format
######################################################
def test_arg_text_invalid(self):
with self.assertRaises(ValueError):
SteamID("randomtext")
def test_arg_steam2(self):
self.compare(SteamID("STEAM_0:1:1"),
[3, EType.Individual, EUniverse.Public, 1]
)
self.compare(SteamID("STEAM_1:1:1"),
[3, EType.Individual, EUniverse.Public, 1]
)
self.compare(SteamID("STEAM_0:0:4"),
[8, EType.Individual, EUniverse.Public, 1]
)
self.compare(SteamID("STEAM_1:0:4"),
[8, EType.Individual, EUniverse.Public, 1]
)
def test_arg_steam3(self):
self.compare(SteamID("[U:1:1234]"),
[1234, EType.Individual, EUniverse.Public, 1]
)
self.compare(SteamID("[G:1:1234]"),
[1234, EType.GameServer, EUniverse.Public, 1]
)
self.compare(SteamID("[g:1:4]"),
[4, EType.Clan, EUniverse.Public, 0]
)
self.compare(SteamID("[A:1:4]"),
[4, EType.AnonGameServer, EUniverse.Public, 0]
)
self.compare(SteamID("[A:1:1234:567]"),
[1234, EType.AnonGameServer, EUniverse.Public, 567]
)
######################################################
# KWARGS
######################################################
def test_kwarg_id(self):
# id kwarg is required always
with self.assertRaises(ValueError):
SteamID(instance=0)
SteamID(id=None)
self.assertEqual(SteamID(id=555).id, 555)
self.assertEqual(SteamID(id='555').id, 555)
def test_kwarg_type(self):
with self.assertRaises(KeyError):
SteamID(id=5, type="doesn't exist")
with self.assertRaises(ValueError):
SteamID(id=5, type=99999999)
with self.assertRaises(AttributeError):
SteamID(id=5, type=None)
self.assertEqual(SteamID(id=5, type=1).type, EType.Individual)
self.assertEqual(SteamID(id=5, type='Individual').type, EType.Individual)
self.assertEqual(SteamID(id=5, type='iNDIVIDUAL').type, EType.Individual)
def test_kwarg_universe(self):
with self.assertRaises(KeyError):
SteamID(id=5, universe="doesn't exist")
with self.assertRaises(ValueError):
SteamID(id=5, universe=99999999)
with self.assertRaises(AttributeError):
SteamID(id=5, universe=None)
self.assertEqual(SteamID(id=5, universe=1).universe, EUniverse.Public)
self.assertEqual(SteamID(id=5, universe='Public').universe, EUniverse.Public)
self.assertEqual(SteamID(id=5, universe='pUBLIC').universe, EUniverse.Public)
def test_kwarg_instance(self):
self.assertEqual(SteamID(id=5, instance=1234).instance, 1234)
for etype in EType:
self.assertEqual(SteamID(id=5, type=etype).instance,
1 if etype in (EType.Individual, EType.GameServer) else 0)
def test_kwargs_invalid(self):
invalid = [0, EType.Invalid, EUniverse.Invalid, 0]
self.compare(SteamID(), invalid)
self.compare(SteamID(id=0, type=0, universe=0, instance=0), invalid)
self.compare(SteamID(id=0,
type=EType.Invalid,
universe=EUniverse.Invalid,
instance=0,
), invalid)
self.compare(SteamID(id=0,
type='Invalid',
universe='Invalid',
instance=0,
), invalid)
self.compare(SteamID(id=0,
type='iNVALID',
universe='iNVALID',
instance=0,
), invalid)
class SteamID_properties(unittest.TestCase):
def test_repr(self):
# just to cover in coverage
repr(SteamID())
def test_str(self):
self.assertEqual(str(SteamID(76580280500085312)), '76580280500085312')
def test_as_steam2(self):
self.assertEqual(SteamID('STEAM_0:1:4').as_steam2, 'STEAM_0:1:4')
self.assertEqual(SteamID('STEAM_1:1:4').as_steam2, 'STEAM_0:1:4')
def test_as_steam3(self):
self.assertEqual(SteamID('[U:1:1234]').as_steam3, '[U:1:1234]')
self.assertEqual(SteamID('[g:1:4]').as_steam3, '[g:1:4]')
self.assertEqual(SteamID('[A:1:1234:567]').as_steam3, '[A:1:1234:567]')
self.assertEqual(SteamID('[G:1:1234:567]').as_steam3, '[G:1:1234]')
def test_as_32(self):
self.assertEqual(SteamID(76580280500085312).as_32, 123456)
def test_as_64(self):
self.assertEqual(SteamID(76580280500085312).as_64, 76580280500085312)
def test_community_url(self):
# user url
self.assertEqual(SteamID(76580280500085312).community_url,
'https://steamcommunity.com/profiles/76580280500085312'
)
# group url
self.assertEqual(SteamID('[g:1:4]').community_url,
'https://steamcommunity.com/gid/103582791429521412'
)
# else None
self.assertEqual(SteamID('[A:1:4]').community_url,
None
)

14
tests/test_webapi.py

@ -0,0 +1,14 @@
import unittest
import mock
import vcr
from steam.webapi import WebAPI, requests
from steam.enums import EType, EUniverse
test_api_key = 'test_api_key'
class TCwebapi(unittest.TestCase):
@vcr.use_cassette('vcr/webapi_init.json', mode='once', serializer='json')
def test_initialization(self):
api = WebAPI(test_api_key)

49
vcr/webapi_getserverinfo.json

@ -0,0 +1,49 @@
{
"version": 1,
"interactions": [
{
"request": {
"body": null,
"headers": {
"Connection": [
"keep-alive"
],
"Accept-Encoding": [
"gzip, deflate"
],
"Accept": [
"*/*"
],
"User-Agent": [
"python-requests/2.7.0 CPython/2.7.10 CYGWIN_NT-10.0/2.2.0(0.289/5/3)"
]
},
"method": "GET",
"uri": "https://api.steampowered.com/ISteamWebAPIUtil/GetServerInfo/v1/?key=test_api_key&format=json"
},
"response": {
"status": {
"message": "OK",
"code": 200
},
"headers": {
"date": [
"Sun, 23 Aug 2015 22:58:10 GMT"
],
"content-length": [
"78"
],
"expires": [
"Sun, 23 Aug 2015 22:58:10 GMT"
],
"content-type": [
"application/json; charset=UTF-8"
]
},
"body": {
"string": "{\n\t\"servertime\": 1440370690,\n\t\"servertimestring\": \"Sun Aug 23 15:58:10 2015\"\n}"
}
}
}
]
}

49
vcr/webapi_init.json

File diff suppressed because one or more lines are too long

49
vcr/webapi_resolovevanityurl.json

@ -0,0 +1,49 @@
{
"version": 1,
"interactions": [
{
"request": {
"body": null,
"headers": {
"Connection": [
"keep-alive"
],
"Accept-Encoding": [
"gzip, deflate"
],
"Accept": [
"*/*"
],
"User-Agent": [
"python-requests/2.7.0 CPython/2.7.10 CYGWIN_NT-10.0/2.2.0(0.289/5/3)"
]
},
"method": "GET",
"uri": "https://api.steampowered.com/ISteamUser/ResolveVanityURL/v1/?url_type=2&vanityurl=valve&key=test_api_key&format=json"
},
"response": {
"status": {
"message": "OK",
"code": 200
},
"headers": {
"date": [
"Sun, 23 Aug 2015 22:58:21 GMT"
],
"content-length": [
"71"
],
"expires": [
"Sun, 23 Aug 2015 22:58:21 GMT"
],
"content-type": [
"application/json; charset=UTF-8"
]
},
"body": {
"string": "{\n\t\"response\": {\n\t\t\"steamid\": \"103582791429521412\",\n\t\t\"success\": 1\n\t}\n}"
}
}
}
]
}
Loading…
Cancel
Save