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