Skip to content

Commit

Permalink
Add API response types
Browse files Browse the repository at this point in the history
- Fixed a lot of typing related errors
  • Loading branch information
scrazzz committed Jan 31, 2024
1 parent 245e230 commit b38f494
Show file tree
Hide file tree
Showing 18 changed files with 193 additions and 85 deletions.
15 changes: 15 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[tool.pyright]
include = [
"redgifs",
"redgifs/types"
]
exclude = [
"**/__pycache__",
"build",
"dist",
"docs",
]
reportUnnecessaryTypeIgnoreComment = "warning"
reportUnusedImport = "error"
pythonVersion = "3.8"
typeCheckingMode = "basic"
8 changes: 4 additions & 4 deletions redgifs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@

from typing import Literal, NamedTuple

from .api import API
from .http import ProxyAuth
from .enums import Order, Type
from .tags import Tags
from .api import *
from .http import *
from .enums import *
from .tags import *
from .errors import *
from .utils import *

Expand Down
11 changes: 7 additions & 4 deletions redgifs/aio.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import io
import os
from datetime import datetime
from typing import Any, Dict, List, Optional, Union
from typing import TYPE_CHECKING, Any, List, Optional, Union

import aiohttp

Expand All @@ -38,6 +38,9 @@
from .parser import parse_feeds, parse_search, parse_creator, parse_creators, parse_search_image
from .models import GIF, URL, CreatorResult, Feeds, Image, SearchResult, CreatorsResult

if TYPE_CHECKING:
from redgifs.types.tags import TagInfo

class API:
def __init__(
self,
Expand All @@ -57,7 +60,7 @@ async def get_feeds(self) -> Feeds:
feeds = await self.http.get_feeds()
return parse_feeds(feeds)

async def get_tags(self) -> List[Dict[str, Union[str, int]]]:
async def get_tags(self) -> List[TagInfo]:
resp = await self.http.get_tags()
return resp['tags']

Expand Down Expand Up @@ -90,7 +93,7 @@ async def get_gif(self, id: str) -> GIF:
avg_color=json['avgColor'],
)

async def get_trending_tags(self) -> List[Dict[str, Union[str, int]]]:
async def get_trending_tags(self) -> List[TagInfo]:
result = (await self.http.get_trending_tags())['tags']
return result

Expand All @@ -104,7 +107,7 @@ async def get_trending_images(self) -> List[Image]:

async def fetch_tag_suggestions(self, query: str) -> List[str]:
result = await self.http.get_tag_suggestions(query)
return [d['text'] for d in result]
return [d['text'] for d in result] # type: ignore - `get_tag_suggestions` isn't properly TypedDict'd so ignore the warning

async def search(
self,
Expand Down
2 changes: 2 additions & 0 deletions redgifs/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
from .parser import parse_creator, parse_feeds, parse_search, parse_creators, parse_search_image
from .models import URL, GIF, CreatorResult, Feeds, Image, SearchResult, CreatorsResult

__all__ = ('API',)

class API:
"""The API Instance to get information from the RedGifs API.
Expand Down
1 change: 1 addition & 0 deletions redgifs/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

from enum import Enum

__all__ = ('Order', 'Type')
class Order(Enum):
"""An enum representing the Order."""

Expand Down
2 changes: 2 additions & 0 deletions redgifs/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
DEALINGS IN THE SOFTWARE.
"""

from __future__ import annotations

import requests
import aiohttp

Expand Down
27 changes: 16 additions & 11 deletions redgifs/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,22 @@
import aiohttp
import yarl

from redgifs.types.response import GifResponse, SearchResponse

from . import __version__
from .errors import HTTPException
from .enums import Order, Type
from .const import REDGIFS_THUMBS_RE
from .utils import strip_ip

__all__ = ('ProxyAuth',)

_log = logging.getLogger(__name__)

if TYPE_CHECKING:
from redgifs.types.gif import GetGifResponse, GifResponse, TrendingGifsResponse
from redgifs.types.image import ImageResponse, TrendingImagesResponse
from redgifs.types.feeds import FeedsResponse
from redgifs.types.tags import TagsResponse

T = TypeVar('T')
Response = Coroutine[Any, Any, T]

Expand Down Expand Up @@ -306,16 +311,16 @@ async def login(self, username: Optional[str] = None, password: Optional[str] =

# GIF methods

def get_feeds(self):
def get_feeds(self) -> Response[FeedsResponse]:
return self.request(Route('GET', '/v2/home/feeds'))

def get_tags(self, **params: Any):
def get_tags(self, **params: Any) -> Response[TagsResponse]:
return self.request(Route('GET', '/v1/tags'), **params)

def get_gif(self, id: str, **params: Any) -> Response[GifResponse]:
def get_gif(self, id: str, **params: Any) -> Response[GetGifResponse]:
return self.request(Route('GET', '/v2/gifs/{id}', id=id), **params)

def search(self, search_text: str, order: Order, count: int, page: int, **params: Any) -> Response[SearchResponse]:
def search(self, search_text: str, order: Order, count: int, page: int, **params: Any) -> Response[GifResponse]:
r = Route(
'GET', '/v2/gifs/search?search_text={search_text}&order={order}&count={count}&page={page}',
search_text=search_text, order=order.value, count=count, page=page
Expand Down Expand Up @@ -357,30 +362,30 @@ def search_creator(self, username: str, page: int, count: int, order: Order, typ
)
return self.request(r, **params)

def get_trending_gifs(self):
def get_trending_gifs(self) -> Response[TrendingGifsResponse]:
r = Route('GET', '/v2/explore/trending-gifs')
return self.request(r)

# Pic methods

def search_image(self, search_text: str, order: Order, count: int, page: int, **params: Any):
def search_image(self, search_text: str, order: Order, count: int, page: int, **params: Any) -> Response[ImageResponse]:
r = Route(
'GET', '/v2/gifs/search?search_text={search_text}&order={order}&count={count}&page={page}&type=i',
search_text=search_text, order=order.value, count=count, page=page
)
return self.request(r, **params)

def get_trending_images(self):
def get_trending_images(self) -> Response[TrendingImagesResponse]:
r = Route('GET', '/v2/explore/trending-images')
return self.request(r)

# Tag methods

def get_trending_tags(self):
def get_trending_tags(self) -> Response[TagsResponse]:
r = Route('GET', '/v2/search/trending')
return self.request(r)

def get_tag_suggestions(self, query: str):
def get_tag_suggestions(self, query: str) -> Response[List[Dict[str, Union[str, int]]]]:
r = Route(
'GET', '/v2/search/suggest?query={query}',
query=query
Expand Down
4 changes: 2 additions & 2 deletions redgifs/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class URL:
hd: str
poster: str
thumbnail: str
vthumbnail: str
vthumbnail: Optional[str]
web_url: str
file_url: Optional[str]

Expand Down Expand Up @@ -173,7 +173,7 @@ class Image:
likes: int
tags: List[str]
verified: bool
views: int
views: Optional[int]
published: bool
urls: URL
username: str
Expand Down
15 changes: 9 additions & 6 deletions redgifs/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,20 @@

import logging
from datetime import datetime
from typing import Any, Dict

from redgifs.types.response import SearchResponse
from typing import TYPE_CHECKING, Any, Dict

from .enums import Type
from .utils import _gifs_iter, _images_iter, _users_iter, build_file_url, to_web_url
from .models import GIF, URL, CreatorResult, Feeds, Image, User, SearchResult, CreatorsResult

if TYPE_CHECKING:
from redgifs.types.feeds import FeedsResponse
from redgifs.types.gif import GifResponse
from redgifs.types.image import ImageResponse

_log = logging.getLogger(__name__)

def parse_feeds(json: Dict[str, Any]) -> Feeds:
def parse_feeds(json: FeedsResponse) -> Feeds:
_log.debug('Parsing feeds')
hgifs = json['horizontalGifs']
vgifs = json['verticalGifs']
Expand All @@ -60,7 +63,7 @@ def parse_feeds(json: Dict[str, Any]) -> Feeds:
)

# For GIFs
def parse_search(searched_for: str, json: SearchResponse) -> SearchResult:
def parse_search(searched_for: str, json: GifResponse) -> SearchResult:
_log.debug('Using `parse_search` for: {searched_for}')
json_gifs = json['gifs']
users = json['users']
Expand Down Expand Up @@ -131,7 +134,7 @@ def parse_search(searched_for: str, json: SearchResponse) -> SearchResult:
)

# For images
def parse_search_image(searched_for: str, json: Dict[str, Any]) -> SearchResult:
def parse_search_image(searched_for: str, json: ImageResponse) -> SearchResult:
_log.debug('Using `parse_search` for: {searched_for}')
json_gifs = json['gifs']
users = json['users']
Expand Down
6 changes: 4 additions & 2 deletions redgifs/tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
from .utils import _read_tags_json
from .errors import InvalidTag

__all__ = ('Tags',)

class Tags:
tags_mapping: Dict[str, str] = {}

Expand Down Expand Up @@ -74,9 +76,9 @@ def search(self, tag: str) -> List[str]:
@overload
def random(self, count: Literal[1] = ...) -> str:
...

@overload
def random(self, count: int = ...) -> List[str]:
def random(self, count: int) -> List[str]:
...

def random(self, count: int = 1):
Expand Down
25 changes: 13 additions & 12 deletions redgifs/types/feeds.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
from typing import List, TypedDict
from redgifs.types.gif import GifInfo
from redgifs.types.image import ImageInfo


class Feeds(TypedDict):
horizontalGifs: List[...]
hotCreators: List[...]
hotGifs: List[]
hotImages: List[]
longGifs: List[]
newCreators: List[]
soundGifs: List[]
verifiedGifs: List[]
verifiedImages: List[]
verticalGifs: List[]
class FeedsResponse(TypedDict):
horizontalGifs: List[GifInfo]
hotCreators: List[GifInfo]
hotGifs: List[GifInfo]
hotImages: List[ImageInfo]
longGifs: List[GifInfo]
newCreators: List[ImageInfo]
soundGifs: List[GifInfo]
verifiedGifs: List[GifInfo]
verifiedImages: List[ImageInfo]
verticalGifs: List[GifInfo]
47 changes: 23 additions & 24 deletions redgifs/types/gif.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,14 @@
from typing import List, Optional, TypedDict

class UserInfo(TypedDict):
creationtime: int
description: str
followers: int
following: int
gifs: int
name: str
profileImageUrl: str
profileUrl: str
publishedCollections: Optional[int]
publishedGifs: int
status: Optional[str]
subscription: int
url: str
username: str
verified: bool
views: int
poster: Optional[str]
preview: Optional[str]
thumbnail: Optional[str]
likes: Optional[int]
from redgifs.types.niches import NichesInfo
from redgifs.types.user import UserInfo

class MediaInfo(TypedDict):
sd: str
hd: str
gif: str
poster: str
thumbnail: str
vthumbnail: str
vthumbnail: Optional[str]

class GifInfo(TypedDict):
id: str
Expand All @@ -47,4 +27,23 @@ class GifInfo(TypedDict):
urls: MediaInfo
userName: str
avgColor: str
gallry: str
gallery: str

class GetGifResponse(TypedDict):
gif: GifInfo
user: Optional[UserInfo]

class CommonGifResponse(TypedDict):
page: int
pages: int
total: int
gifs: List[GifInfo]
users: List[UserInfo]
niches: List[NichesInfo]
tags: List[str]

class TrendingGifsResponse(CommonGifResponse):
pass

class GifResponse(CommonGifResponse):
pass
Loading

0 comments on commit b38f494

Please sign in to comment.