Refactor WebFingerClient and allow None for the attr parameter of the rel method

pull/9/head
Jeremy Carbaugh 2013-11-02 17:20:30 -04:00
rodzic 1156fede4a
commit f607e43a0f
2 zmienionych plików z 35 dodań i 41 usunięć

Wyświetl plik

@ -23,21 +23,22 @@ WebFinger is a discovery protocol that allows you to find information about peop
finger
======
finger(resource, rel=None, timeout=None, official=False)
The *finger* method provides a simple way of instantiating a WebFingerClient object and making the request. The *resource* parameter is a URI of the resource about which you are querying. The optional *rel* parameter can be either a string or a list of strings that will limit the response to the specific relations. WebFinger servers are **not** required to obey the *rel* parameter, so you should handle the response accordingly. The optional *timeout* parameter can set a specific HTTP request timeout. The *official* parameter is a boolean that determines if the client will use `unofficial endpoints`_.
finger(resource, rel=None)
*finger* is a convenience method for instantiating a WebFingerClient object and making the request. The *resource* parameter is a URI of the resource about which you are querying. The optional *rel* parameter can be either a string or a list of strings that will limit the response to the specific relations. WebFinger servers are **not** required to obey the *rel* parameter, so you should handle the response accordingly.
WebFingerClient supports additional options, so check that out if *finger* does not meet your needs.
WebFinger Client
================
WebFingerClient(timeout=None, official=False)
Instantiates a client object. *timeout* and *official* are the same as the parameters on the standalone *finger* method.
Instantiates a client object. The optional *timeout* parameter specifies the HTTP request timeout. The optional *official* parameter is a boolean that determines if the client will use `unofficial endpoints`_.
finger(resource, rel=None)
The client *finger* method prepares and executes the WebFinger request. *resource* and *rel* are the same as the parameters on the standalone *finger* method. This method extracts the host from the *resource* parameter and invokes the *jrd* method.
finger(resource, host=None, rel=None, raw=False)
The client *finger* method prepares and executes the WebFinger request. *resource* and *rel* are the same as the parameters on the standalone *finger* method. *host* should only be specified if you want to connect to a host other than the host in the resource parameter. Otherwise, this method extracts the host from the *resource* parameter. *raw* is a boolean that determines if the method returns a WebFingerResponse object or the raw JRD response as a dict.
jrd(host, resource, rel, raw=False)
The *jrd* method is the core of the client object. It executes the HTTP request and creates the response object. *host* is a string of the host against which the request will be executed. *resource* and *rel* are the same as the parameters on the standalone *finger* method. *raw* is a boolean that determines if the method returns a WebFingerResponse object or the raw JRD response as a dict.
If the *host* parameter is passed to this method, unofficial endpoints are ignored. You're asking for a specific host so who am I to disagree?
WebFinger Response
@ -83,6 +84,8 @@ rel(relation, attr='href')
>>> rel = 'http://webfinger.net/rel/avatar'
>>> [l.get('href') for l in rel.links if l.get('rel') == rel]
If *attr* is None, the full dict for the link will be returned.
Relation Properties

Wyświetl plik

@ -63,7 +63,9 @@ class WebFingerResponse(object):
def rel(self, relation, attr='href'):
for link in self.links:
if link.get('rel') == relation:
return link.get(attr)
if attr:
return link.get(attr)
return link
class WebFingerClient(object):
@ -72,11 +74,21 @@ class WebFingerClient(object):
self.official = official
self.timeout = timeout
def jrd(self, host, resource, rel, raw=False):
""" Load resource at given URL and attempt to parse either XRD or JRD
based on HTTP response Content-Type header. The rel parameter
may be a single value or a list.
"""
def _parse_host(self, resource):
host = resource.split("@")[-1]
if host in UNOFFICIAL_ENDPOINTS and not self.official:
unofficial_host = UNOFFICIAL_ENDPOINTS[host]
logging.debug('host %s is not supported, using unofficial endpoint %s' % (host, unofficial_host))
host = unofficial_host
return host
def finger(self, resource, host=None, rel=None, raw=False):
if not host:
host = self._parse_host(resource)
url = "https://%s/.well-known/webfinger" % host
@ -99,36 +111,15 @@ class WebFingerClient(object):
raise WebFingerException('Invalid response type from server')
if raw:
return resp.content
return resp.json()
return resp.json()
def finger(self, resource, rel=None):
""" Perform a WebFinger query based on the given subject.
The `rel` parameter, if specified, will be passed to the provider,
but be aware that providers are not required to implement the
rel filter.
"""
host = resource.split("@")[-1]
if host in UNOFFICIAL_ENDPOINTS and not self.official:
unofficial_host = UNOFFICIAL_ENDPOINTS[host]
logging.debug('host %s is not supported, using unofficial endpoint %s' % (host, unofficial_host))
host = unofficial_host
jrd = self.jrd(host, resource, rel)
return WebFingerResponse(jrd)
return WebFingerResponse(resp.json())
def finger(resource, rel=None, timeout=None, official=False):
""" Shortcut method for invoking WebFingerClient.
def finger(resource, rel=None):
""" Convenience method for invoking WebFingerClient.
"""
if ":" not in resource:
raise WebFingerException("scheme is required in subject URI")
client = WebFingerClient(timeout=timeout, official=official)
return client.finger(resource, rel=rel)
return WebFingerClient().finger(resource, rel=rel)
if __name__ == '__main__':
@ -151,12 +142,12 @@ if __name__ == '__main__':
if args.rel:
link = wf.find_link(args.rel)
link = wf.rel(args.rel)
if link is None:
print("*** Link not found for rel=%s" % args.rel)
print("%s:\n\t%s" % (link.rel, link.href))
print("%s:\n\t%s" % (args.rel, link))
else: