openadmin-dev 0.5.0__tar.gz → 0.6.1__tar.gz

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.
Files changed (82) hide show
  1. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/PKG-INFO +1 -1
  2. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/examples/admin/analytics.py +3 -1
  3. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/examples/admin/authors.py +3 -1
  4. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/examples/admin/books.py +1 -1
  5. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/examples/admin/genres.py +3 -1
  6. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/examples/admin/health.py +3 -1
  7. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/examples/admin/overview.py +5 -1
  8. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/examples/admin/publishers.py +5 -1
  9. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/examples/admin/reports.py +3 -1
  10. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/examples/admin/tags.py +1 -1
  11. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/examples/main.py +9 -3
  12. {openadmin_dev-0.5.0/openadmin/fastapi/types → openadmin_dev-0.6.1/openadmin/fastapi}/action.py +1 -0
  13. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/openadmin/fastapi/admin_page.py +90 -34
  14. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/openadmin/fastapi/admin_panel.py +5 -3
  15. {openadmin_dev-0.5.0/openadmin/fastapi/types → openadmin_dev-0.6.1/openadmin/fastapi}/area_chart.py +1 -0
  16. {openadmin_dev-0.5.0/openadmin/fastapi/types → openadmin_dev-0.6.1/openadmin/fastapi}/bar_chart.py +1 -0
  17. openadmin_dev-0.5.0/openadmin/fastapi/types/__init__.py → openadmin_dev-0.6.1/openadmin/fastapi/component.py +0 -19
  18. openadmin_dev-0.6.1/openadmin/fastapi/counters.py +17 -0
  19. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/openadmin/fastapi/deps.py +1 -1
  20. {openadmin_dev-0.5.0/openadmin/fastapi/types → openadmin_dev-0.6.1/openadmin/fastapi}/form.py +1 -0
  21. {openadmin_dev-0.5.0/openadmin/fastapi/types → openadmin_dev-0.6.1/openadmin/fastapi}/line_chart.py +1 -0
  22. {openadmin_dev-0.5.0/openadmin/fastapi/types → openadmin_dev-0.6.1/openadmin/fastapi}/markdown.py +1 -0
  23. {openadmin_dev-0.5.0/openadmin/fastapi/types → openadmin_dev-0.6.1/openadmin/fastapi}/pie_chart.py +1 -0
  24. {openadmin_dev-0.5.0/openadmin/fastapi/types → openadmin_dev-0.6.1/openadmin/fastapi}/section.py +1 -0
  25. {openadmin_dev-0.5.0/openadmin/fastapi/types → openadmin_dev-0.6.1/openadmin/fastapi}/stat.py +1 -0
  26. {openadmin_dev-0.5.0/openadmin/fastapi/types → openadmin_dev-0.6.1/openadmin/fastapi}/table.py +1 -0
  27. {openadmin_dev-0.5.0/openadmin/spec/components → openadmin_dev-0.6.1/openadmin/spec}/__init__.py +14 -10
  28. {openadmin_dev-0.5.0/openadmin/spec/components → openadmin_dev-0.6.1/openadmin/spec}/action.py +1 -0
  29. {openadmin_dev-0.5.0/openadmin/spec/components → openadmin_dev-0.6.1/openadmin/spec}/area_chart.py +1 -0
  30. {openadmin_dev-0.5.0/openadmin/spec/components → openadmin_dev-0.6.1/openadmin/spec}/bar_chart.py +1 -0
  31. openadmin_dev-0.6.1/openadmin/spec/component.py +19 -0
  32. {openadmin_dev-0.5.0/openadmin/spec/components → openadmin_dev-0.6.1/openadmin/spec}/form.py +1 -0
  33. {openadmin_dev-0.5.0/openadmin/spec/components → openadmin_dev-0.6.1/openadmin/spec}/line_chart.py +1 -0
  34. {openadmin_dev-0.5.0/openadmin/spec/components → openadmin_dev-0.6.1/openadmin/spec}/markdown.py +1 -0
  35. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/openadmin/spec/page.py +3 -1
  36. {openadmin_dev-0.5.0/openadmin/spec/components → openadmin_dev-0.6.1/openadmin/spec}/pie_chart.py +1 -0
  37. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/openadmin/spec/section.py +2 -1
  38. {openadmin_dev-0.5.0/openadmin/spec/components → openadmin_dev-0.6.1/openadmin/spec}/stat.py +1 -0
  39. {openadmin_dev-0.5.0/openadmin/spec/components → openadmin_dev-0.6.1/openadmin/spec}/table.py +1 -0
  40. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/pyproject.toml +1 -1
  41. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/uv.lock +1 -1
  42. openadmin_dev-0.5.0/openadmin/spec/__init__.py +0 -43
  43. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/.github/ISSUE_TEMPLATE/bug.md +0 -0
  44. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/.github/ISSUE_TEMPLATE/chore.md +0 -0
  45. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/.github/ISSUE_TEMPLATE/feature.md +0 -0
  46. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/.github/actions/branch-name/action.yml +0 -0
  47. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/.github/actions/dependency-cves/action.yml +0 -0
  48. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/.github/actions/format/action.yml +0 -0
  49. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/.github/actions/license/action.yml +0 -0
  50. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/.github/actions/lint/action.yml +0 -0
  51. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/.github/actions/security/action.yml +0 -0
  52. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/.github/actions/spell-check/action.yml +0 -0
  53. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/.github/actions/test/action.yml +0 -0
  54. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/.github/actions/typecheck/action.yml +0 -0
  55. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/.github/actions/unused-code/action.yml +0 -0
  56. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/.github/workflows/ci.yml +0 -0
  57. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/.github/workflows/publish.yml +0 -0
  58. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/.gitignore +0 -0
  59. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/.python-version +0 -0
  60. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/LICENSE +0 -0
  61. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/LICENSES/AGPL-3.0-or-later.txt +0 -0
  62. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/Makefile +0 -0
  63. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/README.md +0 -0
  64. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/REUSE.toml +0 -0
  65. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/docs/assets/logo.png +0 -0
  66. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/examples/__init__.py +0 -0
  67. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/examples/admin/__init__.py +0 -0
  68. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/examples/lib/__init__.py +0 -0
  69. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/examples/lib/database.py +0 -0
  70. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/examples/lib/lifespan.py +0 -0
  71. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/examples/lib/models.py +0 -0
  72. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/examples/lib/seed.py +0 -0
  73. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/openadmin/fastapi/__init__.py +0 -0
  74. {openadmin_dev-0.5.0/openadmin/fastapi/types → openadmin_dev-0.6.1/openadmin/fastapi}/page_protocol.py +0 -0
  75. {openadmin_dev-0.5.0/openadmin/fastapi/types → openadmin_dev-0.6.1/openadmin/fastapi}/pagination_params.py +0 -0
  76. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/openadmin/fastapi/utils.py +0 -0
  77. {openadmin_dev-0.5.0/openadmin/spec/components → openadmin_dev-0.6.1/openadmin/spec}/http_methods.py +0 -0
  78. {openadmin_dev-0.5.0/openadmin/spec/components → openadmin_dev-0.6.1/openadmin/spec}/icons.py +0 -0
  79. {openadmin_dev-0.5.0/openadmin/spec/components → openadmin_dev-0.6.1/openadmin/spec}/property.py +0 -0
  80. {openadmin_dev-0.5.0/openadmin/spec/components → openadmin_dev-0.6.1/openadmin/spec}/property_type.py +0 -0
  81. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/openadmin/spec/spec.py +0 -0
  82. {openadmin_dev-0.5.0 → openadmin_dev-0.6.1}/tests/test_hello.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openadmin-dev
3
- Version: 0.5.0
3
+ Version: 0.6.1
4
4
  Summary: Add your description here
5
5
  Project-URL: Homepage, https://github.com/openadmin-team/openadmin-py
6
6
  Project-URL: Issues, https://github.com/openadmin-team/openadmin-py/issues
@@ -10,7 +10,9 @@ from ..lib import models
10
10
  from ..lib.database import AsyncSessionDep
11
11
 
12
12
  page = AdminPage(
13
- "Analytics", description="Library-wide publication trends and insights"
13
+ "Analytics",
14
+ icon="bar-chart",
15
+ description="Library-wide publication trends and insights",
14
16
  )
15
17
 
16
18
 
@@ -12,7 +12,9 @@ from ..lib import models
12
12
  from ..lib.database import AsyncSessionDep
13
13
 
14
14
  page = AdminPage(
15
- "Authors", description="Manage book authors and view productivity stats"
15
+ "Authors",
16
+ icon="users",
17
+ description="Manage book authors and view productivity stats",
16
18
  )
17
19
 
18
20
 
@@ -12,7 +12,7 @@ from openadmin.fastapi.deps import PageDep, SearchQueryDep
12
12
  from ..lib import models
13
13
  from ..lib.database import AsyncSessionDep
14
14
 
15
- page = AdminPage("Books", description="Browse and manage the book catalog")
15
+ page = AdminPage("Books", icon="book", description="Browse and manage the book catalog")
16
16
 
17
17
 
18
18
  @page.stat("Total Books")
@@ -10,7 +10,9 @@ from openadmin.fastapi.deps import PageDep
10
10
  from ..lib import models
11
11
  from ..lib.database import AsyncSessionDep
12
12
 
13
- page = AdminPage("Genres", description="Browse and analyze the genre taxonomy")
13
+ page = AdminPage(
14
+ "Genres", icon="drama", description="Browse and analyze the genre taxonomy"
15
+ )
14
16
 
15
17
 
16
18
  @page.stat("Total Genres")
@@ -4,7 +4,9 @@
4
4
 
5
5
  from openadmin.fastapi import AdminPage
6
6
 
7
- page = AdminPage("Health", description="System health and infrastructure metrics")
7
+ page = AdminPage(
8
+ "Health", icon="heart-pulse", description="System health and infrastructure metrics"
9
+ )
8
10
 
9
11
 
10
12
  @page.stat("API Uptime (%)")
@@ -9,7 +9,11 @@ from openadmin.fastapi import AdminPage
9
9
  from ..lib import models
10
10
  from ..lib.database import AsyncSessionDep
11
11
 
12
- page = AdminPage("Overview", description="High-level database and catalog statistics")
12
+ page = AdminPage(
13
+ "Overview",
14
+ icon="layout-dashboard",
15
+ description="High-level database and catalog statistics",
16
+ )
13
17
 
14
18
 
15
19
  @page.stat("Total Records")
@@ -11,7 +11,11 @@ from openadmin.fastapi.deps import PageDep, SearchQueryDep
11
11
  from ..lib import models
12
12
  from ..lib.database import AsyncSessionDep
13
13
 
14
- page = AdminPage("Publishers", description="Manage publishers and their catalog share")
14
+ page = AdminPage(
15
+ "Publishers",
16
+ icon="building-2",
17
+ description="Manage publishers and their catalog share",
18
+ )
15
19
 
16
20
 
17
21
  @page.stat("Total Publishers")
@@ -11,7 +11,9 @@ from ..lib import models
11
11
  from ..lib.database import AsyncSessionDep
12
12
 
13
13
  page = AdminPage(
14
- "Reports", description="Tag assignment activity and catalog coverage reports"
14
+ "Reports",
15
+ icon="file-text",
16
+ description="Tag assignment activity and catalog coverage reports",
15
17
  )
16
18
 
17
19
 
@@ -11,7 +11,7 @@ from openadmin.fastapi.deps import PageDep
11
11
  from ..lib import models
12
12
  from ..lib.database import AsyncSessionDep
13
13
 
14
- page = AdminPage("Tags", description="Manage and analyze book tags")
14
+ page = AdminPage("Tags", icon="tag", description="Manage and analyze book tags")
15
15
 
16
16
 
17
17
  @page.stat("Total Tags")
@@ -34,8 +34,14 @@ admin_panel = AdminPanel(
34
34
  "Book Library Admin", description="Manage and explore the book catalog"
35
35
  )
36
36
 
37
- admin_panel.section("Library", pages=[books.page, authors.page, publishers.page])
38
- admin_panel.section("Catalog", pages=[genres.page, tags.page, analytics.page])
39
- admin_panel.section("System", pages=[health.page, reports.page, overview.page])
37
+ admin_panel.section(
38
+ "Library", icon="library", pages=[books.page, authors.page, publishers.page]
39
+ )
40
+ admin_panel.section(
41
+ "Catalog", icon="library-big", pages=[genres.page, tags.page, analytics.page]
42
+ )
43
+ admin_panel.section(
44
+ "System", icon="server", pages=[health.page, reports.page, overview.page]
45
+ )
40
46
 
41
47
  admin_panel.mount_to(app)
@@ -11,6 +11,7 @@ from openadmin import spec
11
11
  @dataclass
12
12
  class Action:
13
13
  function_name: str
14
+ id: str
14
15
  name: str
15
16
  description: str | None
16
17
  method: spec.HttpMethod
@@ -9,7 +9,17 @@ from collections.abc import Callable
9
9
  from fastapi import APIRouter, FastAPI
10
10
  from openadmin import spec
11
11
 
12
- from . import types
12
+ from . import counters
13
+ from .action import Action
14
+ from .area_chart import AreaChart
15
+ from .bar_chart import BarChart
16
+ from .component import Component
17
+ from .form import Form
18
+ from .line_chart import LineChart
19
+ from .markdown import Markdown
20
+ from .pie_chart import PieChart
21
+ from .stat import Stat
22
+ from .table import Table
13
23
  from .utils import extract_params
14
24
 
15
25
  _SPECIAL_CHARS_RE = re.compile(r"[^a-zA-Z0-9\s]")
@@ -26,9 +36,11 @@ class AdminPage:
26
36
  self.name = name
27
37
  self.description = description
28
38
  self.icon: spec.Icon | None = icon
29
- self.state: list[types.Component] = []
39
+ self.state: list[Component] = []
30
40
  self.router = APIRouter(prefix=f"/{name.lower().replace(' ', '-')}")
31
41
  self.key_repeat_count: dict[str, int] = {}
42
+ self.page_count = counters.get_next("page")
43
+ self.page_kebab_name, _ = self.__get_kebab_and_unique_name(self.name)
32
44
 
33
45
  def get_page_spec(self, app: FastAPI) -> spec.Page:
34
46
  components: list[spec.Component] = []
@@ -39,10 +51,11 @@ class AdminPage:
39
51
  extract_params(item.func) if item.func else (None, None, None)
40
52
  )
41
53
 
42
- if isinstance(item, types.Stat):
54
+ if isinstance(item, Stat):
43
55
  components.append(
44
56
  spec.Stat(
45
57
  type="stat",
58
+ id=item.id,
46
59
  name=item.name,
47
60
  description=item.description,
48
61
  method=item.method,
@@ -50,10 +63,11 @@ class AdminPage:
50
63
  query=query,
51
64
  )
52
65
  )
53
- elif isinstance(item, types.Table):
66
+ elif isinstance(item, Table):
54
67
  components.append(
55
68
  spec.Table(
56
69
  type="table",
70
+ id=item.id,
57
71
  name=item.name,
58
72
  description=item.description,
59
73
  method=item.method,
@@ -63,10 +77,11 @@ class AdminPage:
63
77
  form=form,
64
78
  )
65
79
  )
66
- elif isinstance(item, types.AreaChart):
80
+ elif isinstance(item, AreaChart):
67
81
  components.append(
68
82
  spec.AreaChart(
69
83
  type="area-chart",
84
+ id=item.id,
70
85
  name=item.name,
71
86
  description=item.description,
72
87
  method=item.method,
@@ -74,10 +89,11 @@ class AdminPage:
74
89
  query=query,
75
90
  )
76
91
  )
77
- elif isinstance(item, types.BarChart):
92
+ elif isinstance(item, BarChart):
78
93
  components.append(
79
94
  spec.BarChart(
80
95
  type="bar-chart",
96
+ id=item.id,
81
97
  name=item.name,
82
98
  description=item.description,
83
99
  method=item.method,
@@ -85,10 +101,11 @@ class AdminPage:
85
101
  query=query,
86
102
  )
87
103
  )
88
- elif isinstance(item, types.LineChart):
104
+ elif isinstance(item, LineChart):
89
105
  components.append(
90
106
  spec.LineChart(
91
107
  type="line-chart",
108
+ id=item.id,
92
109
  name=item.name,
93
110
  description=item.description,
94
111
  method=item.method,
@@ -96,10 +113,11 @@ class AdminPage:
96
113
  query=query,
97
114
  )
98
115
  )
99
- elif isinstance(item, types.PieChart):
116
+ elif isinstance(item, PieChart):
100
117
  components.append(
101
118
  spec.PieChart(
102
119
  type="pie-chart",
120
+ id=item.id,
103
121
  name=item.name,
104
122
  description=item.description,
105
123
  method=item.method,
@@ -107,10 +125,11 @@ class AdminPage:
107
125
  query=query,
108
126
  )
109
127
  )
110
- elif isinstance(item, types.Action):
128
+ elif isinstance(item, Action):
111
129
  components.append(
112
130
  spec.Action(
113
131
  type="action",
132
+ id=item.id,
114
133
  name=item.name,
115
134
  description=item.description,
116
135
  method=item.method,
@@ -121,10 +140,11 @@ class AdminPage:
121
140
  form=form,
122
141
  )
123
142
  )
124
- elif isinstance(item, types.Form):
143
+ elif isinstance(item, Form):
125
144
  components.append(
126
145
  spec.Form(
127
146
  type="form",
147
+ id=item.id,
128
148
  name=item.name,
129
149
  description=item.description,
130
150
  method=item.method,
@@ -135,10 +155,11 @@ class AdminPage:
135
155
  form=form,
136
156
  )
137
157
  )
138
- elif isinstance(item, types.Markdown):
158
+ elif isinstance(item, Markdown):
139
159
  components.append(
140
160
  spec.Markdown(
141
161
  type="markdown",
162
+ id=item.id,
142
163
  name=item.name,
143
164
  description=item.description,
144
165
  method=item.method,
@@ -148,13 +169,14 @@ class AdminPage:
148
169
  )
149
170
 
150
171
  return spec.Page(
172
+ id=f"{self.page_kebab_name}-{self.page_count}",
151
173
  name=self.name,
152
174
  description=self.description,
153
175
  icon=self.icon,
154
176
  components=components,
155
177
  )
156
178
 
157
- def _wrap_user_handler(self, item: types.Component, fastapi_decorator) -> Callable:
179
+ def _wrap_user_handler(self, item: Component, fastapi_decorator) -> Callable:
158
180
  def decorator(func: Callable) -> Callable:
159
181
  item.func = func
160
182
  return fastapi_decorator(func)
@@ -181,8 +203,12 @@ class AdminPage:
181
203
  ):
182
204
  kebab_name, unique_name = self.__get_kebab_and_unique_name(name)
183
205
 
184
- item = types.Table(
185
- function_name=unique_name, method="get", name=name, description=description
206
+ item = Table(
207
+ function_name=unique_name,
208
+ method="get",
209
+ name=name,
210
+ description=description,
211
+ id=kebab_name,
186
212
  )
187
213
  self.state.append(item)
188
214
  return self._wrap_user_handler(
@@ -200,8 +226,12 @@ class AdminPage:
200
226
  ):
201
227
  kebab_name, unique_name = self.__get_kebab_and_unique_name(name)
202
228
 
203
- item = types.Stat(
204
- function_name=unique_name, method="get", name=name, description=description
229
+ item = Stat(
230
+ function_name=unique_name,
231
+ method="get",
232
+ name=name,
233
+ description=description,
234
+ id=kebab_name,
205
235
  )
206
236
  self.state.append(item)
207
237
  return self._wrap_user_handler(
@@ -219,11 +249,12 @@ class AdminPage:
219
249
  ):
220
250
  kebab_name, unique_name = self.__get_kebab_and_unique_name(name)
221
251
 
222
- item = types.Markdown(
252
+ item = Markdown(
223
253
  function_name=unique_name,
224
254
  method="get",
225
255
  name=name,
226
256
  description=description,
257
+ id=kebab_name,
227
258
  )
228
259
  self.state.append(item)
229
260
 
@@ -245,12 +276,13 @@ class AdminPage:
245
276
  ):
246
277
  kebab_name, unique_name = self.__get_kebab_and_unique_name(name)
247
278
 
248
- item = types.Action(
279
+ item = Action(
249
280
  function_name=unique_name,
250
281
  method="post",
251
282
  name=name,
252
283
  description=description,
253
284
  is_hidden=is_hiden,
285
+ id=kebab_name,
254
286
  )
255
287
  self.state.append(item)
256
288
  return self._wrap_user_handler(
@@ -269,12 +301,13 @@ class AdminPage:
269
301
  ):
270
302
  kebab_name, unique_name = self.__get_kebab_and_unique_name(name)
271
303
 
272
- item = types.Action(
304
+ item = Action(
273
305
  function_name=unique_name,
274
306
  method="get",
275
307
  name=name,
276
308
  description=description,
277
309
  is_hidden=is_hiden,
310
+ id=kebab_name,
278
311
  )
279
312
  self.state.append(item)
280
313
  return self._wrap_user_handler(
@@ -293,12 +326,13 @@ class AdminPage:
293
326
  ):
294
327
  kebab_name, unique_name = self.__get_kebab_and_unique_name(name)
295
328
 
296
- item = types.Action(
329
+ item = Action(
297
330
  function_name=unique_name,
298
331
  method="put",
299
332
  name=name,
300
333
  description=description,
301
334
  is_hidden=is_hiden,
335
+ id=kebab_name,
302
336
  )
303
337
  self.state.append(item)
304
338
  return self._wrap_user_handler(
@@ -317,12 +351,13 @@ class AdminPage:
317
351
  ):
318
352
  kebab_name, unique_name = self.__get_kebab_and_unique_name(name)
319
353
 
320
- item = types.Action(
354
+ item = Action(
321
355
  function_name=unique_name,
322
356
  method="patch",
323
357
  name=name,
324
358
  description=description,
325
359
  is_hidden=is_hiden,
360
+ id=kebab_name,
326
361
  )
327
362
  self.state.append(item)
328
363
  return self._wrap_user_handler(
@@ -341,12 +376,13 @@ class AdminPage:
341
376
  ):
342
377
  kebab_name, unique_name = self.__get_kebab_and_unique_name(name)
343
378
 
344
- item = types.Action(
379
+ item = Action(
345
380
  function_name=unique_name,
346
381
  method="delete",
347
382
  name=name,
348
383
  description=description,
349
384
  is_hidden=is_hiden,
385
+ id=kebab_name,
350
386
  )
351
387
  self.state.append(item)
352
388
  return self._wrap_user_handler(
@@ -365,12 +401,13 @@ class AdminPage:
365
401
  ):
366
402
  kebab_name, unique_name = self.__get_kebab_and_unique_name(name)
367
403
 
368
- item = types.Form(
404
+ item = Form(
369
405
  function_name=unique_name,
370
406
  method="post",
371
407
  name=name,
372
408
  description=description,
373
409
  is_hiden=is_hiden,
410
+ id=kebab_name,
374
411
  )
375
412
  self.state.append(item)
376
413
  return self._wrap_user_handler(
@@ -389,12 +426,13 @@ class AdminPage:
389
426
  ):
390
427
  kebab_name, unique_name = self.__get_kebab_and_unique_name(name)
391
428
 
392
- item = types.Form(
429
+ item = Form(
393
430
  function_name=unique_name,
394
431
  method="put",
395
432
  name=name,
396
433
  description=description,
397
434
  is_hiden=is_hiden,
435
+ id=kebab_name,
398
436
  )
399
437
  self.state.append(item)
400
438
  return self._wrap_user_handler(
@@ -413,12 +451,13 @@ class AdminPage:
413
451
  ):
414
452
  kebab_name, unique_name = self.__get_kebab_and_unique_name(name)
415
453
 
416
- item = types.Form(
454
+ item = Form(
417
455
  function_name=unique_name,
418
456
  method="patch",
419
457
  name=name,
420
458
  description=description,
421
459
  is_hiden=is_hiden,
460
+ id=kebab_name,
422
461
  )
423
462
  self.state.append(item)
424
463
  return self._wrap_user_handler(
@@ -437,12 +476,13 @@ class AdminPage:
437
476
  ):
438
477
  kebab_name, unique_name = self.__get_kebab_and_unique_name(name)
439
478
 
440
- item = types.Form(
479
+ item = Form(
441
480
  function_name=unique_name,
442
481
  method="delete",
443
482
  name=name,
444
483
  description=description,
445
484
  is_hiden=is_hiden,
485
+ id=kebab_name,
446
486
  )
447
487
  self.state.append(item)
448
488
  return self._wrap_user_handler(
@@ -460,8 +500,12 @@ class AdminPage:
460
500
  ):
461
501
  kebab_name, unique_name = self.__get_kebab_and_unique_name(name)
462
502
 
463
- item = types.AreaChart(
464
- function_name=unique_name, method="get", name=name, description=description
503
+ item = AreaChart(
504
+ function_name=unique_name,
505
+ method="get",
506
+ name=name,
507
+ description=description,
508
+ id=kebab_name,
465
509
  )
466
510
  self.state.append(item)
467
511
  return self._wrap_user_handler(
@@ -479,8 +523,12 @@ class AdminPage:
479
523
  ):
480
524
  kebab_name, unique_name = self.__get_kebab_and_unique_name(name)
481
525
 
482
- item = types.BarChart(
483
- function_name=unique_name, method="get", name=name, description=description
526
+ item = BarChart(
527
+ function_name=unique_name,
528
+ method="get",
529
+ name=name,
530
+ description=description,
531
+ id=kebab_name,
484
532
  )
485
533
  self.state.append(item)
486
534
  return self._wrap_user_handler(
@@ -498,8 +546,12 @@ class AdminPage:
498
546
  ):
499
547
  kebab_name, unique_name = self.__get_kebab_and_unique_name(name)
500
548
 
501
- item = types.LineChart(
502
- function_name=unique_name, method="get", name=name, description=description
549
+ item = LineChart(
550
+ function_name=unique_name,
551
+ method="get",
552
+ name=name,
553
+ description=description,
554
+ id=kebab_name,
503
555
  )
504
556
  self.state.append(item)
505
557
  return self._wrap_user_handler(
@@ -517,8 +569,12 @@ class AdminPage:
517
569
  ):
518
570
  kebab_name, unique_name = self.__get_kebab_and_unique_name(name)
519
571
 
520
- item = types.PieChart(
521
- function_name=unique_name, method="get", name=name, description=description
572
+ item = PieChart(
573
+ function_name=unique_name,
574
+ method="get",
575
+ name=name,
576
+ description=description,
577
+ id=kebab_name,
522
578
  )
523
579
  self.state.append(item)
524
580
  return self._wrap_user_handler(
@@ -7,8 +7,8 @@ from typing import Dict, List
7
7
  from fastapi import FastAPI, HTTPException, status
8
8
  from openadmin import spec
9
9
 
10
- from . import types
11
10
  from .admin_page import AdminPage
11
+ from .section import Section
12
12
 
13
13
 
14
14
  class AdminPanel:
@@ -16,7 +16,7 @@ class AdminPanel:
16
16
  self.version = "1.0.0"
17
17
  self.name = name
18
18
  self.description = description
19
- self.state: List[types.Section] = []
19
+ self.state: List[Section] = []
20
20
  self.app = FastAPI()
21
21
  self.key_repeat_count: Dict[str, int] = {}
22
22
  self.__init_spec_route(self.app)
@@ -28,6 +28,7 @@ class AdminPanel:
28
28
  for section in self.state:
29
29
  sections.append(
30
30
  spec.Section(
31
+ id=section.id,
31
32
  name=section.name,
32
33
  description=section.description,
33
34
  icon=section.icon,
@@ -60,7 +61,8 @@ class AdminPanel:
60
61
  self.key_repeat_count[kebab_name] = 1
61
62
 
62
63
  self.state.append(
63
- types.Section(
64
+ Section(
65
+ id=kebab_name,
64
66
  name=name,
65
67
  description=description,
66
68
  icon=icon,
@@ -11,6 +11,7 @@ from openadmin import spec
11
11
  @dataclass
12
12
  class AreaChart:
13
13
  function_name: str
14
+ id: str
14
15
  name: str
15
16
  description: str | None
16
17
  method: spec.HttpMethod
@@ -11,6 +11,7 @@ from openadmin import spec
11
11
  @dataclass
12
12
  class BarChart:
13
13
  function_name: str
14
+ id: str
14
15
  name: str
15
16
  description: str | None
16
17
  method: spec.HttpMethod
@@ -10,29 +10,10 @@ from .bar_chart import BarChart
10
10
  from .form import Form
11
11
  from .line_chart import LineChart
12
12
  from .markdown import Markdown
13
- from .page_protocol import PageProtocol
14
- from .pagination_params import PaginationParams
15
13
  from .pie_chart import PieChart
16
- from .section import Section
17
14
  from .stat import Stat
18
15
  from .table import Table
19
16
 
20
17
  type Component = Union[
21
18
  Stat, Table, AreaChart, BarChart, LineChart, PieChart, Action, Form, Markdown
22
19
  ]
23
-
24
- __all__ = [
25
- "PageProtocol",
26
- "Section",
27
- "Stat",
28
- "Table",
29
- "Action",
30
- "AreaChart",
31
- "BarChart",
32
- "Form",
33
- "LineChart",
34
- "PieChart",
35
- "Component",
36
- "Markdown",
37
- "PaginationParams",
38
- ]
@@ -0,0 +1,17 @@
1
+ # SPDX-FileCopyrightText: 2026 OpenAdmin
2
+ #
3
+ # SPDX-License-Identifier: AGPL-3.0-or-later
4
+
5
+ from typing import Literal
6
+
7
+ __counters = {}
8
+
9
+
10
+ def get_next(key: Literal["page"]) -> int:
11
+ if key not in __counters:
12
+ __counters[key] = 1
13
+
14
+ value = __counters[key]
15
+ __counters[key] += 1
16
+
17
+ return value
@@ -6,7 +6,7 @@ from typing import Annotated
6
6
 
7
7
  from fastapi import Depends, Query
8
8
 
9
- from .types import PaginationParams
9
+ from .pagination_params import PaginationParams
10
10
 
11
11
 
12
12
  def pagination_params(
@@ -11,6 +11,7 @@ from openadmin import spec
11
11
  @dataclass
12
12
  class Form:
13
13
  function_name: str
14
+ id: str
14
15
  name: str
15
16
  description: str | None
16
17
  method: spec.HttpMethod
@@ -11,6 +11,7 @@ from openadmin import spec
11
11
  @dataclass
12
12
  class LineChart:
13
13
  function_name: str
14
+ id: str
14
15
  name: str
15
16
  description: str | None
16
17
  method: spec.HttpMethod
@@ -11,6 +11,7 @@ from openadmin import spec
11
11
  @dataclass
12
12
  class Markdown:
13
13
  function_name: str
14
+ id: str
14
15
  name: str
15
16
  description: str | None
16
17
  method: spec.HttpMethod
@@ -11,6 +11,7 @@ from openadmin import spec
11
11
  @dataclass
12
12
  class PieChart:
13
13
  function_name: str
14
+ id: str
14
15
  name: str
15
16
  description: str | None
16
17
  method: spec.HttpMethod
@@ -12,6 +12,7 @@ from .page_protocol import PageProtocol
12
12
 
13
13
  @dataclass
14
14
  class Section:
15
+ id: str
15
16
  name: str
16
17
  description: str | None
17
18
  icon: spec.Icon | None
@@ -12,6 +12,7 @@ from openadmin import spec
12
12
  class Stat:
13
13
  function_name: str
14
14
  method: spec.HttpMethod
15
+ id: str
15
16
  name: str
16
17
  description: str | None
17
18
  func: Callable | None = field(default=None)
@@ -12,6 +12,7 @@ from openadmin import spec
12
12
  class Table:
13
13
  function_name: str
14
14
  method: spec.HttpMethod
15
+ id: str
15
16
  name: str
16
17
  description: str | None
17
18
  func: Callable | None = field(default=None)
@@ -2,36 +2,40 @@
2
2
  #
3
3
  # SPDX-License-Identifier: AGPL-3.0-or-later
4
4
 
5
- from typing import Union
6
-
7
5
  from .action import Action
8
6
  from .area_chart import AreaChart
9
7
  from .bar_chart import BarChart
8
+ from .component import Component
10
9
  from .form import Form
10
+ from .http_methods import HttpMethod
11
11
  from .icons import Icon
12
12
  from .line_chart import LineChart
13
13
  from .markdown import Markdown
14
+ from .page import Page
14
15
  from .pie_chart import PieChart
15
16
  from .property import Property
16
17
  from .property_type import PropertyType
18
+ from .section import Section
19
+ from .spec import Spec
17
20
  from .stat import Stat
18
21
  from .table import Table
19
22
 
20
- type Component = Union[
21
- Stat, Table, AreaChart, BarChart, LineChart, PieChart, Action, Form, Markdown
22
- ]
23
-
24
23
  __all__ = [
24
+ "Action",
25
25
  "AreaChart",
26
26
  "BarChart",
27
27
  "Component",
28
+ "Form",
29
+ "HttpMethod",
28
30
  "LineChart",
31
+ "Page",
29
32
  "PieChart",
30
- "Stat",
31
- "Action",
32
- "Table",
33
- "Form",
34
33
  "Property",
35
34
  "PropertyType",
35
+ "Section",
36
+ "Spec",
37
+ "Stat",
38
+ "Table",
39
+ "Markdown",
36
40
  "Icon",
37
41
  ]
@@ -12,6 +12,7 @@ from .property import Property
12
12
 
13
13
  class Action(BaseModel):
14
14
  type: Literal["action"]
15
+ id: str
15
16
  name: str
16
17
  description: str | None
17
18
  url: str
@@ -12,6 +12,7 @@ from .property import Property
12
12
 
13
13
  class AreaChart(BaseModel):
14
14
  type: Literal["area-chart"]
15
+ id: str
15
16
  name: str
16
17
  description: str | None
17
18
  url: str
@@ -12,6 +12,7 @@ from .property import Property
12
12
 
13
13
  class BarChart(BaseModel):
14
14
  type: Literal["bar-chart"]
15
+ id: str
15
16
  name: str
16
17
  description: str | None
17
18
  url: str
@@ -0,0 +1,19 @@
1
+ # SPDX-FileCopyrightText: 2026 OpenAdmin
2
+ #
3
+ # SPDX-License-Identifier: AGPL-3.0-or-later
4
+
5
+ from typing import Union
6
+
7
+ from .action import Action
8
+ from .area_chart import AreaChart
9
+ from .bar_chart import BarChart
10
+ from .form import Form
11
+ from .line_chart import LineChart
12
+ from .markdown import Markdown
13
+ from .pie_chart import PieChart
14
+ from .stat import Stat
15
+ from .table import Table
16
+
17
+ type Component = Union[
18
+ Stat, Table, AreaChart, BarChart, LineChart, PieChart, Action, Form, Markdown
19
+ ]
@@ -12,6 +12,7 @@ from .property import Property
12
12
 
13
13
  class Form(BaseModel):
14
14
  type: Literal["form"]
15
+ id: str
15
16
  name: str
16
17
  description: str | None
17
18
  url: str
@@ -12,6 +12,7 @@ from .property import Property
12
12
 
13
13
  class LineChart(BaseModel):
14
14
  type: Literal["line-chart"]
15
+ id: str
15
16
  name: str
16
17
  description: str | None
17
18
  url: str
@@ -12,6 +12,7 @@ from .property import Property
12
12
 
13
13
  class Markdown(BaseModel):
14
14
  type: Literal["markdown"]
15
+ id: str
15
16
  name: str
16
17
  description: str | None
17
18
  url: str
@@ -6,10 +6,12 @@ from typing import List
6
6
 
7
7
  from pydantic import BaseModel
8
8
 
9
- from .components import Component, Icon
9
+ from .component import Component
10
+ from .icons import Icon
10
11
 
11
12
 
12
13
  class Page(BaseModel):
14
+ id: str
13
15
  name: str
14
16
  description: str | None
15
17
  icon: Icon | None
@@ -12,6 +12,7 @@ from .property import Property
12
12
 
13
13
  class PieChart(BaseModel):
14
14
  type: Literal["pie-chart"]
15
+ id: str
15
16
  name: str
16
17
  description: str | None
17
18
  url: str
@@ -6,11 +6,12 @@ from typing import List
6
6
 
7
7
  from pydantic import BaseModel
8
8
 
9
- from .components import Icon
9
+ from .icons import Icon
10
10
  from .page import Page
11
11
 
12
12
 
13
13
  class Section(BaseModel):
14
+ id: str
14
15
  name: str
15
16
  description: str | None
16
17
  icon: Icon | None
@@ -12,6 +12,7 @@ from .property import Property
12
12
 
13
13
  class Stat(BaseModel):
14
14
  type: Literal["stat"]
15
+ id: str
15
16
  name: str
16
17
  description: str | None
17
18
  url: str
@@ -12,6 +12,7 @@ from .property import Property
12
12
 
13
13
  class Table(BaseModel):
14
14
  type: Literal["table"]
15
+ id: str
15
16
  name: str
16
17
  description: str | None
17
18
  url: str
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "openadmin-dev"
3
- version = "0.5.0"
3
+ version = "0.6.1"
4
4
  description = "Add your description here"
5
5
  authors = [
6
6
  { name="Mykyta Kasianenko", email="mykytakasianenko@gmail.com" },
@@ -403,7 +403,7 @@ wheels = [
403
403
 
404
404
  [[package]]
405
405
  name = "openadmin"
406
- version = "0.4.0"
406
+ version = "0.6.0"
407
407
  source = { editable = "." }
408
408
  dependencies = [
409
409
  { name = "fastapi", extra = ["standard"] },
@@ -1,43 +0,0 @@
1
- # SPDX-FileCopyrightText: 2026 OpenAdmin
2
- #
3
- # SPDX-License-Identifier: AGPL-3.0-or-later
4
-
5
- from .components import (
6
- Action,
7
- AreaChart,
8
- BarChart,
9
- Component,
10
- Form,
11
- Icon,
12
- LineChart,
13
- Markdown,
14
- PieChart,
15
- Property,
16
- PropertyType,
17
- Stat,
18
- Table,
19
- )
20
- from .components.http_methods import HttpMethod
21
- from .page import Page
22
- from .section import Section
23
- from .spec import Spec
24
-
25
- __all__ = [
26
- "Action",
27
- "AreaChart",
28
- "BarChart",
29
- "Component",
30
- "Form",
31
- "HttpMethod",
32
- "LineChart",
33
- "Page",
34
- "PieChart",
35
- "Property",
36
- "PropertyType",
37
- "Section",
38
- "Spec",
39
- "Stat",
40
- "Table",
41
- "Markdown",
42
- "Icon",
43
- ]
File without changes
File without changes
File without changes
File without changes
File without changes