diff --git a/.github/workflows/python_actions.yml b/.github/workflows/python_actions.yml index e54b4d8..9a1c841 100644 --- a/.github/workflows/python_actions.yml +++ b/.github/workflows/python_actions.yml @@ -11,11 +11,11 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 with: - python-version: '3.10' + python-version: '3.12' - name: Install dependencies run: | - python -m pip install "pip==24" setuptools==57.5.0 wheel + python -m pip install "pip==24" "setuptools>=62.0.0,<70.0.0" wheel pip install ".[dev]" - name: Test with pytest diff --git a/alembic/env.py b/alembic/env.py index 9411ddc..9e9cc5a 100644 --- a/alembic/env.py +++ b/alembic/env.py @@ -1,4 +1,3 @@ -from __future__ import with_statement from alembic import context from sqlalchemy import engine_from_config, pool from logging.config import fileConfig diff --git a/biblib/manage.py b/biblib/manage.py index 206c629..53e2f98 100644 --- a/biblib/manage.py +++ b/biblib/manage.py @@ -6,6 +6,7 @@ from flask import current_app from datetime import datetime from dateutil.relativedelta import relativedelta +from sqlalchemy import text import sqlalchemy_continuum class DeleteStaleUsers: @@ -19,7 +20,7 @@ def run(self, app=None): with app.app_context(): with current_app.session_scope() as session: # Obtain the list of API users - postgres_search_text = 'SELECT id FROM users;' + postgres_search_text = text('SELECT id FROM users;') result = session.execute(postgres_search_text).fetchall() list_of_api_users = [int(r[0]) for r in result] diff --git a/biblib/models.py b/biblib/models.py index ec0633f..0f4d3bf 100644 --- a/biblib/models.py +++ b/biblib/models.py @@ -6,11 +6,11 @@ """ import uuid -from datetime import datetime +from datetime import datetime, timezone from sqlalchemy.dialects.postgresql import UUID, JSON from sqlalchemy.ext.mutable import Mutable from sqlalchemy.types import TypeDecorator, CHAR, String as StringType -from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import declarative_base from sqlalchemy import Column, Integer, String, ForeignKey, DateTime, Boolean, UnicodeText, UniqueConstraint from sqlalchemy.orm import relationship, configure_mappers from sqlalchemy_continuum import make_versioned @@ -189,13 +189,13 @@ class Notes(Base): date_created = Column( DateTime, nullable=False, - default=datetime.utcnow + default=lambda: datetime.now(timezone.utc).replace(tzinfo=None) ) date_last_modified = Column( DateTime, nullable=False, - default=datetime.utcnow, - onupdate=datetime.utcnow + default=lambda: datetime.now(timezone.utc).replace(tzinfo=None), + onupdate=lambda: datetime.now(timezone.utc).replace(tzinfo=None) ) def __repr__(self): @@ -251,13 +251,13 @@ class Library(Base): date_created = Column( DateTime, nullable=False, - default=datetime.utcnow + default=lambda: datetime.now(timezone.utc).replace(tzinfo=None) ) date_last_modified = Column( DateTime, nullable=False, - default=datetime.utcnow, - onupdate=datetime.utcnow + default=lambda: datetime.now(timezone.utc).replace(tzinfo=None), + onupdate=lambda: datetime.now(timezone.utc).replace(tzinfo=None) ) permissions = relationship('Permissions', backref='library', diff --git a/biblib/tests/unit_tests/test_manage.py b/biblib/tests/unit_tests/test_manage.py index c47a00f..f5219ef 100644 --- a/biblib/tests/unit_tests/test_manage.py +++ b/biblib/tests/unit_tests/test_manage.py @@ -6,6 +6,7 @@ from biblib.manage import DeleteObsoleteVersionsNumber, DeleteStaleUsers, DeleteObsoleteVersionsTime from biblib.models import User, Library, Permissions, Notes from sqlalchemy.orm.exc import NoResultFound +from sqlalchemy import text from biblib.tests.base import TestCaseDatabase import sqlalchemy_continuum import freezegun @@ -53,8 +54,8 @@ def test_delete_stale_users(self): with self.app.session_scope() as session: # We do not add user 1 to the API database - session.execute('create table users (id integer, random integer);') - session.execute('insert into users (id, random) values (2, 7);') + session.execute(text('create table users (id integer, random integer);')) + session.execute(text('insert into users (id, random) values (2, 7);')) session.commit() with self.app.session_scope() as session: @@ -171,7 +172,7 @@ def test_delete_stale_users(self): raise finally: # Destroy the tables - session.execute('drop table users;') + session.execute(text('drop table users;')) pass def test_delete_obsolete_versions_number(self): @@ -184,8 +185,8 @@ def test_delete_obsolete_versions_number(self): with self.app.session_scope() as session: # We do not add user 1 to the API database - session.execute('create table users (id integer, random integer);') - session.execute('insert into users (id, random) values (2, 7);') + session.execute(text('create table users (id integer, random integer);')) + session.execute(text('insert into users (id, random) values (2, 7);')) session.commit() with self.app.session_scope() as session: @@ -340,7 +341,7 @@ def test_delete_obsolete_versions_number(self): raise finally: # Destroy the tables - session.execute('drop table users;') + session.execute(text('drop table users;')) pass def test_delete_obsolete_versions_time(self): @@ -353,8 +354,8 @@ def test_delete_obsolete_versions_time(self): with self.app.session_scope() as session: # We do not add user 1 to the API database - session.execute('create table users (id integer, random integer);') - session.execute('insert into users (id, random) values (2, 7);') + session.execute(text('create table users (id integer, random integer);')) + session.execute(text('insert into users (id, random) values (2, 7);')) session.commit() with self.app.session_scope() as session: @@ -535,7 +536,7 @@ def test_delete_obsolete_versions_time(self): raise finally: # Destroy the tables - session.execute('drop table users;') + session.execute(text('drop table users;')) pass if __name__ == '__main__': diff --git a/config.py b/config.py new file mode 100644 index 0000000..4a650ed --- /dev/null +++ b/config.py @@ -0,0 +1 @@ +from biblib.config import * diff --git a/pyproject.toml b/pyproject.toml index 33e898d..b310e2b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,15 +7,15 @@ license = { text = "MIT" } readme = "README.md" packages = ["biblib"] dependencies = [ - "adsmutils @ git+https://github.com/adsabs/ADSMicroserviceUtils.git@v1.3.0", - "alembic==1.12.0", - "psycopg2-binary==2.9.9", - "sqlalchemy-continuum==1.3.6", - "Flask-Mail==0.9.1", + "adsmutils @ git+https://github.com/adsabs/ADSMicroserviceUtils.git@v2.0.0", + "alembic==1.13.3", + "psycopg2-binary==2.9.11", + "sqlalchemy-continuum==1.3.15", + "Flask-Mail==0.10.0", "Flask-Email==1.4.4", - "Jinja2==3.1.2", - "markupsafe==2.1.3", - "itsdangerous==2.1.2", + "Jinja2==3.1.6", + "markupsafe==3.0.3", + "itsdangerous==2.2.0", "werkzeug==2.3.8" ] @@ -24,22 +24,23 @@ dev = [ "Flask-Testing==0.8.1", "httpretty==1.1.4", "testing.postgresql==1.3.0", - "pytest==6.2.5", - "pytest-cov==3.0.0", + "pytest==7.4.4", + "pytest-cov==5.0.0", "Faker==22.0.0", - "factory-boy==3.3.0", - "freezegun==1.4.0", + "factory-boy==3.3.3", + "freezegun==1.5.5", "httmock==1.4.0", - "mock==4.0.3", - "flake8==4.0.1", - "black==22.3.0", + "mock==5.2.0", + "flake8==7.1.0", + "black==24.10.0", "isort==5.12.0", - "coveralls==3.3.1" + "coverage==7.6.1", + "coveralls==4.0.1" ] [build-system] requires = [ - "setuptools==57.5.0", + "setuptools>=62.0.0,<70.0.0", "wheel", "flit_core >=3.2,<4", "ppsetuptools==2.0.2" @@ -52,7 +53,7 @@ testpaths = ["biblib/tests"] [tool.black] line-length = 88 -target-version = ['py310'] +target-version = ['py312'] [tool.isort] profile = "black"