Skip to content

Instantly share code, notes, and snippets.

@c80609a
Created April 1, 2025 04:38
Show Gist options
  • Save c80609a/1b061924f6a54533ec5c29c8c32a27ec to your computer and use it in GitHub Desktop.
Save c80609a/1b061924f6a54533ec5c29c8c32a27ec to your computer and use it in GitHub Desktop.
Flask restfule representations example

В классе Resource из библиотеки flask_restful атрибут representations используется для определения форматов, в которых ресурс может возвращать данные. Это позволяет вам указать, как данные должны быть представлены в ответе в зависимости от заголовка Accept в запросе.

Вот пример, как можно использовать representations в классе Resource:

from flask import Flask, Response
from flask_restful import Api, Resource, marshal_with, fields
from flask_restful.representations.json import output_json
from typing import Any, Dict, Optional

app = Flask(__name__)
api = Api(app)

# Define the data representation format
def output_xml(data: Any, code: int, headers: Optional[Dict[str, str]] = None) -> Response:
    """
    Convert data to XML format and create a Flask response.

    :param data: The data to be represented in XML format.
                 — это данные, которые возвращает метод `get`. 
    :param code: The HTTP status code.
    :param headers: Optional headers to include in the response.
    :return: A Flask Response object with XML data.
    """
    # Example of converting data to XML
    xml_data = '<data>' + str(data) + '</data>'
    resp = app.make_response(xml_data, code)
    resp.headers.extend(headers or {})
    return resp

# Resource class
class MyResource(Resource):
    # Specify available data representation formats
    representations = {
        'application/json': output_json,
        'application/xml': output_xml,
    }

    @marshal_with({'message': fields.String})
    def get(self) -> Dict[str, str]:
        """
        Handle GET requests and return a message.

        :return: A dictionary with a message.
        """
        return {'message': 'Hello, World!'}

# Add the resource to the API
api.add_resource(MyResource, '/')

if __name__ == '__main__':
    app.run(debug=True)

В этом примере мы добавили поддержку XML в качестве формата представления данных. Метод output_xml преобразует данные в XML-формат. Затем мы указали этот метод в representations класса MyResource. Теперь, когда клиент отправляет запрос с заголовком Accept: application/xml, данные будут возвращены в формате XML. В этом примере output_xml принимает данные, которые возвращает метод get, и преобразует их в XML-формат. Затем создается объект Response, который возвращается клиенту.

Вот цепочка вызовов для примера использования representations в классе Resource, представленная в виде вложенных списков:

  1. Клиент отправляет HTTP GET запрос на /

    • Заголовок Accept может быть application/json или application/xml.
  2. Flask принимает запрос

    • Flask передает управление в flask_restful.Api.
  3. Api обрабатывает запрос

    • Вызывает метод dispatch_request класса Resource.
  4. MyResource.dispatch_request

    • Определяет метод HTTP (в данном случае GET).
    • Вызывает метод get.
  5. MyResource.get

    • Возвращает данные: {'message': 'Hello, World!'}.
  6. marshal_with декоратор

    • Применяет маршалинг к данным, используя указанные поля.
  7. MyResource.representations

    • Определяет, какой метод использовать для представления данных в зависимости от заголовка Accept.
    • Если Accept: application/json, используется output_json.
    • Если Accept: application/xml, используется output_xml.
  8. Метод представления данных

    • Преобразует данные в указанный формат.
    • Создает объект ответа с преобразованными данными.
  9. Flask возвращает ответ клиенту

    • Ответ содержит данные в формате, указанном в заголовке Accept.

Эта последовательность показывает, как запрос обрабатывается от момента его получения до отправки ответа клиенту, с учетом использования representations для выбора формата данных.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment