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
6 changes: 3 additions & 3 deletions .github/workflows/annotationengine.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ jobs:
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
steps:
- uses: actions/checkout@v2
- name: Set up Python 3.9
- name: Set up Python 3.10
uses: actions/setup-python@v2
with:
python-version: 3.9
python-version: "3.10"
- uses: actions/cache@v4
with:
path: ~/.cache/pip
Expand All @@ -48,7 +48,7 @@ jobs:
with:
auto-update-conda: true
auto-activate-base: true
python-version: 3.9
python-version: "3.10"
- name: Install dependencies
shell: bash -l {0}
run: |
Expand Down
29 changes: 27 additions & 2 deletions annotationengine/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
from caveclient.auth import AuthClient
import werkzeug
import traceback
import datetime
import pytz

from annotationengine.aligned_volume import (
get_aligned_volumes,
Expand Down Expand Up @@ -100,6 +102,14 @@ def handle_invalid_usage(error):
location="args",
help="whether to only return valid items",
)
query_parser.add_argument(
"timestamp",
type=str,
default=None,
location="args",
required=False,
help="timestamp for filtering results (will default to now if not required)",
)


def check_aligned_volume(aligned_volume):
Expand Down Expand Up @@ -243,11 +253,26 @@ def put(self, aligned_volume_name: str) -> FullMetadataSchema:
@api_bp.expect(query_parser)
def get(self, aligned_volume_name: str):
"""Get list of annotation tables for a aligned_volume"""
args = query_parser.parse_args()
timestamp_str = args.get("timestamp", None)
if timestamp_str is None:
timestamp = datetime.datetime.now(datetime.timezone.utc)
else:
# fromisoformat accepts common ISO 8601 formats with or without microseconds
# (e.g. 2026-02-19T10:30:00 or 2026-02-19T10:30:00.123456)
timestamp = datetime.datetime.fromisoformat(
timestamp_str.replace("Z", "+00:00")
)
if timestamp.tzinfo is None:
timestamp = pytz.utc.localize(timestamp)
else:
timestamp = timestamp.astimezone(pytz.utc)

check_aligned_volume(aligned_volume_name)
db = get_db(aligned_volume_name)
args = query_parser.parse_args()
tables = db.database._get_existing_table_names(
filter_valid=args.get("filter_valid", True)
filter_valid=args.get("filter_valid", True),
filter_timestamp=timestamp
)
return tables, 200

Expand Down
4 changes: 2 additions & 2 deletions dev.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ RUN git config --global http.sslVerify false && \
mkdir -p /home/nginx/.cloudvolume/secrets && chown -R nginx /home/nginx && usermod -d /home/nginx -s /bin/bash nginx

RUN python -m pip install --upgrade pip
COPY dev_requirements.txt /app/.
RUN pip install -r dev_requirements.txt
COPY requirements.txt /app/.
RUN pip install -r requirements.txt
COPY timeout.conf /etc/nginx/conf.d/
COPY . /app

4 changes: 2 additions & 2 deletions dev_requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ deprecated==1.2.13
# via redis
dynamicannotationdb==5.2.2
# via -r requirements.in
emannotationschemas==5.1.1
emannotationschemas==5.24.12
# via
# -r requirements.in
# dynamicannotationdb
Expand Down Expand Up @@ -178,7 +178,7 @@ requests==2.27.1
# -r requirements.in
# caveclient
# middle-auth-client
shapely==1.8.0
shapely==2.0.3
# via
# dynamicannotationdb
# emannotationschemas
Expand Down
2 changes: 1 addition & 1 deletion requirements.in
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Flask<2.0
emannotationschemas>=5.24.13
dynamicannotationdb>=5.5.1
dynamicannotationdb>=5.14.1
caveclient>=4.20.2
multiwrapper
jsonschema<4.0
Expand Down
12 changes: 2 additions & 10 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ click==7.1.2
# via flask
decorator==5.1.1
# via ipython
deprecated==1.2.13
# via redis
dynamicannotationdb==5.8.1
dynamicannotationdb==5.14.1
# via -r requirements.in
emannotationschemas==5.24.13
# via
Expand Down Expand Up @@ -121,9 +119,7 @@ numpy==1.21.5
orderedmultidict==1.0.1
# via furl
packaging==21.3
# via
# geoalchemy2
# redis
# via geoalchemy2
pandas==1.3.5
# via caveclient
parso==0.8.3
Expand Down Expand Up @@ -153,8 +149,6 @@ pytz==2021.3
# dynamicannotationdb
# flask-restx
# pandas
redis==4.1.3
# via middle-auth-client
requests==2.27.1
# via
# -r requirements.in
Expand Down Expand Up @@ -200,7 +194,5 @@ werkzeug==1.0.1
# flask
# flask-accepts
# flask-restx
wrapt==1.13.3
# via deprecated
wtforms==3.0.1
# via flask-admin
18 changes: 17 additions & 1 deletion test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,32 @@ def test_aligned_volume():

@pytest.fixture(scope="module")
def client():
flask_app = create_app(config_name="testing")
config_name = os.environ.get("FLASK_CONFIGURATION", "testing")
flask_app = create_app(config_name=config_name)
test_logger.info("Starting test flask app...")

# Create a test client using the Flask application configured for testing
with flask_app.test_client() as testing_client:
# Establish an application context
with flask_app.app_context():
db.create_all()
logging.info("yielding testing_client")
yield testing_client
# --- Cleanup Phase ---
logging.info("Tearing down testing_client, committing session")

db.session.commit()

logging.info("dropping all tables")
# 2. Drop the tables
db.drop_all()
logging.info("removing session")
# 1. Remove the scoped session to prevent "ResourceBusy" errors
db.session.remove()
logging.info("disposing engine")
# 3. Dispose of the engine to kill the connection pool (The Fix)
db.engine.dispose()
logging.info("cleanup complete")


@pytest.fixture(scope="module")
Expand Down
Loading