KartikTalwar / Duolingo

Unofficial Duolingo API Written in Python
MIT License
825 stars 128 forks source link

Get user data without authentication and initial baseURL configuration #78

Closed igorskh closed 4 years ago

igorskh commented 4 years ago

Firstly, I found out that there is an endpoint to get user data without authentication.

Additionally, this PR adds initial baseURL configuration. It can be useful, since there are different baseURLs for different platforms (iOS, Android, Web) as well as different functionalities, such as leaderboards, therefore some systematic way of storing URLs is necessary.

Lastly, login in on instance initialisation might be not preferable option, the same JWT can be used, especially if many requests are done with thee same script. That is what for official Duolingo apps do.

This PR shouldn't break current implementation, this should be with backward compatibility by now.

SpangleLabs commented 4 years ago

This looks pretty nice! I do like making it possible to switch through accounts with one object, though I'm a little concerned whether it leaves an issue with internal state, like the self.leader_data and self.voice_url_dict? And I'm going to have to check the user data format returned by those endpoints, I thought there was different data you could get back

sorry about the failing travis tests, environment variables aren't set there yet. I've sent an email to kartik asking to get those set

igorskh commented 4 years ago

Data is the same, but method without authentication returns less data, and also it return an array. I've created an OpenAPI spec for some methods, you can have a look at the return format.

igorskh commented 4 years ago

though I'm a little concerned whether it leaves an issue with internal state, like the self.leader_data and self.voice_url_dict?

This is a good question. Is it actually necessary to store data inside the instance? Creating a separate API connection instance for each user would be too much, including authentication process. Because we can still get a lot of data by username/userID of another user with single authenticated session.

SpangleLabs commented 4 years ago

though I'm a little concerned whether it leaves an issue with internal state, like the self.leader_data and self.voice_url_dict?

This is a good question. Is it actually necessary to store data inside the instance? Creating a separate API connection instance for each user would be too much, including authentication process. Because we can still get a lot of data by username/userID of another user with single authenticated session.

The voice_url_dict cache is certainly needed, as it takes about a minute to fill it the first time the get_audio_url() method is used, and can then use it for all future calls.

I'm not sure if leader_data is really used though.

But you can just set them both to None again in the login method, whichever login method ends up staying

piggydoughnut commented 4 years ago

Hi there!

Please correct me if I am wrong. Is this the url which is supposed to be authentication free?

https://duolingo.com/users/%s" % self.username #

coz I just tried it and it throws 401s at me, unless I have a jwt cookie from Duolingo in my browser.

igorskh commented 4 years ago

Hi there!

Please correct me if I am wrong. Is this the url which is supposed to be authentication free?

https://duolingo.com/users/%s" % self.username #

coz I just tried it and it throws 401s at me, unless I have a jwt cookie from Duolingo in my browser.

Hi Daria,

No, the URL should be:

https://www.duolingo.com/2017-06-30/users?username=%s % self.username

Checked just now, works fine without a JWT token.

> GET /2017-06-30/users?username=igorskh HTTP/2
> Host: www.duolingo.com
> User-Agent: insomnia/7.1.1
> Accept: */*
igorskh commented 4 years ago

I don't think we can get it merge. Maybe we should close this and try to get in smaller pieces.