rdf4j-python 0.1.6__py3-none-any.whl → 0.2.0__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.
- rdf4j_python/__init__.py +71 -4
- rdf4j_python/_client/_client.py +127 -66
- rdf4j_python/_driver/__init__.py +4 -0
- rdf4j_python/_driver/_async_rdf4j_db.py +40 -6
- rdf4j_python/_driver/_async_repository.py +249 -18
- rdf4j_python/_driver/_async_transaction.py +310 -0
- rdf4j_python/exception/__init__.py +29 -1
- rdf4j_python/exception/repo_exception.py +49 -22
- rdf4j_python/model/__init__.py +26 -0
- rdf4j_python/model/term.py +15 -0
- {rdf4j_python-0.1.6.dist-info → rdf4j_python-0.2.0.dist-info}/METADATA +82 -28
- rdf4j_python-0.2.0.dist-info/RECORD +24 -0
- {rdf4j_python-0.1.6.dist-info → rdf4j_python-0.2.0.dist-info}/WHEEL +1 -1
- rdf4j_python-0.1.6.dist-info/RECORD +0 -23
- {rdf4j_python-0.1.6.dist-info → rdf4j_python-0.2.0.dist-info}/licenses/LICENSE +0 -0
- {rdf4j_python-0.1.6.dist-info → rdf4j_python-0.2.0.dist-info}/top_level.txt +0 -0
rdf4j_python/__init__.py
CHANGED
|
@@ -2,13 +2,80 @@
|
|
|
2
2
|
RDF4J Python is a Python library for interacting with RDF4J repositories.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
from ._driver import
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
from ._driver import (
|
|
6
|
+
AsyncNamedGraph,
|
|
7
|
+
AsyncRdf4j,
|
|
8
|
+
AsyncRdf4JRepository,
|
|
9
|
+
AsyncTransaction,
|
|
10
|
+
IsolationLevel,
|
|
11
|
+
TransactionState,
|
|
12
|
+
)
|
|
13
|
+
from .exception import (
|
|
14
|
+
NamespaceException,
|
|
15
|
+
NetworkError,
|
|
16
|
+
QueryError,
|
|
17
|
+
Rdf4jError,
|
|
18
|
+
RepositoryCreationException,
|
|
19
|
+
RepositoryDeletionException,
|
|
20
|
+
RepositoryError,
|
|
21
|
+
RepositoryInternalException,
|
|
22
|
+
RepositoryNotFoundException,
|
|
23
|
+
RepositoryUpdateException,
|
|
24
|
+
TransactionError,
|
|
25
|
+
TransactionStateError,
|
|
26
|
+
)
|
|
27
|
+
from .model import (
|
|
28
|
+
IRI,
|
|
29
|
+
BlankNode,
|
|
30
|
+
Context,
|
|
31
|
+
DefaultGraph,
|
|
32
|
+
Literal,
|
|
33
|
+
Namespace,
|
|
34
|
+
Object,
|
|
35
|
+
Predicate,
|
|
36
|
+
Quad,
|
|
37
|
+
QuadResultSet,
|
|
38
|
+
RepositoryMetadata,
|
|
39
|
+
Subject,
|
|
40
|
+
Triple,
|
|
41
|
+
Variable,
|
|
42
|
+
)
|
|
9
43
|
|
|
10
44
|
__all__ = [
|
|
45
|
+
# Main classes
|
|
11
46
|
"AsyncRdf4j",
|
|
12
47
|
"AsyncRdf4JRepository",
|
|
13
48
|
"AsyncNamedGraph",
|
|
49
|
+
# Transaction
|
|
50
|
+
"AsyncTransaction",
|
|
51
|
+
"IsolationLevel",
|
|
52
|
+
"TransactionState",
|
|
53
|
+
# Exceptions
|
|
54
|
+
"Rdf4jError",
|
|
55
|
+
"RepositoryError",
|
|
56
|
+
"RepositoryCreationException",
|
|
57
|
+
"RepositoryDeletionException",
|
|
58
|
+
"RepositoryNotFoundException",
|
|
59
|
+
"RepositoryInternalException",
|
|
60
|
+
"RepositoryUpdateException",
|
|
61
|
+
"NamespaceException",
|
|
62
|
+
"NetworkError",
|
|
63
|
+
"QueryError",
|
|
64
|
+
"TransactionError",
|
|
65
|
+
"TransactionStateError",
|
|
66
|
+
# Model types
|
|
67
|
+
"Namespace",
|
|
68
|
+
"RepositoryMetadata",
|
|
69
|
+
"IRI",
|
|
70
|
+
"BlankNode",
|
|
71
|
+
"Literal",
|
|
72
|
+
"DefaultGraph",
|
|
73
|
+
"Variable",
|
|
74
|
+
"Quad",
|
|
75
|
+
"Triple",
|
|
76
|
+
"Subject",
|
|
77
|
+
"Predicate",
|
|
78
|
+
"Object",
|
|
79
|
+
"Context",
|
|
80
|
+
"QuadResultSet",
|
|
14
81
|
]
|
rdf4j_python/_client/_client.py
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
import logging
|
|
2
|
+
from types import TracebackType
|
|
3
|
+
from typing import Any, Self
|
|
2
4
|
|
|
3
5
|
import httpx
|
|
4
6
|
|
|
7
|
+
logger = logging.getLogger("rdf4j_python")
|
|
8
|
+
|
|
5
9
|
|
|
6
10
|
class BaseClient:
|
|
7
11
|
"""Base HTTP client that provides shared URL building functionality."""
|
|
@@ -42,18 +46,20 @@ class BaseClient:
|
|
|
42
46
|
class SyncApiClient(BaseClient):
|
|
43
47
|
"""Synchronous API client using httpx.Client."""
|
|
44
48
|
|
|
45
|
-
def __init__(self, base_url: str, timeout: int = 10):
|
|
49
|
+
def __init__(self, base_url: str, timeout: int = 10, retries: int = 3) -> None:
|
|
46
50
|
"""
|
|
47
51
|
Initializes the SyncApiClient.
|
|
48
52
|
|
|
49
53
|
Args:
|
|
50
54
|
base_url (str): The base URL for the API endpoints.
|
|
51
55
|
timeout (int, optional): Request timeout in seconds. Defaults to 10.
|
|
56
|
+
retries (int, optional): Number of retries for failed requests. Defaults to 3.
|
|
52
57
|
"""
|
|
53
58
|
super().__init__(base_url, timeout)
|
|
54
|
-
|
|
59
|
+
transport = httpx.HTTPTransport(retries=retries)
|
|
60
|
+
self.client = httpx.Client(timeout=self.timeout, transport=transport)
|
|
55
61
|
|
|
56
|
-
def __enter__(self):
|
|
62
|
+
def __enter__(self) -> Self:
|
|
57
63
|
"""
|
|
58
64
|
Enters the context and initializes the HTTP client.
|
|
59
65
|
|
|
@@ -63,7 +69,12 @@ class SyncApiClient(BaseClient):
|
|
|
63
69
|
self.client.__enter__()
|
|
64
70
|
return self
|
|
65
71
|
|
|
66
|
-
def __exit__(
|
|
72
|
+
def __exit__(
|
|
73
|
+
self,
|
|
74
|
+
exc_type: type[BaseException] | None,
|
|
75
|
+
exc_value: BaseException | None,
|
|
76
|
+
traceback: TracebackType | None,
|
|
77
|
+
) -> None:
|
|
67
78
|
"""
|
|
68
79
|
Exits the context and closes the HTTP client.
|
|
69
80
|
"""
|
|
@@ -72,99 +83,129 @@ class SyncApiClient(BaseClient):
|
|
|
72
83
|
def get(
|
|
73
84
|
self,
|
|
74
85
|
path: str,
|
|
75
|
-
params:
|
|
76
|
-
headers:
|
|
86
|
+
params: dict[str, Any] | None = None,
|
|
87
|
+
headers: dict[str, str] | None = None,
|
|
77
88
|
) -> httpx.Response:
|
|
78
89
|
"""
|
|
79
90
|
Sends a GET request.
|
|
80
91
|
|
|
81
92
|
Args:
|
|
82
93
|
path (str): API endpoint path.
|
|
83
|
-
params (
|
|
84
|
-
headers (
|
|
94
|
+
params (dict[str, Any] | None): Query parameters.
|
|
95
|
+
headers (dict[str, str] | None): Request headers.
|
|
85
96
|
|
|
86
97
|
Returns:
|
|
87
98
|
httpx.Response: The HTTP response.
|
|
88
99
|
"""
|
|
89
|
-
|
|
100
|
+
url = self._build_url(path)
|
|
101
|
+
logger.debug("GET %s params=%s", url, params)
|
|
102
|
+
response = self.client.get(url, params=params, headers=headers)
|
|
103
|
+
logger.debug("Response %s: %s bytes", response.status_code, len(response.content))
|
|
104
|
+
return response
|
|
90
105
|
|
|
91
106
|
def post(
|
|
92
107
|
self,
|
|
93
108
|
path: str,
|
|
94
|
-
|
|
95
|
-
json:
|
|
96
|
-
headers:
|
|
109
|
+
content: str | bytes | None = None,
|
|
110
|
+
json: Any | None = None,
|
|
111
|
+
headers: dict[str, str] | None = None,
|
|
112
|
+
params: dict[str, Any] | None = None,
|
|
97
113
|
) -> httpx.Response:
|
|
98
114
|
"""
|
|
99
115
|
Sends a POST request.
|
|
100
116
|
|
|
101
117
|
Args:
|
|
102
118
|
path (str): API endpoint path.
|
|
103
|
-
|
|
104
|
-
json (
|
|
105
|
-
headers (
|
|
119
|
+
content (str | bytes | None): Raw content to include in the request body.
|
|
120
|
+
json (Any | None): JSON-encoded body data.
|
|
121
|
+
headers (dict[str, str] | None): Request headers.
|
|
122
|
+
params (dict[str, Any] | None): Query parameters.
|
|
106
123
|
|
|
107
124
|
Returns:
|
|
108
125
|
httpx.Response: The HTTP response.
|
|
109
126
|
"""
|
|
110
|
-
|
|
111
|
-
|
|
127
|
+
url = self._build_url(path)
|
|
128
|
+
logger.debug("POST %s params=%s", url, params)
|
|
129
|
+
response = self.client.post(
|
|
130
|
+
url, content=content, json=json, headers=headers, params=params
|
|
112
131
|
)
|
|
132
|
+
logger.debug("Response %s: %s bytes", response.status_code, len(response.content))
|
|
133
|
+
return response
|
|
113
134
|
|
|
114
135
|
def put(
|
|
115
136
|
self,
|
|
116
137
|
path: str,
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
138
|
+
content: str | bytes | None = None,
|
|
139
|
+
params: dict[str, Any] | None = None,
|
|
140
|
+
json: Any | None = None,
|
|
141
|
+
headers: dict[str, str] | None = None,
|
|
120
142
|
) -> httpx.Response:
|
|
121
143
|
"""
|
|
122
144
|
Sends a PUT request.
|
|
123
145
|
|
|
124
146
|
Args:
|
|
125
147
|
path (str): API endpoint path.
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
148
|
+
content (str | bytes | None): Raw content to include in the request body.
|
|
149
|
+
params (dict[str, Any] | None): Query parameters.
|
|
150
|
+
json (Any | None): JSON-encoded body data.
|
|
151
|
+
headers (dict[str, str] | None): Request headers.
|
|
129
152
|
|
|
130
153
|
Returns:
|
|
131
154
|
httpx.Response: The HTTP response.
|
|
132
155
|
"""
|
|
133
|
-
|
|
134
|
-
|
|
156
|
+
url = self._build_url(path)
|
|
157
|
+
logger.debug("PUT %s params=%s", url, params)
|
|
158
|
+
response = self.client.put(
|
|
159
|
+
url,
|
|
160
|
+
content=content,
|
|
161
|
+
json=json,
|
|
162
|
+
headers=headers,
|
|
163
|
+
params=params,
|
|
135
164
|
)
|
|
165
|
+
logger.debug("Response %s: %s bytes", response.status_code, len(response.content))
|
|
166
|
+
return response
|
|
136
167
|
|
|
137
168
|
def delete(
|
|
138
|
-
self,
|
|
169
|
+
self,
|
|
170
|
+
path: str,
|
|
171
|
+
params: dict[str, Any] | None = None,
|
|
172
|
+
headers: dict[str, str] | None = None,
|
|
139
173
|
) -> httpx.Response:
|
|
140
174
|
"""
|
|
141
175
|
Sends a DELETE request.
|
|
142
176
|
|
|
143
177
|
Args:
|
|
144
178
|
path (str): API endpoint path.
|
|
145
|
-
|
|
179
|
+
params (dict[str, Any] | None): Query parameters.
|
|
180
|
+
headers (dict[str, str] | None): Request headers.
|
|
146
181
|
|
|
147
182
|
Returns:
|
|
148
183
|
httpx.Response: The HTTP response.
|
|
149
184
|
"""
|
|
150
|
-
|
|
185
|
+
url = self._build_url(path)
|
|
186
|
+
logger.debug("DELETE %s params=%s", url, params)
|
|
187
|
+
response = self.client.delete(url, params=params, headers=headers)
|
|
188
|
+
logger.debug("Response %s: %s bytes", response.status_code, len(response.content))
|
|
189
|
+
return response
|
|
151
190
|
|
|
152
191
|
|
|
153
192
|
class AsyncApiClient(BaseClient):
|
|
154
193
|
"""Asynchronous API client using httpx.AsyncClient."""
|
|
155
194
|
|
|
156
|
-
def __init__(self, base_url: str, timeout: int = 10):
|
|
195
|
+
def __init__(self, base_url: str, timeout: int = 10, retries: int = 3) -> None:
|
|
157
196
|
"""
|
|
158
197
|
Initializes the AsyncApiClient.
|
|
159
198
|
|
|
160
199
|
Args:
|
|
161
200
|
base_url (str): The base URL for the API endpoints.
|
|
162
201
|
timeout (int, optional): Request timeout in seconds. Defaults to 10.
|
|
202
|
+
retries (int, optional): Number of retries for failed requests. Defaults to 3.
|
|
163
203
|
"""
|
|
164
204
|
super().__init__(base_url, timeout)
|
|
165
|
-
|
|
205
|
+
transport = httpx.AsyncHTTPTransport(retries=retries)
|
|
206
|
+
self.client = httpx.AsyncClient(timeout=self.timeout, transport=transport)
|
|
166
207
|
|
|
167
|
-
async def __aenter__(self):
|
|
208
|
+
async def __aenter__(self) -> Self:
|
|
168
209
|
"""
|
|
169
210
|
Enters the async context and initializes the HTTP client.
|
|
170
211
|
|
|
@@ -174,7 +215,12 @@ class AsyncApiClient(BaseClient):
|
|
|
174
215
|
await self.client.__aenter__()
|
|
175
216
|
return self
|
|
176
217
|
|
|
177
|
-
async def __aexit__(
|
|
218
|
+
async def __aexit__(
|
|
219
|
+
self,
|
|
220
|
+
exc_type: type[BaseException] | None,
|
|
221
|
+
exc_value: BaseException | None,
|
|
222
|
+
traceback: TracebackType | None,
|
|
223
|
+
) -> None:
|
|
178
224
|
"""
|
|
179
225
|
Exits the async context and closes the HTTP client.
|
|
180
226
|
"""
|
|
@@ -183,99 +229,114 @@ class AsyncApiClient(BaseClient):
|
|
|
183
229
|
async def get(
|
|
184
230
|
self,
|
|
185
231
|
path: str,
|
|
186
|
-
params:
|
|
187
|
-
headers:
|
|
232
|
+
params: dict[str, Any] | None = None,
|
|
233
|
+
headers: dict[str, str] | None = None,
|
|
188
234
|
) -> httpx.Response:
|
|
189
235
|
"""
|
|
190
236
|
Sends an asynchronous GET request.
|
|
191
237
|
|
|
192
238
|
Args:
|
|
193
239
|
path (str): API endpoint path.
|
|
194
|
-
params (
|
|
195
|
-
headers (
|
|
240
|
+
params (dict[str, Any] | None): Query parameters.
|
|
241
|
+
headers (dict[str, str] | None): Request headers.
|
|
196
242
|
|
|
197
243
|
Returns:
|
|
198
244
|
httpx.Response: The HTTP response.
|
|
199
245
|
"""
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
)
|
|
246
|
+
url = self._build_url(path)
|
|
247
|
+
logger.debug("GET %s params=%s", url, params)
|
|
248
|
+
response = await self.client.get(url, params=params, headers=headers)
|
|
249
|
+
logger.debug("Response %s: %s bytes", response.status_code, len(response.content))
|
|
250
|
+
return response
|
|
203
251
|
|
|
204
252
|
async def post(
|
|
205
253
|
self,
|
|
206
254
|
path: str,
|
|
207
|
-
content:
|
|
208
|
-
json:
|
|
209
|
-
headers:
|
|
255
|
+
content: str | bytes | None = None,
|
|
256
|
+
json: Any | None = None,
|
|
257
|
+
headers: dict[str, str] | None = None,
|
|
258
|
+
params: dict[str, Any] | None = None,
|
|
210
259
|
) -> httpx.Response:
|
|
211
260
|
"""
|
|
212
261
|
Sends an asynchronous POST request.
|
|
213
262
|
|
|
214
263
|
Args:
|
|
215
264
|
path (str): API endpoint path.
|
|
216
|
-
content (
|
|
217
|
-
json (
|
|
218
|
-
headers (
|
|
265
|
+
content (str | bytes | None): Raw content to include in the request body.
|
|
266
|
+
json (Any | None): JSON-encoded body data.
|
|
267
|
+
headers (dict[str, str] | None): Request headers.
|
|
268
|
+
params (dict[str, Any] | None): Query parameters.
|
|
219
269
|
|
|
220
270
|
Returns:
|
|
221
271
|
httpx.Response: The HTTP response.
|
|
222
272
|
"""
|
|
223
|
-
|
|
224
|
-
|
|
273
|
+
url = self._build_url(path)
|
|
274
|
+
logger.debug("POST %s params=%s", url, params)
|
|
275
|
+
response = await self.client.post(
|
|
276
|
+
url, content=content, json=json, headers=headers, params=params
|
|
225
277
|
)
|
|
278
|
+
logger.debug("Response %s: %s bytes", response.status_code, len(response.content))
|
|
279
|
+
return response
|
|
226
280
|
|
|
227
281
|
async def put(
|
|
228
282
|
self,
|
|
229
283
|
path: str,
|
|
230
|
-
content:
|
|
231
|
-
params:
|
|
232
|
-
json:
|
|
233
|
-
headers:
|
|
284
|
+
content: str | bytes | None = None,
|
|
285
|
+
params: dict[str, Any] | None = None,
|
|
286
|
+
json: Any | None = None,
|
|
287
|
+
headers: dict[str, str] | None = None,
|
|
234
288
|
) -> httpx.Response:
|
|
235
289
|
"""
|
|
236
290
|
Sends an asynchronous PUT request.
|
|
237
291
|
|
|
238
292
|
Args:
|
|
239
293
|
path (str): API endpoint path.
|
|
240
|
-
content (
|
|
241
|
-
params (
|
|
242
|
-
json (
|
|
243
|
-
headers (
|
|
294
|
+
content (str | bytes | None): Raw content to include in the request body.
|
|
295
|
+
params (dict[str, Any] | None): Query parameters.
|
|
296
|
+
json (Any | None): JSON-encoded body data.
|
|
297
|
+
headers (dict[str, str] | None): Request headers.
|
|
244
298
|
|
|
245
299
|
Returns:
|
|
246
300
|
httpx.Response: The HTTP response.
|
|
247
301
|
"""
|
|
248
|
-
|
|
249
|
-
|
|
302
|
+
url = self._build_url(path)
|
|
303
|
+
logger.debug("PUT %s params=%s", url, params)
|
|
304
|
+
response = await self.client.put(
|
|
305
|
+
url,
|
|
250
306
|
content=content,
|
|
251
307
|
json=json,
|
|
252
308
|
headers=headers,
|
|
253
309
|
params=params,
|
|
254
310
|
)
|
|
311
|
+
logger.debug("Response %s: %s bytes", response.status_code, len(response.content))
|
|
312
|
+
return response
|
|
255
313
|
|
|
256
314
|
async def delete(
|
|
257
315
|
self,
|
|
258
316
|
path: str,
|
|
259
|
-
params:
|
|
260
|
-
headers:
|
|
317
|
+
params: dict[str, Any] | None = None,
|
|
318
|
+
headers: dict[str, str] | None = None,
|
|
261
319
|
) -> httpx.Response:
|
|
262
320
|
"""
|
|
263
321
|
Sends an asynchronous DELETE request.
|
|
264
322
|
|
|
265
323
|
Args:
|
|
266
324
|
path (str): API endpoint path.
|
|
267
|
-
params (
|
|
268
|
-
headers (
|
|
325
|
+
params (dict[str, Any] | None): Query parameters.
|
|
326
|
+
headers (dict[str, str] | None): Request headers.
|
|
269
327
|
|
|
270
328
|
Returns:
|
|
271
329
|
httpx.Response: The HTTP response.
|
|
272
330
|
"""
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
)
|
|
331
|
+
url = self._build_url(path)
|
|
332
|
+
logger.debug("DELETE %s params=%s", url, params)
|
|
333
|
+
response = await self.client.delete(url, params=params, headers=headers)
|
|
334
|
+
logger.debug("Response %s: %s bytes", response.status_code, len(response.content))
|
|
335
|
+
return response
|
|
276
336
|
|
|
277
|
-
async def aclose(self):
|
|
337
|
+
async def aclose(self) -> None:
|
|
278
338
|
"""
|
|
279
339
|
Asynchronously closes the client connection.
|
|
280
340
|
"""
|
|
341
|
+
logger.debug("Closing async client connection")
|
|
281
342
|
await self.client.aclose()
|
rdf4j_python/_driver/__init__.py
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
from ._async_named_graph import AsyncNamedGraph
|
|
2
2
|
from ._async_rdf4j_db import AsyncRdf4j
|
|
3
3
|
from ._async_repository import AsyncRdf4JRepository
|
|
4
|
+
from ._async_transaction import AsyncTransaction, IsolationLevel, TransactionState
|
|
4
5
|
|
|
5
6
|
__all__ = [
|
|
6
7
|
"AsyncRdf4j",
|
|
7
8
|
"AsyncRdf4JRepository",
|
|
8
9
|
"AsyncNamedGraph",
|
|
10
|
+
"AsyncTransaction",
|
|
11
|
+
"IsolationLevel",
|
|
12
|
+
"TransactionState",
|
|
9
13
|
]
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
from types import TracebackType
|
|
2
|
+
from typing import Self
|
|
3
|
+
|
|
1
4
|
import httpx
|
|
2
5
|
import pyoxigraph as og
|
|
3
6
|
|
|
@@ -28,16 +31,21 @@ class AsyncRdf4j:
|
|
|
28
31
|
self._base_url = base_url.rstrip("/")
|
|
29
32
|
self._client = AsyncApiClient(base_url=self._base_url)
|
|
30
33
|
|
|
31
|
-
async def __aenter__(self):
|
|
34
|
+
async def __aenter__(self) -> Self:
|
|
32
35
|
"""Enters the async context and initializes the HTTP client.
|
|
33
36
|
|
|
34
37
|
Returns:
|
|
35
38
|
AsyncRdf4j: The initialized RDF4J interface.
|
|
36
39
|
"""
|
|
37
|
-
|
|
40
|
+
await self._client.__aenter__()
|
|
38
41
|
return self
|
|
39
42
|
|
|
40
|
-
async def __aexit__(
|
|
43
|
+
async def __aexit__(
|
|
44
|
+
self,
|
|
45
|
+
exc_type: type[BaseException] | None,
|
|
46
|
+
exc_value: BaseException | None,
|
|
47
|
+
traceback: TracebackType | None,
|
|
48
|
+
) -> None:
|
|
41
49
|
"""Closes the HTTP client when exiting the async context."""
|
|
42
50
|
await self._client.__aexit__(exc_type, exc_value, traceback)
|
|
43
51
|
|
|
@@ -70,7 +78,10 @@ class AsyncRdf4j:
|
|
|
70
78
|
query_solutions = og.parse_query_results(
|
|
71
79
|
response.text, format=og.QueryResultsFormat.JSON
|
|
72
80
|
)
|
|
73
|
-
|
|
81
|
+
if not isinstance(query_solutions, og.QuerySolutions):
|
|
82
|
+
raise TypeError(
|
|
83
|
+
f"Expected QuerySolutions, got {type(query_solutions).__name__}"
|
|
84
|
+
)
|
|
74
85
|
return [
|
|
75
86
|
RepositoryMetadata.from_sparql_query_solution(query_solution)
|
|
76
87
|
for query_solution in query_solutions
|
|
@@ -114,7 +125,7 @@ class AsyncRdf4j:
|
|
|
114
125
|
)
|
|
115
126
|
return AsyncRdf4JRepository(self._client, config.repo_id)
|
|
116
127
|
|
|
117
|
-
async def delete_repository(self, repository_id: str):
|
|
128
|
+
async def delete_repository(self, repository_id: str) -> None:
|
|
118
129
|
"""Deletes a repository and all its data and configuration.
|
|
119
130
|
|
|
120
131
|
Args:
|
|
@@ -130,6 +141,29 @@ class AsyncRdf4j:
|
|
|
130
141
|
f"Failed to delete repository '{repository_id}': {response.status_code} - {response.text}"
|
|
131
142
|
)
|
|
132
143
|
|
|
133
|
-
async def
|
|
144
|
+
async def health_check(self) -> bool:
|
|
145
|
+
"""Checks if the RDF4J server is reachable and healthy.
|
|
146
|
+
|
|
147
|
+
This method attempts to fetch the protocol version from the server
|
|
148
|
+
to verify connectivity.
|
|
149
|
+
|
|
150
|
+
Returns:
|
|
151
|
+
bool: True if the server is reachable and responds correctly,
|
|
152
|
+
False otherwise.
|
|
153
|
+
|
|
154
|
+
Example:
|
|
155
|
+
>>> async with AsyncRdf4j("http://localhost:8080/rdf4j-server") as db:
|
|
156
|
+
... if await db.health_check():
|
|
157
|
+
... print("Server is healthy")
|
|
158
|
+
... else:
|
|
159
|
+
... print("Server is not reachable")
|
|
160
|
+
"""
|
|
161
|
+
try:
|
|
162
|
+
response = await self._client.get("/protocol")
|
|
163
|
+
return response.status_code == httpx.codes.OK
|
|
164
|
+
except Exception:
|
|
165
|
+
return False
|
|
166
|
+
|
|
167
|
+
async def aclose(self) -> None:
|
|
134
168
|
"""Asynchronously closes the client connection."""
|
|
135
169
|
await self._client.aclose()
|