qurl-python 0.2.2__py3-none-any.whl → 0.4.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.
- layerv_qurl/__init__.py +0 -4
- layerv_qurl/_utils.py +10 -22
- layerv_qurl/async_client.py +0 -29
- layerv_qurl/client.py +0 -29
- layerv_qurl/types.py +17 -24
- {qurl_python-0.2.2.dist-info → qurl_python-0.4.0.dist-info}/METADATA +26 -4
- qurl_python-0.4.0.dist-info/RECORD +12 -0
- {qurl_python-0.2.2.dist-info → qurl_python-0.4.0.dist-info}/WHEEL +1 -1
- qurl_python-0.2.2.dist-info/RECORD +0 -12
- {qurl_python-0.2.2.dist-info → qurl_python-0.4.0.dist-info}/licenses/LICENSE +0 -0
layerv_qurl/__init__.py
CHANGED
|
@@ -31,7 +31,6 @@ from layerv_qurl.types import (
|
|
|
31
31
|
AccessGrant,
|
|
32
32
|
AccessPolicy,
|
|
33
33
|
AccessToken,
|
|
34
|
-
AgentBootstrapOutput,
|
|
35
34
|
AIAgentPolicy,
|
|
36
35
|
APIKey,
|
|
37
36
|
APIKeyListOutput,
|
|
@@ -57,7 +56,6 @@ from layerv_qurl.types import (
|
|
|
57
56
|
InvoiceListOutput,
|
|
58
57
|
ListOutput,
|
|
59
58
|
MintOutput,
|
|
60
|
-
NHPServerPeerInfo,
|
|
61
59
|
Portal,
|
|
62
60
|
PortalSession,
|
|
63
61
|
Quota,
|
|
@@ -108,7 +106,6 @@ __all__ = [
|
|
|
108
106
|
"AccessCode",
|
|
109
107
|
"AccessCodeListOutput",
|
|
110
108
|
"AIAgentPolicy",
|
|
111
|
-
"AgentBootstrapOutput",
|
|
112
109
|
"APIKey",
|
|
113
110
|
"APIKeyListOutput",
|
|
114
111
|
"BatchCreateItem",
|
|
@@ -130,7 +127,6 @@ __all__ = [
|
|
|
130
127
|
"DomainVerifyOutput",
|
|
131
128
|
"Invoice",
|
|
132
129
|
"InvoiceListOutput",
|
|
133
|
-
"NHPServerPeerInfo",
|
|
134
130
|
"Portal",
|
|
135
131
|
"PortalSession",
|
|
136
132
|
"QuotaPlan",
|
layerv_qurl/_utils.py
CHANGED
|
@@ -43,7 +43,6 @@ from layerv_qurl.types import (
|
|
|
43
43
|
AccessGrant,
|
|
44
44
|
AccessPolicy,
|
|
45
45
|
AccessToken,
|
|
46
|
-
AgentBootstrapOutput,
|
|
47
46
|
AIAgentPolicy,
|
|
48
47
|
APIKey,
|
|
49
48
|
APIKeyListOutput,
|
|
@@ -68,7 +67,6 @@ from layerv_qurl.types import (
|
|
|
68
67
|
InvoiceListOutput,
|
|
69
68
|
ListOutput,
|
|
70
69
|
MintOutput,
|
|
71
|
-
NHPServerPeerInfo,
|
|
72
70
|
Portal,
|
|
73
71
|
PortalSession,
|
|
74
72
|
Quota,
|
|
@@ -991,9 +989,10 @@ def _parse_rate_limits(data: dict[str, Any] | None) -> RateLimits | None:
|
|
|
991
989
|
create_per_hour=data.get("create_per_hour", 0),
|
|
992
990
|
list_per_minute=data.get("list_per_minute", 0),
|
|
993
991
|
resolve_per_minute=data.get("resolve_per_minute", 0),
|
|
994
|
-
max_active_qurls=data.get("max_active_qurls"
|
|
995
|
-
max_tokens_per_qurl=data.get("max_tokens_per_qurl", 0),
|
|
992
|
+
max_active_qurls=data.get("max_active_qurls"),
|
|
996
993
|
max_expiry_seconds=data.get("max_expiry_seconds", 0),
|
|
994
|
+
max_active_resources=data.get("max_active_resources"),
|
|
995
|
+
max_data_transfer_bytes=data.get("max_data_transfer_bytes"),
|
|
997
996
|
)
|
|
998
997
|
|
|
999
998
|
|
|
@@ -1002,11 +1001,14 @@ def _parse_usage_block(data: dict[str, Any] | None) -> Usage | None:
|
|
|
1002
1001
|
return None
|
|
1003
1002
|
return Usage(
|
|
1004
1003
|
qurls_created=data.get("qurls_created", 0),
|
|
1005
|
-
active_qurls=data.get("active_qurls"
|
|
1004
|
+
active_qurls=data.get("active_qurls"),
|
|
1006
1005
|
# Nullable per the API spec — the field is null when
|
|
1007
1006
|
# max_active_qurls is unlimited.
|
|
1008
1007
|
active_qurls_percent=data.get("active_qurls_percent"),
|
|
1009
1008
|
total_accesses=data.get("total_accesses", 0),
|
|
1009
|
+
active_resources=data.get("active_resources"),
|
|
1010
|
+
active_resources_percent=data.get("active_resources_percent"),
|
|
1011
|
+
data_transfer_bytes=data.get("data_transfer_bytes"),
|
|
1010
1012
|
)
|
|
1011
1013
|
|
|
1012
1014
|
|
|
@@ -1292,8 +1294,10 @@ def parse_current_period_usage(data: dict[str, Any]) -> CurrentPeriodUsage:
|
|
|
1292
1294
|
period_start=_parse_dt(data.get("period_start")),
|
|
1293
1295
|
period_end=_parse_dt(data.get("period_end")),
|
|
1294
1296
|
qurls_created=data.get("qurls_created", 0),
|
|
1295
|
-
active_qurls=data.get("active_qurls"
|
|
1297
|
+
active_qurls=data.get("active_qurls"),
|
|
1296
1298
|
cost_estimate=_parse_usage_cost(data.get("cost_estimate")),
|
|
1299
|
+
active_resources=data.get("active_resources"),
|
|
1300
|
+
data_transfer_bytes=data.get("data_transfer_bytes"),
|
|
1297
1301
|
)
|
|
1298
1302
|
|
|
1299
1303
|
|
|
@@ -1439,22 +1443,6 @@ def parse_connector_installation_list_output(
|
|
|
1439
1443
|
)
|
|
1440
1444
|
|
|
1441
1445
|
|
|
1442
|
-
def parse_agent_bootstrap_output(data: dict[str, Any]) -> AgentBootstrapOutput:
|
|
1443
|
-
"""Parse connector agent bootstrap output."""
|
|
1444
|
-
raw_peer = data.get("nhp_server_peer")
|
|
1445
|
-
peer = raw_peer if isinstance(raw_peer, dict) else {}
|
|
1446
|
-
return AgentBootstrapOutput(
|
|
1447
|
-
agent_id=data.get("agent_id", ""),
|
|
1448
|
-
registered_at=_parse_dt(data.get("registered_at")),
|
|
1449
|
-
nhp_server_peer=NHPServerPeerInfo(
|
|
1450
|
-
public_key_b64=peer.get("public_key_b64", ""),
|
|
1451
|
-
host=peer.get("host", ""),
|
|
1452
|
-
port=peer.get("port", 0),
|
|
1453
|
-
expire_time=peer.get("expire_time", 0),
|
|
1454
|
-
),
|
|
1455
|
-
)
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
1446
|
def _validate_batch_create_shape(data: Any) -> None:
|
|
1459
1447
|
"""Defense-in-depth structural check for batch_create responses.
|
|
1460
1448
|
|
layerv_qurl/async_client.py
CHANGED
|
@@ -35,7 +35,6 @@ from layerv_qurl._utils import (
|
|
|
35
35
|
parse_access_code,
|
|
36
36
|
parse_access_code_list_output,
|
|
37
37
|
parse_access_token,
|
|
38
|
-
parse_agent_bootstrap_output,
|
|
39
38
|
parse_api_key,
|
|
40
39
|
parse_api_key_list_output,
|
|
41
40
|
parse_batch_create_output,
|
|
@@ -101,7 +100,6 @@ if TYPE_CHECKING:
|
|
|
101
100
|
AccessCodeListOutput,
|
|
102
101
|
AccessPolicy,
|
|
103
102
|
AccessToken,
|
|
104
|
-
AgentBootstrapOutput,
|
|
105
103
|
APIKey,
|
|
106
104
|
APIKeyListOutput,
|
|
107
105
|
BatchCreateItem,
|
|
@@ -1516,33 +1514,6 @@ class AsyncQURLClient:
|
|
|
1516
1514
|
)
|
|
1517
1515
|
return parse_connector_installation_list_output(data, meta)
|
|
1518
1516
|
|
|
1519
|
-
async def bootstrap_agent(
|
|
1520
|
-
self,
|
|
1521
|
-
*,
|
|
1522
|
-
public_key: str,
|
|
1523
|
-
agent_id: str | None = None,
|
|
1524
|
-
hostname: str | None = None,
|
|
1525
|
-
version: str | None = None,
|
|
1526
|
-
idempotency_key: str | None = None,
|
|
1527
|
-
) -> AgentBootstrapOutput:
|
|
1528
|
-
"""Bootstrap a LayerV qURL Connector agent."""
|
|
1529
|
-
validate_required_string(public_key, "public_key")
|
|
1530
|
-
body = build_body(
|
|
1531
|
-
{
|
|
1532
|
-
"public_key": public_key,
|
|
1533
|
-
"agent_id": agent_id,
|
|
1534
|
-
"hostname": hostname,
|
|
1535
|
-
"version": version,
|
|
1536
|
-
}
|
|
1537
|
-
)
|
|
1538
|
-
resp = await self._request(
|
|
1539
|
-
"POST",
|
|
1540
|
-
"/v1/agent/bootstrap",
|
|
1541
|
-
body=body,
|
|
1542
|
-
headers=idempotency_headers(idempotency_key),
|
|
1543
|
-
)
|
|
1544
|
-
return parse_agent_bootstrap_output(resp)
|
|
1545
|
-
|
|
1546
1517
|
# --- Internal HTTP plumbing ---
|
|
1547
1518
|
|
|
1548
1519
|
async def _request(
|
layerv_qurl/client.py
CHANGED
|
@@ -36,7 +36,6 @@ from layerv_qurl._utils import (
|
|
|
36
36
|
parse_access_code,
|
|
37
37
|
parse_access_code_list_output,
|
|
38
38
|
parse_access_token,
|
|
39
|
-
parse_agent_bootstrap_output,
|
|
40
39
|
parse_api_key,
|
|
41
40
|
parse_api_key_list_output,
|
|
42
41
|
parse_batch_create_output,
|
|
@@ -101,7 +100,6 @@ if TYPE_CHECKING:
|
|
|
101
100
|
AccessCodeListOutput,
|
|
102
101
|
AccessPolicy,
|
|
103
102
|
AccessToken,
|
|
104
|
-
AgentBootstrapOutput,
|
|
105
103
|
APIKey,
|
|
106
104
|
APIKeyListOutput,
|
|
107
105
|
BatchCreateItem,
|
|
@@ -1649,33 +1647,6 @@ class QURLClient:
|
|
|
1649
1647
|
)
|
|
1650
1648
|
return parse_connector_installation_list_output(data, meta)
|
|
1651
1649
|
|
|
1652
|
-
def bootstrap_agent(
|
|
1653
|
-
self,
|
|
1654
|
-
*,
|
|
1655
|
-
public_key: str,
|
|
1656
|
-
agent_id: str | None = None,
|
|
1657
|
-
hostname: str | None = None,
|
|
1658
|
-
version: str | None = None,
|
|
1659
|
-
idempotency_key: str | None = None,
|
|
1660
|
-
) -> AgentBootstrapOutput:
|
|
1661
|
-
"""Bootstrap a LayerV qURL Connector agent."""
|
|
1662
|
-
validate_required_string(public_key, "public_key")
|
|
1663
|
-
body = build_body(
|
|
1664
|
-
{
|
|
1665
|
-
"public_key": public_key,
|
|
1666
|
-
"agent_id": agent_id,
|
|
1667
|
-
"hostname": hostname,
|
|
1668
|
-
"version": version,
|
|
1669
|
-
}
|
|
1670
|
-
)
|
|
1671
|
-
resp = self._request(
|
|
1672
|
-
"POST",
|
|
1673
|
-
"/v1/agent/bootstrap",
|
|
1674
|
-
body=body,
|
|
1675
|
-
headers=idempotency_headers(idempotency_key),
|
|
1676
|
-
)
|
|
1677
|
-
return parse_agent_bootstrap_output(resp)
|
|
1678
|
-
|
|
1679
1650
|
# --- Internal HTTP plumbing ---
|
|
1680
1651
|
|
|
1681
1652
|
def _request(
|
layerv_qurl/types.py
CHANGED
|
@@ -211,15 +211,18 @@ class ListOutput:
|
|
|
211
211
|
|
|
212
212
|
@dataclass
|
|
213
213
|
class RateLimits:
|
|
214
|
-
"""Rate
|
|
214
|
+
"""Rate limits and plan allowances."""
|
|
215
215
|
|
|
216
216
|
create_per_minute: int = 0
|
|
217
217
|
create_per_hour: int = 0
|
|
218
218
|
list_per_minute: int = 0
|
|
219
219
|
resolve_per_minute: int = 0
|
|
220
|
-
|
|
221
|
-
|
|
220
|
+
# Deprecated alias for max_active_resources, not a qURL-count cap.
|
|
221
|
+
max_active_qurls: int | None = None
|
|
222
222
|
max_expiry_seconds: int = 0
|
|
223
|
+
# Missing/null limits remain unknown; -1 is the unlimited sentinel.
|
|
224
|
+
max_active_resources: int | None = None
|
|
225
|
+
max_data_transfer_bytes: int | None = None
|
|
223
226
|
|
|
224
227
|
|
|
225
228
|
@dataclass
|
|
@@ -227,10 +230,15 @@ class Usage:
|
|
|
227
230
|
"""Usage statistics."""
|
|
228
231
|
|
|
229
232
|
qurls_created: int = 0
|
|
230
|
-
|
|
233
|
+
# Deprecated alias for active_resources, not a count of qURLs.
|
|
234
|
+
active_qurls: int | None = None
|
|
231
235
|
# Changed from float=0.0 — callers must None-check before arithmetic.
|
|
232
236
|
active_qurls_percent: float | None = None
|
|
233
237
|
total_accesses: int = 0
|
|
238
|
+
active_resources: int | None = None
|
|
239
|
+
active_resources_percent: float | None = None
|
|
240
|
+
# Measured bytes this UTC calendar month; None is distinct from zero.
|
|
241
|
+
data_transfer_bytes: int | None = None
|
|
234
242
|
|
|
235
243
|
|
|
236
244
|
@dataclass
|
|
@@ -550,8 +558,12 @@ class CurrentPeriodUsage:
|
|
|
550
558
|
period_start: datetime | None
|
|
551
559
|
period_end: datetime | None
|
|
552
560
|
qurls_created: int
|
|
553
|
-
|
|
561
|
+
# Deprecated alias for active_resources, not a count of qURLs.
|
|
562
|
+
active_qurls: int | None
|
|
554
563
|
cost_estimate: UsageCostEstimate | None = None
|
|
564
|
+
active_resources: int | None = None
|
|
565
|
+
# Measured bytes this UTC calendar month, independent of the billing period.
|
|
566
|
+
data_transfer_bytes: int | None = None
|
|
555
567
|
|
|
556
568
|
|
|
557
569
|
@dataclass
|
|
@@ -663,25 +675,6 @@ class ConnectorInstallationListOutput:
|
|
|
663
675
|
has_more: bool = False
|
|
664
676
|
|
|
665
677
|
|
|
666
|
-
@dataclass
|
|
667
|
-
class NHPServerPeerInfo:
|
|
668
|
-
"""NHP server peer info returned to connector agents."""
|
|
669
|
-
|
|
670
|
-
public_key_b64: str
|
|
671
|
-
host: str
|
|
672
|
-
port: int
|
|
673
|
-
expire_time: int
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
@dataclass
|
|
677
|
-
class AgentBootstrapOutput:
|
|
678
|
-
"""Response from connector agent bootstrap."""
|
|
679
|
-
|
|
680
|
-
agent_id: str
|
|
681
|
-
registered_at: datetime | None
|
|
682
|
-
nhp_server_peer: NHPServerPeerInfo
|
|
683
|
-
|
|
684
|
-
|
|
685
678
|
# ---- batch_create input shape -------------------------------------------
|
|
686
679
|
# TypedDicts for :meth:`QURLClient.batch_create` items. Split into a
|
|
687
680
|
# required-fields base class and an `total=False` subclass so callers on
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: qurl-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Python SDK for the qURL™ API — secure, time-limited access links. Quantum URL is how you enter the hidden layer of the internet.
|
|
5
5
|
Project-URL: Homepage, https://github.com/layervai/qurl-python
|
|
6
6
|
Project-URL: Repository, https://github.com/layervai/qurl-python
|
|
@@ -25,6 +25,7 @@ Requires-Dist: langchain-core<2,>=0.3; extra == 'dev'
|
|
|
25
25
|
Requires-Dist: mypy>=1.14; extra == 'dev'
|
|
26
26
|
Requires-Dist: pytest-asyncio>=0.25; extra == 'dev'
|
|
27
27
|
Requires-Dist: pytest>=8; extra == 'dev'
|
|
28
|
+
Requires-Dist: qurl-conformance<0.13,>=0.1.2; extra == 'dev'
|
|
28
29
|
Requires-Dist: respx>=0.22; extra == 'dev'
|
|
29
30
|
Requires-Dist: ruff>=0.11; extra == 'dev'
|
|
30
31
|
Provides-Extra: langchain
|
|
@@ -331,10 +332,31 @@ All error classes inherit from `QURLError`, so `except QURLError` catches everyt
|
|
|
331
332
|
```python
|
|
332
333
|
quota = client.get_quota()
|
|
333
334
|
print(f"Plan: {quota.plan}")
|
|
334
|
-
|
|
335
|
-
|
|
335
|
+
usage = quota.usage
|
|
336
|
+
active = usage.active_resources if usage is not None else None
|
|
337
|
+
if active is None and usage is not None:
|
|
338
|
+
active = usage.active_qurls
|
|
339
|
+
print("Active protected resources:", active if active is not None else "unavailable")
|
|
340
|
+
if quota.rate_limits is not None:
|
|
341
|
+
print(f"Rate limit: {quota.rate_limits.create_per_minute}/min")
|
|
336
342
|
```
|
|
337
343
|
|
|
344
|
+
Use `max_active_resources`, `active_resources`, and `active_resources_percent`
|
|
345
|
+
for resource quotas. `max_data_transfer_bytes` is the monthly byte allowance;
|
|
346
|
+
`data_transfer_bytes` is measured usage, available on both quota usage and
|
|
347
|
+
current-period responses. This usage always covers the current UTC calendar
|
|
348
|
+
month, independently of a paid account's billing period. Missing or null values
|
|
349
|
+
remain `None`, distinct from a reported zero. The [service OpenAPI spec](https://github.com/layervai/qurl-service/blob/01d7c47361b5f72f890428f1a53bd04e8d7f67cc/api/openapi.yaml#L5796)
|
|
350
|
+
defines `-1` as unlimited for `max_active_resources` and its legacy alias
|
|
351
|
+
`max_active_qurls`, as well as `max_data_transfer_bytes`.
|
|
352
|
+
|
|
353
|
+
**Migration:** the deprecated `max_active_qurls` and `active_qurls` fields still
|
|
354
|
+
represent protected resources. Missing values now return `None` instead of
|
|
355
|
+
`0`; check `is not None` before arithmetic or displaying a count. Canonical
|
|
356
|
+
and legacy fields preserve their own wire values, so an older response that
|
|
357
|
+
omits canonical fields leaves those fields `None`. Prefer the canonical fields
|
|
358
|
+
when available.
|
|
359
|
+
|
|
338
360
|
JWT-authenticated dashboard endpoints are also available for usage, customer
|
|
339
361
|
settings, billing sessions, invoices, and API-key management. API-key auth
|
|
340
362
|
continues to work for normal qURL, resource, domain, webhook, connector, and
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
layerv_qurl/__init__.py,sha256=1PMfphJ3oAJm0VygtRg3lH2uH0NP1ruzkpJeErJJZkk,3795
|
|
2
|
+
layerv_qurl/_utils.py,sha256=UUhH4jsxv6KxDA_iSl3r-JETDl5Bqic0d2OOtM7gLkM,65742
|
|
3
|
+
layerv_qurl/async_client.py,sha256=2ap4aPZ0FfThnqjA2-P5bkyWpTYYqXC0yyu2D09QRFs,64703
|
|
4
|
+
layerv_qurl/client.py,sha256=w43jvXKUOyOS_Uta2ve7VfLz8VcM8ESMlwfO-QvFEFE,70582
|
|
5
|
+
layerv_qurl/errors.py,sha256=7vyBEsJnN-e7804hil9KRwEgmUv5QW-DUGTf6FdSaV0,4932
|
|
6
|
+
layerv_qurl/langchain.py,sha256=MJdow63lc6DXfL-riyu-rYC3cMiEKIOY9UZUvY4hEUQ,4695
|
|
7
|
+
layerv_qurl/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
layerv_qurl/types.py,sha256=Rb4Wu1ER_1U4pNES7A__TR_k7FPj3Y_6EmHOijGZC1w,18872
|
|
9
|
+
qurl_python-0.4.0.dist-info/METADATA,sha256=dURx4UtZTHY3pdYLXEm96FlY3Ab7Ltyn2f9wqmhUkJg,14560
|
|
10
|
+
qurl_python-0.4.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
11
|
+
qurl_python-0.4.0.dist-info/licenses/LICENSE,sha256=cg6W6pLqMQFf89yPfz5ClnVSrNEeoTh3NOEQyH9CaZw,1069
|
|
12
|
+
qurl_python-0.4.0.dist-info/RECORD,,
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
layerv_qurl/__init__.py,sha256=nrIMkVysd1vLBj9p1TvFpz8JQFCA5al-lhCLyzIiiMk,3897
|
|
2
|
-
layerv_qurl/_utils.py,sha256=OdZWAKOwewxzlSEeimgmv2r9o8feQWU-idwGziJg-bI,66046
|
|
3
|
-
layerv_qurl/async_client.py,sha256=05wIEqQTPsTB8y8hYXXM0jP8EIrXb1pF4nEHcVp7Ntk,65599
|
|
4
|
-
layerv_qurl/client.py,sha256=yvH-RlAx19LYCghEQpV0uam-DcF5lvloW3UKTUkQaRo,71466
|
|
5
|
-
layerv_qurl/errors.py,sha256=7vyBEsJnN-e7804hil9KRwEgmUv5QW-DUGTf6FdSaV0,4932
|
|
6
|
-
layerv_qurl/langchain.py,sha256=MJdow63lc6DXfL-riyu-rYC3cMiEKIOY9UZUvY4hEUQ,4695
|
|
7
|
-
layerv_qurl/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
-
layerv_qurl/types.py,sha256=HhUFPS3TVxttXFyHGtUMvOPNLh7AZWQq6Uueq6o0pho,18490
|
|
9
|
-
qurl_python-0.2.2.dist-info/METADATA,sha256=qDL7LzO0BFobOEWSrLnPMzKLGYZcgfm9XKgl0cC_o00,13161
|
|
10
|
-
qurl_python-0.2.2.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
|
|
11
|
-
qurl_python-0.2.2.dist-info/licenses/LICENSE,sha256=cg6W6pLqMQFf89yPfz5ClnVSrNEeoTh3NOEQyH9CaZw,1069
|
|
12
|
-
qurl_python-0.2.2.dist-info/RECORD,,
|
|
File without changes
|