skrift 0.1.0a1__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 (68) hide show
  1. skrift-0.1.0a1/.gitignore +24 -0
  2. skrift-0.1.0a1/PKG-INFO +233 -0
  3. skrift-0.1.0a1/README.md +214 -0
  4. skrift-0.1.0a1/pyproject.toml +50 -0
  5. skrift-0.1.0a1/skrift/__init__.py +1 -0
  6. skrift-0.1.0a1/skrift/__main__.py +17 -0
  7. skrift-0.1.0a1/skrift/admin/__init__.py +11 -0
  8. skrift-0.1.0a1/skrift/admin/controller.py +452 -0
  9. skrift-0.1.0a1/skrift/admin/navigation.py +105 -0
  10. skrift-0.1.0a1/skrift/alembic/env.py +91 -0
  11. skrift-0.1.0a1/skrift/alembic/script.py.mako +26 -0
  12. skrift-0.1.0a1/skrift/alembic/versions/20260120_210154_09b0364dbb7b_initial_schema.py +70 -0
  13. skrift-0.1.0a1/skrift/alembic/versions/20260122_152744_0b7c927d2591_add_roles_and_permissions.py +57 -0
  14. skrift-0.1.0a1/skrift/alembic/versions/20260122_172836_cdf734a5b847_add_sa_orm_sentinel_column.py +31 -0
  15. skrift-0.1.0a1/skrift/alembic/versions/20260122_175637_a9c55348eae7_remove_page_type_column.py +43 -0
  16. skrift-0.1.0a1/skrift/alembic/versions/20260122_200000_add_settings_table.py +38 -0
  17. skrift-0.1.0a1/skrift/alembic.ini +77 -0
  18. skrift-0.1.0a1/skrift/asgi.py +545 -0
  19. skrift-0.1.0a1/skrift/auth/__init__.py +58 -0
  20. skrift-0.1.0a1/skrift/auth/guards.py +130 -0
  21. skrift-0.1.0a1/skrift/auth/roles.py +94 -0
  22. skrift-0.1.0a1/skrift/auth/services.py +184 -0
  23. skrift-0.1.0a1/skrift/cli.py +45 -0
  24. skrift-0.1.0a1/skrift/config.py +192 -0
  25. skrift-0.1.0a1/skrift/controllers/__init__.py +4 -0
  26. skrift-0.1.0a1/skrift/controllers/auth.py +371 -0
  27. skrift-0.1.0a1/skrift/controllers/web.py +67 -0
  28. skrift-0.1.0a1/skrift/db/__init__.py +3 -0
  29. skrift-0.1.0a1/skrift/db/base.py +7 -0
  30. skrift-0.1.0a1/skrift/db/models/__init__.py +6 -0
  31. skrift-0.1.0a1/skrift/db/models/page.py +26 -0
  32. skrift-0.1.0a1/skrift/db/models/role.py +56 -0
  33. skrift-0.1.0a1/skrift/db/models/setting.py +13 -0
  34. skrift-0.1.0a1/skrift/db/models/user.py +36 -0
  35. skrift-0.1.0a1/skrift/db/services/__init__.py +1 -0
  36. skrift-0.1.0a1/skrift/db/services/page_service.py +217 -0
  37. skrift-0.1.0a1/skrift/db/services/setting_service.py +206 -0
  38. skrift-0.1.0a1/skrift/lib/__init__.py +3 -0
  39. skrift-0.1.0a1/skrift/lib/exceptions.py +168 -0
  40. skrift-0.1.0a1/skrift/lib/template.py +108 -0
  41. skrift-0.1.0a1/skrift/setup/__init__.py +14 -0
  42. skrift-0.1.0a1/skrift/setup/config_writer.py +211 -0
  43. skrift-0.1.0a1/skrift/setup/controller.py +751 -0
  44. skrift-0.1.0a1/skrift/setup/middleware.py +89 -0
  45. skrift-0.1.0a1/skrift/setup/providers.py +163 -0
  46. skrift-0.1.0a1/skrift/setup/state.py +134 -0
  47. skrift-0.1.0a1/skrift/static/css/style.css +998 -0
  48. skrift-0.1.0a1/skrift/templates/admin/admin.html +19 -0
  49. skrift-0.1.0a1/skrift/templates/admin/base.html +24 -0
  50. skrift-0.1.0a1/skrift/templates/admin/pages/edit.html +32 -0
  51. skrift-0.1.0a1/skrift/templates/admin/pages/list.html +62 -0
  52. skrift-0.1.0a1/skrift/templates/admin/settings/site.html +32 -0
  53. skrift-0.1.0a1/skrift/templates/admin/users/list.html +58 -0
  54. skrift-0.1.0a1/skrift/templates/admin/users/roles.html +42 -0
  55. skrift-0.1.0a1/skrift/templates/auth/login.html +125 -0
  56. skrift-0.1.0a1/skrift/templates/base.html +52 -0
  57. skrift-0.1.0a1/skrift/templates/error-404.html +19 -0
  58. skrift-0.1.0a1/skrift/templates/error-500.html +19 -0
  59. skrift-0.1.0a1/skrift/templates/error.html +19 -0
  60. skrift-0.1.0a1/skrift/templates/index.html +9 -0
  61. skrift-0.1.0a1/skrift/templates/page.html +26 -0
  62. skrift-0.1.0a1/skrift/templates/setup/admin.html +24 -0
  63. skrift-0.1.0a1/skrift/templates/setup/auth.html +110 -0
  64. skrift-0.1.0a1/skrift/templates/setup/base.html +407 -0
  65. skrift-0.1.0a1/skrift/templates/setup/complete.html +17 -0
  66. skrift-0.1.0a1/skrift/templates/setup/database.html +125 -0
  67. skrift-0.1.0a1/skrift/templates/setup/restart.html +28 -0
  68. skrift-0.1.0a1/skrift/templates/setup/site.html +39 -0
@@ -0,0 +1,24 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Virtual environments
10
+ .venv
11
+
12
+ # Environment variables
13
+ .env
14
+
15
+ # Database
16
+ *.db
17
+
18
+ # IDE
19
+ .idea/
20
+
21
+ # App configuration (generated by setup wizard)
22
+ app.yaml
23
+ app.bak.yaml
24
+ app.yaml.backup.*
@@ -0,0 +1,233 @@
1
+ Metadata-Version: 2.4
2
+ Name: skrift
3
+ Version: 0.1.0a1
4
+ Summary: A lightweight async Python CMS for crafting modern websites
5
+ Requires-Python: >=3.13
6
+ Requires-Dist: advanced-alchemy>=0.26.0
7
+ Requires-Dist: aiosqlite>=0.20.0
8
+ Requires-Dist: alembic>=1.14.0
9
+ Requires-Dist: asyncpg>=0.30.0
10
+ Requires-Dist: httpx>=0.28.0
11
+ Requires-Dist: litestar[cryptography,jinja,standard]>=2.14.0
12
+ Requires-Dist: pydantic-settings>=2.7.0
13
+ Requires-Dist: python-dotenv>=1.0.0
14
+ Requires-Dist: pyyaml>=6.0.0
15
+ Requires-Dist: ruamel-yaml>=0.18.0
16
+ Requires-Dist: sqlalchemy[asyncio]>=2.0.36
17
+ Requires-Dist: uvicorn>=0.34.0
18
+ Description-Content-Type: text/markdown
19
+
20
+ # Skrift
21
+
22
+ A modern Litestar-powered content management framework with multi-provider OAuth authentication, role-based access control, and WordPress-like template resolution.
23
+
24
+ ## Features
25
+
26
+ - **Multi-Provider OAuth**: Authenticate with Google, GitHub, Microsoft, Discord, Facebook, or Twitter/X
27
+ - **Role-Based Access Control**: Flexible permission system with Admin, Editor, Author, and Moderator roles
28
+ - **Setup Wizard**: Guided first-time configuration without manual file editing
29
+ - **Admin Interface**: Web-based management for users, pages, and site settings
30
+ - **WordPress-like Templates**: Hierarchical template resolution for content pages
31
+ - **Dynamic Controllers**: Load controllers from `app.yaml` configuration
32
+ - **SQLAlchemy Integration**: Async database support with SQLite/PostgreSQL
33
+ - **Client-Side Sessions**: Encrypted cookie sessions for horizontal scalability
34
+
35
+ ## Quick Start
36
+
37
+ ### Prerequisites
38
+
39
+ - Python 3.13+
40
+
41
+ ### Installation
42
+
43
+ ```bash
44
+ # Install Skrift
45
+ pip install skrift
46
+
47
+ # Or install from git
48
+ pip install git+https://github.com/ZechCodes/skrift.git
49
+ ```
50
+
51
+ ### Getting Started
52
+
53
+ Create a project directory and set up your environment:
54
+
55
+ ```bash
56
+ mkdir mysite && cd mysite
57
+
58
+ # Create minimal environment file
59
+ echo "SECRET_KEY=$(python -c 'import secrets; print(secrets.token_urlsafe(32))')" > .env
60
+
61
+ # Start Skrift
62
+ skrift
63
+ ```
64
+
65
+ Open http://localhost:8080 to launch the setup wizard.
66
+
67
+ ### Setup Wizard
68
+
69
+ The setup wizard guides you through initial configuration:
70
+
71
+ 1. **Database Configuration**: Choose SQLite (dev) or PostgreSQL (production)
72
+ 2. **Authentication Providers**: Configure OAuth credentials
73
+ 3. **Site Settings**: Set site name, tagline, and copyright info
74
+ 4. **Admin Account**: Create your first admin user via OAuth login
75
+
76
+ After completing the wizard, an `app.yaml` configuration file is created in your project directory.
77
+
78
+ ### Manual Configuration
79
+
80
+ Alternatively, create `app.yaml` manually:
81
+
82
+ ```yaml
83
+ controllers:
84
+ - skrift.controllers.auth:AuthController
85
+ - skrift.admin.controller:AdminController
86
+ - skrift.controllers.web:WebController
87
+
88
+ db:
89
+ url: sqlite+aiosqlite:///./app.db
90
+
91
+ auth:
92
+ redirect_base_url: http://localhost:8080
93
+ providers:
94
+ google:
95
+ client_id: $GOOGLE_CLIENT_ID
96
+ client_secret: $GOOGLE_CLIENT_SECRET
97
+ scopes: [openid, email, profile]
98
+ ```
99
+
100
+ Then run migrations and start the server:
101
+
102
+ ```bash
103
+ skrift-db upgrade head
104
+ skrift
105
+ ```
106
+
107
+ ## Documentation
108
+
109
+ - **[Full Documentation](docs/README.md)**: Comprehensive guide covering all features
110
+ - **[Deployment Guide](docs/deployment.md)**: VPS, Docker, and Kubernetes deployment
111
+ - **[CSS Framework](docs/css-framework.md)**: Styling documentation
112
+
113
+ ## Project Structure
114
+
115
+ ```
116
+ skrift/
117
+ ├── skrift/ # Main Python package
118
+ │ ├── asgi.py # Application factory
119
+ │ ├── config.py # Settings management
120
+ │ ├── controllers/ # Route handlers
121
+ │ ├── admin/ # Admin panel
122
+ │ ├── auth/ # RBAC and guards
123
+ │ ├── db/ # Models and services
124
+ │ ├── lib/ # Template resolver
125
+ │ └── setup/ # Setup wizard
126
+ ├── templates/ # Jinja2 templates
127
+ ├── static/ # Static assets
128
+ ├── alembic/ # Database migrations
129
+ ├── docs/ # Documentation
130
+ ├── app.yaml # Application config (generated)
131
+ └── main.py # Development entry point
132
+ ```
133
+
134
+ ## Configuration
135
+
136
+ ### Environment Variables
137
+
138
+ | Variable | Required | Description |
139
+ |----------|----------|-------------|
140
+ | `SECRET_KEY` | Yes | Session encryption key |
141
+ | `DEBUG` | No | Enable debug mode (default: false) |
142
+ | `DATABASE_URL` | No | Database connection string |
143
+ | `OAUTH_REDIRECT_BASE_URL` | No | OAuth callback base URL |
144
+
145
+ OAuth credentials are configured per-provider (e.g., `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET`).
146
+
147
+ ### app.yaml
148
+
149
+ Application configuration is stored in `app.yaml` (generated by setup wizard):
150
+
151
+ ```yaml
152
+ controllers:
153
+ - skrift.controllers.auth:AuthController
154
+ - skrift.admin.controller:AdminController
155
+ - skrift.controllers.web:WebController
156
+
157
+ db:
158
+ url: $DATABASE_URL
159
+ pool_size: 5
160
+
161
+ auth:
162
+ redirect_base_url: $OAUTH_REDIRECT_BASE_URL
163
+ providers:
164
+ google:
165
+ client_id: $GOOGLE_CLIENT_ID
166
+ client_secret: $GOOGLE_CLIENT_SECRET
167
+ ```
168
+
169
+ Environment variables (prefixed with `$`) are interpolated at runtime.
170
+
171
+ ## Deployment
172
+
173
+ ### Minimal VPS Deployment
174
+
175
+ ```bash
176
+ # Install Skrift
177
+ pip install skrift
178
+
179
+ # Create project directory
180
+ mkdir -p /opt/skrift && cd /opt/skrift
181
+
182
+ # Configure environment
183
+ cat > .env << EOF
184
+ SECRET_KEY=$(python -c "import secrets; print(secrets.token_urlsafe(32))")
185
+ DATABASE_URL=sqlite+aiosqlite:///./app.db
186
+ OAUTH_REDIRECT_BASE_URL=https://yourdomain.com
187
+ EOF
188
+
189
+ # Start server (use setup wizard or create app.yaml manually)
190
+ skrift
191
+ ```
192
+
193
+ ### Production with Gunicorn
194
+
195
+ ```bash
196
+ pip install gunicorn
197
+ gunicorn skrift.asgi:app -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8080
198
+ ```
199
+
200
+ See the [Deployment Guide](docs/deployment.md) for detailed instructions including Docker, Docker Compose, and Kubernetes deployments.
201
+
202
+ ## Database Migrations
203
+
204
+ ```bash
205
+ # Apply migrations
206
+ skrift-db upgrade head
207
+
208
+ # Create new migration
209
+ skrift-db revision --autogenerate -m "description"
210
+
211
+ # Rollback
212
+ skrift-db downgrade -1
213
+ ```
214
+
215
+ ## Template Resolution
216
+
217
+ Templates follow WordPress-like hierarchical resolution:
218
+
219
+ | URL Path | Templates Tried |
220
+ |----------|-----------------|
221
+ | `/about` | `page-about.html` -> `page.html` |
222
+ | `/services/web` | `page-services-web.html` -> `page-services.html` -> `page.html` |
223
+
224
+ ## Contributing
225
+
226
+ 1. Fork the repository
227
+ 2. Create a feature branch
228
+ 3. Make your changes
229
+ 4. Submit a pull request
230
+
231
+ ## License
232
+
233
+ MIT
@@ -0,0 +1,214 @@
1
+ # Skrift
2
+
3
+ A modern Litestar-powered content management framework with multi-provider OAuth authentication, role-based access control, and WordPress-like template resolution.
4
+
5
+ ## Features
6
+
7
+ - **Multi-Provider OAuth**: Authenticate with Google, GitHub, Microsoft, Discord, Facebook, or Twitter/X
8
+ - **Role-Based Access Control**: Flexible permission system with Admin, Editor, Author, and Moderator roles
9
+ - **Setup Wizard**: Guided first-time configuration without manual file editing
10
+ - **Admin Interface**: Web-based management for users, pages, and site settings
11
+ - **WordPress-like Templates**: Hierarchical template resolution for content pages
12
+ - **Dynamic Controllers**: Load controllers from `app.yaml` configuration
13
+ - **SQLAlchemy Integration**: Async database support with SQLite/PostgreSQL
14
+ - **Client-Side Sessions**: Encrypted cookie sessions for horizontal scalability
15
+
16
+ ## Quick Start
17
+
18
+ ### Prerequisites
19
+
20
+ - Python 3.13+
21
+
22
+ ### Installation
23
+
24
+ ```bash
25
+ # Install Skrift
26
+ pip install skrift
27
+
28
+ # Or install from git
29
+ pip install git+https://github.com/ZechCodes/skrift.git
30
+ ```
31
+
32
+ ### Getting Started
33
+
34
+ Create a project directory and set up your environment:
35
+
36
+ ```bash
37
+ mkdir mysite && cd mysite
38
+
39
+ # Create minimal environment file
40
+ echo "SECRET_KEY=$(python -c 'import secrets; print(secrets.token_urlsafe(32))')" > .env
41
+
42
+ # Start Skrift
43
+ skrift
44
+ ```
45
+
46
+ Open http://localhost:8080 to launch the setup wizard.
47
+
48
+ ### Setup Wizard
49
+
50
+ The setup wizard guides you through initial configuration:
51
+
52
+ 1. **Database Configuration**: Choose SQLite (dev) or PostgreSQL (production)
53
+ 2. **Authentication Providers**: Configure OAuth credentials
54
+ 3. **Site Settings**: Set site name, tagline, and copyright info
55
+ 4. **Admin Account**: Create your first admin user via OAuth login
56
+
57
+ After completing the wizard, an `app.yaml` configuration file is created in your project directory.
58
+
59
+ ### Manual Configuration
60
+
61
+ Alternatively, create `app.yaml` manually:
62
+
63
+ ```yaml
64
+ controllers:
65
+ - skrift.controllers.auth:AuthController
66
+ - skrift.admin.controller:AdminController
67
+ - skrift.controllers.web:WebController
68
+
69
+ db:
70
+ url: sqlite+aiosqlite:///./app.db
71
+
72
+ auth:
73
+ redirect_base_url: http://localhost:8080
74
+ providers:
75
+ google:
76
+ client_id: $GOOGLE_CLIENT_ID
77
+ client_secret: $GOOGLE_CLIENT_SECRET
78
+ scopes: [openid, email, profile]
79
+ ```
80
+
81
+ Then run migrations and start the server:
82
+
83
+ ```bash
84
+ skrift-db upgrade head
85
+ skrift
86
+ ```
87
+
88
+ ## Documentation
89
+
90
+ - **[Full Documentation](docs/README.md)**: Comprehensive guide covering all features
91
+ - **[Deployment Guide](docs/deployment.md)**: VPS, Docker, and Kubernetes deployment
92
+ - **[CSS Framework](docs/css-framework.md)**: Styling documentation
93
+
94
+ ## Project Structure
95
+
96
+ ```
97
+ skrift/
98
+ ├── skrift/ # Main Python package
99
+ │ ├── asgi.py # Application factory
100
+ │ ├── config.py # Settings management
101
+ │ ├── controllers/ # Route handlers
102
+ │ ├── admin/ # Admin panel
103
+ │ ├── auth/ # RBAC and guards
104
+ │ ├── db/ # Models and services
105
+ │ ├── lib/ # Template resolver
106
+ │ └── setup/ # Setup wizard
107
+ ├── templates/ # Jinja2 templates
108
+ ├── static/ # Static assets
109
+ ├── alembic/ # Database migrations
110
+ ├── docs/ # Documentation
111
+ ├── app.yaml # Application config (generated)
112
+ └── main.py # Development entry point
113
+ ```
114
+
115
+ ## Configuration
116
+
117
+ ### Environment Variables
118
+
119
+ | Variable | Required | Description |
120
+ |----------|----------|-------------|
121
+ | `SECRET_KEY` | Yes | Session encryption key |
122
+ | `DEBUG` | No | Enable debug mode (default: false) |
123
+ | `DATABASE_URL` | No | Database connection string |
124
+ | `OAUTH_REDIRECT_BASE_URL` | No | OAuth callback base URL |
125
+
126
+ OAuth credentials are configured per-provider (e.g., `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET`).
127
+
128
+ ### app.yaml
129
+
130
+ Application configuration is stored in `app.yaml` (generated by setup wizard):
131
+
132
+ ```yaml
133
+ controllers:
134
+ - skrift.controllers.auth:AuthController
135
+ - skrift.admin.controller:AdminController
136
+ - skrift.controllers.web:WebController
137
+
138
+ db:
139
+ url: $DATABASE_URL
140
+ pool_size: 5
141
+
142
+ auth:
143
+ redirect_base_url: $OAUTH_REDIRECT_BASE_URL
144
+ providers:
145
+ google:
146
+ client_id: $GOOGLE_CLIENT_ID
147
+ client_secret: $GOOGLE_CLIENT_SECRET
148
+ ```
149
+
150
+ Environment variables (prefixed with `$`) are interpolated at runtime.
151
+
152
+ ## Deployment
153
+
154
+ ### Minimal VPS Deployment
155
+
156
+ ```bash
157
+ # Install Skrift
158
+ pip install skrift
159
+
160
+ # Create project directory
161
+ mkdir -p /opt/skrift && cd /opt/skrift
162
+
163
+ # Configure environment
164
+ cat > .env << EOF
165
+ SECRET_KEY=$(python -c "import secrets; print(secrets.token_urlsafe(32))")
166
+ DATABASE_URL=sqlite+aiosqlite:///./app.db
167
+ OAUTH_REDIRECT_BASE_URL=https://yourdomain.com
168
+ EOF
169
+
170
+ # Start server (use setup wizard or create app.yaml manually)
171
+ skrift
172
+ ```
173
+
174
+ ### Production with Gunicorn
175
+
176
+ ```bash
177
+ pip install gunicorn
178
+ gunicorn skrift.asgi:app -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8080
179
+ ```
180
+
181
+ See the [Deployment Guide](docs/deployment.md) for detailed instructions including Docker, Docker Compose, and Kubernetes deployments.
182
+
183
+ ## Database Migrations
184
+
185
+ ```bash
186
+ # Apply migrations
187
+ skrift-db upgrade head
188
+
189
+ # Create new migration
190
+ skrift-db revision --autogenerate -m "description"
191
+
192
+ # Rollback
193
+ skrift-db downgrade -1
194
+ ```
195
+
196
+ ## Template Resolution
197
+
198
+ Templates follow WordPress-like hierarchical resolution:
199
+
200
+ | URL Path | Templates Tried |
201
+ |----------|-----------------|
202
+ | `/about` | `page-about.html` -> `page.html` |
203
+ | `/services/web` | `page-services-web.html` -> `page-services.html` -> `page.html` |
204
+
205
+ ## Contributing
206
+
207
+ 1. Fork the repository
208
+ 2. Create a feature branch
209
+ 3. Make your changes
210
+ 4. Submit a pull request
211
+
212
+ ## License
213
+
214
+ MIT
@@ -0,0 +1,50 @@
1
+ [project]
2
+ name = "skrift"
3
+ version = "0.1.0a1"
4
+ description = "A lightweight async Python CMS for crafting modern websites"
5
+ readme = "README.md"
6
+ requires-python = ">=3.13"
7
+ dependencies = [
8
+ "litestar[standard,jinja,cryptography]>=2.14.0",
9
+ "sqlalchemy[asyncio]>=2.0.36",
10
+ "aiosqlite>=0.20.0",
11
+ "asyncpg>=0.30.0",
12
+ "advanced-alchemy>=0.26.0",
13
+ "alembic>=1.14.0",
14
+ "httpx>=0.28.0",
15
+ "pydantic-settings>=2.7.0",
16
+ "python-dotenv>=1.0.0",
17
+ "uvicorn>=0.34.0",
18
+ "pyyaml>=6.0.0",
19
+ "ruamel.yaml>=0.18.0",
20
+ ]
21
+
22
+ [project.scripts]
23
+ skrift = "skrift.__main__:main"
24
+ skrift-db = "skrift.cli:db"
25
+
26
+ [tool.uv]
27
+ package = true
28
+
29
+ [build-system]
30
+ requires = ["hatchling"]
31
+ build-backend = "hatchling.build"
32
+
33
+ [tool.hatch.build]
34
+ include = [
35
+ "skrift/**/*.py",
36
+ "skrift/templates/**/*.html",
37
+ "skrift/static/**/*",
38
+ "skrift/alembic/**/*",
39
+ "skrift/alembic.ini",
40
+ ]
41
+ exclude = [
42
+ "**/__pycache__",
43
+ "**/*.pyc",
44
+ "app.yaml",
45
+ "*.db",
46
+ ]
47
+
48
+ [tool.ruff]
49
+ line-length = 100
50
+ target-version = "py313"
@@ -0,0 +1 @@
1
+ # Skrift application package
@@ -0,0 +1,17 @@
1
+ """Entry point for the skrift package."""
2
+
3
+ import uvicorn
4
+
5
+
6
+ def main():
7
+ """Run the Skrift development server."""
8
+ uvicorn.run(
9
+ "skrift.asgi:app",
10
+ host="0.0.0.0",
11
+ port=8080,
12
+ reload=True,
13
+ )
14
+
15
+
16
+ if __name__ == "__main__":
17
+ main()
@@ -0,0 +1,11 @@
1
+ """Admin module for administrative functionality."""
2
+
3
+ from skrift.admin.controller import AdminController
4
+ from skrift.admin.navigation import AdminNavItem, build_admin_nav, ADMIN_NAV_TAG
5
+
6
+ __all__ = [
7
+ "AdminController",
8
+ "AdminNavItem",
9
+ "build_admin_nav",
10
+ "ADMIN_NAV_TAG",
11
+ ]