biocypher 0.5.40__py3-none-any.whl → 0.5.41__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.

Potentially problematic release.


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

biocypher/_connect.py CHANGED
@@ -11,11 +11,12 @@
11
11
  """
12
12
  BioCypher 'online' mode. Handles connection and manipulation of a running DBMS.
13
13
  """
14
+ import subprocess
15
+
14
16
  from ._logger import logger
15
17
 
16
18
  logger.debug(f"Loading module {__name__}.")
17
19
 
18
- from typing import Optional
19
20
  from collections.abc import Iterable
20
21
  import itertools
21
22
 
@@ -24,7 +25,6 @@ import neo4j_utils
24
25
  from . import _misc
25
26
  from ._config import config as _config
26
27
  from ._create import BioCypherEdge, BioCypherNode
27
- from ._ontology import Ontology
28
28
  from ._translate import Translator
29
29
 
30
30
  __all__ = ["_Neo4jDriver"]
@@ -137,16 +137,43 @@ class _Neo4jDriver:
137
137
 
138
138
  logger.info("Creating constraints for node types in config.")
139
139
 
140
+ major_neo4j_version = int(self._get_neo4j_version().split(".")[0])
140
141
  # get structure
141
142
  for leaf in self.translator.ontology.mapping.extended_schema.items():
142
- label = _misc.sentencecase_to_pascalcase(leaf[0])
143
+ label = _misc.sentencecase_to_pascalcase(leaf[0], sep=r"\s\.")
143
144
  if leaf[1]["represented_as"] == "node":
144
- s = (
145
- f"CREATE CONSTRAINT `{label}_id` "
146
- f"IF NOT EXISTS ON (n:`{label}`) "
147
- "ASSERT n.id IS UNIQUE"
148
- )
149
- self._driver.query(s)
145
+ if major_neo4j_version >= 5:
146
+ s = (
147
+ f"CREATE CONSTRAINT `{label}_id` "
148
+ f"IF NOT EXISTS FOR (n:`{label}`) "
149
+ "REQUIRE n.id IS UNIQUE"
150
+ )
151
+ self._driver.query(s)
152
+ else:
153
+ s = (
154
+ f"CREATE CONSTRAINT `{label}_id` "
155
+ f"IF NOT EXISTS ON (n:`{label}`) "
156
+ "ASSERT n.id IS UNIQUE"
157
+ )
158
+ self._driver.query(s)
159
+
160
+ def _get_neo4j_version(self):
161
+ """Get neo4j version."""
162
+ try:
163
+ neo4j_version = self._driver.query(
164
+ """
165
+ CALL dbms.components()
166
+ YIELD name, versions, edition
167
+ UNWIND versions AS version
168
+ RETURN version AS version
169
+ """,
170
+ )[0][0]["version"]
171
+ return neo4j_version
172
+ except Exception as e:
173
+ logger.warning(
174
+ f"Error detecting Neo4j version: {e} use default version 4.0.0."
175
+ )
176
+ return "4.0.0"
150
177
 
151
178
  def add_nodes(self, id_type_tuples: Iterable[tuple]) -> tuple:
152
179
  """
biocypher/_metadata.py CHANGED
@@ -19,7 +19,7 @@ import importlib.metadata
19
19
 
20
20
  import toml
21
21
 
22
- _VERSION = "0.5.40"
22
+ _VERSION = "0.5.41"
23
23
 
24
24
 
25
25
  def get_metadata():
biocypher/_misc.py CHANGED
@@ -205,7 +205,7 @@ def sentencecase_to_snakecase(s: str) -> str:
205
205
  return stringcase.snakecase(s).lower()
206
206
 
207
207
 
208
- def sentencecase_to_pascalcase(s: str) -> str:
208
+ def sentencecase_to_pascalcase(s: str, sep: str = r"\s") -> str:
209
209
  """
210
210
  Convert sentence case to PascalCase.
211
211
 
@@ -215,7 +215,11 @@ def sentencecase_to_pascalcase(s: str) -> str:
215
215
  Returns:
216
216
  string in PascalCase form
217
217
  """
218
- return re.sub(r"(?:^| )([a-zA-Z])", lambda match: match.group(1).upper(), s)
218
+ return re.sub(
219
+ r"(?:^|[" + sep + "])([a-zA-Z])",
220
+ lambda match: match.group(1).upper(),
221
+ s,
222
+ )
219
223
 
220
224
 
221
225
  def to_lower_sentence_case(s: str) -> str:
biocypher/write/_write.py CHANGED
@@ -25,7 +25,7 @@ from typing import TYPE_CHECKING
25
25
 
26
26
  from biocypher._config import config as _config
27
27
 
28
- __all__ = ["get_writer"]
28
+ __all__ = ["get_writer", "DBMS_TO_CLASS"]
29
29
 
30
30
  if TYPE_CHECKING:
31
31
  from biocypher._translate import Translator
@@ -1,4 +1,6 @@
1
1
  import os
2
+ import re
3
+ import subprocess
2
4
 
3
5
  from biocypher._logger import logger
4
6
  from biocypher.write._batch_writer import parse_label, _BatchWriter
@@ -22,6 +24,19 @@ class _Neo4jBatchWriter(_BatchWriter):
22
24
  - _write_array_string
23
25
  """
24
26
 
27
+ def __init__(self, *args, **kwargs):
28
+ """
29
+ Constructor.
30
+
31
+ Check the version of Neo4j and adds a command scope if version >= 5.
32
+
33
+ Returns:
34
+ _Neo4jBatchWriter: An instance of the writer.
35
+ """
36
+
37
+ # Should read the configuration and setup import_call_bin_prefix.
38
+ super().__init__(*args, **kwargs)
39
+
25
40
  def _get_default_import_call_bin_prefix(self):
26
41
  """
27
42
  Method to provide the default string for the import call bin prefix.
@@ -29,6 +44,7 @@ class _Neo4jBatchWriter(_BatchWriter):
29
44
  Returns:
30
45
  str: The default location for the neo4j admin import location
31
46
  """
47
+
32
48
  return "bin/"
33
49
 
34
50
  def _write_array_string(self, string_list):
@@ -263,9 +279,32 @@ class _Neo4jBatchWriter(_BatchWriter):
263
279
  Returns:
264
280
  str: a bash command for neo4j-admin import
265
281
  """
282
+ import_call_neo4j_v4 = self._get_import_call(
283
+ "import", "--database=", "--force="
284
+ )
285
+ import_call_neo4j_v5 = self._get_import_call(
286
+ "database import full", "", "--overwrite-destination="
287
+ )
288
+ neo4j_version_check = f"version=$({self._get_default_import_call_bin_prefix()}neo4j-admin --version | cut -d '.' -f 1)"
289
+
290
+ import_script = f"#!/bin/bash\n{neo4j_version_check}\nif [[ $version -ge 5 ]]; then\n\t{import_call_neo4j_v5}\nelse\n\t{import_call_neo4j_v4}\nfi"
291
+ return import_script
292
+
293
+ def _get_import_call(
294
+ self, import_cmd: str, database_cmd: str, wipe_cmd: str
295
+ ) -> str:
296
+ """Get parametrized import call for Neo4j 4 or 5+.
297
+
298
+ Args:
299
+ import_cmd (str): The import command to use.
300
+ database_cmd (str): The database command to use.
301
+ wipe_cmd (str): The wipe command to use.
302
+
303
+ Returns:
304
+ str: The import call.
305
+ """
266
306
  import_call = (
267
- f"{self.import_call_bin_prefix}neo4j-admin import "
268
- f"--database={self.db_name} "
307
+ f"{self.import_call_bin_prefix}neo4j-admin {import_cmd} "
269
308
  f'--delimiter="{self.escaped_delim}" '
270
309
  f'--array-delimiter="{self.escaped_adelim}" '
271
310
  )
@@ -276,7 +315,7 @@ class _Neo4jBatchWriter(_BatchWriter):
276
315
  import_call += f"--quote='{self.quote}' "
277
316
 
278
317
  if self.wipe:
279
- import_call += f"--force=true "
318
+ import_call += f"{wipe_cmd}true "
280
319
  if self.skip_bad_relationships:
281
320
  import_call += "--skip-bad-relationships=true "
282
321
  if self.skip_duplicate_nodes:
@@ -290,4 +329,6 @@ class _Neo4jBatchWriter(_BatchWriter):
290
329
  for header_path, parts_path in self.import_call_edges:
291
330
  import_call += f'--relationships="{header_path},{parts_path}" '
292
331
 
332
+ # Database needs to be at the end starting with Neo4j 5.0+.
333
+ import_call += f"{database_cmd}{self.db_name} "
293
334
  return import_call
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: biocypher
3
- Version: 0.5.40
3
+ Version: 0.5.41
4
4
  Summary: A unifying framework for biomedical research knowledge graphs
5
5
  Home-page: https://github.com/biocypher/biocypher
6
6
  License: MIT
@@ -5,28 +5,28 @@ biocypher/_config/test_config.yaml,sha256=Np8jeS5_EP6HHOvMKb7B_Tkyqd5YaYlYz_DVsX
5
5
  biocypher/_config/test_schema_config.yaml,sha256=D1600WgEj3iTXrumVU9LIivJHJO36iaxfkOgyam9zVU,3129
6
6
  biocypher/_config/test_schema_config_disconnected.yaml,sha256=Qm8FLxEn2spHcyj_5F859KjcDvKSxNhxDvi4b4LLkvQ,68
7
7
  biocypher/_config/test_schema_config_extended.yaml,sha256=wn3A76142hhjnImhMF6RODbCFESTJ2TtPvcFdIFsAT0,3309
8
- biocypher/_connect.py,sha256=0oSyO6CEIlKL8rHo-HHE7y0FzGfSi4vnEXSDy1TnIUE,12456
8
+ biocypher/_connect.py,sha256=7hk3J03hzZOPE48ISaoB6IgRun8GaUmDtIRnnD7vKiU,13453
9
9
  biocypher/_core.py,sha256=5rZKYie_vSjTYduH8oH-GxLMZuNqLAe3ZYAQ5nUp8Nc,22578
10
10
  biocypher/_create.py,sha256=vpUchUdEpWupZi1LgFLxAWMtqoBwnWbP7PwEDUCBS4A,10202
11
11
  biocypher/_deduplicate.py,sha256=BBvfpXzu6L5YDY5FdtXxnf8YlsbJpbCE8RdUoKsm0n0,4949
12
12
  biocypher/_get.py,sha256=3Kpky3blfNf1JwxKWLsZxTU2aTP_C4sUe8OpiyYj63I,10810
13
13
  biocypher/_logger.py,sha256=NGXe3hZA79WSujfOgpcxHBf8N2QAfrmvM1LFDpsGK2U,3185
14
14
  biocypher/_mapping.py,sha256=ERSNH2Bg19145KytxbFE4BInPaiP-LWW7osOBot29Eo,9304
15
- biocypher/_metadata.py,sha256=AffJrg0s1b35C6caoCs0DlcXtXlEzUXDDylHdUFa_rI,1658
16
- biocypher/_misc.py,sha256=g5B-PO_XJlYEJC7kEVRdCXeB2NW0ZSVr_5KqTEk2ldk,5877
15
+ biocypher/_metadata.py,sha256=GGh6YvKYrRWqdyZQYTaLnkYPaHgVHz00V6kpXQdjr2k,1658
16
+ biocypher/_misc.py,sha256=lUUbF13FdBlYq01C-Vit52IbeRehW0oSUWsQ9tFC-xo,5938
17
17
  biocypher/_ontology.py,sha256=3Wu1ZZYmtLpWfopi-aY9BA8qZ-ltPMXN4Ok_diK1YdA,28410
18
18
  biocypher/_pandas.py,sha256=GVCFM68J7yBjh40MpkNVgD8qT1RFMrrIjMOtD3iKsf4,3040
19
19
  biocypher/_translate.py,sha256=JafvhtVaFSpruRfYh9BzjVbvDF1Mhg7LLKMDZHWkRjg,16496
20
20
  biocypher/write/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
21
  biocypher/write/_batch_writer.py,sha256=Ta2DNjSnJcVtFDMOGTtH5nnbKwyqSGf7xXGpYzi1bDM,36826
22
- biocypher/write/_write.py,sha256=u7m2XaliEgOrKdLddTn-2z6kqICmUmuTDQIcRzIFNY4,3087
22
+ biocypher/write/_write.py,sha256=HLFQyGqLdkmIoBOjL9m81OUuSsHjvSfK9LY4jtrinv0,3104
23
23
  biocypher/write/graph/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
24
  biocypher/write/graph/_arangodb.py,sha256=du5pivCR7xKs8VyxeegxYsSBIcsXGrfSbM_AffFapwg,8071
25
- biocypher/write/graph/_neo4j.py,sha256=dcBQ-OzvMG4gSTlU98k2LeqxRswpirM2XMEX9UEeBjo,10483
25
+ biocypher/write/graph/_neo4j.py,sha256=qSj1PryD4UmveS7ACs1R3eo2pegi53pVI7d7P0ihOKI,11930
26
26
  biocypher/write/relational/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
27
  biocypher/write/relational/_postgresql.py,sha256=NdI-ULP8valsqlkObOg50od-3-amVj5RzGnZ_7NW2ww,11945
28
28
  biocypher/write/relational/_sqlite.py,sha256=KLQpxQXF1B8qqTtKUFfjWdwHjd1Fhn9syK931Z0dsq0,2066
29
- biocypher-0.5.40.dist-info/LICENSE,sha256=SjUaQkq671iQUZOxEUpC4jvJxXOlfSiHTTueyz9kXJM,1065
30
- biocypher-0.5.40.dist-info/METADATA,sha256=ur2IINfCgegTsj3B_ZKdV6BVAomyNX-NF3nDmtmkDjw,10642
31
- biocypher-0.5.40.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
32
- biocypher-0.5.40.dist-info/RECORD,,
29
+ biocypher-0.5.41.dist-info/LICENSE,sha256=SjUaQkq671iQUZOxEUpC4jvJxXOlfSiHTTueyz9kXJM,1065
30
+ biocypher-0.5.41.dist-info/METADATA,sha256=D23b4n9k_oEmXIMC3eKYJLP5MJVVYHkAeAWB8DAFpYk,10642
31
+ biocypher-0.5.41.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
32
+ biocypher-0.5.41.dist-info/RECORD,,