diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..aec596b --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,37 @@ +# 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: 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/CHANGELOG.md b/CHANGELOG.md index c410024..c9632f9 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-app-flask-sqlalchemy/commits/master) +### Changed +- Modified model and access code to work with SQLAlchemy version 2 (Issue #3) +- Updated packaging information files per PEP 517, PEP 518 (Issue #4) +- Restricted Python minimum working version to 3.7 or higher to align with SQLAlchemy 2 (Issue #3) + ## [1.0.1](https://github.com/python-social-auth/social-app-flask-sqlalchemy/releases/tag/1.0.1) - 2017-01-29 ### Added 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..41523e9 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,60 @@ +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[project] +name = 'social-auth-app-flask-sqlalchemy' +dynamic = ["version"] +dependencies = [ + "six", + "sqlalchemy", + "social-auth-core>=1.0.0", + "social-auth-app-flask>=1.0.0", + "social-auth-storage-sqlalchemy>=1.0.1", +] +authors = [ + {name = "Matias Aguirre", email = "matiasaguirre@gmail.com"}, + {name = "Lee Ji-ho", email = "search5@gmail.com"}, +] +description = 'Python Social Authentication, SQLAlchemy Flask models integration.' +license = {text = 'BSD'} +keywords = ["flask", "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-app-flask-sqlalchemy' +Documentation = 'http://python-social-auth.readthedocs.org' +Issues = 'https://github.com/python-social-auth/social-app-flask-sqlalchemy/issues' +Changelog = 'https://github.com/python-social-auth/social-app-flask-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_flask_sqlalchemy.__version__"} + +[tool.flake8] +max-line-length = 79 +# Ignore some well known paths +exclude = ['.venv','.tox','dist','doc','build','*.egg','db/env.py','db/versions/*.py','site','Pipfile','Pipfile.lock'] \ No newline at end of file diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index c6b4e63..0000000 --- a/requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -six -sqlalchemy -social-auth-core >= 1.0.0 -social-auth-app-flask >= 1.0.0 -social-auth-storage-sqlalchemy >= 1.0.1 diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index d817985..0000000 --- a/setup.cfg +++ /dev/null @@ -1,11 +0,0 @@ -[flake8] -max-line-length = 119 -# Ignore some well known paths -exclude = .venv,.tox,dist,doc,build,*.egg,db/env.py,db/versions/*.py,site - -[nosetests] -verbosity=2 -with-coverage=1 -cover-erase=1 -cover-package=social -rednose=1 diff --git a/setup.py b/setup.py deleted file mode 100644 index 495ac7a..0000000 --- a/setup.py +++ /dev/null @@ -1,37 +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-app-flask-sqlalchemy', - version=__import__('social_flask_sqlalchemy').__version__, - author='Matias Aguirre', - author_email='matiasaguirre@gmail.com', - description='Python Social Authentication, SQLAlchemy Flask ' - 'models integration.', - license='BSD', - keywords='flask, sqlalchemy, social auth', - url='https://github.com/python-social-auth/social-app-flask-sqlalchemy', - packages=['social_flask_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 :: 2.7', - 'Programming Language :: Python :: 3' - ], - zip_safe=False -) diff --git a/social_flask_sqlalchemy/__init__.py b/social_flask_sqlalchemy/__init__.py index cd7ca49..5c4105c 100644 --- a/social_flask_sqlalchemy/__init__.py +++ b/social_flask_sqlalchemy/__init__.py @@ -1 +1 @@ -__version__ = '1.0.1' +__version__ = "1.0.1" diff --git a/social_flask_sqlalchemy/models.py b/social_flask_sqlalchemy/models.py index db1f187..8ced105 100644 --- a/social_flask_sqlalchemy/models.py +++ b/social_flask_sqlalchemy/models.py @@ -1,19 +1,26 @@ """Flask SQLAlchemy ORM models for Social Auth""" -from sqlalchemy import Column, String, ForeignKey -from sqlalchemy.orm import relationship, backref -from sqlalchemy.schema import UniqueConstraint -from sqlalchemy.ext.declarative import declarative_base -from social_core.utils import setting_name, module_member -from social_sqlalchemy.storage import SQLAlchemyUserMixin, \ - SQLAlchemyAssociationMixin, \ - SQLAlchemyNonceMixin, \ - SQLAlchemyCodeMixin, \ - SQLAlchemyPartialMixin, \ - BaseSQLAlchemyStorage +from social_core.utils import module_member, setting_name +from social_sqlalchemy.storage import ( + BaseSQLAlchemyStorage, + SQLAlchemyAssociationMixin, + SQLAlchemyCodeMixin, + SQLAlchemyNonceMixin, + SQLAlchemyPartialMixin, + SQLAlchemyUserMixin, +) +from sqlalchemy import ForeignKey +from sqlalchemy.orm import ( # fmt: skip + DeclarativeBase, + backref, + mapped_column, + relationship, +) +from sqlalchemy.schema import UniqueConstraint -PSABase = declarative_base() +class PSABase(DeclarativeBase): + pass class _AppSession(PSABase): @@ -30,9 +37,9 @@ def _session(cls): class UserSocialAuth(_AppSession, SQLAlchemyUserMixin): """Social Auth association model""" + # Temporary override of constraints to avoid an error on the still-to-be # missing column uid. - __table_args__ = () @classmethod def user_model(cls): @@ -41,26 +48,30 @@ def user_model(cls): @classmethod def username_max_length(cls): user_model = cls.user_model() - return user_model.__table__.columns.get('username').type.length + return user_model.__table__.columns.get("username").type.length class Nonce(_AppSession, SQLAlchemyNonceMixin): """One use numbers""" + pass class Association(_AppSession, SQLAlchemyAssociationMixin): """OpenId account association""" + pass class Code(_AppSession, SQLAlchemyCodeMixin): """Mail validation single one time use code""" + pass class Partial(_AppSession, SQLAlchemyPartialMixin): """Partial pipeline storage""" + pass @@ -73,12 +84,12 @@ class FlaskStorage(BaseSQLAlchemyStorage): def init_social(app, session): - UID_LENGTH = app.config.get(setting_name('UID_LENGTH'), 255) - User = module_member(app.config[setting_name('USER_MODEL')]) + User = module_member(app.config[setting_name("USER_MODEL")]) _AppSession._set_session(session) - UserSocialAuth.__table_args__ = (UniqueConstraint('provider', 'uid'),) - UserSocialAuth.uid = Column(String(UID_LENGTH)) - UserSocialAuth.user_id = Column(User.id.type, ForeignKey(User.id), - nullable=False, index=True) - UserSocialAuth.user = relationship(User, backref=backref('social_auth', - lazy='dynamic')) + UserSocialAuth.__table_args__ = (UniqueConstraint("provider", "uid"),) + UserSocialAuth.user_id = mapped_column( + ForeignKey(User.id), nullable=False, index=True + ) + UserSocialAuth.user = relationship( + User, backref=backref("social_auth", lazy="dynamic") + )