Skip to content

Commit

Permalink
typehints (succeeds mypy --disallow-untyped-defs)
Browse files Browse the repository at this point in the history
  • Loading branch information
tassaron committed Jul 23, 2023
1 parent e2b11ec commit 866c9fa
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 125 deletions.
29 changes: 21 additions & 8 deletions dnd_character/SRD.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,24 @@
import json
from os import environ, walk, path, remove, mkdir
import logging
from typing import Callable, Optional


LOG = logging.getLogger(__package__)
LOG.setLevel(logging.DEBUG)


class DecoratedAPICallable:
"""Type for decorated API call"""

def __init__(self, func: Callable[[str], dict]):
self.func = func
self.cache: dict[str, dict] = {}

def __call__(self, uri: str) -> dict:
return self.func(uri)


try:
JSON_CACHE = f"{path.dirname(path.abspath(__file__))}/json_cache"
if not path.exists(JSON_CACHE):
Expand All @@ -19,12 +31,13 @@
LOG.error(f"Entire JSON cache failed to load: {str(e)}")


def cached_json(func):
def cached_json(func: Callable[[str], dict]) -> Callable[[str], dict]:
"""
Decorator which caches REST get requests into a dict
and saves them to JSON files so the cache can be reloaded
Decorator which caches REST HTTP-get requests into a dict
and saves them to JSON files so the cache can be reloaded.
This adds a new `cache` attribute to the decorated function
"""
func.cache = {}
func = DecoratedAPICallable(func)
for dirname, __, files in walk(JSON_CACHE):
for fp in files:
if path.splitext(fp)[1] != ".json":
Expand All @@ -37,8 +50,8 @@ def cached_json(func):
LOG.error(f"{fp} failed to load: {str(e)}")
remove(f"{dirname}/{fp}")

def outer_wrapper(func):
def inner_wrapper(uri):
def outer_wrapper(func: DecoratedAPICallable) -> Callable[[str], dict]:
def inner_wrapper(uri: str) -> dict:
try:
return func.cache[uri]
except KeyError:
Expand All @@ -54,14 +67,14 @@ def inner_wrapper(uri):
return outer_wrapper(func)


def __SRD_API_CALL():
def __SRD_API_CALL() -> Callable[[str], dict]:
"""
Closure for API calls
"""
SRD_API = environ.get("SRD_API", "http://dnd5eapi.co")

@cached_json
def get_from_SRD(uri):
def get_from_SRD(uri: str) -> dict:
import requests

LOG.warning(f"Live API request! {str(uri)}")
Expand Down
2 changes: 1 addition & 1 deletion dnd_character/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
CLASS_NAMES = list(CLASSES.keys())


def main():
def main() -> None:
parser = argparse.ArgumentParser(
prog="dnd-character",
description="generate D&D 5e character sheet from terminal",
Expand Down
Loading

0 comments on commit 866c9fa

Please sign in to comment.