Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/cs102.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python 3.8.6
- name: Set up Python 3.9
uses: actions/setup-python@v2
with:
python-version: '3.8.6'
python-version: '3.9'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand Down
3 changes: 3 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions .idea/Waycoolers.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/inspectionProfiles/profiles_settings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 20 additions & 1 deletion homework05/research/age.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,23 @@ def age_predict(user_id: int) -> tp.Optional[float]:
:param user_id: Идентификатор пользователя.
:return: Медианный возраст пользователя.
"""
pass
list_friends = get_friends(user_id=user_id, fields=["bdate"])
ret = []
year = dt.datetime.now().year
month = dt.datetime.now().month
day = dt.datetime.now().day
for i in list_friends.items:
if "bdate" in i: # type: ignore
date = list(map(int, i["bdate"].split("."))) # type: ignore
if len(date) != 3:
continue
age = (
-date[2]
+ year
- (1 if (date[1] < month or (date[1] == month and day < date[0])) else 0)
)
ret.append(age)
if not len(ret):
return None

return statistics.median(ret)
9 changes: 7 additions & 2 deletions homework05/research/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import matplotlib.pyplot as plt
import networkx as nx
import pandas as pd

from vkapi.friends import get_friends, get_mutual


Expand All @@ -18,7 +17,13 @@ def ego_network(
:param user_id: Идентификатор пользователя, для которого строится граф друзей.
:param friends: Идентификаторы друзей, между которыми устанавливаются связи.
"""
pass
ret = []
mutual_friends = get_mutual(source_uid=user_id, target_uids=friends)
for person in mutual_friends:
if person is not None:
for j in person["common_friends"]: # type: ignore
ret.append((person["id"], j)) # type: ignore
return ret


def plot_ego_network(net: tp.List[tp.Tuple[int, int]]) -> None:
Expand Down
1 change: 0 additions & 1 deletion homework05/research/topic_modeling.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from gensim.corpora import Dictionary
from textacy import preprocessing
from tqdm import tqdm

from vkapi.wall import get_wall_execute


Expand Down
1 change: 0 additions & 1 deletion homework05/tests/tests_api/test_friends.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import unittest

import responses

from vkapi.friends import FriendsResponse, get_friends, get_mutual


Expand Down
8 changes: 6 additions & 2 deletions homework05/tests/tests_api/test_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@

import httpretty
import responses
from requests.exceptions import ConnectionError, HTTPError, ReadTimeout, RetryError

from requests.exceptions import ( # mypy: ignore-errors
ConnectionError,
HTTPError,
ReadTimeout,
RetryError,
)
from vkapi.session import Session


Expand Down
1 change: 0 additions & 1 deletion homework05/tests/tests_api/test_wall.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

import pandas as pd
import responses

from vkapi.wall import get_wall_execute


Expand Down
1 change: 0 additions & 1 deletion homework05/tests/tests_research/test_age.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import unittest

import responses

from research.age import age_predict


Expand Down
1 change: 0 additions & 1 deletion homework05/tests/tests_research/test_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import unittest

import responses

from research.network import ego_network


Expand Down
2 changes: 1 addition & 1 deletion homework05/vkapi/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

VK_CONFIG = {
"domain": "https://api.vk.com/method",
"access_token": "",
"access_token": "https://oauth.vk.com/blank.html#access_token=vk1.a.MQmRX7cHcqF_La-YErIO8ZhRfpsltLJS2bOj0TYaYgULRj6a79mRo685eQUe0hTZNrnZYuufUHvCqsg09jTvbXSYddaWawXpf5RjtFi0GU7lPCTmfOeqlo4xuqZfb-w-hX4zOfulVhDzOqB4ttzSNBY1aM5FPSdA-AT-EY3_7ykzjhPIfUtZYAQ5VcnysL5q&expires_in=86400&user_id=203091488",
"version": "5.126",
}
33 changes: 31 additions & 2 deletions homework05/vkapi/friends.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,16 @@ def get_friends(
:param fields: Список полей, которые нужно получить для каждого пользователя.
:return: Список идентификаторов друзей пользователя или список пользователей.
"""
pass
list_of_friends = session.get(
"friends.get",
user_id=user_id,
count=count,
offset=offset,
fields=fields,
version=config.VK_CONFIG["version"],
access_token=config.VK_CONFIG,
).json()["response"]
return FriendsResponse(count=list_of_friends["count"], items=list_of_friends["items"])


class MutualFriends(tp.TypedDict):
Expand Down Expand Up @@ -57,4 +66,24 @@ def get_mutual(
:param offset: Смещение, необходимое для выборки определенного подмножества общих друзей.
:param progress: Callback для отображения прогресса.
"""
pass
ret = []
ln = 1
if target_uids is not None:
ln = (int(len(target_uids)) + 99) // 100

for i in range(0, ln):
ret += session.get(
"friends.getMutual",
source_uid=source_uid,
target_uid=target_uid,
target_uids=target_uids,
order=order,
count=count,
offset=i * 100,
version=config.VK_CONFIG["version"],
access_token=config.VK_CONFIG["access_token"],
).json()["response"]
if i % 3 == 2:
time.sleep(1)

return ret
32 changes: 26 additions & 6 deletions homework05/vkapi/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,35 @@ class Session:

def __init__(
self,
base_url: str,
base_url: str = "https://",
timeout: float = 5.0,
max_retries: int = 3,
backoff_factor: float = 0.3,
) -> None:
pass
self.current_session = requests.session()
retry_strategy = Retry(
total=max_retries,
backoff_factor=backoff_factor,
status_forcelist=[429, 500, 502, 503, 504],
method_whitelist=["HEAD", "GET", "OPTIONS"],
)
adapter = HTTPAdapter(
max_retries=retry_strategy
) # повторяет попытку соединения в случае неудачи
self.current_session.mount(
base_url, adapter=adapter
) # регистрируем экземпляр адаптера в префиксе
self.base_url = base_url
self.timeout = timeout

def get(self, url: str, *args: tp.Any, **kwargs: tp.Any) -> requests.Response:
pass
def get(
self, url: str, *args: tp.Any, **kwargs: tp.Any
) -> requests.Response: # запрос содержимого с определенного ресурса
return self.current_session.get(
self.base_url + "/" + url, params=kwargs, timeout=self.timeout
)

def post(self, url: str, *args: tp.Any, **kwargs: tp.Any) -> requests.Response:
pass
def post(
self, url: str, *args: tp.Any, **kwargs: tp.Any
) -> requests.Response: # передача пользовательских данных заданному ресурсу
return self.current_session.post(self.base_url + "/" + url, data=kwargs)
43 changes: 40 additions & 3 deletions homework05/vkapi/wall.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

import pandas as pd
from pandas import json_normalize

from vkapi import config, session
from vkapi.exceptions import APIError

Expand All @@ -20,7 +19,7 @@ def get_posts_2500(
extended: int = 0,
fields: tp.Optional[tp.List[str]] = None,
) -> tp.Dict[str, tp.Any]:
pass
return {}


def get_wall_execute(
Expand Down Expand Up @@ -49,4 +48,42 @@ def get_wall_execute(
:param fields: Список дополнительных полей для профилей и сообществ, которые необходимо вернуть.
:param progress: Callback для отображения прогресса.
"""
pass
code = f"""
if({count} < 100):
retVal = API.wall.get(
{{
"owner_id":{owner_id},
"domain":{domain},
"offset":{offset},
"count":"{count}",
"filter":{filter},
"extended":{extended},
"fields": {fields}
"v":{config.VK_CONFIG["version"]}
}}
)
else :
retVal =[]
for i in range(0, Math.floor({count} / 100) - 1, 100):
answer=API.wall.get({{
"owner_id": str = {owner_id},
"domain": str = {domain},
"offset": int = {offset} + i * 100,
"count": int = 100,
"filter": str = {filter},
"extended": str = {extended},
"fields": str = {fields},
"v":{config.VK_CONFIG["version"]}
}})
retVal.push(...answer)
return retVal
"""
time.sleep(2)
response = session.post(
"execute",
code=code,
access_token=config.VK_CONFIG["access_token"],
version=config.VK_CONFIG["version"],
).json()["response"]["items"]

return json_normalize(response)
14 changes: 14 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,17 @@ isort==5.4.2
mypy==0.782
pylint==2.6.0
pytest==6.0.1

setuptools~=49.2.1
pandas~=1.5.3
responses~=0.22.0
vkapi~=1.1
httpretty~=1.1.4
requests~=2.28.2
community~=1.0.0b1
matplotlib~=3.7.0
networkx~=3.0
gensim~=4.3.0
pyLDAvis~=3.4.0
textacy~=0.12.0
tqdm~=4.64.1