0.7.6 fix @glue() stray usage

This commit is contained in:
Yusur 2025-11-01 10:05:22 +01:00
parent 556019e0bd
commit 96a65c38e3
3 changed files with 62 additions and 65 deletions

View file

@ -10,7 +10,7 @@ license = "Apache-2.0"
readme = "README.md" readme = "README.md"
dependencies = [ dependencies = [
"suou==0.7.4", "suou==0.7.5",
"itsdangerous", "itsdangerous",
"toml", "toml",
"pydantic", "pydantic",
@ -39,14 +39,16 @@ Documentation = "https://suou.readthedocs.io"
[project.optional-dependencies] [project.optional-dependencies]
# the below are all dev dependencies (and probably already installed) # the below are all dev dependencies (and probably already installed)
sqlalchemy = [ sqlalchemy = [
"SQLAlchemy[asyncio]>=2.0.0" "SQLAlchemy[asyncio]>=2.0.0",
"flask-sqlalchemy"
] ]
flask = [ flask = [
"Flask>=2.0.0", "Flask>=2.0.0",
"Flask-RestX" "Flask-RestX"
] ]
flask_sqlalchemy = [ flask_sqlalchemy = [
"Flask-SqlAlchemy", "sakuragasaki46_suou[sqlalchemy]",
"sakuragasaki46_suou[flask]"
] ]
peewee = [ peewee = [
## HEADS UP! peewee has setup.py, may slow down installation ## HEADS UP! peewee has setup.py, may slow down installation
@ -71,7 +73,6 @@ full = [
"sakuragasaki46_suou[quart]", "sakuragasaki46_suou[quart]",
"sakuragasaki46_suou[peewee]", "sakuragasaki46_suou[peewee]",
"sakuragasaki46_suou[markdown]", "sakuragasaki46_suou[markdown]",
"sakuragasaki46_suou[flask-sqlalchemy]",
"sakuragasaki46_suou[sass]" "sakuragasaki46_suou[sass]"
] ]

View file

@ -37,7 +37,7 @@ from .redact import redact_url_password
from .http import WantsContentType from .http import WantsContentType
from .color import chalk from .color import chalk
__version__ = "0.7.5" __version__ = "0.7.6"
__all__ = ( __all__ = (
'ConfigOptions', 'ConfigParserConfigSource', 'ConfigSource', 'ConfigValue', 'ConfigOptions', 'ConfigParserConfigSource', 'ConfigSource', 'ConfigValue',

View file

@ -119,76 +119,72 @@ class SQLAlchemy:
# XXX NOT public API! DO NOT USE # XXX NOT public API! DO NOT USE
current_session: ContextVar[AsyncSession] = ContextVar('current_session') current_session: ContextVar[AsyncSession] = ContextVar('current_session')
## experimental
@glue('flask_sqlalchemy')
def _make_AsyncSelectPagination(flask_sqlalchemy):
class AsyncSelectPagination(flask_sqlalchemy.pagination.Pagination):
"""
flask_sqlalchemy.SelectPagination but asynchronous.
Pagination is not part of the public API, therefore expect that it may break
"""
async def _query_items(self) -> list:
select_q: Select = self._query_args["select"]
select = select_q.limit(self.per_page).offset(self._query_offset)
session: AsyncSession = self._query_args["session"]
out = (await session.execute(select)).scalars()
return out
async def _query_count(self) -> int: class AsyncSelectPagination(flask_sqlalchemy.pagination.Pagination):
select_q: Select = self._query_args["select"] """
sub = select_q.options(lazyload("*")).order_by(None).subquery() flask_sqlalchemy.SelectPagination but asynchronous.
session: AsyncSession = self._query_args["session"]
out = (await session.execute(select(func.count()).select_from(sub))).scalar()
return out
def __init__(self, Pagination is not part of the public API, therefore expect that it may break
page: int | None = None, """
per_page: int | None = None,
max_per_page: int | None = 100,
error_out: Exception | None = NotFoundError,
count: bool = True,
**kwargs):
## XXX flask-sqlalchemy says Pagination() is not public API.
## Things may break; beware.
self._query_args = kwargs
page, per_page = self._prepare_page_args(
page=page,
per_page=per_page,
max_per_page=max_per_page,
error_out=error_out,
)
self.page: int = page async def _query_items(self) -> list:
"""The current page.""" select_q: Select = self._query_args["select"]
select = select_q.limit(self.per_page).offset(self._query_offset)
session: AsyncSession = self._query_args["session"]
out = (await session.execute(select)).scalars()
return out
self.per_page: int = per_page async def _query_count(self) -> int:
"""The maximum number of items on a page.""" select_q: Select = self._query_args["select"]
sub = select_q.options(lazyload("*")).order_by(None).subquery()
session: AsyncSession = self._query_args["session"]
out = (await session.execute(select(func.count()).select_from(sub))).scalar()
return out
self.max_per_page: int | None = max_per_page def __init__(self,
"""The maximum allowed value for ``per_page``.""" page: int | None = None,
per_page: int | None = None,
max_per_page: int | None = 100,
error_out: Exception | None = NotFoundError,
count: bool = True,
**kwargs):
## XXX flask-sqlalchemy says Pagination() is not public API.
## Things may break; beware.
self._query_args = kwargs
page, per_page = self._prepare_page_args(
page=page,
per_page=per_page,
max_per_page=max_per_page,
error_out=error_out,
)
self.items = None self.page: int = page
self.total = None """The current page."""
self.error_out = error_out
self.has_count = count
async def __aiter__(self): self.per_page: int = per_page
self.items = await self._query_items() """The maximum number of items on a page."""
if self.items is None:
raise RuntimeError('query returned None')
if not self.items and self.page != 1 and self.error_out:
raise self.error_out
if self.has_count:
self.total = await self._query_count()
for i in self.items:
yield i
return AsyncSelectPagination self.max_per_page: int | None = max_per_page
"""The maximum allowed value for ``per_page``."""
self.items = None
self.total = None
self.error_out = error_out
self.has_count = count
async def __aiter__(self):
self.items = await self._query_items()
if self.items is None:
raise RuntimeError('query returned None')
if not self.items and self.page != 1 and self.error_out:
raise self.error_out
if self.has_count:
self.total = await self._query_count()
for i in self.items:
yield i
AsyncSelectPagination = _make_AsyncSelectPagination()
del _make_AsyncSelectPagination
def async_query(db: SQLAlchemy, multi: False): def async_query(db: SQLAlchemy, multi: False):
@ -256,4 +252,4 @@ class SessionWrapper:
return getattr(self._session, key) return getattr(self._session, key)
# Optional dependency: do not import into __init__.py # Optional dependency: do not import into __init__.py
__all__ = ('SQLAlchemy', 'AsyncSelectPagination', 'async_query', 'SessionWrapper') __all__ = ('SQLAlchemy', 'AsyncSelectPagination', 'async_query', 'SessionWrapper')