Я столкнулся с ошибкой TypeError: string indices must be integers, not 'str'. Как можно ее исправить?

Привет всем! У меня есть страница, на которой отображаются сервера, управляемые пользователем. Для реализации этой функциональности я использую две функции: <code class="python">get_user_guilds</code>, которая получает список всех серверов пользователя, и <code class="python">get_user_managed_servers</code>, которая из этого списка фильтрует только те серверы, где у пользователя есть права администратора. 

Вот сам код: 
<pre><code class="python">@app.route('/servers')
@require_auth
def select_server():
    guilds = get_user_guilds()
    user_servers = get_user_managed_servers(guilds)

    return render_template('select-server.html', user_servers=user_servers)</code></pre>

Также я определил функцию <code class="python">get_user_guilds</code>:
<pre><code class="python">def get_user_guilds():
    oauth2_token = session.get('oauth2_token')
    discord = make_session(token=oauth2_token)
    return discord.get(API_BASE_URL + '/users/@me/guilds').json()</code></pre>

И функцию <code class="python">get_user_managed_servers</code>:
<pre><code class="python">def get_user_managed_servers(guilds):
    return list(
        filter(
            lambda g: (g['owner'] is True) or
            bool((int(g['permissions']) >> 5) & 1),
            guilds)
    )</code></pre>

Кроме того, у меня есть обертка (wrap), которая используется на странице сервера для проверки прав администратора пользователя:
<pre><code class="python">def require_bot_admin(f):
    @wraps(f)
    def wrapper(*args, **kwargs):
        server_id = kwargs.get('server_id')

        guilds = get_user_guilds()
        user_servers = get_user_managed_servers(guilds)

        if str(server_id) not in map(lambda g: g['id'], user_servers):
            return redirect(url_for('select_server'))

        return f(*args, **kwargs)
    return wrapper</code></pre>

Во вложении представлю и код для страницы сервера: 
<pre><code class="python">@app.rout...
  • 11 февраля 2025 г. 9:24
Ответы на вопрос 1
Ошибка `TypeError: string indices must be integers, not 'str'` чаще всего возникает, когда вы пытаетесь получить доступ к элементам строкового объекта, как если бы он был словарем. В вашем коде это может произойти, если вы ожидаете, что `guilds` будет списком словарей, но на самом деле это строка или что-то иное.

Чтобы выяснить, где конкретно происходит ошибка, я бы рекомендовал добавить несколько отладочных утверждений (например, `print`), чтобы просмотреть переменные на разных стадиях выполнения программы. Также стоит убедиться, что API, который вы используете (в данном случае Discord API), возвращает данные в ожидаемом формате.

Вот что вы можете сделать для устранения проблемы:

1. Убедитесь, что ответ от API действительно является списком, содержащим словари. Попробуйте добавить отладочный вывод для `guilds` в функции `select_server`:

    ```python
    @app.route('/servers')
    @require_auth
    def select_server():
        guilds = get_user_guilds()
        print('Guilds:', guilds)  # Отладочный вывод
        user_servers = get_user_managed_servers(guilds)
        return render_template('select-server.html', user_servers=user_servers)
    ```

2. Также добавьте вывод внутри функции `get_user_guilds`:

    ```python
    def get_user_guilds():
        oauth2_token = session.get('oauth2_token')
        discord = make_session(token=oauth2_token)
        response = discord.get(API_BASE_URL + '/users/@me/guilds').json()
        print('Response:', response)  # Отладочный вывод
        return response
    ```

3. Убедитесь, что `guilds` в `get_user_managed_servers` - это список словарей. Добавьте логирование в эту функцию:

    ```python
    def get_user_managed_servers(guilds):
        print('Guilds being filtered:', guilds)  # Отладочный вывод
        return list(
            filter(
                lambda g: (g['owner'] is True) or
                bool((int(g['permissions']) >> 5) & 1),
                guilds)
        )
    ```

4. Проверьте, что `g['id']` в функции `require_bot_admin` также доступен. Возможно, там также стоит добавить проверку типа:

    ```python
    server_ids = map(lambda g: g['id'], user_servers)
    if str(server_id) not in server_ids:
        return redirect(url_for('select_server'))
    ```

После добавления отладочных выводов, выполните приложение и обратите внимание на вывод в консоли, чтобы определить, где данные становятся некорректными. Так вы сможете более точно найти и устранить источник ошибки.
Похожие вопросы