dearpygui-forms 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,127 @@
1
+ """
2
+ Dearpygui extention for autogeneration forms powered by pydantic.
3
+ """
4
+ import decimal
5
+ from typing import Any, Type
6
+ from pprint import pformat
7
+
8
+
9
+ import dearpygui.dearpygui as dpg
10
+ from loguru import logger
11
+ import pydantic
12
+
13
+ def main() -> None:
14
+ print("Hello from dearpygui-forms!")
15
+
16
+
17
+ def parse_property_type(property_schema: dict[str, Any]) -> str:
18
+ property_type = property_schema.get("type", None)
19
+ if property_type is None:
20
+ any_of = property_schema.get("anyOf", None)
21
+ if any_of is None:
22
+ raise ValueError(f"Property type not detected. {property_schema}")
23
+
24
+ # Text input field preferred for Decimal type than float input field
25
+ if 'string' in map(lambda x: x.get("type"), any_of):
26
+ property_type = 'string'
27
+ else:
28
+ property_type = any_of[0].get("type", None)
29
+
30
+ if property_type is None:
31
+ raise ValueError(f"Property type not detected. {property_schema}")
32
+ return property_type
33
+
34
+ class DPGForm:
35
+ """
36
+ Base class for dearpygui forms.
37
+ Sublasses must define `__pydantic_model__` with some Pydantic model type.
38
+
39
+ # Example:
40
+ ```python
41
+ import dearpygui.dearpygui as dpg
42
+ from pydantic import BaseModel
43
+ from dearpygui_forms import DPGForm
44
+
45
+ class User(BaseModel):
46
+ name: str
47
+ age: int
48
+
49
+ class UserForm(DPGForm):
50
+ __pydantic_model__ = User
51
+
52
+ dpg.create_context()
53
+ dpg.create_viewport()
54
+ with dpg.window(label="User Form"):
55
+ user_form = UserForm(callback=lambda x: print(x))
56
+ user_form.add()
57
+ dpg.setup_dearpygui()
58
+ dpg.show_viewport()
59
+ dpg.start_dearpygui()
60
+ dpg.destroy_context()
61
+ ```
62
+ """
63
+ __pydantic_model__: Type[pydantic.BaseModel]
64
+
65
+ def __init__(self, callback):
66
+ """
67
+ Initializes the UserForm instance.
68
+
69
+ Args:
70
+ callback (Callable): The callback function to be called with a validated pydantic model.
71
+ """
72
+ self.callback = callback
73
+ logger.debug(self.__pydantic_model__)
74
+ self.model_schema = self.__pydantic_model__.model_json_schema()
75
+ logger.debug(pformat(self.model_schema))
76
+
77
+ def add(self):
78
+ """Adds form as child_window dearpygui element."""
79
+ schema = self.model_schema
80
+ with dpg.child_window(label=schema["title"]):
81
+ for property_name, property_schema in schema["properties"].items():
82
+ property_type = parse_property_type(property_schema)
83
+ default_value = property_schema.get("default")
84
+ if property_type == "string":
85
+ schema["properties"][property_name]["dpg_form_id"] = \
86
+ dpg.add_input_text(label=property_schema["title"], default_value=default_value or '')
87
+ elif property_type == "integer":
88
+ schema["properties"][property_name]["dpg_form_id"] = \
89
+ dpg.add_input_int(label=property_schema["title"], default_value=default_value)
90
+ elif property_type == "number":
91
+ schema["properties"][property_name]["dpg_form_id"] = \
92
+ dpg.add_input_float(label=property_schema["title"], default_value=float(default_value))
93
+ elif property_type == "boolean":
94
+ schema["properties"][property_name]["dpg_form_id"] = \
95
+ dpg.add_checkbox(label=property_schema["title"], default_value=default_value)
96
+ elif property_type == "array":
97
+ schema["properties"][property_name]["dpg_form_id"] = \
98
+ dpg.add_input_text(label=property_schema["title"])
99
+ elif property_type == "object":
100
+ schema["properties"][property_name]["dpg_form_id"] = \
101
+ dpg.add_input_text(label=property_schema["title"])
102
+ else:
103
+ raise ValueError(f"Unsupported type: {property_type}")
104
+
105
+ dpg.add_button(label="Submit", callback=self.submit)
106
+
107
+ logger.debug(pformat(self.model_schema))
108
+
109
+ def submit(self):
110
+ try:
111
+ data = self._handle_data()
112
+ except pydantic.ValidationError as e:
113
+ with dpg.window(label="Validation error", modal=True):
114
+ dpg.add_text(str(e))
115
+ else:
116
+ self.callback(data)
117
+
118
+ def _handle_data(self):
119
+ json_data = {}
120
+ for property_name, property_schema in self.model_schema["properties"].items():
121
+ form_id = property_schema["dpg_form_id"]
122
+ if form_id is not None:
123
+ json_data[property_name] = dpg.get_value(form_id)
124
+ else:
125
+ raise ValueError(f"Missing form ID for property: {property_name}")
126
+
127
+ return self.__pydantic_model__(**json_data)
@@ -0,0 +1,9 @@
1
+ Metadata-Version: 2.4
2
+ Name: dearpygui-forms
3
+ Version: 0.1.0
4
+ Summary: Add your description here
5
+ Author-email: Aeek True <aeektrue@gmail.com>
6
+ Requires-Python: >=3.13
7
+ Requires-Dist: dearpygui>=2.0.0
8
+ Requires-Dist: loguru>=0.7.3
9
+ Requires-Dist: pydantic>=2.11.7
@@ -0,0 +1,5 @@
1
+ dearpygui_forms/__init__.py,sha256=I8Ikthx1SlMz1v3MaruLBB3Q8e-lWI6j7liqnI54XPc,4749
2
+ dearpygui_forms-0.1.0.dist-info/METADATA,sha256=1ysiVHWh3m7DqlaEleu3OCH9oOOPqAPtBnVw2s3vjXU,256
3
+ dearpygui_forms-0.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
4
+ dearpygui_forms-0.1.0.dist-info/entry_points.txt,sha256=7Iv9K4ckShx5C5O1M7Ta6zoIN9HUBBa7vHllqm2kvDQ,57
5
+ dearpygui_forms-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.27.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ dearpygui-forms = dearpygui_forms:main