Django LRU_Cache с помощью вызовов API

Я пытаюсь использовать API Reddit через PRAW (https://praw.readthedocs.io/en/stable/) в Django и думаю попробовать использовать декоратор functools lru_cache для реализации некоторого вида кэширования, чтобы я мог кэшировать результаты похожих вызовов API для уменьшения общего количества вызовов. Я никогда не делал ничего подобного, поэтому в основном слежу за примерами реализации декоратора @lru_cache.

У меня есть 3 файла, которые в основном связаны с вызовами API / отображением здесь. У меня есть:

account.html

{% extends 'myapp/base.html' %}
<h1> {{ name }} </h1>
<h3> {{ comment_karma }} </h3>

<h5> Top Posts </h5>
<table>
    <tr>
        <th> Post </th>
        <th> Subreddit </th>
    </tr>
    {% for s in top_submissions %}
        <tr>
           <td> {{ s.title }} </td>
            <td> {{ s.subreddit }} </td>
        </tr>
    {% endfor %}
</table>

views.py

from . import reddit

reddit = reddit.Reddit()

def account_page():
    context = reddit.details(request.user.reddit_username)
    return render(request, 'stats/dashboard.html', context)

reddit.py

 from functools import lru_cache

 class Reddit:
    def __init__(self):
        self.praw = praw.Reddit(
            client_id = CLIENT_ID,
            client_secret = CLIENT_SECRET,
            user_agent = USER_AGENT
        )

     @lru_cache(maxsize = 256)
     def details(self, redditor):
        redditor = self.praw.redditor(redditor)

        overview = {
            'name': redditor.name,
            'comment_karma': redditor.comment_karma,
            'top_submissions': redditor.submissions.top(limit=10),
        }
        return overview

Вот в чем проблема: когда у меня нет lru_cache, то все работает нормально и все данные приходят как всегда. Однако, когда я устанавливаю опцию lru_cache, то приходят только имя и comment_karma, а submissions (итерируемый список) просто не отображается на моей странице (поэтому я предполагаю, что он не имеет никаких значений).

Я неправильно использую lru_cache? По сути, моя цель состоит в том, что если redditor передается в функцию overview, я не хочу продолжать делать одни и те же вызовы API снова и снова, а вместо этого хочу поместить его в кэш и извлечь те же данные, если они есть в кэше.

PRAW возвращает объекты генератора, которые лениво оцениваются. Вы хотите оценивать их внутри вашей кэшированной функции. В противном случае после исчерпания генератора вы не сможете получить результаты снова.

Таким образом, рабочая версия должна выглядеть следующим образом:

     @lru_cache(maxsize = 256)
     def details(self, redditor):
        redditor = self.praw.redditor(redditor)

        overview = {
            'name': redditor.name,
            'comment_karma': redditor.comment_karma,
            'top_submissions': list(redditor.submissions.top(limit=10)),
        }
        return overview

list(redditor.submissions.top(limit=10)) будет потреблять генератор, и кэшированный результат будет содержать список, а не объект генератора, который может быть потреблен только один раз.

Вернуться на верх