fastapi-viewsets 1.2.0__tar.gz → 1.2.1__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 (43) hide show
  1. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/PKG-INFO +1 -1
  2. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/fastapi_viewsets/orm/sqlalchemy_adapter.py +12 -6
  3. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/fastapi_viewsets.egg-info/PKG-INFO +1 -1
  4. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/fastapi_viewsets.egg-info/SOURCES.txt +1 -0
  5. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/pyproject.toml +5 -3
  6. fastapi_viewsets-1.2.1/tests/test_async_driver_missing.py +57 -0
  7. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/LICENSE +0 -0
  8. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/README.md +0 -0
  9. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/fastapi_viewsets/__init__.py +0 -0
  10. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/fastapi_viewsets/_compat.py +0 -0
  11. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/fastapi_viewsets/_register.py +0 -0
  12. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/fastapi_viewsets/async_base.py +0 -0
  13. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/fastapi_viewsets/async_utils.py +0 -0
  14. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/fastapi_viewsets/constants.py +0 -0
  15. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/fastapi_viewsets/db_conf.py +0 -0
  16. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/fastapi_viewsets/orm/__init__.py +0 -0
  17. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/fastapi_viewsets/orm/base.py +0 -0
  18. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/fastapi_viewsets/orm/factory.py +0 -0
  19. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/fastapi_viewsets/orm/peewee_adapter.py +0 -0
  20. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/fastapi_viewsets/orm/tortoise_adapter.py +0 -0
  21. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/fastapi_viewsets/utils.py +0 -0
  22. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/fastapi_viewsets.egg-info/dependency_links.txt +0 -0
  23. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/fastapi_viewsets.egg-info/requires.txt +0 -0
  24. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/fastapi_viewsets.egg-info/top_level.txt +0 -0
  25. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/setup.cfg +0 -0
  26. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/setup.py +0 -0
  27. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/tests/test_adapter_methods_coverage.py +0 -0
  28. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/tests/test_async_base_viewset.py +0 -0
  29. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/tests/test_async_utils.py +0 -0
  30. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/tests/test_backward_compatibility.py +0 -0
  31. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/tests/test_base_viewset.py +0 -0
  32. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/tests/test_coverage_gaps.py +0 -0
  33. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/tests/test_db_conf.py +0 -0
  34. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/tests/test_db_conf_extended.py +0 -0
  35. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/tests/test_edge_cases.py +0 -0
  36. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/tests/test_error_handling.py +0 -0
  37. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/tests/test_exception_handling.py +0 -0
  38. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/tests/test_integration.py +0 -0
  39. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/tests/test_missing_coverage.py +0 -0
  40. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/tests/test_orm_adapters.py +0 -0
  41. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/tests/test_orm_adapters_extended.py +0 -0
  42. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/tests/test_utils.py +0 -0
  43. {fastapi_viewsets-1.2.0 → fastapi_viewsets-1.2.1}/tests/test_viewsets_with_adapters.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi_viewsets
3
- Version: 1.2.0
3
+ Version: 1.2.1
4
4
  Summary: DRF-style viewsets for FastAPI with SQLAlchemy/Tortoise/Peewee adapters and Pydantic v2 support.
5
5
  Author: Alexander Valenchits
6
6
  License: MIT
@@ -67,19 +67,25 @@ class SQLAlchemyAdapter(BaseORMAdapter):
67
67
 
68
68
  self.Base.query = self.db_session.query_property()
69
69
 
70
- # Setup async engine and session
70
+ # Setup async engine and session.
71
+ #
72
+ # The async engine is best-effort: if the matching async DB-API
73
+ # driver (aiosqlite, asyncpg, aiomysql, ...) is not installed we
74
+ # fall back to ``async_engine = None`` so that purely synchronous
75
+ # usage still works. The error is re-raised lazily from
76
+ # :meth:`get_async_session` with installation hints.
71
77
  if async_engine:
72
78
  self.async_engine = async_engine
73
- elif async_database_url:
74
- self.async_engine = create_async_engine(async_database_url, echo=False)
75
79
  else:
76
- # Auto-convert sync URL to async
77
- async_url = self._get_async_database_url()
80
+ async_url = async_database_url or self._get_async_database_url()
78
81
  try:
79
82
  self.async_engine = create_async_engine(async_url, echo=False)
80
83
  except Exception:
84
+ # Missing async DB-API driver (aiosqlite/asyncpg/aiomysql),
85
+ # or no async dialect for this URL — degrade to sync-only mode.
86
+ # The error is re-raised lazily from ``get_async_session``.
81
87
  self.async_engine = None
82
-
88
+
83
89
  if self.async_engine:
84
90
  self.AsyncSessionLocal = async_sessionmaker(
85
91
  self.async_engine,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi_viewsets
3
- Version: 1.2.0
3
+ Version: 1.2.1
4
4
  Summary: DRF-style viewsets for FastAPI with SQLAlchemy/Tortoise/Peewee adapters and Pydantic v2 support.
5
5
  Author: Alexander Valenchits
6
6
  License: MIT
@@ -24,6 +24,7 @@ fastapi_viewsets/orm/sqlalchemy_adapter.py
24
24
  fastapi_viewsets/orm/tortoise_adapter.py
25
25
  tests/test_adapter_methods_coverage.py
26
26
  tests/test_async_base_viewset.py
27
+ tests/test_async_driver_missing.py
27
28
  tests/test_async_utils.py
28
29
  tests/test_backward_compatibility.py
29
30
  tests/test_base_viewset.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "fastapi_viewsets"
7
- version = "1.2.0"
7
+ version = "1.2.1"
8
8
  description = "DRF-style viewsets for FastAPI with SQLAlchemy/Tortoise/Peewee adapters and Pydantic v2 support."
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -51,8 +51,10 @@ Homepage = "https://github.com/svalench/fastapi_viewsets"
51
51
  Issues = "https://github.com/svalench/fastapi_viewsets/issues"
52
52
  Changelog = "https://github.com/svalench/fastapi_viewsets/blob/main/RELEASE_NOTES.md"
53
53
 
54
- [tool.setuptools]
55
- packages = ["fastapi_viewsets", "fastapi_viewsets.orm"]
54
+ [tool.setuptools.packages.find]
55
+ where = ["."]
56
+ include = ["fastapi_viewsets*"]
57
+ exclude = ["tests*"]
56
58
 
57
59
  [tool.black]
58
60
  line-length = 100
@@ -0,0 +1,57 @@
1
+ """Regression test for v1.2.1.
2
+
3
+ When ``async_database_url`` is provided but the corresponding async DB-API
4
+ driver (e.g. ``aiosqlite``) is not installed, ``SQLAlchemyAdapter.__init__``
5
+ must degrade gracefully to sync-only mode instead of raising
6
+ ``ModuleNotFoundError`` at construction time.
7
+
8
+ Regression introduced in v1.2.0 where ``ORMFactory.get_adapter_from_env``
9
+ started always passing an explicit ``async_database_url`` to the adapter,
10
+ bypassing the existing best-effort ``try/except`` on the URL-conversion path.
11
+ """
12
+
13
+ from unittest.mock import patch
14
+
15
+ import pytest
16
+
17
+ from fastapi_viewsets.orm.sqlalchemy_adapter import SQLAlchemyAdapter
18
+
19
+
20
+ def _import_error(*_args, **_kwargs):
21
+ raise ModuleNotFoundError("No module named 'aiosqlite'")
22
+
23
+
24
+ def test_explicit_async_url_without_driver_falls_back_to_sync():
25
+ """Adapter must not raise when async driver is missing."""
26
+ with patch(
27
+ "fastapi_viewsets.orm.sqlalchemy_adapter.create_async_engine",
28
+ side_effect=_import_error,
29
+ ):
30
+ adapter = SQLAlchemyAdapter(
31
+ database_url="sqlite:///:memory:",
32
+ async_database_url="sqlite+aiosqlite:///:memory:",
33
+ )
34
+
35
+ assert adapter.async_engine is None
36
+ assert adapter.AsyncSessionLocal is None
37
+
38
+ # Sync session must keep working.
39
+ session = adapter.get_session()
40
+ assert session is not None
41
+ session.close()
42
+
43
+ # Async session must raise a helpful runtime error (not at __init__).
44
+ with pytest.raises(RuntimeError, match="async database driver"):
45
+ adapter.get_async_session()
46
+
47
+
48
+ def test_auto_converted_async_url_without_driver_falls_back_to_sync():
49
+ """Same fallback when ``async_database_url`` is auto-derived."""
50
+ with patch(
51
+ "fastapi_viewsets.orm.sqlalchemy_adapter.create_async_engine",
52
+ side_effect=_import_error,
53
+ ):
54
+ adapter = SQLAlchemyAdapter(database_url="sqlite:///:memory:")
55
+
56
+ assert adapter.async_engine is None
57
+ assert adapter.AsyncSessionLocal is None