From a587044dd7a6eb44a34473cf66a9fd8ccfe7a588 Mon Sep 17 00:00:00 2001 From: Robbie Court Date: Tue, 14 Jul 2026 10:56:20 +0100 Subject: [PATCH] Offer part-in/synaptic queries on all neural regions; page NeuronsSynaptic Term-info menu gates were tied to the old XMI 'Class + Synaptic_neuropil' takes, so ganglion-level neural regions (e.g. adult cerebrum FBbt_00007050) missed queries that do return results there: - ImagesNeurons (Images of neurons with some part in): now mirrors NeuronsPartHere (Class + not Neuron + (Synaptic_neuropil OR Anatomy)); returns 154,993 for adult cerebrum. - NeuronsSynaptic / NeuronsPresynapticHere / NeuronsPostsynapticHere: now Class + not Neuron + Nervous_system (superset of the old Synaptic_neuropil / Visual_system / Synaptic_neuropil_domain gate, adds ganglia). The OWL query (RO_0002130 some ) returns 8,716 neuron classes for adult cerebrum. Paging: - get_neurons_with_synapses_in_cached lacked an offset param while the query is in PAGED_QUERY_FUNCS and the underlying get_neurons_with_synapses_in takes offset -> 500 'unexpected keyword argument offset'. Add offset and forward it (mirrors the pre/post-synaptic cached wrappers). - ha_api _call now defensively drops offset/limit and retries once if a target does not declare them, so no query can 500 on paging kwargs even if a wrapper is missed. Bump 1.22.26 -> 1.22.27. --- src/vfbquery/_version.py | 2 +- src/vfbquery/cached_functions.py | 4 ++-- src/vfbquery/ha_api.py | 19 ++++++++++++++++--- src/vfbquery/vfb_queries.py | 22 +++++----------------- 4 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/vfbquery/_version.py b/src/vfbquery/_version.py index cce251a..901dd64 100644 --- a/src/vfbquery/_version.py +++ b/src/vfbquery/_version.py @@ -6,4 +6,4 @@ cache's version stamp can never drift apart. """ -__version__ = "1.22.26" +__version__ = "1.22.27" diff --git a/src/vfbquery/cached_functions.py b/src/vfbquery/cached_functions.py index 08930d4..36245f3 100644 --- a/src/vfbquery/cached_functions.py +++ b/src/vfbquery/cached_functions.py @@ -253,7 +253,7 @@ def get_neurons_with_part_in_cached(short_form: str, return_dataframe=True, limi """ return _original_get_neurons_with_part_in(short_form=short_form, return_dataframe=return_dataframe, limit=limit, offset=offset, force_refresh=force_refresh) -def get_neurons_with_synapses_in_cached(short_form: str, return_dataframe=True, limit: int = -1, force_refresh: bool = False): +def get_neurons_with_synapses_in_cached(short_form: str, return_dataframe=True, limit: int = -1, offset: int = 0, force_refresh: bool = False): """ Enhanced get_neurons_with_synapses_in with SOLR caching. @@ -265,7 +265,7 @@ def get_neurons_with_synapses_in_cached(short_form: str, return_dataframe=True, Returns: Neurons with synapses in the specified anatomical structure """ - return _original_get_neurons_with_synapses_in(short_form=short_form, return_dataframe=return_dataframe, limit=limit, force_refresh=force_refresh) + return _original_get_neurons_with_synapses_in(short_form=short_form, return_dataframe=return_dataframe, limit=limit, offset=offset, force_refresh=force_refresh) def get_neurons_with_presynaptic_terminals_in_cached(short_form: str, return_dataframe=True, limit: int = -1, offset: int = 0, force_refresh: bool = False): """ diff --git a/src/vfbquery/ha_api.py b/src/vfbquery/ha_api.py index 7e5e1c6..4408255 100644 --- a/src/vfbquery/ha_api.py +++ b/src/vfbquery/ha_api.py @@ -422,9 +422,22 @@ def _run_query(short_form, func_name, force_refresh=False, offset=0, limit=0): # inner function ever gets force_refresh as an unexpected kwarg. def _call(extra=None): kw = {**base_kwargs, **(extra or {})} - if func_name == "get_all_datasets": - return fn(**kw) - return fn(short_form, **kw) + def _invoke(kwargs): + if func_name == "get_all_datasets": + return fn(**kwargs) + return fn(short_form, **kwargs) + try: + return _invoke(kw) + except TypeError as e: + # Belt-and-braces: a target that does not declare offset/limit (e.g. + # a cached wrapper not yet updated) must not 500 -- drop the paging + # kwargs and retry once. Real paging targets never hit this. + msg = str(e) + if ("offset" in msg or "limit" in msg) and ("offset" in kw or "limit" in kw): + stripped = {k: v for k, v in kw.items() if k not in ("offset", "limit")} + log.warning("_run_query: %s does not accept paging kwargs (%s); retrying without offset/limit.", func_name, e) + return _invoke(stripped) + raise if force_refresh: try: diff --git a/src/vfbquery/vfb_queries.py b/src/vfbquery/vfb_queries.py index 0a20c7b..4f4de3a 100644 --- a/src/vfbquery/vfb_queries.py +++ b/src/vfbquery/vfb_queries.py @@ -1064,31 +1064,19 @@ def term_info_parse_object(results, short_form): # NeuronsSynaptic query - for synaptic neuropils and visual systems # Matches XMI criteria: Class + (Synaptic_neuropil OR Visual_system OR Synaptic_neuropil_domain) - if contains_all_tags(termInfo["SuperTypes"], ["Class"]) and ( - "Synaptic_neuropil" in termInfo["SuperTypes"] or - "Visual_system" in termInfo["SuperTypes"] or - "Synaptic_neuropil_domain" in termInfo["SuperTypes"] - ): + if contains_all_tags(termInfo["SuperTypes"], ["Class"]) and "Neuron" not in termInfo["SuperTypes"] and "Nervous_system" in termInfo["SuperTypes"]: q = NeuronsSynaptic_to_schema(termInfo["Name"], {"short_form": vfbTerm.term.core.short_form}) queries.append(q) # NeuronsPresynapticHere query - for synaptic neuropils and visual systems # Matches XMI criteria: Class + (Synaptic_neuropil OR Visual_system OR Synaptic_neuropil_domain) - if contains_all_tags(termInfo["SuperTypes"], ["Class"]) and ( - "Synaptic_neuropil" in termInfo["SuperTypes"] or - "Visual_system" in termInfo["SuperTypes"] or - "Synaptic_neuropil_domain" in termInfo["SuperTypes"] - ): + if contains_all_tags(termInfo["SuperTypes"], ["Class"]) and "Neuron" not in termInfo["SuperTypes"] and "Nervous_system" in termInfo["SuperTypes"]: q = NeuronsPresynapticHere_to_schema(termInfo["Name"], {"short_form": vfbTerm.term.core.short_form}) queries.append(q) # NeuronsPostsynapticHere query - for synaptic neuropils and visual systems # Matches XMI criteria: Class + (Synaptic_neuropil OR Visual_system OR Synaptic_neuropil_domain) - if contains_all_tags(termInfo["SuperTypes"], ["Class"]) and ( - "Synaptic_neuropil" in termInfo["SuperTypes"] or - "Visual_system" in termInfo["SuperTypes"] or - "Synaptic_neuropil_domain" in termInfo["SuperTypes"] - ): + if contains_all_tags(termInfo["SuperTypes"], ["Class"]) and "Neuron" not in termInfo["SuperTypes"] and "Nervous_system" in termInfo["SuperTypes"]: q = NeuronsPostsynapticHere_to_schema(termInfo["Name"], {"short_form": vfbTerm.term.core.short_form}) queries.append(q) @@ -1150,9 +1138,9 @@ def term_info_parse_object(results, short_form): # ImagesNeurons query - for synaptic neuropils # Matches XMI criteria: Class + (Synaptic_neuropil OR Synaptic_neuropil_domain) # Returns individual neuron images (instances) rather than neuron classes - if contains_all_tags(termInfo["SuperTypes"], ["Class"]) and ( + if contains_all_tags(termInfo["SuperTypes"], ["Class"]) and "Neuron" not in termInfo["SuperTypes"] and ( "Synaptic_neuropil" in termInfo["SuperTypes"] or - "Synaptic_neuropil_domain" in termInfo["SuperTypes"] + "Anatomy" in termInfo["SuperTypes"] ): q = ImagesNeurons_to_schema(termInfo["Name"], {"short_form": vfbTerm.term.core.short_form}) queries.append(q)