Skip to content

Commit

Permalink
Merge pull request #7 from sgaynetdinov/use_post
Browse files Browse the repository at this point in the history
Send payload use POST method
  • Loading branch information
sgaynetdinov authored Dec 3, 2018
2 parents ff57f72 + b706297 commit d50c5ef
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 23 deletions.
3 changes: 2 additions & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pytest
isort
isort
pytest-mock
31 changes: 31 additions & 0 deletions tests/test_fetch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import io

import vk
from vk.fetch import Session


def test_url_open(mocker):
mocker.patch('vk.fetch.urlopen')

mock_json = mocker.patch('json.load')
mock_json.return_value = {'response': [{
"id": 1,
"first_name": "Павел",
"last_name": "Дуров",
"domain": "durov",
}]}

api = vk.Api('TOKEN')
user = api.get_user('durov')

assert user.domain == 'durov'


def test_upload_photo():
file_obj = io.BytesIO(b'Python developer and blogger.')
data, boundary = Session()._file_upload(file_obj)

assert b'Content-Disposition: file; name="photo"; filename="photo.jpg"' in data
assert b'Content-Type: application/octet-stream' in data
assert b'Python developer and blogger.' in data
assert boundary.encode() in data
54 changes: 36 additions & 18 deletions vk/fetch.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,23 @@
# coding=utf-8
import io
import json
import uuid

from .error import VKError, VKParseJsonError

try:
from urllib.parse import urlencode
from urllib.request import urlopen
from urllib.request import urlopen, Request
except ImportError:
from urllib import urlencode, urlopen



class Session(object):
def __init__(self, access_token=None, lang='ru', version_api='5.63'):
self.access_token = access_token
self.lang = lang
self.version_api = version_api

@staticmethod
def url_open(url, data=None):
data = data or {}
res = urlopen(url, data=data)

try:
data_json = json.loads(res.read())
except ValueError:
raise VKParseJsonError

return data_json

def fetch(self, method_name, **params):
url = "https://api.vk.com/method/{method_name}".format(method_name=method_name)
params['v'] = self.version_api
Expand All @@ -40,9 +29,13 @@ def fetch(self, method_name, **params):

params = {key: value for key, value in params.items() if value is not None}

url = url + "?" + urlencode(params)
request = Request(url, data=urlencode(params).encode())
res = urlopen(request)

data_json = self.url_open(url)
try:
data_json = json.load(res)
except ValueError:
raise VKParseJsonError

if 'error' in data_json:
error = data_json['error']
Expand Down Expand Up @@ -80,8 +73,19 @@ def fetch_items(self, method_name, constructor_from_json, count, **params):

offset += count

def fetch_post(self, url, **kwargs):
return self.url_open(url, data=kwargs)
def fetch_photo(self, url, file_obj):
data, boundary = self._file_upload(file_obj)

req = Request(url, data=data)
req.add_header('Content-type', 'multipart/form-data; boundary={0}'.format(boundary))
req.add_header('Content-length', len(data))

res = urlopen(req)

try:
return json.load(res)
except ValueError:
raise VKParseJsonError

def _convert_list2str(self, fields):
"""
Expand All @@ -91,3 +95,17 @@ def _convert_list2str(self, fields):
if isinstance(fields, tuple) or isinstance(fields, list):
return ','.join(fields)
return fields

def _file_upload(self, file_obj):
boundary = uuid.uuid4().hex

buffer = io.BytesIO()
buffer.write('--{0}\r\n'.format(boundary).encode())
buffer.write('Content-Disposition: file; name="photo"; filename="photo.jpg"\r\n'.encode())
buffer.write('Content-Type: application/octet-stream\r\n'.encode())
buffer.write(b'\r\n')
buffer.write(file_obj.read())
buffer.write(b'\r\n')
buffer.write('--{0}--\r\n'.format(boundary).encode())

return buffer.getvalue(), boundary
3 changes: 1 addition & 2 deletions vk/groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,7 @@ def get_walls_count(self):

def set_cover_photo(self, file_like, width, height):
upload_url = Photo._get_owner_cover_photo_upload_server(self._session, self.id, crop_x2=width, crop_y2=height)
files = {'photo': file_like}
response_json = self._session.fetch_post(upload_url, files=files)
response_json = self._session.fetch_photo(upload_url, file_like)

Photo._save_owner_cover_photo(self._session, response_json['hash'], response_json['photo'])

Expand Down
4 changes: 2 additions & 2 deletions vk/photos.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def _upload_wall_photos_for_group(session, group_id, image_files):

attachments = []
for image_fd in image_files:
response_json = session.fetch_post(upload_url, files={'photo': image_fd})
response_json = session.fetch_photo(upload_url, image_fd)
photo, server, _hash = response_json['photo'], response_json['server'], response_json['hash']
photo_id, owner_id = Photo._get_save_wall_photo(session, photo, server, _hash, group_id=group_id)
attachments.append("photo{0}_{1}".format(owner_id, photo_id))
Expand Down Expand Up @@ -110,7 +110,7 @@ def _upload_messages_photos_for_group(session, user_id, image_files):

attachments = []
for image_fd in image_files:
response_json = session.fetch_post(upload_url, files={'photo': image_fd})
response_json = session.fetch_photo(upload_url, image_fd)
photo, server, _hash = response_json['photo'], response_json['server'], response_json['hash']
photo_id, owner_id = Photo._get_save_messages_photo(session, photo, server, _hash)
attachments.append("photo{0}_{1}".format(owner_id, photo_id))
Expand Down

0 comments on commit d50c5ef

Please sign in to comment.