sparql-cli 0.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.
Files changed (53) hide show
  1. sparql_cli-0.1.0/.coverage +0 -0
  2. sparql_cli-0.1.0/LICENSE +21 -0
  3. sparql_cli-0.1.0/PKG-INFO +435 -0
  4. sparql_cli-0.1.0/README.md +411 -0
  5. sparql_cli-0.1.0/config.example.toml +48 -0
  6. sparql_cli-0.1.0/pyproject.toml +70 -0
  7. sparql_cli-0.1.0/sparql/__init__.py +6 -0
  8. sparql_cli-0.1.0/sparql/__main__.py +6 -0
  9. sparql_cli-0.1.0/sparql/_version.py +1 -0
  10. sparql_cli-0.1.0/sparql/cli/__init__.py +3 -0
  11. sparql_cli-0.1.0/sparql/cli/commands/__init__.py +1 -0
  12. sparql_cli-0.1.0/sparql/cli/commands/config.py +143 -0
  13. sparql_cli-0.1.0/sparql/cli/commands/convenience.py +886 -0
  14. sparql_cli-0.1.0/sparql/cli/commands/query.py +210 -0
  15. sparql_cli-0.1.0/sparql/cli/main.py +160 -0
  16. sparql_cli-0.1.0/sparql/cli/output.py +12 -0
  17. sparql_cli-0.1.0/sparql/core/__init__.py +0 -0
  18. sparql_cli-0.1.0/sparql/core/client.py +90 -0
  19. sparql_cli-0.1.0/sparql/core/config.py +244 -0
  20. sparql_cli-0.1.0/sparql/core/exceptions.py +34 -0
  21. sparql_cli-0.1.0/sparql/core/exit_codes.py +17 -0
  22. sparql_cli-0.1.0/sparql/core/logging.py +43 -0
  23. sparql_cli-0.1.0/sparql/core/models.py +49 -0
  24. sparql_cli-0.1.0/sparql/core/monitoring.py +37 -0
  25. sparql_cli-0.1.0/sparql/core/prefixes.py +61 -0
  26. sparql_cli-0.1.0/sparql/core/query_source.py +55 -0
  27. sparql_cli-0.1.0/sparql/formatters/__init__.py +37 -0
  28. sparql_cli-0.1.0/sparql/formatters/base.py +76 -0
  29. sparql_cli-0.1.0/sparql/formatters/csv.py +89 -0
  30. sparql_cli-0.1.0/sparql/formatters/json.py +100 -0
  31. sparql_cli-0.1.0/sparql/formatters/table.py +72 -0
  32. sparql_cli-0.1.0/tests/__init__.py +0 -0
  33. sparql_cli-0.1.0/tests/cli/__init__.py +0 -0
  34. sparql_cli-0.1.0/tests/cli/test_config_command.py +117 -0
  35. sparql_cli-0.1.0/tests/cli/test_convenience_commands.py +328 -0
  36. sparql_cli-0.1.0/tests/cli/test_query_command.py +108 -0
  37. sparql_cli-0.1.0/tests/conftest.py +31 -0
  38. sparql_cli-0.1.0/tests/core/__init__.py +0 -0
  39. sparql_cli-0.1.0/tests/core/test_client.py +116 -0
  40. sparql_cli-0.1.0/tests/core/test_config.py +610 -0
  41. sparql_cli-0.1.0/tests/core/test_models.py +118 -0
  42. sparql_cli-0.1.0/tests/core/test_prefixes.py +118 -0
  43. sparql_cli-0.1.0/tests/core/test_query_source.py +121 -0
  44. sparql_cli-0.1.0/tests/formatters/__init__.py +0 -0
  45. sparql_cli-0.1.0/tests/formatters/test_csv_formatter.py +219 -0
  46. sparql_cli-0.1.0/tests/formatters/test_json_formatter.py +236 -0
  47. sparql_cli-0.1.0/tests/formatters/test_registry.py +56 -0
  48. sparql_cli-0.1.0/tests/formatters/test_table_formatter.py +104 -0
  49. sparql_cli-0.1.0/tests/test_exceptions.py +109 -0
  50. sparql_cli-0.1.0/tests/test_logging.py +30 -0
  51. sparql_cli-0.1.0/tests/test_monitoring.py +5 -0
  52. sparql_cli-0.1.0/tests/test_package.py +39 -0
  53. sparql_cli-0.1.0/uv.lock +553 -0
Binary file
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Vlad Korolev
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,435 @@
1
+ Metadata-Version: 2.4
2
+ Name: sparql-cli
3
+ Version: 0.1.0
4
+ Summary: CLI tool for querying SPARQL endpoints
5
+ Project-URL: Homepage, https://github.com/vlad/sparql-cli
6
+ Project-URL: Repository, https://github.com/vlad/sparql-cli
7
+ Project-URL: Issues, https://github.com/vlad/sparql-cli/issues
8
+ Author-email: Vlad Korolev <vlad@v-lad.org>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Requires-Python: >=3.13
12
+ Requires-Dist: httpx>=0.25.0
13
+ Requires-Dist: pydantic>=2.5.0
14
+ Requires-Dist: rich>=13.0.0
15
+ Requires-Dist: sentry-sdk>=1.40.0
16
+ Requires-Dist: structlog>=23.2.0
17
+ Requires-Dist: typer>=0.9.0
18
+ Provides-Extra: dev
19
+ Requires-Dist: mypy>=1.7.0; extra == 'dev'
20
+ Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
21
+ Requires-Dist: pytest>=7.4.0; extra == 'dev'
22
+ Requires-Dist: ruff>=0.1.0; extra == 'dev'
23
+ Description-Content-Type: text/markdown
24
+
25
+ # SPARQL CLI
26
+
27
+ CLI tool for querying SPARQL endpoints from the command line.
28
+
29
+ ## Installation
30
+
31
+ ### From PyPI (recommended)
32
+
33
+ ```bash
34
+ pip install sparql-cli
35
+ ```
36
+
37
+ Or with [uv](https://github.com/astral-sh/uv):
38
+
39
+ ```bash
40
+ uv tool install sparql-cli
41
+ ```
42
+
43
+ ### From Source
44
+
45
+ ```bash
46
+ git clone https://github.com/vlad/sparql-cli.git
47
+ cd sparql-cli
48
+ uv sync --dev
49
+ ```
50
+
51
+ ## Quick Start
52
+
53
+ ### Query Public Endpoints
54
+
55
+ ```bash
56
+ # Planet names across cultures - English, Welsh, Ukrainian, Chinese, Arabic, Latin (Wikidata)
57
+ sparql query -P wikidata -e "SELECT ?en ?cy ?uk ?zh ?ar ?la WHERE {
58
+ VALUES ?planet { wd:Q308 wd:Q313 wd:Q2 wd:Q111 wd:Q319 wd:Q193 wd:Q324 wd:Q332 }
59
+ OPTIONAL { ?planet rdfs:label ?en FILTER(LANG(?en) = 'en') }
60
+ OPTIONAL { ?planet rdfs:label ?cy FILTER(LANG(?cy) = 'cy') }
61
+ OPTIONAL { ?planet rdfs:label ?uk FILTER(LANG(?uk) = 'uk') }
62
+ OPTIONAL { ?planet rdfs:label ?zh FILTER(LANG(?zh) = 'zh') }
63
+ OPTIONAL { ?planet rdfs:label ?ar FILTER(LANG(?ar) = 'ar') }
64
+ OPTIONAL { ?planet rdfs:label ?la FILTER(LANG(?la) = 'la') }
65
+ }" --table
66
+
67
+ # Find scientists (DBpedia)
68
+ sparql query -P dbpedia -e "SELECT DISTINCT ?person ?name WHERE {
69
+ ?person a dbo:Scientist; foaf:name ?name.
70
+ FILTER(lang(?name)='en')
71
+ } LIMIT 5"
72
+
73
+ # Protein counts for model organisms - Human, Mouse, Fly, Worm, Yeast, Plant (UniProt)
74
+ sparql query -P uniprot -e "PREFIX up: <http://purl.uniprot.org/core/>
75
+ PREFIX taxon: <http://purl.uniprot.org/taxonomy/>
76
+ SELECT ?organism (COUNT(?protein) AS ?proteins) WHERE {
77
+ VALUES ?tax { taxon:9606 taxon:10090 taxon:7227 taxon:6239 taxon:4932 taxon:3702 }
78
+ ?protein a up:Protein ; up:organism ?tax .
79
+ ?tax up:scientificName ?organism .
80
+ } GROUP BY ?organism ORDER BY DESC(?proteins)"
81
+
82
+ # Approved drugs with most known targets - generic name, brand, target count (ChEMBL)
83
+ echo 'PREFIX chembl: <http://rdf.ebi.ac.uk/terms/chembl#>
84
+ PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
85
+ PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
86
+ SELECT ?generic (SAMPLE(?brand) AS ?brandName) (COUNT(DISTINCT ?target) AS ?targets) WHERE {
87
+ ?mol a chembl:SmallMolecule ; rdfs:label ?generic ; chembl:highestDevelopmentPhase 4 ;
88
+ skos:altLabel ?brand ; chembl:hasActivity/chembl:hasAssay/chembl:hasTarget ?target .
89
+ FILTER(REGEX(?brand, "^[A-Z][a-z]+$"))
90
+ FILTER(!REGEX(?brand, ?generic, "i"))
91
+ } GROUP BY ?generic ORDER BY DESC(?targets) LIMIT 10' | sparql query -E "https://chemblmirror.rdf.bigcat-bioinformatics.org/sparql" -t 120
92
+
93
+ # Simple query from file
94
+ sparql query query.rq
95
+ ```
96
+
97
+ ### Explore Endpoints with Convenience Commands
98
+
99
+ ```bash
100
+ # List classes in an endpoint
101
+ sparql classes -P dbpedia -n 10
102
+
103
+ # List predicates
104
+ sparql predicates -P wikidata -n 10
105
+
106
+ # Explore a specific entity (Douglas Adams = Q42)
107
+ sparql explore wd:Q42 -P wikidata -n 5
108
+
109
+ # List instances of a class
110
+ sparql objects dbo:Scientist -P dbpedia -n 5
111
+
112
+ # Describe a specific resource
113
+ sparql object dbr:Albert_Einstein -P dbpedia
114
+ ```
115
+
116
+ ### Override Endpoint
117
+
118
+ ```bash
119
+ # Use a different profile
120
+ sparql query --profile dbpedia -e "SELECT * WHERE { ?s ?p ?o } LIMIT 5"
121
+
122
+ # Override endpoint URL directly
123
+ sparql query --endpoint https://example.com/sparql -e "SELECT * WHERE { ?s ?p ?o } LIMIT 5"
124
+ ```
125
+
126
+ ## Commands
127
+
128
+ ### `query` - Execute SPARQL Queries
129
+
130
+ Execute arbitrary SPARQL queries against an endpoint.
131
+
132
+ ```bash
133
+ sparql query -e "SELECT * WHERE { ?s ?p ?o } LIMIT 5"
134
+ sparql query query.rq
135
+ cat query.rq | sparql query
136
+ ```
137
+
138
+ ### `classes` - List RDF Classes
139
+
140
+ List distinct `rdf:type` values in the endpoint.
141
+
142
+ ```bash
143
+ sparql classes -P wikidata -n 20
144
+ sparql classes --labels # Include rdfs:label (slower)
145
+ ```
146
+
147
+ ### `predicates` - List Predicates
148
+
149
+ List distinct predicates, or show usage of a specific predicate.
150
+
151
+ ```bash
152
+ sparql predicates -P dbpedia -n 20
153
+ sparql predicates rdf:type --values # Show distinct values
154
+ ```
155
+
156
+ ### `explore` - Explore URI Relationships
157
+
158
+ Find all triples where a URI appears as subject, predicate, or object.
159
+
160
+ ```bash
161
+ sparql explore wd:Q42 -P wikidata
162
+ sparql explore dbo:Person -P dbpedia
163
+ ```
164
+
165
+ ### `objects` - List Class Instances
166
+
167
+ List instances of a given RDF class.
168
+
169
+ ```bash
170
+ sparql objects dbo:Scientist -P dbpedia -n 10
171
+ sparql objects foaf:Person -P dbpedia --labels
172
+ ```
173
+
174
+ ### `object` - Describe Resource
175
+
176
+ Show all predicates and values for a specific resource.
177
+
178
+ ```bash
179
+ sparql object dbr:Albert_Einstein -P dbpedia
180
+ sparql object wd:Q42 -P wikidata
181
+ ```
182
+
183
+ ### `graphs` - List Named Graphs
184
+
185
+ List named graphs in the endpoint.
186
+
187
+ ```bash
188
+ sparql graphs -P dbpedia -n 10
189
+ ```
190
+
191
+ ### `config` - Configuration Management
192
+
193
+ ```bash
194
+ sparql config show # Show current configuration
195
+ sparql config show --json # Output as JSON
196
+ sparql config profiles # List available profiles
197
+ ```
198
+
199
+ ## Global Options
200
+
201
+ These options work with all commands:
202
+
203
+ | Option | Short | Description |
204
+ |--------|-------|-------------|
205
+ | `--profile` | `-P` | Use named endpoint profile |
206
+ | `--endpoint` | `-E` | Override endpoint URL |
207
+ | `--graphs` | `-g` | Show graph column in output |
208
+ | `--graph` | `-G` | Filter to specific named graph |
209
+ | `--verbose` | | Enable verbose logging |
210
+ | `--version` | `-V` | Show version and exit |
211
+
212
+ ## Command-Specific Options
213
+
214
+ ### Query Options
215
+
216
+ | Option | Short | Description |
217
+ |--------|-------|-------------|
218
+ | `--execute` | `-e` | Inline SPARQL query |
219
+ | `--timeout` | `-t` | Query timeout in seconds |
220
+ | `--format` | `-f` | Output format (json, jsonl, table, csv, tsv, sparql11) |
221
+ | `--table` | | Shorthand for `--format table` |
222
+ | `--jsonl` | | Shorthand for `--format jsonl` |
223
+ | `--compact` | | No pretty-print for sparql11 |
224
+ | `--no-header` | | Skip header for CSV/TSV |
225
+ | `--width` | | Max column width for table |
226
+ | `--user` | `-u` | Username for auth |
227
+ | `--password` | `-p` | Password for auth |
228
+ | `--digest` | | Use HTTP Digest auth |
229
+
230
+ ### Convenience Command Options
231
+
232
+ | Option | Short | Description |
233
+ |--------|-------|-------------|
234
+ | `--limit` | `-n` | Max results (default: 100) |
235
+ | `--labels` | `-l` | Include rdfs:label (slower) |
236
+ | `--values` | | Show only values (predicates cmd) |
237
+
238
+ ## Output Formats
239
+
240
+ The CLI supports multiple output formats. By default, it auto-detects:
241
+ - **Interactive terminal**: Table format with colored headers
242
+ - **Piped output**: TSV format for easy processing
243
+
244
+ ### Available Formats
245
+
246
+ | Format | Flag | Description |
247
+ |--------|------|-------------|
248
+ | `table` | `--format table` or `--table` | Rich formatted table with headers |
249
+ | `json` | `--format json` | JSON array of objects (pandas-compatible) |
250
+ | `jsonl` | `--format jsonl` or `--jsonl` | JSON Lines (one object per line, streaming) |
251
+ | `sparql11` | `--format sparql11` | SPARQL 1.1 Query Results JSON Format |
252
+ | `csv` | `--format csv` | RFC 4180 CSV with proper escaping |
253
+ | `tsv` | `--format tsv` | Tab-separated values |
254
+
255
+ ### Format Examples
256
+
257
+ ```bash
258
+ # Pretty table for interactive exploration
259
+ sparql query -e "SELECT ?s ?p ?o WHERE { ?s ?p ?o } LIMIT 5" --table
260
+
261
+ # JSON for loading into pandas
262
+ sparql query -e "SELECT ?item ?label WHERE { ... }" --format json > results.json
263
+
264
+ # JSONL for streaming pipelines
265
+ sparql query -e "SELECT * WHERE { ... }" --jsonl | jq '.item'
266
+
267
+ # TSV for spreadsheets or unix tools
268
+ sparql query -e "SELECT * WHERE { ... }" --format tsv | cut -f1
269
+
270
+ # Table with custom column width
271
+ sparql query -e "..." --table --width 60
272
+
273
+ # CSV/TSV without header row
274
+ sparql query -e "..." --format csv --no-header
275
+ ```
276
+
277
+ ## Configuration
278
+
279
+ Create `~/.config/sparql/config.toml`:
280
+
281
+ ```toml
282
+ # Default profile to use
283
+ default_endpoint = "wikidata"
284
+
285
+ [endpoints.wikidata]
286
+ url = "https://query.wikidata.org/sparql"
287
+ timeout = 60.0
288
+
289
+ [endpoints.dbpedia]
290
+ url = "https://dbpedia.org/sparql"
291
+
292
+ # Private endpoint with authentication
293
+ [endpoints.private]
294
+ url = "https://private.example.com/sparql"
295
+ auth_type = "basic" # or "digest"
296
+ username = "admin"
297
+ password = "secret" # pragma: allowlist secret
298
+ ```
299
+
300
+ View current configuration:
301
+
302
+ ```bash
303
+ sparql config show
304
+ sparql config show --json
305
+ sparql config profiles
306
+ ```
307
+
308
+ ### Environment Variables
309
+
310
+ | Variable | Description |
311
+ |----------|-------------|
312
+ | `SPARQL_PROFILE` | Override default profile |
313
+ | `SPARQL_ENDPOINT` | Override endpoint URL |
314
+ | `SPARQL_TIMEOUT` | Override timeout (seconds) |
315
+ | `SPARQL_USER` | Override username |
316
+ | `SPARQL_PASSWORD` | Override password |
317
+
318
+ ### Precedence
319
+
320
+ CLI flags > Environment variables > Profile settings > Config defaults
321
+
322
+ ## Authentication
323
+
324
+ Authentication can be configured per-profile in config file:
325
+
326
+ ```toml
327
+ [endpoints.marklogic]
328
+ url = "http://localhost:8000/v1/graphs/sparql"
329
+ auth_type = "digest"
330
+ username = "admin"
331
+ password = "your-password" # pragma: allowlist secret
332
+ ```
333
+
334
+ Or via CLI/environment:
335
+
336
+ ```bash
337
+ # CLI flags
338
+ sparql query --user admin --password secret --digest -e "..."
339
+
340
+ # Environment
341
+ SPARQL_USER=admin SPARQL_PASSWORD=secret sparql query -e "..."
342
+ ```
343
+
344
+ ## Troubleshooting
345
+
346
+ ### Debugging Options
347
+
348
+ ```bash
349
+ # Show endpoint and query before execution
350
+ sparql classes -P dbpedia --verbose
351
+
352
+ # Show which graph data comes from
353
+ sparql classes -P dbpedia --graphs
354
+
355
+ # Filter to specific named graph
356
+ sparql classes -P dbpedia --graph http://dbpedia.org
357
+ ```
358
+
359
+ ### Common Issues
360
+
361
+ **Connection errors:**
362
+ ```bash
363
+ # Check endpoint is reachable
364
+ sparql config show # Verify endpoint URL
365
+ sparql query -E https://your-endpoint/sparql -e "SELECT * WHERE { ?s ?p ?o } LIMIT 1"
366
+ ```
367
+
368
+ **Query timeout:**
369
+ ```bash
370
+ # Increase timeout
371
+ sparql query -t 120 -e "..." # 2 minute timeout
372
+ ```
373
+
374
+ **Unknown profile:**
375
+ ```bash
376
+ # List available profiles
377
+ sparql config profiles
378
+ ```
379
+
380
+ **Empty results:**
381
+ - Check if the endpoint has data: `sparql classes -n 5`
382
+ - Verify predicates exist: `sparql predicates -n 5`
383
+ - Try with verbose mode: `--verbose`
384
+
385
+ ### Exit Codes
386
+
387
+ | Code | Meaning |
388
+ |------|---------|
389
+ | 0 | Success |
390
+ | 1 | General error |
391
+ | 2 | Usage error |
392
+ | 3 | Input error (bad query file, empty query) |
393
+ | 5 | Network error |
394
+ | 6 | Timeout |
395
+ | 7 | Config error |
396
+
397
+ ## Endpoint Notes
398
+
399
+ | Server | URL Format |
400
+ |--------|------------|
401
+ | Stardog | Must end with `/query` (e.g., `http://host:5820/db-name/query`) |
402
+ | MarkLogic | Use `/v1/graphs/sparql` path |
403
+ | Blazegraph | Standard `/sparql` or `/blazegraph/sparql` |
404
+ | Fuseki | Use `/dataset/sparql` or `/dataset/query` |
405
+
406
+ ## Development
407
+
408
+ ```bash
409
+ git clone https://github.com/vlad/sparql-cli.git
410
+ cd sparql-cli
411
+ uv sync --dev
412
+
413
+ # Run tests
414
+ uv run pytest
415
+
416
+ # Type checking
417
+ uv run mypy sparql/
418
+
419
+ # Linting
420
+ uv run ruff check .
421
+ ```
422
+
423
+ ## Contributing
424
+
425
+ Contributions are welcome! Please feel free to submit a Pull Request.
426
+
427
+ ## License
428
+
429
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
430
+
431
+ ## Links
432
+
433
+ - **Repository**: https://github.com/vlad/sparql-cli
434
+ - **Issue Tracker**: https://github.com/vlad/sparql-cli/issues
435
+ - **PyPI**: https://pypi.org/project/sparql-cli/