Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/workflows/python_actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@ 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
pip install ".[dev]"

- name: Test with pytest
Expand Down
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ docker run -d --name postgres -e POSTGRES_USER="postgres" -e POSTGRES_PASSWORD="
python3 -m venv python
source python/bin/activate

# Install with legacy build support (requires pip 24 and specific setuptools)
python -m pip install "pip==24" setuptools==57.5.0 wheel
# Install the project and dev dependencies
pip install -e ".[dev]"

# Run tests
Expand All @@ -48,7 +47,7 @@ All tests have been written top down, or in a Test-Driven Development approach,
### Running Biblib Locally

To run a version of Biblib locally, a postgres database needs to be created and properly formatted for use with Biblib. This can be done with a local postgres instance or in a docker container using the following commands.
`local_config.py` should be created in `biblib/` and the environment variables must be adjusted to reflect the local environment.
`local_config.py` should be created at the repo root (next to `config.py`) and the environment variables must be adjusted to reflect the local environment.

```bash
# Setup database
Expand Down
1 change: 0 additions & 1 deletion alembic/env.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down
3 changes: 2 additions & 1 deletion biblib/manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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]

Expand Down
16 changes: 8 additions & 8 deletions biblib/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
"""

import uuid
from datetime import datetime
from datetime import datetime, timezone

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did something change in sqlalchemy that now requires us to explicitly strip the timezone?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change is in Python. datetime.utcnow() is deprecated and should be replaced with datetime.now(timezone.utc), but the former is timezone-naive, and the latter is timezone-aware. I'm stripping the timezone so the new version is the same as the previous one.

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
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from biblib.tests.base import TestCaseDatabase, MockEmailService, \
MockSolrBigqueryService, MockEndPoint, MockClassicService
from biblib.views.http_errors import NO_CLASSIC_ACCOUNT
from biblib.config import BIBLIB_CLASSIC_SERVICE_URL
from config import BIBLIB_CLASSIC_SERVICE_URL


class TestBBClassicUserEpic(TestCaseDatabase):
Expand Down
2 changes: 1 addition & 1 deletion biblib/tests/functional_tests/test_classic_user_epic.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from biblib.tests.base import TestCaseDatabase, MockEmailService, \
MockSolrBigqueryService, MockEndPoint, MockClassicService
from biblib.views.http_errors import NO_CLASSIC_ACCOUNT
from biblib.config import BIBLIB_CLASSIC_SERVICE_URL
from config import BIBLIB_CLASSIC_SERVICE_URL


@urlmatch(netloc=r'(.*\.)?{}.*'.format(BIBLIB_CLASSIC_SERVICE_URL))
Expand Down
19 changes: 10 additions & 9 deletions biblib/tests/unit_tests/test_manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this strictly input sanitization?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from biblib.tests.base import TestCaseDatabase
import sqlalchemy_continuum
import freezegun
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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):
Expand All @@ -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:
Expand Down Expand Up @@ -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):
Expand All @@ -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:
Expand Down Expand Up @@ -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__':
Expand Down

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an interesting way to solve the relocated config. We can talk more about it at our next weekly and decide if this is how we want to do it going forward?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That bypassed my review. I just moved the config to the root so it can be found after the changes to adsmutils.

File renamed without changes.
42 changes: 22 additions & 20 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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.18.5",
"psycopg2-binary==2.9.12",
"sqlalchemy-continuum==1.6.0",
"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"
]

Expand All @@ -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",
"Faker==22.0.0",
"factory-boy==3.3.0",
"freezegun==1.4.0",
"pytest==9.1.1",
"pytest-cov==7.1.0",
"Faker==40.28.1",
"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",
"isort==5.12.0",
"coveralls==3.3.1"
"mock==5.2.0",
"flake8==7.3.0",
"black==26.5.1",
"isort==8.0.1",
"coverage==7.15.0",
"coveralls==4.1.0"
]

[build-system]
requires = [
"setuptools==57.5.0",
"setuptools>=62.0.0",
"wheel",
"flit_core >=3.2,<4",
"ppsetuptools==2.0.2"
Expand All @@ -49,10 +50,11 @@ build-backend = "flit_core.buildapi"
[tool.pytest.ini_options]
addopts = "--cov=biblib --cov-report=term-missing"
testpaths = ["biblib/tests"]
pythonpath = ["."]

[tool.black]
line-length = 88
target-version = ['py310']
target-version = ['py312']

[tool.isort]
profile = "black"
Loading