pyobo 0.12.12__tar.gz → 0.12.14__tar.gz

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.
Files changed (211) hide show
  1. {pyobo-0.12.12 → pyobo-0.12.14}/PKG-INFO +3 -3
  2. {pyobo-0.12.12 → pyobo-0.12.14}/pyproject.toml +4 -4
  3. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/constants.py +1 -1
  4. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/chebi.py +1 -4
  5. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/hgnc/hgnc.py +3 -0
  6. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/mesh.py +8 -1
  7. pyobo-0.12.14/src/pyobo/sources/ror.py +415 -0
  8. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/struct/struct.py +15 -7
  9. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/struct/struct_utils.py +2 -0
  10. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/struct/typedef.py +39 -0
  11. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/utils/misc.py +9 -0
  12. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/version.py +1 -1
  13. pyobo-0.12.12/src/pyobo/sources/ror.py +0 -237
  14. {pyobo-0.12.12 → pyobo-0.12.14}/LICENSE +0 -0
  15. {pyobo-0.12.12 → pyobo-0.12.14}/README.md +0 -0
  16. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/.DS_Store +0 -0
  17. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/__init__.py +0 -0
  18. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/__main__.py +0 -0
  19. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/api/__init__.py +0 -0
  20. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/api/alts.py +0 -0
  21. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/api/combine.py +0 -0
  22. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/api/edges.py +0 -0
  23. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/api/embedding.py +0 -0
  24. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/api/hierarchy.py +0 -0
  25. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/api/metadata.py +0 -0
  26. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/api/names.py +0 -0
  27. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/api/properties.py +0 -0
  28. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/api/relations.py +0 -0
  29. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/api/species.py +0 -0
  30. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/api/typedefs.py +0 -0
  31. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/api/utils.py +0 -0
  32. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/api/xrefs.py +0 -0
  33. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/cli/__init__.py +0 -0
  34. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/cli/cli.py +0 -0
  35. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/cli/database.py +0 -0
  36. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/cli/database_utils.py +0 -0
  37. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/cli/lookup.py +0 -0
  38. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/cli/utils.py +0 -0
  39. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/getters.py +0 -0
  40. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/gilda_utils.py +0 -0
  41. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/identifier_utils/__init__.py +0 -0
  42. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/identifier_utils/api.py +0 -0
  43. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/identifier_utils/relations/__init__.py +0 -0
  44. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/identifier_utils/relations/api.py +0 -0
  45. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/identifier_utils/relations/data.json +0 -0
  46. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/identifier_utils/relations/data_owl.json +0 -0
  47. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/identifier_utils/relations/data_rdf.json +0 -0
  48. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/identifier_utils/relations/data_rdfs.json +0 -0
  49. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/mocks.py +0 -0
  50. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/ner/__init__.py +0 -0
  51. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/ner/api.py +0 -0
  52. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/ner/normalizer.py +0 -0
  53. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/ner/scispacy_utils.py +0 -0
  54. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/plugins.py +0 -0
  55. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/py.typed +0 -0
  56. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/resource_utils.py +0 -0
  57. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/resources/__init__.py +0 -0
  58. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/resources/ncbitaxon.py +0 -0
  59. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/resources/ncbitaxon.tsv.gz +0 -0
  60. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/resources/ro.py +0 -0
  61. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/resources/ro.tsv +0 -0
  62. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/resources/so.py +0 -0
  63. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/resources/so.tsv +0 -0
  64. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/README.md +0 -0
  65. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/__init__.py +0 -0
  66. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/agrovoc.py +0 -0
  67. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/antibodyregistry.py +0 -0
  68. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/bigg/__init__.py +0 -0
  69. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/bigg/bigg_compartment.py +0 -0
  70. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/bigg/bigg_metabolite.py +0 -0
  71. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/bigg/bigg_model.py +0 -0
  72. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/bigg/bigg_reaction.py +0 -0
  73. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/biogrid.py +0 -0
  74. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/ccle.py +0 -0
  75. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/cgnc.py +0 -0
  76. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/chembl/__init__.py +0 -0
  77. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/chembl/chembl_cell.py +0 -0
  78. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/chembl/chembl_compound.py +0 -0
  79. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/chembl/chembl_mechanism.py +0 -0
  80. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/chembl/chembl_target.py +0 -0
  81. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/chembl/chembl_tissue.py +0 -0
  82. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/civic_gene.py +0 -0
  83. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/clinicaltrials.py +0 -0
  84. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/complexportal.py +0 -0
  85. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/conso.py +0 -0
  86. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/cpt.py +0 -0
  87. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/credit.py +0 -0
  88. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/cvx.py +0 -0
  89. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/depmap.py +0 -0
  90. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/dictybase_gene.py +0 -0
  91. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/drugbank/__init__.py +0 -0
  92. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/drugbank/drugbank.py +0 -0
  93. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/drugbank/drugbank_salt.py +0 -0
  94. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/drugcentral.py +0 -0
  95. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/expasy.py +0 -0
  96. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/famplex.py +0 -0
  97. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/flybase.py +0 -0
  98. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/gard.py +0 -0
  99. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/geonames/__init__.py +0 -0
  100. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/geonames/features.py +0 -0
  101. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/geonames/geonames.py +0 -0
  102. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/geonames/utils.py +0 -0
  103. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/gmt_utils.py +0 -0
  104. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/go.py +0 -0
  105. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/goldbook.py +0 -0
  106. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/gtdb.py +0 -0
  107. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/gwascentral/__init__.py +0 -0
  108. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/gwascentral/gwascentral_phenotype.py +0 -0
  109. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/gwascentral/gwascentral_study.py +0 -0
  110. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/hgnc/__init__.py +0 -0
  111. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/hgnc/hgncgenefamily.py +0 -0
  112. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/iana_media_type.py +0 -0
  113. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/icd/__init__.py +0 -0
  114. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/icd/icd10.py +0 -0
  115. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/icd/icd11.py +0 -0
  116. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/icd/icd_utils.py +0 -0
  117. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/iconclass.py +0 -0
  118. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/intact.py +0 -0
  119. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/interpro.py +0 -0
  120. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/itis.py +0 -0
  121. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/kegg/__init__.py +0 -0
  122. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/kegg/api.py +0 -0
  123. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/kegg/genes.py +0 -0
  124. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/kegg/genome.py +0 -0
  125. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/kegg/pathway.py +0 -0
  126. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/mgi.py +0 -0
  127. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/mirbase/__init__.py +0 -0
  128. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/mirbase/mirbase.py +0 -0
  129. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/mirbase/mirbase_constants.py +0 -0
  130. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/mirbase/mirbase_family.py +0 -0
  131. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/mirbase/mirbase_mature.py +0 -0
  132. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/msigdb.py +0 -0
  133. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/ncbi/__init__.py +0 -0
  134. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/ncbi/ncbi_gc.py +0 -0
  135. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/ncbi/ncbigene.py +0 -0
  136. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/nih_reporter.py +0 -0
  137. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/nlm/__init__.py +0 -0
  138. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/nlm/nlm_catalog.py +0 -0
  139. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/nlm/nlm_publisher.py +0 -0
  140. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/nlm/utils.py +0 -0
  141. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/npass.py +0 -0
  142. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/omim_ps.py +0 -0
  143. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/pathbank.py +0 -0
  144. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/pfam/__init__.py +0 -0
  145. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/pfam/pfam.py +0 -0
  146. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/pfam/pfam_clan.py +0 -0
  147. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/pharmgkb/__init__.py +0 -0
  148. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/pharmgkb/pharmgkb_chemical.py +0 -0
  149. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/pharmgkb/pharmgkb_disease.py +0 -0
  150. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/pharmgkb/pharmgkb_gene.py +0 -0
  151. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/pharmgkb/pharmgkb_pathway.py +0 -0
  152. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/pharmgkb/pharmgkb_variant.py +0 -0
  153. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/pharmgkb/utils.py +0 -0
  154. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/pid.py +0 -0
  155. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/pombase.py +0 -0
  156. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/pubchem.py +0 -0
  157. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/reactome.py +0 -0
  158. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/rgd.py +0 -0
  159. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/rhea.py +0 -0
  160. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/selventa/__init__.py +0 -0
  161. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/selventa/schem.py +0 -0
  162. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/selventa/scomp.py +0 -0
  163. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/selventa/sdis.py +0 -0
  164. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/selventa/sfam.py +0 -0
  165. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/sgd.py +0 -0
  166. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/signor/__init__.py +0 -0
  167. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/signor/download.py +0 -0
  168. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/signor/signor_complexes.py +0 -0
  169. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/slm.py +0 -0
  170. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/spdx.py +0 -0
  171. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/umls/__init__.py +0 -0
  172. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/umls/__main__.py +0 -0
  173. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/umls/get_synonym_types.py +0 -0
  174. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/umls/sty.py +0 -0
  175. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/umls/synonym_types.tsv +0 -0
  176. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/umls/umls.py +0 -0
  177. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/unimod.py +0 -0
  178. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/uniprot/__init__.py +0 -0
  179. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/uniprot/uniprot.py +0 -0
  180. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/uniprot/uniprot_ptm.py +0 -0
  181. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/utils.py +0 -0
  182. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/wikipathways.py +0 -0
  183. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/sources/zfin.py +0 -0
  184. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/ssg/__init__.py +0 -0
  185. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/ssg/base.html +0 -0
  186. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/ssg/index.html +0 -0
  187. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/ssg/term.html +0 -0
  188. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/ssg/typedef.html +0 -0
  189. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/struct/__init__.py +0 -0
  190. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/struct/functional/__init__.py +0 -0
  191. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/struct/functional/dsl.py +0 -0
  192. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/struct/functional/macros.py +0 -0
  193. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/struct/functional/obo_to_functional.py +0 -0
  194. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/struct/functional/ontology.py +0 -0
  195. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/struct/functional/utils.py +0 -0
  196. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/struct/obo/__init__.py +0 -0
  197. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/struct/obo/reader.py +0 -0
  198. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/struct/obo/reader_utils.py +0 -0
  199. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/struct/obograph/__init__.py +0 -0
  200. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/struct/obograph/export.py +0 -0
  201. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/struct/obograph/reader.py +0 -0
  202. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/struct/obograph/utils.py +0 -0
  203. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/struct/reference.py +0 -0
  204. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/struct/utils.py +0 -0
  205. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/struct/vocabulary.py +0 -0
  206. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/utils/__init__.py +0 -0
  207. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/utils/cache.py +0 -0
  208. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/utils/io.py +0 -0
  209. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/utils/iter.py +0 -0
  210. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/utils/ndex_utils.py +0 -0
  211. {pyobo-0.12.12 → pyobo-0.12.14}/src/pyobo/utils/path.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyobo
3
- Version: 0.12.12
3
+ Version: 0.12.14
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
@@ -40,11 +40,11 @@ Requires-Dist: bioversions>=0.8.101
40
40
  Requires-Dist: bioregistry>=0.12.30
41
41
  Requires-Dist: bioontologies>=0.7.2
42
42
  Requires-Dist: ssslm>=0.0.13
43
- Requires-Dist: zenodo-client>=0.3.6
43
+ Requires-Dist: zenodo-client>=0.4.0
44
44
  Requires-Dist: class-resolver>=0.6.0
45
45
  Requires-Dist: pydantic>=2.0
46
46
  Requires-Dist: curies>=0.10.17
47
- Requires-Dist: curies-processing>=0.1.2
47
+ Requires-Dist: curies-processing>=0.1.6
48
48
  Requires-Dist: python-dateutil
49
49
  Requires-Dist: networkx>=3.4
50
50
  Requires-Dist: drugbank-downloader
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "pyobo"
7
- version = "0.12.12"
7
+ version = "0.12.14"
8
8
  description = "A python package for handling and generating OBO"
9
9
  readme = "README.md"
10
10
  authors = [
@@ -73,11 +73,11 @@ dependencies = [
73
73
  "bioregistry>=0.12.30",
74
74
  "bioontologies>=0.7.2",
75
75
  "ssslm>=0.0.13",
76
- "zenodo-client>=0.3.6",
76
+ "zenodo-client>=0.4.0",
77
77
  "class_resolver>=0.6.0",
78
78
  "pydantic>=2.0",
79
79
  "curies>=0.10.17",
80
- "curies-processing>=0.1.2",
80
+ "curies-processing>=0.1.6",
81
81
  "python-dateutil",
82
82
  "networkx>=3.4",
83
83
  # Resource Downloaders
@@ -315,7 +315,7 @@ known-first-party = [
315
315
  docstring-code-format = true
316
316
 
317
317
  [tool.bumpversion]
318
- current_version = "0.12.12"
318
+ current_version = "0.12.14"
319
319
  parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)(?:-(?P<release>[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?(?:\\+(?P<build>[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?"
320
320
  serialize = [
321
321
  "{major}.{minor}.{patch}-{release}+{build}",
@@ -267,7 +267,7 @@ def _get_json_download(prefix: str) -> str | None:
267
267
  def _get_rdf_download(prefix: str) -> str | None:
268
268
  import bioregistry
269
269
 
270
- return bioregistry.get_rdf_download(prefix)
270
+ return bioregistry.get_rdf_download(prefix, get_format=False)
271
271
 
272
272
 
273
273
  #: Functions that get ontology files. Order matters in this list,
@@ -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)
@@ -210,6 +210,7 @@ class HGNCGetter(Obo):
210
210
  for so_id in sorted(set(LOCUS_TYPE_TO_SO.values()))
211
211
  if so_id
212
212
  ]
213
+ skip_maintainers = True
213
214
 
214
215
  def iter_terms(self, force: bool = False) -> Iterable[Term]:
215
216
  """Iterate over terms in the ontology."""
@@ -342,6 +343,8 @@ def get_terms(version: str | None = None, force: bool = False) -> Iterable[Term]
342
343
  term.append_exact_match(
343
344
  Reference(prefix="iuphar.ligand", identifier=iuphar[len("ligandId:") :])
344
345
  )
346
+ elif iuphar.startswith("HGNC:"):
347
+ pass
345
348
  else:
346
349
  tqdm.write(f"[hgnc:{identifier}] unhandled IUPHAR: {iuphar}")
347
350
 
@@ -131,7 +131,14 @@ def get_terms(version: str, *, force: bool = False) -> Iterable[Term]:
131
131
  for term in concept["terms"]:
132
132
  synonyms.add(term["name"])
133
133
  for xref_prefix, xref_identifier in concept.get("xrefs", []):
134
- xrefs.append(Reference(prefix=xref_prefix, identifier=xref_identifier))
134
+ try:
135
+ xref = Reference(prefix=xref_prefix, identifier=xref_identifier)
136
+ except ValueError:
137
+ tqdm.write(
138
+ f"[mesh:{identifier}] has invalid xref {xref_prefix}:{xref_identifier}"
139
+ )
140
+ else:
141
+ xrefs.append(xref)
135
142
 
136
143
  mesh_id_to_term[identifier] = Term(
137
144
  definition=definition,
@@ -0,0 +1,415 @@
1
+ """Convert the Research Organization Registry (ROR) into an ontology."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import datetime
6
+ import json
7
+ import logging
8
+ import zipfile
9
+ from collections.abc import Iterable
10
+ from functools import lru_cache
11
+ from pathlib import Path
12
+ from typing import Any, Literal, NamedTuple, TypeAlias
13
+
14
+ import bioregistry
15
+ import zenodo_client
16
+ from pydantic import BaseModel, ValidationError
17
+ from tqdm.auto import tqdm
18
+
19
+ from pyobo.struct import Obo, Reference, Term
20
+ from pyobo.struct.struct import CHARLIE_TERM, HUMAN_TERM, PYOBO_INJECTED, acronym
21
+ from pyobo.struct.typedef import (
22
+ has_homepage,
23
+ has_part,
24
+ has_predecessor,
25
+ has_successor,
26
+ located_in,
27
+ part_of,
28
+ see_also,
29
+ )
30
+
31
+ __all__ = [
32
+ "OrganizationType",
33
+ "RORStatus",
34
+ "get_ror_records",
35
+ "get_ror_status",
36
+ "get_ror_to_country_geonames",
37
+ ]
38
+
39
+ logger = logging.getLogger(__name__)
40
+ PREFIX = "ror"
41
+ ROR_ZENODO_RECORD_ID = "17953395"
42
+
43
+ # Constants
44
+ ORG_CLASS = Reference(prefix="OBI", identifier="0000245", name="organization")
45
+ CITY_CLASS = Reference(prefix="ENVO", identifier="00000856", name="city")
46
+
47
+ RMAP = {
48
+ "related": see_also,
49
+ "child": has_part,
50
+ "parent": part_of,
51
+ "predecessor": has_predecessor,
52
+ "successor": has_successor,
53
+ "located in": located_in,
54
+ }
55
+ NAME_REMAPPING = {
56
+ "'s-Hertogenbosch": "Den Bosch", # SMH Netherlands, why u gotta be like this
57
+ "'s Heeren Loo": "s Heeren Loo",
58
+ "'s-Heerenberg": "s-Heerenberg",
59
+ "Institut Virion\\Serion": "Institut Virion/Serion",
60
+ "Hematology\\Oncology Clinic": "Hematology/Oncology Clinic",
61
+ }
62
+
63
+
64
+ class RORGetter(Obo):
65
+ """An ontology representation of the ROR."""
66
+
67
+ ontology = bioregistry_key = PREFIX
68
+ typedefs = [has_homepage, *RMAP.values()]
69
+ synonym_typedefs = [acronym]
70
+ root_terms = [CITY_CLASS, ORG_CLASS]
71
+
72
+ def __post_init__(self):
73
+ self.data_version, _url, _path = get_ror_status()
74
+ super().__post_init__()
75
+
76
+ def iter_terms(self, force: bool = False) -> Iterable[Term]:
77
+ """Iterate over terms in the ontology."""
78
+ yield CHARLIE_TERM
79
+ yield HUMAN_TERM
80
+ yield Term(reference=ORG_CLASS)
81
+ yield Term(reference=CITY_CLASS)
82
+ yield from ROR_ORGANIZATION_TYPE_TO_OBI.values()
83
+ yield from iterate_ror_terms(force=force)
84
+
85
+
86
+ OrganizationType: TypeAlias = Literal[
87
+ "education",
88
+ "facility",
89
+ "funder",
90
+ "company",
91
+ "government",
92
+ "healthcare",
93
+ "archive",
94
+ "nonprofit",
95
+ "other",
96
+ ]
97
+
98
+ ROR_ORGANIZATION_TYPE_TO_OBI: dict[OrganizationType, Term] = {
99
+ "education": Term.default(PREFIX, "education", "educational organization"),
100
+ "facility": Term.default(PREFIX, "facility", "facility"),
101
+ "funder": Term.default(PREFIX, "funder", "funder"),
102
+ "company": Term.default(PREFIX, "company", "company"),
103
+ "government": Term.default(PREFIX, "government", "government organization"),
104
+ "healthcare": Term.default(PREFIX, "healthcare", "healthcare organization"),
105
+ "archive": Term.default(PREFIX, "archive", "archival organization"),
106
+ "nonprofit": Term.default(PREFIX, "healthcare", "nonprofit organization")
107
+ .append_xref(Reference(prefix="ICO", identifier="0000048"))
108
+ .append_xref(Reference(prefix="GSSO", identifier="004615")),
109
+ }
110
+ for _k, v in ROR_ORGANIZATION_TYPE_TO_OBI.items():
111
+ v.append_parent(ORG_CLASS)
112
+ v.append_contributor(CHARLIE_TERM)
113
+ v.append_comment(PYOBO_INJECTED)
114
+
115
+ _MISSED_ORG_TYPES: set[str] = set()
116
+
117
+
118
+ class LocationDetails(BaseModel):
119
+ """The location details slot in the ROR schema."""
120
+
121
+ continent_code: str
122
+ continent_name: str
123
+ country_code: str
124
+ country_name: str
125
+ country_subdivision_code: str | None = None
126
+ country_subdivision_name: str | None = None
127
+ lat: float
128
+ lng: float
129
+ name: str
130
+
131
+
132
+ class Location(BaseModel):
133
+ """The lcoation slot in the ROR schema."""
134
+
135
+ geonames_id: int
136
+ geonames_details: LocationDetails
137
+
138
+
139
+ class ExternalID(BaseModel):
140
+ """The external ID slot in the ROR schema."""
141
+
142
+ type: str
143
+ all: list[str]
144
+ preferred: str | None = None
145
+
146
+
147
+ class Link(BaseModel):
148
+ """The link slot in the ROR schema."""
149
+
150
+ type: str
151
+ value: str
152
+
153
+
154
+ class Name(BaseModel):
155
+ """The name slot in the ROR schema."""
156
+
157
+ value: str
158
+ types: list[str]
159
+ lang: str | None = None
160
+
161
+
162
+ class Relationship(BaseModel):
163
+ """The relationship slot in the ROR schema."""
164
+
165
+ type: str
166
+ label: str
167
+ id: str
168
+
169
+
170
+ class DateAnnotated(BaseModel):
171
+ """The annotated date slot in the ROR schema."""
172
+
173
+ date: datetime.date
174
+ schema_version: str
175
+
176
+
177
+ class Admin(BaseModel):
178
+ """The admin slot in the ROR schema."""
179
+
180
+ created: DateAnnotated
181
+ last_modified: DateAnnotated
182
+
183
+
184
+ Status: TypeAlias = Literal["active", "inactive", "withdrawn"]
185
+
186
+
187
+ class Record(BaseModel):
188
+ """A ROR record."""
189
+
190
+ locations: list[Location]
191
+ established: int | None = None
192
+ external_ids: list[ExternalID]
193
+ id: str
194
+ domains: list[str]
195
+ links: list[Link]
196
+ names: list[Name]
197
+ relationships: list[Relationship]
198
+ status: Status
199
+ types: list[OrganizationType]
200
+ admin: Admin
201
+
202
+ def get_preferred_label(self) -> str | None:
203
+ """Get the preferred label."""
204
+ primary_name: str | None = None
205
+ for name in self.names:
206
+ if "ror_display" in name.types:
207
+ primary_name = name.value
208
+ if primary_name is None:
209
+ return None
210
+ primary_name = NAME_REMAPPING.get(primary_name, primary_name)
211
+ return primary_name
212
+
213
+
214
+ _description_prefix = {
215
+ "education": "an educational organization",
216
+ "facility": "a facility",
217
+ "funder": "a funder",
218
+ "company": "a company",
219
+ "government": "a governmental organization",
220
+ "healthcare": "a healthcare organization",
221
+ "archive": "an archive",
222
+ "nonprofit": "a nonprofit organization",
223
+ "other": "an organization",
224
+ }
225
+
226
+
227
+ def _get_description(record: Record) -> str | None:
228
+ description = (
229
+ f"{_description_prefix[record.types[0]]} in {record.locations[0].geonames_details.name}"
230
+ )
231
+ if record.established:
232
+ description += f" established in {record.established}"
233
+ return description
234
+
235
+
236
+ def iterate_ror_terms(*, force: bool = False) -> Iterable[Term]:
237
+ """Iterate over terms in ROR."""
238
+ status, records = get_ror_records(force=force)
239
+ unhandled_xref_prefixes: set[str] = set()
240
+
241
+ seen_geonames_references = set()
242
+ for record in tqdm(records, unit_scale=True, unit="record", desc=f"{PREFIX} v{status.version}"):
243
+ identifier = record.id.removeprefix("https://ror.org/")
244
+
245
+ primary_name = record.get_preferred_label()
246
+ if primary_name is None:
247
+ raise ValueError("should have got a primary name...")
248
+
249
+ term = Term(
250
+ reference=Reference(prefix=PREFIX, identifier=identifier, name=primary_name),
251
+ type="Instance",
252
+ definition=_get_description(record),
253
+ )
254
+ for organization_type in record.types:
255
+ if organization_type in ROR_ORGANIZATION_TYPE_TO_OBI:
256
+ term.append_parent(ROR_ORGANIZATION_TYPE_TO_OBI[organization_type])
257
+ else:
258
+ term.append_parent(ORG_CLASS)
259
+
260
+ for link in record.links:
261
+ term.annotate_uri(has_homepage, link.value)
262
+
263
+ if primary_name.startswith("The "):
264
+ term.append_synonym(primary_name.removeprefix("The "))
265
+
266
+ for relationship in record.relationships:
267
+ target_id = relationship.id.removeprefix("https://ror.org/")
268
+ term.append_relationship(
269
+ RMAP[relationship.type], Reference(prefix=PREFIX, identifier=target_id)
270
+ )
271
+
272
+ if record.status != "active":
273
+ term.is_obsolete = True
274
+
275
+ for location in record.locations:
276
+ geonames_reference = Reference(
277
+ prefix="geonames",
278
+ identifier=str(location.geonames_id),
279
+ name=location.geonames_details.name,
280
+ )
281
+ seen_geonames_references.add(geonames_reference)
282
+ term.append_relationship(RMAP["located in"], geonames_reference)
283
+
284
+ for name in record.names:
285
+ if "ror_display" in name.types:
286
+ continue
287
+ elif name.types == ["acronym"]:
288
+ term.append_synonym(name.value, type=acronym)
289
+ elif name.types == ["alias"]:
290
+ synonym = name.value.strip().replace("\n", " ")
291
+ term.append_synonym(synonym)
292
+ if synonym.startswith("The "):
293
+ term.append_synonym(synonym.removeprefix("The "), language=name.lang)
294
+ elif name.types == ["label"]:
295
+ label = name.value.strip().replace("\n", " ")
296
+ term.append_synonym(label, language=name.lang)
297
+ if label.startswith("The "):
298
+ term.append_synonym(label.removeprefix("The "), language=name.lang)
299
+ else:
300
+ tqdm.write(
301
+ f"[ror:{identifier}] unhandled name types: {name.types} for {name.value}"
302
+ )
303
+ continue
304
+
305
+ for external_id in record.external_ids:
306
+ if external_id.type.lower() == "orgref":
307
+ # OrgRef refers to wikipedia page id, see
308
+ # https://stackoverflow.com/questions/6168020/what-is-wikipedia-pageid-how-to-change-it-into-real-page-url
309
+ continue
310
+ norm_prefix = bioregistry.normalize_prefix(external_id.type)
311
+ xref_ids = external_id.all
312
+
313
+ if norm_prefix is None:
314
+ if external_id.type not in unhandled_xref_prefixes:
315
+ tqdm.write(
316
+ f"Unhandled prefix: {external_id.type} in {primary_name} ({term.curie}). Values:"
317
+ )
318
+ for xref_id in xref_ids:
319
+ tqdm.write(f"- {xref_id}")
320
+ unhandled_xref_prefixes.add(external_id.type)
321
+ continue
322
+
323
+ if isinstance(xref_ids, str):
324
+ xref_ids = [xref_ids]
325
+ for xref_id in xref_ids:
326
+ xref_id = xref_id.replace(" ", "")
327
+ try:
328
+ xref = Reference(prefix=norm_prefix, identifier=xref_id)
329
+ except ValidationError:
330
+ tqdm.write(f"[{term.curie}] invalid xref: {norm_prefix}:{xref_id}")
331
+ else:
332
+ term.append_xref(xref)
333
+
334
+ yield term
335
+
336
+ for geonames_ref in sorted(seen_geonames_references):
337
+ geonames_term = Term(reference=geonames_ref, type="Instance")
338
+ geonames_term.append_parent(CITY_CLASS)
339
+ yield geonames_term
340
+
341
+
342
+ class RORStatus(NamedTuple):
343
+ """A version information tuple."""
344
+
345
+ version: str
346
+ url: str
347
+ path: Path
348
+
349
+
350
+ def get_ror_status(*, force: bool = False, authenticate_zenodo: bool = True) -> RORStatus:
351
+ """Ensure the latest ROR record, metadata, and filepath.
352
+
353
+ :param force: Should the record be downloaded again? This almost
354
+ never needs to be true, since the data doesn't change for
355
+ a given version
356
+ :param authenticate_zenodo: Should Zenodo be authenticated?
357
+ This isn't required, but can help avoid rate limits
358
+ :return: A version information tuple
359
+
360
+ .. note::
361
+
362
+ this goes into the ``~/.data/zenodo/6347574`` folder,
363
+ because 6347574 is the super-record ID, which groups all
364
+ versions together. this is different from the value
365
+ for :data:`ROR_ZENODO_RECORD_ID`
366
+ """
367
+ client = zenodo_client.Zenodo()
368
+ latest_record_id = client.get_latest_record(
369
+ ROR_ZENODO_RECORD_ID, authenticate=authenticate_zenodo
370
+ )
371
+ response = client.get_record(latest_record_id, authenticate=authenticate_zenodo)
372
+ response_json = response.json()
373
+ version = response_json["metadata"]["version"].lstrip("v")
374
+ file_record = response_json["files"][0]
375
+ name = file_record["key"]
376
+ url = file_record["links"]["self"]
377
+ path = client.download(latest_record_id, name=name, force=force)
378
+ return RORStatus(version=version, url=url, path=path)
379
+
380
+
381
+ @lru_cache
382
+ def get_ror_records(
383
+ *, force: bool = False, authenticate_zenodo: bool = True
384
+ ) -> tuple[RORStatus, list[Record]]:
385
+ """Get the latest ROR metadata and records."""
386
+ status = get_ror_status(force=force, authenticate_zenodo=authenticate_zenodo)
387
+ with zipfile.ZipFile(status.path) as zf:
388
+ for zip_info in zf.filelist:
389
+ if zip_info.filename.endswith(".json"):
390
+ with zf.open(zip_info) as file:
391
+ records = [
392
+ Record.model_validate(record)
393
+ for record in tqdm(json.load(file), unit_scale=True)
394
+ ]
395
+ return status, records
396
+ raise FileNotFoundError
397
+
398
+
399
+ def get_ror_to_country_geonames(**kwargs: Any) -> dict[str, str]:
400
+ """Get a mapping of ROR ids to GeoNames IDs for countries."""
401
+ from pyobo.sources.geonames.geonames import get_city_to_country
402
+
403
+ city_to_country = get_city_to_country()
404
+ rv = {}
405
+ for term in iterate_ror_terms(**kwargs):
406
+ city_geonames_reference = term.get_relationship(located_in)
407
+ if city_geonames_reference is None:
408
+ continue
409
+ if city_geonames_reference.identifier in city_to_country:
410
+ rv[term.identifier] = city_to_country[city_geonames_reference.identifier]
411
+ return rv
412
+
413
+
414
+ if __name__ == "__main__":
415
+ RORGetter.cli()
@@ -611,6 +611,11 @@ class Obo:
611
611
 
612
612
  ontology_version_iri: ClassVar[str | None] = None
613
613
 
614
+ #: Allow skipping adding maintainers annotations, in case
615
+ #: the resource maintainers don't want their names associated
616
+ #: with the OWL exports that e.g. end up on EBI OLS
617
+ skip_maintainers: ClassVar[bool] = False
618
+
614
619
  def __post_init__(self):
615
620
  """Run post-init checks."""
616
621
  if self.ontology is None:
@@ -978,19 +983,22 @@ class Obo:
978
983
  yield Annotation(v.has_logo, OBOLiteral.uri(logo))
979
984
  if mailing_list := resource.get_mailing_list():
980
985
  yield Annotation(v.has_mailing_list, OBOLiteral.string(mailing_list))
981
- if (maintainer := resource.get_contact()) and maintainer.orcid:
982
- yield Annotation(
983
- v.has_maintainer,
984
- Reference(prefix="orcid", identifier=maintainer.orcid, name=maintainer.name),
985
- )
986
- for maintainer in resource.contact_extras or []:
987
- if maintainer.orcid:
986
+ if not self.skip_maintainers:
987
+ if (maintainer := resource.get_contact()) and maintainer.orcid:
988
988
  yield Annotation(
989
989
  v.has_maintainer,
990
990
  Reference(
991
991
  prefix="orcid", identifier=maintainer.orcid, name=maintainer.name
992
992
  ),
993
993
  )
994
+ for maintainer in resource.contact_extras or []:
995
+ if maintainer.orcid:
996
+ yield Annotation(
997
+ v.has_maintainer,
998
+ Reference(
999
+ prefix="orcid", identifier=maintainer.orcid, name=maintainer.name
1000
+ ),
1001
+ )
994
1002
 
995
1003
  # Root terms
996
1004
  for root_term in self.root_terms or []:
@@ -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 + "}"
@@ -18,7 +18,9 @@ __all__ = [
18
18
  "contributes_to_condition",
19
19
  "default_typedefs",
20
20
  "derives_from_organism",
21
+ "directly_regulates_activity_of",
21
22
  "editor_note",
23
+ "editor_preferred_term",
22
24
  "enables",
23
25
  "ends",
24
26
  "exact_match",
@@ -27,6 +29,7 @@ __all__ = [
27
29
  "gene_product_member_of",
28
30
  "has_contributor",
29
31
  "has_creator",
32
+ "has_curation_status",
30
33
  "has_dbxref",
31
34
  "has_depiction",
32
35
  "has_end_date",
@@ -42,19 +45,27 @@ __all__ = [
42
45
  "has_role",
43
46
  "has_salt",
44
47
  "has_smiles",
48
+ "has_source",
45
49
  "has_start_date",
46
50
  "has_successor",
47
51
  "has_taxonomy_rank",
48
52
  "is_a",
53
+ "is_agonist_of",
54
+ "is_antagonist_of",
55
+ "is_defined_by",
56
+ "is_inverse_agonist_of",
49
57
  "located_in",
50
58
  "mapping_has_confidence",
51
59
  "mapping_has_justification",
52
60
  "match_typedefs",
61
+ "may_be_identical_to",
53
62
  "member_of",
54
63
  "narrow_match",
64
+ "negatively_regulates",
55
65
  "orthologous",
56
66
  "part_of",
57
67
  "participates_in",
68
+ "positively_regulates",
58
69
  "related_match",
59
70
  "role_of",
60
71
  "see_also",
@@ -145,6 +156,10 @@ subproperty_of = TypeDef(reference=v.subproperty_of)
145
156
  see_also = TypeDef(reference=v.see_also, is_metadata_tag=True)
146
157
  comment = TypeDef(reference=v.comment, is_metadata_tag=True)
147
158
  label = TypeDef(reference=v.label, is_metadata_tag=True)
159
+ is_defined_by = TypeDef(
160
+ reference=Reference(prefix="rdfs", identifier="isDefinedBy", name="is defined by"),
161
+ is_metadata_tag=True,
162
+ )
148
163
  has_member = TypeDef(
149
164
  reference=Reference(prefix=RO_PREFIX, identifier="0002351", name="has member"),
150
165
  )
@@ -221,6 +236,17 @@ definition_source = TypeDef(
221
236
  reference=Reference(prefix=IAO_PREFIX, identifier="0000119", name="definition source"),
222
237
  is_metadata_tag=True,
223
238
  )
239
+ may_be_identical_to = TypeDef(
240
+ reference=Reference(prefix=IAO_PREFIX, identifier="0006011", name="may be identical to")
241
+ )
242
+ # todo this is also useful for SSSLM
243
+ editor_preferred_term = TypeDef(
244
+ reference=Reference(prefix=IAO_PREFIX, identifier="0000111", name="editor preferred term")
245
+ )
246
+ has_curation_status = TypeDef(
247
+ reference=Reference(prefix=IAO_PREFIX, identifier="0000114", name="has curation status")
248
+ )
249
+
224
250
  has_dbxref = TypeDef(reference=v.has_dbxref, is_metadata_tag=True)
225
251
 
226
252
  editor_note = TypeDef(
@@ -267,6 +293,19 @@ has_functional_parent = TypeDef(
267
293
  reference=Reference(prefix="ro", identifier="0018038", name="has functional parent"),
268
294
  )
269
295
 
296
+ positively_regulates = TypeDef(
297
+ Reference(prefix="RO", identifier="0002213", name="positively regulates")
298
+ )
299
+ negatively_regulates = TypeDef(
300
+ Reference(prefix="RO", identifier="0002212", name="negatively regulates")
301
+ )
302
+ is_agonist_of = TypeDef.from_triple("RO", "0018027", "is agonist of")
303
+ is_inverse_agonist_of = TypeDef.from_triple("RO", "0018028", "is inverse agonist of")
304
+ is_antagonist_of = TypeDef.from_triple("RO", "0018029", "is antagonist of")
305
+ directly_regulates_activity_of = TypeDef.from_triple(
306
+ "RO", "0002448", "directly regulates activity of"
307
+ )
308
+
270
309
  is_mentioned_by = TypeDef(
271
310
  reference=v.is_mentioned_by,
272
311
  is_metadata_tag=True,