1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
"""Type stubs for prefix_register"""
:
"""
A PostgreSQL-backed namespace prefix registry for CURIE expansion.
This class provides async methods to store and retrieve namespace prefixes,
expand CURIEs, and manage prefix-to-URI mappings. All operations are atomic
and thread-safe.
"""
"""
Create a new prefix registry connected to PostgreSQL.
Args:
database_url: PostgreSQL connection string (e.g., "postgres://user:password@host:port/database")
max_connections: Maximum number of connections in the pool (recommended: 5-20)
Returns:
A new PrefixRegistry instance
Raises:
RuntimeError: If connection to database fails
Example:
>>> registry = await PrefixRegistry.new("postgres://localhost/mydb", 10)
"""
...
"""
Create a new prefix registry with retry logic for transient failures.
Args:
database_url: PostgreSQL connection string
max_connections: Maximum number of connections in the pool
max_retries: Maximum number of retry attempts (default: 5)
initial_delay_ms: Initial delay in milliseconds before first retry (default: 1000)
max_delay_ms: Maximum delay in milliseconds between retries (default: 30000)
Returns:
A new PrefixRegistry instance
Raises:
RuntimeError: If connection fails after all retries
Example:
>>> registry = await PrefixRegistry.new_with_retry(
... "postgres://localhost/mydb", 10, 5, 1000, 30000
... )
"""
...
"""
Store a new prefix if the URI doesn't already have one.
Follows the "first prefix wins" rule - if a URI already has a prefix
registered, the new prefix is ignored.
Args:
prefix: The namespace prefix (e.g., "foaf", "rdf")
uri: The full namespace URI (e.g., "http://xmlns.com/foaf/0.1/")
Returns:
True if the prefix was stored, False if the URI already had a prefix
Raises:
RuntimeError: If storage fails
ValueError: If prefix or URI is invalid
Example:
>>> stored = await registry.store_prefix_if_new("foaf", "http://xmlns.com/foaf/0.1/")
>>> if stored:
... print("New prefix stored")
"""
...
"""
Store multiple prefixes in batch.
More efficient than calling store_prefix_if_new() repeatedly.
Args:
prefixes: List of (prefix, uri) tuples to store
Returns:
Dictionary with 'stored' and 'skipped' counts
Raises:
RuntimeError: If batch storage fails
Example:
>>> prefixes = [
... ("foaf", "http://xmlns.com/foaf/0.1/"),
... ("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"),
... ]
>>> result = await registry.store_prefixes_if_new(prefixes)
>>> print(f"Stored {result['stored']}, skipped {result['skipped']}")
"""
...
"""
Get the URI for a given prefix.
First checks the in-memory cache, then falls back to the database.
Args:
prefix: The namespace prefix (e.g., "foaf")
Returns:
The URI if the prefix is known, None otherwise
Raises:
RuntimeError: If lookup fails
Example:
>>> uri = await registry.get_uri_for_prefix("foaf")
>>> if uri:
... print(f"foaf = {uri}")
"""
...
"""
Get the prefix for a given URI.
Args:
uri: The full namespace URI
Returns:
The prefix if the URI is registered, None otherwise
Raises:
RuntimeError: If lookup fails
Example:
>>> prefix = await registry.get_prefix_for_uri("http://xmlns.com/foaf/0.1/")
>>> if prefix:
... print(f"URI has prefix: {prefix}")
"""
...
"""
Expand a CURIE (Compact URI) to a full URI.
Args:
prefix: The namespace prefix (e.g., "foaf")
local_name: The local part (e.g., "Person")
Returns:
The full URI (e.g., "http://xmlns.com/foaf/0.1/Person") or None if prefix unknown
Raises:
RuntimeError: If expansion fails
Example:
>>> uri = await registry.expand_curie("foaf", "Person")
>>> if uri:
... print(f"foaf:Person = {uri}")
... # Output: foaf:Person = http://xmlns.com/foaf/0.1/Person
"""
...
"""
Get all registered prefixes.
Returns:
Dictionary mapping prefixes to URIs
Example:
>>> prefixes = await registry.get_all_prefixes()
>>> for prefix, uri in prefixes.items():
... print(f"{prefix}: {uri}")
"""
...
"""
Get the number of registered prefixes.
Returns:
The number of registered prefixes
Example:
>>> count = await registry.prefix_count()
>>> print(f"Registered prefixes: {count}")
"""
...
"""
Shorten a URI to a (prefix, local_name) tuple.
Uses longest-match semantics: if multiple namespaces match the URI,
the longest one wins. For example, if both "http://a/" and "http://a/b#"
are registered, "http://a/b#foo" would match the longer namespace.
Args:
uri: The full URI to shorten
Returns:
A (prefix, local_name) tuple if a match is found, None otherwise
Raises:
RuntimeError: If the lookup fails
Example:
>>> result = await registry.shorten_uri("http://xmlns.com/foaf/0.1/Person")
>>> if result:
... prefix, local = result
... print(f"{prefix}:{local}") # Output: foaf:Person
"""
...
"""
Shorten a URI to a CURIE string, or return the original URI if no match.
This is a convenience method that returns a formatted string rather than
a tuple. Uses longest-match semantics for namespace matching.
Args:
uri: The full URI to shorten
Returns:
A CURIE string like "prefix:local", or the original URI if no namespace matches
Raises:
RuntimeError: If the lookup fails
Example:
>>> result = await registry.shorten_uri_or_full("http://xmlns.com/foaf/0.1/Person")
>>> print(result) # "foaf:Person" or the full URI if not registered
"""
...
"""
Shorten multiple URIs in batch.
Uses longest-match semantics for each URI. More efficient than calling
shorten_uri() repeatedly.
Args:
uris: List of URIs to shorten
Returns:
List with (prefix, local_name) for matched URIs, None for unmatched
Raises:
RuntimeError: If the batch lookup fails
Example:
>>> uris = ["http://xmlns.com/foaf/0.1/Person", "http://unknown.org/thing"]
>>> results = await registry.shorten_uri_batch(uris)
>>> for result in results:
... if result:
... print(f"{result[0]}:{result[1]}")
... else:
... print("No match")
"""
...
"""
Expand multiple CURIEs in batch.
More efficient than calling expand_curie() repeatedly.
Args:
curies: List of (prefix, local_name) tuples
Returns:
List with expanded URIs for known prefixes, None for unknown
Raises:
RuntimeError: If the batch expansion fails
Example:
>>> curies = [("foaf", "Person"), ("unknown", "Thing")]
>>> results = await registry.expand_curie_batch(curies)
>>> for result in results:
... if result:
... print(result)
... else:
... print("Unknown prefix")
"""
...
=