Skip to content
Draft
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
2 changes: 1 addition & 1 deletion .coveragerc
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[run]
omit = vault_service/tests*
omit = */vault_service/tests/*
10 changes: 4 additions & 6 deletions .github/workflows/python_actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:

services:
postgres:
image: postgres:9.6
image: postgres:15
env:
POSTGRES_DB: test
POSTGRES_PASSWORD: postgres
Expand All @@ -35,17 +35,15 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: 3.8
python-version: '3.12'

- name: Install dependencies
run: |
python -m pip install --upgrade wheel setuptools==56 pip
pip install -U -r requirements.txt
pip install -U -r dev-requirements.txt
pip install ".[dev]"

- name: Test with pytest
run: |
py.test vault_service
pytest

- name: Upload coverage data to coveralls.io
run: coveralls
Expand Down
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,22 @@ Microservice for storing queries, user preferences and stuff
create database vault;
alter database vault owner to vault;

* create modified vault_service/local_config.py, update (at least)
* create local_config.py at the repo root (next to config.py), update (at least)
VAULT_OAUTH_CLIENT_TOKEN = '.......'
SQLALCHEMY_DATABASE_URI = "....."

* run `alembic upgrade head`

* note: you need alembic and all dependencies in your python (`virtualenv python; pip install -r requirements; source python/bin/activate`)
* note: you need alembic and all dependencies in your python

```bash
python3.12 -m venv python
source python/bin/activate
pip install -e ".[dev]"

# run the tests
pytest
```



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
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import sqlalchemy as sa


from sqlalchemy.dialects import postgresql

def upgrade():
#with app.app_context() as c:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import sqlalchemy as sa


from sqlalchemy.dialects import postgresql

def upgrade():
#with app.app_context() as c:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import sqlalchemy as sa
import json

from sqlalchemy.dialects import postgresql

def upgrade():
#with app.app_context() as c:
Expand All @@ -31,7 +30,7 @@ def upgrade():
# Delete link_server from user_data
# But save the link_server in the library table instead to be accessible via users.library_id

users = bind.execute("SELECT id, user_data FROM users WHERE user_data ? 'link_server'")
users = bind.execute(sa.text("SELECT id, user_data FROM users WHERE user_data ? 'link_server'"))

for user_id, user_data in users:
if user_data and isinstance(user_data, dict):
Expand All @@ -40,7 +39,7 @@ def upgrade():
library_id = None
if link_server: # Only look up library if link_server is not empty
library_result = bind.execute(
"SELECT id FROM library WHERE libserver = %(libserver)s",
sa.text("SELECT id FROM library WHERE libserver = :libserver"),
{"libserver": link_server}
).fetchone()
library_id = library_result[0] if library_result else None
Expand All @@ -50,7 +49,7 @@ def upgrade():

# Convert dictionary to JSON string for PostgreSQL
bind.execute(
"UPDATE users SET user_data = %(user_data)s, library_id = %(library_id)s WHERE id = %(user_id)s",
sa.text("UPDATE users SET user_data = :user_data, library_id = :library_id WHERE id = :user_id"),
{
"user_data": json.dumps(new_user_data),
"library_id": library_id,
Expand All @@ -63,15 +62,15 @@ def downgrade():

bind = op.get_bind()

result = bind.execute("SELECT u.id, u.user_data, l.libserver FROM users u JOIN library l ON u.library_id = l.id WHERE u.library_id IS NOT NULL")
result = bind.execute(sa.text("SELECT u.id, u.user_data, l.libserver FROM users u JOIN library l ON u.library_id = l.id WHERE u.library_id IS NOT NULL"))

for user_id, user_data, libserver in result:
user_data = user_data or {}
if isinstance(user_data, dict):
if libserver is not None:
user_data['link_server'] = libserver
bind.execute(
"UPDATE users SET user_data = %(user_data)s WHERE id = %(user_id)s",
sa.text("UPDATE users SET user_data = :user_data WHERE id = :user_id"),
{
"user_data": json.dumps(user_data),
"user_id": user_id
Expand All @@ -80,12 +79,12 @@ def downgrade():

# Find and drop the actual foreign key constraint
bind = op.get_bind()
result = bind.execute("""
result = bind.execute(sa.text("""
SELECT constraint_name
FROM information_schema.table_constraints
WHERE table_name = 'users'
AND constraint_type = 'FOREIGN KEY'
""").fetchone()
""")).fetchone()

if result:
constraint_name = result[0]
Expand Down
1 change: 0 additions & 1 deletion alembic/versions/ffdbd392dc89_myads_nullable_fix.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
down_revision = 'c342556e5569'

from alembic import op
import sqlalchemy as sa



Expand Down
11 changes: 0 additions & 11 deletions dev-requirements.txt

This file was deleted.

50 changes: 50 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
[project]
name = "vault_service"
version = "0.0.1"
description = "ADS Vault Service"
authors = [{ name = "ADS Team", email = "adshelp@cfa.harvard.edu" }]
license = { text = "MIT" }
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"adsmutils @ git+https://github.com/adsabs/ADSMicroserviceUtils.git@v2.0.0",
"ADSParser @ git+https://github.com/adsabs/ADSParser.git@v1.0.4",
"Flask-Cors==6.0.5",
"alembic==1.19.1",
"psycopg2-binary==2.9.12",
"Jinja2==3.1.6",
"markupsafe==3.0.3",
"itsdangerous==2.2.0",
"werkzeug==2.3.8"
]

[project.optional-dependencies]
dev = [
"Flask-Testing==0.8.1",
"httpretty==1.1.4",
"testing.postgresql==1.3.0",
"pytest==9.1.1",
"pytest-cov==7.1.0",
"coverage==7.16.0",
"coveralls==4.1.0"
]

[build-system]
requires = ["setuptools>=62.0.0", "wheel"]
build-backend = "setuptools.build_meta"

[tool.setuptools.packages.find]
include = ["vault_service*"]
exclude = ["vault_service.tests*"]

[tool.pytest.ini_options]
addopts = "--cov=vault_service --cov-report=term-missing"
testpaths = ["vault_service/tests"]
pythonpath = ["."]

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

[tool.isort]
profile = "black"
3 changes: 0 additions & 3 deletions pytest.ini

This file was deleted.

9 changes: 0 additions & 9 deletions requirements.txt

This file was deleted.

5 changes: 2 additions & 3 deletions vault_service/app.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import logging.config

from werkzeug.serving import run_simple
import os, sys, inspect
Expand Down Expand Up @@ -26,7 +25,7 @@ def create_app(**config):
## http://docs.sqlalchemy.org/en/rel_0_9/dialects/sqlite.html#pysqlite-serializable

if 'sqlite' in app.config.get('SQLALCHEMY_DATABASE_URI', None):
from sqlalchemy import event
from sqlalchemy import event, text
engine = app.db.engine

@event.listens_for(engine, "connect")
Expand All @@ -38,7 +37,7 @@ def do_connect(dbapi_connection, connection_record):
@event.listens_for(engine, "begin")
def do_begin(conn):
# emit our own BEGIN
conn.execute("BEGIN")
conn.execute(text("BEGIN"))


# Note about imports being here rather than at the top level
Expand Down
2 changes: 1 addition & 1 deletion vault_service/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"""
from sqlalchemy import Column, Integer, String, LargeBinary, ForeignKey, Boolean, Text
from sqlalchemy.dialects.postgresql import JSONB, ENUM, ARRAY
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import declarative_base
from sqlalchemy.ext.mutable import MutableDict
from adsmutils import UTCDateTime, get_date
import sqlalchemy as sa
Expand Down
6 changes: 2 additions & 4 deletions vault_service/tests/test_bumblebee.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import sys, os
from urllib.parse import urlencode
from flask import url_for, request
from flask import url_for
import unittest
import json

project_home = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../'))
if project_home not in sys.path:
sys.path.insert(0, project_home)

from vault_service import app
from vault_service.models import Query, Institute, Library, Base
from vault_service.models import Institute, Library, Base
from vault_service.tests.base import TestCaseDatabase

class TestSite(TestCaseDatabase):
Expand Down
6 changes: 1 addition & 5 deletions vault_service/tests/test_query_as_monument.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import sys, os
from urllib.parse import urlencode
from flask import url_for, request
from flask import url_for
import unittest
import json
import httpretty
import cgi
from io import StringIO

project_home = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../'))
if project_home not in sys.path:
Expand Down
6 changes: 0 additions & 6 deletions vault_service/tests/test_service.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
import sys, os
from urllib.parse import urlencode

project_home = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../'))
if project_home not in sys.path:
sys.path.insert(0, project_home)

from flask import url_for, request
import unittest
import json
import httpretty
import cgi
from io import StringIO
from vault_service.tests.base import TestCaseDatabase

class TestServices(TestCaseDatabase):
Expand Down
8 changes: 2 additions & 6 deletions vault_service/tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
import sys, os
from urllib.parse import urlencode
from flask import url_for, request
from flask import url_for
import unittest
import json
import httpretty
import cgi
from io import StringIO

project_home = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../'))
if project_home not in sys.path:
sys.path.insert(0, project_home)

from vault_service.models import Query, User, MyADS
from vault_service.models import MyADS
from vault_service.views import utils
from vault_service.tests.base import TestCaseDatabase
import adsmutils


class TestServices(TestCaseDatabase):
Expand Down
2 changes: 1 addition & 1 deletion vault_service/views/user.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from flask import Blueprint
from flask import current_app
from flask import request, url_for
from flask import request

import json
from hashlib import md5
Expand Down
1 change: 0 additions & 1 deletion vault_service/views/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

from sqlalchemy import exc
from sqlalchemy.orm import exc as ormexc
from sqlalchemy.sql.expression import all_


def make_solr_request(query, bigquery=None, headers=None):
Expand Down
Loading