openadmin-dev 0.4.0__tar.gz → 0.5.0__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 (80) hide show
  1. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/PKG-INFO +1 -1
  2. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/examples/admin/books.py +20 -0
  3. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/examples/main.py +10 -0
  4. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/fastapi/admin_page.py +3 -0
  5. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/fastapi/admin_panel.py +3 -0
  6. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/fastapi/types/section.py +3 -0
  7. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/spec/__init__.py +2 -0
  8. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/spec/components/__init__.py +2 -0
  9. openadmin_dev-0.5.0/openadmin/spec/components/icons.py +2003 -0
  10. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/spec/page.py +2 -1
  11. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/spec/section.py +2 -0
  12. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/pyproject.toml +4 -1
  13. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/.github/ISSUE_TEMPLATE/bug.md +0 -0
  14. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/.github/ISSUE_TEMPLATE/chore.md +0 -0
  15. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/.github/ISSUE_TEMPLATE/feature.md +0 -0
  16. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/.github/actions/branch-name/action.yml +0 -0
  17. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/.github/actions/dependency-cves/action.yml +0 -0
  18. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/.github/actions/format/action.yml +0 -0
  19. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/.github/actions/license/action.yml +0 -0
  20. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/.github/actions/lint/action.yml +0 -0
  21. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/.github/actions/security/action.yml +0 -0
  22. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/.github/actions/spell-check/action.yml +0 -0
  23. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/.github/actions/test/action.yml +0 -0
  24. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/.github/actions/typecheck/action.yml +0 -0
  25. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/.github/actions/unused-code/action.yml +0 -0
  26. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/.github/workflows/ci.yml +0 -0
  27. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/.github/workflows/publish.yml +0 -0
  28. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/.gitignore +0 -0
  29. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/.python-version +0 -0
  30. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/LICENSE +0 -0
  31. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/LICENSES/AGPL-3.0-or-later.txt +0 -0
  32. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/Makefile +0 -0
  33. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/README.md +0 -0
  34. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/REUSE.toml +0 -0
  35. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/docs/assets/logo.png +0 -0
  36. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/examples/__init__.py +0 -0
  37. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/examples/admin/__init__.py +0 -0
  38. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/examples/admin/analytics.py +0 -0
  39. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/examples/admin/authors.py +0 -0
  40. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/examples/admin/genres.py +0 -0
  41. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/examples/admin/health.py +0 -0
  42. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/examples/admin/overview.py +0 -0
  43. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/examples/admin/publishers.py +0 -0
  44. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/examples/admin/reports.py +0 -0
  45. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/examples/admin/tags.py +0 -0
  46. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/examples/lib/__init__.py +0 -0
  47. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/examples/lib/database.py +0 -0
  48. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/examples/lib/lifespan.py +0 -0
  49. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/examples/lib/models.py +0 -0
  50. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/examples/lib/seed.py +0 -0
  51. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/fastapi/__init__.py +0 -0
  52. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/fastapi/deps.py +0 -0
  53. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/fastapi/types/__init__.py +0 -0
  54. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/fastapi/types/action.py +0 -0
  55. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/fastapi/types/area_chart.py +0 -0
  56. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/fastapi/types/bar_chart.py +0 -0
  57. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/fastapi/types/form.py +0 -0
  58. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/fastapi/types/line_chart.py +0 -0
  59. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/fastapi/types/markdown.py +0 -0
  60. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/fastapi/types/page_protocol.py +0 -0
  61. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/fastapi/types/pagination_params.py +0 -0
  62. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/fastapi/types/pie_chart.py +0 -0
  63. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/fastapi/types/stat.py +0 -0
  64. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/fastapi/types/table.py +0 -0
  65. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/fastapi/utils.py +0 -0
  66. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/spec/components/action.py +0 -0
  67. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/spec/components/area_chart.py +0 -0
  68. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/spec/components/bar_chart.py +0 -0
  69. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/spec/components/form.py +0 -0
  70. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/spec/components/http_methods.py +0 -0
  71. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/spec/components/line_chart.py +0 -0
  72. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/spec/components/markdown.py +0 -0
  73. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/spec/components/pie_chart.py +0 -0
  74. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/spec/components/property.py +0 -0
  75. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/spec/components/property_type.py +0 -0
  76. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/spec/components/stat.py +0 -0
  77. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/spec/components/table.py +0 -0
  78. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/openadmin/spec/spec.py +0 -0
  79. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/tests/test_hello.py +0 -0
  80. {openadmin_dev-0.4.0 → openadmin_dev-0.5.0}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openadmin-dev
3
- Version: 0.4.0
3
+ Version: 0.5.0
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
@@ -69,6 +69,26 @@ class AddBookBody(BaseModel):
69
69
  publisher_id: int | None = None
70
70
 
71
71
 
72
+ @page.table("Books by Author", description="Number of books per author")
73
+ async def get_books_by_author(session: AsyncSessionDep, pagination: PageDep):
74
+ stmt = (
75
+ select(models.Author, func.count(models.Book.id).label("book_count"))
76
+ .join(models.Book, models.Book.author_id == models.Author.id)
77
+ .group_by(models.Author.id)
78
+ .order_by(func.count(models.Book.id).desc())
79
+ .offset(pagination.page * pagination.per_page)
80
+ .limit(pagination.per_page)
81
+ )
82
+ result = await session.execute(stmt)
83
+ return [
84
+ {
85
+ "author": f"{author.first_name} {author.last_name}",
86
+ "book_count": book_count,
87
+ }
88
+ for author, book_count in result.all()
89
+ ]
90
+
91
+
72
92
  @page.form_post("Add Book", description="Add a new book to the catalog")
73
93
  async def add_book(body: AddBookBody, session: AsyncSessionDep):
74
94
  book = models.Book(**body.model_dump())
@@ -3,6 +3,7 @@
3
3
  # SPDX-License-Identifier: AGPL-3.0-or-later
4
4
 
5
5
  from fastapi import FastAPI
6
+ from fastapi.middleware.cors import CORSMiddleware
6
7
 
7
8
  from openadmin.fastapi import AdminPanel
8
9
 
@@ -20,6 +21,15 @@ from .admin import (
20
21
  from .lib import lifespan
21
22
 
22
23
  app = FastAPI(lifespan=lifespan.lifespan)
24
+
25
+ app.add_middleware(
26
+ CORSMiddleware,
27
+ allow_origins=["*"],
28
+ allow_credentials=False,
29
+ allow_methods=["*"],
30
+ allow_headers=["*"],
31
+ )
32
+
23
33
  admin_panel = AdminPanel(
24
34
  "Book Library Admin", description="Manage and explore the book catalog"
25
35
  )
@@ -20,10 +20,12 @@ class AdminPage:
20
20
  self,
21
21
  name: str,
22
22
  *,
23
+ icon: spec.Icon | None = None,
23
24
  description: str | None = None,
24
25
  ) -> None:
25
26
  self.name = name
26
27
  self.description = description
28
+ self.icon: spec.Icon | None = icon
27
29
  self.state: list[types.Component] = []
28
30
  self.router = APIRouter(prefix=f"/{name.lower().replace(' ', '-')}")
29
31
  self.key_repeat_count: dict[str, int] = {}
@@ -148,6 +150,7 @@ class AdminPage:
148
150
  return spec.Page(
149
151
  name=self.name,
150
152
  description=self.description,
153
+ icon=self.icon,
151
154
  components=components,
152
155
  )
153
156
 
@@ -30,6 +30,7 @@ class AdminPanel:
30
30
  spec.Section(
31
31
  name=section.name,
32
32
  description=section.description,
33
+ icon=section.icon,
33
34
  pages=[p.get_page_spec(app) for p in section.pages],
34
35
  )
35
36
  )
@@ -46,6 +47,7 @@ class AdminPanel:
46
47
  name: str,
47
48
  *,
48
49
  description: str | None = None,
50
+ icon: spec.Icon | None = None,
49
51
  pages: List[AdminPage],
50
52
  ) -> None:
51
53
  kebab_name = name.lower().replace(" ", "-")
@@ -61,6 +63,7 @@ class AdminPanel:
61
63
  types.Section(
62
64
  name=name,
63
65
  description=description,
66
+ icon=icon,
64
67
  pages=pages,
65
68
  )
66
69
  )
@@ -5,6 +5,8 @@
5
5
  from dataclasses import dataclass
6
6
  from typing import Sequence
7
7
 
8
+ from openadmin import spec
9
+
8
10
  from .page_protocol import PageProtocol
9
11
 
10
12
 
@@ -12,4 +14,5 @@ from .page_protocol import PageProtocol
12
14
  class Section:
13
15
  name: str
14
16
  description: str | None
17
+ icon: spec.Icon | None
15
18
  pages: Sequence[PageProtocol]
@@ -8,6 +8,7 @@ from .components import (
8
8
  BarChart,
9
9
  Component,
10
10
  Form,
11
+ Icon,
11
12
  LineChart,
12
13
  Markdown,
13
14
  PieChart,
@@ -38,4 +39,5 @@ __all__ = [
38
39
  "Stat",
39
40
  "Table",
40
41
  "Markdown",
42
+ "Icon",
41
43
  ]
@@ -8,6 +8,7 @@ from .action import Action
8
8
  from .area_chart import AreaChart
9
9
  from .bar_chart import BarChart
10
10
  from .form import Form
11
+ from .icons import Icon
11
12
  from .line_chart import LineChart
12
13
  from .markdown import Markdown
13
14
  from .pie_chart import PieChart
@@ -32,4 +33,5 @@ __all__ = [
32
33
  "Form",
33
34
  "Property",
34
35
  "PropertyType",
36
+ "Icon",
35
37
  ]