Terrance / SkPy

An unofficial Python library for interacting with the Skype HTTP API.
https://skpy.t.allofti.me
BSD 3-Clause "New" or "Revised" License
262 stars 66 forks source link

AttributeError: 'SkypeSettings' object has no attribute 'flags' #73

Closed maxnikulin closed 6 years ago

maxnikulin commented 6 years ago

Just after login I try to get settings (actually I was exploring SkPy features) sk.settings I get exception

AttributeError                            Traceback (most recent call last)
<ipython-input-2-587c42275037> in <module>()
----> 1 sk.settings

<path>/github/OllieTerrance/SkPy/skpy/core.pyc in __repr__(self)
    100         reprs = []
    101         for attr in self.attrs:
--> 102             val = getattr(self, attr)
    103             if not val == self.defaults.get(attr):
    104                 reprs.append("{0}={1}".format(attr, repr(val)))

<path>/github/OllieTerrance/SkPy/skpy/main.pyc in flag(self)
    326         @property
    327         def flag(self):
--> 328             return (id in self.flags) ^ invert
    329 
    330         @flag.setter

AttributeError: 'SkypeSettings' object has no attribute 'flags'

I see no network activity. It is Python 2.7.12.

Account type

An old skype account not connected to a microsoft account.

Conversation details

N/A.

Steps to reproduce

Log in and try to get settings.

Result or traceback

See above.

Terrance commented 6 years ago

The flag data is retrieved when creating the Skype instance, so you should always see a request for that even when using a token:

$ SKPY_DEBUG_HTTP=1 python
>>> from skpy import Skype
>>> sk = Skype("fred.2", tokenFile=".tokens")
<= [20/12 18:35:13] GET https://flagsapi.skype.com/flags/v1
{}
=> [20/12 18:35:13] 200
{'Content-Length': '26',
 'Content-Type': 'application/json; charset=utf-8',
 'Date': 'Wed, 20 Dec 2017 18:35:15 GMT',
 'Server': 'Microsoft-HTTPAPI/2.0',
 'Strict-Transport-Security': 'max-age=31536000',
 'X-Content-Type-Options': 'nosniff',
 'X-Frame-Options': 'SAMEORIGIN',
 'X-XSS-Protection': '1; mode=block'}
[1, 2, ...]

If you're not seeing any network requests at all, perhaps the debug flag isn't actually making it through IPython? Can you try with a vanilla Python shell?

The other possibility (which I just noticed) is if you're not connecting at startup (i.e. Skype(connect=False) and then setting it up yourself), in which case the call in the first link above doesn't happen. You can call sk.settings.syncFlags() yourself, though really that ought to be handled somewhere for you...

maxnikulin commented 6 years ago

You guess is right, to avoid auth rate limit I use a recipe found somewhere on the website

sk = Skype(connect = False, tokenFile = tokenFile)
try:
    sk.conn.readToken()
except (SkypeAuthException, IOError):
    sk.conn.setUserPwd(user, getpass.getpass(user + ' password:'))
    sk.conn.getSkypeToken()

When authorizing first time today I had to type password. I noticed a long response with country titles, so I decided that flags were synced as well.

sk.settings

resulted in usual error AttributeError: 'SkypeSettings' object has no attribute 'flags'. After that I tried sk.settings.syncFlags(), successfully got array of some numbers. Another attempt to inspect sk.settings produced another error

<= [21/12 XX:XX:45] GET https://people.directory.live.com/people/account/settings
{}
INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): people.directory.live.com
DEBUG:requests.packages.urllib3.connectionpool:"GET /people/account/settings HTTP/1.1" 200 17
=> [21/12 XX:XX:47] 200
{'Cache-Control': 'no-cache',
 'Content-Encoding': 'deflate',
 'Content-Length': '17',
 'Content-Type': 'application/json',
...
{u'Settings': []}
<= [21/12 XX:XX:47] GET https://api.skype.com/users/<my-login>/options/OPT_SKYPE_CALL_POLICY
{}
INFO:requests.packages.urllib3.connectionpool:Resetting dropped connection: api.skype.com
DEBUG:requests.packages.urllib3.connectionpool:"GET /users/<my-login>/options/OPT_SKYPE_CALL_POLICY HTTP/1.1" 404 54
=> [21/12 XX:XX:47] 404
{'Cache-Control': 'no-store, no-cache, must-revalidate',
 'Connection': 'keep-alive',
...
 'X-XSS-Protection': '1; mode=block'}
{u'status': {u'code': 40400, u'text': u'Property not found.'}}
---------------------------------------------------------------------------
SkypeApiException                         Traceback (most recent call last)
<ipython-input-4-587c42275037> in <module>()
----> 1 sk.settings

<path>/github/OllieTerrance/SkPy/skpy/core.pyc in __repr__(self)
    100         reprs = []
    101         for attr in self.attrs:
--> 102             val = getattr(self, attr)
    103             if not val == self.defaults.get(attr):
    104                 reprs.append("{0}={1}".format(attr, repr(val)))

<path>/github/OllieTerrance/SkPy/skpy/main.pyc in callPrivacy(self)
    377     def callPrivacy(self):
    378         # Behaviour here is consistent with Skype for Web (neither 0 nor 1 displays as contacts only).
--> 379         return self.Privacy.Anyone if self.callPrivacyOpt == 0 else self.Privacy.Contacts
    380 
    381     @callPrivacy.setter

<path>/github/OllieTerrance/SkPy/skpy/main.pyc in opt(self)
    343             json = self.skype.conn("GET", "{0}/users/{1}/options/{2}".format(SkypeConnection.API_USER,
    344                                                                              self.skype.userId, id),
--> 345                                    auth=SkypeConnection.Auth.SkypeToken).json()
    346             return json.get("optionInt", json.get("optionStr", json.get("optionBin")))
    347 

<path>/github/OllieTerrance/SkPy/skpy/conn.pyc in __call__(self, method, url, codes, auth, headers, **kwargs)
    215             if resp.status_code == 429:
    216                 raise SkypeAuthException("Auth rate limit exceeded", resp)
--> 217             raise SkypeApiException("{0} response from {1} {2}".format(resp.status_code, method, url), resp)
    218         return resp
    219 

SkypeApiException: ('404 response from GET https://api.skype.com/users/<my-login>/options/OPT_SKYPE_CALL_POLICY', <Response [404]>)

So sk.settings.syncFlags() does not help if Skype instance is created with connect = False. Although I reported this issue, I am unsure if settings will be useful for me.

maxnikulin commented 6 years ago

With your suggestion, plain python (2.7 in my case) and coonection using

sk = Skype("fred.2", tokenFile=".tokens")

I get the same error 404. Flags are synced on Skype instance creation as you expect.

Terrance commented 6 years ago

404 response from GET https://api.skype.com/users//options/OPT_SKYPE_CALL_POLICY

Huh, that's a curious one. It should look something like this:

<= [13/01 11:33:46] GET https://api.skype.com/users/fred.2/options/OPT_SKYPE_CALL_POLICY
{}
=> [13/01 11:33:46] 200
{'Cache-Control': 'no-store, no-cache, must-revalidate',
 'Connection': 'keep-alive',
 'Content-Length': '86',
 'Content-Type': 'application/json; ver=1.0; charset=utf-8',
 'Date': 'Sat, 13 Jan 2018 11:34:33 GMT',
 'Expires': 'Thu, 01 Jan 1970 00:00:01 +0000',
 'Pragma': 'no-cache',
 'Server': 'nginx/1.7.8',
 'Strict-Transport-Security': 'max-age=31536000; includeSubdomains;',
 'X-Content-Type-Options': 'nosniff',
 'X-Frame-Options': 'SAMEORIGIN',
 'X-Processing-Time': '0.055',
 'X-Skype-Request-Id': 'xxxxxxxx',
 'X-Stratus-Endpoint': '/users/:username/options/:option',
 'X-Stratus-Processing-Time': '0.0534',
 'X-Stratus-Request-Id': 'xxxxxxxx',
 'X-XSS-Protection': '1; mode=block'}
{'optionBin': None,
 'optionInt': 2,
 'optionName': 'OPT_SKYPE_CALL_POLICY',
 'optionStr': None}

Can you see this request being made anywhere for your account on Skype for Web? It should fire during startup.

maxnikulin commented 6 years ago

web.skype.com gets the same 404 for OPT_SKYPE_CALL_POLICY Do you have any guess what can be broken in skype for web due to this error?

I was going to report another 404 failure on attempt to delete a contact but finally that error has gone away. I do not know if it might be related to e.g. contact status or any other non-obvious state.

Terrance commented 6 years ago

I wonder if it throws a 404 until you actually try and set that option via Skype for Web.

If you haven't set it before, can you try changing it and reloading to see if it still 404s?

image

Terrance commented 6 years ago

It looks like this setting has probably been replaced by one on a different API server -- f4cca78 added support for it, so this should be resolved now?