client.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. from .session import ClientSession
  2. from .endpoints import (
  3. LiveEndpointsMixin,
  4. VREndpointsMixin,
  5. RoomEndpointsMixin,
  6. UserEndpointsMixin,
  7. OtherEndpointsMixin
  8. )
  9. from json import JSONDecodeError
  10. import time
  11. from showroom.api.utils import get_csrf_token
  12. from requests.exceptions import HTTPError
  13. import logging
  14. _base_url = 'https://www.showroom-live.com'
  15. # TODO: logging, warnings
  16. # TODO: load auth or credentials from file or dict
  17. # TODO: save auth or credentials to file
  18. client_logger = logging.getLogger('showroom.client')
  19. class ShowroomClient(
  20. LiveEndpointsMixin,
  21. UserEndpointsMixin,
  22. RoomEndpointsMixin,
  23. VREndpointsMixin,
  24. OtherEndpointsMixin
  25. ):
  26. """
  27. Client for interacting with the Showroom API.
  28. :param cookies: dict containing stored cookies
  29. :ivar cookies: Reference to the underlying session's cookies.
  30. """
  31. def __init__(self, cookies=None):
  32. self._session = ClientSession()
  33. self._auth = None
  34. self.cookies = self._session.cookies
  35. if cookies:
  36. self.cookies.update(cookies)
  37. expiry = self.cookies.expires_earliest
  38. if expiry and int(time.time()) >= expiry:
  39. # TODO: more information, more specific error
  40. raise ValueError('A cookie has expired')
  41. # TODO: does this actually mean we're logged in? if no, how do I check?
  42. self._auth = self.cookies.get('sr_id')
  43. # TODO: request responses in different languages
  44. # to force japanese text in responses:
  45. # self.session.cookies.update({'lang': 'ja'})
  46. # this doesn't always seem to work? it worked until i manually set lang:en, then switching back failed
  47. self.__csrf_token = None
  48. self._last_response = None
  49. @property
  50. def _csrf_token(self):
  51. if not self.__csrf_token:
  52. self._update_csrf_token(_base_url)
  53. return self.__csrf_token
  54. def _update_csrf_token(self, url):
  55. r = self._session.get(url)
  56. self.__csrf_token = get_csrf_token(r.text)
  57. def _api_get(self, endpoint, params=None, return_response=False, default=None, raise_error=True):
  58. try:
  59. r = self._session.get(_base_url + endpoint, params=params)
  60. except HTTPError as e:
  61. r = e.response
  62. if raise_error:
  63. raise
  64. self._last_response = r
  65. if return_response:
  66. return r
  67. else:
  68. try:
  69. return r.json()
  70. except JSONDecodeError as e:
  71. client_logger.error('JSON decoding error while getting {}: {}'.format(r.request.url, e))
  72. return default or {}
  73. def _api_post(self, endpoint, params=None, data=None, return_response=None, default=None):
  74. try:
  75. r = self._session.post(_base_url + endpoint, params=params, data=data)
  76. except HTTPError as e:
  77. r = e.response
  78. self._last_response = r
  79. # TODO: check for expired csrf_token
  80. if return_response:
  81. return r
  82. else:
  83. try:
  84. return r.json()
  85. except JSONDecodeError as e:
  86. client_logger.error('JSON decoding error while posting to {}: {}'.format(r.request.url, e))
  87. return default or {}