feather-framework 0.8.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.
Files changed (83) hide show
  1. feather/__init__.py +284 -0
  2. feather/auth/__init__.py +131 -0
  3. feather/auth/decorators.py +518 -0
  4. feather/auth/domains.py +171 -0
  5. feather/auth/google.py +583 -0
  6. feather/auth/permissions.py +61 -0
  7. feather/auth/permissions_logic.py +66 -0
  8. feather/auth/roles.py +80 -0
  9. feather/auth/routes.py +74 -0
  10. feather/auth/setup.py +192 -0
  11. feather/auth/tenancy.py +160 -0
  12. feather/cache/__init__.py +196 -0
  13. feather/cache/base.py +196 -0
  14. feather/cache/decorators.py +352 -0
  15. feather/cache/memory.py +211 -0
  16. feather/cache/redis.py +288 -0
  17. feather/cli/__init__.py +123 -0
  18. feather/cli/build.py +133 -0
  19. feather/cli/db.py +128 -0
  20. feather/cli/dev.py +97 -0
  21. feather/cli/dx.py +457 -0
  22. feather/cli/generate.py +602 -0
  23. feather/cli/jobs.py +238 -0
  24. feather/cli/new.py +5934 -0
  25. feather/cli/platform_admin.py +83 -0
  26. feather/core/__init__.py +6 -0
  27. feather/core/app.py +433 -0
  28. feather/core/config.py +153 -0
  29. feather/core/decorators.py +420 -0
  30. feather/core/discovery.py +140 -0
  31. feather/core/error_handlers.py +356 -0
  32. feather/core/health.py +116 -0
  33. feather/core/helpers.py +318 -0
  34. feather/core/middleware.py +253 -0
  35. feather/db/__init__.py +146 -0
  36. feather/db/base.py +272 -0
  37. feather/db/mixins.py +600 -0
  38. feather/db/pagination.py +275 -0
  39. feather/events/__init__.py +67 -0
  40. feather/events/dispatcher.py +269 -0
  41. feather/events/events.py +160 -0
  42. feather/exceptions/__init__.py +350 -0
  43. feather/jobs/__init__.py +399 -0
  44. feather/jobs/base.py +248 -0
  45. feather/jobs/monitoring.py +218 -0
  46. feather/jobs/rq.py +326 -0
  47. feather/jobs/scheduler.py +287 -0
  48. feather/jobs/sync.py +169 -0
  49. feather/jobs/thread.py +585 -0
  50. feather/serializers/__init__.py +106 -0
  51. feather/serializers/base.py +477 -0
  52. feather/services/__init__.py +38 -0
  53. feather/services/base.py +581 -0
  54. feather/static/api.js +330 -0
  55. feather/static/apple-touch-icon.png +0 -0
  56. feather/static/dropdown.js +244 -0
  57. feather/static/favicon.svg +12 -0
  58. feather/static/feather.js +546 -0
  59. feather/static/icon-192.png +0 -0
  60. feather/static/icon-512.png +0 -0
  61. feather/storage/__init__.py +94 -0
  62. feather/storage/base.py +176 -0
  63. feather/storage/gcs.py +250 -0
  64. feather/storage/local.py +193 -0
  65. feather/templates/components/__init__.html +20 -0
  66. feather/templates/components/alert.html +13 -0
  67. feather/templates/components/button.html +27 -0
  68. feather/templates/components/card.html +15 -0
  69. feather/templates/components/confirm_modal.html +44 -0
  70. feather/templates/components/dropdown.html +112 -0
  71. feather/templates/components/icon.html +17 -0
  72. feather/templates/components/input.html +28 -0
  73. feather/templates/components/modal.html +18 -0
  74. feather/templates/components/prompt_modal.html +120 -0
  75. feather/templates/components/toast.html +101 -0
  76. feather/templates/errors/auth_required.html +94 -0
  77. feather/templates/errors/error.html +30 -0
  78. feather_framework-0.8.0.dist-info/METADATA +2007 -0
  79. feather_framework-0.8.0.dist-info/RECORD +83 -0
  80. feather_framework-0.8.0.dist-info/WHEEL +5 -0
  81. feather_framework-0.8.0.dist-info/entry_points.txt +2 -0
  82. feather_framework-0.8.0.dist-info/licenses/LICENSE +21 -0
  83. feather_framework-0.8.0.dist-info/top_level.txt +1 -0
feather/__init__.py ADDED
@@ -0,0 +1,284 @@
1
+ """
2
+ Feather - A Flask-based web framework for solo developers using AI coding tools.
3
+
4
+ Server-first architecture with progressive enhancement, batteries included.
5
+
6
+ Quick Start
7
+ -----------
8
+ Create a new project and start developing in seconds::
9
+
10
+ $ pip install feather-framework
11
+ $ feather new myapp
12
+ $ cd myapp
13
+ $ feather dev
14
+
15
+ Then open http://localhost:5000 in your browser.
16
+
17
+ Basic Usage
18
+ -----------
19
+ Your app.py is just 3 lines::
20
+
21
+ from feather import Feather
22
+
23
+ app = Feather(__name__)
24
+
25
+ if __name__ == "__main__":
26
+ app.run()
27
+
28
+ Feather auto-discovers your models, services, and routes. No configuration needed.
29
+
30
+ Creating Routes
31
+ ---------------
32
+ API routes (mounted at /api/*)::
33
+
34
+ from feather import api
35
+
36
+ @api.get('/users')
37
+ def list_users():
38
+ return {'users': [...]}
39
+
40
+ Page routes (mounted at /*)::
41
+
42
+ from feather import page
43
+ from flask import render_template
44
+
45
+ @page.get('/')
46
+ def home():
47
+ return render_template('pages/home.html')
48
+
49
+ Using Services
50
+ --------------
51
+ Services contain your business logic::
52
+
53
+ from feather import Service
54
+ from feather.exceptions import NotFoundError
55
+
56
+ class UserService(Service):
57
+ def get_by_id(self, user_id: str):
58
+ return self.get_or_404(User, user_id)
59
+
60
+ def create(self, email: str, username: str):
61
+ user = User(email=email, username=username)
62
+ self.save(user)
63
+ return user
64
+
65
+ Inject services into routes::
66
+
67
+ from feather import api, inject
68
+
69
+ @api.get('/users/<user_id>')
70
+ @inject(UserService)
71
+ def get_user(user_id, user_service):
72
+ user = user_service.get_by_id(user_id)
73
+ return {'user': user.to_dict()}
74
+
75
+ Error Handling
76
+ --------------
77
+ Use exceptions for clean error handling::
78
+
79
+ from feather.exceptions import ValidationError, NotFoundError
80
+
81
+ if not email:
82
+ raise ValidationError('Email is required', field='email')
83
+
84
+ user = User.query.get(user_id)
85
+ if not user:
86
+ raise NotFoundError('User', user_id)
87
+
88
+ Events
89
+ ------
90
+ Dispatch events for loose coupling::
91
+
92
+ from feather import dispatch, listen
93
+ from feather.events import Event
94
+
95
+ class UserCreatedEvent(Event):
96
+ pass
97
+
98
+ @listen(UserCreatedEvent)
99
+ def send_welcome_email(event):
100
+ # Send email to event.user_id
101
+ pass
102
+
103
+ # In your service:
104
+ dispatch(UserCreatedEvent(user_id=user.id))
105
+
106
+ For more information, see the full documentation in feather_framework.md.
107
+ """
108
+
109
+ __version__ = "0.8.0"
110
+
111
+ # =============================================================================
112
+ # Core Application
113
+ # =============================================================================
114
+ # The main Feather class extends Flask with auto-discovery and batteries-included
115
+ # features. Use this as your application entry point.
116
+ from feather.core.app import Feather
117
+
118
+ # Route blueprints and decorators for building your application:
119
+ # - api: Blueprint for API routes, mounted at /api/*
120
+ # - page: Blueprint for page routes, mounted at /*
121
+ # - inject: Decorator to inject service instances into routes
122
+ # - auth_required: Decorator to require authentication
123
+ # - csrf_exempt: Decorator to exempt webhook routes from CSRF protection
124
+ from feather.core.decorators import api, page, inject, auth_required, csrf_exempt
125
+
126
+ # =============================================================================
127
+ # Services Layer
128
+ # =============================================================================
129
+ # Services contain business logic and are the recommended way to interact with
130
+ # your data. Keep routes thin - delegate to services.
131
+ from feather.services.base import Service, transactional, singleton
132
+
133
+ # =============================================================================
134
+ # Authentication Decorators
135
+ # =============================================================================
136
+ # Role-based access control decorators for routes.
137
+ from feather.auth.decorators import (
138
+ admin_required,
139
+ role_required,
140
+ permission_required,
141
+ platform_admin_required,
142
+ rate_limit,
143
+ )
144
+
145
+ # =============================================================================
146
+ # Tenancy
147
+ # =============================================================================
148
+ # Multi-tenant utilities for tenant isolation.
149
+ from feather.auth.tenancy import get_current_tenant_id, tenant_required
150
+
151
+ # =============================================================================
152
+ # Database
153
+ # =============================================================================
154
+ # SQLAlchemy database instance and base model class. All models should inherit
155
+ # from Model to get common functionality like save(), delete(), get_by_id().
156
+ from feather.db.base import db, Model
157
+
158
+ # Database mixins for common patterns - use only what you need
159
+ from feather.db.mixins import (
160
+ UUIDMixin,
161
+ TimestampMixin,
162
+ SoftDeleteMixin,
163
+ OrderingMixin,
164
+ TenantScopedMixin,
165
+ )
166
+
167
+ # Pagination utilities for list endpoints
168
+ from feather.db.pagination import paginate, PaginatedResult
169
+
170
+ # =============================================================================
171
+ # Event System
172
+ # =============================================================================
173
+ # Pub/sub pattern for loose coupling between components. Dispatch events after
174
+ # actions complete, and listen for them in separate handlers.
175
+ from feather.events.dispatcher import dispatch, listen
176
+
177
+ # =============================================================================
178
+ # Storage
179
+ # =============================================================================
180
+ # File storage abstraction supporting local filesystem and Google Cloud Storage.
181
+ # Use get_storage() to get the configured backend.
182
+ from feather.storage import get_storage
183
+
184
+ # =============================================================================
185
+ # Caching
186
+ # =============================================================================
187
+ # Response and function result caching with memory or Redis backends.
188
+ from feather.cache import get_cache, cached, cache_response
189
+
190
+ # =============================================================================
191
+ # Background Jobs
192
+ # =============================================================================
193
+ # Background job processing with sync (dev) or RQ (production) backends.
194
+ from feather.jobs import get_queue, job, scheduled
195
+
196
+ # =============================================================================
197
+ # Request Tracking
198
+ # =============================================================================
199
+ # Get the current request ID for logging and tracing.
200
+ from feather.core.middleware import get_request_id
201
+
202
+ # =============================================================================
203
+ # Exceptions
204
+ # =============================================================================
205
+ # Use these exceptions throughout your application for consistent error handling.
206
+ # They are automatically converted to proper JSON API responses with appropriate
207
+ # HTTP status codes.
208
+ from feather.exceptions import (
209
+ FeatherException, # Base exception - 500 Internal Server Error
210
+ ValidationError, # Invalid input - 400 Bad Request
211
+ AuthenticationError, # Not logged in - 401 Unauthorized
212
+ AuthorizationError, # No permission - 403 Forbidden
213
+ NotFoundError, # Resource not found - 404 Not Found
214
+ ConflictError, # Already exists - 409 Conflict
215
+ StorageError, # File storage failed - 500 Internal Server Error
216
+ DatabaseError, # Database operation failed - 500 Internal Server Error
217
+ )
218
+
219
+ # =============================================================================
220
+ # Public API
221
+ # =============================================================================
222
+ # These are the recommended imports for Feather applications. Import what you
223
+ # need directly from feather:
224
+ #
225
+ # from feather import Feather, api, Service, ValidationError
226
+ #
227
+ __all__ = [
228
+ # Core - The application class and route decorators
229
+ "Feather",
230
+ "api",
231
+ "page",
232
+ "inject",
233
+ "auth_required",
234
+ "csrf_exempt",
235
+ # Services - Business logic layer
236
+ "Service",
237
+ "transactional",
238
+ "singleton",
239
+ # Authentication - Role-based access control
240
+ "admin_required",
241
+ "role_required",
242
+ "permission_required",
243
+ "platform_admin_required",
244
+ "rate_limit",
245
+ # Tenancy - Multi-tenant utilities
246
+ "get_current_tenant_id",
247
+ "tenant_required",
248
+ # Database - SQLAlchemy integration
249
+ "db",
250
+ "Model",
251
+ # Database Mixins - Common model patterns
252
+ "UUIDMixin",
253
+ "TimestampMixin",
254
+ "SoftDeleteMixin",
255
+ "OrderingMixin",
256
+ "TenantScopedMixin",
257
+ # Pagination - List endpoints
258
+ "paginate",
259
+ "PaginatedResult",
260
+ # Events - Pub/sub for loose coupling
261
+ "dispatch",
262
+ "listen",
263
+ # Storage - File upload/download
264
+ "get_storage",
265
+ # Caching - Response and result caching
266
+ "get_cache",
267
+ "cached",
268
+ "cache_response",
269
+ # Background Jobs - Async job processing
270
+ "get_queue",
271
+ "job",
272
+ "scheduled",
273
+ # Request Tracking - For logging and tracing
274
+ "get_request_id",
275
+ # Exceptions - Error handling (automatically converted to JSON responses)
276
+ "FeatherException",
277
+ "ValidationError",
278
+ "AuthenticationError",
279
+ "AuthorizationError",
280
+ "NotFoundError",
281
+ "ConflictError",
282
+ "StorageError",
283
+ "DatabaseError",
284
+ ]
@@ -0,0 +1,131 @@
1
+ """
2
+ Authentication Module
3
+ =====================
4
+
5
+ Provides authentication and authorization for Feather applications.
6
+
7
+ Feather uses a **two-axis authority model**:
8
+ 1. **Tenant role** (`role`): Authority within a tenant (admin, editor, user)
9
+ 2. **Platform authority** (`is_platform_admin`): Cross-tenant operator power
10
+
11
+ This module includes:
12
+ - Flask-Login integration for session management
13
+ - Google OAuth 2.0 support
14
+ - Role-based and permission-based access control
15
+ - Multi-tenant isolation utilities
16
+ - Domain validation for tenant assignment
17
+
18
+ Quick Start
19
+ -----------
20
+ Enable authentication in your app::
21
+
22
+ # app.py
23
+ from feather import Feather
24
+
25
+ app = Feather(__name__)
26
+ # Auth is automatically initialized if User model exists
27
+ # and GOOGLE_CLIENT_ID is configured
28
+
29
+ Using Decorators
30
+ ----------------
31
+ Protect routes with role or permission requirements::
32
+
33
+ from feather import api, auth_required
34
+ from feather.auth import admin_required, role_required, permission_required
35
+
36
+ @api.get('/admin/users')
37
+ @admin_required
38
+ def list_users():
39
+ return {'users': [...]}
40
+
41
+ @api.post('/resources')
42
+ @permission_required('resources.create')
43
+ def create_resource():
44
+ return {'resource': {...}}
45
+
46
+ @api.post('/platform/tenants')
47
+ @platform_admin_required
48
+ def create_tenant():
49
+ # Only platform admins can manage tenants
50
+ pass
51
+
52
+ Tenant Isolation
53
+ ----------------
54
+ Use tenant utilities in your services::
55
+
56
+ from feather.auth import get_current_tenant_id
57
+ from models import Resource
58
+
59
+ def list_resources():
60
+ tenant_id = get_current_tenant_id()
61
+ return Resource.for_tenant(tenant_id).all()
62
+
63
+ Google OAuth
64
+ ------------
65
+ Configure in .env::
66
+
67
+ GOOGLE_CLIENT_ID=your-client-id
68
+ GOOGLE_CLIENT_SECRET=your-client-secret
69
+
70
+ Then users can log in at /auth/google/login
71
+ """
72
+
73
+ from feather.auth.setup import init_auth, login_manager, set_user_loader
74
+
75
+ # Decorators
76
+ from feather.auth.decorators import (
77
+ admin_required,
78
+ auth_required,
79
+ permission_required,
80
+ platform_admin_required,
81
+ rate_limit,
82
+ role_required,
83
+ )
84
+
85
+ # Tenancy
86
+ from feather.auth.tenancy import (
87
+ get_current_tenant_id,
88
+ require_same_tenant,
89
+ tenant_required,
90
+ )
91
+
92
+ # Roles and permissions
93
+ from feather.auth.roles import effective_roles, ROLE_INHERITS
94
+ from feather.auth.permissions import ROLE_PERMISSIONS
95
+ from feather.auth.permissions_logic import effective_permissions
96
+
97
+ # Domain validation
98
+ from feather.auth.domains import (
99
+ extract_domain,
100
+ get_tenant_slug_from_domain,
101
+ is_public_email_domain,
102
+ PUBLIC_EMAIL_DOMAINS,
103
+ )
104
+
105
+ __all__ = [
106
+ # Setup
107
+ "init_auth",
108
+ "login_manager",
109
+ "set_user_loader",
110
+ # Decorators
111
+ "admin_required",
112
+ "auth_required",
113
+ "permission_required",
114
+ "platform_admin_required",
115
+ "rate_limit",
116
+ "role_required",
117
+ # Tenancy
118
+ "get_current_tenant_id",
119
+ "require_same_tenant",
120
+ "tenant_required",
121
+ # Roles and permissions
122
+ "effective_roles",
123
+ "effective_permissions",
124
+ "ROLE_INHERITS",
125
+ "ROLE_PERMISSIONS",
126
+ # Domain validation
127
+ "extract_domain",
128
+ "get_tenant_slug_from_domain",
129
+ "is_public_email_domain",
130
+ "PUBLIC_EMAIL_DOMAINS",
131
+ ]