pyobo 0.12.11__py3-none-any.whl → 0.12.13__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pyobo/api/xrefs.py CHANGED
@@ -9,7 +9,7 @@ import curies
9
9
  import pandas as pd
10
10
  from curies import ReferenceTuple
11
11
  from sssom_pydantic import SemanticMapping
12
- from sssom_pydantic.io import parse_record, parse_row
12
+ from sssom_pydantic.io import row_to_semantic_mapping
13
13
  from typing_extensions import Unpack
14
14
 
15
15
  from .utils import get_version_from_kwargs
@@ -124,12 +124,7 @@ def get_semantic_mappings(
124
124
  )
125
125
  if converter is None:
126
126
  converter = get_converter()
127
- rv = []
128
- for _, row in df.iterrows():
129
- record = parse_row(row.to_dict())
130
- mapping = parse_record(record, converter=converter)
131
- rv.append(mapping)
132
- return rv
127
+ return [row_to_semantic_mapping(row, converter=converter) for _, row in df.iterrows()]
133
128
 
134
129
 
135
130
  def get_mappings_df(
pyobo/cli/cli.py CHANGED
@@ -6,10 +6,7 @@ from collections.abc import Iterable
6
6
  from functools import lru_cache
7
7
  from operator import itemgetter
8
8
 
9
- import bioregistry
10
9
  import click
11
- import humanize
12
- from tabulate import tabulate
13
10
 
14
11
  from .database import main as database_main
15
12
  from .lookup import lookup
@@ -59,6 +56,9 @@ def clean(remove_obo: bool):
59
56
  @main.command()
60
57
  def ls():
61
58
  """List how big all of the OBO files are."""
59
+ import humanize
60
+ from tabulate import tabulate
61
+
62
62
  entries = [(prefix, os.path.getsize(path)) for prefix, path in _iter_cached_obo()]
63
63
  entries = [
64
64
  (prefix, humanize.naturalsize(size), "✅" if not has_nomenclature_plugin(prefix) else "❌")
@@ -69,6 +69,8 @@ def ls():
69
69
 
70
70
  def _iter_cached_obo() -> Iterable[tuple[str, str]]:
71
71
  """Iterate over cached OBO paths."""
72
+ import bioregistry
73
+
72
74
  for prefix in os.listdir(RAW_DIRECTORY):
73
75
  if prefix in GLOBAL_SKIP or _has_no_download(prefix) or bioregistry.is_deprecated(prefix):
74
76
  continue
@@ -83,6 +85,8 @@ def _iter_cached_obo() -> Iterable[tuple[str, str]]:
83
85
 
84
86
  def _has_no_download(prefix: str) -> bool:
85
87
  """Return if the prefix is not available."""
88
+ import bioregistry
89
+
86
90
  prefix_norm = bioregistry.normalize_prefix(prefix)
87
91
  return prefix_norm is not None and prefix_norm in _no_download()
88
92
 
@@ -90,6 +94,8 @@ def _has_no_download(prefix: str) -> bool:
90
94
  @lru_cache(maxsize=1)
91
95
  def _no_download() -> set[str]:
92
96
  """Get the list of prefixes not available as OBO."""
97
+ import bioregistry
98
+
93
99
  return {resource.prefix for resource in bioregistry.resources() if not resource.has_download()}
94
100
 
95
101
 
pyobo/cli/database.py CHANGED
@@ -5,29 +5,11 @@ import warnings
5
5
  from collections.abc import Iterable
6
6
  from pathlib import Path
7
7
 
8
- import bioregistry
9
- import bioversions
10
8
  import click
11
9
  from more_click import verbose_option
12
10
  from tqdm.contrib.logging import logging_redirect_tqdm
13
11
  from typing_extensions import Unpack
14
- from zenodo_client import update_zenodo
15
-
16
- from .database_utils import (
17
- IterHelperHelperDict,
18
- _iter_alts,
19
- _iter_definitions,
20
- _iter_edges,
21
- _iter_mappings,
22
- _iter_names,
23
- _iter_properties,
24
- _iter_relations,
25
- _iter_species,
26
- _iter_synonyms,
27
- _iter_typedefs,
28
- _iter_xrefs,
29
- iter_helper_helper,
30
- )
12
+
31
13
  from .utils import (
32
14
  Clickable,
33
15
  directory_option,
@@ -48,7 +30,6 @@ from ..constants import (
48
30
  TYPEDEFS_RECORD,
49
31
  DatabaseKwargs,
50
32
  )
51
- from ..getters import db_output_helper, get_ontology
52
33
 
53
34
  __all__ = [
54
35
  "main",
@@ -107,6 +88,8 @@ def build(ctx: click.Context, eager_versions: bool, **kwargs: Unpack[DatabaseKwa
107
88
  # sys.exit(1)
108
89
 
109
90
  if eager_versions:
91
+ import bioversions
92
+
110
93
  bioversions.get_rows(use_tqdm=True)
111
94
 
112
95
  with logging_redirect_tqdm():
@@ -143,6 +126,9 @@ def build(ctx: click.Context, eager_versions: bool, **kwargs: Unpack[DatabaseKwa
143
126
  @database_annotate
144
127
  def cache(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) -> None:
145
128
  """Cache all things."""
129
+ from .database_utils import iter_helper_helper
130
+ from ..getters import get_ontology
131
+
146
132
  if zenodo:
147
133
  click.echo("no zenodo for caching")
148
134
 
@@ -156,9 +142,13 @@ def cache(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) -> No
156
142
  @database_annotate
157
143
  def metadata(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) -> None:
158
144
  """Make the prefix-metadata dump."""
145
+ import bioregistry
146
+
147
+ from .database_utils import IterHelperHelperDict, iter_helper_helper
159
148
  from ..api import get_metadata
149
+ from ..getters import db_output_helper
160
150
 
161
- def _iter_metadata(
151
+ def _iter_metadata_internal(
162
152
  **kwargs: Unpack[IterHelperHelperDict],
163
153
  ) -> Iterable[tuple[str, str, str, bool]]:
164
154
  for prefix, data in iter_helper_helper(get_metadata, **kwargs):
@@ -166,7 +156,7 @@ def metadata(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) ->
166
156
  logger.debug(f"[{prefix}] using version {version}")
167
157
  yield prefix, version, data["date"], bioregistry.is_deprecated(prefix)
168
158
 
169
- it = _iter_metadata(**kwargs)
159
+ it = _iter_metadata_internal(**kwargs)
170
160
  db_output_helper(
171
161
  it,
172
162
  "metadata",
@@ -181,6 +171,9 @@ def metadata(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) ->
181
171
  @database_annotate
182
172
  def names(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) -> None:
183
173
  """Make the prefix-identifier-name dump."""
174
+ from .database_utils import _iter_names
175
+ from ..getters import db_output_helper
176
+
184
177
  it = _iter_names(**kwargs)
185
178
  with logging_redirect_tqdm():
186
179
  paths = db_output_helper(
@@ -190,6 +183,8 @@ def names(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) -> No
190
183
  directory=directory,
191
184
  )
192
185
  if zenodo:
186
+ from zenodo_client import update_zenodo
187
+
193
188
  # see https://zenodo.org/record/4020486
194
189
  update_zenodo(OOH_NA_NA_RECORD, paths)
195
190
 
@@ -197,6 +192,9 @@ def names(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) -> No
197
192
  @database_annotate
198
193
  def species(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) -> None:
199
194
  """Make the prefix-identifier-species dump."""
195
+ from .database_utils import _iter_species
196
+ from ..getters import db_output_helper
197
+
200
198
  with logging_redirect_tqdm():
201
199
  it = _iter_species(**kwargs)
202
200
  paths = db_output_helper(
@@ -206,6 +204,8 @@ def species(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) ->
206
204
  directory=directory,
207
205
  )
208
206
  if zenodo:
207
+ from zenodo_client import update_zenodo
208
+
209
209
  # see https://zenodo.org/record/5334738
210
210
  update_zenodo(SPECIES_RECORD, paths)
211
211
 
@@ -221,6 +221,9 @@ def _extend_skip_set(kwargs: DatabaseKwargs, skip_set: set[str]) -> None:
221
221
  @database_annotate
222
222
  def definitions(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) -> None:
223
223
  """Make the prefix-identifier-definition dump."""
224
+ from .database_utils import _iter_definitions
225
+ from ..getters import db_output_helper
226
+
224
227
  with logging_redirect_tqdm():
225
228
  _extend_skip_set(kwargs, {"kegg.pathway", "kegg.genes", "kegg.genome", "umls"})
226
229
  it = _iter_definitions(**kwargs)
@@ -231,6 +234,8 @@ def definitions(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs])
231
234
  directory=directory,
232
235
  )
233
236
  if zenodo:
237
+ from zenodo_client import update_zenodo
238
+
234
239
  # see https://zenodo.org/record/4637061
235
240
  update_zenodo(DEFINITIONS_RECORD, paths)
236
241
 
@@ -238,6 +243,9 @@ def definitions(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs])
238
243
  @database_annotate
239
244
  def typedefs(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) -> None:
240
245
  """Make the typedef prefix-identifier-name dump."""
246
+ from .database_utils import _iter_typedefs
247
+ from ..getters import db_output_helper
248
+
241
249
  with logging_redirect_tqdm():
242
250
  _extend_skip_set(kwargs, {"ncbigene", "kegg.pathway", "kegg.genes", "kegg.genome"})
243
251
  it = _iter_typedefs(**kwargs)
@@ -249,6 +257,8 @@ def typedefs(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) ->
249
257
  directory=directory,
250
258
  )
251
259
  if zenodo:
260
+ from zenodo_client import update_zenodo
261
+
252
262
  # see https://zenodo.org/record/4644013
253
263
  update_zenodo(TYPEDEFS_RECORD, paths)
254
264
 
@@ -256,6 +266,9 @@ def typedefs(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) ->
256
266
  @database_annotate
257
267
  def alts(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) -> None:
258
268
  """Make the prefix-alt-id dump."""
269
+ from .database_utils import _iter_alts
270
+ from ..getters import db_output_helper
271
+
259
272
  with logging_redirect_tqdm():
260
273
  _extend_skip_set(kwargs, {"kegg.pathway", "kegg.genes", "kegg.genome", "umls"})
261
274
  it = _iter_alts(**kwargs)
@@ -266,6 +279,8 @@ def alts(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) -> Non
266
279
  directory=directory,
267
280
  )
268
281
  if zenodo:
282
+ from zenodo_client import update_zenodo
283
+
269
284
  # see https://zenodo.org/record/4021476
270
285
  update_zenodo(ALTS_DATA_RECORD, paths)
271
286
 
@@ -273,6 +288,9 @@ def alts(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) -> Non
273
288
  @database_annotate
274
289
  def synonyms(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) -> None:
275
290
  """Make the prefix-identifier-synonym dump."""
291
+ from .database_utils import _iter_synonyms
292
+ from ..getters import db_output_helper
293
+
276
294
  with logging_redirect_tqdm():
277
295
  _extend_skip_set(kwargs, {"kegg.pathway", "kegg.genes", "kegg.genome"})
278
296
  it = _iter_synonyms(**kwargs)
@@ -283,6 +301,8 @@ def synonyms(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) ->
283
301
  directory=directory,
284
302
  )
285
303
  if zenodo:
304
+ from zenodo_client import update_zenodo
305
+
286
306
  # see https://zenodo.org/record/4021482
287
307
  update_zenodo(SYNONYMS_RECORD, paths)
288
308
 
@@ -290,6 +310,9 @@ def synonyms(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) ->
290
310
  @database_annotate
291
311
  def relations(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) -> None:
292
312
  """Make the relation dump."""
313
+ from .database_utils import _iter_relations
314
+ from ..getters import db_output_helper
315
+
293
316
  with logging_redirect_tqdm():
294
317
  it = _iter_relations(**kwargs)
295
318
  paths = db_output_helper(
@@ -307,6 +330,8 @@ def relations(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) -
307
330
  directory=directory,
308
331
  )
309
332
  if zenodo:
333
+ from zenodo_client import update_zenodo
334
+
310
335
  # see https://zenodo.org/record/4625167
311
336
  update_zenodo(RELATIONS_RECORD, paths)
312
337
 
@@ -314,6 +339,9 @@ def relations(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) -
314
339
  @database_annotate
315
340
  def edges(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) -> None:
316
341
  """Make the edges dump."""
342
+ from .database_utils import _iter_edges
343
+ from ..getters import db_output_helper
344
+
317
345
  with logging_redirect_tqdm():
318
346
  it = _iter_edges(**kwargs)
319
347
  db_output_helper(
@@ -334,6 +362,9 @@ def edges(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) -> No
334
362
  @database_annotate
335
363
  def properties(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) -> None:
336
364
  """Make the properties dump."""
365
+ from .database_utils import _iter_properties
366
+ from ..getters import db_output_helper
367
+
337
368
  with logging_redirect_tqdm():
338
369
  it = _iter_properties(**kwargs)
339
370
  paths = db_output_helper(
@@ -344,6 +375,8 @@ def properties(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs])
344
375
  directory=directory,
345
376
  )
346
377
  if zenodo:
378
+ from zenodo_client import update_zenodo
379
+
347
380
  # see https://zenodo.org/record/4625172
348
381
  update_zenodo(PROPERTIES_RECORD, paths)
349
382
 
@@ -351,6 +384,9 @@ def properties(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs])
351
384
  @database_annotate
352
385
  def xrefs(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) -> None:
353
386
  """Make the prefix-identifier-xref dump."""
387
+ from .database_utils import _iter_xrefs
388
+ from ..getters import db_output_helper
389
+
354
390
  warnings.warn("Use pyobo.database.mappings instead", DeprecationWarning, stacklevel=2)
355
391
  with logging_redirect_tqdm():
356
392
  it = _iter_xrefs(**kwargs)
@@ -362,6 +398,8 @@ def xrefs(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) -> No
362
398
  directory=directory,
363
399
  )
364
400
  if zenodo:
401
+ from zenodo_client import update_zenodo
402
+
365
403
  # see https://zenodo.org/record/4021477
366
404
  update_zenodo(JAVERT_RECORD, paths)
367
405
 
@@ -369,6 +407,9 @@ def xrefs(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) -> No
369
407
  @database_annotate
370
408
  def mappings(zenodo: bool, directory: Path, **kwargs: Unpack[DatabaseKwargs]) -> None:
371
409
  """Make the SSSOM dump."""
410
+ from .database_utils import _iter_mappings
411
+ from ..getters import db_output_helper
412
+
372
413
  columns = [
373
414
  "subject_id",
374
415
  "object_id",
pyobo/cli/lookup.py CHANGED
@@ -4,7 +4,6 @@ import json
4
4
  import sys
5
5
  from collections.abc import Mapping
6
6
 
7
- import bioregistry
8
7
  import click
9
8
  from more_click import verbose_option
10
9
  from typing_extensions import Unpack
@@ -18,30 +17,7 @@ from .utils import (
18
17
  strict_option,
19
18
  version_option,
20
19
  )
21
- from ..api import (
22
- get_ancestors,
23
- get_descendants,
24
- get_filtered_properties_df,
25
- get_filtered_relations_df,
26
- get_filtered_xrefs,
27
- get_hierarchy,
28
- get_id_definition_mapping,
29
- get_id_name_mapping,
30
- get_id_species_mapping,
31
- get_id_synonyms_mapping,
32
- get_id_to_alts,
33
- get_ids,
34
- get_mappings_df,
35
- get_metadata,
36
- get_name,
37
- get_properties_df,
38
- get_relations_df,
39
- get_typedef_df,
40
- get_xrefs_df,
41
- )
42
20
  from ..constants import LookupKwargs
43
- from ..getters import get_ontology
44
- from ..struct.reference import _parse_str_or_curie_or_uri
45
21
 
46
22
  __all__ = [
47
23
  "lookup",
@@ -75,6 +51,10 @@ identifier_option = click.option("-i", "--identifier")
75
51
  @click.option("-t", "--target")
76
52
  def xrefs(target: str, **kwargs: Unpack[LookupKwargs]) -> None:
77
53
  """Page through xrefs for the given namespace to the second given namespace."""
54
+ import bioregistry
55
+
56
+ from ..api import get_filtered_xrefs, get_xrefs_df
57
+
78
58
  if target:
79
59
  target_norm = bioregistry.normalize_prefix(target)
80
60
  filtered_xrefs = get_filtered_xrefs(xref_prefix=target_norm, **kwargs)
@@ -91,6 +71,10 @@ def xrefs(target: str, **kwargs: Unpack[LookupKwargs]) -> None:
91
71
  @click.option("-t", "--target")
92
72
  def mappings(include_names: bool, target: str | None, **kwargs: Unpack[LookupKwargs]) -> None:
93
73
  """Page through mappings for the given namespace."""
74
+ import bioregistry
75
+
76
+ from ..api import get_mappings_df
77
+
94
78
  mappings_df = get_mappings_df(names=include_names, **kwargs)
95
79
  if target:
96
80
  target_norm = bioregistry.normalize_prefix(target)
@@ -106,6 +90,8 @@ def mappings(include_names: bool, target: str | None, **kwargs: Unpack[LookupKwa
106
90
  @lookup_annotate
107
91
  def metadata(**kwargs: Unpack[LookupKwargs]) -> None:
108
92
  """Print the metadata for the given namespace."""
93
+ from ..api import get_metadata
94
+
109
95
  metadata = get_metadata(**kwargs)
110
96
  click.echo(json.dumps(metadata, indent=2))
111
97
 
@@ -113,6 +99,8 @@ def metadata(**kwargs: Unpack[LookupKwargs]) -> None:
113
99
  @lookup_annotate
114
100
  def ids(**kwargs: Unpack[LookupKwargs]) -> None:
115
101
  """Page through the identifiers of entities in the given namespace."""
102
+ from ..api import get_ids
103
+
116
104
  id_list = get_ids(**kwargs)
117
105
  if not id_list:
118
106
  click.secho("no data", fg="red")
@@ -124,6 +112,8 @@ def ids(**kwargs: Unpack[LookupKwargs]) -> None:
124
112
  @identifier_option
125
113
  def names(identifier: str | None, **kwargs: Unpack[LookupKwargs]) -> None:
126
114
  """Page through the identifiers and names of entities in the given namespace."""
115
+ from ..api import get_id_name_mapping
116
+
127
117
  id_to_name = get_id_name_mapping(**kwargs)
128
118
  _help_page_mapping(id_to_name, identifier=identifier)
129
119
 
@@ -132,6 +122,8 @@ def names(identifier: str | None, **kwargs: Unpack[LookupKwargs]) -> None:
132
122
  @identifier_option
133
123
  def species(identifier: str | None, **kwargs: Unpack[LookupKwargs]) -> None:
134
124
  """Page through the identifiers and species of entities in the given namespace."""
125
+ from ..api import get_id_species_mapping
126
+
135
127
  id_to_species = get_id_species_mapping(**kwargs)
136
128
  _help_page_mapping(id_to_species, identifier=identifier)
137
129
 
@@ -140,6 +132,8 @@ def species(identifier: str | None, **kwargs: Unpack[LookupKwargs]) -> None:
140
132
  @identifier_option
141
133
  def definitions(identifier: str | None, **kwargs: Unpack[LookupKwargs]) -> None:
142
134
  """Page through the identifiers and definitions of entities in the given namespace."""
135
+ from ..api import get_id_definition_mapping
136
+
143
137
  id_to_definition = get_id_definition_mapping(**kwargs)
144
138
  _help_page_mapping(id_to_definition, identifier=identifier)
145
139
 
@@ -147,6 +141,8 @@ def definitions(identifier: str | None, **kwargs: Unpack[LookupKwargs]) -> None:
147
141
  @lookup_annotate
148
142
  def typedefs(**kwargs: Unpack[LookupKwargs]) -> None:
149
143
  """Page through the identifiers and names of typedefs in the given namespace."""
144
+ from ..api import get_typedef_df
145
+
150
146
  df = get_typedef_df(**kwargs)
151
147
  echo_df(df)
152
148
 
@@ -168,6 +164,8 @@ def _help_page_mapping(id_to_name: Mapping[str, str], *, identifier: str | None
168
164
  @identifier_option
169
165
  def synonyms(identifier: str | None, **kwargs: Unpack[LookupKwargs]) -> None:
170
166
  """Page through the synonyms for entities in the given namespace."""
167
+ from ..api import get_id_synonyms_mapping
168
+
171
169
  id_to_synonyms = get_id_synonyms_mapping(**kwargs)
172
170
  if identifier is None:
173
171
  click.echo_via_pager(
@@ -198,6 +196,11 @@ def relations(
198
196
  **kwargs: Unpack[LookupKwargs],
199
197
  ) -> None:
200
198
  """Page through the relations for entities in the given namespace."""
199
+ import bioregistry
200
+
201
+ from ..api import get_filtered_relations_df, get_relations_df
202
+ from ..struct.reference import _parse_str_or_curie_or_uri
203
+
201
204
  if relation is None:
202
205
  relations_df = get_relations_df(**kwargs)
203
206
  if summarize:
@@ -232,6 +235,8 @@ def hierarchy(
232
235
  **kwargs: Unpack[LookupKwargs],
233
236
  ) -> None:
234
237
  """Page through the hierarchy for entities in the namespace."""
238
+ from ..api import get_hierarchy
239
+
235
240
  h = get_hierarchy(
236
241
  include_part_of=include_part_of,
237
242
  include_has_member=include_has_member,
@@ -250,6 +255,8 @@ def ancestors(
250
255
  **kwargs: Unpack[LookupKwargs],
251
256
  ) -> None:
252
257
  """Look up ancestors."""
258
+ from ..api import get_ancestors, get_name
259
+
253
260
  # note, prefix is passed via kwargs
254
261
  ancestors = get_ancestors(identifier=identifier, **kwargs)
255
262
  for ancestor in sorted(ancestors or []):
@@ -263,6 +270,8 @@ def descendants(
263
270
  **kwargs: Unpack[LookupKwargs],
264
271
  ) -> None:
265
272
  """Look up descendants."""
273
+ from ..api import get_descendants, get_name
274
+
266
275
  # note, prefix is passed via kwargs
267
276
  descendants = get_descendants(identifier=identifier, **kwargs)
268
277
  for descendant in sorted(descendants or []):
@@ -276,6 +285,8 @@ def properties(
276
285
  **kwargs: Unpack[LookupKwargs],
277
286
  ) -> None:
278
287
  """Page through the properties for entities in the given namespace."""
288
+ from ..api import get_filtered_properties_df, get_properties_df
289
+
279
290
  if key is None:
280
291
  properties_df = get_properties_df(**kwargs)
281
292
  else:
@@ -290,6 +301,8 @@ def alts(
290
301
  **kwargs: Unpack[LookupKwargs],
291
302
  ) -> None:
292
303
  """Page through alt ids in a namespace."""
304
+ from ..api import get_id_to_alts
305
+
293
306
  id_to_alts = get_id_to_alts(**kwargs)
294
307
  _help_page_mapping(id_to_alts, identifier=identifier)
295
308
 
@@ -297,6 +310,8 @@ def alts(
297
310
  @lookup_annotate
298
311
  def prefixes(**kwargs: Unpack[LookupKwargs]) -> None:
299
312
  """Page through prefixes appearing in an ontology."""
313
+ from ..getters import get_ontology
314
+
300
315
  ontology = get_ontology(**kwargs)
301
316
  for prefix in sorted(ontology._get_prefixes(), key=str.casefold):
302
317
  click.echo(prefix)
pyobo/cli/utils.py CHANGED
@@ -1,15 +1,19 @@
1
1
  """Utilities for the CLI."""
2
2
 
3
+ from __future__ import annotations
4
+
3
5
  import datetime
4
6
  import pathlib
5
7
  from collections.abc import Callable
6
- from typing import TypeVar
8
+ from typing import TYPE_CHECKING, TypeVar
7
9
 
8
10
  import click
9
- import pandas as pd
10
11
 
11
12
  from ..constants import DATABASE_DIRECTORY
12
13
 
14
+ if TYPE_CHECKING:
15
+ import pandas as pd
16
+
13
17
  __all__ = [
14
18
  "Clickable",
15
19
  "directory_option",
pyobo/constants.py CHANGED
@@ -8,7 +8,6 @@ from collections.abc import Callable
8
8
  from pathlib import Path
9
9
  from typing import Literal, NamedTuple, TypeAlias
10
10
 
11
- import bioregistry
12
11
  import pystow
13
12
  from typing_extensions import NotRequired, TypedDict
14
13
 
@@ -247,11 +246,35 @@ class OntologyPathPack(NamedTuple):
247
246
  path: Path
248
247
 
249
248
 
249
+ def _get_obo_download(prefix: str) -> str | None:
250
+ import bioregistry
251
+
252
+ return bioregistry.get_obo_download(prefix)
253
+
254
+
255
+ def _get_owl_download(prefix: str) -> str | None:
256
+ import bioregistry
257
+
258
+ return bioregistry.get_owl_download(prefix)
259
+
260
+
261
+ def _get_json_download(prefix: str) -> str | None:
262
+ import bioregistry
263
+
264
+ return bioregistry.get_json_download(prefix)
265
+
266
+
267
+ def _get_rdf_download(prefix: str) -> str | None:
268
+ import bioregistry
269
+
270
+ return bioregistry.get_rdf_download(prefix)
271
+
272
+
250
273
  #: Functions that get ontology files. Order matters in this list,
251
274
  #: since order implicitly defines priority
252
275
  ONTOLOGY_GETTERS: list[tuple[OntologyFormat, Callable[[str], str | None]]] = [
253
- ("obo", bioregistry.get_obo_download),
254
- ("owl", bioregistry.get_owl_download),
255
- ("json", bioregistry.get_json_download),
256
- ("rdf", bioregistry.get_rdf_download),
276
+ ("obo", _get_obo_download),
277
+ ("owl", _get_owl_download),
278
+ ("json", _get_json_download),
279
+ ("rdf", _get_rdf_download),
257
280
  ]
pyobo/ner/api.py CHANGED
@@ -32,6 +32,7 @@ def get_grounder(
32
32
  grounder_cls: type[gilda.Grounder] | None = None,
33
33
  versions: None | str | Iterable[str | None] | dict[str, str] = None,
34
34
  skip_obsolete: bool = False,
35
+ raise_on_missing: bool = False,
35
36
  **kwargs: Unpack[GetOntologyKwargs],
36
37
  ) -> ssslm.Grounder:
37
38
  """Get a grounder for the given prefix(es)."""
@@ -46,6 +47,8 @@ def get_grounder(
46
47
  continue
47
48
  else:
48
49
  if not literal_mappings:
50
+ if raise_on_missing:
51
+ raise ValueError(f"no literal mappings were loaded for {prefix}")
49
52
  logger.warning("[%s] no literal mappings loaded", prefix)
50
53
  all_literal_mappings.extend(literal_mappings)
51
54
 
@@ -227,6 +227,8 @@ def get_scispacy_entities(prefix: str, **kwargs: Unpack[GetOntologyKwargs]) -> I
227
227
  # TODO reuse labels, synonyms, and definitions cache
228
228
  ontology = get_ontology(prefix, **kwargs)
229
229
  for term in ontology:
230
+ if not term.name or term.prefix != ontology.ontology:
231
+ continue
230
232
  yield Entity(
231
233
  concept_id=term.curie,
232
234
  canonical_name=term.name,
pyobo/plugins.py CHANGED
@@ -4,8 +4,10 @@ from __future__ import annotations
4
4
 
5
5
  from collections.abc import Callable, Iterable, Mapping
6
6
  from functools import lru_cache
7
+ from typing import TYPE_CHECKING
7
8
 
8
- from .struct import Obo
9
+ if TYPE_CHECKING:
10
+ from .struct import Obo
9
11
 
10
12
  __all__ = [
11
13
  "has_nomenclature_plugin",
pyobo/sources/chebi.py CHANGED
@@ -3,7 +3,7 @@
3
3
  from collections.abc import Mapping
4
4
 
5
5
  from ..api import get_filtered_properties_mapping, get_filtered_relations_df
6
- from ..struct import Reference, TypeDef
6
+ from ..struct.typedef import has_role
7
7
  from ..utils.io import multisetdict
8
8
 
9
9
  __all__ = [
@@ -28,9 +28,6 @@ def get_chebi_smiles_id_mapping() -> Mapping[str, str]:
28
28
  return {v: k for k, v in get_chebi_id_smiles_mapping().items()}
29
29
 
30
30
 
31
- has_role = TypeDef(reference=Reference(prefix="chebi", identifier="has_role"))
32
-
33
-
34
31
  def get_chebi_role_to_children() -> Mapping[str, set[tuple[str, str]]]:
35
32
  """Get the ChEBI role to children mapping."""
36
33
  df = get_filtered_relations_df("chebi", relation=has_role)
@@ -345,7 +345,7 @@ def _get_terms(
345
345
  _process_equivalent_to(term, data, ontology_prefix=ontology_prefix, strict=strict)
346
346
  _process_disjoint_from(term, data, ontology_prefix=ontology_prefix, strict=strict)
347
347
  _process_consider(term, data, ontology_prefix=ontology_prefix, strict=strict)
348
- _process_comment(term, data, ontology_prefix=ontology_prefix, strict=strict)
348
+ _process_comment(term, data)
349
349
  _process_description(term, data, ontology_prefix=ontology_prefix, strict=strict)
350
350
  _process_creation_date(term, data)
351
351
 
@@ -367,7 +367,7 @@ def _process_description(term: Stanza, data, *, ontology_prefix: str, strict: bo
367
367
  )
368
368
 
369
369
 
370
- def _process_comment(term: Stanza, data, *, ontology_prefix: str, strict: bool) -> None:
370
+ def _process_comment(term: Stanza, data) -> None:
371
371
  if comment := data.get("comment"):
372
372
  term.append_comment(comment)
373
373
 
@@ -902,7 +902,7 @@ def iterate_typedefs(
902
902
  _process_equivalent_to(typedef, data, ontology_prefix=ontology_prefix, strict=strict)
903
903
  _process_disjoint_from(typedef, data, ontology_prefix=ontology_prefix, strict=strict)
904
904
  _process_consider(typedef, data, ontology_prefix=ontology_prefix, strict=strict)
905
- _process_comment(typedef, data, ontology_prefix=ontology_prefix, strict=strict)
905
+ _process_comment(typedef, data)
906
906
  _process_description(typedef, data, ontology_prefix=ontology_prefix, strict=strict)
907
907
  _process_creation_date(typedef, data)
908
908
 
@@ -1020,6 +1020,8 @@ def _format_obo_trailing_modifiers(
1020
1020
  right = f'"{obo_escape_slim(value)}"'
1021
1021
  else:
1022
1022
  right = value
1023
+ case _:
1024
+ raise TypeError(f"invalid prop value: {type(prop.value)} - {prop.value}")
1023
1025
  modifiers.append((left, right))
1024
1026
  inner = ", ".join(f"{key}={value}" for key, value in modifiers)
1025
1027
  return " {" + inner + "}"
pyobo/struct/typedef.py CHANGED
@@ -18,6 +18,7 @@ __all__ = [
18
18
  "contributes_to_condition",
19
19
  "default_typedefs",
20
20
  "derives_from_organism",
21
+ "directly_regulates_activity_of",
21
22
  "editor_note",
22
23
  "enables",
23
24
  "ends",
@@ -26,6 +27,7 @@ __all__ = [
26
27
  "from_species",
27
28
  "gene_product_member_of",
28
29
  "has_contributor",
30
+ "has_creator",
29
31
  "has_dbxref",
30
32
  "has_depiction",
31
33
  "has_end_date",
@@ -45,15 +47,20 @@ __all__ = [
45
47
  "has_successor",
46
48
  "has_taxonomy_rank",
47
49
  "is_a",
50
+ "is_agonist_of",
51
+ "is_antagonist_of",
52
+ "is_inverse_agonist_of",
48
53
  "located_in",
49
54
  "mapping_has_confidence",
50
55
  "mapping_has_justification",
51
56
  "match_typedefs",
52
57
  "member_of",
53
58
  "narrow_match",
59
+ "negatively_regulates",
54
60
  "orthologous",
55
61
  "part_of",
56
62
  "participates_in",
63
+ "positively_regulates",
57
64
  "related_match",
58
65
  "role_of",
59
66
  "see_also",
@@ -266,6 +273,19 @@ has_functional_parent = TypeDef(
266
273
  reference=Reference(prefix="ro", identifier="0018038", name="has functional parent"),
267
274
  )
268
275
 
276
+ positively_regulates = TypeDef(
277
+ Reference(prefix="RO", identifier="0002213", name="positively regulates")
278
+ )
279
+ negatively_regulates = TypeDef(
280
+ Reference(prefix="RO", identifier="0002212", name="negatively regulates")
281
+ )
282
+ is_agonist_of = TypeDef.from_triple("RO", "0018027", "is agonist of")
283
+ is_inverse_agonist_of = TypeDef.from_triple("RO", "0018028", "is inverse agonist of")
284
+ is_antagonist_of = TypeDef.from_triple("RO", "0018029", "is antagonist of")
285
+ directly_regulates_activity_of = TypeDef.from_triple(
286
+ "RO", "0002448", "directly regulates activity of"
287
+ )
288
+
269
289
  is_mentioned_by = TypeDef(
270
290
  reference=v.is_mentioned_by,
271
291
  is_metadata_tag=True,
@@ -319,6 +339,8 @@ has_end_date = TypeDef(
319
339
 
320
340
  has_title = TypeDef(reference=v.has_title, is_metadata_tag=True)
321
341
  has_license = TypeDef(reference=v.has_license, is_metadata_tag=True)
342
+ has_creator = TypeDef(reference=v.has_creator, is_metadata_tag=True)
343
+
322
344
  has_description = TypeDef(reference=v.has_description, is_metadata_tag=True)
323
345
  obo_autogenerated_by = TypeDef(reference=v.obo_autogenerated_by, is_metadata_tag=True)
324
346
  obo_has_format_version = TypeDef(reference=v.obo_has_format_version, is_metadata_tag=True)
@@ -41,6 +41,7 @@ mapping_has_justification = Reference(
41
41
  )
42
42
  mapping_has_confidence = Reference(prefix="sssom", identifier="confidence", name="has confidence")
43
43
  has_contributor = _c(_v.has_contributor)
44
+ has_creator = Reference(prefix="dcterms", identifier="creator", name="creator")
44
45
  has_source = _c(_v.has_source)
45
46
  has_date = _c(_v.has_date)
46
47
  has_dbxref = _c(_v.has_dbxref)
@@ -89,6 +90,7 @@ mentions = Reference(prefix="mito", identifier="mentions", name="mentions")
89
90
 
90
91
  has_description = _c(_v.has_description)
91
92
  has_license = _c(_v.has_license)
93
+ has_license = _c(_v.has_license)
92
94
  has_title = _c(_v.has_title)
93
95
 
94
96
  has_homepage = Reference(prefix="foaf", identifier="homepage", name="has homepage")
pyobo/version.py CHANGED
@@ -12,7 +12,7 @@ __all__ = [
12
12
  "get_version",
13
13
  ]
14
14
 
15
- VERSION = "0.12.11"
15
+ VERSION = "0.12.13"
16
16
 
17
17
 
18
18
  def get_git_hash() -> str:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyobo
3
- Version: 0.12.11
3
+ Version: 0.12.13
4
4
  Summary: A python package for handling and generating OBO
5
5
  Keywords: snekpack,cookiecutter,ontologies,biomedical ontologies,life sciences,natural sciences,bioinformatics,cheminformatics,Open Biomedical Ontologies,OBO
6
6
  Author: Charles Tapley Hoyt
@@ -55,7 +55,7 @@ Requires-Dist: nih-reporter-downloader>=0.0.1
55
55
  Requires-Dist: typing-extensions
56
56
  Requires-Dist: rdflib
57
57
  Requires-Dist: obographs>=0.0.8
58
- Requires-Dist: sssom-pydantic
58
+ Requires-Dist: sssom-pydantic>=0.1.1
59
59
  Requires-Dist: psycopg2-binary ; extra == 'drugcentral'
60
60
  Requires-Dist: ssslm[gilda] ; extra == 'gilda'
61
61
  Requires-Dist: ssslm[gilda-slim] ; extra == 'gilda-slim'
@@ -523,20 +523,6 @@ Alternatively, install using pip:
523
523
  $ python3 -m pip install -e .
524
524
  ```
525
525
 
526
- ### Updating Package Boilerplate
527
-
528
- This project uses `cruft` to keep boilerplate (i.e., configuration, contribution
529
- guidelines, documentation configuration) up-to-date with the upstream
530
- cookiecutter package. Install cruft with either `uv tool install cruft` or
531
- `python3 -m pip install cruft` then run:
532
-
533
- ```console
534
- $ cruft update
535
- ```
536
-
537
- More info on Cruft's update command is available
538
- [here](https://github.com/cruft/cruft?tab=readme-ov-file#updating-a-project).
539
-
540
526
  ### 🥼 Testing
541
527
 
542
528
  After cloning the repository and installing `tox` with
@@ -574,8 +560,21 @@ only that Sphinx can build the documentation in an isolated environment (i.e.,
574
560
  with `tox -e docs-test`) but also that
575
561
  [ReadTheDocs can build it too](https://docs.readthedocs.io/en/stable/pull-requests.html).
576
562
 
563
+ </details>
564
+
565
+ ## 🧑‍💻 For Maintainers
566
+
567
+ <details>
568
+ <summary>See maintainer instructions</summary>
569
+
570
+ ### Initial Configuration
571
+
577
572
  #### Configuring ReadTheDocs
578
573
 
574
+ [ReadTheDocs](https://readthedocs.org) is an external documentation hosting
575
+ service that integrates with GitHub's CI/CD. Do the following for each
576
+ repository:
577
+
579
578
  1. Log in to ReadTheDocs with your GitHub account to install the integration at
580
579
  https://readthedocs.org/accounts/login/?next=/dashboard/
581
580
  2. Import your project by navigating to https://readthedocs.org/dashboard/import
@@ -584,12 +583,10 @@ with `tox -e docs-test`) but also that
584
583
  (i.e., with spaces and capital letters)
585
584
  4. Click next, and you're good to go!
586
585
 
587
- ### 📦 Making a Release
588
-
589
- #### Configuring Zenodo
586
+ #### Configuring Archival on Zenodo
590
587
 
591
588
  [Zenodo](https://zenodo.org) is a long-term archival system that assigns a DOI
592
- to each release of your package.
589
+ to each release of your package. Do the following for each repository:
593
590
 
594
591
  1. Log in to Zenodo via GitHub with this link:
595
592
  https://zenodo.org/oauth/login/github/?next=%2F. This brings you to a page
@@ -609,10 +606,10 @@ the DOI for the release and link to the Zenodo record for it.
609
606
 
610
607
  #### Registering with the Python Package Index (PyPI)
611
608
 
612
- You only have to do the following steps once.
609
+ The [Python Package Index (PyPI)](https://pypi.org) hosts packages so they can
610
+ be easily installed with `pip`, `uv`, and equivalent tools.
613
611
 
614
- 1. Register for an account on the
615
- [Python Package Index (PyPI)](https://pypi.org/account/register)
612
+ 1. Register for an account [here](https://pypi.org/account/register)
616
613
  2. Navigate to https://pypi.org/manage/account and make sure you have verified
617
614
  your email address. A verification email might not have been sent by default,
618
615
  so you might have to click the "options" dropdown next to your address to get
@@ -623,9 +620,11 @@ You only have to do the following steps once.
623
620
  2-factor authentication
624
621
  4. Issue an API token from https://pypi.org/manage/account/token
625
622
 
623
+ This only needs to be done once per developer.
624
+
626
625
  #### Configuring your machine's connection to PyPI
627
626
 
628
- You have to do the following steps once per machine.
627
+ This needs to be done once per machine.
629
628
 
630
629
  ```console
631
630
  $ uv tool install keyring
@@ -635,6 +634,8 @@ $ keyring set https://test.pypi.org/legacy/ __token__
635
634
 
636
635
  Note that this deprecates previous workflows using `.pypirc`.
637
636
 
637
+ ### 📦 Making a Release
638
+
638
639
  #### Uploading to PyPI
639
640
 
640
641
  After installing the package in development mode and installing `tox` with
@@ -672,4 +673,18 @@ This script does the following:
672
673
 
673
674
  This will trigger Zenodo to assign a DOI to your release as well.
674
675
 
676
+ ### Updating Package Boilerplate
677
+
678
+ This project uses `cruft` to keep boilerplate (i.e., configuration, contribution
679
+ guidelines, documentation configuration) up-to-date with the upstream
680
+ cookiecutter package. Install cruft with either `uv tool install cruft` or
681
+ `python3 -m pip install cruft` then run:
682
+
683
+ ```console
684
+ $ cruft update
685
+ ```
686
+
687
+ More info on Cruft's update command is available
688
+ [here](https://github.com/cruft/cruft?tab=readme-ov-file#updating-a-project).
689
+
675
690
  </details>
@@ -14,14 +14,14 @@ pyobo/api/relations.py,sha256=Kebguj5khScU2c0Pm8dJrewu8je9DnKlNenRtmYWGKI,5875
14
14
  pyobo/api/species.py,sha256=YxzJeClfuKI-pjYLpu5797jdDeyTkXpjQDgdmc9MKwo,2376
15
15
  pyobo/api/typedefs.py,sha256=HTui0kl_VELxgji0vfBr-NBG3zrrpCU8tmuQOSWK6fw,1262
16
16
  pyobo/api/utils.py,sha256=SCMsy4QyYVhn-QK0h90Ef1XUMbyHKR1fvteRESzs-bk,5192
17
- pyobo/api/xrefs.py,sha256=oQ7D2p9mrzb-LtLkXlJ_LYRArs5eqq9Zwwx9_0Yov_o,6053
17
+ pyobo/api/xrefs.py,sha256=szsPOMwkKmfDRb7CNgyEoe7hRQK8aX1Vm6Vcz0FYN2w,5956
18
18
  pyobo/cli/__init__.py,sha256=pTiLuzjjpi0P69yVjQ2kE6nBUmZuYFnqdJNDZLDkgvk,71
19
- pyobo/cli/cli.py,sha256=5bY_7ZVZOoHwhZtCxx-AYL5ybyBzjS65NU5v5X9DsLA,2842
20
- pyobo/cli/database.py,sha256=grPVG1d78yhog5lvEAu3wwHkBASKhtmabwmvx49WRIc,12121
19
+ pyobo/cli/cli.py,sha256=lyN_Hi5Hf2jyCUXjD87pG7RU3g7TnbBiOd8o-PMqIEw,2904
20
+ pyobo/cli/database.py,sha256=iq4-eJ_8Kgim0MMnSqf1wu2hvHDZk9BWNMVuwykz2Ko,13407
21
21
  pyobo/cli/database_utils.py,sha256=jQ7qSg-oZk-Q-RC121NkUbqXeNg0K8fV96igXaK3ra4,5540
22
- pyobo/cli/lookup.py,sha256=GxG753GXnDRf-N9JRWKRmQC5XiN8fEN5l1le5C3jHHY,9163
23
- pyobo/cli/utils.py,sha256=nmtXsxG0TWEIjjIe-jh_aqzr09bTN7-NHFifuHGzME0,1738
24
- pyobo/constants.py,sha256=vqaf3xj0Sv39PETE3PJuuZ5SZTpoprsngKOzwpca1CU,7129
22
+ pyobo/cli/lookup.py,sha256=-Tz6E3OP6HBPipVqSrMn7LyzrezbT0pngeDExF5uyn4,9467
23
+ pyobo/cli/utils.py,sha256=SfW9JC8olzp4AcAsDodMPdgHfteeXq0Ngd8yQ2kzOMA,1812
24
+ pyobo/constants.py,sha256=K3d8gjfty6zVc3nUBX32oVQX7tzFxnEkGCO1THlC5Qw,7564
25
25
  pyobo/getters.py,sha256=exZNjlseRoWhshQYArWwN2KLvkk4NmCQnHM88YUYf-w,18340
26
26
  pyobo/gilda_utils.py,sha256=uThAArALSNzJi-hrR9lUvtQci5VIw4Cqq2L6mtkp0Ko,1990
27
27
  pyobo/identifier_utils/__init__.py,sha256=iSHAZhOwqWZmYpOfpXNLuKouSYj7ZSViaX7BF5uT8so,793
@@ -34,10 +34,10 @@ pyobo/identifier_utils/relations/data_rdf.json,sha256=T1PNoYwrqgwDVLtfmj7L5e0Sq0
34
34
  pyobo/identifier_utils/relations/data_rdfs.json,sha256=bjpxZte3g4WvrGJsmHuAJN_cg_faxqIa9tCL7auHdqQ,86
35
35
  pyobo/mocks.py,sha256=j545K9P_DPsDBuYHDrhyTLjmlPoNlRdEtcRlLhXlbXI,2440
36
36
  pyobo/ner/__init__.py,sha256=7Os84d8_gZktUxyUW9Tn2dW33rYFWSO8cviJJef-ZeE,373
37
- pyobo/ner/api.py,sha256=dy51kXQbfx7C8ZIwxlsu78HjsdYtdgdkbF0KuaDJoG4,2396
37
+ pyobo/ner/api.py,sha256=a_wMpzIbRdBeK3UaMsklzL44T4Q7a9gtV3tzDrqBEX0,2555
38
38
  pyobo/ner/normalizer.py,sha256=pdvwFG9elriK83FKqjQfT2s-ZuC-QZZuMPudjfay21w,954
39
- pyobo/ner/scispacy_utils.py,sha256=4NRGJ1JJB-OmlVthHhyms1iPMwJYrkVMQP1jgZfJ18U,8170
40
- pyobo/plugins.py,sha256=wEr-NpyZ7Z6uEr0uGDNOeXLOGZokGbFmo3e-z2PNKJM,1232
39
+ pyobo/ner/scispacy_utils.py,sha256=13oQi4R5ikbg3xkzU0L46zno-Acq3BtjdtLm5eiBKjw,8253
40
+ pyobo/plugins.py,sha256=DJFJ3Eogb0snTUz22w6I56Yn2Ys0OOXK1dJJgzpyCOM,1287
41
41
  pyobo/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
42
  pyobo/resource_utils.py,sha256=bloSKbHfMLz0hB8AkhMkfLOGqw6FyO8CEU6LNg0PVMk,4406
43
43
  pyobo/resources/__init__.py,sha256=Q9nik7HgpICCON7GEKpbw3z9ZIM7NFJwoGNpepkn2nA,38
@@ -59,7 +59,7 @@ pyobo/sources/bigg/bigg_reaction.py,sha256=45SIIae32GtDxzL_gpF7p1TKVfh6t3UgHpF4f
59
59
  pyobo/sources/biogrid.py,sha256=dYl6Pt3YpND2cvTl5LIAekWyJpclf7R1JvFJUT9XH9A,3297
60
60
  pyobo/sources/ccle.py,sha256=Fn1tY1YHHyZj6mlqg8ISMGUYG4o6W5MeeO7l_KlLmos,2924
61
61
  pyobo/sources/cgnc.py,sha256=XlwqqjJc7B97352-AgaRo8lazXnKf__JVV4ldfGJl1Q,2299
62
- pyobo/sources/chebi.py,sha256=-f_XyBLOHoC2uGqu8UzQ3HgAlbqAhm7-AUve0HK0TOA,1202
62
+ pyobo/sources/chebi.py,sha256=1ESngeNgenO4DwMD0YFgRIQx6LLndqT0JS4lLhQTRCk,1119
63
63
  pyobo/sources/chembl/__init__.py,sha256=mfqYGDIjoUj66ooq2AUvzX2DLFheSdSsvwyKt9pLonY,414
64
64
  pyobo/sources/chembl/chembl_cell.py,sha256=q-O7wJyOT2bjtqN5-0d2gEkJr0R-ULKHvt6843j8gVA,2669
65
65
  pyobo/sources/chembl/chembl_compound.py,sha256=Ds9axuT1uO-9L3lQnEpr_8JdWo-mDNWJv9hTWG9WXsk,1888
@@ -184,7 +184,7 @@ pyobo/struct/functional/obo_to_functional.py,sha256=65OmttFto-tm6-7T0RQlgIKo34sw
184
184
  pyobo/struct/functional/ontology.py,sha256=-a8jx-61NsI3dgCBEYNP-VeswAy8wWxLBlAEFMJucyI,9342
185
185
  pyobo/struct/functional/utils.py,sha256=c-XG2SJ7ChYtz7KU3K0F-T6ocMjYevei0WxlkfkkmtE,3487
186
186
  pyobo/struct/obo/__init__.py,sha256=xJAFJ4yueWBQv3BrtTuHHJ7AzOqCgOuHgKY4RQocsW0,157
187
- pyobo/struct/obo/reader.py,sha256=fzh1YiNblhmA4rfehOO37WmCfi2r5I4R72ubWwmK4eE,50799
187
+ pyobo/struct/obo/reader.py,sha256=HJ4u1c2ScA-2qxKhyKIZZo8RI2QOUSXwushK9FZGdrQ,50664
188
188
  pyobo/struct/obo/reader_utils.py,sha256=UyQVTQhXbhZ9fCizZg26o5TmeHis9-qZMKvQFwIBRgo,4423
189
189
  pyobo/struct/obograph/__init__.py,sha256=B4rNP9OCTnMXm8YpQ0rar1swn4GIw9b4gQD-IVuqHyw,452
190
190
  pyobo/struct/obograph/export.py,sha256=yk3MHulDM_SMohfwiFdeB62-XGJ2ZNgRUZGjGjiyonY,9945
@@ -192,10 +192,10 @@ pyobo/struct/obograph/reader.py,sha256=264yVeD8a3jGx9EaGUZVxFbSQ_pwQ_6ckVw9S8wiJ
192
192
  pyobo/struct/obograph/utils.py,sha256=je0kSkC24MU9pWRHq1_K-J5jWhjWESY6NI3TpZqvZ_Q,1516
193
193
  pyobo/struct/reference.py,sha256=qgwTa-0VIoDklQ7LjlYH-mf2WG0_uO7KlHt0PSBail4,11744
194
194
  pyobo/struct/struct.py,sha256=-JaApTZ7e50bRJ2dXPdAVuJ0ElIVJIJ-HHRsVdaiMxM,96291
195
- pyobo/struct/struct_utils.py,sha256=tqaUOYKfM3NAa9NfIrWUbaEFJuSOi05_fXPh1cNMY2w,40911
196
- pyobo/struct/typedef.py,sha256=X5eDKtFsuXXbmFxAS3GxNHQaES5s6UyowAI7_c8Qcao,13364
195
+ pyobo/struct/struct_utils.py,sha256=VFC82fgphTs7sBSNGn53sv2WMl7Ho9srALFq92bRFQQ,41021
196
+ pyobo/struct/typedef.py,sha256=LGDfJPAiTdp4PZPHUMgvhLsJrOZMIaGSBHA2oh8uCuU,14188
197
197
  pyobo/struct/utils.py,sha256=zkpOE42JQIfkN0rc5qNENK03VIKmkf_57tHojMJK71Y,906
198
- pyobo/struct/vocabulary.py,sha256=87VqrkU1BrarSW4C2sVbe3qnkn-4jwztCOrnBXy5Ujs,5262
198
+ pyobo/struct/vocabulary.py,sha256=wY_wlV17NyoPQZMiCkf72GL4bIB9gwTHIoMlx7W8Cf4,5375
199
199
  pyobo/utils/__init__.py,sha256=CANSY8vGq_6v8rWhWRIdnk-Wo5LA2R9Wjg1nqbWqLOw,17
200
200
  pyobo/utils/cache.py,sha256=x7Dnw8vHYsoslXWiV9L9ZdTu5ZueIR1ki5Ncdpb7H10,3136
201
201
  pyobo/utils/io.py,sha256=QTvGjNDkaIf78Tca23B5RW_aVweKiSsxmgwSKXcMSNo,3921
@@ -203,9 +203,9 @@ pyobo/utils/iter.py,sha256=rYRbbaFJHxMaE0yU-rQZoCagYIrtev09uY0mxFkf5zY,1524
203
203
  pyobo/utils/misc.py,sha256=499pencyDqW9_xm0H0Cq0FhOw0MoNoq-9IVQTKh-eaE,7992
204
204
  pyobo/utils/ndex_utils.py,sha256=EokCWS00Wrk_4y8ldeQuUyaaC6yNzBg3DagUl-J2czY,2326
205
205
  pyobo/utils/path.py,sha256=snV58UHxHO6GI2QPPE46ssR4RWozaw83V59sS_I9BY8,4109
206
- pyobo/version.py,sha256=v0j2YjxitLkr27imJK-XFpLZk5UCOkggapvETMVWd4I,927
207
- pyobo-0.12.11.dist-info/licenses/LICENSE,sha256=QcgJZKGxlW5BwBNnCBL8VZLVtRvXs81Ch9lJRQSIpJg,1076
208
- pyobo-0.12.11.dist-info/WHEEL,sha256=Pi5uDq5Fdo_Rr-HD5h9BiPn9Et29Y9Sh8NhcJNnFU1c,79
209
- pyobo-0.12.11.dist-info/entry_points.txt,sha256=ANgzvuwF_9_1ipCoxJtbBM6A4i2Mkt39gMPzQO6hvGs,42
210
- pyobo-0.12.11.dist-info/METADATA,sha256=pUsxtOFil50llmHEkOeZi_NcSwly-ezHUMZyZ1EJ2YM,22340
211
- pyobo-0.12.11.dist-info/RECORD,,
206
+ pyobo/version.py,sha256=-3azDhk7QGSEF_6hXZvXJhIqE9utObgNlX9avQrhAtI,927
207
+ pyobo-0.12.13.dist-info/licenses/LICENSE,sha256=QcgJZKGxlW5BwBNnCBL8VZLVtRvXs81Ch9lJRQSIpJg,1076
208
+ pyobo-0.12.13.dist-info/WHEEL,sha256=YUH1mBqsx8Dh2cQG2rlcuRYUhJddG9iClegy4IgnHik,79
209
+ pyobo-0.12.13.dist-info/entry_points.txt,sha256=ANgzvuwF_9_1ipCoxJtbBM6A4i2Mkt39gMPzQO6hvGs,42
210
+ pyobo-0.12.13.dist-info/METADATA,sha256=RiVfL9jxKk1n8rRSTO4BdCbWMLDZOJF_Qb_ZJU94u_s,22783
211
+ pyobo-0.12.13.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: uv 0.8.17
2
+ Generator: uv 0.9.11
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any