From 22fdf81e40eccffe6b2300adf568f59f9edb802e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=A7=80=ED=98=B8?= Date: Sat, 24 Feb 2024 13:47:52 +0900 Subject: [PATCH 1/6] Binding DB sessions based on SQLAlchemy 1, changing how to declare Base Model classes, and other code modernization - DB session binding based on SQLAlchemy 2, Base Model class declaration method change - Reflected select, delete code based on SQLAlchemy 2 - Changed how to declare Model class based on SQLAlchemy 2 - Added pyproject.toml file after removing setup.py due to the introduction of PEP 517/518 - Fixed minimum installed version to Python 3.7 --- CHANGELOG.md | 5 ++ Makefile | 8 +-- pyproject.toml | 53 +++++++++++++++++ requirements.txt | 3 - setup.py | 36 ------------ social_sqlalchemy/storage.py | 111 ++++++++++++++++++++--------------- 6 files changed, 124 insertions(+), 92 deletions(-) create mode 100644 pyproject.toml delete mode 100644 requirements.txt delete mode 100644 setup.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ec591b..48c2c00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased](https://github.com/python-social-auth/social-storage-sqlalchemy/commits/master) +### Changed +- Modified model and access code to work with SQLAlchemy version 2 (Issue #9) +- Updated packaging information files per PEP 517, PEP 518 (Issue #10) +- Restricted Python minimum working version to 3.7 or higher to align with SQLAlchemy 2 (Issue #9) + ## [1.1.0](https://github.com/python-social-auth/social-storage-sqlalchemy/releases/tag/1.1.0) - 2017-05-06 ### Changed diff --git a/Makefile b/Makefile index 53cf9f8..8b9b717 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,8 @@ build: - @ python setup.py sdist - @ python setup.py bdist_wheel --python-tag py2 - @ BUILD_VERSION=3 python setup.py bdist_wheel --python-tag py3 + @ python -m build publish: - @ python setup.py sdist upload - @ python setup.py bdist_wheel --python-tag py2 upload - @ BUILD_VERSION=3 python setup.py bdist_wheel --python-tag py3 upload + @ twine upload dist/* clean: @ find . -name '*.py[co]' -delete diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..772de68 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,53 @@ +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[project] +name = 'social-auth-storage-sqlalchemy' +dynamic = ["version"] +dependencies = [ + "six", + "sqlalchemy", + "social-auth-core>=1.0.0", +] +authors = [ + {name = "Matias Aguirre", email = "matiasaguirre@gmail.com"}, + {name = "Lee Ji-ho", email = "search5@gmail.com"}, +] +description = 'Python Social Authentication, SQLAlchemy storage.' +license = {text = 'BSD'} +keywords = ["sqlalchemy", "social auth"] +readme = "README.md" +classifiers=[ + 'Development Status :: 4 - Beta', + 'Topic :: Internet', + 'License :: OSI Approved :: BSD License', + 'Intended Audience :: Developers', + 'Environment :: Web Environment', + 'Programming Language :: Python', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12' +] +requires-python = ">= 3.7" + +[project.urls] +Repository = 'https://github.com/python-social-auth/social-storage-sqlalchemy' +Documentation = 'http://python-social-auth.readthedocs.org' +Issues = 'https://github.com/python-social-auth/social-storage-sqlalchemy/issues' +Changelog = 'https://github.com/python-social-auth/social-storage-sqlalchemy/blob/master/CHANGELOG.md + +[options] +zip_safe = false + +[tool.setuptools] +include-package-data = true + +[tool.setuptools.packages] +find = {} + +[tool.setuptools.dynamic] +version = {attr = "social_sqlalchemy.__version__"} diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 08c3b2e..0000000 --- a/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -six -sqlalchemy -social-auth-core >= 1.0.0 diff --git a/setup.py b/setup.py deleted file mode 100644 index cd25caf..0000000 --- a/setup.py +++ /dev/null @@ -1,36 +0,0 @@ -# -*- coding: utf-8 -*- -"""Setup file for easy installation""" -from os.path import join, dirname -from setuptools import setup - - -def long_description(): - return open(join(dirname(__file__), 'README.md')).read() - -def load_requirements(): - return open(join(dirname(__file__), 'requirements.txt')).readlines() - -setup( - name='social-auth-storage-sqlalchemy', - version=__import__('social_sqlalchemy').__version__, - author='Matias Aguirre', - author_email='matiasaguirre@gmail.com', - description='Python Social Authentication, SQLAlchemy storage.', - license='BSD', - keywords='sqlalchemy, social auth', - url='https://github.com/python-social-auth/social-storage-sqlalchemy', - packages=['social_sqlalchemy'], - long_description=long_description(), - install_requires=load_requirements(), - classifiers=[ - 'Development Status :: 4 - Beta', - 'Topic :: Internet', - 'License :: OSI Approved :: BSD License', - 'Intended Audience :: Developers', - 'Environment :: Web Environment', - 'Programming Language :: Python', - 'Programming Language :: Python :: 3' - ], - python_requires='>=3.6', - zip_safe=False -) diff --git a/social_sqlalchemy/storage.py b/social_sqlalchemy/storage.py index c525d6c..85fd657 100644 --- a/social_sqlalchemy/storage.py +++ b/social_sqlalchemy/storage.py @@ -1,5 +1,7 @@ """SQLAlchemy models for Social Auth""" import base64 +from typing import Optional + import six import json @@ -8,11 +10,12 @@ except ImportError: transaction = None -from sqlalchemy import Column, Integer, String +from sqlalchemy import select, delete, String, func, Integer from sqlalchemy.exc import IntegrityError from sqlalchemy.types import PickleType, Text from sqlalchemy.schema import UniqueConstraint -from sqlalchemy.ext.declarative import declared_attr + +from sqlalchemy.orm import declared_attr, Mapped, mapped_column from sqlalchemy.ext.mutable import MutableDict from social_core.storage import UserMixin, AssociationMixin, NonceMixin, \ @@ -51,7 +54,7 @@ def _session(cls): @classmethod def _query(cls): - return cls._session().query(cls) + return select(cls) @classmethod def _new_instance(cls, model, *args, **kwargs): @@ -86,15 +89,15 @@ class SQLAlchemyUserMixin(SQLAlchemyMixin, UserMixin): """Social Auth association model""" __tablename__ = 'social_auth_usersocialauth' __table_args__ = (UniqueConstraint('provider', 'uid'),) - id = Column(Integer, primary_key=True) - provider = Column(String(32)) - uid = None + id: Mapped[int] = mapped_column(primary_key=True) + provider: Mapped[str] = mapped_column(String(32)) + uid: Mapped[str] = mapped_column(String(255)) user_id = None user = None @declared_attr - def extra_data(cls): - return Column(MutableDict.as_mutable(JSONType)) + def extra_data(cls) -> Mapped[Optional[dict[str, str]]]: + return mapped_column(MutableDict.as_mutable(JSONType)) @classmethod def changed(cls, user): @@ -107,16 +110,22 @@ def set_extra_data(self, extra_data=None): @classmethod def allowed_to_disconnect(cls, user, backend_name, association_id=None): if association_id is not None: - qs = cls._query().filter(cls.id != association_id) + qs = cls._query().where(cls.id != association_id) else: - qs = cls._query().filter(cls.provider != backend_name) - qs = qs.filter(cls.user == user) + qs = cls._query().where(cls.provider != backend_name) + qs = qs.where(cls.user == user) if hasattr(user, 'has_usable_password'): # TODO valid_password = user.has_usable_password() else: valid_password = True - return valid_password or qs.count() > 0 + + qs_count = cls._session().scalar( + select(func.count()). + select_from(qs.subquery()) + ) + + return valid_password or qs_count > 0 @classmethod def disconnect(cls, entry): @@ -125,7 +134,7 @@ def disconnect(cls, entry): @classmethod def user_query(cls): - return cls._session().query(cls.user_model()) + return select(cls.user_model()) @classmethod def user_exists(cls, *args, **kwargs): @@ -133,7 +142,14 @@ def user_exists(cls, *args, **kwargs): Return True/False if a User instance exists with the given arguments. Arguments are directly passed to filter() manager method. """ - return cls.user_query().filter_by(*args, **kwargs).count() > 0 + stmt = cls.user_query().filter_by(*args, **kwargs) + + user_count = cls._session().scalar( + select(func.count()). + select_from(stmt.subquery()) + ) + + return user_count > 0 @classmethod def get_username(cls, user): @@ -145,19 +161,19 @@ def create_user(cls, *args, **kwargs): @classmethod def get_user(cls, pk): - return cls.user_query().get(pk) + return cls._session().get(cls.user_model(), pk) @classmethod def get_users_by_email(cls, email): - return cls.user_query().filter_by(email=email) + return cls._session().scalar(cls.user_query().filter_by(email=email)) @classmethod def get_social_auth(cls, provider, uid): if not isinstance(uid, six.string_types): uid = str(uid) try: - return cls._query().filter_by(provider=provider, - uid=uid)[0] + return cls._session().scalar( + cls._query().filter_by(provider=provider, uid=uid)) except IndexError: return None @@ -168,7 +184,7 @@ def get_social_auth_for_user(cls, user, provider=None, id=None): qs = qs.filter_by(provider=provider) if id: qs = qs.filter_by(id=id) - return qs + return cls._session().scalars(qs) @classmethod def create_social_auth(cls, user, uid, provider): @@ -180,17 +196,18 @@ def create_social_auth(cls, user, uid, provider): class SQLAlchemyNonceMixin(SQLAlchemyMixin, NonceMixin): __tablename__ = 'social_auth_nonce' __table_args__ = (UniqueConstraint('server_url', 'timestamp', 'salt'),) - id = Column(Integer, primary_key=True) - server_url = Column(String(255)) - timestamp = Column(Integer) - salt = Column(String(40)) + + id: Mapped[int] = mapped_column(primary_key=True) + server_url: Mapped[str] = mapped_column(String(255)) + timestamp: Mapped[int] = mapped_column(Integer) + salt: Mapped[str] = mapped_column(String(40)) @classmethod def use(cls, server_url, timestamp, salt): kwargs = {'server_url': server_url, 'timestamp': timestamp, 'salt': salt} try: - return cls._query().filter_by(**kwargs)[0] + return cls._session().scalar(cls._query().filter_by(**kwargs)) except IndexError: return cls._new_instance(cls, **kwargs) @@ -198,20 +215,20 @@ def use(cls, server_url, timestamp, salt): class SQLAlchemyAssociationMixin(SQLAlchemyMixin, AssociationMixin): __tablename__ = 'social_auth_association' __table_args__ = (UniqueConstraint('server_url', 'handle'),) - id = Column(Integer, primary_key=True) - server_url = Column(String(255)) - handle = Column(String(255)) - secret = Column(String(255)) # base64 encoded - issued = Column(Integer) - lifetime = Column(Integer) - assoc_type = Column(String(64)) + id: Mapped[int] = mapped_column(primary_key=True) + server_url: Mapped[str] = mapped_column(String(255)) + handle: Mapped[str] = mapped_column(String(255)) + secret: Mapped[str] = mapped_column(String(255)) # base64 encoded + issued: Mapped[int] = mapped_column() + lifetime: Mapped[int] = mapped_column() + assoc_type: Mapped[str] = mapped_column(String(64)) @classmethod def store(cls, server_url, association): # Don't use get_or_create because issued cannot be null try: - assoc = cls._query().filter_by(server_url=server_url, - handle=association.handle)[0] + assoc = cls._session().scalar(cls._query().filter_by(server_url=server_url, + handle=association.handle)) except IndexError: assoc = cls(server_url=server_url, handle=association.handle) @@ -223,38 +240,38 @@ def store(cls, server_url, association): @classmethod def get(cls, *args, **kwargs): - return cls._query().filter_by(*args, **kwargs) + return cls._session().scalar(cls._query().filter_by(*args, **kwargs)) @classmethod def remove(cls, ids_to_delete): - cls._query().filter(cls.id.in_(ids_to_delete)).delete( - synchronize_session='fetch' - ) + cls._session().execute(delete( + cls._query().where(cls.id.in_(ids_to_delete)) + ).execution_options(synchronize_session="fetch")) class SQLAlchemyCodeMixin(SQLAlchemyMixin, CodeMixin): __tablename__ = 'social_auth_code' __table_args__ = (UniqueConstraint('code', 'email'),) - id = Column(Integer, primary_key=True) - email = Column(String(200)) - code = Column(String(32), index=True) + id: Mapped[int] = mapped_column(primary_key=True) + email: Mapped[str] = mapped_column(String(200)) + code: Mapped[str] = mapped_column(String(32), index=True) @classmethod def get_code(cls, code): - return cls._query().filter(cls.code == code).first() + return cls._session().scalar(cls._query().where(cls.code == code)) class SQLAlchemyPartialMixin(SQLAlchemyMixin, PartialMixin): __tablename__ = 'social_auth_partial' - id = Column(Integer, primary_key=True) - token = Column(String(32), index=True) - data = Column(MutableDict.as_mutable(JSONType)) - next_step = Column(Integer) - backend = Column(String(32)) + id: Mapped[int] = mapped_column(primary_key=True) + token: Mapped[str] = mapped_column(String(32), index=True) + data: Mapped[dict[str, str]] = mapped_column(MutableDict.as_mutable(JSONType)) + next_step: Mapped[int] = mapped_column() + backend: Mapped[str] = mapped_column(String(32)) @classmethod def load(cls, token): - return cls._query().filter(cls.token == token).first() + return cls._session().scalar(cls._query().where(cls.token == token)) @classmethod def destroy(cls, token): From 432487b26364a97e543ca304d7dabfcc38339e78 Mon Sep 17 00:00:00 2001 From: ji-ho lee Date: Sun, 10 Mar 2024 18:07:06 +0900 Subject: [PATCH 2/6] PEP8 working --- .pre-commit-config.yaml | 38 ++++++++++++++++++++++++++++++++++++ pyproject.toml | 7 ++++++- social_sqlalchemy/storage.py | 11 +++++++---- 3 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..23019de --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,38 @@ +# See https://pre-commit.com for more information +# See https://pre-commit.com/hooks.html for more hooks +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: check-merge-conflict + - id: check-json + - id: debug-statements + - id: mixed-line-ending + args: [--fix=lf] +- repo: https://github.com/pycqa/isort + rev: 5.13.2 + hooks: + - id: isort + args: [--profile=black] +- repo: https://github.com/asottile/pyupgrade + rev: v3.15.1 + hooks: + - id: pyupgrade + args: [--py36-plus] +- repo: https://github.com/psf/black + rev: 24.2.0 + hooks: + - id: black +- repo: https://github.com/PyCQA/flake8 + rev: 7.0.0 + hooks: + - id: flake8 +- repo: meta + hooks: + - id: check-hooks-apply + - id: check-useless-excludes +- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks + rev: v2.12.0 + hooks: + - id: pretty-format-yaml + args: [--autofix, --indent, '2'] diff --git a/pyproject.toml b/pyproject.toml index 772de68..3a1e576 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,7 +38,7 @@ requires-python = ">= 3.7" Repository = 'https://github.com/python-social-auth/social-storage-sqlalchemy' Documentation = 'http://python-social-auth.readthedocs.org' Issues = 'https://github.com/python-social-auth/social-storage-sqlalchemy/issues' -Changelog = 'https://github.com/python-social-auth/social-storage-sqlalchemy/blob/master/CHANGELOG.md +Changelog = 'https://github.com/python-social-auth/social-storage-sqlalchemy/blob/master/CHANGELOG.md' [options] zip_safe = false @@ -51,3 +51,8 @@ find = {} [tool.setuptools.dynamic] version = {attr = "social_sqlalchemy.__version__"} + +[tool.flake8] +max-line-length = 80 +# Ignore some well known paths +exclude = ['.venv','.tox','dist','doc','build','*.egg','db/env.py','db/versions/*.py','site','Pipfile','Pipfile.lock'] diff --git a/social_sqlalchemy/storage.py b/social_sqlalchemy/storage.py index 85fd657..67f3d12 100644 --- a/social_sqlalchemy/storage.py +++ b/social_sqlalchemy/storage.py @@ -21,6 +21,7 @@ from social_core.storage import UserMixin, AssociationMixin, NonceMixin, \ CodeMixin, PartialMixin, BaseStorage + class JSONPickler(object): """JSON pickler wrapper around json lib since SQLAlchemy invokes dumps with extra positional parameters""" @@ -119,7 +120,7 @@ def allowed_to_disconnect(cls, user, backend_name, association_id=None): valid_password = user.has_usable_password() else: valid_password = True - + qs_count = cls._session().scalar( select(func.count()). select_from(qs.subquery()) @@ -227,8 +228,9 @@ class SQLAlchemyAssociationMixin(SQLAlchemyMixin, AssociationMixin): def store(cls, server_url, association): # Don't use get_or_create because issued cannot be null try: - assoc = cls._session().scalar(cls._query().filter_by(server_url=server_url, - handle=association.handle)) + assoc = cls._session().scalar( # fix: skip + cls._query().filter_by(server_url=server_url, # fix: skip + handle=association.handle)) except IndexError: assoc = cls(server_url=server_url, handle=association.handle) @@ -265,7 +267,8 @@ class SQLAlchemyPartialMixin(SQLAlchemyMixin, PartialMixin): __tablename__ = 'social_auth_partial' id: Mapped[int] = mapped_column(primary_key=True) token: Mapped[str] = mapped_column(String(32), index=True) - data: Mapped[dict[str, str]] = mapped_column(MutableDict.as_mutable(JSONType)) + data: Mapped[dict[str, str]] = mapped_column( # fix: skip + MutableDict.as_mutable(JSONType)) next_step: Mapped[int] = mapped_column() backend: Mapped[str] = mapped_column(String(32)) From 4b513d14ee6ff15964ac0d8bc55229bd5734cc74 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 10 Mar 2024 09:07:17 +0000 Subject: [PATCH 3/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- social_sqlalchemy/__init__.py | 2 +- social_sqlalchemy/storage.py | 94 +++++++++++++++++++---------------- 2 files changed, 52 insertions(+), 44 deletions(-) diff --git a/social_sqlalchemy/__init__.py b/social_sqlalchemy/__init__.py index 1a72d32..6849410 100644 --- a/social_sqlalchemy/__init__.py +++ b/social_sqlalchemy/__init__.py @@ -1 +1 @@ -__version__ = '1.1.0' +__version__ = "1.1.0" diff --git a/social_sqlalchemy/storage.py b/social_sqlalchemy/storage.py index 67f3d12..dd93ab9 100644 --- a/social_sqlalchemy/storage.py +++ b/social_sqlalchemy/storage.py @@ -1,28 +1,33 @@ """SQLAlchemy models for Social Auth""" + import base64 +import json from typing import Optional import six -import json try: import transaction except ImportError: transaction = None -from sqlalchemy import select, delete, String, func, Integer +from social_core.storage import ( + AssociationMixin, + BaseStorage, + CodeMixin, + NonceMixin, + PartialMixin, + UserMixin, +) +from sqlalchemy import Integer, String, delete, func, select from sqlalchemy.exc import IntegrityError -from sqlalchemy.types import PickleType, Text -from sqlalchemy.schema import UniqueConstraint - -from sqlalchemy.orm import declared_attr, Mapped, mapped_column from sqlalchemy.ext.mutable import MutableDict - -from social_core.storage import UserMixin, AssociationMixin, NonceMixin, \ - CodeMixin, PartialMixin, BaseStorage +from sqlalchemy.orm import Mapped, declared_attr, mapped_column +from sqlalchemy.schema import UniqueConstraint +from sqlalchemy.types import PickleType, Text -class JSONPickler(object): +class JSONPickler: """JSON pickler wrapper around json lib since SQLAlchemy invokes dumps with extra positional parameters""" @@ -42,16 +47,16 @@ class JSONType(PickleType): impl = Text def __init__(self, *args, **kwargs): - kwargs['pickler'] = JSONPickler - super(JSONType, self).__init__(*args, **kwargs) + kwargs["pickler"] = JSONPickler + super().__init__(*args, **kwargs) -class SQLAlchemyMixin(object): +class SQLAlchemyMixin: COMMIT_SESSION = True @classmethod def _session(cls): - raise NotImplementedError('Implement in subclass') + raise NotImplementedError("Implement in subclass") @classmethod def _query(cls): @@ -88,8 +93,9 @@ def save(self): class SQLAlchemyUserMixin(SQLAlchemyMixin, UserMixin): """Social Auth association model""" - __tablename__ = 'social_auth_usersocialauth' - __table_args__ = (UniqueConstraint('provider', 'uid'),) + + __tablename__ = "social_auth_usersocialauth" + __table_args__ = (UniqueConstraint("provider", "uid"),) id: Mapped[int] = mapped_column(primary_key=True) provider: Mapped[str] = mapped_column(String(32)) uid: Mapped[str] = mapped_column(String(255)) @@ -105,7 +111,7 @@ def changed(cls, user): cls._save_instance(user) def set_extra_data(self, extra_data=None): - if super(SQLAlchemyUserMixin, self).set_extra_data(extra_data): + if super().set_extra_data(extra_data): self._save_instance(self) @classmethod @@ -116,14 +122,13 @@ def allowed_to_disconnect(cls, user, backend_name, association_id=None): qs = cls._query().where(cls.provider != backend_name) qs = qs.where(cls.user == user) - if hasattr(user, 'has_usable_password'): # TODO + if hasattr(user, "has_usable_password"): # TODO valid_password = user.has_usable_password() else: valid_password = True qs_count = cls._session().scalar( - select(func.count()). - select_from(qs.subquery()) + select(func.count()).select_from(qs.subquery()) ) return valid_password or qs_count > 0 @@ -146,15 +151,14 @@ def user_exists(cls, *args, **kwargs): stmt = cls.user_query().filter_by(*args, **kwargs) user_count = cls._session().scalar( - select(func.count()). - select_from(stmt.subquery()) + select(func.count()).select_from(stmt.subquery()) ) return user_count > 0 @classmethod def get_username(cls, user): - return getattr(user, 'username', None) + return getattr(user, "username", None) @classmethod def create_user(cls, *args, **kwargs): @@ -170,11 +174,12 @@ def get_users_by_email(cls, email): @classmethod def get_social_auth(cls, provider, uid): - if not isinstance(uid, six.string_types): + if not isinstance(uid, str): uid = str(uid) try: return cls._session().scalar( - cls._query().filter_by(provider=provider, uid=uid)) + cls._query().filter_by(provider=provider, uid=uid) + ) except IndexError: return None @@ -189,14 +194,14 @@ def get_social_auth_for_user(cls, user, provider=None, id=None): @classmethod def create_social_auth(cls, user, uid, provider): - if not isinstance(uid, six.string_types): + if not isinstance(uid, str): uid = str(uid) return cls._new_instance(cls, user=user, uid=uid, provider=provider) class SQLAlchemyNonceMixin(SQLAlchemyMixin, NonceMixin): - __tablename__ = 'social_auth_nonce' - __table_args__ = (UniqueConstraint('server_url', 'timestamp', 'salt'),) + __tablename__ = "social_auth_nonce" + __table_args__ = (UniqueConstraint("server_url", "timestamp", "salt"),) id: Mapped[int] = mapped_column(primary_key=True) server_url: Mapped[str] = mapped_column(String(255)) @@ -205,8 +210,7 @@ class SQLAlchemyNonceMixin(SQLAlchemyMixin, NonceMixin): @classmethod def use(cls, server_url, timestamp, salt): - kwargs = {'server_url': server_url, 'timestamp': timestamp, - 'salt': salt} + kwargs = {"server_url": server_url, "timestamp": timestamp, "salt": salt} try: return cls._session().scalar(cls._query().filter_by(**kwargs)) except IndexError: @@ -214,8 +218,8 @@ def use(cls, server_url, timestamp, salt): class SQLAlchemyAssociationMixin(SQLAlchemyMixin, AssociationMixin): - __tablename__ = 'social_auth_association' - __table_args__ = (UniqueConstraint('server_url', 'handle'),) + __tablename__ = "social_auth_association" + __table_args__ = (UniqueConstraint("server_url", "handle"),) id: Mapped[int] = mapped_column(primary_key=True) server_url: Mapped[str] = mapped_column(String(255)) handle: Mapped[str] = mapped_column(String(255)) @@ -229,11 +233,12 @@ def store(cls, server_url, association): # Don't use get_or_create because issued cannot be null try: assoc = cls._session().scalar( # fix: skip - cls._query().filter_by(server_url=server_url, # fix: skip - handle=association.handle)) + cls._query().filter_by( + server_url=server_url, handle=association.handle # fix: skip + ) + ) except IndexError: - assoc = cls(server_url=server_url, - handle=association.handle) + assoc = cls(server_url=server_url, handle=association.handle) assoc.secret = base64.encodebytes(association.secret).decode() assoc.issued = association.issued assoc.lifetime = association.lifetime @@ -246,14 +251,16 @@ def get(cls, *args, **kwargs): @classmethod def remove(cls, ids_to_delete): - cls._session().execute(delete( - cls._query().where(cls.id.in_(ids_to_delete)) - ).execution_options(synchronize_session="fetch")) + cls._session().execute( + delete(cls._query().where(cls.id.in_(ids_to_delete))).execution_options( + synchronize_session="fetch" + ) + ) class SQLAlchemyCodeMixin(SQLAlchemyMixin, CodeMixin): - __tablename__ = 'social_auth_code' - __table_args__ = (UniqueConstraint('code', 'email'),) + __tablename__ = "social_auth_code" + __table_args__ = (UniqueConstraint("code", "email"),) id: Mapped[int] = mapped_column(primary_key=True) email: Mapped[str] = mapped_column(String(200)) code: Mapped[str] = mapped_column(String(32), index=True) @@ -264,11 +271,12 @@ def get_code(cls, code): class SQLAlchemyPartialMixin(SQLAlchemyMixin, PartialMixin): - __tablename__ = 'social_auth_partial' + __tablename__ = "social_auth_partial" id: Mapped[int] = mapped_column(primary_key=True) token: Mapped[str] = mapped_column(String(32), index=True) data: Mapped[dict[str, str]] = mapped_column( # fix: skip - MutableDict.as_mutable(JSONType)) + MutableDict.as_mutable(JSONType) + ) next_step: Mapped[int] = mapped_column() backend: Mapped[str] = mapped_column(String(32)) From 4f2ce5c9cef8369e4f9d2fa2ce617114769cb0c9 Mon Sep 17 00:00:00 2001 From: ji-ho lee Date: Sun, 10 Mar 2024 18:09:38 +0900 Subject: [PATCH 4/6] PEP8 Working --- social_sqlalchemy/storage.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/social_sqlalchemy/storage.py b/social_sqlalchemy/storage.py index dd93ab9..e50240e 100644 --- a/social_sqlalchemy/storage.py +++ b/social_sqlalchemy/storage.py @@ -4,8 +4,6 @@ import json from typing import Optional -import six - try: import transaction except ImportError: @@ -210,7 +208,8 @@ class SQLAlchemyNonceMixin(SQLAlchemyMixin, NonceMixin): @classmethod def use(cls, server_url, timestamp, salt): - kwargs = {"server_url": server_url, "timestamp": timestamp, "salt": salt} + kwargs = { # fix: skip + "server_url": server_url, "timestamp": timestamp, "salt": salt} try: return cls._session().scalar(cls._query().filter_by(**kwargs)) except IndexError: @@ -234,7 +233,8 @@ def store(cls, server_url, association): try: assoc = cls._session().scalar( # fix: skip cls._query().filter_by( - server_url=server_url, handle=association.handle # fix: skip + server_url=server_url, # fix: skip + handle=association.handle # fix: skip ) ) except IndexError: @@ -252,7 +252,8 @@ def get(cls, *args, **kwargs): @classmethod def remove(cls, ids_to_delete): cls._session().execute( - delete(cls._query().where(cls.id.in_(ids_to_delete))).execution_options( + delete(cls._query().where( # fix: skip + cls.id.in_(ids_to_delete))).execution_options( synchronize_session="fetch" ) ) From 7251ad3ac4d5530756745f1e5ad37e26e74e2233 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 10 Mar 2024 09:09:49 +0000 Subject: [PATCH 5/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- social_sqlalchemy/storage.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/social_sqlalchemy/storage.py b/social_sqlalchemy/storage.py index e50240e..6cda73a 100644 --- a/social_sqlalchemy/storage.py +++ b/social_sqlalchemy/storage.py @@ -209,7 +209,10 @@ class SQLAlchemyNonceMixin(SQLAlchemyMixin, NonceMixin): @classmethod def use(cls, server_url, timestamp, salt): kwargs = { # fix: skip - "server_url": server_url, "timestamp": timestamp, "salt": salt} + "server_url": server_url, + "timestamp": timestamp, + "salt": salt, + } try: return cls._session().scalar(cls._query().filter_by(**kwargs)) except IndexError: @@ -234,7 +237,7 @@ def store(cls, server_url, association): assoc = cls._session().scalar( # fix: skip cls._query().filter_by( server_url=server_url, # fix: skip - handle=association.handle # fix: skip + handle=association.handle, # fix: skip ) ) except IndexError: @@ -252,10 +255,9 @@ def get(cls, *args, **kwargs): @classmethod def remove(cls, ids_to_delete): cls._session().execute( - delete(cls._query().where( # fix: skip - cls.id.in_(ids_to_delete))).execution_options( - synchronize_session="fetch" - ) + delete( + cls._query().where(cls.id.in_(ids_to_delete)) # fix: skip + ).execution_options(synchronize_session="fetch") ) From 4c75866281f67b36a1bb98076a1560362e676c41 Mon Sep 17 00:00:00 2001 From: ji-ho lee Date: Sun, 10 Mar 2024 18:10:36 +0900 Subject: [PATCH 6/6] check-json remove --- .pre-commit-config.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 23019de..aec596b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,6 @@ repos: rev: v4.5.0 hooks: - id: check-merge-conflict - - id: check-json - id: debug-statements - id: mixed-line-ending args: [--fix=lf]