Skip to content

Commit efe9182

Browse files
authored
Merge pull request #99 from yashksaini-coder/Fix/98
Fix Tag-Only Protocols validation error
2 parents 6651c13 + d3838eb commit efe9182

File tree

7 files changed

+497
-50
lines changed

7 files changed

+497
-50
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ clean-build:
3838
rm -fr dist/
3939
rm -fr .eggs/
4040
find . -name '*.egg-info' -exec rm -fr {} +
41-
find . -name '*.egg' -exec rm -f {} +
41+
find . -name '*.egg' -exec rm -rf {} +
4242

4343
clean-pyc:
4444
find . -name '*.pyc' -exec rm -f {} +

docs/examples.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,22 @@ This example shows:
101101
:language: python
102102
:caption: examples/garlic/garlic_examples.py
103103

104+
Tag-Only Protocol Examples
105+
---------------------------
106+
107+
The `examples/tag_only/` directory demonstrates how to work with tag-only protocols (protocols that do not accept values) in multiaddr addresses.
108+
109+
This example shows:
110+
- Basic tag-only protocol usage (http, https, tls, noise, webrtc, etc.)
111+
- Protocol validation for tag-only protocols
112+
- Error handling for invalid value assignments (both ``/tag/value`` and ``/tag=value`` syntaxes)
113+
- Multiaddr integration with tag-only protocols
114+
- Chaining multiple tag-only protocols
115+
116+
.. literalinclude:: ../examples/tag_only/tag_only_examples.py
117+
:language: python
118+
:caption: examples/tag_only/tag_only_examples.py
119+
104120
Running the Examples
105121
--------------------
106122

@@ -126,4 +142,7 @@ All examples can be run directly with Python:
126142
# Garlic protocol examples
127143
python examples/garlic/garlic_examples.py
128144
145+
# Tag-only protocol examples
146+
python examples/tag_only/tag_only_examples.py
147+
129148
Note: Some examples require network connectivity and may take a few seconds to complete due to DNS resolution.
Lines changed: 297 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Tag-only protocol examples for py-multiaddr.
4+
5+
This script demonstrates how to work with tag-only protocols in py-multiaddr.
6+
Tag-only protocols are protocols that do not accept values - their presence
7+
alone indicates a specific property or capability (e.g., ``/http``, ``/tls``,
8+
``/noise``).
9+
10+
## Overview
11+
12+
This script shows various examples of tag-only protocol usage:
13+
14+
1. **Basic Tag-Only Protocol Usage**: Creating and parsing simple tag-only addresses.
15+
2. **Protocol Validation**: Testing valid and invalid tag-only protocol syntax.
16+
3. **Error Handling**: Demonstrating clear error messages for invalid value assignments.
17+
4. **Multiaddr Integration**: Using tag-only protocols in realistic multiaddr stacks.
18+
5. **Common Tag-Only Protocols**: Examples with various tag-only protocols.
19+
20+
## Expected Output
21+
22+
When you run this script, you should see output similar to:
23+
24+
```
25+
Tag-Only Protocol Examples
26+
==================================================
27+
=== Basic Tag-Only Protocol Usage ===
28+
Valid tag-only addresses:
29+
/http
30+
/https
31+
/tls
32+
/noise
33+
/webrtc
34+
35+
=== Protocol Validation ===
36+
Testing valid tag-only: /http
37+
Valid: True
38+
Protocols: ['http']
39+
40+
Testing invalid tag-only (with value): /http/value
41+
Valid: False
42+
Error: Protocol 'http' does not take an argument
43+
44+
Testing invalid tag-only (= syntax): /http=value
45+
Valid: False
46+
Error: Protocol 'http' does not take an argument
47+
48+
=== Multiaddr Integration ===
49+
Complex multiaddr with tag-only protocols:
50+
Address: /ip4/127.0.0.1/tcp/443/https
51+
Protocols: ['ip4', 'tcp', 'https']
52+
Has 'https' protocol: True
53+
54+
=== Common Tag-Only Protocols ===
55+
HTTP: /ip4/127.0.0.1/tcp/80/http
56+
HTTPS: /ip4/127.0.0.1/tcp/443/https
57+
TLS: /ip4/127.0.0.1/tcp/443/tls
58+
WebRTC: /ip4/127.0.0.1/udp/9090/webrtc-direct
59+
Noise: /ip4/127.0.0.1/tcp/12345/noise
60+
61+
==================================================
62+
All examples completed!
63+
```
64+
65+
## Key Features Demonstrated
66+
67+
- **Tag-Only Protocols**: Protocols that don't accept values (http, https, tls, noise, webrtc, etc.)
68+
- **Validation**: Ensures no value is provided to tag-only protocols
69+
- **Error Messages**: Clear error messages that don't include invalid values
70+
- **Multiaddr Integration**: Using tag-only protocols as part of connection stacks
71+
- **Syntax Validation**: Both ``/tag/value`` and ``/tag=value`` syntaxes are rejected
72+
73+
## Requirements
74+
75+
- Python 3.10+
76+
- py-multiaddr library
77+
78+
## Usage
79+
80+
```bash
81+
python examples/tag_only/tag_only_examples.py
82+
```
83+
"""
84+
85+
from multiaddr import Multiaddr
86+
from multiaddr.exceptions import StringParseError
87+
88+
# Common tag-only protocols
89+
TAG_ONLY_PROTOCOLS = [
90+
"http",
91+
"https",
92+
"tls",
93+
"noise",
94+
"webrtc",
95+
"webrtc-direct",
96+
"quic",
97+
"quic-v1",
98+
"ws",
99+
"wss",
100+
"p2p-circuit",
101+
"webtransport",
102+
]
103+
104+
105+
def basic_tag_only_usage():
106+
"""
107+
Basic tag-only protocol usage example.
108+
109+
This function demonstrates:
110+
- Creating tag-only multiaddrs
111+
- Extracting protocol information
112+
- Validating tag-only addresses
113+
"""
114+
print("=== Basic Tag-Only Protocol Usage ===")
115+
print("Valid tag-only addresses:")
116+
117+
for proto_name in TAG_ONLY_PROTOCOLS[:5]: # Show first 5
118+
addr_str = f"/{proto_name}"
119+
try:
120+
_ = Multiaddr(addr_str) # Validate the address
121+
print(f" {addr_str}")
122+
except Exception as e:
123+
print(f" {addr_str} - Error: {e}")
124+
125+
126+
def protocol_validation():
127+
"""
128+
Demonstrate protocol validation for tag-only protocols.
129+
130+
This function shows:
131+
- Valid tag-only addresses
132+
- Invalid tag-only addresses with /tag/value syntax
133+
- Invalid tag-only addresses with /tag=value syntax
134+
- Error handling for validation failures
135+
"""
136+
print("\n=== Protocol Validation ===")
137+
138+
# Test valid tag-only protocol
139+
valid_addr = "/http"
140+
print(f"Testing valid tag-only: {valid_addr}")
141+
try:
142+
ma = Multiaddr(valid_addr)
143+
print(" Valid: True")
144+
print(f" Protocols: {[p.name for p in ma.protocols()]}")
145+
except Exception as e:
146+
print(" Valid: False")
147+
print(f" Error: {e}")
148+
149+
# Test invalid tag-only with /tag/value syntax
150+
invalid_addr_slash = "/http/value"
151+
print(f"\nTesting invalid tag-only (with value): {invalid_addr_slash}")
152+
try:
153+
Multiaddr(invalid_addr_slash)
154+
print(" Valid: True (ERROR: Should have failed)")
155+
except StringParseError as e:
156+
print(" Valid: False")
157+
print(f" Error: {e}")
158+
# Verify error message doesn't include the invalid value
159+
error_str = str(e)
160+
assert "value" not in error_str or "does not take an argument" in error_str
161+
162+
# Test invalid tag-only with /tag=value syntax
163+
invalid_addr_equals = "/http=value"
164+
print(f"\nTesting invalid tag-only (= syntax): {invalid_addr_equals}")
165+
try:
166+
Multiaddr(invalid_addr_equals)
167+
print(" Valid: True (ERROR: Should have failed)")
168+
except StringParseError as e:
169+
print(" Valid: False")
170+
print(f" Error: {e}")
171+
172+
173+
def multiaddr_integration():
174+
"""
175+
Demonstrate tag-only protocol integration with other protocols.
176+
177+
This function shows:
178+
- Using tag-only protocols as part of realistic multiaddr stacks
179+
- Protocol stack analysis
180+
- Common use cases
181+
"""
182+
print("\n=== Multiaddr Integration ===")
183+
184+
# HTTPS example
185+
https_addr = "/ip4/127.0.0.1/tcp/443/https"
186+
print("Complex multiaddr with tag-only protocols:")
187+
print(f" Address: {https_addr}")
188+
189+
try:
190+
ma = Multiaddr(https_addr)
191+
protocols = [p.name for p in ma.protocols()]
192+
print(f" Protocols: {protocols}")
193+
194+
# Check for 'https' protocol
195+
has_https = "https" in protocols
196+
print(f" Has 'https' protocol: {has_https}")
197+
198+
except Exception as e:
199+
print(f" Error: {e}")
200+
201+
202+
def common_tag_only_protocols():
203+
"""
204+
Demonstrate common tag-only protocol use cases.
205+
206+
This function shows:
207+
- HTTP and HTTPS usage
208+
- TLS usage
209+
- WebRTC usage
210+
- Noise protocol usage
211+
"""
212+
print("\n=== Common Tag-Only Protocols ===")
213+
214+
examples = [
215+
("HTTP", "/ip4/127.0.0.1/tcp/80/http"),
216+
("HTTPS", "/ip4/127.0.0.1/tcp/443/https"),
217+
("TLS", "/ip4/127.0.0.1/tcp/443/tls"),
218+
("WebRTC", "/ip4/127.0.0.1/udp/9090/webrtc-direct"),
219+
("Noise", "/ip4/127.0.0.1/tcp/12345/noise"),
220+
]
221+
222+
for name, addr_str in examples:
223+
try:
224+
_ = Multiaddr(addr_str) # Validate the address
225+
print(f"{name}: {addr_str}")
226+
except Exception as e:
227+
print(f"{name}: {addr_str} - Error: {e}")
228+
229+
230+
def chaining_tag_only_protocols():
231+
"""
232+
Demonstrate chaining multiple tag-only protocols.
233+
234+
This function shows:
235+
- Multiple tag-only protocols in sequence
236+
- Valid combinations
237+
- Protocol stack analysis
238+
"""
239+
print("\n=== Chaining Tag-Only Protocols ===")
240+
241+
examples = [
242+
"/webrtc/noise",
243+
"/webrtc-direct/webrtc",
244+
"/tls/http",
245+
]
246+
247+
for addr_str in examples:
248+
try:
249+
ma = Multiaddr(addr_str)
250+
protocols = [p.name for p in ma.protocols()]
251+
print(f" {addr_str}")
252+
print(f" Protocols: {protocols}")
253+
except Exception as e:
254+
print(f" {addr_str} - Error: {e}")
255+
256+
257+
def main():
258+
"""
259+
Run all tag-only protocol examples.
260+
261+
This function orchestrates all the tag-only protocol examples:
262+
1. Basic tag-only usage
263+
2. Protocol validation
264+
3. Multiaddr integration
265+
4. Common tag-only protocols
266+
5. Chaining tag-only protocols
267+
268+
Each example demonstrates different aspects of tag-only protocol
269+
functionality and shows how to use them with py-multiaddr.
270+
"""
271+
print("Tag-Only Protocol Examples")
272+
print("=" * 50)
273+
274+
try:
275+
basic_tag_only_usage()
276+
protocol_validation()
277+
multiaddr_integration()
278+
common_tag_only_protocols()
279+
chaining_tag_only_protocols()
280+
281+
print("\n" + "=" * 50)
282+
print("All examples completed!")
283+
print("\nSummary:")
284+
print("- Tag-only protocols work correctly")
285+
print("- Validation catches invalid use (with values)")
286+
print("- Both /tag/value and /tag=value syntaxes are rejected")
287+
print("- Integration with other protocols works as expected")
288+
print("- Multiple tag-only protocols can be chained")
289+
290+
except KeyboardInterrupt:
291+
print("\nExamples interrupted by user")
292+
except Exception as e:
293+
print(f"\nUnexpected error: {e}")
294+
295+
296+
if __name__ == "__main__":
297+
main()

0 commit comments

Comments
 (0)