biocypher 0.9.0__tar.gz → 0.9.2__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.

Potentially problematic release.


This version of biocypher might be problematic. Click here for more details.

Files changed (44) hide show
  1. {biocypher-0.9.0 → biocypher-0.9.2}/PKG-INFO +1 -2
  2. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/_core.py +25 -4
  3. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/_metadata.py +1 -1
  4. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/_misc.py +51 -43
  5. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/output/write/_get_writer.py +1 -1
  6. {biocypher-0.9.0 → biocypher-0.9.2}/pyproject.toml +1 -2
  7. {biocypher-0.9.0 → biocypher-0.9.2}/LICENSE +0 -0
  8. {biocypher-0.9.0 → biocypher-0.9.2}/README.md +0 -0
  9. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/__init__.py +0 -0
  10. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/_config/__init__.py +0 -0
  11. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/_config/biocypher_config.yaml +0 -0
  12. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/_config/test_config.yaml +0 -0
  13. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/_config/test_schema_config.yaml +0 -0
  14. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/_config/test_schema_config_disconnected.yaml +0 -0
  15. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/_config/test_schema_config_extended.yaml +0 -0
  16. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/_create.py +0 -0
  17. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/_deduplicate.py +0 -0
  18. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/_get.py +0 -0
  19. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/_logger.py +0 -0
  20. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/_mapping.py +0 -0
  21. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/_ontology.py +0 -0
  22. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/_translate.py +0 -0
  23. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/output/__init__.py +0 -0
  24. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/output/connect/__init__.py +0 -0
  25. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/output/connect/_get_connector.py +0 -0
  26. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/output/connect/_neo4j_driver.py +0 -0
  27. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/output/in_memory/__init__.py +0 -0
  28. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/output/in_memory/_get_in_memory_kg.py +0 -0
  29. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/output/in_memory/_in_memory_kg.py +0 -0
  30. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/output/in_memory/_networkx.py +0 -0
  31. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/output/in_memory/_pandas.py +0 -0
  32. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/output/write/__init__.py +0 -0
  33. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/output/write/_batch_writer.py +0 -0
  34. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/output/write/_writer.py +0 -0
  35. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/output/write/graph/__init__.py +0 -0
  36. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/output/write/graph/_arangodb.py +0 -0
  37. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/output/write/graph/_neo4j.py +0 -0
  38. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/output/write/graph/_networkx.py +0 -0
  39. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/output/write/graph/_owl.py +0 -0
  40. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/output/write/graph/_rdf.py +0 -0
  41. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/output/write/relational/__init__.py +0 -0
  42. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/output/write/relational/_csv.py +0 -0
  43. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/output/write/relational/_postgresql.py +0 -0
  44. {biocypher-0.9.0 → biocypher-0.9.2}/biocypher/output/write/relational/_sqlite.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: biocypher
3
- Version: 0.9.0
3
+ Version: 0.9.2
4
4
  Summary: A unifying framework for biomedical research knowledge graphs
5
5
  Home-page: https://github.com/biocypher/biocypher
6
6
  License: MIT
@@ -27,7 +27,6 @@ Requires-Dist: networkx (>=3.0,<4.0)
27
27
  Requires-Dist: pandas (>=2.0.1,<3.0.0)
28
28
  Requires-Dist: pooch (>=1.7.0,<2.0.0)
29
29
  Requires-Dist: rdflib (>=6.2.0,<7.0.0)
30
- Requires-Dist: stringcase (>=1.2.0,<2.0.0)
31
30
  Requires-Dist: tqdm (>=4.65.0,<5.0.0)
32
31
  Requires-Dist: treelib (==1.6.4)
33
32
  Project-URL: Bug Tracker, https://github.com/biocypher/biocypher/issues
@@ -118,6 +118,15 @@ class BioCypher:
118
118
  else:
119
119
  self._offline = offline
120
120
 
121
+ # Check if pandas/tabular is being used in offline mode
122
+ if self._offline and self._dbms.lower() in ["pandas", "tabular"]:
123
+ msg = (
124
+ f"The '{self._dbms}' DBMS is only available in online mode. "
125
+ f"If you want to write CSV files, use 'csv' as the DBMS. "
126
+ f"If you want to use pandas, set 'offline: false' in your configuration."
127
+ )
128
+ raise ValueError(msg)
129
+
121
130
  if strict_mode is None:
122
131
  self._strict_mode = self.base_config["strict_mode"]
123
132
  else:
@@ -225,19 +234,31 @@ class BioCypher:
225
234
  The knowledge graph is returned based on the `dbms` parameter in
226
235
  the biocypher configuration file.
227
236
 
237
+ TODO: These conditionals are a hack, we need to refactor the in-memory
238
+ KG to be generic, and simplify access and conversion to output formats.
239
+
228
240
  Returns
229
241
  -------
230
242
  Any: knowledge graph.
231
243
 
232
244
  """
245
+ # If we're using an in-memory KG and it already exists, return it directly
246
+ if self._in_memory_kg and self._is_online_and_in_memory():
247
+ return self._in_memory_kg.get_kg()
248
+
249
+ # Otherwise, initialize and populate the in-memory KG
233
250
  if not self._in_memory_kg:
234
251
  self._initialize_in_memory_kg()
235
252
  if not self._translator:
236
253
  self._get_translator()
237
- tnodes = self._translator.translate_entities(self._nodes)
238
- tedges = self._translator.translate_entities(self._edges)
239
- self._in_memory_kg.add_nodes(tnodes)
240
- self._in_memory_kg.add_edges(tedges)
254
+
255
+ # These attributes might not exist when using in-memory KG directly
256
+ if hasattr(self, "_nodes") and hasattr(self, "_edges"):
257
+ tnodes = self._translator.translate_entities(self._nodes)
258
+ tedges = self._translator.translate_entities(self._edges)
259
+ self._in_memory_kg.add_nodes(tnodes)
260
+ self._in_memory_kg.add_edges(tedges)
261
+
241
262
  return self._in_memory_kg.get_kg()
242
263
 
243
264
  def _get_deduplicator(self) -> Deduplicator:
@@ -10,7 +10,7 @@ import pathlib
10
10
 
11
11
  import toml
12
12
 
13
- _VERSION = "0.9.0"
13
+ _VERSION = "0.9.2"
14
14
 
15
15
 
16
16
  def get_metadata():
@@ -1,22 +1,18 @@
1
- """
2
- Handy functions for use in various places.
3
- """
1
+ """Handy functions for use in various places."""
4
2
 
5
3
  import re
6
4
 
7
- from collections.abc import Iterable
8
- from typing import (
9
- Any,
5
+ from collections.abc import (
10
6
  Generator,
11
7
  ItemsView,
8
+ Iterable,
12
9
  KeysView,
13
10
  Mapping,
14
- Union,
15
11
  ValuesView,
16
12
  )
13
+ from typing import Any
17
14
 
18
15
  import networkx as nx
19
- import stringcase
20
16
 
21
17
  from treelib import Tree
22
18
 
@@ -48,10 +44,7 @@ LIST_LIKE = (
48
44
 
49
45
 
50
46
  def to_list(value: Any) -> list:
51
- """
52
- Ensures that ``value`` is a list.
53
- """
54
-
47
+ """Ensure that ``value`` is a list."""
55
48
  if isinstance(value, LIST_LIKE):
56
49
  value = list(value)
57
50
 
@@ -62,17 +55,12 @@ def to_list(value: Any) -> list:
62
55
 
63
56
 
64
57
  def ensure_iterable(value: Any) -> Iterable:
65
- """
66
- Returns iterables, except strings, wraps simple types into tuple.
67
- """
68
-
58
+ """Return iterables, except strings, wrap simple types into tuple."""
69
59
  return value if isinstance(value, LIST_LIKE) else (value,)
70
60
 
71
61
 
72
- def create_tree_visualisation(inheritance_graph: Union[dict, nx.Graph]) -> Tree:
73
- """
74
- Creates a visualisation of the inheritance tree using treelib.
75
- """
62
+ def create_tree_visualisation(inheritance_graph: dict | nx.Graph) -> Tree:
63
+ """Create a visualisation of the inheritance tree using treelib."""
76
64
  inheritance_tree = _get_inheritance_tree(inheritance_graph)
77
65
  classes, root = _find_root_node(inheritance_tree)
78
66
 
@@ -91,38 +79,42 @@ def create_tree_visualisation(inheritance_graph: Union[dict, nx.Graph]) -> Tree:
91
79
  return tree
92
80
 
93
81
 
94
- def _get_inheritance_tree(inheritance_graph: Union[dict, nx.Graph]) -> dict:
95
- """Transforms an inheritance_graph into an inheritance_tree.
82
+ def _get_inheritance_tree(inheritance_graph: dict | nx.Graph) -> dict | None:
83
+ """Transform an inheritance_graph into an inheritance_tree.
96
84
 
97
85
  Args:
86
+ ----
98
87
  inheritance_graph: A dict or nx.Graph representing the inheritance graph.
99
88
 
100
89
  Returns:
90
+ -------
101
91
  A dict representing the inheritance tree.
92
+
102
93
  """
103
94
  if isinstance(inheritance_graph, nx.Graph):
104
95
  inheritance_tree = nx.to_dict_of_lists(inheritance_graph)
105
96
 
106
97
  multiple_parents_present = _multiple_inheritance_present(inheritance_tree)
107
98
  if multiple_parents_present:
108
- logger.warning(
99
+ msg = (
109
100
  "The ontology contains multiple inheritance (one child node "
110
101
  "has multiple parent nodes). This is not visualized in the "
111
102
  "following hierarchy tree (the child node is only added once). "
112
103
  "If you wish to browse all relationships of the parsed "
113
104
  "ontologies, write a graphml file to disk using "
114
- "`to_disk = <directory>` and view this file."
105
+ "`to_disk = <directory>` and view this file.",
115
106
  )
116
-
107
+ logger.warning(msg)
117
108
  # unlist values
118
109
  inheritance_tree = {k: v[0] for k, v in inheritance_tree.items() if v}
119
110
  return inheritance_tree
120
111
  elif not _multiple_inheritance_present(inheritance_graph):
121
112
  return inheritance_graph
113
+ return None # Explicit return for the case when neither condition is met
122
114
 
123
115
 
124
116
  def _multiple_inheritance_present(inheritance_tree: dict) -> bool:
125
- """Checks if multiple inheritance is present in the inheritance_tree."""
117
+ """Check if multiple inheritance is present in the inheritance_tree."""
126
118
  return any(len(value) > 1 for value in inheritance_tree.values())
127
119
 
128
120
 
@@ -134,7 +126,9 @@ def _find_root_node(inheritance_tree: dict) -> tuple[set, str]:
134
126
  if "entity" in root:
135
127
  root = "entity" # TODO: default: good standard?
136
128
  else:
137
- raise ValueError("Inheritance tree cannot have more than one root node. " f"Found {len(root)}: {root}.")
129
+ msg = f"Inheritance tree cannot have more than one root node. Found {len(root)}: {root}."
130
+ logger.error(msg)
131
+ raise ValueError(msg)
138
132
  else:
139
133
  root = root[0]
140
134
  if not root:
@@ -158,53 +152,62 @@ def from_pascal(s: str, sep: str = " ") -> str:
158
152
 
159
153
 
160
154
  def pascalcase_to_sentencecase(s: str) -> str:
161
- """
162
- Convert PascalCase to sentence case.
155
+ """Convert PascalCase to sentence case.
163
156
 
164
157
  Args:
158
+ ----
165
159
  s: Input string in PascalCase
166
160
 
167
161
  Returns:
162
+ -------
168
163
  string in sentence case form
164
+
169
165
  """
170
166
  return from_pascal(s, sep=" ")
171
167
 
172
168
 
173
169
  def snakecase_to_sentencecase(s: str) -> str:
174
- """
175
- Convert snake_case to sentence case.
170
+ """Convert snake_case to sentence case.
176
171
 
177
172
  Args:
173
+ ----
178
174
  s: Input string in snake_case
179
175
 
180
176
  Returns:
177
+ -------
181
178
  string in sentence case form
179
+
182
180
  """
183
- return stringcase.sentencecase(s).lower()
181
+ return " ".join(word.lower() for word in s.split("_"))
184
182
 
185
183
 
186
184
  def sentencecase_to_snakecase(s: str) -> str:
187
- """
188
- Convert sentence case to snake_case.
185
+ """Convert sentence case to snake_case.
189
186
 
190
187
  Args:
188
+ ----
191
189
  s: Input string in sentence case
192
190
 
193
191
  Returns:
192
+ -------
194
193
  string in snake_case form
194
+
195
195
  """
196
- return stringcase.snakecase(s).lower()
196
+ return "_".join(s.lower().split())
197
197
 
198
198
 
199
199
  def sentencecase_to_pascalcase(s: str, sep: str = r"\s") -> str:
200
- """
201
- Convert sentence case to PascalCase.
200
+ """Convert sentence case to PascalCase.
202
201
 
203
202
  Args:
203
+ ----
204
204
  s: Input string in sentence case
205
+ sep: Separator for the words in the input string
205
206
 
206
207
  Returns:
208
+ -------
207
209
  string in PascalCase form
210
+
208
211
  """
209
212
  return re.sub(
210
213
  r"(?:^|[" + sep + "])([a-zA-Z])",
@@ -214,15 +217,18 @@ def sentencecase_to_pascalcase(s: str, sep: str = r"\s") -> str:
214
217
 
215
218
 
216
219
  def to_lower_sentence_case(s: str) -> str:
217
- """
218
- Convert any string to lower sentence case. Works with snake_case,
219
- PascalCase, and sentence case.
220
+ """Convert any string to lower sentence case.
221
+
222
+ Works with snake_case, PascalCase, and sentence case.
220
223
 
221
224
  Args:
225
+ ----
222
226
  s: Input string
223
227
 
224
228
  Returns:
229
+ -------
225
230
  string in lower sentence case form
231
+
226
232
  """
227
233
  if "_" in s:
228
234
  return snakecase_to_sentencecase(s)
@@ -234,15 +240,17 @@ def to_lower_sentence_case(s: str) -> str:
234
240
  return s
235
241
 
236
242
 
237
- def is_nested(lst) -> bool:
238
- """
239
- Check if a list is nested.
243
+ def is_nested(lst: list) -> bool:
244
+ """Check if a list is nested.
240
245
 
241
246
  Args:
247
+ ----
242
248
  lst (list): The list to check.
243
249
 
244
250
  Returns:
251
+ -------
245
252
  bool: True if the list is nested, False otherwise.
253
+
246
254
  """
247
255
  for item in lst:
248
256
  if isinstance(item, list):
@@ -75,7 +75,7 @@ def get_writer(
75
75
  instance: an instance of the selected writer class.
76
76
 
77
77
  """
78
- dbms_config = _config(dbms)
78
+ dbms_config = _config(dbms) or {}
79
79
 
80
80
  writer = DBMS_TO_CLASS[dbms]
81
81
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "biocypher"
3
- version = "0.9.0"
3
+ version = "0.9.2"
4
4
  description = "A unifying framework for biomedical research knowledge graphs"
5
5
  authors = [
6
6
  "Sebastian Lobentanzer <sebastian.lobentanzer@gmail.com>",
@@ -40,7 +40,6 @@ appdirs = "*"
40
40
  treelib = "1.6.4"
41
41
  rdflib = "^6.2.0"
42
42
  networkx = "^3.0"
43
- stringcase = "^1.2.0"
44
43
  neo4j-utils = "0.0.7"
45
44
  pandas = "^2.0.1"
46
45
  pooch = "^1.7.0"
File without changes
File without changes
File without changes