Skip to content

Commit 5133fab

Browse files
authored
💥 Enable fetching Gitmoji data from the official API (#9)
1 parent a94eb4e commit 5133fab

File tree

7 files changed

+84
-1
lines changed

7 files changed

+84
-1
lines changed

‎.pre-commit-config.yaml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ repos:
2020
hooks:
2121
- id: mypy
2222
exclude: '^(?:(?!src).)*$'
23+
additional_dependencies:
24+
- types-requests
2325
- repo: https://github.com/astral-sh/ruff-pre-commit
2426
rev: 'v0.1.3'
2527
hooks:

‎pyproject.toml‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ build-backend = "setuptools.build_meta"
99
name = "python-gitmojis"
1010
version = "0.0.0"
1111
requires-python = ">= 3.10"
12-
dependencies = []
12+
dependencies = [
13+
"requests",
14+
]
1315

1416
[project.optional-dependencies]
1517
dev = [
@@ -20,6 +22,7 @@ lint = [
2022
"black",
2123
"mypy",
2224
"ruff",
25+
"types-requests",
2326
]
2427
test = [
2528
"pytest",

‎src/gitmojis/__init__.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
from .core import fetch_guide
12
from .model import Gitmoji, Guide
23

34
__all__ = [
45
"Gitmoji",
56
"Guide",
7+
"fetch_guide",
68
]

‎src/gitmojis/core.py‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import requests
2+
3+
from . import defaults
4+
from .exceptions import ResponseJsonError
5+
from .model import Gitmoji, Guide
6+
7+
8+
def fetch_guide() -> Guide:
9+
"""Fetch the Gitmoji guide from the official Gitmoji API.
10+
11+
This function sends a GET request to the Gitmoji API to retrieve the current state
12+
of the Gitmoji guide.
13+
14+
Returns:
15+
A `Guide` object representing the current state of the Gitmoji API.
16+
17+
Raises:
18+
ResponseJsonError: If the API response doesn't contain the expected JSON data.
19+
"""
20+
response = requests.get(defaults.GITMOJI_API_URL)
21+
22+
if (gitmojis_json := response.json().get(defaults.GITMOJI_API_KEY)) is None:
23+
raise ResponseJsonError
24+
25+
guide = Guide(gitmojis=[Gitmoji(**gitmoji_json) for gitmoji_json in gitmojis_json])
26+
27+
return guide

‎src/gitmojis/defaults.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from typing import Final
2+
3+
GITMOJI_API_URL: Final = "https://gitmoji.dev/api/gitmojis"
4+
5+
GITMOJI_API_KEY: Final = "gitmojis"

‎src/gitmojis/exceptions.py‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class GitmojisException(Exception):
2+
message: str
3+
4+
def __init__(self, message: str | None = None) -> None:
5+
super().__init__(message or getattr(self.__class__, "message", ""))
6+
7+
8+
class ApiError(GitmojisException):
9+
pass
10+
11+
12+
class ResponseJsonError(ApiError):
13+
message = "unsupported format of the JSON data returned by the API"

‎tests/test_core.py‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import pytest
2+
import requests
3+
4+
from gitmojis import defaults
5+
from gitmojis.core import fetch_guide
6+
from gitmojis.exceptions import ResponseJsonError
7+
from gitmojis.model import Guide
8+
9+
10+
@pytest.fixture()
11+
def response(mocker):
12+
return mocker.Mock(spec_set=requests.Response)
13+
14+
15+
def test_fetch_guide_creates_guide_from_api_response_json(mocker, response):
16+
response.json.return_value = {defaults.GITMOJI_API_KEY: []}
17+
18+
mocker.patch("requests.get", return_value=response)
19+
20+
guide = fetch_guide()
21+
22+
assert isinstance(guide, Guide)
23+
24+
25+
def test_fetch_guide_raises_error_if_gitmoji_api_key_not_in_response_json(mocker, response): # fmt: skip
26+
response.json.return_value = {} # `GITMOJI_API_KEY` not in the response's JSON
27+
28+
mocker.patch("requests.get", return_value=response)
29+
30+
with pytest.raises(ResponseJsonError):
31+
fetch_guide()

0 commit comments

Comments
 (0)