From 53185ffd9eb5d4453e75c8039d8252dc94458b33 Mon Sep 17 00:00:00 2001 From: NotSoSuper Date: Sat, 22 Apr 2017 15:30:15 -0400 Subject: [PATCH 1/8] aio-imgurpython --- imgurpython/client.py | 424 +++++++++++++++++++++--------------------- requirements.txt | 2 +- 2 files changed, 212 insertions(+), 214 deletions(-) diff --git a/imgurpython/client.py b/imgurpython/client.py index 9c41ea6..6c894d4 100644 --- a/imgurpython/client.py +++ b/imgurpython/client.py @@ -1,5 +1,5 @@ import base64 -import requests +import aiohttp from .imgur.models.tag import Tag from .imgur.models.album import Album from .imgur.models.image import Image @@ -37,7 +37,7 @@ def get_refresh_token(self): def get_current_access_token(self): return self.current_access_token - def refresh(self): + async def refresh(self): data = { 'refresh_token': self.refresh_token, 'client_id': self.client_id, @@ -46,13 +46,11 @@ def refresh(self): } url = API_URL + 'oauth2/token' - - response = requests.post(url, data=data) - - if response.status_code != 200: - raise ImgurClientError('Error refreshing access token!', response.status_code) - - response_data = response.json() + with aiohttp.ClientSession() as session: + async with session.post(url, data=data) as r: + if response.status != 200: + raise ImgurClientError('Error refreshing access token!', response.status) + response_data = await r.json() self.current_access_token = response_data['access_token'] @@ -90,14 +88,14 @@ def set_user_auth(self, access_token, refresh_token): def get_client_id(self): return self.client_id - def get_credits(self): - return self.make_request('GET', 'credits', None, True) + async def get_credits(self): + return await self.make_request('GET', 'credits', None, True) def get_auth_url(self, response_type='pin'): return '%soauth2/authorize?client_id=%s&response_type=%s' % (API_URL, self.client_id, response_type) - def authorize(self, response, grant_type='pin'): - return self.make_request('POST', 'oauth2/token', { + async def authorize(self, response, grant_type='pin'): + return await self.make_request('POST', 'oauth2/token', { 'client_id': self.client_id, 'client_secret': self.client_secret, 'grant_type': grant_type, @@ -120,47 +118,47 @@ def prepare_headers(self, force_anon=False): return headers - def make_request(self, method, route, data=None, force_anon=False): - method = method.lower() - method_to_call = getattr(requests, method) - - header = self.prepare_headers(force_anon) - url = (MASHAPE_URL if self.mashape_key is not None else API_URL) + ('3/%s' % route if 'oauth2' not in route else route) - - if method in ('delete', 'get'): - response = method_to_call(url, headers=header, params=data, data=data) - else: - response = method_to_call(url, headers=header, data=data) - - if response.status_code == 403 and self.auth is not None: - self.auth.refresh() - header = self.prepare_headers() - if method in ('delete', 'get'): - response = method_to_call(url, headers=header, params=data, data=data) - else: - response = method_to_call(url, headers=header, data=data) - - self.credits = { - 'UserLimit': response.headers.get('X-RateLimit-UserLimit'), - 'UserRemaining': response.headers.get('X-RateLimit-UserRemaining'), - 'UserReset': response.headers.get('X-RateLimit-UserReset'), - 'ClientLimit': response.headers.get('X-RateLimit-ClientLimit'), - 'ClientRemaining': response.headers.get('X-RateLimit-ClientRemaining') - } - - # Rate-limit check - if response.status_code == 429: - raise ImgurClientRateLimitError() - + async def make_request(self, method, route, data=None, force_anon=False): try: - response_data = response.json() - except: - raise ImgurClientError('JSON decoding of response failed.') - - if 'data' in response_data and isinstance(response_data['data'], dict) and 'error' in response_data['data']: - raise ImgurClientError(response_data['data']['error'], response.status_code) - - return response_data['data'] if 'data' in response_data else response_data + method = method.lower() + session = aiohttp.ClientSession() + predicate = getattr(session, method) + + header = self.prepare_headers(force_anon) + url = (MASHAPE_URL if self.mashape_key is not None else API_URL) + ('3/%s' % route if 'oauth2' not in route else route) + + async with predicate(url, headers=header, params=data, data=data) as response: + if response.status == 403 and self.auth is not None: + await self.auth.refresh() + header = self.prepare_headers() + if method in ('delete', 'get'): + response = method_to_call(url, headers=header, params=data, data=data) + else: + response = method_to_call(url, headers=header, data=data) + + self.credits = { + 'UserLimit': response.headers.get('X-RateLimit-UserLimit'), + 'UserRemaining': response.headers.get('X-RateLimit-UserRemaining'), + 'UserReset': response.headers.get('X-RateLimit-UserReset'), + 'ClientLimit': response.headers.get('X-RateLimit-ClientLimit'), + 'ClientRemaining': response.headers.get('X-RateLimit-ClientRemaining') + } + + # Rate-limit check + if response.status == 429: + raise ImgurClientRateLimitError() + + try: + response_data = await response.json() + except: + raise ImgurClientError('JSON decoding of response failed.') + + if 'data' in response_data and isinstance(response_data['data'], dict) and 'error' in response_data['data']: + raise ImgurClientError(response_data['data']['error'], response.status) + + return response_data['data'] if 'data' in response_data.keys() else response_data + finally: + await session.close() def validate_user_context(self, username): if username == 'me' and self.auth is None: @@ -171,9 +169,9 @@ def logged_in(self): raise ImgurClientError('Must be logged in to complete request.') # Account-related endpoints - def get_account(self, username): + async def get_account(self, username): self.validate_user_context(username) - account_data = self.make_request('GET', 'account/%s' % username) + account_data = await self.make_request('GET', 'account/%s' % username) return Account( account_data['id'], @@ -184,27 +182,27 @@ def get_account(self, username): account_data['pro_expiration'], ) - def get_gallery_favorites(self, username, page=0): + async def get_gallery_favorites(self, username, page=0): self.validate_user_context(username) - gallery_favorites = self.make_request('GET', 'account/%s/gallery_favorites/%d' % (username, page)) + gallery_favorites = await self.make_request('GET', 'account/%s/gallery_favorites/%d' % (username, page)) return build_gallery_images_and_albums(gallery_favorites) - def get_account_favorites(self, username, page=0): + async def get_account_favorites(self, username, page=0): self.validate_user_context(username) - favorites = self.make_request('GET', 'account/%s/favorites/%d' % (username, page)) + favorites = await self.make_request('GET', 'account/%s/favorites/%d' % (username, page)) return build_gallery_images_and_albums(favorites) - def get_account_submissions(self, username, page=0): + async def get_account_submissions(self, username, page=0): self.validate_user_context(username) - submissions = self.make_request('GET', 'account/%s/submissions/%d' % (username, page)) + submissions = await self.make_request('GET', 'account/%s/submissions/%d' % (username, page)) return build_gallery_images_and_albums(submissions) - def get_account_settings(self, username): + async def get_account_settings(self, username): self.logged_in() - settings = self.make_request('GET', 'account/%s/settings' % username) + settings = await self.make_request('GET', 'account/%s/settings' % username) return AccountSettings( settings['email'], @@ -218,145 +216,145 @@ def get_account_settings(self, username): settings['blocked_users'] ) - def change_account_settings(self, username, fields): + async def change_account_settings(self, username, fields): post_data = {setting: fields[setting] for setting in set(self.allowed_account_fields).intersection(fields.keys())} - return self.make_request('POST', 'account/%s/settings' % username, post_data) + return await self.make_request('POST', 'account/%s/settings' % username, post_data) - def get_email_verification_status(self, username): + async def get_email_verification_status(self, username): self.logged_in() self.validate_user_context(username) - return self.make_request('GET', 'account/%s/verifyemail' % username) + return await self.make_request('GET', 'account/%s/verifyemail' % username) - def send_verification_email(self, username): + async def send_verification_email(self, username): self.logged_in() self.validate_user_context(username) - return self.make_request('POST', 'account/%s/verifyemail' % username) + return await self.make_request('POST', 'account/%s/verifyemail' % username) - def get_account_albums(self, username, page=0): + async def get_account_albums(self, username, page=0): self.validate_user_context(username) - albums = self.make_request('GET', 'account/%s/albums/%d' % (username, page)) + albums = await self.make_request('GET', 'account/%s/albums/%d' % (username, page)) return [Album(album) for album in albums] - def get_account_album_ids(self, username, page=0): + async def get_account_album_ids(self, username, page=0): self.validate_user_context(username) - return self.make_request('GET', 'account/%s/albums/ids/%d' % (username, page)) + return await self.make_request('GET', 'account/%s/albums/ids/%d' % (username, page)) - def get_account_album_count(self, username): + async def get_account_album_count(self, username): self.validate_user_context(username) - return self.make_request('GET', 'account/%s/albums/count' % username) + return await self.make_request('GET', 'account/%s/albums/count' % username) - def get_account_comments(self, username, sort='newest', page=0): + async def get_account_comments(self, username, sort='newest', page=0): self.validate_user_context(username) - comments = self.make_request('GET', 'account/%s/comments/%s/%s' % (username, sort, page)) + comments = await self.make_request('GET', 'account/%s/comments/%s/%s' % (username, sort, page)) return [Comment(comment) for comment in comments] - def get_account_comment_ids(self, username, sort='newest', page=0): + async def get_account_comment_ids(self, username, sort='newest', page=0): self.validate_user_context(username) - return self.make_request('GET', 'account/%s/comments/ids/%s/%s' % (username, sort, page)) + return await self.make_request('GET', 'account/%s/comments/ids/%s/%s' % (username, sort, page)) - def get_account_comment_count(self, username): + async def get_account_comment_count(self, username): self.validate_user_context(username) - return self.make_request('GET', 'account/%s/comments/count' % username) + return await self.make_request('GET', 'account/%s/comments/count' % username) - def get_account_images(self, username, page=0): + async def get_account_images(self, username, page=0): self.validate_user_context(username) - images = self.make_request('GET', 'account/%s/images/%d' % (username, page)) + images = await self.make_request('GET', 'account/%s/images/%d' % (username, page)) return [Image(image) for image in images] - def get_account_image_ids(self, username, page=0): + async def get_account_image_ids(self, username, page=0): self.validate_user_context(username) - return self.make_request('GET', 'account/%s/images/ids/%d' % (username, page)) + return await self.make_request('GET', 'account/%s/images/ids/%d' % (username, page)) - def get_account_images_count(self, username): + async def get_account_images_count(self, username): self.validate_user_context(username) - return self.make_request('GET', 'account/%s/images/count' % username) + return await self.make_request('GET', 'account/%s/images/count' % username) # Album-related endpoints - def get_album(self, album_id): - album = self.make_request('GET', 'album/%s' % album_id) + async def get_album(self, album_id): + album = await self.make_request('GET', 'album/%s' % album_id) return Album(album) - def get_album_images(self, album_id): - images = self.make_request('GET', 'album/%s/images' % album_id) + async def get_album_images(self, album_id): + images = await self.make_request('GET', 'album/%s/images' % album_id) return [Image(image) for image in images] - def create_album(self, fields): + async def create_album(self, fields): post_data = {field: fields[field] for field in set(self.allowed_album_fields).intersection(fields.keys())} if 'ids' in post_data: self.logged_in() - return self.make_request('POST', 'album', data=post_data) + return await self.make_request('POST', 'album', data=post_data) - def update_album(self, album_id, fields): + async def update_album(self, album_id, fields): post_data = {field: fields[field] for field in set(self.allowed_album_fields).intersection(fields.keys())} if isinstance(post_data['ids'], list): post_data['ids'] = ','.join(post_data['ids']) - return self.make_request('POST', 'album/%s' % album_id, data=post_data) + return await self.make_request('POST', 'album/%s' % album_id, data=post_data) - def album_delete(self, album_id): - return self.make_request('DELETE', 'album/%s' % album_id) + async def album_delete(self, album_id): + return await self.make_request('DELETE', 'album/%s' % album_id) - def album_favorite(self, album_id): + async def album_favorite(self, album_id): self.logged_in() - return self.make_request('POST', 'album/%s/favorite' % album_id) + return await self.make_request('POST', 'album/%s/favorite' % album_id) - def album_set_images(self, album_id, ids): + async def album_set_images(self, album_id, ids): if isinstance(ids, list): ids = ','.join(ids) - return self.make_request('POST', 'album/%s/' % album_id, {'ids': ids}) + return await self.make_request('POST', 'album/%s/' % album_id, {'ids': ids}) - def album_add_images(self, album_id, ids): + async def album_add_images(self, album_id, ids): if isinstance(ids, list): ids = ','.join(ids) - return self.make_request('POST', 'album/%s/add' % album_id, {'ids': ids}) + return await self.make_request('POST', 'album/%s/add' % album_id, {'ids': ids}) - def album_remove_images(self, album_id, ids): + async def album_remove_images(self, album_id, ids): if isinstance(ids, list): ids = ','.join(ids) - return self.make_request('DELETE', 'album/%s/remove_images' % album_id, {'ids': ids}) + return await self.make_request('DELETE', 'album/%s/remove_images' % album_id, {'ids': ids}) # Comment-related endpoints - def get_comment(self, comment_id): - comment = self.make_request('GET', 'comment/%d' % comment_id) + async def get_comment(self, comment_id): + comment = await self.make_request('GET', 'comment/%d' % comment_id) return Comment(comment) - def delete_comment(self, comment_id): + async def delete_comment(self, comment_id): self.logged_in() - return self.make_request('DELETE', 'comment/%d' % comment_id) + return await self.make_request('DELETE', 'comment/%d' % comment_id) - def get_comment_replies(self, comment_id): - replies = self.make_request('GET', 'comment/%d/replies' % comment_id) + async def get_comment_replies(self, comment_id): + replies = await self.make_request('GET', 'comment/%d/replies' % comment_id) return format_comment_tree(replies) - def post_comment_reply(self, comment_id, image_id, comment): + async def post_comment_reply(self, comment_id, image_id, comment): self.logged_in() data = { 'image_id': image_id, 'comment': comment } - return self.make_request('POST', 'comment/%d' % comment_id, data) + return await self.make_request('POST', 'comment/%d' % comment_id, data) - def comment_vote(self, comment_id, vote='up'): + async def comment_vote(self, comment_id, vote='up'): self.logged_in() - return self.make_request('POST', 'comment/%d/vote/%s' % (comment_id, vote)) + return await self.make_request('POST', 'comment/%d/vote/%s' % (comment_id, vote)) - def comment_report(self, comment_id): + async def comment_report(self, comment_id): self.logged_in() - return self.make_request('POST', 'comment/%d/report' % comment_id) + return await self.make_request('POST', 'comment/%d/report' % comment_id) # Custom Gallery Endpoints - def get_custom_gallery(self, gallery_id, sort='viral', window='week', page=0): - gallery = self.make_request('GET', 'g/%s/%s/%s/%s' % (gallery_id, sort, window, page)) + async def get_custom_gallery(self, gallery_id, sort='viral', window='week', page=0): + gallery = await self.make_request('GET', 'g/%s/%s/%s/%s' % (gallery_id, sort, window, page)) return CustomGallery( gallery['id'], gallery['name'], @@ -368,9 +366,9 @@ def get_custom_gallery(self, gallery_id, sort='viral', window='week', page=0): gallery['items'] ) - def get_user_galleries(self): + async def get_user_galleries(self): self.logged_in() - galleries = self.make_request('GET', 'g') + galleries = await self.make_request('GET', 'g') return [CustomGallery( gallery['id'], @@ -381,14 +379,14 @@ def get_user_galleries(self): gallery['tags'] ) for gallery in galleries] - def create_custom_gallery(self, name, tags=None): + async def create_custom_gallery(self, name, tags=None): self.logged_in() data = {'name': name} if tags: data['tags'] = ','.join(tags) - gallery = self.make_request('POST', 'g', data) + gallery = await self.make_request('POST', 'g', data) return CustomGallery( gallery['id'], @@ -399,14 +397,14 @@ def create_custom_gallery(self, name, tags=None): gallery['tags'] ) - def custom_gallery_update(self, gallery_id, name): + async def custom_gallery_update(self, gallery_id, name): self.logged_in() data = { 'id': gallery_id, 'name': name } - gallery = self.make_request('POST', 'g/%s' % gallery_id, data) + gallery = await self.make_request('POST', 'g/%s' % gallery_id, data) return CustomGallery( gallery['id'], @@ -417,7 +415,7 @@ def custom_gallery_update(self, gallery_id, name): gallery['tags'] ) - def custom_gallery_add_tags(self, gallery_id, tags): + async def custom_gallery_add_tags(self, gallery_id, tags): self.logged_in() if tags: @@ -425,9 +423,9 @@ def custom_gallery_add_tags(self, gallery_id, tags): else: raise ImgurClientError('tags must not be empty!') - return self.make_request('PUT', 'g/%s/add_tags' % gallery_id, data) + return await self.make_request('PUT', 'g/%s/add_tags' % gallery_id, data) - def custom_gallery_remove_tags(self, gallery_id, tags): + async def custom_gallery_remove_tags(self, gallery_id, tags): self.logged_in() if tags: @@ -435,64 +433,64 @@ def custom_gallery_remove_tags(self, gallery_id, tags): else: raise ImgurClientError('tags must not be empty!') - return self.make_request('DELETE', 'g/%s/remove_tags' % gallery_id, data) + return await self.make_request('DELETE', 'g/%s/remove_tags' % gallery_id, data) - def custom_gallery_delete(self, gallery_id): + async def custom_gallery_delete(self, gallery_id): self.logged_in() - return self.make_request('DELETE', 'g/%s' % gallery_id) + return await self.make_request('DELETE', 'g/%s' % gallery_id) - def filtered_out_tags(self): + async def filtered_out_tags(self): self.logged_in() - return self.make_request('GET', 'g/filtered_out') + return await self.make_request('GET', 'g/filtered_out') - def block_tag(self, tag): + async def block_tag(self, tag): self.logged_in() - return self.make_request('POST', 'g/block_tag', data={'tag': tag}) + return await self.make_request('POST', 'g/block_tag', data={'tag': tag}) - def unblock_tag(self, tag): + async def unblock_tag(self, tag): self.logged_in() - return self.make_request('POST', 'g/unblock_tag', data={'tag': tag}) + return await self.make_request('POST', 'g/unblock_tag', data={'tag': tag}) # Gallery-related endpoints - def gallery(self, section='hot', sort='viral', page=0, window='day', show_viral=True): + async def gallery(self, section='hot', sort='viral', page=0, window='day', show_viral=True): if section == 'top': - response = self.make_request('GET', 'gallery/%s/%s/%s/%d?showViral=%s' + response = await self.make_request('GET', 'gallery/%s/%s/%s/%d?showViral=%s' % (section, sort, window, page, str(show_viral).lower())) else: - response = self.make_request('GET', 'gallery/%s/%s/%d?showViral=%s' + response = await self.make_request('GET', 'gallery/%s/%s/%d?showViral=%s' % (section, sort, page, str(show_viral).lower())) return build_gallery_images_and_albums(response) - def memes_subgallery(self, sort='viral', page=0, window='week'): + async def memes_subgallery(self, sort='viral', page=0, window='week'): if sort == 'top': - response = self.make_request('GET', 'g/memes/%s/%s/%d' % (sort, window, page)) + response = await self.make_request('GET', 'g/memes/%s/%s/%d' % (sort, window, page)) else: - response = self.make_request('GET', 'g/memes/%s/%d' % (sort, page)) + response = await self.make_request('GET', 'g/memes/%s/%d' % (sort, page)) return build_gallery_images_and_albums(response) - def memes_subgallery_image(self, item_id): - item = self.make_request('GET', 'g/memes/%s' % item_id) + async def memes_subgallery_image(self, item_id): + item = await self.make_request('GET', 'g/memes/%s' % item_id) return build_gallery_images_and_albums(item) - def subreddit_gallery(self, subreddit, sort='time', window='week', page=0): + async def subreddit_gallery(self, subreddit, sort='time', window='week', page=0): if sort == 'top': - response = self.make_request('GET', 'gallery/r/%s/%s/%s/%d' % (subreddit, sort, window, page)) + response = await self.make_request('GET', 'gallery/r/%s/%s/%s/%d' % (subreddit, sort, window, page)) else: - response = self.make_request('GET', 'gallery/r/%s/%s/%d' % (subreddit, sort, page)) + response = await self.make_request('GET', 'gallery/r/%s/%s/%d' % (subreddit, sort, page)) return build_gallery_images_and_albums(response) - def subreddit_image(self, subreddit, image_id): - item = self.make_request('GET', 'gallery/r/%s/%s' % (subreddit, image_id)) + async def subreddit_image(self, subreddit, image_id): + item = await self.make_request('GET', 'gallery/r/%s/%s' % (subreddit, image_id)) return build_gallery_images_and_albums(item) - def gallery_tag(self, tag, sort='viral', page=0, window='week'): + async def gallery_tag(self, tag, sort='viral', page=0, window='week'): if sort == 'top': - response = self.make_request('GET', 'gallery/t/%s/%s/%s/%d' % (tag, sort, window, page)) + response = await self.make_request('GET', 'gallery/t/%s/%s/%s/%d' % (tag, sort, window, page)) else: - response = self.make_request('GET', 'gallery/t/%s/%s/%d' % (tag, sort, page)) + response = await self.make_request('GET', 'gallery/t/%s/%s/%d' % (tag, sort, page)) return Tag( response['name'], @@ -502,12 +500,12 @@ def gallery_tag(self, tag, sort='viral', page=0, window='week'): response['items'] ) - def gallery_tag_image(self, tag, item_id): - item = self.make_request('GET', 'gallery/t/%s/%s' % (tag, item_id)) + async def gallery_tag_image(self, tag, item_id): + item = await self.make_request('GET', 'gallery/t/%s/%s' % (tag, item_id)) return build_gallery_images_and_albums(item) - def gallery_item_tags(self, item_id): - response = self.make_request('GET', 'gallery/%s/tags' % item_id) + async def gallery_item_tags(self, item_id): + response = await self.make_request('GET', 'gallery/%s/tags' % item_id) return [TagVote( item['ups'], @@ -516,74 +514,74 @@ def gallery_item_tags(self, item_id): item['author'] ) for item in response['tags']] - def gallery_tag_vote(self, item_id, tag, vote): + async def gallery_tag_vote(self, item_id, tag, vote): self.logged_in() - response = self.make_request('POST', 'gallery/%s/vote/tag/%s/%s' % (item_id, tag, vote)) + response = await self.make_request('POST', 'gallery/%s/vote/tag/%s/%s' % (item_id, tag, vote)) return response - def gallery_search(self, q, advanced=None, sort='time', window='all', page=0): + async def gallery_search(self, q, advanced=None, sort='time', window='all', page=0): if advanced: data = {field: advanced[field] for field in set(self.allowed_advanced_search_fields).intersection(advanced.keys())} else: data = {'q': q} - response = self.make_request('GET', 'gallery/search/%s/%s/%s' % (sort, window, page), data) + response = await self.make_request('GET', 'gallery/search/%s/%s/%s' % (sort, window, page), data) return build_gallery_images_and_albums(response) - def gallery_random(self, page=0): - response = self.make_request('GET', 'gallery/random/random/%d' % page) + async def gallery_random(self, page=0): + response = await self.make_request('GET', 'gallery/random/random/%d' % page) return build_gallery_images_and_albums(response) - def share_on_imgur(self, item_id, title, terms=0): + async def share_on_imgur(self, item_id, title, terms=0): self.logged_in() data = { 'title': title, 'terms': terms } - return self.make_request('POST', 'gallery/%s' % item_id, data) + return await self.make_request('POST', 'gallery/%s' % item_id, data) - def remove_from_gallery(self, item_id): + async def remove_from_gallery(self, item_id): self.logged_in() - return self.make_request('DELETE', 'gallery/%s' % item_id) + return await self.make_request('DELETE', 'gallery/%s' % item_id) - def gallery_item(self, item_id): - response = self.make_request('GET', 'gallery/%s' % item_id) + async def gallery_item(self, item_id): + response = await self.make_request('GET', 'gallery/%s' % item_id) return build_gallery_images_and_albums(response) - def report_gallery_item(self, item_id): + async def report_gallery_item(self, item_id): self.logged_in() - return self.make_request('POST', 'gallery/%s/report' % item_id) + return await self.make_request('POST', 'gallery/%s/report' % item_id) - def gallery_item_vote(self, item_id, vote='up'): + async def gallery_item_vote(self, item_id, vote='up'): self.logged_in() - return self.make_request('POST', 'gallery/%s/vote/%s' % (item_id, vote)) + return await self.make_request('POST', 'gallery/%s/vote/%s' % (item_id, vote)) - def gallery_item_comments(self, item_id, sort='best'): - response = self.make_request('GET', 'gallery/%s/comments/%s' % (item_id, sort)) + async def gallery_item_comments(self, item_id, sort='best'): + response = await self.make_request('GET', 'gallery/%s/comments/%s' % (item_id, sort)) return format_comment_tree(response) - def gallery_comment(self, item_id, comment): + async def gallery_comment(self, item_id, comment): self.logged_in() - return self.make_request('POST', 'gallery/%s/comment' % item_id, {'comment': comment}) + return await self.make_request('POST', 'gallery/%s/comment' % item_id, {'comment': comment}) - def gallery_comment_ids(self, item_id): - return self.make_request('GET', 'gallery/%s/comments/ids' % item_id) + async def gallery_comment_ids(self, item_id): + return await self.make_request('GET', 'gallery/%s/comments/ids' % item_id) - def gallery_comment_count(self, item_id): - return self.make_request('GET', 'gallery/%s/comments/count' % item_id) + async def gallery_comment_count(self, item_id): + return await self.make_request('GET', 'gallery/%s/comments/count' % item_id) # Image-related endpoints - def get_image(self, image_id): - image = self.make_request('GET', 'image/%s' % image_id) + async def get_image(self, image_id): + image = await self.make_request('GET', 'image/%s' % image_id) return Image(image) - def upload_from_path(self, path, config=None, anon=True): + async def upload_from_path(self, path, config=None, anon=True): with open(path, 'rb') as fd: - self.upload(fd, config, anon) + await self.upload(fd, config, anon) - def upload(self, fd, config=None, anon=True): + async def upload(self, fd, config=None, anon=True): if not config: config = dict() @@ -595,9 +593,9 @@ def upload(self, fd, config=None, anon=True): } data.update({meta: config[meta] for meta in set(self.allowed_image_fields).intersection(config.keys())}) - return self.make_request('POST', 'upload', data, anon) + return await self.make_request('POST', 'upload', data, anon) - def upload_from_url(self, url, config=None, anon=True): + async def upload_from_url(self, url, config=None, anon=True): if not config: config = dict() @@ -607,20 +605,20 @@ def upload_from_url(self, url, config=None, anon=True): } data.update({meta: config[meta] for meta in set(self.allowed_image_fields).intersection(config.keys())}) - return self.make_request('POST', 'upload', data, anon) + return await self.make_request('POST', 'upload', data, anon) - def delete_image(self, image_id): - return self.make_request('DELETE', 'image/%s' % image_id) + async def delete_image(self, image_id): + return await self.make_request('DELETE', 'image/%s' % image_id) - def favorite_image(self, image_id): + async def favorite_image(self, image_id): self.logged_in() - return self.make_request('POST', 'image/%s/favorite' % image_id) + return await self.make_request('POST', 'image/%s/favorite' % image_id) # Conversation-related endpoints - def conversation_list(self): + async def conversation_list(self): self.logged_in() - conversations = self.make_request('GET', 'conversations') + conversations = await self.make_request('GET', 'conversations') return [Conversation( conversation['id'], conversation['last_message_preview'], @@ -630,10 +628,10 @@ def conversation_list(self): conversation['message_count'], ) for conversation in conversations] - def get_conversation(self, conversation_id, page=1, offset=0): + async def get_conversation(self, conversation_id, page=1, offset=0): self.logged_in() - conversation = self.make_request('GET', 'conversations/%d/%d/%d' % (conversation_id, page, offset)) + conversation = await self.make_request('GET', 'conversations/%d/%d/%d' % (conversation_id, page, offset)) return Conversation( conversation['id'], conversation['last_message_preview'], @@ -646,38 +644,38 @@ def get_conversation(self, conversation_id, page=1, offset=0): conversation['page'] ) - def create_message(self, recipient, body): + async def create_message(self, recipient, body): self.logged_in() - return self.make_request('POST', 'conversations/%s' % recipient, {'body': body}) + return await self.make_request('POST', 'conversations/%s' % recipient, {'body': body}) - def delete_conversation(self, conversation_id): + async def delete_conversation(self, conversation_id): self.logged_in() - return self.make_request('DELETE', 'conversations/%d' % conversation_id) + return await self.make_request('DELETE', 'conversations/%d' % conversation_id) - def report_sender(self, username): + async def report_sender(self, username): self.logged_in() - return self.make_request('POST', 'conversations/report/%s' % username) + return await self.make_request('POST', 'conversations/report/%s' % username) - def block_sender(self, username): + async def block_sender(self, username): self.logged_in() - return self.make_request('POST', 'conversations/block/%s' % username) + return await self.make_request('POST', 'conversations/block/%s' % username) # Notification-related endpoints - def get_notifications(self, new=True): + async def get_notifications(self, new=True): self.logged_in() - response = self.make_request('GET', 'notification', {'new': str(new).lower()}) + response = await self.make_request('GET', 'notification', {'new': str(new).lower()}) return build_notifications(response) - def get_notification(self, notification_id): + async def get_notification(self, notification_id): self.logged_in() - response = self.make_request('GET', 'notification/%d' % notification_id) + response = await self.make_request('GET', 'notification/%d' % notification_id) return build_notification(response) - def mark_notifications_as_read(self, notification_ids): + async def mark_notifications_as_read(self, notification_ids): self.logged_in() - return self.make_request('POST', 'notification', ','.join(notification_ids)) + return await self.make_request('POST', 'notification', ','.join(notification_ids)) # Memegen-related endpoints - def default_memes(self): - response = self.make_request('GET', 'memegen/defaults') + async def default_memes(self): + response = await self.make_request('GET', 'memegen/defaults') return [Image(meme) for meme in response] diff --git a/requirements.txt b/requirements.txt index f229360..ce23571 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ -requests +aiohttp \ No newline at end of file From 5d67daffc6c8ece05397896cd42ef504584104fc Mon Sep 17 00:00:00 2001 From: NotSoSuper Date: Sat, 22 Apr 2017 15:31:57 -0400 Subject: [PATCH 2/8] ok python --- imgurpython/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgurpython/client.py b/imgurpython/client.py index 6c894d4..e42504c 100644 --- a/imgurpython/client.py +++ b/imgurpython/client.py @@ -244,7 +244,7 @@ async def get_account_album_count(self, username): self.validate_user_context(username) return await self.make_request('GET', 'account/%s/albums/count' % username) - async def get_account_comments(self, username, sort='newest', page=0): + async def get_account_comments(self, username, sort='newest', page=0): self.validate_user_context(username) comments = await self.make_request('GET', 'account/%s/comments/%s/%s' % (username, sort, page)) From a827cc44f38f8a106c99b4aa6f8d108add6f1659 Mon Sep 17 00:00:00 2001 From: NotSoSuper Date: Sat, 22 Apr 2017 15:32:30 -0400 Subject: [PATCH 3/8] ok python --- imgurpython/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgurpython/client.py b/imgurpython/client.py index e42504c..e1fe2b4 100644 --- a/imgurpython/client.py +++ b/imgurpython/client.py @@ -595,7 +595,7 @@ async def upload(self, fd, config=None, anon=True): return await self.make_request('POST', 'upload', data, anon) - async def upload_from_url(self, url, config=None, anon=True): + async def upload_from_url(self, url, config=None, anon=True): if not config: config = dict() From 39cd03c4892be2979eaa98e402a6b56e4b26b569 Mon Sep 17 00:00:00 2001 From: NotSoSuper Date: Mon, 8 May 2017 21:32:36 -0400 Subject: [PATCH 4/8] credits --- imgurpython/client.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/imgurpython/client.py b/imgurpython/client.py index e1fe2b4..231228e 100644 --- a/imgurpython/client.py +++ b/imgurpython/client.py @@ -1,5 +1,6 @@ import base64 import aiohttp +import asyncio from .imgur.models.tag import Tag from .imgur.models.album import Album from .imgur.models.image import Image @@ -80,7 +81,7 @@ def __init__(self, client_id, client_secret, access_token=None, refresh_token=No if refresh_token is not None: self.auth = AuthWrapper(access_token, refresh_token, client_id, client_secret) - self.credits = self.get_credits() + asyncio.get_event_loop().create_task(self.set_credits()) def set_user_auth(self, access_token, refresh_token): self.auth = AuthWrapper(access_token, refresh_token, self.client_id, self.client_secret) @@ -88,6 +89,9 @@ def set_user_auth(self, access_token, refresh_token): def get_client_id(self): return self.client_id + async def set_credits(self): + self.credits = await self.get_credits() + async def get_credits(self): return await self.make_request('GET', 'credits', None, True) From 06469f114e24edbf97ae5b10e2bb697752636580 Mon Sep 17 00:00:00 2001 From: NotSoSuper Date: Fri, 30 Jun 2017 16:45:54 -0400 Subject: [PATCH 5/8] fix for aiohttp 2.2 --- imgurpython/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgurpython/client.py b/imgurpython/client.py index 231228e..9736547 100644 --- a/imgurpython/client.py +++ b/imgurpython/client.py @@ -162,7 +162,7 @@ async def make_request(self, method, route, data=None, force_anon=False): return response_data['data'] if 'data' in response_data.keys() else response_data finally: - await session.close() + session.close() def validate_user_context(self, username): if username == 'me' and self.auth is None: From 340ce07a2ffcfb6a7aac8e1f2c03b99833c09b29 Mon Sep 17 00:00:00 2001 From: NotSoSuper Date: Sun, 18 Feb 2018 12:17:21 -0500 Subject: [PATCH 6/8] aiohttp thing --- imgurpython/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgurpython/client.py b/imgurpython/client.py index 231228e..d1cf88b 100644 --- a/imgurpython/client.py +++ b/imgurpython/client.py @@ -47,7 +47,7 @@ async def refresh(self): } url = API_URL + 'oauth2/token' - with aiohttp.ClientSession() as session: + async with aiohttp.ClientSession() as session: async with session.post(url, data=data) as r: if response.status != 200: raise ImgurClientError('Error refreshing access token!', response.status) From 3d9a633f26cf8974c6aa9e6a962b39f916db7a08 Mon Sep 17 00:00:00 2001 From: NotSoSuper Date: Thu, 14 Jun 2018 01:34:35 -0400 Subject: [PATCH 7/8] aiohttp 3.x, bug fixes --- imgurpython/client.py | 45 ++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/imgurpython/client.py b/imgurpython/client.py index 2771d54..d9e4be7 100644 --- a/imgurpython/client.py +++ b/imgurpython/client.py @@ -1,21 +1,21 @@ +import asyncio import base64 + import aiohttp -import asyncio -from .imgur.models.tag import Tag -from .imgur.models.album import Album -from .imgur.models.image import Image + +from .helpers.error import ImgurClientError, ImgurClientRateLimitError +from .helpers.format import (build_gallery_images_and_albums, + build_notification, build_notifications, + format_comment_tree) from .imgur.models.account import Account +from .imgur.models.account_settings import AccountSettings +from .imgur.models.album import Album from .imgur.models.comment import Comment -from .imgur.models.tag_vote import TagVote -from .helpers.error import ImgurClientError -from .helpers.format import build_notification -from .helpers.format import format_comment_tree -from .helpers.format import build_notifications from .imgur.models.conversation import Conversation -from .helpers.error import ImgurClientRateLimitError -from .helpers.format import build_gallery_images_and_albums from .imgur.models.custom_gallery import CustomGallery -from .imgur.models.account_settings import AccountSettings +from .imgur.models.image import Image +from .imgur.models.tag import Tag +from .imgur.models.tag_vote import TagVote API_URL = 'https://api.imgur.com/' MASHAPE_URL = 'https://imgur-apiv3.p.mashape.com/' @@ -49,8 +49,8 @@ async def refresh(self): url = API_URL + 'oauth2/token' async with aiohttp.ClientSession() as session: async with session.post(url, data=data) as r: - if response.status != 200: - raise ImgurClientError('Error refreshing access token!', response.status) + if r.status != 200: + raise ImgurClientError('Error refreshing access token!', r.status) response_data = await r.json() self.current_access_token = response_data['access_token'] @@ -81,7 +81,7 @@ def __init__(self, client_id, client_secret, access_token=None, refresh_token=No if refresh_token is not None: self.auth = AuthWrapper(access_token, refresh_token, client_id, client_secret) - asyncio.get_event_loop().create_task(self.set_credits()) + asyncio.get_event_loop().create_task(self.set_credits()) def set_user_auth(self, access_token, refresh_token): self.auth = AuthWrapper(access_token, refresh_token, self.client_id, self.client_secret) @@ -123,15 +123,14 @@ def prepare_headers(self, force_anon=False): async def make_request(self, method, route, data=None, force_anon=False): - try: - method = method.lower() - session = aiohttp.ClientSession() - predicate = getattr(session, method) + method = method.lower() - header = self.prepare_headers(force_anon) - url = (MASHAPE_URL if self.mashape_key is not None else API_URL) + ('3/%s' % route if 'oauth2' not in route else route) + header = self.prepare_headers(force_anon) + url = (MASHAPE_URL if self.mashape_key is not None else API_URL) + ('3/%s' % route if 'oauth2' not in route else route) - async with predicate(url, headers=header, params=data, data=data) as response: + async with aiohttp.ClientSession() as session: + method_to_call = getattr(session, method) + async with method_to_call(url, headers=header, params=data, data=data) as response: if response.status == 403 and self.auth is not None: await self.auth.refresh() header = self.prepare_headers() @@ -161,8 +160,6 @@ async def make_request(self, method, route, data=None, force_anon=False): raise ImgurClientError(response_data['data']['error'], response.status) return response_data['data'] if 'data' in response_data.keys() else response_data - finally: - session.close() def validate_user_context(self, username): if username == 'me' and self.auth is None: From 9abc3c9423a2da8447774b4190128ef58f7d931e Mon Sep 17 00:00:00 2001 From: NotSoSuper Date: Thu, 18 Jul 2019 15:05:30 +0300 Subject: [PATCH 8/8] Remove requests dependency from setup.py --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 300e786..ae152e5 100644 --- a/setup.py +++ b/setup.py @@ -60,7 +60,7 @@ # project is installed. For an analysis of "install_requires" vs pip's # requirements files see: # https://packaging.python.org/en/latest/technical.html#install-requires-vs-requirements-files - install_requires=['requests'], + install_requires=["aiohttp"], # If there are data files included in your packages that need to be # installed, specify them here. If using Python 2.6 or less, then these