Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initial commit

  • Loading branch information...
commit 338b754583a95b3c56cade75efc0d85b67bbdd69 0 parents
@peterhenderson peterhenderson authored
4 .gitignore
@@ -0,0 +1,4 @@
+*.pyc
+build
+dist
+MANIFEST
15 LICENSE
@@ -0,0 +1,15 @@
+Copyright 2010 FamilySearch
+
+Licensed under the FamilySearch API License Agreement (the "License"); you may
+not use these files except in compliance with this License. This Sample Client
+Library is included as "Sample Code" under that license.
+
+You may obtain a copy of the License at
+http://devnet.familysearch.org/certification/affiliate-programs/familysearch-legal-agreements/APILicense.pdf
+
+Unless required by applicable law or agreed to in writing, software distributed
+under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+CONDITIONS OF ANY KIND, either express or implied.
+
+See the License for the specific language governing permissions and limitations
+under the License.
13 setup.py
@@ -0,0 +1,13 @@
+from distutils.core import setup
+
+setup(name='python-fs-stack',
+ version='0.1',
+ description='Python wrapper for all FamilySearch APIs',
+ url='https://devnet.familysearch.org/downloads/sample-code',
+ author='Peter Henderson',
+ author_email='peter.henderson@ldschurch.org',
+ license='FamilySearch API License Agreement <https://devnet.familysearch.org/downloads/sample-code/sample-clients/sample-client-license>',
+ package_dir={'': 'src'},
+ packages=['enunciate'],
+ scripts=['src/login.py'],
+ )
3  src/enunciate/README
@@ -0,0 +1,3 @@
+This directory should contain code generated by Enunciate to read and write the
+FamilySearch API's JSON. For now, since Enunciate does not yet generate Python
+code, this directory contains example code.
0  src/enunciate/__init__.py
No changes.
66 src/enunciate/identity.py
@@ -0,0 +1,66 @@
+try:
+ import json
+except ImportError:
+ import simplejson as json
+
+
+def parse(input):
+ """Parse specified file or string and return an Identity object created from it."""
+ if hasattr(input, "read"):
+ data = json.load(input)
+ else:
+ data = json.loads(input)
+ return Identity(data)
+
+
+class JSONBase:
+ """Base class for all JSON-related objects"""
+ def to_json(self):
+ return json.dumps(self.to_json_dict())
+
+ def __repr__(self):
+ return self.to_json()
+
+
+class FSDict(dict):
+ """Convenience class to access FamilySearch-style property lists as dictionaries
+
+ For example,
+ [{"name": "key1", "value": "value1"}, {"name": "key2", "value": "value2"}]
+ converts to
+ {"key1": "value1", "key2": "value2"}
+
+ """
+
+ def __init__(self, pairs=None):
+ if isinstance(pairs, list) and all((isinstance(pair, dict) for pair in pairs)):
+ dict.__init__(self)
+ for pair in pairs:
+ self[pair["name"]] = pair["value"]
+
+ def to_json_array(self):
+ return [{"name": key, "value": self[key]} for key in self]
+
+
+class Identity(JSONBase):
+ def __init__(self, o):
+ if "statusCode" in o:
+ self.statusCode = o["statusCode"]
+ if "statusMessage" in o:
+ self.statusMessage = o["statusMessage"]
+ if "version" in o:
+ self.version = o["version"]
+ if "properties" in o:
+ self.properties = FSDict(o["properties"])
+
+ def to_json_dict(self):
+ d = {}
+ if hasattr(self, "statusCode"):
+ d["statusCode"] = self.statusCode
+ if hasattr(self, "statusMessage"):
+ d["statusMessage"] = self.statusMessage
+ if hasattr(self, "version"):
+ d["version"] = self.version
+ if hasattr(self, "properties"):
+ d["properties"] = self.properties.to_json_array()
+ return d
77 src/login.py
@@ -0,0 +1,77 @@
+# Sample OAuth authentication web app
+# By Peter Henderson <peter.henderson@ldschurch.org>
+
+# Requires:
+# - python-oauth2 <http://github.com/simplegeo/python-oauth2>
+# - httplib2 <http://code.google.com/p/httplib2/>
+# - web.py <http://webpy.org/>
+
+import urllib2
+import urlparse
+
+import oauth2 as oauth
+import web
+
+import enunciate.identity
+
+consumer_key = 'WCQY-7J1Q-GKVV-7DNM-SQ5M-9Q5H-JX3H-CMJK'
+consumer_secret = ''
+
+familysearch_base_url = 'http://www.dev.usys.org'
+properties_url = familysearch_base_url + '/identity/v2/properties' + '?dataFormat=application/json'
+properties = enunciate.identity.parse(urllib2.urlopen(properties_url)).properties
+request_token_url = properties["request.token.url"]
+access_token_url = properties["access.token.url"]
+authorize_url = properties["authorize.url"]
+
+urls = (
+ '/', 'login',
+ '/authorized', 'authorized',
+ )
+app = web.application(urls, globals())
+
+
+class login():
+
+ def GET(self):
+ callback_url = web.ctx.home + '/authorized'
+ consumer = oauth.Consumer(consumer_key, consumer_secret)
+ client = oauth.Client(consumer)
+ client.set_signature_method(oauth.SignatureMethod_PLAINTEXT())
+
+ # Step 1: Get a request token. This is a temporary token that is used for
+ # having the user authorize an access token and to sign the request to obtain
+ # said access token.
+ resp, content = client.request(request_token_url + "?oauth_callback=%s" % callback_url)
+ if resp['status'] != '200':
+ return 'Invalid response %s.' % resp['status']
+ request_token = dict(urlparse.parse_qsl(content))
+ web.setcookie('request_token', request_token['oauth_token'])
+ web.setcookie('request_token_secret', request_token['oauth_token_secret'])
+
+ # Step 2: Redirect to the provider's authorize page.
+ raise web.found('%s?oauth_token=%s' % (authorize_url, request_token['oauth_token']))
+
+
+class authorized():
+
+ def GET(self):
+ # Step 3: Once the consumer has redirected the user back to the oauth_callback
+ # URL you can request the access token the user has approved. You use the
+ # request token to sign this request. After this is done you throw away the
+ # request token and use the access token returned. You should store this
+ # access token somewhere safe, like a database, for future use.
+ cookies = web.cookies(request_token='', request_token_secret='')
+ params = web.input(oauth_verifier='')
+ token = oauth.Token(cookies.request_token, cookies.request_token_secret)
+ token.set_verifier(params.oauth_verifier)
+ consumer = oauth.Consumer(consumer_key, consumer_secret)
+ client = oauth.Client(consumer, token)
+
+ resp, content = client.request(access_token_url)
+ access_token = dict(urlparse.parse_qsl(content))
+ return 'Your session is: %s' % access_token['oauth_token']
+
+
+if __name__ == '__main__':
+ app.run()
Please sign in to comment.
Something went wrong with that request. Please try again.