pyobo 0.10.8__py3-none-any.whl → 0.10.9__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/hierarchy.py CHANGED
@@ -168,14 +168,15 @@ def is_descendent(prefix, identifier, ancestor_prefix, ancestor_identifier) -> b
168
168
  @lru_cache()
169
169
  def get_descendants(
170
170
  prefix: str,
171
- identifier: str,
171
+ identifier: Optional[str] = None,
172
172
  include_part_of: bool = True,
173
173
  include_has_member: bool = False,
174
174
  use_tqdm: bool = False,
175
175
  force: bool = False,
176
176
  **kwargs,
177
177
  ) -> Optional[Set[str]]:
178
- """Get all of the descendants (children) of the term as CURIEs."""
178
+ """Get all the descendants (children) of the term as CURIEs."""
179
+ curie, prefix, identifier = _pic(prefix, identifier)
179
180
  hierarchy = get_hierarchy(
180
181
  prefix=prefix,
181
182
  include_has_member=include_has_member,
@@ -184,23 +185,32 @@ def get_descendants(
184
185
  force=force,
185
186
  **kwargs,
186
187
  )
187
- curie = f"{prefix}:{identifier}"
188
188
  if curie not in hierarchy:
189
189
  return None
190
190
  return nx.ancestors(hierarchy, curie) # note this is backwards
191
191
 
192
192
 
193
+ def _pic(prefix, identifier=None) -> Tuple[str, str, str]:
194
+ if identifier is None:
195
+ curie = prefix
196
+ prefix, identifier = prefix.split(":")
197
+ else:
198
+ curie = f"{prefix}:{identifier}"
199
+ return curie, prefix, identifier
200
+
201
+
193
202
  @lru_cache()
194
203
  def get_children(
195
204
  prefix: str,
196
- identifier: str,
205
+ identifier: Optional[str] = None,
197
206
  include_part_of: bool = True,
198
207
  include_has_member: bool = False,
199
208
  use_tqdm: bool = False,
200
209
  force: bool = False,
201
210
  **kwargs,
202
211
  ) -> Optional[Set[str]]:
203
- """Get all of the descendants (children) of the term as CURIEs."""
212
+ """Get all the descendants (children) of the term as CURIEs."""
213
+ curie, prefix, identifier = _pic(prefix, identifier)
204
214
  hierarchy = get_hierarchy(
205
215
  prefix=prefix,
206
216
  include_has_member=include_has_member,
@@ -209,7 +219,6 @@ def get_children(
209
219
  force=force,
210
220
  **kwargs,
211
221
  )
212
- curie = f"{prefix}:{identifier}"
213
222
  if curie not in hierarchy:
214
223
  return None
215
224
  return set(hierarchy.predecessors(curie))
@@ -228,14 +237,15 @@ def has_ancestor(prefix, identifier, ancestor_prefix, ancestor_identifier) -> bo
228
237
  @lru_cache()
229
238
  def get_ancestors(
230
239
  prefix: str,
231
- identifier: str,
240
+ identifier: Optional[str] = None,
232
241
  include_part_of: bool = True,
233
242
  include_has_member: bool = False,
234
243
  use_tqdm: bool = False,
235
244
  force: bool = False,
236
245
  **kwargs,
237
246
  ) -> Optional[Set[str]]:
238
- """Get all of the ancestors (parents) of the term as CURIEs."""
247
+ """Get all the ancestors (parents) of the term as CURIEs."""
248
+ curie, prefix, identifier = _pic(prefix, identifier)
239
249
  hierarchy = get_hierarchy(
240
250
  prefix=prefix,
241
251
  include_has_member=include_has_member,
@@ -244,7 +254,6 @@ def get_ancestors(
244
254
  force=force,
245
255
  **kwargs,
246
256
  )
247
- curie = f"{prefix}:{identifier}"
248
257
  if curie not in hierarchy:
249
258
  return None
250
259
  return nx.descendants(hierarchy, curie) # note this is backwards
@@ -252,7 +261,7 @@ def get_ancestors(
252
261
 
253
262
  def get_subhierarchy(
254
263
  prefix: str,
255
- identifier: str,
264
+ identifier: Optional[str] = None,
256
265
  include_part_of: bool = True,
257
266
  include_has_member: bool = False,
258
267
  use_tqdm: bool = False,
@@ -260,6 +269,7 @@ def get_subhierarchy(
260
269
  **kwargs,
261
270
  ) -> nx.DiGraph:
262
271
  """Get the subhierarchy for a given node."""
272
+ curie, prefix, identifier = _pic(prefix, identifier)
263
273
  hierarchy = get_hierarchy(
264
274
  prefix=prefix,
265
275
  include_has_member=include_has_member,
@@ -271,7 +281,7 @@ def get_subhierarchy(
271
281
  logger.info(
272
282
  "getting descendants of %s:%s ! %s", prefix, identifier, get_name(prefix, identifier)
273
283
  )
274
- curies = nx.ancestors(hierarchy, f"{prefix}:{identifier}") # note this is backwards
284
+ curies = nx.ancestors(hierarchy, curie) # note this is backwards
275
285
  logger.info("inducing subgraph")
276
286
  sg = hierarchy.subgraph(curies).copy()
277
287
  logger.info("subgraph has %d nodes/%d edges", sg.number_of_nodes(), sg.number_of_edges())
pyobo/api/xrefs.py CHANGED
@@ -142,7 +142,9 @@ def get_sssom_df(
142
142
  df = get_xrefs_df(prefix=prefix, **kwargs)
143
143
  rows: List[Tuple[str, ...]] = []
144
144
  with logging_redirect_tqdm():
145
- for source_id, target_prefix, target_id in tqdm(df.values, unit="mapping", unit_scale=True):
145
+ for source_id, target_prefix, target_id in tqdm(
146
+ df.values, unit="mapping", unit_scale=True, desc=f"[{prefix}] SSSOM"
147
+ ):
146
148
  source = Reference(prefix=prefix, identifier=source_id)
147
149
  target = Reference(prefix=target_prefix, identifier=target_id)
148
150
 
pyobo/getters.py CHANGED
@@ -55,7 +55,7 @@ class UnhandledFormat(NoBuild):
55
55
 
56
56
  #: The following prefixes can not be loaded through ROBOT without
57
57
  #: turning off integrity checks
58
- REQUIRES_NO_ROBOT_CHECK = {"clo", "vo"}
58
+ REQUIRES_NO_ROBOT_CHECK = {"clo", "vo", "orphanet.ordo", "orphanet"}
59
59
 
60
60
 
61
61
  @wrap_norm_prefix
@@ -117,7 +117,7 @@ def get_ontology(
117
117
 
118
118
  ontology_format, path = _ensure_ontology_path(prefix, force=force, version=version)
119
119
  if path is None:
120
- raise NoBuild
120
+ raise NoBuild(prefix)
121
121
  elif ontology_format == "obo":
122
122
  pass # all gucci
123
123
  elif ontology_format == "owl":
pyobo/sources/__init__.py CHANGED
@@ -8,6 +8,7 @@ from .antibodyregistry import AntibodyRegistryGetter
8
8
  from .ccle import CCLEGetter
9
9
  from .cgnc import CGNCGetter
10
10
  from .chembl import ChEMBLCompoundGetter
11
+ from .civic_gene import CIVICGeneGetter
11
12
  from .complexportal import ComplexPortalGetter
12
13
  from .conso import CONSOGetter
13
14
  from .cpt import CPTGetter
@@ -38,6 +39,7 @@ from .mirbase_mature import MiRBaseMatureGetter
38
39
  from .msigdb import MSigDBGetter
39
40
  from .ncbigene import NCBIGeneGetter
40
41
  from .npass import NPASSGetter
42
+ from .omim_ps import OMIMPSGetter
41
43
  from .pathbank import PathBankGetter
42
44
  from .pfam import PfamGetter
43
45
  from .pfam_clan import PfamClanGetter
@@ -61,6 +63,7 @@ __all__ = [
61
63
  "AntibodyRegistryGetter",
62
64
  "CCLEGetter",
63
65
  "CGNCGetter",
66
+ "CIVICGeneGetter",
64
67
  "CONSOGetter",
65
68
  "CPTGetter",
66
69
  "CVXGetter",
@@ -94,6 +97,7 @@ __all__ = [
94
97
  "MiRBaseMatureGetter",
95
98
  "NCBIGeneGetter",
96
99
  "NPASSGetter",
100
+ "OMIMPSGetter",
97
101
  "PIDGetter",
98
102
  "PathBankGetter",
99
103
  "PfamClanGetter",
pyobo/sources/cgnc.py CHANGED
@@ -69,7 +69,7 @@ def get_terms(force: bool = False) -> Iterable[Term]:
69
69
  term = Term.from_triple(
70
70
  prefix=PREFIX,
71
71
  identifier=cgnc_id,
72
- name=name,
72
+ name=name if pd.notna(name) else None,
73
73
  )
74
74
  term.set_species(identifier="9031", name="Gallus gallus")
75
75
  if entrez_id and pd.notna(entrez_id):
@@ -0,0 +1,55 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ """Converter for CiVIC Genes."""
4
+
5
+ from typing import Iterable, Optional
6
+
7
+ import pandas as pd
8
+
9
+ from pyobo.struct import Obo, Reference, Term
10
+ from pyobo.utils.path import ensure_df
11
+
12
+ __all__ = [
13
+ "CIVICGeneGetter",
14
+ ]
15
+
16
+ PREFIX = "civic.gid"
17
+ URL = "https://civicdb.org/downloads/nightly/nightly-GeneSummaries.tsv"
18
+
19
+
20
+ def _sort(_o, t):
21
+ return int(t.identifier)
22
+
23
+
24
+ class CIVICGeneGetter(Obo):
25
+ """An ontology representation of CiVIC's gene nomenclature."""
26
+
27
+ bioversions_key = ontology = PREFIX
28
+ term_sort_key = _sort
29
+
30
+ def iter_terms(self, force: bool = False) -> Iterable[Term]:
31
+ """Iterate over gene terms for CiVIC."""
32
+ yield from get_terms(self.data_version, force=force)
33
+
34
+
35
+ def get_terms(version: Optional[str] = None, force: bool = False) -> Iterable[Term]:
36
+ """Get CIVIC terms."""
37
+ # if version is not None:
38
+ # version_dt: datetime.date = dateutil.parser.parse(version)
39
+ # else:
40
+ # version_dt: datetime.date = datetime.today()
41
+ # version = version_dt.strftime("01-%b-%Y")
42
+ # version is like 01-Feb-2024
43
+ url = f"https://civicdb.org/downloads/{version}/{version}-GeneSummaries.tsv"
44
+ df = ensure_df(prefix=PREFIX, url=url, sep="\t", force=force, dtype=str, version=version)
45
+ for identifier, _, name, entrez_id, description, _last_review, _flag in df.values:
46
+ term = Term(
47
+ reference=Reference(prefix=PREFIX, identifier=identifier, name=name),
48
+ definition=description if pd.notna(description) else None,
49
+ )
50
+ term.append_exact_match(Reference(prefix="ncbigene", identifier=entrez_id))
51
+ yield term
52
+
53
+
54
+ if __name__ == "__main__":
55
+ CIVICGeneGetter.cli()
pyobo/sources/mesh.py CHANGED
@@ -6,7 +6,7 @@ import datetime
6
6
  import itertools as itt
7
7
  import logging
8
8
  import re
9
- from typing import Any, Dict, Iterable, List, Mapping, Optional, Set, Tuple
9
+ from typing import Any, Collection, Dict, Iterable, List, Mapping, Optional, Set, Tuple
10
10
  from xml.etree.ElementTree import Element
11
11
 
12
12
  from tqdm.auto import tqdm
@@ -19,6 +19,7 @@ from pyobo.utils.path import ensure_path, prefix_directory_join
19
19
 
20
20
  __all__ = [
21
21
  "MeSHGetter",
22
+ "get_mesh_category_curies",
22
23
  ]
23
24
 
24
25
  logger = logging.getLogger(__name__)
@@ -317,5 +318,32 @@ def _get_descriptor_qualifiers(descriptor: Element) -> List[Mapping[str, str]]:
317
318
  ]
318
319
 
319
320
 
321
+ def get_mesh_category_curies(letter: str, skip: Optional[Collection[str]] = None) -> List[str]:
322
+ """Get the MeSH LUIDs for a category, by letter (e.g., "A").
323
+
324
+ :param letter: The MeSH tree, A for anatomy, C for disease, etc.
325
+ :param skip: An optional collection of MeSH tree codes to skip, such as "A03"
326
+ :returns: A list of MeSH CURIE strings for the top level of each MeSH tree.
327
+
328
+ .. seealso:: https://meshb.nlm.nih.gov/treeView
329
+ """
330
+ import bioversions
331
+
332
+ mesh_version = bioversions.get_version("mesh")
333
+ if mesh_version is None:
334
+ raise ValueError
335
+ tree_to_mesh = get_tree_to_mesh_id(mesh_version)
336
+ rv = []
337
+ for i in range(1, 100):
338
+ key = f"{letter}{i:02}"
339
+ if skip and key in skip:
340
+ continue
341
+ mesh_id = tree_to_mesh.get(key)
342
+ if mesh_id is None:
343
+ break
344
+ rv.append(f"mesh:{mesh_id}")
345
+ return rv
346
+
347
+
320
348
  if __name__ == "__main__":
321
349
  get_obo(force=True).write_default(force=True, write_obo=True)
pyobo/sources/ncbigene.py CHANGED
@@ -171,15 +171,17 @@ def get_terms(force: bool = False) -> Iterable[Term]:
171
171
  continue
172
172
  term = Term(
173
173
  reference=Reference(prefix=PREFIX, identifier=gene_id, name=symbol),
174
- definition=description,
174
+ definition=description if pd.notna(description) else None,
175
175
  )
176
176
  term.set_species(identifier=tax_id)
177
177
  if pd.notna(xref_curies):
178
178
  for xref_curie in xref_curies.split("|"):
179
179
  if xref_curie.startswith("EnsemblRapid"):
180
180
  continue
181
- if xref_curie.startswith("AllianceGenome"):
181
+ elif xref_curie.startswith("AllianceGenome"):
182
182
  xref_curie = xref_curie[len("xref_curie") :]
183
+ elif xref_curie.startswith("nome:WB:"):
184
+ xref_curie = xref_curie[len("nome:") :]
183
185
  xref_prefix, xref_id = bioregistry.parse_curie(xref_curie)
184
186
  if xref_prefix and xref_id:
185
187
  term.append_xref(Reference(prefix=xref_prefix, identifier=xref_id))
@@ -187,7 +189,7 @@ def get_terms(force: bool = False) -> Iterable[Term]:
187
189
  p = xref_curie.split(":")[0]
188
190
  if p not in warning_prefixes:
189
191
  warning_prefixes.add(p)
190
- tqdm.write(f"[{PREFIX}] unhandled xref prefix: {p}")
192
+ tqdm.write(f"[{PREFIX}] unhandled prefix in xref: {xref_curie}")
191
193
  yield term
192
194
 
193
195
 
@@ -0,0 +1,39 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ """Converter for OMIM Phenotypic Series."""
4
+
5
+ import logging
6
+ from typing import Iterable
7
+
8
+ from bioversions.utils import get_soup
9
+
10
+ from pyobo.struct import Obo, Term
11
+
12
+ __all__ = [
13
+ "OMIMPSGetter",
14
+ ]
15
+
16
+
17
+ logger = logging.getLogger(__name__)
18
+ PREFIX = "omim.ps"
19
+ URL = "https://omim.org/phenotypicSeriesTitles/all"
20
+
21
+
22
+ class OMIMPSGetter(Obo):
23
+ """An ontology representation of OMIM Phenotypic Series."""
24
+
25
+ ontology = bioversions_key = PREFIX
26
+
27
+ def iter_terms(self, force: bool = False) -> Iterable[Term]:
28
+ """Iterate over terms in the ontology."""
29
+ soup = get_soup(URL, user_agent="Mozilla/5.0")
30
+ rows = soup.find(id="mimContent").find("table").find("tbody").find_all("tr")
31
+ for row in rows:
32
+ anchor = row.find("td").find("a")
33
+ name = anchor.text.strip()
34
+ identifier = anchor.attrs["href"][len("/phenotypicSeries/") :]
35
+ yield Term.from_triple(PREFIX, identifier, name)
36
+
37
+
38
+ if __name__ == "__main__":
39
+ OMIMPSGetter.cli()
@@ -7,12 +7,13 @@ Run with ``python -m pyobo.sources.umls``
7
7
 
8
8
  import itertools as itt
9
9
  import operator
10
- from typing import Iterable
10
+ from collections import defaultdict
11
+ from typing import Iterable, Mapping, Set
11
12
 
12
13
  import bioregistry
13
14
  import pandas as pd
14
15
  from tqdm.auto import tqdm
15
- from umls_downloader import open_umls
16
+ from umls_downloader import open_umls, open_umls_semantic_types
16
17
 
17
18
  from pyobo import Obo, Reference, Synonym, SynonymTypeDef, Term
18
19
 
@@ -66,8 +67,20 @@ def get_obo() -> Obo:
66
67
  return UMLSGetter()
67
68
 
68
69
 
70
+ def get_semantic_types() -> Mapping[str, Set[str]]:
71
+ """Get UMLS semantic types for each term."""
72
+ dd = defaultdict(set)
73
+ with open_umls_semantic_types() as file:
74
+ for line in tqdm(file, unit_scale=True):
75
+ cui, sty, _ = line.decode("utf8").split("|", 2)
76
+ dd[cui].add(sty)
77
+ return dict(dd)
78
+
79
+
69
80
  def iter_terms(version: str) -> Iterable[Term]:
70
81
  """Iterate over UMLS terms."""
82
+ semantic_types = get_semantic_types()
83
+
71
84
  with open_umls(version=version) as file:
72
85
  it = tqdm(file, unit_scale=True, desc="[umls] parsing")
73
86
  lines = (line.decode("utf-8").strip().split("|") for line in it)
@@ -118,6 +131,8 @@ def iter_terms(version: str) -> Iterable[Term]:
118
131
  synonyms=synonyms,
119
132
  xrefs=xrefs,
120
133
  )
134
+ for sty_id in semantic_types.get(cui, set()):
135
+ term.append_parent(Reference(prefix="sty", identifier=sty_id))
121
136
  yield term
122
137
 
123
138
 
@@ -2,8 +2,9 @@
2
2
 
3
3
  """Converter for UniProt."""
4
4
 
5
+ from operator import attrgetter
5
6
  from pathlib import Path
6
- from typing import Iterable, Optional
7
+ from typing import Iterable, List, Optional, cast
7
8
 
8
9
  import bioversions
9
10
  from tqdm.auto import tqdm
@@ -11,22 +12,52 @@ from tqdm.auto import tqdm
11
12
  from pyobo import Obo, Reference
12
13
  from pyobo.constants import RAW_MODULE
13
14
  from pyobo.identifier_utils import standardize_ec
14
- from pyobo.struct import Term, enables, from_species
15
+ from pyobo.struct import Term, derives_from, enables, from_species, participates_in
16
+ from pyobo.struct.typedef import gene_product_of, located_in, molecularly_interacts_with
15
17
  from pyobo.utils.io import open_reader
16
18
 
17
19
  PREFIX = "uniprot"
18
- REVIEWED_URL = (
19
- "https://rest.uniprot.org/uniprotkb/stream?compressed=true"
20
- "&fields=accession%2Cid%2Corganism_id%2Cprotein_name%2Cec%2Clit_pubmed_id%2Cxref_pdb"
21
- "&format=tsv&query=%28%2A%29%20AND%20%28reviewed%3Atrue%29"
22
- )
20
+ BASE_URL = "https://rest.uniprot.org/uniprotkb/stream"
21
+ SEARCH_URL = "https://rest.uniprot.org/uniprotkb/search"
22
+ QUERY = "(*) AND (reviewed:true)"
23
+ FIELDS = [
24
+ "accession",
25
+ "id",
26
+ "organism_id",
27
+ "protein_name",
28
+ "ec",
29
+ "lit_pubmed_id",
30
+ "xref_pdb",
31
+ "xref_proteomes",
32
+ "xref_geneid",
33
+ "rhea",
34
+ "go_c",
35
+ "go_f",
36
+ "go_p",
37
+ "ft_binding",
38
+ "cc_function",
39
+ ]
40
+ PARAMS = {
41
+ "compressed": "true",
42
+ "format": "tsv",
43
+ # "size": 10, # only used with search
44
+ "query": QUERY,
45
+ "fields": FIELDS,
46
+ }
23
47
 
24
48
 
25
49
  class UniProtGetter(Obo):
26
50
  """An ontology representation of the UniProt database."""
27
51
 
28
52
  bioversions_key = ontology = PREFIX
29
- typedefs = [from_species, enables]
53
+ typedefs = [
54
+ from_species,
55
+ enables,
56
+ participates_in,
57
+ gene_product_of,
58
+ molecularly_interacts_with,
59
+ derives_from,
60
+ ]
30
61
 
31
62
  def iter_terms(self, force: bool = False) -> Iterable[Term]:
32
63
  """Iterate over terms in the ontology."""
@@ -42,13 +73,73 @@ def iter_terms(version: Optional[str] = None) -> Iterable[Term]:
42
73
  """Iterate over UniProt Terms."""
43
74
  with open_reader(ensure(version=version)) as reader:
44
75
  _ = next(reader) # header
45
- for uniprot_id, name, taxonomy_id, _synonyms, ecs, pubmeds, pdbs in tqdm(
46
- reader, desc="Mapping UniProt", unit_scale=True
47
- ):
48
- term = Term.from_triple(prefix=PREFIX, identifier=uniprot_id, name=name)
49
- # TODO add gene encodes from relationship
50
- # TODO add description
76
+ for (
77
+ uniprot_id,
78
+ accession,
79
+ taxonomy_id,
80
+ _name, # this field should have the name, but it's a mismatch of random name annotations
81
+ ecs,
82
+ pubmeds,
83
+ pdbs,
84
+ proteome,
85
+ gene_id,
86
+ rhea_curies,
87
+ go_components,
88
+ go_functions,
89
+ go_processes,
90
+ bindings,
91
+ description,
92
+ ) in tqdm(reader, desc="Mapping UniProt", unit_scale=True):
93
+ if description:
94
+ description = description.removeprefix("FUNCTION: ")
95
+ term = Term(
96
+ reference=Reference(prefix=PREFIX, identifier=uniprot_id, name=accession),
97
+ definition=description or None,
98
+ )
51
99
  term.set_species(taxonomy_id)
100
+ if gene_id:
101
+ term.append_relationship(
102
+ gene_product_of, Reference(prefix="ncbigene", identifier=gene_id)
103
+ )
104
+
105
+ # TODO add type=Reference(prefix="xsd", identifier="boolean")
106
+ term.append_property("reviewed", "true")
107
+
108
+ for go_process_ref in _parse_go(go_processes):
109
+ term.append_relationship(participates_in, go_process_ref)
110
+ for go_function_ref in _parse_go(go_functions):
111
+ term.append_relationship(enables, go_function_ref)
112
+ for go_component_ref in _parse_go(go_components):
113
+ term.append_relationship(located_in, go_component_ref)
114
+
115
+ if proteome:
116
+ uniprot_proteome_id = proteome.split(":")[0]
117
+ term.append_relationship(
118
+ derives_from,
119
+ Reference(prefix="uniprot.proteome", identifier=uniprot_proteome_id),
120
+ )
121
+
122
+ if rhea_curies:
123
+ for rhea_curie in rhea_curies.split(" "):
124
+ term.append_relationship(
125
+ # FIXME this needs a different relation than enables
126
+ # see https://github.com/biopragmatics/pyobo/pull/168#issuecomment-1918680152
127
+ enables,
128
+ cast(Reference, Reference.from_curie(rhea_curie, strict=True)),
129
+ )
130
+
131
+ if bindings:
132
+ binding_references = set()
133
+ for part in bindings.split(";"):
134
+ part = part.strip()
135
+ if part.startswith("/ligand_id"):
136
+ curie = part.removeprefix('/ligand_id="').rstrip('"')
137
+ binding_references.add(
138
+ cast(Reference, Reference.from_curie(curie, strict=True))
139
+ )
140
+ for binding_reference in sorted(binding_references, key=attrgetter("curie")):
141
+ term.append_relationship(molecularly_interacts_with, binding_reference)
142
+
52
143
  if ecs:
53
144
  for ec in ecs.split(";"):
54
145
  term.append_relationship(
@@ -63,11 +154,27 @@ def iter_terms(version: Optional[str] = None) -> Iterable[Term]:
63
154
  yield term
64
155
 
65
156
 
66
- def ensure(version: Optional[str] = None) -> Path:
157
+ def _parse_go(go_terms) -> List[Reference]:
158
+ rv = []
159
+ if go_terms:
160
+ for go_term in go_terms.split(";"):
161
+ go_id = go_term.rsplit("[GO:")[1].rstrip("]")
162
+ rv.append(Reference(prefix="go", identifier=go_id))
163
+ return rv
164
+
165
+
166
+ def ensure(version: Optional[str] = None, force: bool = False) -> Path:
67
167
  """Ensure the reviewed uniprot names are available."""
68
168
  if version is None:
69
169
  version = bioversions.get_version("uniprot")
70
- return RAW_MODULE.ensure(PREFIX, version, name="reviewed.tsv.gz", url=REVIEWED_URL)
170
+ return RAW_MODULE.ensure(
171
+ PREFIX,
172
+ version,
173
+ force=force,
174
+ name="reviewed.tsv.gz",
175
+ url=BASE_URL, # switch to SEARCH_URL for debugging
176
+ download_kwargs={"backend": "requests", "params": PARAMS},
177
+ )
71
178
 
72
179
 
73
180
  if __name__ == "__main__":
pyobo/struct/__init__.py CHANGED
@@ -15,6 +15,7 @@ from .struct import ( # noqa: F401
15
15
  from .typedef import ( # noqa: F401
16
16
  RelationHint,
17
17
  TypeDef,
18
+ derives_from,
18
19
  enables,
19
20
  from_species,
20
21
  gene_product_member_of,
pyobo/struct/struct.py CHANGED
@@ -1023,7 +1023,7 @@ class Obo:
1023
1023
  def iterate_id_name(self, *, use_tqdm: bool = False) -> Iterable[Tuple[str, str]]:
1024
1024
  """Iterate identifier name pairs."""
1025
1025
  for term in self._iter_terms(use_tqdm=use_tqdm, desc=f"[{self.ontology}] getting names"):
1026
- if term.name:
1026
+ if term.prefix == self.ontology and term.name:
1027
1027
  yield term.identifier, term.name
1028
1028
 
1029
1029
  def get_id_name_mapping(self, *, use_tqdm: bool = False) -> Mapping[str, str]:
pyobo/struct/typedef.py CHANGED
@@ -205,6 +205,15 @@ has_participant = TypeDef(
205
205
  comment="Inverse of has participant",
206
206
  inverse=Reference(prefix=RO_PREFIX, identifier="0000056", name="participates in"),
207
207
  )
208
+ derives_from = TypeDef(
209
+ reference=Reference(prefix=RO_PREFIX, identifier="0001000", name="derives from"),
210
+ )
211
+ molecularly_interacts_with = TypeDef(
212
+ reference=Reference(prefix=RO_PREFIX, identifier="0002436", name="molecularly interacts with"),
213
+ )
214
+ located_in = TypeDef(
215
+ reference=Reference(prefix=RO_PREFIX, identifier="0001025", name="located in"),
216
+ )
208
217
  exact_match = TypeDef(
209
218
  reference=Reference(prefix="skos", identifier="exactMatch", name="exact match"),
210
219
  )
pyobo/utils/misc.py CHANGED
@@ -52,22 +52,28 @@ def cleanup_version(data_version: str, prefix: str) -> Optional[str]:
52
52
  if prefix == "orth":
53
53
  # TODO add bioversions for this
54
54
  return "2"
55
- if data_version.startswith("http://www.orpha.net/version"):
56
- return data_version[len("http://www.orpha.net/version") :]
57
- if data_version.startswith("http://humanbehaviourchange.org/ontology/bcio.owl/"):
58
- return data_version[len("http://humanbehaviourchange.org/ontology/bcio.owl/") :]
59
- if data_version.startswith("http://www.ebi.ac.uk/efo/releases/v"):
60
- return data_version[len("http://www.ebi.ac.uk/efo/releases/v") :].split("/")[0]
61
- if data_version.startswith("http://www.ebi.ac.uk/swo/swo.owl/"):
62
- return data_version[len("http://www.ebi.ac.uk/swo/swo.owl/") :].split("/")[0]
63
- if data_version.startswith("http://purl.org/pav/"):
64
- return data_version[len("http://purl.org/pav/") :]
65
- if data_version.startswith("http://semanticscience.org/ontology/sio/v"):
66
- return data_version[len("http://semanticscience.org/ontology/sio/v")].split("/")[0]
67
- if data_version.startswith("http://ontology.neuinfo.org/NIF/ttl/nif/version/"):
68
- return data_version[len("http://ontology.neuinfo.org/NIF/ttl/nif/version/") :].split("/")[0]
69
- if data_version.startswith("http://identifiers.org/combine.specifications/teddy.rel-"):
70
- return data_version[len("http://identifiers.org/combine.specifications/teddy.rel-") :]
55
+
56
+ version_prefixes = [
57
+ "http://www.orpha.net/version",
58
+ "https://www.orphadata.com/data/ontologies/ordo/last_version/ORDO_en_",
59
+ "http://humanbehaviourchange.org/ontology/bcio.owl/",
60
+ "http://purl.org/pav/",
61
+ "http://identifiers.org/combine.specifications/teddy.rel-",
62
+ ]
63
+ for version_prefix in version_prefixes:
64
+ if data_version.startswith(version_prefix):
65
+ return data_version[len(version_prefix) :]
66
+
67
+ version_prefixes_split = [
68
+ "http://www.ebi.ac.uk/efo/releases/v",
69
+ "http://www.ebi.ac.uk/swo/swo.owl/",
70
+ "http://semanticscience.org/ontology/sio/v",
71
+ "http://ontology.neuinfo.org/NIF/ttl/nif/version/",
72
+ ]
73
+ for version_prefix_split in version_prefixes_split:
74
+ if data_version.startswith(version_prefix_split):
75
+ return data_version[len(version_prefix_split) :].split("/")[0]
76
+
71
77
  if data_version.replace(".", "").isnumeric():
72
78
  return data_version # consecutive, major.minor, or semantic versioning
73
79
  for v in reversed(data_version.split("/")):
pyobo/version.py CHANGED
@@ -14,7 +14,7 @@ __all__ = [
14
14
  "get_git_hash",
15
15
  ]
16
16
 
17
- VERSION = "0.10.8"
17
+ VERSION = "0.10.9"
18
18
 
19
19
 
20
20
  def get_git_hash() -> str:
@@ -24,7 +24,7 @@ logger = logging.getLogger(__name__)
24
24
  #: WikiData SPARQL endpoint. See https://www.wikidata.org/wiki/Wikidata:SPARQL_query_service#Interfacing
25
25
  URL = "https://query.wikidata.org/bigdata/namespace/wdq/sparql"
26
26
 
27
- WIKIDATA_MAPPING_DIRECTORY = RAW_MODULE.submodule("wikidata", "mappings")
27
+ WIKIDATA_MAPPING_DIRECTORY = RAW_MODULE.module("wikidata", "mappings")
28
28
 
29
29
 
30
30
  def get_wikidata_xrefs_df(*, use_tqdm: bool = True) -> pd.DataFrame:
@@ -66,10 +66,12 @@ def get_wikidata_df(prefix: str, wikidata_property: str) -> pd.DataFrame:
66
66
  return df
67
67
 
68
68
 
69
- def iter_wikidata_mappings(wikidata_property: str) -> Iterable[Tuple[str, str]]:
69
+ def iter_wikidata_mappings(
70
+ wikidata_property: str, *, cache: bool = True
71
+ ) -> Iterable[Tuple[str, str]]:
70
72
  """Iterate over Wikidata xrefs."""
71
73
  path = WIKIDATA_MAPPING_DIRECTORY.join(name=f"{wikidata_property}.json")
72
- if path.exists():
74
+ if path.exists() and cache:
73
75
  with path.open() as file:
74
76
  rows = json.load(file)
75
77
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyobo
3
- Version: 0.10.8
3
+ Version: 0.10.9
4
4
  Summary: Handling and writing OBO
5
5
  Home-page: https://github.com/pyobo/pyobo
6
6
  Download-URL: https://github.com/pyobo/pyobo/releases
@@ -49,7 +49,7 @@ Requires-Dist: class-resolver
49
49
  Requires-Dist: psycopg2-binary
50
50
  Requires-Dist: drugbank-downloader
51
51
  Requires-Dist: chembl-downloader
52
- Requires-Dist: umls-downloader >=0.1.2
52
+ Requires-Dist: umls-downloader >=0.1.3
53
53
  Requires-Dist: typing-extensions
54
54
  Provides-Extra: agrovoc
55
55
  Requires-Dist: rdflib ; extra == 'agrovoc'
@@ -2,7 +2,7 @@ pyobo/__init__.py,sha256=mZ96iZ-5ucxe2eLBi0xuSKaa2ZfeInaSR5Ajc_NkvUo,1862
2
2
  pyobo/__main__.py,sha256=cQjBabQ2wlFKcv54PFdt0SgPXNeb3oWneuOHaBgHx1Q,108
3
3
  pyobo/aws.py,sha256=EUXsN_sQEOWOV2oZXrVrkO8R6Zo_JJHGeGzzWWgpvzo,5948
4
4
  pyobo/constants.py,sha256=gj8xSUmCO0rU-eGXHOW7Vix3SAHl50cLAM3HXuoAFt4,2200
5
- pyobo/getters.py,sha256=PFKV03izOK8wIU9CpZVRKgu5x-Mqnl39Kzo_bVPs8cs,15528
5
+ pyobo/getters.py,sha256=37e7pcTqU-uVjx_XctT9pJMn7zaazsNfcyWoe7KMHi0,15565
6
6
  pyobo/gilda_utils.py,sha256=9rzlOkmq2MFac2sJ7b-XHS6UTSTiOM_rRk_xzt-uJiI,7582
7
7
  pyobo/identifier_utils.py,sha256=y4eFbJJQGoGe0HKRqQoUc_3tani22W_K4z7OZFL6Z0E,3659
8
8
  pyobo/mocks.py,sha256=R-4W3Rm5NarIHfNjxurbvBYsLHXt6jmDb6THMUt6K1w,2432
@@ -11,10 +11,10 @@ pyobo/obographs.py,sha256=JKE0a7e-gmxqdJoeX2zb_xQ6Tv5PAe60YhnIpAvrrYg,3758
11
11
  pyobo/plugins.py,sha256=dXWGoFuQktNeQUWSJlPz2a7FeLysggc9ry6auEZdw98,1227
12
12
  pyobo/reader.py,sha256=3VTWQMmA-AHi3RdA2jb48d2deXO-lYKqXbcMa9Qhi_4,21271
13
13
  pyobo/resource_utils.py,sha256=JBcJRihZhNwp78-qWZPrzSCGoYfyOjzBwMkfmOkO_no,4289
14
- pyobo/version.py,sha256=i-EQd4I3sb_xaI_bR3WzuldGnpe7ujiT_B2VTY_TPxE,977
14
+ pyobo/version.py,sha256=ONSzSms19NKy9Bl2q8M4P_Mlo0MkqMGJ7X1SKZuec4M,977
15
15
  pyobo/api/__init__.py,sha256=Hq8p5uPW8fFYG2KfLqUsHhtLkTPqE4TqItGkedZzvXM,1326
16
16
  pyobo/api/alts.py,sha256=xmAb-gGQCJ9MbaFvoNK6E-V0B3TV9hxulkfbkHIvOso,2617
17
- pyobo/api/hierarchy.py,sha256=TBZs6SqG1wBP3026D7_bsznH-PAXeM2t1Onwb6_10R4,9010
17
+ pyobo/api/hierarchy.py,sha256=2KtyTkqOKJzejNqVvlhPQD_w0fKzrOQp1BSx-Ina3t0,9413
18
18
  pyobo/api/metadata.py,sha256=62E7j0ZW3vYK2Rh-R7NCMKnChbYjZwPjVDoaE1AsCOc,1070
19
19
  pyobo/api/names.py,sha256=A5HprOfdt7twF2LfjdQQaIj3FNj4_GD7MZ7CrKllY5M,7559
20
20
  pyobo/api/properties.py,sha256=BKqUgN8nTpYrc0fROdaGGkptELgjbGT6TC_N2X8FIQM,7813
@@ -22,7 +22,7 @@ pyobo/api/relations.py,sha256=VEQCQjPamehyGaL-wFzUYH9OeVq9pVzj70sl9K3ttKw,5996
22
22
  pyobo/api/species.py,sha256=xRPRoD6n1wcDaqlC_tHLw3rKMWa4razWsSPNa228g_4,2181
23
23
  pyobo/api/typedefs.py,sha256=TqNZ8_5ntw6PXwvqIlHtMHqD7l2jWwHn48vccUPbJiI,1061
24
24
  pyobo/api/utils.py,sha256=jxisiISIUtoW_SfNa3eOVTkEYP5ygYHaFTDibmMO7UE,1059
25
- pyobo/api/xrefs.py,sha256=_gWioZs0s1VAH5g49MSP7AQMXOuR-KcKblKlVXWotPw,5894
25
+ pyobo/api/xrefs.py,sha256=p2ZdAcCOVnaRUQezGH3i0cTj2wVH-0mhSae98YVrMOQ,5942
26
26
  pyobo/apps/__init__.py,sha256=iACi86TkTiGxwneGmfaudZOIEqZ45YjPXng7XjPE38Y,72
27
27
  pyobo/apps/cli.py,sha256=gnXBAaESw1T1BvgMpTv-0P26hM2vKCAXPy0SOskgUwU,335
28
28
  pyobo/apps/gilda/__init__.py,sha256=jpLIHJOmR_66tdXXUWFP9NiZnpQKvjv5YpCJWoAKnUI,54
@@ -52,14 +52,15 @@ pyobo/resources/ncbitaxon.py,sha256=kyJDMGm8qIpIpckN6NSGovCBDacG1qGYTIpvJ--HXhM,
52
52
  pyobo/resources/ncbitaxon.tsv.gz,sha256=43zHjnVt62TA4_lV58X-FCPdMDfLg1B1PvZSr_Xy9hY,22981954
53
53
  pyobo/resources/ro.py,sha256=_CYD90vftMZvu8Rj6H9kOiw6wRBbs1LWmCl-HToxMIg,1484
54
54
  pyobo/resources/ro.tsv,sha256=YvlBLPAKy2w4IheYzO9ox1Yg6WkHdMVzMQTikIlECog,26586
55
- pyobo/sources/__init__.py,sha256=vWzTP4kraQulrA4h2NTAhsjouehsEj0hQBwpqLypXSs,3666
55
+ pyobo/sources/__init__.py,sha256=uG7If-_xo4GfuvQ43yVQFBDUjYMGwmm5o3vyAm0Qqow,3783
56
56
  pyobo/sources/agrovoc.py,sha256=J425AyyOVAeqeyN5MhmAR9OtJom41GDvKArfyz1iIU8,795
57
57
  pyobo/sources/antibodyregistry.py,sha256=5i2qRhGgyi11Ke9xrHU1NRFxD3xMCnHQWWKh9fQCXDs,3178
58
58
  pyobo/sources/biogrid.py,sha256=Rr5gSLmOK95YPm2cYcFbGLDm3LWNckLvlarmbSIP-5M,3290
59
59
  pyobo/sources/ccle.py,sha256=KqqVokOq0HYE980plNa3987O1ixLkpcC0j9rYoQIM70,2963
60
- pyobo/sources/cgnc.py,sha256=5epG5LK9RWMAUp2pL7rvd-5A-QPloqCNjw1MxHn6x-c,2308
60
+ pyobo/sources/cgnc.py,sha256=hCjFv05_aS2_Mn5Qb9VGLKGcOY87rEXZ6jH7r6WgUeg,2336
61
61
  pyobo/sources/chebi.py,sha256=7t5CaykOWXMQ9JRW8x1g_gsZhygCdjR2MGRYTFLEiTs,1230
62
62
  pyobo/sources/chembl.py,sha256=MG_bTilUwhhkeuTA3owLn1gro1QicMyGGfcd-48NGgE,2296
63
+ pyobo/sources/civic_gene.py,sha256=SUwlb1PXwVVB-XQanyI7tRbPMGaDNiB-CXNry_idAZY,1691
63
64
  pyobo/sources/complexportal.py,sha256=nhEaUzw4riuN31OLiwpGffj66YMCeLigekblTWGk3nk,6022
64
65
  pyobo/sources/conso.py,sha256=ZLQ_T5EgrcuX9q6kCBKCwfGzAEVxgN6xADl-LKzJtbk,2460
65
66
  pyobo/sources/cpt.py,sha256=x8P15D9UX5Fwf6bmeVsU1DAFJvZ22rxVPy5ur-GUk_Q,1482
@@ -84,15 +85,16 @@ pyobo/sources/icd11.py,sha256=04nLt-Lr64hAroOLH4OP-iNbuIjBk-mYcg-Ib34zgMM,2834
84
85
  pyobo/sources/icd_utils.py,sha256=c1Xkk9YAyKQ-vvnPud5GKq5ygZVbd1j0NFSml3RjQZ0,3155
85
86
  pyobo/sources/interpro.py,sha256=sWla5FDOkzA8elzeNHXOMD0nEVIbNK7jg4UZ0Zp7BfI,4934
86
87
  pyobo/sources/itis.py,sha256=LXS4MTL7OMmdfo-ypoF75UJkePw7VnHDrgq10RF_VUk,2967
87
- pyobo/sources/mesh.py,sha256=2vpfF_85fQqdOORha0ekZJ4gifAV1HDNyo5y6arSmjE,11103
88
+ pyobo/sources/mesh.py,sha256=w06h1p0qeLUyNKEGLIqSdQXDtA4yqdfwnaAxF-4Xbr8,12048
88
89
  pyobo/sources/mgi.py,sha256=c0CiiH_LolAFdHPNu1lpLeAzHq20wVLyOrLRTkLYxhY,5766
89
90
  pyobo/sources/mirbase.py,sha256=NMqZfT7CbbetqCV-KdGjHJmz2uM5QvdF_M1BxKi1ZCw,6349
90
91
  pyobo/sources/mirbase_constants.py,sha256=X7KhJDp1saGrdBwUR9fQSWwebzns5f-mEF4qWSETs2k,2023
91
92
  pyobo/sources/mirbase_family.py,sha256=Yj3oXaeBWDxcmBKnvOl0q_7nzlye5EXhSJPWlV3YpT8,2167
92
93
  pyobo/sources/mirbase_mature.py,sha256=nvWcQVDMBucPu6v5DLFb_W_9fz_J_Id7HZrilkUhaFI,1504
93
94
  pyobo/sources/msigdb.py,sha256=YKgFyPgYKdYQtu22P69IVyLeBsLfgNyaNOl7q0Sy8IU,5019
94
- pyobo/sources/ncbigene.py,sha256=FXGwSrnPSQREiF2k3qtZvRBEiung3bbVb-NAJv33uHU,4890
95
+ pyobo/sources/ncbigene.py,sha256=qipZEaaXop289vRro_NS8BB0_t-c738lJItWSjzD7PI,5055
95
96
  pyobo/sources/npass.py,sha256=t8TDdxpfvvXYo8VczT4ngoSspPAdPJuLKigvHZ9OHrE,2805
97
+ pyobo/sources/omim_ps.py,sha256=uULW_1gmYIE66O85GdLCGbdmsi9qxcS7tZziOny0wc0,1020
96
98
  pyobo/sources/pathbank.py,sha256=yhdS4BCbGxQf0o3HCGzL2cYRY7zyvHvDzzSBkkezoog,4989
97
99
  pyobo/sources/pfam.py,sha256=aHXdXmoG6xyNkScHft_xYe4J2DzRr22EinyfjpmwEj4,1846
98
100
  pyobo/sources/pfam_clan.py,sha256=hjJ0UUEcrNoaQVWbXZ_EaTWFo4iB9VG9Sp6pcO90gxY,1340
@@ -122,25 +124,25 @@ pyobo/sources/umls/__init__.py,sha256=L49nPxoXFtFHwzP327cEOTr1oJrKAz7_nS2tahajpn
122
124
  pyobo/sources/umls/__main__.py,sha256=mz2UqO02rnA68XM3420Nev4yocBn20QFSqU3E0oqNx8,133
123
125
  pyobo/sources/umls/get_synonym_types.py,sha256=5u1ZEl8gp_StuQxrasvHK4S0DyVWdgp_rLzo3aFOALI,1111
124
126
  pyobo/sources/umls/synonym_types.tsv,sha256=z--ngeAqA_Kk8ft2YD8qOU_XUxhnTxF0OhL8jRd5xqo,8551
125
- pyobo/sources/umls/umls.py,sha256=nCeUPTJyKKs7K5Yft2ZSgVXaC6sCau0387AVzDXzXk0,3730
127
+ pyobo/sources/umls/umls.py,sha256=C3UXVd1iSlj5TC6Ib1T1oDIyJ4pIveNeGPK8ORkRtG4,4318
126
128
  pyobo/sources/uniprot/__init__.py,sha256=dsL0BvfMn3O_swtNhzQpjJUlP56NUBCcjSYdFvRlwmI,225
127
- pyobo/sources/uniprot/uniprot.py,sha256=tJqSubCTMBfFkIRQxXqzVGlS7PTCrA9c_0mofjAFmj8,2557
129
+ pyobo/sources/uniprot/uniprot.py,sha256=WVSxy6cDPYu5S69_V5_dzRdsU6aSVm-rFXvmEcuk8eI,6105
128
130
  pyobo/sources/uniprot/uniprot_ptm.py,sha256=ze1cf0_kkqslhS-lXa7EdfasV4reUDp6niJat6yymT8,3551
129
131
  pyobo/ssg/__init__.py,sha256=Q5vYmk1LZwriShmA3TcYZ1Z1yiyjTWItcGxep5Fi2pw,5390
130
132
  pyobo/ssg/base.html,sha256=_vldUCa-gL2YTNY6GgAuxNT3TgaED585vF_q7TrrjYs,2844
131
133
  pyobo/ssg/index.html,sha256=zDGkwIQBtbpnhCYALXQ0vr7qsVmAqDtbwOyPqU3hZ8s,3993
132
134
  pyobo/ssg/term.html,sha256=QU6piGOq4dq8zlNhJvLFxqFjhVQyWlkiG31I0Sg5frg,3559
133
135
  pyobo/ssg/typedef.html,sha256=KrdqzB6xjt689bG33D26AL-11JrvNuEkoxNNI-EG-Tg,2038
134
- pyobo/struct/__init__.py,sha256=imJ-ffEGBI8f_kSbmDC-VQMCZksLxoHh7OjwvF4chwM,653
136
+ pyobo/struct/__init__.py,sha256=F5iav-0rnkLrldDxDPVeDt4zd1tXYBKICoKODJBk_kQ,671
135
137
  pyobo/struct/reference.py,sha256=U2qHIANj_0XhSxh7UBaXUiOXWtVjtyIBeDQ03heWuxA,5712
136
- pyobo/struct/struct.py,sha256=vhxJkGbI_rpugxdIwTOveUEm2zOnilQrOdFdjC_D-SU,54365
137
- pyobo/struct/typedef.py,sha256=ThTnchHonL07rSgc1WKjQTpzRwt5bAAH-MfhZnchSgI,13138
138
+ pyobo/struct/struct.py,sha256=bkZv5H_sZFaWQr3cXA5F6JQbqg_OtVfMBV4mS10aHKk,54398
139
+ pyobo/struct/typedef.py,sha256=spRRFWV-lV7yOU6HHnxAAFA-4ap6bm3l27KV-bmdLlc,13498
138
140
  pyobo/struct/utils.py,sha256=-XHuCETp7jPNhjHCW72gikaKoaiTPTNhDK5BZYyJsVw,815
139
141
  pyobo/utils/__init__.py,sha256=wXtcjcasWRBtJdTSMCC3jT8yFG8ZkQC-Xdh9lLiQDAo,42
140
142
  pyobo/utils/cache.py,sha256=bmuEE0DyppY6szNEzkS1tLLKfsLIrHQFhp0P-q94KFs,2677
141
143
  pyobo/utils/io.py,sha256=GiOittPhSJKc-acmj6h3DGSvLnPDntRIiUhjuCEUwj8,4756
142
144
  pyobo/utils/iter.py,sha256=VyISqr04Pg2xLSLJhypUuZnh7WzxVmpp3MsASCuL8Tk,1475
143
- pyobo/utils/misc.py,sha256=iJuog7Koluf_qF1Q5AMYdlzOQIiKnEebMxsD5ZcmqjE,3235
145
+ pyobo/utils/misc.py,sha256=WfvJ_AGge8plp9IIlAGiahPxoCiWAow4t_-ncr7AjwY,2857
144
146
  pyobo/utils/ndex_utils.py,sha256=gxmGfR_O-ZMOsBil_YFSn99x_Fvatg7O8s9iZp4Iy10,2351
145
147
  pyobo/utils/path.py,sha256=-IVv_0H4Q790-ymmLdOlFgFSDuDubh9jZpPtDQzf-hI,3931
146
148
  pyobo/xrefdb/__init__.py,sha256=0W6AuvghFHQ1zY-Dq26z8V_MRC9xL39aWqLb-JbU8T8,74
@@ -158,10 +160,10 @@ pyobo/xrefdb/sources/gilda.py,sha256=aYMFXMbDKB-_HqPMzEIUhvz6YahJiuyAcNgo2KfFalk
158
160
  pyobo/xrefdb/sources/intact.py,sha256=F0z6WrOwI79aZSuM5MsvQwzqoyzh9J0UuB4Mseoj9X8,2966
159
161
  pyobo/xrefdb/sources/ncit.py,sha256=unoIKJqdcfitTc6pU9P1SxJ1w8ax0iDjvEOlqe64nCY,3745
160
162
  pyobo/xrefdb/sources/pubchem.py,sha256=GaqgqtSV-T_P-900nL3alPx_ZB36MlmnEepOnZMONA4,780
161
- pyobo/xrefdb/sources/wikidata.py,sha256=ODi87EMsE3pJKkZTmaOgjbxsHFgqROGsZ6r0w2gbHC8,3351
162
- pyobo-0.10.8.dist-info/LICENSE,sha256=GRbxxtZEWtZiFGDENk1gntCQK4HEJYYbylEJEwpSLao,1076
163
- pyobo-0.10.8.dist-info/METADATA,sha256=MdXKo1rQUgXInDbi0lnDCaQ6iltinDyzaNAMuZ6Qo2U,20045
164
- pyobo-0.10.8.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
165
- pyobo-0.10.8.dist-info/entry_points.txt,sha256=Du5V6qw_T917Z5ZoMhLTTJoolK7kkVuUWkdE7aJWea0,669
166
- pyobo-0.10.8.dist-info/top_level.txt,sha256=oVdkT-pbiGoSdGSQplXFuP1KQGJNf4GdRC65jn6y9t0,6
167
- pyobo-0.10.8.dist-info/RECORD,,
163
+ pyobo/xrefdb/sources/wikidata.py,sha256=bOI2zUkkLbmXvOMJZmVWq1xKlMCuL_3l1NVsaoJr1x4,3387
164
+ pyobo-0.10.9.dist-info/LICENSE,sha256=GRbxxtZEWtZiFGDENk1gntCQK4HEJYYbylEJEwpSLao,1076
165
+ pyobo-0.10.9.dist-info/METADATA,sha256=BDEySfczBniUX3mHWKWI4XC9uxrbB_XPCRhp3Q5I8uE,20045
166
+ pyobo-0.10.9.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
167
+ pyobo-0.10.9.dist-info/entry_points.txt,sha256=Du5V6qw_T917Z5ZoMhLTTJoolK7kkVuUWkdE7aJWea0,669
168
+ pyobo-0.10.9.dist-info/top_level.txt,sha256=oVdkT-pbiGoSdGSQplXFuP1KQGJNf4GdRC65jn6y9t0,6
169
+ pyobo-0.10.9.dist-info/RECORD,,
File without changes