rdf4j-python 0.1.5__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.
@@ -2,4 +2,32 @@
2
2
  RDF4J Python Exception Module
3
3
  """
4
4
 
5
- from .repo_exception import * # noqa: F403
5
+ from .repo_exception import (
6
+ NamespaceException,
7
+ NetworkError,
8
+ QueryError,
9
+ Rdf4jError,
10
+ RepositoryCreationException,
11
+ RepositoryDeletionException,
12
+ RepositoryError,
13
+ RepositoryInternalException,
14
+ RepositoryNotFoundException,
15
+ RepositoryUpdateException,
16
+ TransactionError,
17
+ TransactionStateError,
18
+ )
19
+
20
+ __all__ = [
21
+ "Rdf4jError",
22
+ "RepositoryError",
23
+ "RepositoryCreationException",
24
+ "RepositoryDeletionException",
25
+ "RepositoryNotFoundException",
26
+ "RepositoryInternalException",
27
+ "RepositoryUpdateException",
28
+ "NamespaceException",
29
+ "NetworkError",
30
+ "QueryError",
31
+ "TransactionError",
32
+ "TransactionStateError",
33
+ ]
@@ -1,34 +1,61 @@
1
- class RepositoryCreationException(Exception):
2
- """
3
- Exception raised when a repository creation fails.
4
- """
1
+ class Rdf4jError(Exception):
2
+ """Base exception for all RDF4J SDK errors.
5
3
 
4
+ All exceptions raised by the RDF4J Python SDK inherit from this class,
5
+ allowing users to catch all SDK-related errors with a single except clause.
6
6
 
7
- class RepositoryDeletionException(Exception):
8
- """
9
- Exception raised when a repository deletion fails.
7
+ Example:
8
+ try:
9
+ await repo.query("SELECT * WHERE { ?s ?p ?o }")
10
+ except Rdf4jError as e:
11
+ # Catches any RDF4J SDK error
12
+ print(f"RDF4J error: {e}")
10
13
  """
11
14
 
12
15
 
13
- class NamespaceException(Exception):
14
- """
15
- Exception raised when a namespace operation fails.
16
- """
16
+ class RepositoryError(Rdf4jError):
17
+ """Base exception for repository-related errors."""
17
18
 
18
19
 
19
- class RepositoryNotFoundException(Exception):
20
- """
21
- Exception raised when a repository is not found.
22
- """
20
+ class RepositoryCreationException(RepositoryError):
21
+ """Exception raised when a repository creation fails."""
23
22
 
24
23
 
25
- class RepositoryInternalException(Exception):
26
- """
27
- Exception raised when a repository internal error occurs.
28
- """
24
+ class RepositoryDeletionException(RepositoryError):
25
+ """Exception raised when a repository deletion fails."""
29
26
 
30
27
 
31
- class RepositoryUpdateException(Exception):
32
- """
33
- Exception raised when a repository update fails.
28
+ class RepositoryNotFoundException(RepositoryError):
29
+ """Exception raised when a repository is not found."""
30
+
31
+
32
+ class RepositoryInternalException(RepositoryError):
33
+ """Exception raised when a repository internal error occurs."""
34
+
35
+
36
+ class RepositoryUpdateException(RepositoryError):
37
+ """Exception raised when a repository update fails."""
38
+
39
+
40
+ class NamespaceException(Rdf4jError):
41
+ """Exception raised when a namespace operation fails."""
42
+
43
+
44
+ class NetworkError(Rdf4jError):
45
+ """Exception raised when a network/connection error occurs."""
46
+
47
+
48
+ class QueryError(Rdf4jError):
49
+ """Exception raised when a SPARQL query is invalid or fails."""
50
+
51
+
52
+ class TransactionError(Rdf4jError):
53
+ """Base exception for transaction-related errors."""
54
+
55
+
56
+ class TransactionStateError(TransactionError):
57
+ """Exception raised when a transaction operation is invalid for the current state.
58
+
59
+ For example, trying to commit an already committed transaction,
60
+ or trying to add statements to a closed transaction.
34
61
  """
@@ -4,8 +4,34 @@ RDF4J Python Model Module
4
4
 
5
5
  from ._namespace import Namespace
6
6
  from ._repository_info import RepositoryMetadata
7
+ from .term import (
8
+ IRI,
9
+ BlankNode,
10
+ Context,
11
+ DefaultGraph,
12
+ Literal,
13
+ Object,
14
+ Predicate,
15
+ Quad,
16
+ QuadResultSet,
17
+ Subject,
18
+ Triple,
19
+ Variable,
20
+ )
7
21
 
8
22
  __all__ = [
9
23
  "Namespace",
10
24
  "RepositoryMetadata",
25
+ "IRI",
26
+ "BlankNode",
27
+ "Literal",
28
+ "DefaultGraph",
29
+ "Variable",
30
+ "Quad",
31
+ "Triple",
32
+ "Subject",
33
+ "Predicate",
34
+ "Object",
35
+ "Context",
36
+ "QuadResultSet",
11
37
  ]
@@ -18,3 +18,18 @@ Context: TypeAlias = IRI | BlankNode | DefaultGraph | None
18
18
 
19
19
 
20
20
  QuadResultSet: TypeAlias = og.QuadParser
21
+
22
+ __all__ = [
23
+ "IRI",
24
+ "BlankNode",
25
+ "Literal",
26
+ "DefaultGraph",
27
+ "Variable",
28
+ "Quad",
29
+ "Triple",
30
+ "Subject",
31
+ "Predicate",
32
+ "Object",
33
+ "Context",
34
+ "QuadResultSet",
35
+ ]
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rdf4j-python
3
- Version: 0.1.5
3
+ Version: 0.2.0
4
4
  Summary: The Python client for RDF4J
5
5
  Author-email: Chengxu Bian <cbian564@gmail.com>
6
- Requires-Python: >=3.10
6
+ Requires-Python: >=3.11
7
7
  Description-Content-Type: text/markdown
8
8
  License-File: LICENSE
9
9
  Requires-Dist: httpx>=0.28.1
@@ -14,28 +14,34 @@ Dynamic: license-file
14
14
 
15
15
  # rdf4j-python
16
16
 
17
+ [![PyPI version](https://badge.fury.io/py/rdf4j-python.svg)](https://badge.fury.io/py/rdf4j-python)
18
+ [![Python Versions](https://img.shields.io/pypi/pyversions/rdf4j-python.svg)](https://pypi.org/project/rdf4j-python/)
19
+ [![CI](https://github.com/odysa/rdf4j-python/actions/workflows/ci.yaml/badge.svg)](https://github.com/odysa/rdf4j-python/actions/workflows/ci.yaml)
20
+ [![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
21
+ [![Documentation](https://img.shields.io/badge/docs-sphinx-blue.svg)](https://github.com/odysa/rdf4j-python/tree/main/docs)
22
+
17
23
  **A modern Python client for the Eclipse RDF4J framework, enabling seamless RDF data management and SPARQL operations from Python applications.**
18
24
 
19
25
  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
26
 
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
27
  ## Features
24
28
 
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
29
+ - **Async-First Design**: Native support for async/await with synchronous fallback
30
+ - **Repository Management**: Create, access, and manage RDF4J repositories programmatically
31
+ - **SPARQL Support**: Execute SELECT, ASK, CONSTRUCT, and UPDATE queries effortlessly
32
+ - **Transaction Support**: Atomic operations with commit/rollback and isolation levels
33
+ - **Flexible Data Handling**: Add, retrieve, and manipulate RDF triples and quads
34
+ - **File Upload**: Upload RDF files (Turtle, N-Triples, N-Quads, RDF/XML, JSON-LD, TriG, N3) directly to repositories
35
+ - **Multiple Formats**: Support for various RDF serialization formats
36
+ - **Repository Types**: Memory stores, native stores, HTTP repositories, and more
37
+ - **Named Graph Support**: Work with multiple graphs within repositories
38
+ - **Inferencing**: Built-in support for RDFS and custom inferencing rules
33
39
 
34
40
  ## Installation
35
41
 
36
42
  ### Prerequisites
37
43
 
38
- - Python 3.10 or higher
44
+ - Python 3.11 or higher
39
45
  - RDF4J Server (for remote repositories) or embedded usage
40
46
 
41
47
  ### Install from PyPI
@@ -175,6 +181,55 @@ async def advanced_example():
175
181
  results = await repo.query(query)
176
182
  ```
177
183
 
184
+ ### Uploading RDF Files
185
+
186
+ ```python
187
+ import pyoxigraph as og
188
+
189
+ async def upload_example():
190
+ async with AsyncRdf4j("http://localhost:19780/rdf4j-server") as db:
191
+ repo = await db.get_repository("my-repo")
192
+
193
+ # Upload a Turtle file (format auto-detected from extension)
194
+ await repo.upload_file("data.ttl")
195
+
196
+ # Upload to a specific named graph
197
+ await repo.upload_file("data.ttl", context=IRI("http://example.com/graph"))
198
+
199
+ # Upload with explicit format
200
+ await repo.upload_file("data.txt", rdf_format=og.RdfFormat.N_TRIPLES)
201
+
202
+ # Upload with base URI for relative URIs
203
+ await repo.upload_file("data.ttl", base_uri="http://example.com/")
204
+ ```
205
+
206
+ ### Using Transactions
207
+
208
+ ```python
209
+ from rdf4j_python import IsolationLevel
210
+
211
+ async def transaction_example():
212
+ async with AsyncRdf4j("http://localhost:19780/rdf4j-server") as db:
213
+ repo = await db.get_repository("my-repo")
214
+
215
+ # Atomic operations with auto-commit/rollback
216
+ async with repo.transaction() as txn:
217
+ await txn.add_statements([
218
+ Quad(IRI("http://example.com/alice"), IRI("http://xmlns.com/foaf/0.1/name"), Literal("Alice")),
219
+ Quad(IRI("http://example.com/bob"), IRI("http://xmlns.com/foaf/0.1/name"), Literal("Bob")),
220
+ ])
221
+ await txn.delete_statements([old_quad])
222
+ # Commits automatically on success, rolls back on exception
223
+
224
+ # With specific isolation level
225
+ async with repo.transaction(IsolationLevel.SERIALIZABLE) as txn:
226
+ await txn.update("""
227
+ DELETE { ?s <http://example.com/status> "draft" }
228
+ INSERT { ?s <http://example.com/status> "published" }
229
+ WHERE { ?s <http://example.com/status> "draft" }
230
+ """)
231
+ ```
232
+
178
233
  For more detailed examples, see the [examples](examples/) directory.
179
234
 
180
235
  ## Development
@@ -223,17 +278,17 @@ tests/ # Test suite
223
278
  docs/ # Documentation
224
279
  ```
225
280
 
226
- ### Contributing
281
+ ## Contributing
227
282
 
228
283
  We welcome contributions! Here's how to get involved:
229
284
 
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
285
+ 1. Fork the repository on GitHub
286
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
287
+ 3. Make your changes and add tests
288
+ 4. Run the test suite to ensure everything works
289
+ 5. Commit your changes (`git commit -m 'Add amazing feature'`)
290
+ 6. Push to your branch (`git push origin feature/amazing-feature`)
291
+ 7. Open a Pull Request
237
292
 
238
293
  ### Running Examples
239
294
 
@@ -245,15 +300,14 @@ python examples/query.py
245
300
 
246
301
  ## License
247
302
 
248
- This project is licensed under the **BSD 3-Clause License**. See the [LICENSE](LICENSE) file for the full license text.
303
+ This project is licensed under the BSD 3-Clause License. See the [LICENSE](LICENSE) file for details.
249
304
 
250
- ```
251
305
  Copyright (c) 2025, Chengxu Bian
252
- All rights reserved.
253
- ```
254
306
 
255
- ---
307
+ ## Support
256
308
 
257
- **Questions or Issues?** Please feel free to [open an issue](https://github.com/odysa/rdf4j-python/issues) on GitHub.
309
+ - **Issues & Bug Reports**: [GitHub Issues](https://github.com/odysa/rdf4j-python/issues)
310
+ - **Documentation**: [docs/](https://github.com/odysa/rdf4j-python/tree/main/docs)
311
+ - **Questions**: Feel free to open a discussion or issue
258
312
 
259
- **⭐ Star this repo** if you find it useful!
313
+ If you find this project useful, please consider starring the repository!
@@ -0,0 +1,24 @@
1
+ rdf4j_python/__init__.py,sha256=ddmkZKSc_YLJIRVGAJeqIU0iqvLTFBReLNU2WHwH-kI,1581
2
+ rdf4j_python/_client/__init__.py,sha256=L5q5RTHXCNyHp2WNP4xTemGXNntUW4RF_QJPoCWciUQ,98
3
+ rdf4j_python/_client/_client.py,sha256=BY5G64aY65FFEriRO4E_hbCdV1HzjggTMdWRJyhVjLQ,11023
4
+ rdf4j_python/_driver/__init__.py,sha256=wUFsKlqDedyyBpU-8LxtQP3tBGI12v7l20i_kgM_CM4,377
5
+ rdf4j_python/_driver/_async_named_graph.py,sha256=BqJRpN-JzGpvlSnWY2RrM5TrnIHg6W4PortZ0y-4mgw,2685
6
+ rdf4j_python/_driver/_async_rdf4j_db.py,sha256=h7JAxvNpJcz0aLO00IlUwYZPkm_mWyu5Jj7aQLSz3dY,5791
7
+ rdf4j_python/_driver/_async_repository.py,sha256=-8d0ssNA-Iw-GrOid5s5sSSvNzQ1zRwAnLUmAg7hSEM,24505
8
+ rdf4j_python/_driver/_async_transaction.py,sha256=nEY4t8SAujChAsg410SFwq1hlTrdycbeMjkCA60j4Cs,10574
9
+ rdf4j_python/exception/__init__.py,sha256=R1ebBTPeEjjphPr3kiELttjqnrHr6g3Ktw6FuVdD9vY,724
10
+ rdf4j_python/exception/repo_exception.py,sha256=nlkcR2E3FD3BAfQnZd6YXsYO7zzNiokRbDp90e1oCB8,1777
11
+ rdf4j_python/model/__init__.py,sha256=v3ytMSrL4D4Ej1S2RFprj1xj7BWrUbq_NhbLdyzVIug,548
12
+ rdf4j_python/model/_namespace.py,sha256=6iOvPc2Z6XFY44wmVucQCrjZbFuxdBtoTfDq_bSHJS0,3854
13
+ rdf4j_python/model/_repository_info.py,sha256=fdKwjoQz6_D95Q8uZEuEYhXEUeqElsdBkHRCRRNxjzM,2010
14
+ rdf4j_python/model/repository_config.py,sha256=USaWQ_C8UlnKSnL3coiXFly0TjOvapS6OMy3Nt9eVlg,22482
15
+ rdf4j_python/model/term.py,sha256=BSK5ILBFrG6glb2TIKlTaVpP994V_C-XGQsLUwVRTF4,710
16
+ rdf4j_python/model/vocabulary.py,sha256=Yam0F_YNlO-7wDi2fc0DkAqIKB4ZqCpqq56wKRrFAcw,307
17
+ rdf4j_python/utils/__init__.py,sha256=LAyzkmO5QOIjJogQE1m4Eszwb2cCU8ytKRfhjAGoraw,34
18
+ rdf4j_python/utils/const.py,sha256=HKH9ZGe7m_dvMx1RwT6zhu2HUkvwOX2Y4e8vQFs3uE8,849
19
+ rdf4j_python/utils/helpers.py,sha256=4ubvrx3OV_0Y2_YECNIJhkJUB-JthdCJA8d6Hz_G_kE,506
20
+ rdf4j_python-0.2.0.dist-info/licenses/LICENSE,sha256=sGjA7CzoCG1LVlkh0ZB76ZdgWHVpUFegLU41YYDkGIA,1499
21
+ rdf4j_python-0.2.0.dist-info/METADATA,sha256=2o4BVtidPfxnPh9fMXXs3NnlJH4Jgl3vkquqSMp5ElY,10360
22
+ rdf4j_python-0.2.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
23
+ rdf4j_python-0.2.0.dist-info/top_level.txt,sha256=Lf2K8d8WcEkmvo5giLGuZ3gl20rNEwMssyAFBeVzbCs,13
24
+ rdf4j_python-0.2.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,23 +0,0 @@
1
- rdf4j_python/__init__.py,sha256=E8gojaWuLHo2AfNn5HBc5cF7K8_dK2jOBcZaH_qoZs4,347
2
- rdf4j_python/_client/__init__.py,sha256=L5q5RTHXCNyHp2WNP4xTemGXNntUW4RF_QJPoCWciUQ,98
3
- rdf4j_python/_client/_client.py,sha256=0jlxEdmg9uwoUYhaLJQq0zD21ZlqyoaAL4vkTa5dz3o,8083
4
- rdf4j_python/_driver/__init__.py,sha256=au0r15mQBVaJkqBknw9CoVswe7_rPPFs1wFWI_ttdy4,224
5
- rdf4j_python/_driver/_async_named_graph.py,sha256=BqJRpN-JzGpvlSnWY2RrM5TrnIHg6W4PortZ0y-4mgw,2685
6
- rdf4j_python/_driver/_async_rdf4j_db.py,sha256=POJ2-5EiyFOjX6ykjxbm0RH7yjtU6mXCY2PlVYidLDI,4497
7
- rdf4j_python/_driver/_async_repository.py,sha256=bNO4m_0u0uNjz14vXlsyzkVYLUy5cpCSNnvEZg4fG3o,15364
8
- rdf4j_python/exception/__init__.py,sha256=PFdUyIMsHIL5e2P2z33Qr2pwlUAJVI0G5T8114W4-1A,83
9
- rdf4j_python/exception/repo_exception.py,sha256=WXlfIYzOYfNU8LpwtOct9fAZADR-P3cZx4jAX9v_HaA,704
10
- rdf4j_python/model/__init__.py,sha256=wHboqZX2bN3AubXvWRwKOWwnrefpeiiB_nnry2Ba_a4,176
11
- rdf4j_python/model/_namespace.py,sha256=6iOvPc2Z6XFY44wmVucQCrjZbFuxdBtoTfDq_bSHJS0,3854
12
- rdf4j_python/model/_repository_info.py,sha256=fdKwjoQz6_D95Q8uZEuEYhXEUeqElsdBkHRCRRNxjzM,2010
13
- rdf4j_python/model/repository_config.py,sha256=USaWQ_C8UlnKSnL3coiXFly0TjOvapS6OMy3Nt9eVlg,22482
14
- rdf4j_python/model/term.py,sha256=JBxndQESR2KEY6y9s6TqoELUQaegKcIUO0ctR818QaA,508
15
- rdf4j_python/model/vocabulary.py,sha256=Yam0F_YNlO-7wDi2fc0DkAqIKB4ZqCpqq56wKRrFAcw,307
16
- rdf4j_python/utils/__init__.py,sha256=LAyzkmO5QOIjJogQE1m4Eszwb2cCU8ytKRfhjAGoraw,34
17
- rdf4j_python/utils/const.py,sha256=HKH9ZGe7m_dvMx1RwT6zhu2HUkvwOX2Y4e8vQFs3uE8,849
18
- rdf4j_python/utils/helpers.py,sha256=4ubvrx3OV_0Y2_YECNIJhkJUB-JthdCJA8d6Hz_G_kE,506
19
- rdf4j_python-0.1.5.dist-info/licenses/LICENSE,sha256=sGjA7CzoCG1LVlkh0ZB76ZdgWHVpUFegLU41YYDkGIA,1499
20
- rdf4j_python-0.1.5.dist-info/METADATA,sha256=cMzk7E91qtPK_l_8EQJbkDYOsN5twDUotZWcIHNyiIo,7968
21
- rdf4j_python-0.1.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
22
- rdf4j_python-0.1.5.dist-info/top_level.txt,sha256=Lf2K8d8WcEkmvo5giLGuZ3gl20rNEwMssyAFBeVzbCs,13
23
- rdf4j_python-0.1.5.dist-info/RECORD,,