graph-databases 20210214.2__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.
- graph_databases/__init__.py +123 -0
- graph_databases/data/__init__.py +2 -0
- graph_databases/data/brouwer_srg_database.json +1 -0
- graph_databases/data/graphs.db +0 -0
- graph_databases/data/isgci_sage.xml +11116 -0
- graph_databases/data/smallgraphs.txt +565 -0
- graph_databases-20210214.2.dist-info/METADATA +114 -0
- graph_databases-20210214.2.dist-info/RECORD +12 -0
- graph_databases-20210214.2.dist-info/WHEEL +5 -0
- graph_databases-20210214.2.dist-info/licenses/DATA_LICENSES.md +42 -0
- graph_databases-20210214.2.dist-info/licenses/LICENSE +338 -0
- graph_databases-20210214.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"""Read-only access to the graph data resources distributed by this package."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Iterator
|
|
6
|
+
from contextlib import contextmanager
|
|
7
|
+
from importlib.resources import as_file, files
|
|
8
|
+
import json
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
import sqlite3
|
|
11
|
+
from typing import IO, Any, Literal, Optional, overload
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"DATA_FILES",
|
|
15
|
+
"__version__",
|
|
16
|
+
"graph_database_connection",
|
|
17
|
+
"load_brouwer_database",
|
|
18
|
+
"open_resource",
|
|
19
|
+
"resource",
|
|
20
|
+
"resource_path",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
__version__ = "20210214.2"
|
|
24
|
+
|
|
25
|
+
DATA_FILES = (
|
|
26
|
+
"brouwer_srg_database.json",
|
|
27
|
+
"graphs.db",
|
|
28
|
+
"isgci_sage.xml",
|
|
29
|
+
"smallgraphs.txt",
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
_DATA_PACKAGE = "graph_databases.data"
|
|
33
|
+
_TEXT_ENCODINGS = {
|
|
34
|
+
"brouwer_srg_database.json": "utf-8",
|
|
35
|
+
"isgci_sage.xml": "iso-8859-1",
|
|
36
|
+
"smallgraphs.txt": "utf-8",
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def resource(name: str) -> Any:
|
|
41
|
+
"""Return the package resource named *name*.
|
|
42
|
+
|
|
43
|
+
Only the four documented top-level filenames are accepted. Restricting
|
|
44
|
+
names prevents accidental path traversal and makes the public data surface
|
|
45
|
+
explicit.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
if name not in DATA_FILES:
|
|
49
|
+
choices = ", ".join(DATA_FILES)
|
|
50
|
+
raise ValueError(f"unknown graph data resource {name!r}; choose from {choices}")
|
|
51
|
+
return files(_DATA_PACKAGE).joinpath(name)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@overload
|
|
55
|
+
def open_resource(
|
|
56
|
+
name: str, mode: Literal["rb"] = "rb", *, encoding: None = None
|
|
57
|
+
) -> IO[bytes]: ...
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@overload
|
|
61
|
+
def open_resource(
|
|
62
|
+
name: str, mode: Literal["r"], *, encoding: Optional[str] = None
|
|
63
|
+
) -> IO[str]: ...
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def open_resource(
|
|
67
|
+
name: str,
|
|
68
|
+
mode: Literal["r", "rb"] = "rb",
|
|
69
|
+
*,
|
|
70
|
+
encoding: Optional[str] = None,
|
|
71
|
+
) -> IO[Any]:
|
|
72
|
+
"""Open a bundled resource for reading.
|
|
73
|
+
|
|
74
|
+
Binary mode is the default. Text mode uses the resource's known encoding
|
|
75
|
+
unless *encoding* is supplied explicitly. Write and update modes are not
|
|
76
|
+
supported.
|
|
77
|
+
"""
|
|
78
|
+
|
|
79
|
+
item = resource(name)
|
|
80
|
+
if mode == "rb":
|
|
81
|
+
if encoding is not None:
|
|
82
|
+
raise ValueError("encoding is only valid in text mode")
|
|
83
|
+
return item.open("rb")
|
|
84
|
+
if mode == "r":
|
|
85
|
+
selected_encoding = encoding or _TEXT_ENCODINGS.get(name, "utf-8")
|
|
86
|
+
return item.open("r", encoding=selected_encoding)
|
|
87
|
+
raise ValueError("mode must be 'r' or 'rb'")
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
@contextmanager
|
|
91
|
+
def resource_path(name: str) -> Iterator[Path]:
|
|
92
|
+
"""Yield a filesystem path for a bundled resource.
|
|
93
|
+
|
|
94
|
+
The path is only guaranteed to remain valid for the duration of the
|
|
95
|
+
context, which also supports importers that must extract resources.
|
|
96
|
+
"""
|
|
97
|
+
|
|
98
|
+
with as_file(resource(name)) as path:
|
|
99
|
+
yield path
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@contextmanager
|
|
103
|
+
def graph_database_connection() -> Iterator[sqlite3.Connection]:
|
|
104
|
+
"""Yield a read-only connection to the bundled ``graphs.db`` database."""
|
|
105
|
+
|
|
106
|
+
with resource_path("graphs.db") as database_path:
|
|
107
|
+
uri = f"{database_path.resolve().as_uri()}?mode=ro&immutable=1"
|
|
108
|
+
connection = sqlite3.connect(uri, uri=True)
|
|
109
|
+
try:
|
|
110
|
+
connection.execute("PRAGMA query_only = ON")
|
|
111
|
+
yield connection
|
|
112
|
+
finally:
|
|
113
|
+
connection.close()
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def load_brouwer_database() -> list[list[Any]]:
|
|
117
|
+
"""Decode and return the records in ``brouwer_srg_database.json``."""
|
|
118
|
+
|
|
119
|
+
with open_resource("brouwer_srg_database.json", "r") as stream:
|
|
120
|
+
data = json.load(stream)
|
|
121
|
+
if not isinstance(data, list):
|
|
122
|
+
raise ValueError("Brouwer database must contain a JSON list")
|
|
123
|
+
return data
|