Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Skeleton dev #285

Closed
wants to merge 39 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
f8e819b
SkeletonService docs update. SkeletonService default versions clean-u…
kebwi Nov 21, 2024
f2ec3dd
Bug fix
kebwi Dec 6, 2024
d6d22ad
Bug fix
kebwi Dec 6, 2024
0ea4b96
Initial SkeletonClient tests
kebwi Dec 9, 2024
21d69d3
Bump version: 7.0.1 → 7.0.2
github-actions[bot] Nov 21, 2024
5b33f1a
Use pyproject.toml and new build system (#232)
bdpedigo Nov 22, 2024
43bd282
Bump version: 7.0.2 → 7.0.3
github-actions[bot] Nov 22, 2024
84b4374
Remove requirements.txt (#270)
bdpedigo Nov 22, 2024
dcc5f4c
Bump version: 7.0.3 → 7.0.4
github-actions[bot] Nov 22, 2024
35981b6
Leaves many (#273)
fcollman Dec 4, 2024
0fbad5d
Bump version: 7.0.4 → 7.1.0
github-actions[bot] Dec 4, 2024
0fa07b5
Allow get_state_json to accept direct URLs (#271)
ceesem Dec 4, 2024
603f7d5
Bump version: 7.1.0 → 7.2.0
github-actions[bot] Dec 4, 2024
7770a56
Use raw string notation in regex (#275)
bdpedigo Dec 5, 2024
dd29629
Bump version: 7.2.0 → 7.2.1
github-actions[bot] Dec 5, 2024
02abcfb
Get minimal covering nodes (#274)
fcollman Dec 5, 2024
f702997
Bump version: 7.2.1 → 7.3.0
github-actions[bot] Dec 5, 2024
dd362a1
add doc improvement to update_metadata
fcollman Dec 5, 2024
608c85d
Bump version: 7.3.0 → 7.3.1
github-actions[bot] Dec 5, 2024
07267ec
Merge branch 'master' into skeleton_dev
kebwi Dec 9, 2024
bdd2823
ruff cleanup
kebwi Dec 9, 2024
56855e5
ruff cleanup
kebwi Dec 9, 2024
4a3756b
Code cleanup
kebwi Dec 9, 2024
139c1a2
Merge branch 'master' into skeleton_dev
fcollman Dec 10, 2024
1121ab5
adding test to None functionality
fcollman Dec 10, 2024
942a48f
ruff cleanup
kebwi Dec 11, 2024
3a5bdb9
Merge branch 'master' into skeleton_dev
fcollman Dec 12, 2024
81dbc30
fixing imports adding formatting
fcollman Dec 12, 2024
8ca4536
fixiing test to have an assertion
fcollman Dec 12, 2024
4347fda
lint fix
fcollman Dec 12, 2024
2bd1221
updating doc string
fcollman Dec 12, 2024
0fc1bd7
skeletons_exist() now takes a numpy array of ints or strs (in additio…
kebwi Dec 13, 2024
3b06b9a
generate_bulk_skeletons_async() imposes a 10k limit and breaks the bu…
kebwi Dec 13, 2024
4206cb0
ruff cleanup
kebwi Dec 13, 2024
ae67cb0
adding codecov (#280)
fcollman Dec 12, 2024
0c04369
Codecov (#281)
fcollman Dec 12, 2024
9348b2b
Bump version: 7.3.2 → 7.4.0
github-actions[bot] Dec 12, 2024
14a49c9
Update changelog.md
fcollman Dec 12, 2024
e8166b4
update contributing guidelines (#283)
bdpedigo Dec 13, 2024
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
7 changes: 6 additions & 1 deletion .github/workflows/dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,9 @@ jobs:

- name: Test with pytest
run: |
uvx --from poethepoet poe test
uvx --from poethepoet poe test

- name: Upload to codecov
uses: codecov/codecov-action@v2
with:
token: ${{ secrets.CODECOV_TOKEN }}
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

![PyPI - Version](https://img.shields.io/pypi/v/CAVEclient)
[![build status](https://github.com/CAVEconnectome/CAVEclient/actions/workflows/daily.yml/badge.svg)](https://github.com/CAVEconnectome/CAVEclient/actions/workflows/daily.yml) [![Downloads](https://static.pepy.tech/badge/caveclient)](https://pepy.tech/project/caveclient)
[![codecov](https://codecov.io/gh/CAVEconnectome/CAVEclient/graph/badge.svg?token=KVI1AG6B8A)](https://codecov.io/gh/CAVEconnectome/CAVEclient)

CAVE is short for Connectome Annotation Versioning Engine. CAVE is a set of microservices
that provide a framework for storing and versioning connectomics data and large sets of
Expand All @@ -27,8 +28,16 @@ pip install caveclient[cv]

## Python version support

Currently we are officially supporting and testing against Python 3.8, 3.9, 3.10, 3.11 and 3.12.
Currently we are officially supporting and testing against Python 3.9, 3.10, 3.11 and 3.12.

## Documentation

You can find full documentation at [caveconnectome.github.io/CAVEclient](https://caveconnectome.github.io/CAVEclient).

## Issues

We welcome bug reports and questions. Please post an informative issue on the [GitHub issue tracker](https://github.com/CAVEconnectome/CAVEclient/issues).

## Development

To view information about developing CAVEclient, see our [contributing guide](https://caveconnectome.github.io/CAVEclient/contributing).
28 changes: 17 additions & 11 deletions caveclient/annotationengine.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,10 @@
if user_id is not None:
metadata["user_id"] = user_id
if notice_text is not None:
if notice_text.lower() == "none":

Check warning on line 315 in caveclient/annotationengine.py

View check run for this annotation

Codecov / codecov/patch

caveclient/annotationengine.py#L315

Added line #L315 was not covered by tests
# This alteration is actually redundant with similar code in the server,
# but there's no harm in doubling up on it here.
notice_text = ""

Check warning on line 318 in caveclient/annotationengine.py

View check run for this annotation

Codecov / codecov/patch

caveclient/annotationengine.py#L318

Added line #L318 was not covered by tests
metadata["notice_text"] = notice_text
if reference_table is not None:
metadata["table_metadata"] = {
Expand Down Expand Up @@ -347,31 +351,32 @@
----------
table_name (str): name of table to update
description (str, optional): text description of the the table.
Defaults to None (will not update).
Defaults to the None type, in which case no change will be made to this metadata field.
flat_segmentation_source (str, optional): cloudpath to a flat segmentation associated with this table.
Defaults to None (will not update).
Defaults to the None type, in which case no change will be made to this metadata field.
read_permission: str, optional
What permissions to give the table for reading. One of
PRIVATE: only you can read this table. Intended to be used for sorting out bugs.
GROUP: only members that share a group with you can read (intended for within group vetting)
PUBLIC: anyone with permissions to read this datastack can read this data
Defaults to None (will not update).
Defaults to the None type, in which case no change will be made to this metadata field.
write_permission: str, optional
What permissions to give the table for writing. One of
PRIVATE: only you can write to this table
GROUP: only members that share a group with you can write (excluding some groups)
PUBLIC: Anyone can write to this table. Note all data is logged, and deletes are done
by marking rows as deleted, so all data is always recoverable
Defaults to None (will not update).
Defaults to the None type, in which case no change will be made to this metadata field.
user_id (int, optional): change ownership of this table to this user_id.
Note, if you use this you will not be able to update the metadata on this table any longer
and depending on permissions may not be able to read or write to it
Defaults to None. (will not update)
Defaults to the None type, in which case no change will be made to this metadata field.
notice_text: str, optional
Text the user will see when querying this table. Can be used to warn users of flaws,
and uncertainty in the data, or to advertise citations that should be used with this table.
If you wish to remove the notice_text pass an empty string.
Defaults to None. (will not update)
If you wish to remove the notice_text pass an empty string, or "none", "None", "NONE",
or any other capitaliztion of the word "none".
Defaults to the None type, in which case no change will be made to this metadata field.
aligned_volume_name : str or None, optional
Name of the aligned_volume. If None, uses the one specified in the client.
"""
Expand Down Expand Up @@ -406,10 +411,11 @@
if user_id is not None:
metadata["user_id"] = user_id
if notice_text is not None:
if notice_text == "None":
metadata["notice_text"] = ""
else:
metadata["notice_text"] = notice_text
if notice_text.lower() == "none":
# This alteration is actually redundant with similar code in the server,
# but there's no harm in doubling up on it here.
notice_text = ""
metadata["notice_text"] = notice_text

data = {"table_name": table_name, "metadata": metadata}
response = self.session.put(url, json=data)
Expand Down
58 changes: 46 additions & 12 deletions caveclient/skeletonservice.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from io import BytesIO, StringIO
from typing import List, Literal, Optional, Union

import numpy as np
import pandas as pd
from cachetools import TTLCache, cached
from packaging.version import Version
Expand All @@ -22,6 +23,9 @@

SERVER_KEY = "skeleton_server_address"

MAX_BULK_ASYNCHRONOUS_SKELETONS = 10000
BULK_ASYNC_SKELETONS_BATCH_SIZE = 100


class NoL2CacheException(Exception):
def __init__(self, value=""):
Expand Down Expand Up @@ -375,6 +379,9 @@
f"Unknown skeleton version: {skeleton_version}. Valid options: {valid_skeleton_versions}"
)

if isinstance(root_ids, np.ndarray):
root_ids = root_ids.tolist()

Check warning on line 383 in caveclient/skeletonservice.py

View check run for this annotation

Codecov / codecov/patch

caveclient/skeletonservice.py#L382-L383

Added lines #L382 - L383 were not covered by tests

if isinstance(root_ids, int):
root_ids = str(root_ids)
elif isinstance(root_ids, List):
Expand Down Expand Up @@ -669,20 +676,47 @@
)
skeleton_version = -1

url = self._build_bulk_async_endpoint(
root_ids, datastack_name, skeleton_version
)
response = self.session.get(url)
self.raise_for_status(response, log_warning=log_warning)
if isinstance(root_ids, np.ndarray):
root_ids = root_ids.tolist()
if not isinstance(root_ids, list):
raise ValueError(

Check warning on line 682 in caveclient/skeletonservice.py

View check run for this annotation

Codecov / codecov/patch

caveclient/skeletonservice.py#L679-L682

Added lines #L679 - L682 were not covered by tests
f"root_ids must be a list or numpy array of root_ids, not a {type(root_ids)}"
)

estimated_async_time_secs_upper_bound = float(response.text)
if len(root_ids) > MAX_BULK_ASYNCHRONOUS_SKELETONS:
logging.warning(

Check warning on line 687 in caveclient/skeletonservice.py

View check run for this annotation

Codecov / codecov/patch

caveclient/skeletonservice.py#L686-L687

Added lines #L686 - L687 were not covered by tests
f"The number of root_ids exceeds the current limit of {MAX_BULK_ASYNCHRONOUS_SKELETONS}. Only the first {MAX_BULK_ASYNCHRONOUS_SKELETONS} will be processed."
)
root_ids = root_ids[:MAX_BULK_ASYNCHRONOUS_SKELETONS]

Check warning on line 690 in caveclient/skeletonservice.py

View check run for this annotation

Codecov / codecov/patch

caveclient/skeletonservice.py#L690

Added line #L690 was not covered by tests

if verbose_level >= 1:
logging.info(
f"Queued asynchronous skeleton generation for root_ids: {root_ids}"
estimated_async_time_secs_upper_bound_sum = 0
for batch in range(0, len(root_ids), BULK_ASYNC_SKELETONS_BATCH_SIZE):
rids_one_batch = root_ids[batch : batch + BULK_ASYNC_SKELETONS_BATCH_SIZE]

Check warning on line 694 in caveclient/skeletonservice.py

View check run for this annotation

Codecov / codecov/patch

caveclient/skeletonservice.py#L692-L694

Added lines #L692 - L694 were not covered by tests

url = self._build_bulk_async_endpoint(

Check warning on line 696 in caveclient/skeletonservice.py

View check run for this annotation

Codecov / codecov/patch

caveclient/skeletonservice.py#L696

Added line #L696 was not covered by tests
rids_one_batch, datastack_name, skeleton_version
)
logging.info(
f"Upper estimate to generate {len(root_ids)} skeletons: {estimated_async_time_secs_upper_bound} seconds"
response = self.session.get(url)
self.raise_for_status(response, log_warning=log_warning)

Check warning on line 700 in caveclient/skeletonservice.py

View check run for this annotation

Codecov / codecov/patch

caveclient/skeletonservice.py#L699-L700

Added lines #L699 - L700 were not covered by tests

estimated_async_time_secs_upper_bound = float(response.text)
estimated_async_time_secs_upper_bound_sum += (

Check warning on line 703 in caveclient/skeletonservice.py

View check run for this annotation

Codecov / codecov/patch

caveclient/skeletonservice.py#L702-L703

Added lines #L702 - L703 were not covered by tests
estimated_async_time_secs_upper_bound
)

return f"Upper estimate to generate {len(root_ids)} skeletons: {estimated_async_time_secs_upper_bound} seconds"
if verbose_level >= 1:
logging.info(

Check warning on line 708 in caveclient/skeletonservice.py

View check run for this annotation

Codecov / codecov/patch

caveclient/skeletonservice.py#L707-L708

Added lines #L707 - L708 were not covered by tests
f"Queued asynchronous skeleton generation for one batch of root_ids: {rids_one_batch}"
)
logging.info(

Check warning on line 711 in caveclient/skeletonservice.py

View check run for this annotation

Codecov / codecov/patch

caveclient/skeletonservice.py#L711

Added line #L711 was not covered by tests
f"Upper estimate to generate one batch of {len(rids_one_batch)} skeletons: {estimated_async_time_secs_upper_bound} seconds"
)

if estimated_async_time_secs_upper_bound_sum < 60:
return f"Upper estimate to generate all {len(root_ids)} skeletons: {estimated_async_time_secs_upper_bound_sum:.0f} seconds"
if estimated_async_time_secs_upper_bound_sum < 3600:
return f"Upper estimate to generate all {len(root_ids)} skeletons: {(estimated_async_time_secs_upper_bound_sum / 60):.1f} minutes"

Check warning on line 718 in caveclient/skeletonservice.py

View check run for this annotation

Codecov / codecov/patch

caveclient/skeletonservice.py#L715-L718

Added lines #L715 - L718 were not covered by tests
# With a 10000 skeleton limit, the maximum time about 12 hours, so we don't need to check for more than that.
if True: # estimated_async_time_secs_upper_bound_sum < 86400:
return f"Upper estimate to generate all {len(root_ids)} skeletons: {(estimated_async_time_secs_upper_bound_sum / 3600):.1f} hours"

Check warning on line 721 in caveclient/skeletonservice.py

View check run for this annotation

Codecov / codecov/patch

caveclient/skeletonservice.py#L720-L721

Added lines #L720 - L721 were not covered by tests
# return f"Upper estimate to generate all {len(root_ids)} skeletons: {(estimated_async_time_secs_upper_bound_sum / 86400):.2f} days"
4 changes: 4 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
---
title: Changelog
---
## 7.4.0 (December 12, 2024)
annotation module: Added support for "None", "none", etc. to remove notice_text and
improved documentation on method

## 7.3.2 (December 10, 2024)
Dropped oldest supported numpy requirements and declared python 3.8 support

Expand Down
80 changes: 47 additions & 33 deletions docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ If you are proposing a feature:
- Keep the scope as narrow as possible, to make it easier to implement.
- Remember that while contributions are welcome, developer/maintainer time is limited.

## Get Started
## Modifying Code

Ready to contribute? Here's how to set up `{{ names.package }}` for local development.

Expand All @@ -56,17 +56,22 @@ Ready to contribute? Here's how to set up `{{ names.package }}` for local develo
git clone [email protected]:your_name_here/{{ names.repo_title }}.git
```

- Ensure [pip](https://pip.pypa.io/en/stable/installation/) is installed.
- Create a virtual environment (here we use venv):
- We use [`uv`](https://docs.astral.sh/uv/) for various developer tasks. Ensure you have `uv` installed according to the [installation instructions](https://docs.astral.sh/uv/getting-started/installation/).

!!! note

While we recommend using `uv` as described here, these tasks could also be achieved using `pip` to install and run the various required tools. You can view the development requirements and build/check commands in our [`pyproject.toml`](https://github.com/CAVEconnectome/CAVEclient/blob/master/pyproject.toml), so we avoid duplicating them here.

- Navigate to the newly cloned directory, e.g.:

```console
python3 -m venv .venv
cd {{ names.repo_title }}
```

- Start your virtualenv:
- Create a synced virtual environment, optionally specifying a Python version:

```console
source .venv/bin/activate
uv sync --python 3.12
```

- Create a branch for local development:
Expand All @@ -76,37 +81,57 @@ git clone [email protected]:your_name_here/{{ names.repo_title }}.git
```

- Make your changes locally
- Install development requirements:

- If you have added code that should be tested, add [tests](https://github.com/{{ config.repo_name }}/tree/master/tests).

- If you have modified dependencies in any way, make sure to run

```console
pip install -r test_requirements.txt
pip install -e .
uv sync
```

- When you're done making changes, check that your changes pass the
tests by running [pytest](https://docs.pytest.org/en/):
- Make sure you have added documentation for any additions or modifications to public functions or classes. You can build the documentation locally to make sure it renders correctly with:

```console
pytest tests
uvx --from poethepoet poe doc-build
```

Note that once you submit your pull request, GitHub Actions will run the tests also,
including on multiple operating systems and Python versions. Your pull request will
have to pass on all of these before it can be merged.
## Automated Checks

- Ensure your contribution meets style guidelines. First, install [ruff](https://docs.astral.sh/ruff/):
- Run the autoformatter:

```console
pip install ruff
uvx --from poethepoet poe lint-fix
```

- Fix linting and formatting. From the root of the repository, run the following commands:
- Ensure that your changes pass the checks that will be run on Github Actions, including building the documentation, checking the formatting of the code, and running the tests. To run all at once, do:

```console
ruff check . --extend-select I --fix
ruff format .
uvx --from poethepoet poe checks
```

- You may be interested in running some of these checks individually, such as:
- To run the tests:

```console
uvx --from poethepoet poe test
```

- To build the documentation:

```console
uvx --from poethepoet poe doc-build
```

- To run the linter

```console
uvx --from poethepoet poe lint
```

## Submitting a Pull Request

- Ensure your code has passed all of the tests described above.
- Commit your changes and push your branch to GitHub:

```console
Expand All @@ -117,22 +142,11 @@ git clone [email protected]:your_name_here/{{ names.repo_title }}.git

- [Submit a pull request](https://github.com/{{ config.repo_name }}/compare) through the GitHub website.

## Pull Request Guidelines

Before you submit a pull request, check that it meets these guidelines:

- The pull request should include tests if adding a new feature.
- The docs should be updated with whatever changes you have made. Put
your new functionality into a function with a docstring, and make sure the new
functionality is documented after building the documentation.

## Documentation style

We use [mkdocs](https://www.mkdocs.org/) to build the documentation. In particular, we
use the [mkdocs-material](https://squidfunk.github.io/mkdocs-material/) theme, and a
variety of other extensions.

!!! note
functionality is documented after building the documentation (described above).

More information codifying our documentation style and principles coming soon. For
now, just try to follow the style of the existing documentation.
- Once you submit a pull request, automated checks will run. You may require administrator approval before running these checks if this is your first time contributing to the repo.
8 changes: 5 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ maintainers = [{ name = "CAVE Developers" }]
name = "caveclient"
readme = "README.md"
requires-python = ">=3.9"
version = "7.3.2"
version = "7.4.0"

[project.urls]
Documentation = "https://caveconnectome.github.io/CAVEclient/"
Expand Down Expand Up @@ -62,7 +62,7 @@ test = ["pytest", "pytest-cov", "pytest-env", "pytest-mock", "responses"]
allow_dirty = false
commit = true
commit_args = ""
current_version = "7.3.2"
current_version = "7.4.0"
ignore_missing_version = false
message = "Bump version: {current_version} → {new_version}"
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
Expand Down Expand Up @@ -90,7 +90,9 @@ dry-bump = "uv run bump-my-version bump --dry-run --verbose"
lint = ['lint-check', 'lint-format']
lint-check = "uv run ruff check . --extend-select I"
lint-format = "uv run ruff format . --check"
test = "uv run pytest tests"
test = "uv run pytest --cov --cov-report xml tests"
lint-fix = "uv run ruff format caveclient tests"


[build-system]
build-backend = "hatchling.build"
Expand Down
Loading
Loading