interpals-api 2.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- interpals_api/__init__.py +161 -0
- interpals_api/api.py +655 -0
- interpals_api/cookie.py +48 -0
- interpals_api/errors.py +65 -0
- interpals_api/parsers/__init__.py +3 -0
- interpals_api/parsers/chat_parser.py +132 -0
- interpals_api/parsers/friends_parser.py +53 -0
- interpals_api/parsers/pictures_parser.py +91 -0
- interpals_api/parsers/profile_parser.py +124 -0
- interpals_api/session.py +243 -0
- interpals_api/utils.py +23 -0
- interpals_api-2.3.0.dist-info/METADATA +196 -0
- interpals_api-2.3.0.dist-info/RECORD +15 -0
- interpals_api-2.3.0.dist-info/WHEEL +5 -0
- interpals_api-2.3.0.dist-info/top_level.txt +1 -0
interpals_api/session.py
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Session instance keeps the necessary cookie parameters so API calls work
|
|
3
|
+
correctly. Session can be created from raw cookie data or emulate the login
|
|
4
|
+
process using username and password.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
from urllib.parse import urljoin
|
|
9
|
+
from typing import Dict, TextIO, Self
|
|
10
|
+
|
|
11
|
+
import requests
|
|
12
|
+
import aiohttp
|
|
13
|
+
|
|
14
|
+
from .utils import find_csrf_token
|
|
15
|
+
from .errors import (NoCSRFTokenError, WrongUsernameOrPasswordError,
|
|
16
|
+
SessionError, TooManyLoginAttemptsError)
|
|
17
|
+
from .cookie import Cookie
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class Session:
|
|
21
|
+
"""
|
|
22
|
+
Synchronous session class.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(self, username: str, interpals_sessid: str,
|
|
26
|
+
csrf_cookieV2: str):
|
|
27
|
+
"""
|
|
28
|
+
Create a new session instance from the necessary cookie data:
|
|
29
|
+
`username`, `interpals_sessid`, `csrf_cookieV2`.
|
|
30
|
+
"""
|
|
31
|
+
self.username = username
|
|
32
|
+
"""
|
|
33
|
+
`username`
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
self.interpals_sessid = interpals_sessid
|
|
37
|
+
"""
|
|
38
|
+
`interpals_sessid` cookie
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
self.csrf_cookieV2 = csrf_cookieV2
|
|
42
|
+
"""
|
|
43
|
+
`csrf_cookieV2` cookie
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
def __repr__(self) -> str:
|
|
47
|
+
return f"Session(username={self.username}, " \
|
|
48
|
+
f"interpals_sessid={self.interpals_sessid}, " \
|
|
49
|
+
f"csrf_cookieV2={self.csrf_cookieV2})"
|
|
50
|
+
|
|
51
|
+
def cookie(self) -> Dict[str, str]:
|
|
52
|
+
"""
|
|
53
|
+
Get cookie data as a dictionary.
|
|
54
|
+
"""
|
|
55
|
+
return {
|
|
56
|
+
'interpals_sessid': self.interpals_sessid,
|
|
57
|
+
'csrf_cookieV2': self.csrf_cookieV2
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
def dump(self, f: TextIO):
|
|
61
|
+
"""
|
|
62
|
+
Dump session data into a file-like object.
|
|
63
|
+
"""
|
|
64
|
+
kwargs = {
|
|
65
|
+
'username': self.username,
|
|
66
|
+
'interpals_sessid': self.interpals_sessid,
|
|
67
|
+
'csrf_cookieV2': self.csrf_cookieV2,
|
|
68
|
+
}
|
|
69
|
+
json.dump(kwargs, f)
|
|
70
|
+
|
|
71
|
+
@classmethod
|
|
72
|
+
def load(cls, f: TextIO) -> Self:
|
|
73
|
+
"""
|
|
74
|
+
Load session instance from a file-like object.
|
|
75
|
+
"""
|
|
76
|
+
kwargs = json.load(f)
|
|
77
|
+
return cls(**kwargs)
|
|
78
|
+
|
|
79
|
+
@classmethod
|
|
80
|
+
def login(cls, username: str, password: str) -> Self:
|
|
81
|
+
"""
|
|
82
|
+
Emulate the login process. It will return a session instance on success.
|
|
83
|
+
"""
|
|
84
|
+
# Cookie object
|
|
85
|
+
cookie = Cookie()
|
|
86
|
+
|
|
87
|
+
# Request initial page
|
|
88
|
+
csrf_token = cls._request_initial_page(cookie)
|
|
89
|
+
|
|
90
|
+
# Request login endpoint
|
|
91
|
+
cls._request_login_endpoint(username, password, cookie, csrf_token)
|
|
92
|
+
|
|
93
|
+
# Create and return session instance
|
|
94
|
+
return cls(username=username,
|
|
95
|
+
interpals_sessid=cookie['interpals_sessid'],
|
|
96
|
+
csrf_cookieV2=cookie['csrf_cookieV2'])
|
|
97
|
+
|
|
98
|
+
@classmethod
|
|
99
|
+
def _request_initial_page(cls, cookie):
|
|
100
|
+
with requests.get("https://www.interpals.net/") as resp:
|
|
101
|
+
# Get initial cookie
|
|
102
|
+
set_cookie = Cookie.from_response_headers(resp.headers)
|
|
103
|
+
cookie.update(set_cookie)
|
|
104
|
+
|
|
105
|
+
# Extract CSRF token from the HTML
|
|
106
|
+
csrf_token = find_csrf_token(resp.text)
|
|
107
|
+
|
|
108
|
+
# Raise error if no token found
|
|
109
|
+
if csrf_token is None:
|
|
110
|
+
raise NoCSRFTokenError()
|
|
111
|
+
|
|
112
|
+
return csrf_token
|
|
113
|
+
|
|
114
|
+
@classmethod
|
|
115
|
+
def _request_login_endpoint(cls, username, password, cookie, csrf_token):
|
|
116
|
+
headers = {
|
|
117
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
118
|
+
'Cookie': cookie.as_string(),
|
|
119
|
+
'Referer': 'https://www.interpals.net/',
|
|
120
|
+
}
|
|
121
|
+
data = {
|
|
122
|
+
'username': username,
|
|
123
|
+
'password': password,
|
|
124
|
+
'csrf_token': csrf_token
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
# Request login entry point
|
|
128
|
+
with requests.post("https://www.interpals.net/app/auth/login",
|
|
129
|
+
data=data, headers=headers,
|
|
130
|
+
allow_redirects=False) as resp:
|
|
131
|
+
# Update cookie
|
|
132
|
+
set_cookie = Cookie.from_response_headers(resp.headers)
|
|
133
|
+
cookie.update(set_cookie)
|
|
134
|
+
|
|
135
|
+
# Check status
|
|
136
|
+
if resp.status_code == 200:
|
|
137
|
+
raise WrongUsernameOrPasswordError()
|
|
138
|
+
elif resp.status_code == 302:
|
|
139
|
+
location = resp.headers['Location']
|
|
140
|
+
else:
|
|
141
|
+
raise SessionError(
|
|
142
|
+
f"Unknown response status while login: {resp.status_code}"
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
# Request the location to check success
|
|
146
|
+
url = urljoin("https://www.interpals.net", location)
|
|
147
|
+
headers = {
|
|
148
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
149
|
+
'Cookie': cookie.as_string(),
|
|
150
|
+
}
|
|
151
|
+
with requests.get(url, headers=headers) as resp:
|
|
152
|
+
if "Too many unsuccessful login attempts." in resp.text:
|
|
153
|
+
raise TooManyLoginAttemptsError()
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
class SessionAsync(Session):
|
|
157
|
+
"""
|
|
158
|
+
Synchronous session class. It is inherited from [Session](#Session).
|
|
159
|
+
"""
|
|
160
|
+
|
|
161
|
+
@classmethod
|
|
162
|
+
async def login(cls, username: str, password: str) -> Self:
|
|
163
|
+
"""
|
|
164
|
+
Emulate the login process. It will return a session instance on success.
|
|
165
|
+
"""
|
|
166
|
+
# Cookie object
|
|
167
|
+
cookie = Cookie()
|
|
168
|
+
|
|
169
|
+
# Request initial page
|
|
170
|
+
csrf_token = await cls._request_initial_page(cookie)
|
|
171
|
+
|
|
172
|
+
# Request login endpoint
|
|
173
|
+
await cls._request_login_endpoint(
|
|
174
|
+
username, password, cookie, csrf_token
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
# Create and return session instance
|
|
178
|
+
return cls(username=username,
|
|
179
|
+
interpals_sessid=cookie['interpals_sessid'],
|
|
180
|
+
csrf_cookieV2=cookie['csrf_cookieV2'])
|
|
181
|
+
|
|
182
|
+
@classmethod
|
|
183
|
+
async def _request_initial_page(cls, cookie):
|
|
184
|
+
async with aiohttp.ClientSession() as session:
|
|
185
|
+
async with session.get("https://www.interpals.net/") as resp:
|
|
186
|
+
# Get initial cookie
|
|
187
|
+
set_cookie = Cookie.from_response_headers(resp.headers)
|
|
188
|
+
cookie.update(set_cookie)
|
|
189
|
+
|
|
190
|
+
# Extract CSRF token from the HTML
|
|
191
|
+
text = await resp.text()
|
|
192
|
+
csrf_token = find_csrf_token(text)
|
|
193
|
+
|
|
194
|
+
# Raise error if no token found
|
|
195
|
+
if csrf_token is None:
|
|
196
|
+
raise NoCSRFTokenError()
|
|
197
|
+
|
|
198
|
+
return csrf_token
|
|
199
|
+
|
|
200
|
+
@classmethod
|
|
201
|
+
async def _request_login_endpoint(cls, username, password, cookie,
|
|
202
|
+
csrf_token):
|
|
203
|
+
headers = {
|
|
204
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
205
|
+
'Cookie': cookie.as_string(),
|
|
206
|
+
'Referer': 'https://www.interpals.net/',
|
|
207
|
+
}
|
|
208
|
+
data = {
|
|
209
|
+
'username': username,
|
|
210
|
+
'password': password,
|
|
211
|
+
'csrf_token': csrf_token
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
# Request login entry point
|
|
215
|
+
async with aiohttp.ClientSession() as session:
|
|
216
|
+
async with session.post("https://www.interpals.net/app/auth/login",
|
|
217
|
+
data=data, headers=headers,
|
|
218
|
+
allow_redirects=False) as resp:
|
|
219
|
+
# Update cookie
|
|
220
|
+
set_cookie = Cookie.from_response_headers(resp.headers)
|
|
221
|
+
cookie.update(set_cookie)
|
|
222
|
+
|
|
223
|
+
# Check status
|
|
224
|
+
if resp.status == 200:
|
|
225
|
+
raise WrongUsernameOrPasswordError()
|
|
226
|
+
elif resp.status == 302:
|
|
227
|
+
location = resp.headers['Location']
|
|
228
|
+
else:
|
|
229
|
+
raise SessionError(
|
|
230
|
+
f"Unknown response status while login: {resp.status}"
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
# Request the location to check success
|
|
234
|
+
url = urljoin("https://www.interpals.net", location)
|
|
235
|
+
headers = {
|
|
236
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
237
|
+
'Cookie': cookie.as_string(),
|
|
238
|
+
}
|
|
239
|
+
async with aiohttp.ClientSession() as session:
|
|
240
|
+
async with session.get(url, headers=headers) as resp:
|
|
241
|
+
text = await resp.text()
|
|
242
|
+
if "Too many unsuccessful login attempts." in text:
|
|
243
|
+
raise TooManyLoginAttemptsError()
|
interpals_api/utils.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Useful functions.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import re
|
|
6
|
+
from typing import Optional
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
re_csfr_token = re.compile(r'<meta name="csrf_token" content="(.*?)"')
|
|
10
|
+
"""
|
|
11
|
+
Regex for CSRF token meta tag, it selects its value.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def find_csrf_token(html: str) -> Optional[str]:
|
|
16
|
+
"""
|
|
17
|
+
Extract the content of CSRF token in the meta tag from HTML.
|
|
18
|
+
"""
|
|
19
|
+
match = re_csfr_token.search(html)
|
|
20
|
+
if match is not None:
|
|
21
|
+
return match.group(1)
|
|
22
|
+
else:
|
|
23
|
+
return None
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: interpals-api
|
|
3
|
+
Version: 2.3.0
|
|
4
|
+
Summary: Unofficial Python API for Interpals.net.
|
|
5
|
+
Home-page: https://github.com/fomalhaut88/interpals-api
|
|
6
|
+
Author: Alexander Khlebushchev
|
|
7
|
+
License: MIT
|
|
8
|
+
Project-URL: Homepage, https://pypi.org/project/interpals-api/
|
|
9
|
+
Project-URL: Documentation, https://fomalhaut88.github.io/interpals-api/
|
|
10
|
+
Project-URL: Source, https://github.com/fomalhaut88/interpals-api
|
|
11
|
+
Project-URL: Issues, https://github.com/fomalhaut88/interpals-api/issues
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
15
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Operating System :: OS Independent
|
|
23
|
+
Requires-Python: >=3.12
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
Requires-Dist: aiohttp>=3.12
|
|
26
|
+
Requires-Dist: requests>=2.32
|
|
27
|
+
Requires-Dist: lxml>=6.0
|
|
28
|
+
Requires-Dist: beautifulsoup4>=4.13
|
|
29
|
+
Dynamic: author
|
|
30
|
+
Dynamic: classifier
|
|
31
|
+
Dynamic: description
|
|
32
|
+
Dynamic: description-content-type
|
|
33
|
+
Dynamic: home-page
|
|
34
|
+
Dynamic: license
|
|
35
|
+
Dynamic: project-url
|
|
36
|
+
Dynamic: requires-dist
|
|
37
|
+
Dynamic: requires-python
|
|
38
|
+
Dynamic: summary
|
|
39
|
+
|
|
40
|
+
# interpals-api
|
|
41
|
+
|
|
42
|
+
This Python library provides a simple HTTP API for working with the website https://interpals.net/. It includes:
|
|
43
|
+
|
|
44
|
+
* retrieving data by user identifier
|
|
45
|
+
* listing visitors
|
|
46
|
+
* searching for users by criterions
|
|
47
|
+
* viewing and sending messages, deleting chats
|
|
48
|
+
* listing, adding and removing friends
|
|
49
|
+
* listing albums and pictures
|
|
50
|
+
|
|
51
|
+
## Installation
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
pip install interpals-api
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Basic example
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
from interpals_api import Session, Api
|
|
61
|
+
|
|
62
|
+
session = Session.login('yourusername', 'yourpassword')
|
|
63
|
+
api = Api(session)
|
|
64
|
+
|
|
65
|
+
user_info = api.profile('someuser')
|
|
66
|
+
print(user_info)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Since version `2.1` it supports asynchronous calls for each api method. Below there is a brief asynchonous example:
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from interpals_api import SessionAsync, ApiAsync
|
|
73
|
+
|
|
74
|
+
session = await SessionAsync.login('yourusername', 'yourpassword')
|
|
75
|
+
api = ApiAsync(session)
|
|
76
|
+
|
|
77
|
+
user_info = await api.profile('someuser')
|
|
78
|
+
print(user_info)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Other examples
|
|
82
|
+
|
|
83
|
+
Basic example to retrieve user info:
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from interpals_api import Session, Api
|
|
87
|
+
|
|
88
|
+
session = Session.login('yourusername', 'yourpassword')
|
|
89
|
+
api = Api(session)
|
|
90
|
+
|
|
91
|
+
# This gives info of the user with the link: https://www.interpals.net/someuser
|
|
92
|
+
user_info = api.profile('someuser')
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Dump and load session object:
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
from interpals_api import Session, Api
|
|
99
|
+
|
|
100
|
+
session = Session.login('yourusername', 'yourpassword')
|
|
101
|
+
|
|
102
|
+
# Save session into a file
|
|
103
|
+
with open('session.json', 'w') as f:
|
|
104
|
+
session.dump(f)
|
|
105
|
+
|
|
106
|
+
# Load session from the saved file
|
|
107
|
+
with open('session.json') as f:
|
|
108
|
+
session = Session.load(f)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Viewing and searching for users:
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
from interpals_api import Session, Api
|
|
115
|
+
|
|
116
|
+
session = Session.login('yourusername', 'yourpassword')
|
|
117
|
+
api = Api(session)
|
|
118
|
+
|
|
119
|
+
# Viewing a certain user
|
|
120
|
+
api.view('someuser')
|
|
121
|
+
|
|
122
|
+
# Showing the visitors of your profile
|
|
123
|
+
users = api.visitors()
|
|
124
|
+
print(users)
|
|
125
|
+
|
|
126
|
+
# Searching for users
|
|
127
|
+
options = {
|
|
128
|
+
'age1': '20',
|
|
129
|
+
'age2': '40',
|
|
130
|
+
'sex': ['male', 'female'],
|
|
131
|
+
'continents': ['AF', 'AS', 'EU', 'NA', 'OC', 'SA'],
|
|
132
|
+
'countries': ['US', 'CA', 'UK', 'RU'],
|
|
133
|
+
'keywords': 'travelling',
|
|
134
|
+
'online': True,
|
|
135
|
+
'cityName': 'London' # Or you can use 'city' with its direct code on the website (it's faster)
|
|
136
|
+
}
|
|
137
|
+
for user in api.search(options, limit=100, timeout=1.0):
|
|
138
|
+
print(user)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
To work with friends and pictures, it is necessary to use `uid` in methods:
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
from interpals_api import Session, Api
|
|
145
|
+
|
|
146
|
+
session = Session.login('yourusername', 'yourpassword')
|
|
147
|
+
api = Api(session)
|
|
148
|
+
|
|
149
|
+
uid = api.get_uid('someuser')
|
|
150
|
+
|
|
151
|
+
# Listing friends of the user 'someuser'
|
|
152
|
+
friends = api.friends(uid)
|
|
153
|
+
print(friends)
|
|
154
|
+
|
|
155
|
+
# Adding 'someuser' to friends
|
|
156
|
+
api.friend_add(uid)
|
|
157
|
+
|
|
158
|
+
# Removing 'someuser' from friends
|
|
159
|
+
api.friend_remove(uid)
|
|
160
|
+
|
|
161
|
+
# Listing pictures
|
|
162
|
+
albums = api.albums(uid)
|
|
163
|
+
for album in albums:
|
|
164
|
+
aid = album['aid']
|
|
165
|
+
pictures = api.pictures(uid, aid)
|
|
166
|
+
for picture in pictures:
|
|
167
|
+
print(picture['src'])
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Working with the chat is done through `thread_id`:
|
|
171
|
+
|
|
172
|
+
```python
|
|
173
|
+
from interpals_api import Session, Api
|
|
174
|
+
|
|
175
|
+
session = Session.login('yourusername', 'yourpassword')
|
|
176
|
+
api = Api(session)
|
|
177
|
+
|
|
178
|
+
uid = api.get_uid('someuser')
|
|
179
|
+
|
|
180
|
+
# Listing your chats
|
|
181
|
+
result = api.chat(count=9, offset=0)
|
|
182
|
+
print(result['chats'])
|
|
183
|
+
|
|
184
|
+
# Staring new chat (getting thread_id)
|
|
185
|
+
thread_id = api.get_thread_id(uid)
|
|
186
|
+
|
|
187
|
+
# Show chat messages
|
|
188
|
+
messages = api.chat_messages(thread_id)
|
|
189
|
+
print(messages)
|
|
190
|
+
|
|
191
|
+
# Send new message to the thread
|
|
192
|
+
api.chat_send(thread_id, "Hey! How are you?")
|
|
193
|
+
|
|
194
|
+
# Removing chat
|
|
195
|
+
api.chat_delete(thread_id)
|
|
196
|
+
```
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
interpals_api/__init__.py,sha256=1kK2H0Y0z-ogmm5_kWV40PZjM03yaDi2SBfTd21zo64,3526
|
|
2
|
+
interpals_api/api.py,sha256=KQ8RhMV1sQR_R7xlM5jr0ymgSUMItzRXfi9ZkCMHNRc,20286
|
|
3
|
+
interpals_api/cookie.py,sha256=qmgZNzBYPEkaBlRvBwEA0LYNoWiyQGEYLfzYF4VmcCU,1410
|
|
4
|
+
interpals_api/errors.py,sha256=8F8RwegyWM1ZY7w428PDxcCnyfkCSCUFHBKRNv20DVk,923
|
|
5
|
+
interpals_api/session.py,sha256=Lp1yStrhMZaWYnMTH-gGIxnQZKyFKGeqUjOtIwzhQrw,8035
|
|
6
|
+
interpals_api/utils.py,sha256=0pHsn4prOE_OuiEBJ8xyd18z35UBOYdULn2Cho6guos,456
|
|
7
|
+
interpals_api/parsers/__init__.py,sha256=fUWisdZwAqbL9-YCL0fL1Z-Syhh8fsFSnkktPYpRJC0,46
|
|
8
|
+
interpals_api/parsers/chat_parser.py,sha256=8tnef9ZfhyDqSB3YSwhuQuqA5nCAAjET75zLV7ACIYA,4298
|
|
9
|
+
interpals_api/parsers/friends_parser.py,sha256=Sb_ZDma0ynF6BVdSvHT_YSRt8QsgzU9Z-MWW9osIP5E,1326
|
|
10
|
+
interpals_api/parsers/pictures_parser.py,sha256=OhG_pkVJjzAgMHeIT_UF_bFjI4hRyG0EU9EZJqpxURw,2716
|
|
11
|
+
interpals_api/parsers/profile_parser.py,sha256=ZrTgHPRmsx7Ws0VIn7jpBSwVZ-EDFfrK41g5YYd6uf0,3863
|
|
12
|
+
interpals_api-2.3.0.dist-info/METADATA,sha256=IqTA0Uq9_fS_2OxVHzJlhL5-PET-7YKPcemo9w-O9TM,4902
|
|
13
|
+
interpals_api-2.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
14
|
+
interpals_api-2.3.0.dist-info/top_level.txt,sha256=dXTmgNrsv3Y2J5bKnb3eWyjR8KnF4zRZqkomSAMP-Mo,14
|
|
15
|
+
interpals_api-2.3.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
interpals_api
|