revisit 0.0.8__tar.gz → 0.0.10__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {revisit-0.0.8 → revisit-0.0.10}/PKG-INFO +2 -2
- {revisit-0.0.8 → revisit-0.0.10}/README.md +1 -1
- {revisit-0.0.8 → revisit-0.0.10}/pyproject.toml +1 -1
- {revisit-0.0.8 → revisit-0.0.10}/src/revisit/models.py +260 -1
- {revisit-0.0.8 → revisit-0.0.10}/src/revisit/revisit.py +27 -15
- {revisit-0.0.8 → revisit-0.0.10}/.gitignore +0 -0
- {revisit-0.0.8 → revisit-0.0.10}/src/revisit/__init__.py +0 -0
- {revisit-0.0.8 → revisit-0.0.10}/src/revisit/static/widget.css +0 -0
- {revisit-0.0.8 → revisit-0.0.10}/src/revisit/static/widget.js +0 -0
- {revisit-0.0.8 → revisit-0.0.10}/src/revisit/widget.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: revisit
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.10
|
4
4
|
Requires-Dist: anywidget
|
5
5
|
Requires-Dist: ipykernel>=6.29.5
|
6
6
|
Requires-Dist: pydantic>=2.10.5
|
@@ -63,7 +63,7 @@ in the notebook.
|
|
63
63
|
## CODE GEN
|
64
64
|
|
65
65
|
```bash
|
66
|
-
datamodel-codegen --input StudyConfigSchema.json --output models.py --custom-template-dir custom_templates --output-model-type pydantic_v2.BaseModel --additional-imports typing.TypedDict --input-file-type jsonschema --special-field-name-prefix we_are_going_to_replace_this && sed -i '' 's/we_are_going_to_replace_this_//g' src/revisit/models.py
|
66
|
+
datamodel-codegen --input StudyConfigSchema.json --output src/revisit/models.py --custom-template-dir custom_templates --output-model-type pydantic_v2.BaseModel --additional-imports "typing.TypedDict, warnings" --input-file-type jsonschema --special-field-name-prefix we_are_going_to_replace_this && sed -i '' 's/we_are_going_to_replace_this_//g' src/revisit/models.py
|
67
67
|
```
|
68
68
|
|
69
69
|
## TESTS
|
@@ -52,7 +52,7 @@ in the notebook.
|
|
52
52
|
## CODE GEN
|
53
53
|
|
54
54
|
```bash
|
55
|
-
datamodel-codegen --input StudyConfigSchema.json --output models.py --custom-template-dir custom_templates --output-model-type pydantic_v2.BaseModel --additional-imports typing.TypedDict --input-file-type jsonschema --special-field-name-prefix we_are_going_to_replace_this && sed -i '' 's/we_are_going_to_replace_this_//g' src/revisit/models.py
|
55
|
+
datamodel-codegen --input StudyConfigSchema.json --output src/revisit/models.py --custom-template-dir custom_templates --output-model-type pydantic_v2.BaseModel --additional-imports "typing.TypedDict, warnings" --input-file-type jsonschema --special-field-name-prefix we_are_going_to_replace_this && sed -i '' 's/we_are_going_to_replace_this_//g' src/revisit/models.py
|
56
56
|
```
|
57
57
|
|
58
58
|
## TESTS
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# generated by datamodel-codegen:
|
2
2
|
# filename: StudyConfigSchema.json
|
3
|
-
# timestamp: 2025-01-
|
3
|
+
# timestamp: 2025-01-11T22:20:26+00:00
|
4
4
|
|
5
5
|
from __future__ import annotations
|
6
6
|
|
@@ -53,6 +53,7 @@ class Type(Enum):
|
|
53
53
|
image = 'image'
|
54
54
|
website = 'website'
|
55
55
|
questionnaire = 'questionnaire'
|
56
|
+
vega = 'vega'
|
56
57
|
|
57
58
|
|
58
59
|
class Order(Enum):
|
@@ -1490,6 +1491,238 @@ class ResponseType(TypedDict):
|
|
1490
1491
|
warnings.filterwarnings("ignore", module="pydantic")
|
1491
1492
|
|
1492
1493
|
|
1494
|
+
class VegaComponentConfig(BaseModel):
|
1495
|
+
model_config = ConfigDict(extra='forbid', populate_by_name=True)
|
1496
|
+
allowFailedTraining: Optional[bool] = Field(
|
1497
|
+
None,
|
1498
|
+
description='Controls whether the component should allow failed training. If not provided, the default is true.',
|
1499
|
+
)
|
1500
|
+
config: Dict[str, Any] = Field(..., description='The vega-lite configuration.')
|
1501
|
+
correctAnswer: Optional[List[Answer]] = Field(
|
1502
|
+
None,
|
1503
|
+
description='The correct answer to the component. This is used for training trials where the user is shown the correct answer after a guess.',
|
1504
|
+
)
|
1505
|
+
description: Optional[str] = Field(
|
1506
|
+
None,
|
1507
|
+
description='The description of the component. This is used to identify and provide additional information for the component in the admin panel.',
|
1508
|
+
)
|
1509
|
+
instruction: Optional[str] = Field(
|
1510
|
+
None,
|
1511
|
+
description='The instruction of the component. This is used to identify and provide additional information for the component in the admin panel.',
|
1512
|
+
)
|
1513
|
+
instructionLocation: Optional[ResponseBlockLocation] = Field(
|
1514
|
+
None, description='The location of the instructions.'
|
1515
|
+
)
|
1516
|
+
meta: Optional[Dict[str, Any]] = Field(
|
1517
|
+
None,
|
1518
|
+
description='The meta data for the component. This is used to identify and provide additional information for the component in the admin panel.',
|
1519
|
+
)
|
1520
|
+
nextButtonDisableTime: Optional[float] = Field(
|
1521
|
+
None,
|
1522
|
+
description='A timeout (in ms) after which the next button will be disabled.',
|
1523
|
+
)
|
1524
|
+
nextButtonEnableTime: Optional[float] = Field(
|
1525
|
+
None, description='A timer (in ms) after which the next button will be enabled.'
|
1526
|
+
)
|
1527
|
+
nextButtonLocation: Optional[ResponseBlockLocation] = Field(
|
1528
|
+
None, description='The location of the next button.'
|
1529
|
+
)
|
1530
|
+
nextButtonText: Optional[str] = Field(
|
1531
|
+
None, description='The text that is displayed on the next button.'
|
1532
|
+
)
|
1533
|
+
provideFeedback: Optional[bool] = Field(
|
1534
|
+
None,
|
1535
|
+
description='Controls whether the component should provide feedback to the participant, such as in a training trial. If not provided, the default is false.',
|
1536
|
+
)
|
1537
|
+
recordAudio: Optional[bool] = Field(
|
1538
|
+
None,
|
1539
|
+
description='Whether or not to record audio for a component. Only relevant if StudyConfig.recordStudyAudio is true. Defaults to true.',
|
1540
|
+
)
|
1541
|
+
response: List[Response] = Field(..., description='The responses to the component')
|
1542
|
+
trainingAttempts: Optional[float] = Field(
|
1543
|
+
None,
|
1544
|
+
description='The number of training attempts allowed for the component. The next button will be disabled until either the correct answer is given or the number of attempts is reached. When the number of attempts is reached, if the answer is incorrect still, the correct value will be shown to the participant. The default value is 2. Providing a value of -1 will allow infinite attempts and the participant must enter the correct answer to continue, and reVISit will not show the correct answer to the user.',
|
1545
|
+
)
|
1546
|
+
type: Literal['vega'] # End of class
|
1547
|
+
|
1548
|
+
|
1549
|
+
class VegaComponentConfigType(TypedDict):
|
1550
|
+
model_config = ConfigDict(extra='forbid', populate_by_name=True)
|
1551
|
+
allowFailedTraining: Optional[bool] = Field(
|
1552
|
+
None,
|
1553
|
+
description='Controls whether the component should allow failed training. If not provided, the default is true.',
|
1554
|
+
)
|
1555
|
+
config: Dict[str, Any] = Field(..., description='The vega-lite configuration.')
|
1556
|
+
correctAnswer: Optional[List[Answer]] = Field(
|
1557
|
+
None,
|
1558
|
+
description='The correct answer to the component. This is used for training trials where the user is shown the correct answer after a guess.',
|
1559
|
+
)
|
1560
|
+
description: Optional[str] = Field(
|
1561
|
+
None,
|
1562
|
+
description='The description of the component. This is used to identify and provide additional information for the component in the admin panel.',
|
1563
|
+
)
|
1564
|
+
instruction: Optional[str] = Field(
|
1565
|
+
None,
|
1566
|
+
description='The instruction of the component. This is used to identify and provide additional information for the component in the admin panel.',
|
1567
|
+
)
|
1568
|
+
instructionLocation: Optional[ResponseBlockLocation] = Field(
|
1569
|
+
None, description='The location of the instructions.'
|
1570
|
+
)
|
1571
|
+
meta: Optional[Dict[str, Any]] = Field(
|
1572
|
+
None,
|
1573
|
+
description='The meta data for the component. This is used to identify and provide additional information for the component in the admin panel.',
|
1574
|
+
)
|
1575
|
+
nextButtonDisableTime: Optional[float] = Field(
|
1576
|
+
None,
|
1577
|
+
description='A timeout (in ms) after which the next button will be disabled.',
|
1578
|
+
)
|
1579
|
+
nextButtonEnableTime: Optional[float] = Field(
|
1580
|
+
None, description='A timer (in ms) after which the next button will be enabled.'
|
1581
|
+
)
|
1582
|
+
nextButtonLocation: Optional[ResponseBlockLocation] = Field(
|
1583
|
+
None, description='The location of the next button.'
|
1584
|
+
)
|
1585
|
+
nextButtonText: Optional[str] = Field(
|
1586
|
+
None, description='The text that is displayed on the next button.'
|
1587
|
+
)
|
1588
|
+
provideFeedback: Optional[bool] = Field(
|
1589
|
+
None,
|
1590
|
+
description='Controls whether the component should provide feedback to the participant, such as in a training trial. If not provided, the default is false.',
|
1591
|
+
)
|
1592
|
+
recordAudio: Optional[bool] = Field(
|
1593
|
+
None,
|
1594
|
+
description='Whether or not to record audio for a component. Only relevant if StudyConfig.recordStudyAudio is true. Defaults to true.',
|
1595
|
+
)
|
1596
|
+
response: List[Response] = Field(..., description='The responses to the component')
|
1597
|
+
trainingAttempts: Optional[float] = Field(
|
1598
|
+
None,
|
1599
|
+
description='The number of training attempts allowed for the component. The next button will be disabled until either the correct answer is given or the number of attempts is reached. When the number of attempts is reached, if the answer is incorrect still, the correct value will be shown to the participant. The default value is 2. Providing a value of -1 will allow infinite attempts and the participant must enter the correct answer to continue, and reVISit will not show the correct answer to the user.',
|
1600
|
+
)
|
1601
|
+
type: Literal['vega']
|
1602
|
+
|
1603
|
+
|
1604
|
+
warnings.filterwarnings("ignore", module="pydantic")
|
1605
|
+
|
1606
|
+
|
1607
|
+
class VegaComponentPath(BaseModel):
|
1608
|
+
model_config = ConfigDict(extra='forbid', populate_by_name=True)
|
1609
|
+
allowFailedTraining: Optional[bool] = Field(
|
1610
|
+
None,
|
1611
|
+
description='Controls whether the component should allow failed training. If not provided, the default is true.',
|
1612
|
+
)
|
1613
|
+
correctAnswer: Optional[List[Answer]] = Field(
|
1614
|
+
None,
|
1615
|
+
description='The correct answer to the component. This is used for training trials where the user is shown the correct answer after a guess.',
|
1616
|
+
)
|
1617
|
+
description: Optional[str] = Field(
|
1618
|
+
None,
|
1619
|
+
description='The description of the component. This is used to identify and provide additional information for the component in the admin panel.',
|
1620
|
+
)
|
1621
|
+
instruction: Optional[str] = Field(
|
1622
|
+
None,
|
1623
|
+
description='The instruction of the component. This is used to identify and provide additional information for the component in the admin panel.',
|
1624
|
+
)
|
1625
|
+
instructionLocation: Optional[ResponseBlockLocation] = Field(
|
1626
|
+
None, description='The location of the instructions.'
|
1627
|
+
)
|
1628
|
+
meta: Optional[Dict[str, Any]] = Field(
|
1629
|
+
None,
|
1630
|
+
description='The meta data for the component. This is used to identify and provide additional information for the component in the admin panel.',
|
1631
|
+
)
|
1632
|
+
nextButtonDisableTime: Optional[float] = Field(
|
1633
|
+
None,
|
1634
|
+
description='A timeout (in ms) after which the next button will be disabled.',
|
1635
|
+
)
|
1636
|
+
nextButtonEnableTime: Optional[float] = Field(
|
1637
|
+
None, description='A timer (in ms) after which the next button will be enabled.'
|
1638
|
+
)
|
1639
|
+
nextButtonLocation: Optional[ResponseBlockLocation] = Field(
|
1640
|
+
None, description='The location of the next button.'
|
1641
|
+
)
|
1642
|
+
nextButtonText: Optional[str] = Field(
|
1643
|
+
None, description='The text that is displayed on the next button.'
|
1644
|
+
)
|
1645
|
+
path: str = Field(
|
1646
|
+
...,
|
1647
|
+
description='The path to the vega file. This should be a relative path from the public folder.',
|
1648
|
+
)
|
1649
|
+
provideFeedback: Optional[bool] = Field(
|
1650
|
+
None,
|
1651
|
+
description='Controls whether the component should provide feedback to the participant, such as in a training trial. If not provided, the default is false.',
|
1652
|
+
)
|
1653
|
+
recordAudio: Optional[bool] = Field(
|
1654
|
+
None,
|
1655
|
+
description='Whether or not to record audio for a component. Only relevant if StudyConfig.recordStudyAudio is true. Defaults to true.',
|
1656
|
+
)
|
1657
|
+
response: List[Response] = Field(..., description='The responses to the component')
|
1658
|
+
trainingAttempts: Optional[float] = Field(
|
1659
|
+
None,
|
1660
|
+
description='The number of training attempts allowed for the component. The next button will be disabled until either the correct answer is given or the number of attempts is reached. When the number of attempts is reached, if the answer is incorrect still, the correct value will be shown to the participant. The default value is 2. Providing a value of -1 will allow infinite attempts and the participant must enter the correct answer to continue, and reVISit will not show the correct answer to the user.',
|
1661
|
+
)
|
1662
|
+
type: Literal['vega'] # End of class
|
1663
|
+
|
1664
|
+
|
1665
|
+
class VegaComponentPathType(TypedDict):
|
1666
|
+
model_config = ConfigDict(extra='forbid', populate_by_name=True)
|
1667
|
+
allowFailedTraining: Optional[bool] = Field(
|
1668
|
+
None,
|
1669
|
+
description='Controls whether the component should allow failed training. If not provided, the default is true.',
|
1670
|
+
)
|
1671
|
+
correctAnswer: Optional[List[Answer]] = Field(
|
1672
|
+
None,
|
1673
|
+
description='The correct answer to the component. This is used for training trials where the user is shown the correct answer after a guess.',
|
1674
|
+
)
|
1675
|
+
description: Optional[str] = Field(
|
1676
|
+
None,
|
1677
|
+
description='The description of the component. This is used to identify and provide additional information for the component in the admin panel.',
|
1678
|
+
)
|
1679
|
+
instruction: Optional[str] = Field(
|
1680
|
+
None,
|
1681
|
+
description='The instruction of the component. This is used to identify and provide additional information for the component in the admin panel.',
|
1682
|
+
)
|
1683
|
+
instructionLocation: Optional[ResponseBlockLocation] = Field(
|
1684
|
+
None, description='The location of the instructions.'
|
1685
|
+
)
|
1686
|
+
meta: Optional[Dict[str, Any]] = Field(
|
1687
|
+
None,
|
1688
|
+
description='The meta data for the component. This is used to identify and provide additional information for the component in the admin panel.',
|
1689
|
+
)
|
1690
|
+
nextButtonDisableTime: Optional[float] = Field(
|
1691
|
+
None,
|
1692
|
+
description='A timeout (in ms) after which the next button will be disabled.',
|
1693
|
+
)
|
1694
|
+
nextButtonEnableTime: Optional[float] = Field(
|
1695
|
+
None, description='A timer (in ms) after which the next button will be enabled.'
|
1696
|
+
)
|
1697
|
+
nextButtonLocation: Optional[ResponseBlockLocation] = Field(
|
1698
|
+
None, description='The location of the next button.'
|
1699
|
+
)
|
1700
|
+
nextButtonText: Optional[str] = Field(
|
1701
|
+
None, description='The text that is displayed on the next button.'
|
1702
|
+
)
|
1703
|
+
path: str = Field(
|
1704
|
+
...,
|
1705
|
+
description='The path to the vega file. This should be a relative path from the public folder.',
|
1706
|
+
)
|
1707
|
+
provideFeedback: Optional[bool] = Field(
|
1708
|
+
None,
|
1709
|
+
description='Controls whether the component should provide feedback to the participant, such as in a training trial. If not provided, the default is false.',
|
1710
|
+
)
|
1711
|
+
recordAudio: Optional[bool] = Field(
|
1712
|
+
None,
|
1713
|
+
description='Whether or not to record audio for a component. Only relevant if StudyConfig.recordStudyAudio is true. Defaults to true.',
|
1714
|
+
)
|
1715
|
+
response: List[Response] = Field(..., description='The responses to the component')
|
1716
|
+
trainingAttempts: Optional[float] = Field(
|
1717
|
+
None,
|
1718
|
+
description='The number of training attempts allowed for the component. The next button will be disabled until either the correct answer is given or the number of attempts is reached. When the number of attempts is reached, if the answer is incorrect still, the correct value will be shown to the participant. The default value is 2. Providing a value of -1 will allow infinite attempts and the participant must enter the correct answer to continue, and reVISit will not show the correct answer to the user.',
|
1719
|
+
)
|
1720
|
+
type: Literal['vega']
|
1721
|
+
|
1722
|
+
|
1723
|
+
warnings.filterwarnings("ignore", module="pydantic")
|
1724
|
+
|
1725
|
+
|
1493
1726
|
class WebsiteComponent(BaseModel):
|
1494
1727
|
model_config = ConfigDict(extra='forbid', populate_by_name=True)
|
1495
1728
|
allowFailedTraining: Optional[bool] = Field(
|
@@ -1623,6 +1856,9 @@ class BaseComponents1(BaseModel):
|
|
1623
1856
|
None,
|
1624
1857
|
description='Controls whether the component should allow failed training. If not provided, the default is true.',
|
1625
1858
|
)
|
1859
|
+
config: Optional[Dict[str, Any]] = Field(
|
1860
|
+
None, description='The vega-lite configuration.'
|
1861
|
+
)
|
1626
1862
|
correctAnswer: Optional[List[Answer]] = Field(
|
1627
1863
|
None,
|
1628
1864
|
description='The correct answer to the component. This is used for training trials where the user is shown the correct answer after a guess.',
|
@@ -1691,6 +1927,9 @@ class BaseComponents1Type(TypedDict):
|
|
1691
1927
|
None,
|
1692
1928
|
description='Controls whether the component should allow failed training. If not provided, the default is true.',
|
1693
1929
|
)
|
1930
|
+
config: Optional[Dict[str, Any]] = Field(
|
1931
|
+
None, description='The vega-lite configuration.'
|
1932
|
+
)
|
1694
1933
|
correctAnswer: Optional[List[Answer]] = Field(
|
1695
1934
|
None,
|
1696
1935
|
description='The correct answer to the component. This is used for training trials where the user is shown the correct answer after a guess.',
|
@@ -1956,6 +2195,9 @@ class InheritedComponent(BaseModel):
|
|
1956
2195
|
description='Controls whether the component should allow failed training. If not provided, the default is true.',
|
1957
2196
|
)
|
1958
2197
|
baseComponent: str
|
2198
|
+
config: Optional[Dict[str, Any]] = Field(
|
2199
|
+
None, description='The vega-lite configuration.'
|
2200
|
+
)
|
1959
2201
|
correctAnswer: Optional[List[Answer]] = Field(
|
1960
2202
|
None,
|
1961
2203
|
description='The correct answer to the component. This is used for training trials where the user is shown the correct answer after a guess.',
|
@@ -2025,6 +2267,9 @@ class InheritedComponentType(TypedDict):
|
|
2025
2267
|
description='Controls whether the component should allow failed training. If not provided, the default is true.',
|
2026
2268
|
)
|
2027
2269
|
baseComponent: str
|
2270
|
+
config: Optional[Dict[str, Any]] = Field(
|
2271
|
+
None, description='The vega-lite configuration.'
|
2272
|
+
)
|
2028
2273
|
correctAnswer: Optional[List[Answer]] = Field(
|
2029
2274
|
None,
|
2030
2275
|
description='The correct answer to the component. This is used for training trials where the user is shown the correct answer after a guess.',
|
@@ -2444,6 +2689,17 @@ class ReactComponentType(TypedDict):
|
|
2444
2689
|
type: Literal['react-component']
|
2445
2690
|
|
2446
2691
|
|
2692
|
+
class VegaComponent(RootModel[Union[VegaComponentPath, VegaComponentConfig]]):
|
2693
|
+
root: Union[VegaComponentPath, VegaComponentConfig]
|
2694
|
+
|
2695
|
+
|
2696
|
+
# End of class
|
2697
|
+
|
2698
|
+
|
2699
|
+
class VegaComponentType(TypedDict):
|
2700
|
+
root: Union[VegaComponentPath, VegaComponentConfig]
|
2701
|
+
|
2702
|
+
|
2447
2703
|
class IndividualComponent(
|
2448
2704
|
RootModel[
|
2449
2705
|
Union[
|
@@ -2452,6 +2708,7 @@ class IndividualComponent(
|
|
2452
2708
|
ImageComponent,
|
2453
2709
|
WebsiteComponent,
|
2454
2710
|
QuestionnaireComponent,
|
2711
|
+
VegaComponent,
|
2455
2712
|
]
|
2456
2713
|
]
|
2457
2714
|
):
|
@@ -2461,6 +2718,7 @@ class IndividualComponent(
|
|
2461
2718
|
ImageComponent,
|
2462
2719
|
WebsiteComponent,
|
2463
2720
|
QuestionnaireComponent,
|
2721
|
+
VegaComponent,
|
2464
2722
|
]
|
2465
2723
|
|
2466
2724
|
|
@@ -2474,6 +2732,7 @@ class IndividualComponentType(TypedDict):
|
|
2474
2732
|
ImageComponent,
|
2475
2733
|
WebsiteComponent,
|
2476
2734
|
QuestionnaireComponent,
|
2735
|
+
VegaComponent,
|
2477
2736
|
]
|
2478
2737
|
|
2479
2738
|
|
@@ -88,7 +88,6 @@ class _WrappedComponent(_JSONableBaseModel):
|
|
88
88
|
return None
|
89
89
|
|
90
90
|
def edit_response(self, id: str, **kwargs) -> _WrappedComponent:
|
91
|
-
print(self.root.response)
|
92
91
|
for r in self.root.response:
|
93
92
|
if r.root.id == id:
|
94
93
|
# Get dict
|
@@ -529,22 +528,30 @@ def _generate_possible_component_types():
|
|
529
528
|
# Generates mappings between the response class name and the
|
530
529
|
# type string literal. Creates the reversed mapping as well.
|
531
530
|
def _generate_possible_types(orig_cls):
|
532
|
-
|
533
|
-
|
531
|
+
type_hints = get_type_hints(orig_cls).get('root')
|
532
|
+
types = get_args(type_hints)
|
534
533
|
type_hints = {}
|
535
534
|
type_hints_reversed = {}
|
536
|
-
for cls in
|
537
|
-
|
538
|
-
|
539
|
-
if
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
535
|
+
for cls in types:
|
536
|
+
# If class is the union of two separate classes,
|
537
|
+
# need to get types from root
|
538
|
+
if get_type_hints(cls).get('root') is not None:
|
539
|
+
test = get_type_hints(cls).get('root')
|
540
|
+
for item in get_args(test):
|
541
|
+
curr_type = get_type_hints(item).get('type')
|
542
|
+
type_hints[cls.__name__] = set([get_args(curr_type)[0]])
|
543
|
+
type_hints_reversed[get_args(curr_type)[0]] = cls.__name__
|
544
|
+
else:
|
545
|
+
curr_type = get_type_hints(cls).get('type')
|
546
|
+
curr_origin = get_origin(get_type_hints(cls).get('type'))
|
547
|
+
if curr_origin is Literal:
|
548
|
+
type_hints[cls.__name__] = set([get_args(curr_type)[0]])
|
549
|
+
type_hints_reversed[get_args(curr_type)[0]] = cls.__name__
|
550
|
+
elif isinstance(curr_type, type) and issubclass(curr_type, Enum):
|
551
|
+
enum_list = [member.value for member in curr_type]
|
552
|
+
type_hints[cls.__name__] = set(enum_list)
|
553
|
+
for item in enum_list:
|
554
|
+
type_hints_reversed[item] = cls.__name__
|
548
555
|
return (type_hints, type_hints_reversed)
|
549
556
|
|
550
557
|
|
@@ -596,6 +603,11 @@ def _get_filtered_kwargs(class_type: Any, kwargs):
|
|
596
603
|
|
597
604
|
valid_fields = set()
|
598
605
|
for model in possible_items:
|
606
|
+
if 'root' in model.model_fields.keys():
|
607
|
+
unioned_classes = (get_args(get_type_hints(model).get('root')))
|
608
|
+
for cls in unioned_classes:
|
609
|
+
valid_fields.update(cls.model_fields.keys())
|
610
|
+
|
599
611
|
valid_fields.update(model.model_fields.keys())
|
600
612
|
|
601
613
|
return {key: value for key, value in kwargs.items() if key in valid_fields}
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|