appkit-commons 0.7.1__py3-none-any.whl → 0.12.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,19 @@
1
+ from starlette.types import ASGIApp, Receive, Scope, Send
2
+
3
+
4
+ # Redirect HTTP to HTTPS when behind a proxy (Azure) that sets X-Forwarded-Proto
5
+ class ForceHTTPSMiddleware:
6
+ def __init__(self, app: ASGIApp):
7
+ self.app = app
8
+
9
+ async def __call__(self, scope: Scope, receive: Receive, send: Send):
10
+ if scope["type"] in ("http", "websocket"):
11
+ # Read headers to find X-Forwarded-Proto
12
+ headers = dict(scope["headers"])
13
+ # If Azure says it was HTTPS, force the scope to HTTPS
14
+ if (
15
+ b"x-forwarded-proto" in headers
16
+ and headers[b"x-forwarded-proto"] == b"https"
17
+ ):
18
+ scope["scheme"] = "https"
19
+ await self.app(scope, receive, send)
@@ -0,0 +1,406 @@
1
+ Metadata-Version: 2.4
2
+ Name: appkit-commons
3
+ Version: 0.12.0
4
+ Summary: Add your description here
5
+ Project-URL: Homepage, https://github.com/jenreh/appkit
6
+ Project-URL: Documentation, https://github.com/jenreh/appkit/tree/main/docs
7
+ Project-URL: Repository, https://github.com/jenreh/appkit
8
+ Project-URL: Issues, https://github.com/jenreh/appkit/issues
9
+ Author: Jens Rehpöhler
10
+ Keywords: components,mantine,reflex,ui,web
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
+ Classifier: Topic :: Software Development :: User Interfaces
17
+ Requires-Python: >=3.13
18
+ Requires-Dist: colorlog>=6.9.0
19
+ Requires-Dist: cryptography>=46.0.2
20
+ Requires-Dist: pydantic-settings>=2.10.1
21
+ Requires-Dist: pyyaml>=6.0.2
22
+ Requires-Dist: sqlalchemy-utils>=0.42.0
23
+ Requires-Dist: sqlalchemy>=2.0.41
24
+ Requires-Dist: starlette>=0.48.0
25
+ Provides-Extra: azure
26
+ Requires-Dist: azure-identity==1.25.1; extra == 'azure'
27
+ Requires-Dist: azure-keyvault-secrets==4.10.0; extra == 'azure'
28
+ Description-Content-Type: text/markdown
29
+
30
+ # appkit-commons
31
+
32
+ [![Python 3.13+](https://img.shields.io/badge/python-3.13+-blue.svg)](https://www.python.org/downloads/)
33
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
34
+
35
+ **Shared utilities and infrastructure for AppKit components.**
36
+
37
+ appkit-commons provides the foundational infrastructure used across all AppKit packages, including configuration management, database integration, logging, security utilities, and dependency injection. It serves as the common base layer that enables consistent behavior and shared functionality across the AppKit ecosystem.
38
+
39
+ ---
40
+
41
+ ## ✨ Features
42
+
43
+ - **Configuration Management** - YAML-based configuration with environment variable overrides and secret handling
44
+ - **Database Integration** - SQLAlchemy-based ORM with PostgreSQL support, connection pooling, and encryption
45
+ - **Logging Infrastructure** - Structured logging with color output and configurable levels
46
+ - **Security Utilities** - Password hashing with PBKDF2 and scrypt, secure random generation
47
+ - **Service Registry** - Dependency injection container for managing application services
48
+ - **Secret Management** - Support for local secrets and Azure Key Vault integration
49
+
50
+ ---
51
+
52
+ ## 🚀 Installation
53
+
54
+ ### As Part of AppKit Workspace
55
+
56
+ If you're using the full AppKit workspace:
57
+
58
+ ```bash
59
+ git clone https://github.com/jenreh/appkit.git
60
+ cd appkit
61
+ uv sync
62
+ ```
63
+
64
+ ### Standalone Installation
65
+
66
+ Install from PyPI:
67
+
68
+ ```bash
69
+ pip install appkit-commons
70
+ ```
71
+
72
+ Or with uv:
73
+
74
+ ```bash
75
+ uv add appkit-commons
76
+ ```
77
+
78
+ ### Optional Dependencies
79
+
80
+ For Azure Key Vault support:
81
+
82
+ ```bash
83
+ pip install appkit-commons[azure]
84
+ # or
85
+ uv add appkit-commons[azure]
86
+ ```
87
+
88
+ ### Dependencies
89
+
90
+ - `colorlog>=6.9.0` (colored logging)
91
+ - `cryptography>=46.0.2` (encryption utilities)
92
+ - `pydantic-settings>=2.10.1` (configuration management)
93
+ - `pyyaml==6.0.2` (YAML configuration)
94
+ - `sqlalchemy-utils==0.42.0` (database utilities)
95
+ - `sqlalchemy==2.0.41` (ORM)
96
+
97
+ ---
98
+
99
+ ## 🏁 Quick Start
100
+
101
+ ### Basic Configuration
102
+
103
+ Create a configuration class extending `BaseConfig`:
104
+
105
+ ```python
106
+ from appkit_commons.configuration import BaseConfig
107
+
108
+ class MyConfig(BaseConfig):
109
+ app_name: str = "MyApp"
110
+ debug: bool = False
111
+ api_key: str = "secret:api_key" # Will be resolved from secrets
112
+ ```
113
+
114
+ Load configuration from YAML and environment:
115
+
116
+ ```python
117
+ from appkit_commons.configuration import load_configuration
118
+
119
+ config = load_configuration(MyConfig, "config.yaml")
120
+ print(f"App: {config.app_name}, Debug: {config.debug}")
121
+ ```
122
+
123
+ ### Database Setup
124
+
125
+ Configure database connection:
126
+
127
+ ```python
128
+ from appkit_commons.database import DatabaseConfig, create_session_manager
129
+
130
+ db_config = DatabaseConfig(
131
+ type="postgresql",
132
+ host="localhost",
133
+ port=5432,
134
+ name="myapp",
135
+ username="user",
136
+ password="secret:db_password"
137
+ )
138
+
139
+ session_manager = create_session_manager(db_config)
140
+
141
+ # Use in your code
142
+ with session_manager.session() as session:
143
+ # Your database operations
144
+ pass
145
+ ```
146
+
147
+ ### Logging Setup
148
+
149
+ Initialize logging with configuration:
150
+
151
+ ```python
152
+ from appkit_commons.configuration import setup_logging
153
+
154
+ # Setup with default configuration
155
+ setup_logging()
156
+
157
+ # Or with custom config
158
+ setup_logging(log_level="DEBUG", log_file="app.log")
159
+ ```
160
+
161
+ ---
162
+
163
+ ## 📖 Usage
164
+
165
+ ### Configuration System
166
+
167
+ #### BaseConfig
168
+
169
+ All configuration classes should inherit from `BaseConfig`:
170
+
171
+ ```python
172
+ from appkit_commons.configuration import BaseConfig
173
+
174
+ class AppConfig(BaseConfig):
175
+ model_config = {"env_prefix": "MYAPP_"}
176
+
177
+ database_url: str = "postgresql://localhost/mydb"
178
+ api_timeout: int = 30
179
+ features: dict[str, bool] = {"new_ui": True}
180
+ ```
181
+
182
+ #### Secret Resolution
183
+
184
+ Use `secret:` prefix for sensitive values:
185
+
186
+ ```python
187
+ class SecureConfig(BaseConfig):
188
+ api_key: str = "secret:openai_api_key" # Resolved from env or Key Vault
189
+ db_password: str = "secret:database_password"
190
+ ```
191
+
192
+ #### YAML Configuration
193
+
194
+ Configuration files support nested structures:
195
+
196
+ ```yaml
197
+ # config.yaml
198
+ app:
199
+ name: "MyApp"
200
+ database:
201
+ host: "localhost"
202
+ port: 5432
203
+ features:
204
+ - "authentication"
205
+ - "file_upload"
206
+ ```
207
+
208
+ ### Database Integration
209
+
210
+ #### Session Management
211
+
212
+ Use the session manager for database operations:
213
+
214
+ ```python
215
+ from appkit_commons.database import create_session_manager
216
+
217
+ manager = create_session_manager(db_config)
218
+
219
+ # Get a session
220
+ with manager.session() as session:
221
+ # Perform operations
222
+ result = session.execute(text("SELECT 1"))
223
+ print(result.scalar())
224
+ ```
225
+
226
+ #### Entity Base Classes
227
+
228
+ Extend from `BaseEntity` for common database fields:
229
+
230
+ ```python
231
+ from appkit_commons.database import BaseEntity
232
+ from sqlalchemy import Column, String
233
+
234
+ class User(BaseEntity):
235
+ __tablename__ = "users"
236
+
237
+ email = Column(String, unique=True, nullable=False)
238
+ name = Column(String, nullable=False)
239
+ ```
240
+
241
+ ### Security Utilities
242
+
243
+ #### Password Hashing
244
+
245
+ ```python
246
+ from appkit_commons.security import hash_password, verify_password
247
+
248
+ # Hash a password
249
+ hashed = hash_password("mypassword")
250
+
251
+ # Verify a password
252
+ is_valid = verify_password("mypassword", hashed)
253
+ ```
254
+
255
+ #### Secure Random Generation
256
+
257
+ ```python
258
+ from appkit_commons.security import generate_token
259
+
260
+ token = generate_token(length=32)
261
+ ```
262
+
263
+ ### Service Registry
264
+
265
+ #### Dependency Injection
266
+
267
+ Register and retrieve services:
268
+
269
+ ```python
270
+ from appkit_commons.registry import service_registry
271
+
272
+ # Register a service
273
+ service_registry.register(MyService())
274
+
275
+ # Retrieve a service
276
+ service = service_registry.get(MyService)
277
+ ```
278
+
279
+ ---
280
+
281
+ ## 🔧 Configuration
282
+
283
+ ### Environment Variables
284
+
285
+ Configuration supports nested environment variables:
286
+
287
+ ```bash
288
+ export MYAPP_APP__NAME="ProductionApp"
289
+ export MYAPP_DATABASE__HOST="prod-db.example.com"
290
+ export MYAPP_API__TIMEOUT="60"
291
+ ```
292
+
293
+ ### Azure Key Vault
294
+
295
+ For production secrets, configure Azure Key Vault:
296
+
297
+ ```python
298
+ from appkit_commons.configuration import configure_azure_key_vault
299
+
300
+ configure_azure_key_vault(
301
+ vault_url="https://myvault.vault.azure.net/",
302
+ credential=None # Uses DefaultAzureCredential
303
+ )
304
+ ```
305
+
306
+ ### Logging Configuration
307
+
308
+ Customize logging output:
309
+
310
+ ```python
311
+ from appkit_commons.configuration import setup_logging
312
+
313
+ setup_logging(
314
+ level="INFO",
315
+ format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
316
+ file="app.log",
317
+ max_file_size="10 MB",
318
+ backup_count=5
319
+ )
320
+ ```
321
+
322
+ ---
323
+
324
+ ## 📋 API Reference
325
+
326
+ ### Configuration
327
+
328
+ - `BaseConfig` - Base class for all configuration objects
329
+ - `load_configuration()` - Load configuration from YAML and environment
330
+ - `setup_logging()` - Initialize logging system
331
+ - `configure_azure_key_vault()` - Setup Azure Key Vault integration
332
+
333
+ ### Database
334
+
335
+ - `DatabaseConfig` - Database connection configuration
336
+ - `create_session_manager()` - Create database session manager
337
+ - `BaseEntity` - Base class for database entities
338
+
339
+ ### Security
340
+
341
+ - `hash_password()` - Hash passwords with PBKDF2 or scrypt
342
+ - `verify_password()` - Verify password against hash
343
+ - `generate_token()` - Generate secure random tokens
344
+
345
+ ### Registry
346
+
347
+ - `service_registry` - Global service registry instance
348
+ - `ServiceRegistry` - Dependency injection container
349
+
350
+ ---
351
+
352
+ ## 🔒 Security
353
+
354
+ > [!IMPORTANT]
355
+ > Always use `SecretStr` for sensitive configuration values and the `secret:` prefix for automatic resolution from secure sources.
356
+
357
+ - Passwords are hashed using industry-standard algorithms (PBKDF2/scrypt)
358
+ - Database credentials support encryption at rest
359
+ - Azure Key Vault integration for production secret management
360
+ - Secure random generation for tokens and salts
361
+
362
+ ---
363
+
364
+ ## 🤝 Integration Examples
365
+
366
+ ### With AppKit Components
367
+
368
+ appkit-commons is automatically integrated into other AppKit packages:
369
+
370
+ ```python
371
+ # Configuration is inherited by appkit-user, appkit-assistant, etc.
372
+ from appkit_user.configuration import UserConfig
373
+
374
+ user_config = UserConfig() # Extends BaseConfig automatically
375
+ ```
376
+
377
+ ### Custom Application Setup
378
+
379
+ Complete application bootstrap:
380
+
381
+ ```python
382
+ from appkit_commons.configuration import load_configuration, setup_logging
383
+ from appkit_commons.database import create_session_manager
384
+ from appkit_commons.registry import service_registry
385
+
386
+ # Load config
387
+ config = load_configuration(MyAppConfig, "config.yaml")
388
+
389
+ # Setup logging
390
+ setup_logging(level=config.log_level)
391
+
392
+ # Setup database
393
+ db_manager = create_session_manager(config.database)
394
+ service_registry.register(db_manager)
395
+
396
+ # Your app logic here
397
+ ```
398
+
399
+ ---
400
+
401
+ ## 📚 Related Components
402
+
403
+ - **[appkit-user](./../appkit-user)** - User authentication and authorization
404
+ - **[appkit-assistant](./../appkit-assistant)** - AI assistant functionality
405
+ - **[appkit-mantine](./../appkit-mantine)** - UI components
406
+ - **[appkit-imagecreator](./../appkit-imagecreator)** - Image generation workflows
@@ -1,4 +1,5 @@
1
1
  appkit_commons/__init__.py,sha256=7Gu8uCaX0p3dsmv_fY-7ww_YPwbS014td5ZCW_egQ2w,295
2
+ appkit_commons/middleware.py,sha256=snFwCJpy_9EdfTxjt-JZfqRHFo-Wgnse9EiPRewpUKs,750
2
3
  appkit_commons/registry.py,sha256=vtwtVCdtvFMO5qe2B2cY5PdofPMMNDrSM7yPDv1bOb4,7578
3
4
  appkit_commons/security.py,sha256=8oE3Fx_HDBYnEIhxhiZHe90hP7_2MX_qXpnLxy13FO4,3976
4
5
  appkit_commons/configuration/__init__.py,sha256=a_8LjZo86yyXflmKgMUq-7B36Zgw10ifeknBEWIzQ04,1628
@@ -11,6 +12,6 @@ appkit_commons/database/configuration.py,sha256=C8xcQk8OgwPviF10KhKNkX-aKZT_YgSy
11
12
  appkit_commons/database/entities.py,sha256=lUJBUNWUqXjq0dFffqZObhgkmWYUG0lcCNlmM5fxHls,1807
12
13
  appkit_commons/database/session.py,sha256=0P6qfae1ITmDGkKoDL4b5EnS1ZaDPH2OXn4y-RYhQv4,2253
13
14
  appkit_commons/database/sessionmanager.py,sha256=fATEqMT1Ze0bM7oZXnC6HtzYrAH9kb5_LRP552nSS_8,1605
14
- appkit_commons-0.7.1.dist-info/METADATA,sha256=cuPGZ0CitdZPCfiSQ2pK6YW_rveVNMf5ZKJwKIJbEWc,494
15
- appkit_commons-0.7.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
16
- appkit_commons-0.7.1.dist-info/RECORD,,
15
+ appkit_commons-0.12.0.dist-info/METADATA,sha256=870GI4hUgPeRXP0YInotK6z9GFiogO8dOOMS7k_QmME,9850
16
+ appkit_commons-0.12.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
17
+ appkit_commons-0.12.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.27.0
2
+ Generator: hatchling 1.28.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,15 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: appkit-commons
3
- Version: 0.7.1
4
- Summary: Add your description here
5
- Author: Jens Rehpöhler
6
- Requires-Python: >=3.13
7
- Requires-Dist: colorlog>=6.9.0
8
- Requires-Dist: cryptography>=46.0.2
9
- Requires-Dist: pydantic-settings>=2.10.1
10
- Requires-Dist: pyyaml==6.0.2
11
- Requires-Dist: sqlalchemy-utils==0.42.0
12
- Requires-Dist: sqlalchemy==2.0.41
13
- Provides-Extra: azure
14
- Requires-Dist: azure-identity==1.23.1; extra == 'azure'
15
- Requires-Dist: azure-keyvault-secrets==4.10.0; extra == 'azure'