rdf4j-python 0.1.4__tar.gz → 0.1.5__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.
Files changed (37) hide show
  1. rdf4j_python-0.1.5/PKG-INFO +259 -0
  2. rdf4j_python-0.1.5/README.md +245 -0
  3. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/pyproject.toml +1 -1
  4. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/rdf4j_python/_client/_client.py +24 -2
  5. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/rdf4j_python/_driver/_async_repository.py +2 -1
  6. rdf4j_python-0.1.5/rdf4j_python/model/repository_config.py +587 -0
  7. rdf4j_python-0.1.5/rdf4j_python.egg-info/PKG-INFO +259 -0
  8. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/rdf4j_python.egg-info/SOURCES.txt +1 -0
  9. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/tests/test_client.py +9 -9
  10. rdf4j_python-0.1.5/tests/test_client_initialization.py +89 -0
  11. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/tests/test_rdf4j_repository.py +15 -10
  12. rdf4j_python-0.1.4/PKG-INFO +0 -80
  13. rdf4j_python-0.1.4/README.md +0 -66
  14. rdf4j_python-0.1.4/rdf4j_python/model/repository_config.py +0 -1500
  15. rdf4j_python-0.1.4/rdf4j_python.egg-info/PKG-INFO +0 -80
  16. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/LICENSE +0 -0
  17. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/rdf4j_python/__init__.py +0 -0
  18. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/rdf4j_python/_client/__init__.py +0 -0
  19. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/rdf4j_python/_driver/__init__.py +0 -0
  20. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/rdf4j_python/_driver/_async_named_graph.py +0 -0
  21. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/rdf4j_python/_driver/_async_rdf4j_db.py +0 -0
  22. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/rdf4j_python/exception/__init__.py +0 -0
  23. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/rdf4j_python/exception/repo_exception.py +0 -0
  24. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/rdf4j_python/model/__init__.py +0 -0
  25. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/rdf4j_python/model/_namespace.py +0 -0
  26. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/rdf4j_python/model/_repository_info.py +0 -0
  27. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/rdf4j_python/model/term.py +0 -0
  28. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/rdf4j_python/model/vocabulary.py +0 -0
  29. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/rdf4j_python/utils/__init__.py +0 -0
  30. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/rdf4j_python/utils/const.py +0 -0
  31. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/rdf4j_python/utils/helpers.py +0 -0
  32. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/rdf4j_python.egg-info/dependency_links.txt +0 -0
  33. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/rdf4j_python.egg-info/requires.txt +0 -0
  34. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/rdf4j_python.egg-info/top_level.txt +0 -0
  35. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/setup.cfg +0 -0
  36. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/tests/test_async_named_graph.py +0 -0
  37. {rdf4j_python-0.1.4 → rdf4j_python-0.1.5}/tests/test_helpers.py +0 -0
@@ -0,0 +1,259 @@
1
+ Metadata-Version: 2.4
2
+ Name: rdf4j-python
3
+ Version: 0.1.5
4
+ Summary: The Python client for RDF4J
5
+ Author-email: Chengxu Bian <cbian564@gmail.com>
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: httpx>=0.28.1
10
+ Requires-Dist: pyoxigraph>=0.4.10
11
+ Provides-Extra: sparqlwrapper
12
+ Requires-Dist: sparqlwrapper>=2.0.0; extra == "sparqlwrapper"
13
+ Dynamic: license-file
14
+
15
+ # rdf4j-python
16
+
17
+ **A modern Python client for the Eclipse RDF4J framework, enabling seamless RDF data management and SPARQL operations from Python applications.**
18
+
19
+ rdf4j-python bridges the gap between Python and the robust [Eclipse RDF4J](https://rdf4j.org/) ecosystem, providing a clean, async-first API for managing RDF repositories, executing SPARQL queries, and handling semantic data with ease.
20
+
21
+ > ⚠️ **Note:** This project is currently under active development and considered **experimental**. Interfaces may change. Use with caution in production environments—and feel free to help shape its future!
22
+
23
+ ## Features
24
+
25
+ - **🚀 Async-First Design**: Native support for async/await with synchronous fallback
26
+ - **🔄 Repository Management**: Create, access, and manage RDF4J repositories programmatically
27
+ - **⚡ SPARQL Support**: Execute SELECT, ASK, CONSTRUCT, and UPDATE queries effortlessly
28
+ - **📊 Flexible Data Handling**: Add, retrieve, and manipulate RDF triples and quads
29
+ - **🎯 Multiple Formats**: Support for various RDF serialization formats (Turtle, N-Triples, JSON-LD, etc.)
30
+ - **🛠️ Repository Types**: Memory stores, native stores, HTTP repositories, and more
31
+ - **🔗 Named Graph Support**: Work with multiple graphs within repositories
32
+ - **⚙️ Inferencing**: Built-in support for RDFS and custom inferencing rules
33
+
34
+ ## Installation
35
+
36
+ ### Prerequisites
37
+
38
+ - Python 3.10 or higher
39
+ - RDF4J Server (for remote repositories) or embedded usage
40
+
41
+ ### Install from PyPI
42
+
43
+ ```bash
44
+ pip install rdf4j-python
45
+ ```
46
+
47
+ ### Install with Optional Dependencies
48
+
49
+ ```bash
50
+ # Include SPARQLWrapper integration
51
+ pip install rdf4j-python[sparqlwrapper]
52
+ ```
53
+
54
+ ### Development Installation
55
+
56
+ ```bash
57
+ git clone https://github.com/odysa/rdf4j-python.git
58
+ cd rdf4j-python
59
+ uv sync --group dev
60
+ ```
61
+
62
+ ## Usage
63
+
64
+ ### Quick Start
65
+
66
+ ```python
67
+ import asyncio
68
+ from rdf4j_python import AsyncRdf4j
69
+ from rdf4j_python.model.repository_config import RepositoryConfig, MemoryStoreConfig, SailRepositoryConfig
70
+ from rdf4j_python.model.term import IRI, Literal
71
+
72
+ async def main():
73
+ # Connect to RDF4J server
74
+ async with AsyncRdf4j("http://localhost:19780/rdf4j-server") as db:
75
+ # Create an in-memory repository
76
+ config = RepositoryConfig(
77
+ repo_id="my-repo",
78
+ title="My Repository",
79
+ impl=SailRepositoryConfig(sail_impl=MemoryStoreConfig(persist=False))
80
+ )
81
+ repo = await db.create_repository(config=config)
82
+
83
+ # Add some data
84
+ await repo.add_statement(
85
+ IRI("http://example.com/person/alice"),
86
+ IRI("http://xmlns.com/foaf/0.1/name"),
87
+ Literal("Alice")
88
+ )
89
+
90
+ # Query the data
91
+ results = await repo.query("SELECT * WHERE { ?s ?p ?o }")
92
+ for result in results:
93
+ print(f"Subject: {result['s']}, Predicate: {result['p']}, Object: {result['o']}")
94
+
95
+ if __name__ == "__main__":
96
+ asyncio.run(main())
97
+ ```
98
+
99
+ ### Working with Multiple Graphs
100
+
101
+ ```python
102
+ from rdf4j_python.model.term import Quad
103
+
104
+ async def multi_graph_example():
105
+ async with AsyncRdf4j("http://localhost:19780/rdf4j-server") as db:
106
+ repo = await db.get_repository("my-repo")
107
+
108
+ # Add data to specific graphs
109
+ statements = [
110
+ Quad(
111
+ IRI("http://example.com/person/bob"),
112
+ IRI("http://xmlns.com/foaf/0.1/name"),
113
+ Literal("Bob"),
114
+ IRI("http://example.com/graph/people")
115
+ ),
116
+ Quad(
117
+ IRI("http://example.com/person/bob"),
118
+ IRI("http://xmlns.com/foaf/0.1/age"),
119
+ Literal("30", datatype=IRI("http://www.w3.org/2001/XMLSchema#integer")),
120
+ IRI("http://example.com/graph/demographics")
121
+ )
122
+ ]
123
+ await repo.add_statements(statements)
124
+
125
+ # Query specific graph
126
+ graph_query = """
127
+ SELECT * WHERE {
128
+ GRAPH <http://example.com/graph/people> {
129
+ ?person ?property ?value
130
+ }
131
+ }
132
+ """
133
+ results = await repo.query(graph_query)
134
+ ```
135
+
136
+ ### Advanced Repository Configuration
137
+
138
+ Here's a more comprehensive example showing repository creation with different configurations:
139
+
140
+ ```python
141
+ async def advanced_example():
142
+ async with AsyncRdf4j("http://localhost:19780/rdf4j-server") as db:
143
+ # Memory store with persistence
144
+ persistent_config = RepositoryConfig(
145
+ repo_id="persistent-repo",
146
+ title="Persistent Memory Store",
147
+ impl=SailRepositoryConfig(sail_impl=MemoryStoreConfig(persist=True))
148
+ )
149
+
150
+ # Create and populate repository
151
+ repo = await db.create_repository(config=persistent_config)
152
+
153
+ # Bulk data operations
154
+ data = [
155
+ (IRI("http://example.com/alice"), IRI("http://xmlns.com/foaf/0.1/name"), Literal("Alice")),
156
+ (IRI("http://example.com/alice"), IRI("http://xmlns.com/foaf/0.1/email"), Literal("alice@example.com")),
157
+ (IRI("http://example.com/bob"), IRI("http://xmlns.com/foaf/0.1/name"), Literal("Bob")),
158
+ ]
159
+
160
+ statements = [
161
+ Quad(subj, pred, obj, IRI("http://example.com/default"))
162
+ for subj, pred, obj in data
163
+ ]
164
+ await repo.add_statements(statements)
165
+
166
+ # Complex SPARQL query
167
+ query = """
168
+ PREFIX foaf: <http://xmlns.com/foaf/0.1/>
169
+ SELECT ?name ?email WHERE {
170
+ ?person foaf:name ?name .
171
+ OPTIONAL { ?person foaf:email ?email }
172
+ }
173
+ ORDER BY ?name
174
+ """
175
+ results = await repo.query(query)
176
+ ```
177
+
178
+ For more detailed examples, see the [examples](examples/) directory.
179
+
180
+ ## Development
181
+
182
+ ### Setting up Development Environment
183
+
184
+ 1. **Clone the repository**:
185
+ ```bash
186
+ git clone https://github.com/odysa/rdf4j-python.git
187
+ cd rdf4j-python
188
+ ```
189
+
190
+ 2. **Install development dependencies**:
191
+ ```bash
192
+ uv sync --group dev
193
+ ```
194
+
195
+ 3. **Start RDF4J Server** (for integration tests):
196
+ ```bash
197
+ # Using Docker
198
+ docker run -p 19780:8080 eclipse/rdf4j:latest
199
+ ```
200
+
201
+ 4. **Run tests**:
202
+ ```bash
203
+ pytest tests/
204
+ ```
205
+
206
+ 5. **Run linting**:
207
+ ```bash
208
+ ruff check .
209
+ ruff format .
210
+ ```
211
+
212
+ ### Project Structure
213
+
214
+ ```
215
+ rdf4j_python/
216
+ ├── _driver/ # Core async driver implementation
217
+ ├── model/ # Data models and configurations
218
+ ├── exception/ # Custom exceptions
219
+ └── utils/ # Utility functions
220
+
221
+ examples/ # Usage examples
222
+ tests/ # Test suite
223
+ docs/ # Documentation
224
+ ```
225
+
226
+ ### Contributing
227
+
228
+ We welcome contributions! Here's how to get involved:
229
+
230
+ 1. **Fork** the repository on GitHub
231
+ 2. **Create** a feature branch (`git checkout -b feature/amazing-feature`)
232
+ 3. **Make** your changes and add tests
233
+ 4. **Run** the test suite to ensure everything works
234
+ 5. **Commit** your changes (`git commit -m 'Add amazing feature'`)
235
+ 6. **Push** to your branch (`git push origin feature/amazing-feature`)
236
+ 7. **Open** a Pull Request
237
+
238
+ ### Running Examples
239
+
240
+ ```bash
241
+ # Make sure RDF4J server is running on localhost:19780
242
+ python examples/complete_workflow.py
243
+ python examples/query.py
244
+ ```
245
+
246
+ ## License
247
+
248
+ This project is licensed under the **BSD 3-Clause License**. See the [LICENSE](LICENSE) file for the full license text.
249
+
250
+ ```
251
+ Copyright (c) 2025, Chengxu Bian
252
+ All rights reserved.
253
+ ```
254
+
255
+ ---
256
+
257
+ **Questions or Issues?** Please feel free to [open an issue](https://github.com/odysa/rdf4j-python/issues) on GitHub.
258
+
259
+ **⭐ Star this repo** if you find it useful!
@@ -0,0 +1,245 @@
1
+ # rdf4j-python
2
+
3
+ **A modern Python client for the Eclipse RDF4J framework, enabling seamless RDF data management and SPARQL operations from Python applications.**
4
+
5
+ rdf4j-python bridges the gap between Python and the robust [Eclipse RDF4J](https://rdf4j.org/) ecosystem, providing a clean, async-first API for managing RDF repositories, executing SPARQL queries, and handling semantic data with ease.
6
+
7
+ > ⚠️ **Note:** This project is currently under active development and considered **experimental**. Interfaces may change. Use with caution in production environments—and feel free to help shape its future!
8
+
9
+ ## Features
10
+
11
+ - **🚀 Async-First Design**: Native support for async/await with synchronous fallback
12
+ - **🔄 Repository Management**: Create, access, and manage RDF4J repositories programmatically
13
+ - **⚡ SPARQL Support**: Execute SELECT, ASK, CONSTRUCT, and UPDATE queries effortlessly
14
+ - **📊 Flexible Data Handling**: Add, retrieve, and manipulate RDF triples and quads
15
+ - **🎯 Multiple Formats**: Support for various RDF serialization formats (Turtle, N-Triples, JSON-LD, etc.)
16
+ - **🛠️ Repository Types**: Memory stores, native stores, HTTP repositories, and more
17
+ - **🔗 Named Graph Support**: Work with multiple graphs within repositories
18
+ - **⚙️ Inferencing**: Built-in support for RDFS and custom inferencing rules
19
+
20
+ ## Installation
21
+
22
+ ### Prerequisites
23
+
24
+ - Python 3.10 or higher
25
+ - RDF4J Server (for remote repositories) or embedded usage
26
+
27
+ ### Install from PyPI
28
+
29
+ ```bash
30
+ pip install rdf4j-python
31
+ ```
32
+
33
+ ### Install with Optional Dependencies
34
+
35
+ ```bash
36
+ # Include SPARQLWrapper integration
37
+ pip install rdf4j-python[sparqlwrapper]
38
+ ```
39
+
40
+ ### Development Installation
41
+
42
+ ```bash
43
+ git clone https://github.com/odysa/rdf4j-python.git
44
+ cd rdf4j-python
45
+ uv sync --group dev
46
+ ```
47
+
48
+ ## Usage
49
+
50
+ ### Quick Start
51
+
52
+ ```python
53
+ import asyncio
54
+ from rdf4j_python import AsyncRdf4j
55
+ from rdf4j_python.model.repository_config import RepositoryConfig, MemoryStoreConfig, SailRepositoryConfig
56
+ from rdf4j_python.model.term import IRI, Literal
57
+
58
+ async def main():
59
+ # Connect to RDF4J server
60
+ async with AsyncRdf4j("http://localhost:19780/rdf4j-server") as db:
61
+ # Create an in-memory repository
62
+ config = RepositoryConfig(
63
+ repo_id="my-repo",
64
+ title="My Repository",
65
+ impl=SailRepositoryConfig(sail_impl=MemoryStoreConfig(persist=False))
66
+ )
67
+ repo = await db.create_repository(config=config)
68
+
69
+ # Add some data
70
+ await repo.add_statement(
71
+ IRI("http://example.com/person/alice"),
72
+ IRI("http://xmlns.com/foaf/0.1/name"),
73
+ Literal("Alice")
74
+ )
75
+
76
+ # Query the data
77
+ results = await repo.query("SELECT * WHERE { ?s ?p ?o }")
78
+ for result in results:
79
+ print(f"Subject: {result['s']}, Predicate: {result['p']}, Object: {result['o']}")
80
+
81
+ if __name__ == "__main__":
82
+ asyncio.run(main())
83
+ ```
84
+
85
+ ### Working with Multiple Graphs
86
+
87
+ ```python
88
+ from rdf4j_python.model.term import Quad
89
+
90
+ async def multi_graph_example():
91
+ async with AsyncRdf4j("http://localhost:19780/rdf4j-server") as db:
92
+ repo = await db.get_repository("my-repo")
93
+
94
+ # Add data to specific graphs
95
+ statements = [
96
+ Quad(
97
+ IRI("http://example.com/person/bob"),
98
+ IRI("http://xmlns.com/foaf/0.1/name"),
99
+ Literal("Bob"),
100
+ IRI("http://example.com/graph/people")
101
+ ),
102
+ Quad(
103
+ IRI("http://example.com/person/bob"),
104
+ IRI("http://xmlns.com/foaf/0.1/age"),
105
+ Literal("30", datatype=IRI("http://www.w3.org/2001/XMLSchema#integer")),
106
+ IRI("http://example.com/graph/demographics")
107
+ )
108
+ ]
109
+ await repo.add_statements(statements)
110
+
111
+ # Query specific graph
112
+ graph_query = """
113
+ SELECT * WHERE {
114
+ GRAPH <http://example.com/graph/people> {
115
+ ?person ?property ?value
116
+ }
117
+ }
118
+ """
119
+ results = await repo.query(graph_query)
120
+ ```
121
+
122
+ ### Advanced Repository Configuration
123
+
124
+ Here's a more comprehensive example showing repository creation with different configurations:
125
+
126
+ ```python
127
+ async def advanced_example():
128
+ async with AsyncRdf4j("http://localhost:19780/rdf4j-server") as db:
129
+ # Memory store with persistence
130
+ persistent_config = RepositoryConfig(
131
+ repo_id="persistent-repo",
132
+ title="Persistent Memory Store",
133
+ impl=SailRepositoryConfig(sail_impl=MemoryStoreConfig(persist=True))
134
+ )
135
+
136
+ # Create and populate repository
137
+ repo = await db.create_repository(config=persistent_config)
138
+
139
+ # Bulk data operations
140
+ data = [
141
+ (IRI("http://example.com/alice"), IRI("http://xmlns.com/foaf/0.1/name"), Literal("Alice")),
142
+ (IRI("http://example.com/alice"), IRI("http://xmlns.com/foaf/0.1/email"), Literal("alice@example.com")),
143
+ (IRI("http://example.com/bob"), IRI("http://xmlns.com/foaf/0.1/name"), Literal("Bob")),
144
+ ]
145
+
146
+ statements = [
147
+ Quad(subj, pred, obj, IRI("http://example.com/default"))
148
+ for subj, pred, obj in data
149
+ ]
150
+ await repo.add_statements(statements)
151
+
152
+ # Complex SPARQL query
153
+ query = """
154
+ PREFIX foaf: <http://xmlns.com/foaf/0.1/>
155
+ SELECT ?name ?email WHERE {
156
+ ?person foaf:name ?name .
157
+ OPTIONAL { ?person foaf:email ?email }
158
+ }
159
+ ORDER BY ?name
160
+ """
161
+ results = await repo.query(query)
162
+ ```
163
+
164
+ For more detailed examples, see the [examples](examples/) directory.
165
+
166
+ ## Development
167
+
168
+ ### Setting up Development Environment
169
+
170
+ 1. **Clone the repository**:
171
+ ```bash
172
+ git clone https://github.com/odysa/rdf4j-python.git
173
+ cd rdf4j-python
174
+ ```
175
+
176
+ 2. **Install development dependencies**:
177
+ ```bash
178
+ uv sync --group dev
179
+ ```
180
+
181
+ 3. **Start RDF4J Server** (for integration tests):
182
+ ```bash
183
+ # Using Docker
184
+ docker run -p 19780:8080 eclipse/rdf4j:latest
185
+ ```
186
+
187
+ 4. **Run tests**:
188
+ ```bash
189
+ pytest tests/
190
+ ```
191
+
192
+ 5. **Run linting**:
193
+ ```bash
194
+ ruff check .
195
+ ruff format .
196
+ ```
197
+
198
+ ### Project Structure
199
+
200
+ ```
201
+ rdf4j_python/
202
+ ├── _driver/ # Core async driver implementation
203
+ ├── model/ # Data models and configurations
204
+ ├── exception/ # Custom exceptions
205
+ └── utils/ # Utility functions
206
+
207
+ examples/ # Usage examples
208
+ tests/ # Test suite
209
+ docs/ # Documentation
210
+ ```
211
+
212
+ ### Contributing
213
+
214
+ We welcome contributions! Here's how to get involved:
215
+
216
+ 1. **Fork** the repository on GitHub
217
+ 2. **Create** a feature branch (`git checkout -b feature/amazing-feature`)
218
+ 3. **Make** your changes and add tests
219
+ 4. **Run** the test suite to ensure everything works
220
+ 5. **Commit** your changes (`git commit -m 'Add amazing feature'`)
221
+ 6. **Push** to your branch (`git push origin feature/amazing-feature`)
222
+ 7. **Open** a Pull Request
223
+
224
+ ### Running Examples
225
+
226
+ ```bash
227
+ # Make sure RDF4J server is running on localhost:19780
228
+ python examples/complete_workflow.py
229
+ python examples/query.py
230
+ ```
231
+
232
+ ## License
233
+
234
+ This project is licensed under the **BSD 3-Clause License**. See the [LICENSE](LICENSE) file for the full license text.
235
+
236
+ ```
237
+ Copyright (c) 2025, Chengxu Bian
238
+ All rights reserved.
239
+ ```
240
+
241
+ ---
242
+
243
+ **Questions or Issues?** Please feel free to [open an issue](https://github.com/odysa/rdf4j-python/issues) on GitHub.
244
+
245
+ **⭐ Star this repo** if you find it useful!
@@ -1,7 +1,7 @@
1
1
  [project]
2
2
  name = "rdf4j-python"
3
3
  authors = [{ name = "Chengxu Bian", email = "cbian564@gmail.com" }]
4
- version = "0.1.4"
4
+ version = "0.1.5"
5
5
  description = "The Python client for RDF4J"
6
6
  readme = "README.md"
7
7
  requires-python = ">=3.10"
@@ -42,6 +42,17 @@ class BaseClient:
42
42
  class SyncApiClient(BaseClient):
43
43
  """Synchronous API client using httpx.Client."""
44
44
 
45
+ def __init__(self, base_url: str, timeout: int = 10):
46
+ """
47
+ Initializes the SyncApiClient.
48
+
49
+ Args:
50
+ base_url (str): The base URL for the API endpoints.
51
+ timeout (int, optional): Request timeout in seconds. Defaults to 10.
52
+ """
53
+ super().__init__(base_url, timeout)
54
+ self.client = httpx.Client(timeout=self.timeout)
55
+
45
56
  def __enter__(self):
46
57
  """
47
58
  Enters the context and initializes the HTTP client.
@@ -49,7 +60,7 @@ class SyncApiClient(BaseClient):
49
60
  Returns:
50
61
  SyncApiClient: The instance of the client.
51
62
  """
52
- self.client = httpx.Client(timeout=self.timeout).__enter__()
63
+ self.client.__enter__()
53
64
  return self
54
65
 
55
66
  def __exit__(self, exc_type, exc_value, traceback):
@@ -142,6 +153,17 @@ class SyncApiClient(BaseClient):
142
153
  class AsyncApiClient(BaseClient):
143
154
  """Asynchronous API client using httpx.AsyncClient."""
144
155
 
156
+ def __init__(self, base_url: str, timeout: int = 10):
157
+ """
158
+ Initializes the AsyncApiClient.
159
+
160
+ Args:
161
+ base_url (str): The base URL for the API endpoints.
162
+ timeout (int, optional): Request timeout in seconds. Defaults to 10.
163
+ """
164
+ super().__init__(base_url, timeout)
165
+ self.client = httpx.AsyncClient(timeout=self.timeout)
166
+
145
167
  async def __aenter__(self):
146
168
  """
147
169
  Enters the async context and initializes the HTTP client.
@@ -149,7 +171,7 @@ class AsyncApiClient(BaseClient):
149
171
  Returns:
150
172
  AsyncApiClient: The instance of the client.
151
173
  """
152
- self.client = await httpx.AsyncClient(timeout=self.timeout).__aenter__()
174
+ await self.client.__aenter__()
153
175
  return self
154
176
 
155
177
  async def __aexit__(self, exc_type, exc_value, traceback):
@@ -100,7 +100,8 @@ class AsyncRdf4JRepository:
100
100
  RepositoryNotFoundException: If the repository doesn't exist.
101
101
  httpx.HTTPStatusError: If the update fails.
102
102
  """
103
- # TODO: handle update results
103
+ # SPARQL UPDATE operations return HTTP 204 No Content on success.
104
+ # No result data is returned as per SPARQL 1.1 UPDATE specification.
104
105
  path = f"/repositories/{self._repository_id}/statements"
105
106
  headers = {"Content-Type": content_type}
106
107
  response = await self._client.post(