python-gitmojis 0.1.5__py3-none-any.whl → 1.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
gitmojis/__init__.py CHANGED
@@ -1,3 +1,8 @@
1
- from .core import gitmojis
1
+ from .core import fetch_guide
2
+ from .model import Gitmoji, Guide
2
3
 
3
- __version__ = "0.1.5"
4
+ __all__ = [
5
+ "Gitmoji",
6
+ "Guide",
7
+ "fetch_guide",
8
+ ]
gitmojis/__main__.py ADDED
@@ -0,0 +1,4 @@
1
+ from gitmojis.cli import gitmojis_cli as main
2
+
3
+ if __name__ == "__main__":
4
+ main()
@@ -0,0 +1,37 @@
1
+ import click
2
+
3
+ from gitmojis.core import fetch_guide
4
+
5
+
6
+ def get_commands() -> list[click.Command]:
7
+ """Return a list of `@click` commands defined in `gitmojis.cli.commands`."""
8
+ from gitmojis.cli import commands as commands_module
9
+
10
+ return [
11
+ command
12
+ for command in commands_module.__dict__.values()
13
+ if isinstance(command, click.Command)
14
+ ]
15
+
16
+
17
+ @click.group(
18
+ name="gitmojis",
19
+ commands=get_commands(),
20
+ )
21
+ @click.option(
22
+ "--use-backup",
23
+ is_flag=True,
24
+ help="Use the backup to fetch data if the API request fails.",
25
+ )
26
+ @click.version_option(
27
+ package_name="python-gitmojis",
28
+ prog_name="gitmojis",
29
+ )
30
+ @click.pass_context
31
+ def gitmojis_cli(context: click.Context, use_backup: bool) -> None:
32
+ """Command-line interface for managing the official Gitmoji guide."""
33
+ # Initialize the context object
34
+ context.ensure_object(dict)
35
+
36
+ # Pass the current state of the Gitmoji guide to the group context
37
+ context.obj["guide"] = fetch_guide(use_backup=use_backup)
@@ -0,0 +1,24 @@
1
+ import json
2
+ from dataclasses import asdict
3
+
4
+ import click
5
+
6
+ from gitmojis import defaults
7
+
8
+
9
+ @click.command()
10
+ @click.pass_context
11
+ def sync(context: click.Context) -> None:
12
+ """Synchronize the backup file with the current state of the API."""
13
+ # Get the `Guide` object from the command's context
14
+ guide = context.obj["guide"]
15
+
16
+ # Covert the `Guide` instance from context to a format defined by the API schema
17
+ gitmojis_json = list(map(asdict, guide))
18
+
19
+ with defaults.GITMOJI_API_PATH.open("w", encoding="UTF-8") as f:
20
+ # Dump the Gitmoji data to the backup file
21
+ json.dump(gitmojis_json, f, ensure_ascii=False, indent=2)
22
+
23
+ # Append a newline to avoid the `end-of-file-fixer` Pre-commit hook error
24
+ f.write("\n")
gitmojis/core.py CHANGED
@@ -1,17 +1,47 @@
1
- from gitmojis.loaders import load_gitmojis_api, load_gitmojis_json
2
- from gitmojis.models import GitmojiList
1
+ import json
3
2
 
4
- __all__ = [
5
- "gitmojis",
6
- ]
3
+ import requests
7
4
 
5
+ from . import defaults
6
+ from .exceptions import ApiRequestError, ResponseJsonError
7
+ from .model import Gitmoji, Guide
8
8
 
9
- def get_gitmojis() -> GitmojiList:
9
+
10
+ def fetch_guide(*, use_backup: bool = False) -> Guide:
11
+ """Fetch the Gitmoji guide from the official Gitmoji API.
12
+
13
+ This function sends a GET request to the Gitmoji API to retrieve the current state
14
+ of the Gitmoji guide. If the request is successful and contains the expected JSON
15
+ data, a `Guide` object is returned. If the expected JSON data is not present, a
16
+ `ResponseJsonError` is raised. In case of an HTTP error during the request
17
+ (e.g., connection error, timeout), and if `use_backup` is set to `True`, the function
18
+ falls back to loading a local copy of the Gitmoji guide. Otherwise, it raises an
19
+ `ApiRequestError`.
20
+
21
+ Args:
22
+ use_backup: A flag indicating whether to use a local backup in case of a request
23
+ failure. Defaults to `False`.
24
+
25
+ Returns:
26
+ A `Guide` object representing the current state of the Gitmoji API.
27
+
28
+ Raises:
29
+ ApiRequestError: If the API request fails and `use_backup` is `False`.
30
+ ResponseJsonError: If the API response doesn't contain the expected JSON data or
31
+ if there is an error loading the local backup of the Gitmoji guide.
32
+ """
10
33
  try:
11
- gitmojis = load_gitmojis_api()
12
- except ConnectionError:
13
- gitmojis = load_gitmojis_json()
14
- return gitmojis
34
+ (response := requests.get(defaults.GITMOJI_API_URL)).raise_for_status()
35
+
36
+ if (gitmojis_json := response.json().get(defaults.GITMOJI_API_KEY)) is None:
37
+ raise ResponseJsonError
38
+ except requests.RequestException as exc_info:
39
+ if use_backup:
40
+ with defaults.GITMOJI_API_PATH.open(encoding="UTF-8") as f:
41
+ gitmojis_json = json.load(f)
42
+ else:
43
+ raise ApiRequestError from exc_info
15
44
 
45
+ guide = Guide(gitmojis=[Gitmoji(**gitmoji_json) for gitmoji_json in gitmojis_json])
16
46
 
17
- gitmojis = get_gitmojis()
47
+ return guide
gitmojis/defaults.py ADDED
@@ -0,0 +1,10 @@
1
+ from pathlib import Path
2
+ from typing import Final
3
+
4
+ import gitmojis
5
+
6
+ GITMOJI_API_URL: Final = "https://gitmoji.dev/api/gitmojis"
7
+
8
+ GITMOJI_API_KEY: Final = "gitmojis"
9
+
10
+ GITMOJI_API_PATH: Final = Path(gitmojis.__file__).parent / "assets" / "gitmojis.json"
gitmojis/exceptions.py ADDED
@@ -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 ApiRequestError(GitmojisException):
9
+ message = "request to get the Gitmoji data from the API failed"
10
+
11
+
12
+ class ResponseJsonError(ApiRequestError):
13
+ message = "unsupported format of the JSON data returned by the API"
gitmojis/model.py ADDED
@@ -0,0 +1,53 @@
1
+ from collections import UserList
2
+ from dataclasses import dataclass
3
+ from typing import Iterable, Literal
4
+
5
+
6
+ @dataclass(frozen=True, kw_only=True)
7
+ class Gitmoji:
8
+ """Represents a single Gitmoji and its data.
9
+
10
+ The data model is adapted from the schema of the original Gitmoji project.
11
+
12
+ Attributes:
13
+ emoji: The emoji symbol representing the Gitmoji.
14
+ entity: The HTML entity corresponding to the Gitmoji.
15
+ code: The Markdown code of the Gitmoji's emoji.
16
+ description: A brief description of changes introduced by commits and pull
17
+ requests marked by the Gitmoji.
18
+ name: The user-defined name or identifier of the Gitmoji.
19
+ semver: The Semantic Versioning level affected by the commits or pull requests
20
+ marked by the emoji associated with the Gitmoji, if specified. May be `None`
21
+ or one of the following: `"major"`, `"minor"`, `"patch"`.
22
+ """
23
+
24
+ emoji: str
25
+ entity: str
26
+ code: str
27
+ description: str
28
+ name: str
29
+ semver: Literal["major", "minor", "patch"] | None
30
+
31
+
32
+ class Guide(UserList[Gitmoji]):
33
+ """Represents a list of (a "guide" through) `Gitmoji` objects.
34
+
35
+ This class is used to create a collection of `Gitmoji` objects, providing a simple
36
+ framework for accessing various Gitmojis and their data.
37
+ """
38
+
39
+ def __init__(self, *, gitmojis: Iterable[Gitmoji] | None = None) -> None:
40
+ """Construct a new `Guide` object.
41
+
42
+ Args:
43
+ gitmojis: An optional iterable of `Gitmoji` objects used to create
44
+ the guide. If `None`, the guide is initialized as empty. Note
45
+ that the data must be passed as a keyword argument, in contrast
46
+ to the implementation provided by the base class.
47
+ """
48
+ super().__init__(gitmojis)
49
+
50
+ @property
51
+ def gitmojis(self) -> list[Gitmoji]:
52
+ """Return the guide's data with a semantically meaningful attribute name."""
53
+ return self.data
@@ -0,0 +1,257 @@
1
+ Metadata-Version: 2.4
2
+ Name: python-gitmojis
3
+ Version: 1.1.0
4
+ Summary: 😜 The official Gitmoji Guide in Python projects 🐍
5
+ Author-email: Kamil Paduszyński <paduszyk@gmail.com>
6
+ Keywords: emoji,git,gitmoji
7
+ Classifier: Development Status :: 5 - Production/Stable
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Programming Language :: Python
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Programming Language :: Python :: 3.14
17
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
+ Requires-Python: >=3.10
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: click<9.0.0,>=8.4.2
22
+ Requires-Dist: requests<3.0.0,>=2.34.2
23
+ Dynamic: license-file
24
+
25
+ # python-gitmojis
26
+
27
+ [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?style=flat-square&logo=pre-commit)][pre-commit.ci]
28
+ [![github-build-workflow](https://img.shields.io/github/actions/workflow/status/paduszyk/python-gitmojis/build-package.yml?style=flat-square&logo=github)][github-build-workflow]
29
+ [![codecov](https://img.shields.io/codecov/c/github/paduszyk/python-gitmojis?style=flat-square&logo=codecov)][codecov]
30
+
31
+ [![nox](https://img.shields.io/badge/%F0%9F%A6%8A-Nox-D85E00.svg?style=flat-square)][nox]
32
+ [![ruff](https://img.shields.io/endpoint?style=flat-square&url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)][ruff]
33
+ [![mypy](https://img.shields.io/badge/type--checked-mypy-blue?style=flat-square)][mypy]
34
+ [![black](https://img.shields.io/badge/code%20style-black-black?style=flat-square)][black]
35
+
36
+ [![pypi-status](https://img.shields.io/pypi/status/python-gitmojis?style=flat-square&logo=pypi&logoColor=white)][pypi]
37
+ [![pypi-version](https://img.shields.io/pypi/v/python-gitmojis?style=flat-square&logo=pypi&logoColor=white)][pypi]
38
+ [![pypi-python-version](https://img.shields.io/pypi/pyversions/python-gitmojis?style=flat-square&logo=python&logoColor=white)][pypi]
39
+ [![pypi-license](https://img.shields.io/pypi/l/python-gitmojis?style=flat-square&label=license)][pypi]
40
+
41
+ ## Summary
42
+
43
+ This package provides a few simple utilities to apply the official
44
+ [Gitmoji Guide][gitmoji-website] in Python libraries. It may potentially serve
45
+ as a helper in projects related to version control systems, versioning, and
46
+ automatic changelog generation. Applications in automation tools for validating
47
+ commit and pull request messages seem feasible as well.
48
+
49
+ ## Features
50
+
51
+ - Handle individual Gitmojis and their lists using Python classes. 👔
52
+ - Fetch Gitmoji data directly from the official [Gitmoji API][gitmoji-api]. 😜
53
+ - Graceful degradation: If the API is unavailable, fall back to backup data. 🦺
54
+
55
+ ## Installation
56
+
57
+ It is recommended to install the package directly from PyPI using `pip`:
58
+
59
+ ```console
60
+ $ pip install python-gitmojis
61
+ ```
62
+
63
+ or any other dependency manager of your preference. After installation, the
64
+ package functionalities can be accessed by importing them from the `gitmojis`
65
+ module:
66
+
67
+ ```python
68
+ import gitmojis
69
+ ```
70
+
71
+ ## Usage
72
+
73
+ ### Data model
74
+
75
+ The data model incorporates two classes representing individual Gitmojis and
76
+ their collections ("guides"), namely, `Gitmoji` and `Guide`, respectively.
77
+
78
+ The classes are defined in `gitmojis.model`, but can also be accessed directly
79
+ from `gitmojis` as well:
80
+
81
+ ```python
82
+ from gitmojis import Gitmoji, Guide
83
+ ```
84
+
85
+ #### `gitmojis.model.Gitmoji`
86
+
87
+ The `Gitmoji` class is a Python `@dataclass` ([PEP 557][PEP-557]) that uses a
88
+ set of fields consistent with the [JSON schema][gitmoji-schema] proposed in the
89
+ original Gitmoji project, namely:
90
+
91
+ - `emoji: str` &ndash; the emoji character representing the Gitmoji;
92
+ - `entity: str` &ndash; the HTML entity of the Gitmoji;
93
+ - `code: str` &ndash; the emoji's code to be used in rendering Gitmojis in the
94
+ Markdown documents;
95
+ - `description: str` &ndash; a short note on the type of changes represented by
96
+ the commits or pull requests marked by the Gitmoji;
97
+ - `name: str` &ndash; a text identifier of the Gitmoji;
98
+ - `semver: str | None` &ndash; the [Semantic Versioning](https://semver.org)
99
+ level affected by the changes marked with the Gitmoji; the allowed string
100
+ values are `"major"`, `"minor"`, and `"patch"`.
101
+
102
+ The class can be used to create immutable objects representing individual
103
+ Gitmojis, for example:
104
+
105
+ ```python
106
+ from gitmojis import Gitmoji
107
+
108
+ gitmoji = Gitmoji(
109
+ emoji="🤖",
110
+ entity="&#x1f916",
111
+ code=":robot:",
112
+ description="Add or update Dependabot configuration.",
113
+ name="robot",
114
+ semver=None,
115
+ )
116
+
117
+ assert gitmoji.emoji == "🤖"
118
+ ```
119
+
120
+ > Note that when creating a new `Gitmoji` instance, all the `@dataclass` fields
121
+ > are required. Furthermore, they all must be passed as keyword arguments.
122
+
123
+ #### `gitmojis.model.Guide`
124
+
125
+ The `Guide` class aims to provide a custom list-like structure to manage a
126
+ collection of Gitmojis. Its instances are created simply by passing an iterable
127
+ of `Gitmoji` objects (as the `gitmojis` keyword argument) to the class
128
+ constructor:
129
+
130
+ ```python
131
+ from gitmojis import Gitmoji, Guide
132
+
133
+ gitmojis_json = [
134
+ {
135
+ "emoji" : "🤖",
136
+ "entity" : "&#x1f916",
137
+ "code" : ":robot:",
138
+ "description" : "Add or update Dependabot configuration.",
139
+ "name" : "robot",
140
+ "semver" : None,
141
+ },
142
+ # ...
143
+ ]
144
+
145
+ guide = Guide(
146
+ gitmojis=[Gitmoji(**gitmoji_json) for gitmoji_json in gitmojis_json]
147
+ )
148
+
149
+ assert guide[0].emoji == "🤖"
150
+ ```
151
+
152
+ The class is based on `collections.UserList`. Currently, it doesn't override
153
+ any base class methods nor does it implement any custom functionality.
154
+
155
+ ### Fetching Gitmojis from the API
156
+
157
+ The main package functionality is implemented as a plain Python function, named
158
+ `fetch_guide`. It can be imported either from `gitmojis` or directly from its
159
+ source, i.e. the `gitmojis.core` module.
160
+
161
+ Usage of the function is extremely easy. In the simplest case, it can be called
162
+ without any arguments:
163
+
164
+ ```python
165
+ from gitmojis import fetch_guide
166
+
167
+ guide = fetch_guide()
168
+ ```
169
+
170
+ The function uses the `requests` library to return a `Guide` instance containing
171
+ the current state of the official [Gitmoji API][gitmoji-api]. If the API is
172
+ inaccessible, the guide can be populated using the data retrieved from the local
173
+ backup file. Such behavior can be triggered by passing `True` as the value of
174
+ the `use_backup` keyword argument (it defaults to `False`):
175
+
176
+ ```python
177
+ from gitmojis import fetch_guide
178
+
179
+ guide = fetch_guide(use_backup=True) # will work even if you're offline
180
+ ```
181
+
182
+ ### Command-line interface (CLI)
183
+
184
+ The package comes with a simple CLI which can be run using the `gitmojis`
185
+ command:
186
+
187
+ ```console
188
+ $ gitmojis
189
+ Usage: gitmojis [OPTIONS] COMMAND [ARGS]...
190
+
191
+ Command-line interface for managing the official Gitmoji guide.
192
+
193
+ Options:
194
+ --use-backup Use the backup to fetch data if the API request fails.
195
+ --version Show the version and exit.
196
+ --help Show this message and exit.
197
+
198
+ Commands:
199
+ sync Synchronize the backup file with the current state of the API.
200
+ ```
201
+
202
+ As seen, currently the CLI provides only the `sync` command which can be used
203
+ to update the Gitmoji data backup file to the current state of the official API
204
+ endpoint.
205
+
206
+ > Checking for the updates of the API state is compared to the backup file by
207
+ > executing the `sync` command at GitHub Actions runner every week. The
208
+ > respective workflow automatically applies the updates and opens a pull
209
+ > request introducing them to the codebase. We plan to do the version bump (on
210
+ > a patch level) upon merging each of such pull requests. Therefore, to stay
211
+ > tuned with the Gitmoji API backed up by this library, you should update
212
+ > the package systematically. This particularly concerns the developers, who
213
+ > work with local repositories most of the time.
214
+
215
+ ## Contributing
216
+
217
+ This project is open-source and embraces contributions of all types. For
218
+ comprehensive instructions on how to contribute to the project, please refer to
219
+ our [Contributing Guide][contributing-guide].
220
+
221
+ We require all contributors to adhere to our [Code of Conduct][code-of-conduct].
222
+ While it may seem intricate at first glance, the essence is simple: treat
223
+ everyone with kindness! 🙂
224
+
225
+ ## Credits
226
+
227
+ The idea of Gitmoji was originally proposed, developed, and maintained by
228
+ Carlos Cuesta ([@carloscuesta][github-carlosquesta]). For more information, see
229
+ the official [repository][gitmoji-repository] and [website][gitmoji-website] of
230
+ the project.
231
+
232
+ ## Authors
233
+
234
+ Created by Kamil Paduszyński ([@paduszyk][github-paduszyk]).
235
+
236
+ ## License
237
+
238
+ Released under the [MIT License][license].
239
+
240
+ [black]: https://github.com/psf/black
241
+ [code-of-conduct]: https://github.com/paduszyk/python-gitmojis/blob/main/.github/CODE_OF_CONDUCT.md
242
+ [codecov]: https://app.codecov.io/gh/paduszyk/python-gitmojis
243
+ [contributing-guide]: https://github.com/paduszyk/python-gitmojis/blob/main/.github/CONTRIBUTING.md
244
+ [github-build-workflow]: https://github.com/paduszyk/python-gitmojis/actions/workflows/build-package.yml
245
+ [github-carlosquesta]: https://github.com/carloscuesta
246
+ [github-paduszyk]: https://github.com/paduszyk
247
+ [gitmoji-api]: https://github.com/carloscuesta/gitmoji/tree/master/packages/gitmojis#api
248
+ [gitmoji-repository]: https://github.com/carloscuesta/gitmoji
249
+ [gitmoji-schema]: https://github.com/carloscuesta/gitmoji/blob/master/packages/gitmojis/src/schema.json
250
+ [gitmoji-website]: https://gitmoji.dev
251
+ [license]: https://github.com/paduszyk/python-gitmojis/blob/main/LICENSE
252
+ [mypy]: https://github.com/python/mypy
253
+ [nox]: https://github.com/wntrblm/nox
254
+ [pep-557]: https://peps.python.org/pep-0557/
255
+ [pre-commit.ci]: https://results.pre-commit.ci/latest/github/paduszyk/python-gitmojis/main
256
+ [pypi]: https://pypi.org/project/python-gitmojis/
257
+ [ruff]: https://github.com/astral-sh/ruff
@@ -0,0 +1,15 @@
1
+ gitmojis/__init__.py,sha256=cFSBvuzXrwJzX6b5TF1m7aY9tyAWj2qb_pW7IgAzCOQ,126
2
+ gitmojis/__main__.py,sha256=TpZKhx32bh5RqAsGuHtNYcB75tPbthqkUfwlXGyyHfI,85
3
+ gitmojis/core.py,sha256=sYj9goHiurbks7CmuET5Hw4XYLdR9pCTv9dlBbX_aic,1871
4
+ gitmojis/defaults.py,sha256=kNrtmSUohor-WrM-H3EilyaPC7-9qEOfw9_vqZHFgXU,252
5
+ gitmojis/exceptions.py,sha256=kzJUWNxtW42kYe2OovBOwOhDLZnhwmTiFsINh8k4Ekg,418
6
+ gitmojis/model.py,sha256=u_PbVBslbWDMl6zcuQ_nwp9bhtozewOeDRBlY_sCYIo,1974
7
+ gitmojis/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ gitmojis/cli/__init__.py,sha256=mkPm04uX4jBP8Lm6uwBH82LL7zwQj3uuzQuPTvHvLcY,1015
9
+ gitmojis/cli/commands.py,sha256=AxJoE0cee8UzROdFbZWSJ74jTWW3-PqVX3kK-bPU_HU,754
10
+ python_gitmojis-1.1.0.dist-info/licenses/LICENSE,sha256=DGTOQe3hoUVVVxkAQq6G5colipirMi1t39vhJ0FIkFE,1080
11
+ python_gitmojis-1.1.0.dist-info/METADATA,sha256=Kck2cEB4hvLeRpaWKirSYWmRGZSKZLenZx9duY7dEAs,9903
12
+ python_gitmojis-1.1.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
13
+ python_gitmojis-1.1.0.dist-info/entry_points.txt,sha256=ikh4RpFvqZT85TD0aUtoOT7C6LbaKNV0RU-iPNXCv1g,52
14
+ python_gitmojis-1.1.0.dist-info/top_level.txt,sha256=hEF9XSDmvmTWl3k8rl92pxO-pG7vEC9EqHjXQkoyY_k,9
15
+ python_gitmojis-1.1.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.41.2)
2
+ Generator: setuptools (83.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ gitmojis = gitmojis.__main__:main
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2023 Kamil Paduszyński
3
+ Copyright (c) 2023-2026 Kamil Paduszyński
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal