kraph 3.0.1__tar.gz → 4.1.0__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.
- kraph-4.1.0/PKG-INFO +105 -0
- kraph-4.1.0/README.md +91 -0
- kraph-4.1.0/kraph/__init__.py +7 -0
- {kraph-3.0.1 → kraph-4.1.0}/kraph/arkitekt.py +4 -4
- {kraph-3.0.1 → kraph-4.1.0}/kraph/datalayer.py +4 -1
- {kraph-3.0.1 → kraph-4.1.0}/kraph/io.py +4 -1
- {kraph-3.0.1 → kraph-4.1.0}/kraph/traits.py +1 -1
- {kraph-3.0.1 → kraph-4.1.0}/pyproject.toml +5 -2
- kraph-3.0.1/PKG-INFO +0 -30
- kraph-3.0.1/README.md +0 -17
- kraph-3.0.1/kraph/__init__.py +0 -18
- {kraph-3.0.1 → kraph-4.1.0}/.gitignore +0 -0
- {kraph-3.0.1 → kraph-4.1.0}/kraph/api/__init__.py +0 -0
- {kraph-3.0.1 → kraph-4.1.0}/kraph/api/project.json +0 -0
- {kraph-3.0.1 → kraph-4.1.0}/kraph/api/schema.graphql +0 -0
- {kraph-3.0.1 → kraph-4.1.0}/kraph/api/schema.py +0 -0
- {kraph-3.0.1 → kraph-4.1.0}/kraph/client.py +0 -0
- {kraph-3.0.1 → kraph-4.1.0}/kraph/contrib/fakts/__init__.py +0 -0
- {kraph-3.0.1 → kraph-4.1.0}/kraph/errors.py +0 -0
- {kraph-3.0.1 → kraph-4.1.0}/kraph/kraph.py +0 -0
- {kraph-3.0.1 → kraph-4.1.0}/kraph/links/__init__.py +0 -0
- {kraph-3.0.1 → kraph-4.1.0}/kraph/links/errors.py +0 -0
- {kraph-3.0.1 → kraph-4.1.0}/kraph/links/upload.py +0 -0
- {kraph-3.0.1 → kraph-4.1.0}/kraph/py.typed +0 -0
- {kraph-3.0.1 → kraph-4.1.0}/kraph/rath.py +0 -0
- {kraph-3.0.1 → kraph-4.1.0}/kraph/refs.py +0 -0
- {kraph-3.0.1 → kraph-4.1.0}/kraph/scalars.py +0 -0
kraph-4.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: kraph
|
|
3
|
+
Version: 4.1.0
|
|
4
|
+
Summary: the arkitekt knowledge graph
|
|
5
|
+
Author-email: jhnnsrs <jhnnsrs@gmail.com>
|
|
6
|
+
License-Expression: GPL-3.0-or-later
|
|
7
|
+
Requires-Python: <4.0,>=3.11
|
|
8
|
+
Requires-Dist: arkitekt-spec>=1.4
|
|
9
|
+
Requires-Dist: dokker>=2.8
|
|
10
|
+
Requires-Dist: fakts>=4
|
|
11
|
+
Requires-Dist: rath>=4.1.1
|
|
12
|
+
Requires-Dist: websockets>=15.0.1
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
|
|
15
|
+
# kraph
|
|
16
|
+
|
|
17
|
+
[](https://pypi.org/project/kraph/)
|
|
18
|
+
[](https://pypi.python.org/pypi/kraph/)
|
|
19
|
+
|
|
20
|
+
The python client for kraph, the [Arkitekt](https://arkitekt.live) knowledge graph service built
|
|
21
|
+
around Apache AGE: recording claims about entities, events, measurements and metrics, backed by the
|
|
22
|
+
structures (images, tables, …) that are evidence for them, and drawing them into graphs.
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pip install kraph
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
With arkitekt, `pip install "arkitekt[rekuest,kraph]"` brings it in.
|
|
31
|
+
|
|
32
|
+
## Concepts
|
|
33
|
+
|
|
34
|
+
- **Claims** — an entity exists, a structure measures it, two things are related — are recorded
|
|
35
|
+
under a *term*, a word your organization owns, never under a graph. Retracting a claim records a
|
|
36
|
+
position rather than deleting anything.
|
|
37
|
+
- **Graphs** are views. A graph declares *categories* (entity, relation, measurement, event, …)
|
|
38
|
+
that say what its words mean, and draws the claims made under those words.
|
|
39
|
+
|
|
40
|
+
## Usage
|
|
41
|
+
|
|
42
|
+
Every kraph operation is a method of the `Kraph` client, in a blocking and an `a`-prefixed async
|
|
43
|
+
flavour (`kraph.create_graph(...)`, `await kraph.acreate_graph(...)`). What a call returns remembers
|
|
44
|
+
the client, so follow-ups from a result go through the same client.
|
|
45
|
+
|
|
46
|
+
### In an arkitekt app
|
|
47
|
+
|
|
48
|
+
Add the service to your app and ask for `kraph: Kraph`; the client is injected by annotation.
|
|
49
|
+
Graphs, categories, structures, metrics, terms and more travel between actions by id
|
|
50
|
+
(`@kraph/graph`, `@kraph/entitycategory`, `@kraph/structure`, `@kraph/term`, …), so an action can
|
|
51
|
+
take and return them directly:
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
from arkitekt import App, run
|
|
55
|
+
from kraph import Kraph, kraph_service
|
|
56
|
+
|
|
57
|
+
app = App("neuron-claims", "0.1.0", services=[kraph_service])
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@app.action
|
|
61
|
+
def claim_neuron(kraph: Kraph) -> str:
|
|
62
|
+
"""Claim Neuron
|
|
63
|
+
|
|
64
|
+
Records that a neuron exists.
|
|
65
|
+
"""
|
|
66
|
+
asserted = kraph.assert_entity_exists(
|
|
67
|
+
term="Neuron", supporting_evidence=[], derived_from=[], same_as=[]
|
|
68
|
+
)
|
|
69
|
+
return asserted.instance.id
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
if __name__ == "__main__":
|
|
73
|
+
run(app)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### From a script
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
from arkitekt import easy
|
|
80
|
+
from kraph import kraph_service
|
|
81
|
+
|
|
82
|
+
with easy("my-script", kraph_service) as kraph:
|
|
83
|
+
graph = kraph.create_graph(name="Neurons", backfill=False)
|
|
84
|
+
kraph.create_entity_category(
|
|
85
|
+
key="Neuron",
|
|
86
|
+
ontology_references=[],
|
|
87
|
+
property_definitions=[],
|
|
88
|
+
graph=graph.id,
|
|
89
|
+
backfill=True,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
asserted = kraph.assert_entity_exists(
|
|
93
|
+
term="Neuron", supporting_evidence=[], derived_from=[], same_as=[]
|
|
94
|
+
)
|
|
95
|
+
print(asserted.is_drawn) # True: the graph declares "Neuron", so it draws the claim
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Testing
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
uv run pytest -m "not integration" # no server needed
|
|
102
|
+
uv run pytest -m integration # a real kraph via dokker
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
See [RELEASING.md](RELEASING.md) for how versions are cut.
|
kraph-4.1.0/README.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# kraph
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/kraph/)
|
|
4
|
+
[](https://pypi.python.org/pypi/kraph/)
|
|
5
|
+
|
|
6
|
+
The python client for kraph, the [Arkitekt](https://arkitekt.live) knowledge graph service built
|
|
7
|
+
around Apache AGE: recording claims about entities, events, measurements and metrics, backed by the
|
|
8
|
+
structures (images, tables, …) that are evidence for them, and drawing them into graphs.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pip install kraph
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
With arkitekt, `pip install "arkitekt[rekuest,kraph]"` brings it in.
|
|
17
|
+
|
|
18
|
+
## Concepts
|
|
19
|
+
|
|
20
|
+
- **Claims** — an entity exists, a structure measures it, two things are related — are recorded
|
|
21
|
+
under a *term*, a word your organization owns, never under a graph. Retracting a claim records a
|
|
22
|
+
position rather than deleting anything.
|
|
23
|
+
- **Graphs** are views. A graph declares *categories* (entity, relation, measurement, event, …)
|
|
24
|
+
that say what its words mean, and draws the claims made under those words.
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
Every kraph operation is a method of the `Kraph` client, in a blocking and an `a`-prefixed async
|
|
29
|
+
flavour (`kraph.create_graph(...)`, `await kraph.acreate_graph(...)`). What a call returns remembers
|
|
30
|
+
the client, so follow-ups from a result go through the same client.
|
|
31
|
+
|
|
32
|
+
### In an arkitekt app
|
|
33
|
+
|
|
34
|
+
Add the service to your app and ask for `kraph: Kraph`; the client is injected by annotation.
|
|
35
|
+
Graphs, categories, structures, metrics, terms and more travel between actions by id
|
|
36
|
+
(`@kraph/graph`, `@kraph/entitycategory`, `@kraph/structure`, `@kraph/term`, …), so an action can
|
|
37
|
+
take and return them directly:
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from arkitekt import App, run
|
|
41
|
+
from kraph import Kraph, kraph_service
|
|
42
|
+
|
|
43
|
+
app = App("neuron-claims", "0.1.0", services=[kraph_service])
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@app.action
|
|
47
|
+
def claim_neuron(kraph: Kraph) -> str:
|
|
48
|
+
"""Claim Neuron
|
|
49
|
+
|
|
50
|
+
Records that a neuron exists.
|
|
51
|
+
"""
|
|
52
|
+
asserted = kraph.assert_entity_exists(
|
|
53
|
+
term="Neuron", supporting_evidence=[], derived_from=[], same_as=[]
|
|
54
|
+
)
|
|
55
|
+
return asserted.instance.id
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
if __name__ == "__main__":
|
|
59
|
+
run(app)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### From a script
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
from arkitekt import easy
|
|
66
|
+
from kraph import kraph_service
|
|
67
|
+
|
|
68
|
+
with easy("my-script", kraph_service) as kraph:
|
|
69
|
+
graph = kraph.create_graph(name="Neurons", backfill=False)
|
|
70
|
+
kraph.create_entity_category(
|
|
71
|
+
key="Neuron",
|
|
72
|
+
ontology_references=[],
|
|
73
|
+
property_definitions=[],
|
|
74
|
+
graph=graph.id,
|
|
75
|
+
backfill=True,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
asserted = kraph.assert_entity_exists(
|
|
79
|
+
term="Neuron", supporting_evidence=[], derived_from=[], same_as=[]
|
|
80
|
+
)
|
|
81
|
+
print(asserted.is_drawn) # True: the graph declares "Neuron", so it draws the claim
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Testing
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
uv run pytest -m "not integration" # no server needed
|
|
88
|
+
uv run pytest -m integration # a real kraph via dokker
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
See [RELEASING.md](RELEASING.md) for how versions are cut.
|
|
@@ -35,8 +35,8 @@ from rath.links.graphql_ws import GraphQLWSLink
|
|
|
35
35
|
from rath.links.shrink import ShrinkingLink
|
|
36
36
|
from rath.links.split import SplitLink
|
|
37
37
|
|
|
38
|
-
from
|
|
39
|
-
from
|
|
38
|
+
from arkitekt_spec.declare.app import AppRegistry
|
|
39
|
+
from arkitekt_spec.declare.widgets import SearchWidget
|
|
40
40
|
|
|
41
41
|
from kraph.api.schema import (
|
|
42
42
|
EntityCategory,
|
|
@@ -111,8 +111,8 @@ def kraph(
|
|
|
111
111
|
FaktsAuthLink(token_loader=tokens),
|
|
112
112
|
UploadLink(datalayer=store),
|
|
113
113
|
SplitLink(
|
|
114
|
-
left=AIOHttpLink(endpoint_url=kraph.to_http_path("graphql")),
|
|
115
|
-
right=GraphQLWSLink(ws_endpoint_url=kraph.to_ws_path("graphql")),
|
|
114
|
+
left=AIOHttpLink(endpoint_url=kraph.to_http_path("graphql"), proxy=kraph.proxy),
|
|
115
|
+
right=GraphQLWSLink(ws_endpoint_url=kraph.to_ws_path("graphql"), proxy=kraph.proxy),
|
|
116
116
|
split=lambda o: o.node.operation != OperationType.SUBSCRIPTION,
|
|
117
117
|
),
|
|
118
118
|
)
|
|
@@ -52,6 +52,9 @@ class DataLayer(KoiledModel):
|
|
|
52
52
|
"""
|
|
53
53
|
|
|
54
54
|
endpoint_url: str = ""
|
|
55
|
+
proxy: str | None = None
|
|
56
|
+
"""The HTTP forward proxy (``http://host:port``) the store is only reachable
|
|
57
|
+
through, when it sits on a private mesh. ``None`` connects directly."""
|
|
55
58
|
|
|
56
59
|
|
|
57
60
|
@classmethod
|
|
@@ -64,7 +67,7 @@ class DataLayer(KoiledModel):
|
|
|
64
67
|
Returns:
|
|
65
68
|
The datalayer, ready to use.
|
|
66
69
|
"""
|
|
67
|
-
return cls(endpoint_url=alias.to_http_path())
|
|
70
|
+
return cls(endpoint_url=alias.to_http_path(), proxy=alias.proxy)
|
|
68
71
|
|
|
69
72
|
async def get_endpoint_url(self):
|
|
70
73
|
return self.endpoint_url
|
|
@@ -12,7 +12,10 @@ async def adownload_file(datalayer: "DataLayer", presigned_url: str, file_name:
|
|
|
12
12
|
endpoint_url = await datalayer.get_endpoint_url()
|
|
13
13
|
|
|
14
14
|
async with aiohttp.ClientSession() as session:
|
|
15
|
-
|
|
15
|
+
# ``proxy=None`` is aiohttp's own default, so an unproxied datalayer is unchanged.
|
|
16
|
+
async with session.get(
|
|
17
|
+
endpoint_url + presigned_url, proxy=datalayer.proxy
|
|
18
|
+
) as response:
|
|
16
19
|
with open(file_name, "wb") as file:
|
|
17
20
|
while True:
|
|
18
21
|
chunk = await response.content.read(
|
|
@@ -32,7 +32,7 @@ from rath.turms.utils import get_attributes_or_error
|
|
|
32
32
|
from kraph.client import client_of
|
|
33
33
|
|
|
34
34
|
if TYPE_CHECKING:
|
|
35
|
-
from
|
|
35
|
+
from arkitekt_spec.declare.structures.registry import StructureRegistry
|
|
36
36
|
|
|
37
37
|
from kraph.kraph import Kraph
|
|
38
38
|
|
|
@@ -10,9 +10,12 @@ requires-python = ">=3.11, <4.0"
|
|
|
10
10
|
license = "GPL-3.0-or-later"
|
|
11
11
|
dependencies = [
|
|
12
12
|
"dokker>=2.8",
|
|
13
|
-
"rath>=4",
|
|
14
|
-
"rekuest>=4",
|
|
13
|
+
"rath>=4.1.1",
|
|
15
14
|
"websockets>=15.0.1",
|
|
15
|
+
# The service and structures are declared with arkitekt-spec.
|
|
16
|
+
"arkitekt-spec>=1.4",
|
|
17
|
+
# The service wiring (Alias, Require, FaktsAuthLink); it came through rekuest before.
|
|
18
|
+
"fakts>=4",
|
|
16
19
|
]
|
|
17
20
|
|
|
18
21
|
[project.optional-dependencies]
|
kraph-3.0.1/PKG-INFO
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.5
|
|
2
|
-
Name: kraph
|
|
3
|
-
Version: 3.0.1
|
|
4
|
-
Summary: the arkitekt knowledge graph
|
|
5
|
-
Author-email: jhnnsrs <jhnnsrs@gmail.com>
|
|
6
|
-
License-Expression: GPL-3.0-or-later
|
|
7
|
-
Requires-Python: <4.0,>=3.11
|
|
8
|
-
Requires-Dist: dokker>=2.8
|
|
9
|
-
Requires-Dist: rath>=4
|
|
10
|
-
Requires-Dist: rekuest>=4
|
|
11
|
-
Requires-Dist: websockets>=15.0.1
|
|
12
|
-
Description-Content-Type: text/markdown
|
|
13
|
-
|
|
14
|
-
# kraph
|
|
15
|
-
|
|
16
|
-
Kraph is a Python library for creating and manipulating knowledge graphs build around apache AGE.
|
|
17
|
-
|
|
18
|
-
## Features
|
|
19
|
-
|
|
20
|
-
- Create and manipulate knowledge graphs
|
|
21
|
-
- Query knowledge graphs using Cypher
|
|
22
|
-
- Ontology support (custom entities and relationships)
|
|
23
|
-
- GraphQL API for adding and querying data
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
## Installation
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
pip install kraph
|
|
30
|
-
```
|
kraph-3.0.1/README.md
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
# kraph
|
|
2
|
-
|
|
3
|
-
Kraph is a Python library for creating and manipulating knowledge graphs build around apache AGE.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- Create and manipulate knowledge graphs
|
|
8
|
-
- Query knowledge graphs using Cypher
|
|
9
|
-
- Ontology support (custom entities and relationships)
|
|
10
|
-
- GraphQL API for adding and querying data
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
## Installation
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
pip install kraph
|
|
17
|
-
```
|
kraph-3.0.1/kraph/__init__.py
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
from .kraph import Kraph
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
try:
|
|
5
|
-
from .arkitekt import kraph as kraph_service
|
|
6
|
-
except ImportError as e:
|
|
7
|
-
# Only "rekuest is not installed" may pass silently. Anything else that fails
|
|
8
|
-
# to import here (a renamed query, a rekuest too old for what the module
|
|
9
|
-
# needs) is a bug, and hiding it makes this package's service vanish
|
|
10
|
-
# without a word. Whether it is installed is asked the plain way.
|
|
11
|
-
try:
|
|
12
|
-
import rekuest # noqa: F401 -- presence is the question
|
|
13
|
-
except ImportError:
|
|
14
|
-
pass
|
|
15
|
-
else:
|
|
16
|
-
raise e
|
|
17
|
-
|
|
18
|
-
__all__ = ["Kraph", "kraph_service"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|