From 4a31fbc14f7cbe89351c83d189032655421302dd Mon Sep 17 00:00:00 2001 From: Yusur Princeps Date: Wed, 5 Nov 2025 10:47:08 +0100 Subject: [PATCH] 0.8.0 improve (experimental) Waiter + add sqlalchemy.username_column() --- CHANGELOG.md | 9 +++++++++ aliases/sakuragasaki46_suou/pyproject.toml | 2 +- docs/sqlalchemy.rst | 2 ++ src/suou/__init__.py | 2 +- src/suou/sqlalchemy/__init__.py | 6 +++--- src/suou/sqlalchemy/orm.py | 1 - src/suou/waiter.py | 23 ++++++++++++++++++++++ 7 files changed, 39 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c3b718..16c47fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 0.8.0 + ++ Add `username_column()` to `.sqlalchemy` ++ Improve (experimental) `Waiter` + +## 0.7.7 + ++ Fix imports in `.sqlalchemy` + ## 0.7.5 + Delay release of `FakeModule` to 0.9.0 diff --git a/aliases/sakuragasaki46_suou/pyproject.toml b/aliases/sakuragasaki46_suou/pyproject.toml index 91b035a..6764e6f 100644 --- a/aliases/sakuragasaki46_suou/pyproject.toml +++ b/aliases/sakuragasaki46_suou/pyproject.toml @@ -10,7 +10,7 @@ license = "Apache-2.0" readme = "README.md" dependencies = [ - "suou==0.7.6", + "suou==0.7.7", "itsdangerous", "toml", "pydantic", diff --git a/docs/sqlalchemy.rst b/docs/sqlalchemy.rst index a1a78ac..197ebe1 100644 --- a/docs/sqlalchemy.rst +++ b/docs/sqlalchemy.rst @@ -25,6 +25,8 @@ Columns .. autofunction:: bool_column +.. autofunction:: username_column + .. autofunction:: unbound_fk .. autofunction:: bound_fk diff --git a/src/suou/__init__.py b/src/suou/__init__.py index 7411deb..a0f3a65 100644 --- a/src/suou/__init__.py +++ b/src/suou/__init__.py @@ -37,7 +37,7 @@ from .redact import redact_url_password from .http import WantsContentType from .color import chalk -__version__ = "0.7.7" +__version__ = "0.8.0" __all__ = ( 'ConfigOptions', 'ConfigParserConfigSource', 'ConfigSource', 'ConfigValue', diff --git a/src/suou/sqlalchemy/__init__.py b/src/suou/sqlalchemy/__init__.py index 7794f39..4b606fc 100644 --- a/src/suou/sqlalchemy/__init__.py +++ b/src/suou/sqlalchemy/__init__.py @@ -113,7 +113,7 @@ class AuthSrc(metaclass=ABCMeta): pass -@deprecated('not working and too complex to use') +@deprecated('not working and too complex to use. Will be removed in 0.9.0') def require_auth_base(cls: type[DeclarativeBase], *, src: AuthSrc, column: str | Column[_T] = 'id', dest: str = 'user', required: bool = False, signed: bool = False, sig_dest: str = 'signature', validators: Callable | Iterable[Callable] | None = None): ''' @@ -161,7 +161,7 @@ def require_auth_base(cls: type[DeclarativeBase], *, src: AuthSrc, column: str | from .asyncio import SQLAlchemy, AsyncSelectPagination, async_query from .orm import ( id_column, snowflake_column, match_column, match_constraint, bool_column, declarative_base, parent_children, - author_pair, age_pair, bound_fk, unbound_fk, want_column, a_relationship, BitSelector, secret_column + author_pair, age_pair, bound_fk, unbound_fk, want_column, a_relationship, BitSelector, secret_column, username_column ) # Optional dependency: do not import into __init__.py @@ -169,7 +169,7 @@ __all__ = ( 'IdType', 'id_column', 'snowflake_column', 'entity_base', 'declarative_base', 'token_signer', 'match_column', 'match_constraint', 'bool_column', 'parent_children', 'author_pair', 'age_pair', 'bound_fk', 'unbound_fk', 'want_column', - 'a_relationship', 'BitSelector', 'secret_column', + 'a_relationship', 'BitSelector', 'secret_column', 'username_column', # .asyncio 'SQLAlchemy', 'AsyncSelectPagination', 'async_query', 'SessionWrapper' ) \ No newline at end of file diff --git a/src/suou/sqlalchemy/orm.py b/src/suou/sqlalchemy/orm.py index 37b4def..9e0ee91 100644 --- a/src/suou/sqlalchemy/orm.py +++ b/src/suou/sqlalchemy/orm.py @@ -115,7 +115,6 @@ def match_column(length: int, regex: str | re.Pattern, /, case: StringCase = Str constraint_name=constraint_name or f'{x.__tablename__}_{n}_valid')), *args, **kwargs) -@future(version='0.8.0') def username_column( length: int = 32, regex: str | re.Pattern = '[a-z_][a-z0-9_-]+', *args, case: StringCase = StringCase.LOWER, nullable : bool = False, **kwargs) -> Incomplete[Column[str] | Column[str | None]]: diff --git a/src/suou/waiter.py b/src/suou/waiter.py index 897062f..51e4590 100644 --- a/src/suou/waiter.py +++ b/src/suou/waiter.py @@ -16,11 +16,13 @@ This software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. """ + import warnings from starlette.applications import Starlette from starlette.responses import JSONResponse, PlainTextResponse, Response from starlette.routing import Route +from suou.itertools import makelist from suou.functools import future @future() @@ -35,6 +37,27 @@ class Waiter(): routes= self.routes ) + def get(self, endpoint: str, *a, **k): + return self._route('GET', endpoint, *a, **k) + + def post(self, endpoint: str, *a, **k): + return self._route('POST', endpoint, *a, **k) + + def delete(self, endpoint: str, *a, **k): + return self._route('DELETE', endpoint, *a, **k) + + def put(self, endpoint: str, *a, **k): + return self._route('PUT', endpoint, *a, **k) + + def patch(self, endpoint: str, *a, **k): + return self._route('PATCH', endpoint, *a, **k) + + def _route(self, methods: list[str], endpoint: str, **kwargs): + def decorator(func): + self.routes.append(Route(endpoint, func, methods=makelist(methods, False), **kwargs)) + return func + return decorator + ## TODO get, post, etc. def ok(content = None, **ka):