amev7fam / familysearch-python-sdk-opensource Goto Github PK
View Code? Open in Web Editor NEWWIP Python SDK for FamilySearch
License: BSD 2-Clause "Simplified" License
WIP Python SDK for FamilySearch
License: BSD 2-Clause "Simplified" License
The link for "getting started" is pointing to a non-existing page.
The correct link is https://amev7fam.github.io/familysearch-python-sdk-opensource/ as is guessable from the pattern, but it would be better if it would point to the right page.
(This affects logging in, so high priority!)
I'm not sure why, but quotes are being added to strings on the POST body, as seen here:
POST /cis-web/oauth2/v3/token
User-Agent: Python-FS-Stack/0.3pre
Content-Type: application/x-www-form-urlencoded
Accept: application/json
"username=foo&grant_type=password&client_id=UBER-SRCT-FMLY-SRCH-APPL-CTON-CODE&password=bar"
The quotes are preventing logging in, and I'm sure that it's affecting all POST strings.
Based on elderamevans/familysearch-gramps#1, which lead to https://gist.github.com/elderamevans/3911cc0e858729b9ad94, I've come to realize that we may need a way to send sign-in issues to the user, without requiring any external diagnostics.
The PW and Code login should work with the diagnoser, come to think of it....
When I attempt to run the sample whoami or the web_person on my machine I get the following error:
Traceback (most recent call last):
File "C:\Users\James\Desktop\FamEarth_Prog\elderamevans-familysearch-python-sdk-opensource-1ffca1d\sample-apps\whoami.py", line 17, in
from familysearch import FamilySearch
File "C:\Python34\lib\familysearch__init__.py", line 215, in
from . import(discovery_, authentication_, authorities_, changeHistory_,
File "C:\Python34\lib\familysearch\discovery_.py", line 83, in
FamilySearch.bases += (Discovery,)
TypeError: Cannot create a consistent method resolution
order (MRO) for bases Discovery, object
Any Ideas on what I need to do to run the sample applications?
Hi !
I use python 3.6.4 on Windows
I tried :
fs = FamilySearch('ClientApp/1.0', app_key)
I got this error:
Traceback (most recent call last):
File "C:\Program Files (x86)\Python36-32\lib\urllib\request.py", line 1318, in do_open
encode_chunked=req.has_header('Transfer-encoding'))
File "C:\Program Files (x86)\Python36-32\lib\http\client.py", line 1239, in request
self._send_request(method, url, body, headers, encode_chunked)
File "C:\Program Files (x86)\Python36-32\lib\http\client.py", line 1285, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File "C:\Program Files (x86)\Python36-32\lib\http\client.py", line 1234, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "C:\Program Files (x86)\Python36-32\lib\http\client.py", line 1026, in _send_output
self.send(msg)
File "C:\Program Files (x86)\Python36-32\lib\http\client.py", line 964, in send
self.connect()
File "C:\Program Files (x86)\Python36-32\lib\http\client.py", line 1392, in connect
super().connect()
File "C:\Program Files (x86)\Python36-32\lib\http\client.py", line 936, in connect
(self.host,self.port), self.timeout, self.source_address)
File "C:\Program Files (x86)\Python36-32\lib\socket.py", line 704, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
File "C:\Program Files (x86)\Python36-32\lib\socket.py", line 745, in getaddrinfo
for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno 11004] getaddrinfo failed
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "Z:\getmyancestors\test.py", line 7, in <module>
fs = FamilySearch('ClientApp/1.0', app_key)
File "Z:\getmyancestors\familysearch\__init__.py", line 122, in __init__
Discovery.__init__(self)
File "Z:\getmyancestors\familysearch\discovery.py", line 12, in __init__
self.root_collection = self.get(self.base + '/.well-known/collection')
File "Z:\getmyancestors\familysearch\__init__.py", line 217, in get
url, data, headers, "GET", nojson), nojson)
File "Z:\getmyancestors\familysearch\__init__.py", line 164, in _request
return self.opener.open(request)
File "C:\Program Files (x86)\Python36-32\lib\urllib\request.py", line 526, in open
response = self._open(req, data)
File "C:\Program Files (x86)\Python36-32\lib\urllib\request.py", line 544, in _open
'_open', req)
File "C:\Program Files (x86)\Python36-32\lib\urllib\request.py", line 504, in _call_chain
result = func(*args)
File "C:\Program Files (x86)\Python36-32\lib\urllib\request.py", line 1361, in https_open
context=self._context, check_hostname=self._check_hostname)
File "C:\Program Files (x86)\Python36-32\lib\urllib\request.py", line 1320, in do_open
raise URLError(err)
urllib.error.URLError: <urlopen error [Errno 11004] getaddrinfo failed>
The code here:
is invalid Python: you are calling the constructor method on each of these classes (without an instance of each), but passing in self which is the instance of a FamilySearch object.
If you want to really create instances of each, you should just make them:
self.discovery = Discovery()
self.authentication = Authentication()
if you need to pass in an instance of FamilySearch, you can do that:
self.discovery = Discovery(self)
self.authentication = Authentication(self)
but then you need to change the definition of the classes to take a FamilySearch object:
class Discovery:
def __init__(self, familysearch):
....
Hope that helps.
When you call get_parents on a person that has no parents, the API will return a status code of 204 with an empty response. In that case, _fs2py will fail when doing this:
response = json.loads(response)
, since response is empty at that point. One potential solution is to do an:
if(len(response))>0:
Just got latest. Looks like imports aren't working anymore.
Simple example:
from familysearch import FamilySearch
fs = FamilySearch('bar', 'foo', base="https://sandbox.familysearch.org")
fs.login(input("Username: "), getpass())
Running this gives:
AttributeError: 'FamilySearch' object has no attribute 'login'
At the end of the function, self.oauth_code(qs)
is being called, that should be self.oauth_code_login(qs)
Also, in python 2.7, the function parse_qs is never imported. Needed to add from urlparse import(parse_qs)
After that, it worked fine.
I'm not sure if I am doing this right, but I wanted to capture the oauth code that I see when using oauth_desktop_login and pass it in a later session to oauth_code_login so that I don't have to keep logging in.
So what I do is, when I use oauth_desktop_login, a browser window pops up, I type in my sandbox username/password. The browser then goes to http://localhost:63342/fslogin?code=some_code_here, I copy the code (everything after the =), store it in a variable, then call oauth_code_login with that code as the parameter. Unfortunately, this results in a 400 Bad Request error.
Am I doing this right and there is some bug in the oauth_code_login? Is there a better way to not have to log in every time before getting the app approved (at which case I can just use login)?
This shouldn't affect functionality, but, in theory, it should help "future-proof" it, in case the hard-coded links change.
I know, this is a bit of an easy one, but it's a bit of an artifact from the old SDK...
from . import FamilySearch
FamilySearch.__bases__ += (Class,)
Technically, we should move the import to the top.
Simple enough, but thought it should be thrown out there...
Some of the requests require you to have the Tree User ID in order to work. Right now,they're hard-coded to the logged in user's User ID (UID).
The reason for doing this is for server environments.
Rather than doing:
fs[userfoo].get(fs[userfoo].bar(baz))
It would allow servers to do:
fs[userfoo].get(fs[server].bar(baz, uid=blah))
It would still allow desktop apps (or otherwise in a single-user environment) to:
fs.get(fs.bar(baz))
While working on the "redirect" function, I realized I needed to have it return a URL. This made me think about the syntax as the rest of the SDK. I realize that, if I were to go through with this, it would take a bit of major tweaking. The good news is, I know of no production app that uses the SDK, so modifying it shouldn't be too drastic of a change, but it's better to do it now than to do it later.
The current syntax:
fs.get_person(pid)
fs.edit_person(pid, data)
fs.create_person(data)
The proposed syntax:
fs.get(fs.person(pid))
fs.post(fs.person(pid), data)
fs.post(fs.person(), data)
I realize that I could have both (for reverse-compatibility and/or preference, but I realize that my choice now could affect us 20 years down the road. What say you?
We need a way to consistently integrate the response headers into the response itself. Some of the functions, in fact, receive 204 (no content) responses, meaning all that there is, is the header information, sometimes containing necessary information, such as the Warning header for merge constraint, or, when creating a person, their person ID.
As it stands right now, there are two ways to "install" the SDK:
familysearch
folder in with your script.Both are OK, but we can do better than this! Besides, I feel that this should eventually go on PyPI!
The biggest question is: what needs to go where...?
Sorry, this may be because I'm unfamiliar with apache servers. For the oath_desktop_login(), the redirect URL is http://localhost.com:63342/fslogin. What is fslogin? I don't see it anywhere in the project, and my default setup (Mac OS X) doesn't have any fslogin scripts.
Related to #22, but thought I'd add it as a specific issue.
Right now, it's hard-coded in a jimmy-rigged way.
(As a side note to whomever fixes this: I've added non-public environment variables of "FSUSERNAME" and "FSPASSWORD". I think you'll know what they're for: Sandbox login information.)
With the (rather) major changes to the SDK, some of the code in the sample apps are outdated.
I'll probably update it myself...
I'm assuming the following lines in places.py contain typos:
22: return self.places_base + "gropus/" + pgid
38: return self.places_base + "type-gropus/" + ptgid
I'm assuming they should be groups, not gropus.
So, I decided to run PyLint on the SDK, just to see what happened. Apparently... It could use some work... With a beginning score of -21.85/10, all I can say is, wow. I did so bad, I owe points! It still functions in the meantime, but it shows that us imperfect people are developing imperfect code.
This is the current results. I will edit below this line as I improve it.
pylint familysearch --disable=no-member,cyclic-import,import-error,missing-final-newline,undefined-variable
Why each of these?
*no-member, cyclic-import due to the deliberate nature of the SDK
************* Module familysearch
C:182, 0: Wrong hanging indentation.
url, data, headers, "GET", nojson), nojson)
^ | (bad-continuation)
C:187, 0: Wrong hanging indentation.
url, data, headers, "POST", nojson), nojson)
^ | (bad-continuation)
C:192, 0: Wrong hanging indentation.
url, data, headers, "PUT", nojson), nojson)
^ | (bad-continuation)
C:197, 0: Wrong hanging indentation.
url, data, headers, "HEAD", nojson), nojson)
^ | (bad-continuation)
C:202, 0: Wrong hanging indentation.
url, data, headers, "OPTIONS", nojson), nojson)
^ | (bad-continuation)
C:207, 0: Wrong hanging indentation.
url, data, headers, "DELETE", nojson), nojson)
^ | (bad-continuation)
C:214, 0: Trailing whitespace (trailing-whitespace)
C:214, 0: Exactly one space required after comma
discussions_, memories_,parentsAndChildren_, ordinances_,
^ (bad-whitespace)
E: 41, 4: No name 'urlencode' in module 'urllib' (no-name-in-module)
R: 51, 0: Too few public methods (1/2) (too-few-public-methods)
C: 68, 0: Missing class docstring (missing-docstring)
C: 68,22: More than one statement on a single line (multiple-statements)
R: 68, 0: Too few public methods (0/2) (too-few-public-methods)
R: 69, 0: Too many instance attributes (9/7) (too-many-instance-attributes)
R:102, 4: Too many arguments (6/5) (too-many-arguments)
C:131,12: Invalid variable name "eh" (invalid-name)
R:139, 4: Method could be a function (no-self-use)
R:151, 4: Method could be a function (no-self-use)
R:165, 4: Method could be a function (no-self-use)
************* Module familysearch.authentication_
W:100, 0: TODO: make IP address generiation automatic
(fixme)
C: 44, 0: Wrong continued indentation.
})
|^ (bad-continuation)
C: 48, 0: Wrong continued indentation.
"Accept": "application/json"}, nojson=True)
^| (bad-continuation)
C: 65, 0: Wrong continued indentation.
'client_id': self.key,
^ | (bad-continuation)
C: 66, 0: Wrong continued indentation.
'redirect_uri': "http://localhost:63342/fslogin"
^ | (bad-continuation)
C: 67, 0: Wrong continued indentation.
})
^ | (bad-continuation)
C: 82, 0: Wrong continued indentation.
})
| ^ (bad-continuation)
C: 86, 0: Wrong continued indentation.
"Accept": "application/json"}, nojson=True)
^| (bad-continuation)
C:100, 0: Line too long (103/100) (line-too-long)
C:103, 0: Wrong continued indentation.
})
|^ (bad-continuation)
C:107, 0: Wrong continued indentation.
"Accept": "application/json"}, nojson=True)
^| (bad-continuation)
E: 11, 4: No name 'urlencode' in module 'urllib' (no-name-in-module)
C: 20, 0: Missing class docstring (missing-docstring)
W: 49,13: Attribute 'session_id' defined outside __init__ (attribute-defined-outside-init)
W: 87,13: Attribute 'session_id' defined outside __init__ (attribute-defined-outside-init)
W:108,13: Attribute 'session_id' defined outside __init__ (attribute-defined-outside-init)
W:119,13: Attribute 'session_id' defined outside __init__ (attribute-defined-outside-init)
W: 37,13: Attribute 'logged_in' defined outside __init__ (attribute-defined-outside-init)
W: 50,13: Attribute 'logged_in' defined outside __init__ (attribute-defined-outside-init)
W: 60,13: Attribute 'logged_in' defined outside __init__ (attribute-defined-outside-init)
W: 88,13: Attribute 'logged_in' defined outside __init__ (attribute-defined-outside-init)
W: 97,13: Attribute 'logged_in' defined outside __init__ (attribute-defined-outside-init)
W:109,13: Attribute 'logged_in' defined outside __init__ (attribute-defined-outside-init)
W:116,13: Attribute 'logged_in' defined outside __init__ (attribute-defined-outside-init)
C:123, 0: Invalid class name "getter" (invalid-name)
C:123, 0: Missing class docstring (missing-docstring)
C:124, 4: Invalid method name "do_GET" (invalid-name)
C:130, 8: Invalid constant name "qs" (invalid-name)
W:130, 8: Global variable 'qs' undefined at the module level (global-variable-undefined)
R:123, 0: Too few public methods (1/2) (too-few-public-methods)
************* Module familysearch.authorities_
C: 3, 0: Trailing whitespace (trailing-whitespace)
R: 6, 0: Too few public methods (1/2) (too-few-public-methods)
************* Module familysearch.changeHistory_
C: 17, 0: Line too long (119/100) (line-too-long)
C: 22, 0: Line too long (107/100) (line-too-long)
C: 1, 0: Invalid module name "changeHistory_" (invalid-name)
W: 14,72: Missing keyword argument 'pid' for format string (missing-format-argument-key)
************* Module familysearch.discovery_
W: 10, 0: TODO: Set it up so that it doesn't need to call the sumbodules
(fixme)
W: 19, 0: Bad indentation. Found 12 spaces, expected 8 (bad-indentation)
C: 18, 4: Missing method docstring (missing-docstring)
W: 29,16: No exception type(s) specified (bare-except)
E: 28, 0: Sequence index is not an int, slice, or instance with __index__ (invalid-sequence-index)
W: 37, 8: No exception type(s) specified (bare-except)
************* Module familysearch.discussions_
W: 11, 8: Unnecessary pass statement (unnecessary-pass)
************* Module familysearch.memories_
C: 27, 0: Trailing whitespace (trailing-whitespace)
C: 31, 0: Trailing whitespace (trailing-whitespace)
************* Module familysearch.ordinances_
C: 11, 0: Trailing whitespace (trailing-whitespace)
R: 6, 0: Too few public methods (0/2) (too-few-public-methods)
************* Module familysearch.parentsAndChildren_
C: 12, 0: Line too long (103/100) (line-too-long)
C: 16, 0: Line too long (110/100) (line-too-long)
C: 20, 0: Line too long (114/100) (line-too-long)
C: 22, 0: Wrong hanging indentation.
self.child_base + crid + "/" + role + "/conclusions/" + cid)
^ | (bad-continuation)
C: 23, 0: Trailing whitespace (trailing-whitespace)
C: 25, 0: Line too long (109/100) (line-too-long)
C: 27, 0: Trailing whitespace (trailing-whitespace)
C: 29, 0: Line too long (109/100) (line-too-long)
C: 33, 0: Line too long (111/100) (line-too-long)
C: 1, 0: Invalid module name "parentsAndChildren_" (invalid-name)
C: 6, 0: Missing class docstring (missing-docstring)
E: 28, 4: method already defined line 24 (function-redefined)
************* Module familysearch.pedigree_
C: 6, 0: Missing class docstring (missing-docstring)
W: 11,28: Unused argument 'query' (unused-argument)
************* Module familysearch.person_
C: 32, 0: Line too long (104/100) (line-too-long)
C: 50, 0: Trailing whitespace (trailing-whitespace)
C: 58, 0: Trailing whitespace (trailing-whitespace)
C: 68, 0: Line too long (101/100) (line-too-long)
C: 72, 0: Line too long (101/100) (line-too-long)
C: 92, 0: Line too long (102/100) (line-too-long)
C: 97, 0: Line too long (102/100) (line-too-long)
C: 6, 0: Missing class docstring (missing-docstring)
W: 11,22: Unused argument 'data' (unused-argument)
W:113,39: Unused argument 'pid' (unused-argument)
W:117,31: Unused argument 'pid' (unused-argument)
R: 6, 0: Too many public methods (27/20) (too-many-public-methods)
************* Module familysearch.places_
C: 29, 0: Line too long (101/100) (line-too-long)
************* Module familysearch.records_
C: 15, 0: Trailing whitespace (trailing-whitespace)
R: 6, 0: Too few public methods (0/2) (too-few-public-methods)
************* Module familysearch.searchAndMatch_
C: 10, 0: Trailing whitespace (trailing-whitespace)
C: 1, 0: Invalid module name "searchAndMatch_" (invalid-name)
************* Module familysearch.sources_
C: 29, 0: Line too long (109/100) (line-too-long)
C: 28, 4: Invalid method name "source_folder_source_descriptions" (invalid-name)
************* Module familysearch.spouses_
C: 21, 0: Line too long (103/100) (line-too-long)
C: 23, 0: Trailing whitespace (trailing-whitespace)
************* Module familysearch.user_
C: 16, 0: Trailing whitespace (trailing-whitespace)
C: 8, 0: Missing class docstring (missing-docstring)
************* Module familysearch.utilities_
C: 20, 0: Wrong hanging indentation.
self.base + "platform/redirect", params, **kwargs)
^ | (bad-continuation)
C: 6, 0: Missing class docstring (missing-docstring)
W: 18,22: Used * or ** magic (star-args)
************* Module familysearch.vocabularies_
C: 19, 0: Trailing whitespace (trailing-whitespace)
448 statements analysed.
now | previous | difference | |
---|---|---|---|
nb duplicated lines | 0 | 0 | = |
percent duplicated lines | 0.000 | 0.000 | = |
|type |number |old number |difference |%documented |%badname |
|module |19 |19 |= |100.00 |15.79 |
|class |22 |22 |= |63.64 |4.55 |
|method |125 |125 |= |99.20 |1.60 |
|function |0 |0 |= |0 |0 |
|code |649 |56.43 |648 |+1.00 |
|docstring |296 |25.83 |296 |-1.00 |
|comment |61 |5.30 |58 |+3.00 |
|empty |143 |12.43 |141 |-2.00 |
type | number | previous | difference |
---|---|---|---|
code | 491 | 54.98 | 491 |
docstring | 252 | 28.22 | 252 |
comment | 33 | 3.70 | 33 |
empty | 117 | 13.10 | 117 |
module | error | warning | refactor | convention |
---|---|---|---|---|
familysearch.authentication_ | 25.00 | 54.17 | 8.33 | 22.39 |
familysearch.discovery_ | 25.00 | 16.67 | 0.00 | 1.49 |
familysearch | 25.00 | 0.00 | 58.33 | 16.42 |
familysearch.parentsAndChildren_ | 25.00 | 0.00 | 0.00 | 16.42 |
familysearch.person_ | 0.00 | 12.50 | 8.33 | 11.94 |
familysearch.changeHistory_ | 0.00 | 4.17 | 0.00 | 4.48 |
familysearch.utilities_ | 0.00 | 4.17 | 0.00 | 2.99 |
familysearch.pedigree_ | 0.00 | 4.17 | 0.00 | 1.49 |
familysearch.discussions_ | 0.00 | 4.17 | 0.00 | 0.00 |
familysearch.records_ | 0.00 | 0.00 | 8.33 | 1.49 |
familysearch.ordinances_ | 0.00 | 0.00 | 8.33 | 1.49 |
familysearch.authorities_ | 0.00 | 0.00 | 8.33 | 1.49 |
familysearch.user_ | 0.00 | 0.00 | 0.00 | 2.99 |
familysearch.spouses_ | 0.00 | 0.00 | 0.00 | 2.99 |
familysearch.sources_ | 0.00 | 0.00 | 0.00 | 2.99 |
familysearch.searchAndMatch_ | 0.00 | 0.00 | 0.00 | 2.99 |
familysearch.memories_ | 0.00 | 0.00 | 0.00 | 2.99 |
familysearch.vocabularies_ | 0.00 | 0.00 | 0.00 | 1.49 |
familysearch.places_ | 0.00 | 0.00 | 0.00 | 1.49 |
message id | occurrences |
---|---|
line-too-long | 17 |
bad-continuation | 17 |
trailing-whitespace | 14 |
attribute-defined-outside-init | 11 |
missing-docstring | 9 |
invalid-name | 8 |
too-few-public-methods | 6 |
unused-argument | 4 |
no-self-use | 3 |
no-name-in-module | 2 |
fixme | 2 |
bare-except | 2 |
unnecessary-pass | 1 |
too-many-public-methods | 1 |
too-many-instance-attributes | 1 |
too-many-arguments | 1 |
star-args | 1 |
multiple-statements | 1 |
missing-format-argument-key | 1 |
invalid-sequence-index | 1 |
global-variable-undefined | 1 |
function-redefined | 1 |
bad-whitespace | 1 |
bad-indentation | 1 |
::
familysearch (familysearch.sources_,familysearch.authorities_,familysearch.places_,familysearch.records_,familysearch.vocabularies_,familysearch.changeHistory_,familysearch.utilities_,familysearch.ordinances_,familysearch.discussions_,familysearch.parentsAndChildren_,familysearch.discovery_,familysearch.sourceBox_,familysearch.searchAndMatch_,familysearch.spouses_,familysearch.memories_,familysearch.notes_,familysearch.pedigree_,familysearch.user_,familysearch.authentication_,familysearch.person_)
\-authentication_ (familysearch)
\-authorities_ (familysearch)
\-changeHistory_ (familysearch)
\-discovery_ (familysearch)
\-discussions_ (familysearch)
\-memories_ (familysearch)
\-notes_ (familysearch)
\-ordinances_ (familysearch)
\-parentsAndChildren_ (familysearch)
\-pedigree_ (familysearch)
\-person_ (familysearch)
\-places_ (familysearch)
\-records_ (familysearch)
\-searchAndMatch_ (familysearch)
\-sourceBox_ (familysearch)
\-sources_ (familysearch)
\-spouses_ (familysearch)
\-user_ (familysearch)
\-utilities_ (familysearch)
http
\-server (familysearch.authentication_)
json (familysearch)
urllib (familysearch.authentication_,familysearch)
\-error (familysearch)
\-parse (familysearch.authentication_,familysearch)
\-request (familysearch.authentication_,familysearch)
webbrowser (familysearch.authentication_)
Your code has been rated at 7.25/10 (previous run: 6.92/10, +0.33)
I needed this GitHub account temporarily (couldn't use my personal one for a couple years for a few reasons), but now, I'm looking to merge this account with @AmEv7Fam.
This will mainly affect this repository.
I'll leave this issue up until the 1st of February, which should allow everybody to be prepared for the transfer.
It's got a good start, but it definitely could use some more work.
Now the question is, what level would we want it to be? Make sure that login works, and basic functions work, or go after every single endpoint that the SDK has available, or somewhere in between?
Or something else? I have no idea how to make a testing suite......
The following code works fine in python 2.7, but not in 3.4:
from familysearch import FamilySearch
fs = FamilySearch('app name', 'api key')
fs.oauth_desktop_login()
# i then enter my info into the browser
Unfortunately, in 3.4, I get the following error:
Traceback (most recent call last):
File "test.py", line 5, in <module>
fs.oauth_desktop_login()
File "familysearch/authentication.py", line 71, in oauth_desktop_login
self.oauth_code_login(qs)
File "familysearch/authentication.py", line 86, in oauth_code_login
"Accept": "application/json"}, nojson=True)
File "familysearch/__init__.py", line 164, in _request
data = data.encode('utf-8')
AttributeError: 'bytes' object has no attribute 'encode'
I'm closing #12 as a technical duplicate, but the point still stands..
Now, we need to keep the documentation in one, consistent place. That would either be the Wiki, or GH-Pages. I was slightly leaning towards the wiki, as anybody could edit it quickly, but the description references the GH-Pages URI, which would eventually be going to PyPI. Of course, we could end up just referencing the wiki in the GH-Pages..... Ack, so many choices!
The big thing is we need to explain the layout of the SDK, but not delve too much into how FamilySearch itself works (which is already explained on FamilySearch's developer page), but we can definitely link to it.
I've come to realize, I have a distinct lack of debugging information support in the SDK. However, I want to find happy levels of debugging; I don't want to end up utterly spamming the prompt window, yet I don't want to leave something vital out.
What came to mind, so far:
class FamilySearch(...):
def init(..., debug=None)
def _request(...)
...
if debug is not None:
print(method, url)
...
def _fs2py(...debug=None)
if debug is not None:
print(headers["status"], headers["message")
Something like that, anyway...
Some of the function names are rather inconsistent. For example, the ancestry()
function vs. the read_person()
. Since the SDK is not hard-coded into any apps I know of, this one is a bit more high-priority.
Also, this also includes finding functions that do the exact same thing, and removing the duplicates.
As far as I can tell, the way it's currently set up, it handles 200 and 304 fine. But something like 429, it crashes on. (This may need to wait until #1 is finished, though.)
Rigth now, unauthenticated_login()
requires you to manually put in the (I believe) external IP address of the user.
It's a minor thing, but it's a terminology change that FS did a year or two "ish" ago...
When I new up a FamilySearch object, I've noticed that it makes a lot of calls. Can we defer these until we need them?
For example:
https://sandbox.familysearch.org/.well-known/collection
https://sandbox.familysearch.org/platform/collections
https://sandbox.familysearch.org/platform/collections/tree
https://sandbox.familysearch.org/platform/collections/records
When trying to log in with Python 2.7 (with 3233262 applied), I get urllib2.HTTPError: HTTP Error 400: Bad Request
. This doesn't happen when running the same code with 3.4.
from familysearch import FamilySearch
fs = FamilySearch(user_agent, app_key, base='https://sandbox.familysearch.org')
fs.unauthenticated_login(ip)
params = {
'givenName': 'John',
'surname': 'Doe',
'fatherGivenName': 'John',
'fatherSurname': 'Doe',
}
headers = {
'Accept': 'application/x-gedcomx-atom+json'
}
q = ' '.join(['%s:%s' % (key, val) for key, val in params.items()])
fs.get(fs.person_search(q=q), headers=headers)
As of right now, the only "default" methods we can use are GET
and POST
.
I've found a "backdoor" to creating additional method (as seen in init.FamilySearch._head), but I need to bugfix it.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.