Skip to content

Grand Comics Database

GrandComicsDatabase

Class with functionality to request GCD API endpoints.

PARAMETER DESCRIPTION
email

The user's GCD email address, which is used for authentication.

TYPE: str

password

The user's GCD password, which is used for authentication.

TYPE: str

cache

SQLiteCache to use if set.

TYPE: SQLiteCache | None

base_url

Root URL of the GCD API.

TYPE: str DEFAULT: 'https://www.comics.org/api'

user_agent

Value sent in the User-Agent request header.

TYPE: str | None DEFAULT: None

timeout

Set how long requests will wait for a response (in seconds).

TYPE: float DEFAULT: 30

limiter

Set a custom limiter, used for testing.

TYPE: Limiter DEFAULT: Limiter(RATELIMIT_BUCKET)

Source code in grayven/grand_comics_database.py
Python
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
def __init__(
    self,
    email: str,
    password: str,
    cache: SQLiteCache | None,
    base_url: str = "https://www.comics.org/api",
    user_agent: str | None = None,
    timeout: float = 30,
    limiter: Limiter = Limiter(RATELIMIT_BUCKET),  # noqa: B008
):
    self._base_url = base_url
    self._client = Client(
        base_url=self._base_url,
        headers={
            "Accept": "application/json",
            "User-Agent": user_agent
            or f"Grayven/{__version__} ({platform.system()}: {platform.release()}; Python v{platform.python_version()})",  # noqa: E501
        },
        auth=BasicAuth(username=email, password=password),
        params={"format": "json"},
        timeout=timeout,
        transport=RateLimiterTransport(limiter),
    )
    self._cache = cache

Functions

get_issue

Request an Issue using its id.

PARAMETER DESCRIPTION
issue_id

The Issue id.

TYPE: int

RETURNS DESCRIPTION
Issue

A Issue object.

RAISES DESCRIPTION
ServiceError

If the API response is invalid or validation fails.

AuthenticationError

If credentials are invalid.

RateLimitError

If the API rate limit is exceeded.

Source code in grayven/grand_comics_database.py
Python
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
def get_issue(self, issue_id: int) -> Issue:
    """Request an Issue using its id.

    Args:
        issue_id: The Issue id.

    Returns:
        A Issue object.

    Raises:
        ServiceError: If the API response is invalid or validation fails.
        AuthenticationError: If credentials are invalid.
        RateLimitError: If the API rate limit is exceeded.
    """
    try:
        result = self._fetch_item(endpoint=f"/issue/{issue_id}")
        return TypeAdapter(Issue).validate_python(result)
    except ValidationError as err:
        raise ServiceError(err) from err

get_publisher

Request a Publisher using its id.

PARAMETER DESCRIPTION
publisher_id

The Publisher id.

TYPE: int

RETURNS DESCRIPTION
Publisher

A Publisher object.

RAISES DESCRIPTION
ServiceError

If the API response is invalid or validation fails.

AuthenticationError

If credentials are invalid.

RateLimitError

If the API rate limit is exceeded.

Source code in grayven/grand_comics_database.py
Python
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
def get_publisher(self, publisher_id: int) -> Publisher:
    """Request a Publisher using its id.

    Args:
        publisher_id: The Publisher id.

    Returns:
        A Publisher object.

    Raises:
        ServiceError: If the API response is invalid or validation fails.
        AuthenticationError: If credentials are invalid.
        RateLimitError: If the API rate limit is exceeded.
    """
    try:
        result = self._fetch_item(endpoint=f"/publisher/{publisher_id}")
        return TypeAdapter(Publisher).validate_python(result)
    except ValidationError as err:
        raise ServiceError(err) from err

get_series

Request a Series using its id.

PARAMETER DESCRIPTION
series_id

The Series id.

TYPE: int

RETURNS DESCRIPTION
Series

A Series object.

RAISES DESCRIPTION
ServiceError

If the API response is invalid or validation fails.

AuthenticationError

If credentials are invalid.

RateLimitError

If the API rate limit is exceeded.

Source code in grayven/grand_comics_database.py
Python
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
def get_series(self, series_id: int) -> Series:
    """Request a Series using its id.

    Args:
        series_id: The Series id.

    Returns:
        A Series object.

    Raises:
        ServiceError: If the API response is invalid or validation fails.
        AuthenticationError: If credentials are invalid.
        RateLimitError: If the API rate limit is exceeded.
    """
    try:
        result = self._fetch_item(endpoint=f"/series/{series_id}")
        return TypeAdapter(Series).validate_python(result)
    except ValidationError as err:
        raise ServiceError(err) from err

list_issues

Request a list of Issues.

PARAMETER DESCRIPTION
series_name

The name of the series to filter issues from.

TYPE: str

issue_number

The number to filter issues by.

TYPE: int

year

Filter the results using the issue year via its key_date.

TYPE: int | None DEFAULT: None

max_results

Maximum number of results to retrieve.

TYPE: int DEFAULT: 500

RETURNS DESCRIPTION
list[BasicIssue]

A list of Issue objects.

RAISES DESCRIPTION
ServiceError

If the API response is invalid or validation fails.

AuthenticationError

If credentials are invalid.

RateLimitError

If the API rate limit is exceeded.

Source code in grayven/grand_comics_database.py
Python
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
def list_issues(
    self, series_name: str, issue_number: int, year: int | None = None, max_results: int = 500
) -> list[BasicIssue]:
    """Request a list of Issues.

    Args:
        series_name: The name of the series to filter issues from.
        issue_number: The number to filter issues by.
        year: Filter the results using the issue year via its key_date.
        max_results: Maximum number of results to retrieve.

    Returns:
        A list of Issue objects.

    Raises:
        ServiceError: If the API response is invalid or validation fails.
        AuthenticationError: If credentials are invalid.
        RateLimitError: If the API rate limit is exceeded.
    """
    try:
        if year is None:
            results = self._fetch_list(
                endpoint=f"/series/name/{series_name}/issue/{issue_number}",
                max_results=max_results,
            )
        else:
            results = self._fetch_list(
                endpoint=f"/series/name/{series_name}/issue/{issue_number}/year/{year}",
                max_results=max_results,
            )
        return TypeAdapter(list[BasicIssue]).validate_python(results)
    except ValidationError as err:
        raise ServiceError(err) from err

list_onsale_weekly_issues

Request a list of issues on sale in a given ISO week.

PARAMETER DESCRIPTION
year

The ISO year (4-digit year).

TYPE: int

week

The ISO week number (1-53).

TYPE: int

max_results

Maximum number of results to retrieve.

TYPE: int DEFAULT: 500

RETURNS DESCRIPTION
list[BasicIssue]

List of BasicIssue objects representing issues that went on sale during the given week.

RAISES DESCRIPTION
ServiceError

If the API response is invalid or validation fails.

AuthenticationError

If credentials are invalid.

RateLimitError

If the API rate limit is exceeded.

Source code in grayven/grand_comics_database.py
Python
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
def list_onsale_weekly_issues(
    self, year: int, week: int, max_results: int = 500
) -> list[BasicIssue]:
    """Request a list of issues on sale in a given ISO week.

    Args:
        year: The ISO year (4-digit year).
        week: The ISO week number (1-53).
        max_results: Maximum number of results to retrieve.

    Returns:
        List of BasicIssue objects representing issues that went on sale during the given week.

    Raises:
        ServiceError: If the API response is invalid or validation fails.
        AuthenticationError: If credentials are invalid.
        RateLimitError: If the API rate limit is exceeded.
    """
    try:
        results = self._fetch_list(
            endpoint=f"/issue/on_sale_weekly/{year}/week/{week}", max_results=max_results
        )
        return TypeAdapter(list[BasicIssue]).validate_python(results)
    except ValidationError as err:
        raise ServiceError(err) from err

list_publishers

Request a list of Publishers.

PARAMETER DESCRIPTION
max_results

Maximum number of results to retrieve.

TYPE: int DEFAULT: 500

RETURNS DESCRIPTION
list[Publisher]

A list of Publisher objects.

RAISES DESCRIPTION
ServiceError

If the API response is invalid or validation fails.

AuthenticationError

If credentials are invalid.

RateLimitError

If the API rate limit is exceeded.

Source code in grayven/grand_comics_database.py
Python
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
def list_publishers(self, max_results: int = 500) -> list[Publisher]:
    """Request a list of Publishers.

    Args:
        max_results: Maximum number of results to retrieve.

    Returns:
        A list of Publisher objects.

    Raises:
        ServiceError: If the API response is invalid or validation fails.
        AuthenticationError: If credentials are invalid.
        RateLimitError: If the API rate limit is exceeded.
    """
    try:
        results = self._fetch_list(endpoint="/publisher", max_results=max_results)
        return TypeAdapter(list[Publisher]).validate_python(results)
    except ValidationError as err:
        raise ServiceError(err) from err

list_series

Request a list of Series.

PARAMETER DESCRIPTION
name

Filter the results using the series name.

TYPE: str | None DEFAULT: None

year

Filter the results using the series beginning year (Requires name to be passed).

TYPE: int | None DEFAULT: None

max_results

Maximum number of results to retrieve.

TYPE: int DEFAULT: 500

RETURNS DESCRIPTION
list[Series]

A list of Series objects.

RAISES DESCRIPTION
ServiceError

If the API response is invalid or validation fails.

AuthenticationError

If credentials are invalid.

RateLimitError

If the API rate limit is exceeded.

Source code in grayven/grand_comics_database.py
Python
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
def list_series(
    self, name: str | None = None, year: int | None = None, max_results: int = 500
) -> list[Series]:
    """Request a list of Series.

    Args:
        name: Filter the results using the series name.
        year: Filter the results using the series beginning year (Requires name to be passed).
        max_results: Maximum number of results to retrieve.

    Returns:
        A list of Series objects.

    Raises:
        ServiceError: If the API response is invalid or validation fails.
        AuthenticationError: If credentials are invalid.
        RateLimitError: If the API rate limit is exceeded.
    """
    try:
        if name is None:
            results = self._fetch_list(endpoint="/series", max_results=max_results)
        elif year is None:
            results = self._fetch_list(endpoint=f"/series/name/{name}", max_results=max_results)
        else:
            results = self._fetch_list(
                endpoint=f"/series/name/{name}/year/{year}", max_results=max_results
            )
        return TypeAdapter(list[Series]).validate_python(results)
    except ValidationError as err:
        raise ServiceError(err) from err