Реализация интерфейсов Typescript в Python

Я ищу несколько советов о том, как лучше всего реализовать набор только "интерфейсов" значений данных в Python, которые эквивалентны их аналогу в машинописном тексте (у нас есть проект, в котором мы используем оба, и мы хотим обеспечить согласованный интерфейс для их связи, который будет через сериализацию python в json для втягивания в компонент TS)

Интерфейсы будут представлять собой композиции, которые сохранят модульность и простоту.

Учитывая набор интерфейсов TS, определенных как:

interface TestOutput {
  phantom: string
  testDateTime: datetime
  author: string
  result: boolean
  report_summaryFile?: string // the '?' means this field is optional
  // ... more values
  series: Array<Series>
  soloImages: Array<Images>
}

interface Series {
  number: number
  filter: string
  kernel: string
  // ... more values
  images: Array<TestImage>
}

Я думал об использовании классов данных и делал следующее:

from dataclasses import dataclass
from typing import List
import datetime

@dataclass
class TestSeries:
    seriesNum: int 
    modality: str 
    description: str = ''

@dataclass
class TestOutput:
    phantom: str 
    testDateTime: datetime.datetime
    author: str 
    result: bool
    series: List[TestSeries]
    soloImages: List[Images]
    report_summaryFile: str = ''

Классы данных - лучший подход для этого?

1 ответ

Решение

Pydantic - хорошая библиотека.
Я сделал нечто подобное, но только для классов данных - ValidatedDC:

from dataclasses import dataclass
from typing import List

from validated_dc import ValidatedDC
import json


@dataclass
class Series(ValidatedDC):
    series_num: int
    modality: str
    description: str = ''


@dataclass
class Output(ValidatedDC):
    phantom: str
    date_time: str
    author: str
    result: bool
    series: List[Series]
    report_summary_file: str = ''


# For example, by API we got a JSON string:
input_json_string = '''
    {
        "phantom": "test_phantom",
        "date_time": "2020.01.01",
        "author": "Peter",
        "result": true,
        "series": [{
            "series_num": 1,
            "modality": "test_modality"
        }]
    }
'''

# Load the string into the dictionary:
input_data = json.loads(input_json_string)

# Then create a dataclass to check the types of values and for the
# convenience of further work with data:
output = Output(**input_data)

# Since valid data were obtained, there are no errors
assert output.get_errors() is None

# Let's say we got data with an error:
input_data['series'][0]['series_num'] = '1'  # The string is not an integer!

output = Output(**input_data)
assert output.get_errors()
print(output.get_errors())
# {
#    'series': [
#        InstanceValidationError(
#            value_repr="{'series_num': '1', 'modal...}",
#            value_type=<class 'dict'>,
#            annotation=<class '__main__.Series'>, exception=None,
#            errors={
#                'series_num': [
#                    BasicValidationError(
#                        value_repr='1', value_type=<class 'str'>,
#                        annotation=<class 'int'>, exception=None
#                    )
#                ]
#            }
#        ),
#        ListValidationError(
#            item_index=0, item_repr="{'series_num': '1', 'modal...}",
#            item_type=<class 'dict'>, annotation=<class '__main__.Series'>
#        )
#    ]
# }

Подробнее см. Здесь:
https://github.com/EvgeniyBurdin/validated_dc

Другие вопросы по тегам