fastapi-viewsets 0.1.2__tar.gz → 1.1.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 (42) hide show
  1. {fastapi_viewsets-0.1.2 → fastapi_viewsets-1.1.0}/LICENSE +20 -20
  2. fastapi_viewsets-1.1.0/PKG-INFO +454 -0
  3. fastapi_viewsets-1.1.0/README.md +412 -0
  4. fastapi_viewsets-1.1.0/fastapi_viewsets/__init__.py +276 -0
  5. fastapi_viewsets-1.1.0/fastapi_viewsets/async_base.py +276 -0
  6. fastapi_viewsets-1.1.0/fastapi_viewsets/async_utils.py +143 -0
  7. fastapi_viewsets-1.1.0/fastapi_viewsets/constants.py +16 -0
  8. fastapi_viewsets-1.1.0/fastapi_viewsets/db_conf.py +134 -0
  9. fastapi_viewsets-1.1.0/fastapi_viewsets/utils.py +142 -0
  10. fastapi_viewsets-1.1.0/fastapi_viewsets.egg-info/PKG-INFO +454 -0
  11. fastapi_viewsets-1.1.0/fastapi_viewsets.egg-info/SOURCES.txt +32 -0
  12. fastapi_viewsets-1.1.0/fastapi_viewsets.egg-info/requires.txt +25 -0
  13. {fastapi_viewsets-0.1.2 → fastapi_viewsets-1.1.0}/setup.cfg +7 -7
  14. fastapi_viewsets-1.1.0/setup.py +50 -0
  15. fastapi_viewsets-1.1.0/tests/test_adapter_methods_coverage.py +447 -0
  16. fastapi_viewsets-1.1.0/tests/test_async_base_viewset.py +340 -0
  17. fastapi_viewsets-1.1.0/tests/test_async_utils.py +343 -0
  18. fastapi_viewsets-1.1.0/tests/test_backward_compatibility.py +155 -0
  19. fastapi_viewsets-1.1.0/tests/test_base_viewset.py +399 -0
  20. fastapi_viewsets-1.1.0/tests/test_coverage_gaps.py +545 -0
  21. fastapi_viewsets-1.1.0/tests/test_db_conf.py +170 -0
  22. fastapi_viewsets-1.1.0/tests/test_db_conf_extended.py +99 -0
  23. fastapi_viewsets-1.1.0/tests/test_edge_cases.py +286 -0
  24. fastapi_viewsets-1.1.0/tests/test_error_handling.py +283 -0
  25. fastapi_viewsets-1.1.0/tests/test_exception_handling.py +564 -0
  26. fastapi_viewsets-1.1.0/tests/test_integration.py +379 -0
  27. fastapi_viewsets-1.1.0/tests/test_missing_coverage.py +359 -0
  28. fastapi_viewsets-1.1.0/tests/test_orm_adapters.py +379 -0
  29. fastapi_viewsets-1.1.0/tests/test_orm_adapters_extended.py +469 -0
  30. fastapi_viewsets-1.1.0/tests/test_utils.py +299 -0
  31. fastapi_viewsets-1.1.0/tests/test_viewsets_with_adapters.py +361 -0
  32. fastapi_viewsets-0.1.2/PKG-INFO +0 -16
  33. fastapi_viewsets-0.1.2/README.md +0 -67
  34. fastapi_viewsets-0.1.2/fastapi_viewsets/__init__.py +0 -93
  35. fastapi_viewsets-0.1.2/fastapi_viewsets/db_conf.py +0 -23
  36. fastapi_viewsets-0.1.2/fastapi_viewsets/utils.py +0 -41
  37. fastapi_viewsets-0.1.2/fastapi_viewsets.egg-info/PKG-INFO +0 -16
  38. fastapi_viewsets-0.1.2/fastapi_viewsets.egg-info/SOURCES.txt +0 -12
  39. fastapi_viewsets-0.1.2/fastapi_viewsets.egg-info/requires.txt +0 -3
  40. fastapi_viewsets-0.1.2/setup.py +0 -19
  41. {fastapi_viewsets-0.1.2 → fastapi_viewsets-1.1.0}/fastapi_viewsets.egg-info/dependency_links.txt +0 -0
  42. {fastapi_viewsets-0.1.2 → fastapi_viewsets-1.1.0}/fastapi_viewsets.egg-info/top_level.txt +0 -0
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2022 Valenchits Alexander
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Valenchits Alexander
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  SOFTWARE.
@@ -0,0 +1,454 @@
1
+ Metadata-Version: 2.4
2
+ Name: fastapi_viewsets
3
+ Version: 1.1.0
4
+ Summary: Package for creating endpoint
5
+ Home-page: https://github.com/svalench/fastapi_viewsets
6
+ Author: Alexander Valenchits
7
+ Classifier: Programming Language :: Python :: 3.9
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.6
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Requires-Dist: fastapi>=0.76.0
14
+ Requires-Dist: uvicorn>=0.17.6
15
+ Requires-Dist: SQLAlchemy>=1.4.36
16
+ Requires-Dist: python-dotenv>=0.19.0
17
+ Requires-Dist: typing-extensions>=4.0.0; python_version < "3.8"
18
+ Provides-Extra: sqlalchemy
19
+ Requires-Dist: SQLAlchemy>=1.4.36; extra == "sqlalchemy"
20
+ Provides-Extra: tortoise
21
+ Requires-Dist: tortoise-orm>=0.20.0; extra == "tortoise"
22
+ Requires-Dist: asyncpg>=0.28.0; extra == "tortoise"
23
+ Provides-Extra: peewee
24
+ Requires-Dist: peewee>=3.17.0; extra == "peewee"
25
+ Provides-Extra: test
26
+ Requires-Dist: pytest>=7.0.0; extra == "test"
27
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "test"
28
+ Requires-Dist: pytest-cov>=4.0.0; extra == "test"
29
+ Requires-Dist: httpx>=0.24.0; extra == "test"
30
+ Requires-Dist: faker>=18.0.0; extra == "test"
31
+ Requires-Dist: aiosqlite>=0.19.0; extra == "test"
32
+ Dynamic: author
33
+ Dynamic: classifier
34
+ Dynamic: description
35
+ Dynamic: description-content-type
36
+ Dynamic: home-page
37
+ Dynamic: license-file
38
+ Dynamic: provides-extra
39
+ Dynamic: requires-dist
40
+ Dynamic: requires-python
41
+ Dynamic: summary
42
+
43
+ # FastAPI ViewSets
44
+
45
+ [![Python Version](https://img.shields.io/badge/python-3.6%2B-blue.svg)](https://www.python.org/downloads/)
46
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
47
+ [![PyPI version](https://badge.fury.io/py/fastapi-viewsets.svg)](https://badge.fury.io/py/fastapi-viewsets)
48
+
49
+ A powerful package for creating REST API endpoints with FastAPI and SQLAlchemy. Automatically generates CRUD operations (Create, Read, Update, Delete) for your database models, similar to Django REST Framework's ViewSets.
50
+
51
+ ## Features
52
+
53
+ - 🚀 **Automatic CRUD endpoints** - Generate REST API endpoints automatically
54
+ - 🔒 **OAuth2 support** - Built-in authentication protection for endpoints
55
+ - ⚡ **Async support** - Full async/await support for high-performance applications
56
+ - 📝 **Type hints** - Full type annotation support for better IDE experience
57
+ - 🎯 **Flexible** - Choose which HTTP methods to enable
58
+ - 🔧 **Easy to use** - Simple API, minimal boilerplate code
59
+
60
+ ## Installation
61
+
62
+ Install the package using pip:
63
+
64
+ ```bash
65
+ pip install fastapi-viewsets
66
+ ```
67
+
68
+ For async support, you'll also need an async database driver:
69
+
70
+ ```bash
71
+ # For SQLite
72
+ pip install aiosqlite
73
+
74
+ # For PostgreSQL
75
+ pip install asyncpg
76
+
77
+ # For MySQL
78
+ pip install aiomysql
79
+ ```
80
+
81
+ ## Quick Start
82
+
83
+ ### Synchronous Example
84
+
85
+ Create a `main.py` file:
86
+
87
+ ```python
88
+ from typing import Optional
89
+ from fastapi import FastAPI
90
+ from pydantic import BaseModel
91
+ from sqlalchemy import Column, Integer, String, Boolean
92
+ from fastapi_viewsets import BaseViewset
93
+ from fastapi_viewsets.db_conf import Base, get_session, engine
94
+
95
+ # Create FastAPI app
96
+ app = FastAPI()
97
+
98
+ # Define Pydantic schema
99
+ class UserSchema(BaseModel):
100
+ """Pydantic Schema"""
101
+ id: Optional[int] = None
102
+ username: str
103
+ password: str
104
+ is_admin: Optional[bool] = False
105
+
106
+ class Config:
107
+ orm_mode = True
108
+
109
+ # Define SQLAlchemy model
110
+ class User(Base):
111
+ """SQLAlchemy model"""
112
+ __tablename__ = "user"
113
+
114
+ id = Column(Integer, primary_key=True, index=True)
115
+ username = Column(String, unique=True)
116
+ password = Column(String(255))
117
+ is_admin = Column(Boolean, default=False)
118
+
119
+ # Create database tables
120
+ Base.metadata.create_all(engine)
121
+
122
+ # Create viewset
123
+ user_viewset = BaseViewset(
124
+ endpoint='/user',
125
+ model=User,
126
+ response_model=UserSchema,
127
+ db_session=get_session,
128
+ tags=['Users']
129
+ )
130
+
131
+ # Register all CRUD methods
132
+ user_viewset.register()
133
+
134
+ # Include router in FastAPI app
135
+ app.include_router(user_viewset)
136
+ ```
137
+
138
+ Run the application:
139
+
140
+ ```bash
141
+ uvicorn main:app --reload
142
+ ```
143
+
144
+ Visit the interactive API documentation at [http://localhost:8000/docs](http://localhost:8000/docs)
145
+
146
+ ### Async Example
147
+
148
+ For async support, use `AsyncBaseViewset`:
149
+
150
+ ```python
151
+ from typing import Optional
152
+ from fastapi import FastAPI
153
+ from pydantic import BaseModel, ConfigDict
154
+ from sqlalchemy import Column, Integer, String, Boolean
155
+ from fastapi_viewsets import AsyncBaseViewset
156
+ from fastapi_viewsets.db_conf import Base, get_async_session, engine
157
+
158
+ # Create FastAPI app
159
+ app = FastAPI()
160
+
161
+ # Define Pydantic schema
162
+ class UserSchema(BaseModel):
163
+ """Pydantic Schema"""
164
+ model_config = ConfigDict(from_attributes=True)
165
+ id: Optional[int] = None
166
+ username: str
167
+ password: str
168
+ is_admin: Optional[bool] = False
169
+
170
+
171
+ # Define SQLAlchemy model
172
+ class User(Base):
173
+ """SQLAlchemy model"""
174
+ __tablename__ = "user"
175
+
176
+ id = Column(Integer, primary_key=True, index=True)
177
+ username = Column(String, unique=True)
178
+ password = Column(String(255))
179
+ is_admin = Column(Boolean, default=False)
180
+
181
+ # Create database tables
182
+ Base.metadata.create_all(engine)
183
+
184
+ # Create async viewset
185
+ user_viewset = AsyncBaseViewset(
186
+ endpoint='/user',
187
+ model=User,
188
+ response_model=UserSchema,
189
+ db_session=get_async_session,
190
+ tags=['Users']
191
+ )
192
+
193
+ # Register all CRUD methods
194
+ user_viewset.register()
195
+
196
+ # Include router in FastAPI app
197
+ app.include_router(user_viewset)
198
+ ```
199
+
200
+ ## Authentication Example
201
+
202
+ You can protect endpoints with OAuth2:
203
+
204
+ ```python
205
+ from fastapi import FastAPI, Depends, HTTPException
206
+ from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
207
+ from fastapi_viewsets import BaseViewset
208
+ from fastapi_viewsets.db_conf import Base, get_session, engine
209
+ from starlette import status
210
+
211
+ app = FastAPI()
212
+
213
+ # ... define User model and schema ...
214
+
215
+ oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
216
+
217
+ # Create protected viewset
218
+ protected_viewset = BaseViewset(
219
+ endpoint='/user',
220
+ model=User,
221
+ response_model=UserSchema,
222
+ db_session=get_session,
223
+ tags=['Protected Users']
224
+ )
225
+
226
+ # Register methods with authentication
227
+ protected_viewset.register(
228
+ methods=['LIST', 'POST', 'GET', 'PUT'],
229
+ protected_methods=['LIST', 'POST', 'GET', 'PUT'],
230
+ oauth_protect=oauth2_scheme
231
+ )
232
+
233
+ app.include_router(protected_viewset)
234
+
235
+ # Token endpoint
236
+ @app.post('/token')
237
+ def generate_token(form_data: OAuth2PasswordRequestForm = Depends()):
238
+ # Your token generation logic here
239
+ pass
240
+ ```
241
+
242
+ ## Available HTTP Methods
243
+
244
+ The following HTTP methods are supported:
245
+
246
+ - `LIST` - GET request to list all items (with pagination)
247
+ - `GET` - GET request to retrieve a single item by ID
248
+ - `POST` - POST request to create a new item
249
+ - `PUT` - PUT request to replace an entire item
250
+ - `PATCH` - PATCH request to partially update an item
251
+ - `DELETE` - DELETE request to delete an item
252
+
253
+ ### Selecting Specific Methods
254
+
255
+ You can register only specific methods:
256
+
257
+ ```python
258
+ user_viewset.register(methods=['LIST', 'GET', 'POST'])
259
+ ```
260
+
261
+ ## Database Configuration
262
+
263
+ ### ORM Selection
264
+
265
+ `fastapi_viewsets` supports multiple ORM libraries. You can choose which ORM to use by setting the `ORM_TYPE` environment variable.
266
+
267
+ ### Environment Variables
268
+
269
+ Create a `.env` file in your project root:
270
+
271
+ #### SQLAlchemy (Default)
272
+
273
+ ```env
274
+ ORM_TYPE=sqlalchemy
275
+ SQLALCHEMY_DATABASE_URL=sqlite:///path/to/db/base.db
276
+ ```
277
+
278
+ Or for PostgreSQL:
279
+
280
+ ```env
281
+ ORM_TYPE=sqlalchemy
282
+ SQLALCHEMY_DATABASE_URL=postgresql://username:password@localhost:5432/mydatabase
283
+ ```
284
+
285
+ For async databases, you can also specify:
286
+
287
+ ```env
288
+ ORM_TYPE=sqlalchemy
289
+ SQLALCHEMY_DATABASE_URL=postgresql://username:password@localhost:5432/mydatabase
290
+ SQLALCHEMY_ASYNC_DATABASE_URL=postgresql+asyncpg://username:password@localhost:5432/mydatabase
291
+ ```
292
+
293
+ #### Tortoise ORM
294
+
295
+ ```env
296
+ ORM_TYPE=tortoise
297
+ TORTOISE_DATABASE_URL=postgresql://username:password@localhost:5432/mydatabase
298
+ TORTOISE_MODELS=["app.models"]
299
+ TORTOISE_APP_LABEL=models
300
+ ```
301
+
302
+ Or use JSON format for models:
303
+
304
+ ```env
305
+ ORM_TYPE=tortoise
306
+ TORTOISE_DATABASE_URL=postgresql://username:password@localhost:5432/mydatabase
307
+ TORTOISE_MODELS=["app.models", "app.other_models"]
308
+ ```
309
+
310
+ #### Peewee
311
+
312
+ ```env
313
+ ORM_TYPE=peewee
314
+ PEEWEE_DATABASE_URL=postgresql://username:password@localhost:5432/mydatabase
315
+ ```
316
+
317
+ Or for SQLite:
318
+
319
+ ```env
320
+ ORM_TYPE=peewee
321
+ PEEWEE_DATABASE_URL=sqlite:///path/to/db/base.db
322
+ ```
323
+
324
+ ### Supported ORMs and Databases
325
+
326
+ - **SQLAlchemy** (default)
327
+ - SQLite (synchronous and async with `aiosqlite`)
328
+ - PostgreSQL (synchronous and async with `asyncpg`)
329
+ - MySQL (synchronous and async with `aiomysql`)
330
+
331
+ - **Tortoise ORM** (async-only)
332
+ - PostgreSQL (with `asyncpg`)
333
+ - MySQL (with `aiomysql`)
334
+ - SQLite (with `aiosqlite`)
335
+
336
+ - **Peewee** (sync-only)
337
+ - SQLite
338
+ - PostgreSQL
339
+ - MySQL
340
+
341
+ ### Installation of ORM-specific Dependencies
342
+
343
+ Install the ORM you want to use:
344
+
345
+ ```bash
346
+ # For SQLAlchemy (default, already included)
347
+ pip install SQLAlchemy
348
+
349
+ # For Tortoise ORM
350
+ pip install tortoise-orm asyncpg # or aiomysql for MySQL
351
+
352
+ # For Peewee
353
+ pip install peewee
354
+ ```
355
+
356
+ For async support with SQLAlchemy, install the appropriate driver:
357
+
358
+ ```bash
359
+ # For SQLite
360
+ pip install aiosqlite
361
+
362
+ # For PostgreSQL
363
+ pip install asyncpg
364
+
365
+ # For MySQL
366
+ pip install aiomysql
367
+ ```
368
+
369
+ ## API Reference
370
+
371
+ ### BaseViewset
372
+
373
+ Synchronous viewset class for CRUD operations.
374
+
375
+ **Parameters:**
376
+ - `endpoint` (str): Base endpoint path (e.g., '/user')
377
+ - `model`: ORM model class (SQLAlchemy, Tortoise, Peewee, etc.)
378
+ - `response_model`: Pydantic model for response serialization
379
+ - `db_session` (Callable): Database session factory function
380
+ - `orm_adapter` (BaseORMAdapter, optional): ORM adapter instance. If not provided, uses default from configuration.
381
+ - `tags` (List[str]): Tags for OpenAPI documentation
382
+ - `allowed_methods` (List[str], optional): List of allowed methods
383
+
384
+ **Methods:**
385
+ - `register(methods=None, oauth_protect=None, protected_methods=None)`: Register CRUD endpoints
386
+
387
+ ### AsyncBaseViewset
388
+
389
+ Asynchronous viewset class for CRUD operations.
390
+
391
+ Same parameters and methods as `BaseViewset`, but all operations are async.
392
+
393
+ ### ORM Adapters
394
+
395
+ The library supports multiple ORM adapters through the `BaseORMAdapter` interface:
396
+
397
+ - **SQLAlchemyAdapter**: For SQLAlchemy ORM (default)
398
+ - **TortoiseAdapter**: For Tortoise ORM (async-only)
399
+ - **PeeweeAdapter**: For Peewee ORM (sync-only)
400
+
401
+ You can get the default adapter from configuration:
402
+
403
+ ```python
404
+ from fastapi_viewsets.db_conf import get_orm_adapter
405
+
406
+ adapter = get_orm_adapter() # Reads ORM_TYPE from environment
407
+ ```
408
+
409
+ Or create a specific adapter:
410
+
411
+ ```python
412
+ from fastapi_viewsets.orm.factory import ORMFactory
413
+
414
+ # Create SQLAlchemy adapter
415
+ adapter = ORMFactory.create_adapter('sqlalchemy', {
416
+ 'database_url': 'postgresql://user:pass@localhost/db'
417
+ })
418
+
419
+ # Create Tortoise adapter
420
+ adapter = ORMFactory.create_adapter('tortoise', {
421
+ 'database_url': 'postgresql://user:pass@localhost/db',
422
+ 'models': ['app.models']
423
+ })
424
+ ```
425
+
426
+ ## Differences Between PUT and PATCH
427
+
428
+ - **PUT**: Replaces the entire object. All fields must be provided (missing fields will be set to None).
429
+ - **PATCH**: Partially updates the object. Only provided fields will be updated.
430
+
431
+ ## Error Handling
432
+
433
+ The library provides comprehensive error handling:
434
+
435
+ - `404 Not Found`: When an element is not found
436
+ - `400 Bad Request`: For validation errors and database integrity errors
437
+ - Detailed error messages for debugging
438
+
439
+ ## Contributing
440
+
441
+ Contributions are welcome! Please feel free to submit a Pull Request.
442
+
443
+ ## License
444
+
445
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
446
+
447
+ ## Author
448
+
449
+ Alexander Valenchits
450
+
451
+ ## Links
452
+
453
+ - [GitHub Repository](https://github.com/svalench/fastapi_viewsets)
454
+ - [PyPI Package](https://pypi.org/project/fastapi-viewsets/)