Repository navigation
Expand file tree
/
Copy pathergonomics.mojo
More file actions
273 lines (215 loc) Β· 11.3 KB
/
Copy pathergonomics.mojo
File metadata and controls
273 lines (215 loc) Β· 11.3 KB
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
"""Example 07 β High-level ergonomics API.
Demonstrates the high-level, requests-style interface:
High-level HTTP
βββββββββββββββ
- Module-level one-shot helpers: get(), post(), put(), patch(), delete(), head()
- String body β Content-Type: application/json set automatically
- json.Value body β auto-serialised to JSON
- HttpClient("https://api.example.com", BearerAuth("tok")) β base URL + auth
- raise_for_status() to turn non-2xx into HttpError
- Response.json() returning a json.Value
- iter_bytes() for streaming response bodies
Authentication
ββββββββββββββ
- BasicAuth (RFC 7617 β base64-encoded username:password)
- BearerAuth (RFC 6750 β Authorization: Bearer <token>)
Context managers
ββββββββββββββββ
- HttpClient as context manager
- WsClient as context manager
High-level WebSocket
ββββββββββββββββββββ
- WsMessage: recv_message() returns a typed message wrapper
- as_text() / as_bytes() / is_text
Buffered I/O
ββββββββββββ
- BufReader[TlsStream] for efficient line-by-line reading
All network-dependent sections skip gracefully when offline.
Run:
pixi run example-ergonomics
"""
from flare.http import (
HttpClient,
BasicAuth,
BearerAuth,
HttpError,
TooManyRedirects,
Status,
get,
post,
put,
patch,
delete,
head,
)
from flare.ws import WsClient, WsMessage
from flare.io import BufReader
from flare.tls import TlsStream, TlsConfig
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# Section 1: Module-level one-shot helpers
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def _demo_oneshot():
print("ββ 1. Module-level one-shot helpers ββ")
try:
var resp = get("http://httpbin.org/get")
print(" get() status:", resp.status, "ok:", resp.ok())
# String body β Content-Type: application/json set automatically
var resp2 = post("http://httpbin.org/post", '{"library": "flare"}')
print(" post() status:", resp2.status)
var resp3 = put("http://httpbin.org/put", '{"action": "replace"}')
print(" put() status:", resp3.status)
var resp4 = patch("http://httpbin.org/patch", '{"field": "patched"}')
print(" patch() status:", resp4.status)
var resp5 = delete("http://httpbin.org/delete")
print(" delete() status:", resp5.status)
var resp6 = head("http://httpbin.org/get")
print(
" head() status:",
resp6.status,
"body:",
len(resp6.body),
"bytes",
)
except e:
print(" [SKIP] network unavailable:", String(e))
print()
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# Section 2: HttpClient with base_url
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def _demo_base_url():
print("ββ 2. HttpClient with base URL (positional first arg) ββ")
try:
# Positional base_url: HttpClient("url") β most natural syntax
var client = HttpClient("http://httpbin.org")
var resp = client.get("/get") # relative path resolved against base
print(" GET /get β", resp.status)
# String body β JSON Content-Type automatic
var resp2 = client.post("/post", '{"key": "value"}')
print(" POST /post β", resp2.status)
except e:
print(" [SKIP] network unavailable:", String(e))
print()
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# Section 3: raise_for_status()
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def _demo_raise_for_status():
print("ββ 3. raise_for_status() ββ")
try:
var resp = get("http://httpbin.org/status/404")
try:
resp.raise_for_status()
print(" ERROR: expected HttpError for 404")
except:
print(" β HttpError raised for 404 (expected)")
except e:
print(" [SKIP] network unavailable:", String(e))
try:
var resp = get("http://httpbin.org/get")
resp.raise_for_status() # no-op for 200
print(" β raise_for_status() no-op on 200")
except e:
print(" [SKIP] network unavailable:", String(e))
print()
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# Section 4: Authentication
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def _demo_auth():
print("ββ 4. Authentication ββ")
# BasicAuth β auth as first positional arg
try:
var client = HttpClient(BasicAuth("alice", "s3cr3t"))
var resp = client.get("http://httpbin.org/basic-auth/alice/s3cr3t")
print(" BasicAuth β", resp.status, "(expect 200)")
except e:
print(" [SKIP] BasicAuth network unavailable:", String(e))
# BearerAuth β base_url + auth as two positional args
try:
var client = HttpClient(
"http://httpbin.org", BearerAuth("my-token-abc")
)
var resp = client.get("/bearer")
print(" BearerAuth + base_url β", resp.status, "(expect 200)")
except e:
print(" [SKIP] BearerAuth network unavailable:", String(e))
print()
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# Section 5: iter_bytes() β streaming body
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def _demo_iter_bytes():
print("ββ 5. iter_bytes() streaming ββ")
try:
var resp = get("http://httpbin.org/bytes/1024")
var total = 0
for chunk in resp.iter_bytes(512):
total += len(chunk)
print(" streamed", total, "bytes in chunks of 512")
except e:
print(" [SKIP] network unavailable:", String(e))
print()
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# Section 6: HttpClient context manager
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def _demo_http_context_manager():
print("ββ 6. HttpClient context manager ββ")
try:
with HttpClient() as c:
var resp = c.get("http://httpbin.org/get")
print(" context manager GET β", resp.status)
except e:
print(" [SKIP] network unavailable:", String(e))
print()
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# Section 7: WsClient context manager + WsMessage
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def _demo_ws_high_level():
print("ββ 7. WebSocket: context manager + WsMessage ββ")
try:
with WsClient.connect("ws://echo.websocket.events") as ws:
ws.send_text("hello from flare!")
print(" Sent: 'hello from flare!'")
# recv_message() wraps recv() in a typed WsMessage
var found = False
for _ in range(5):
var msg = ws.recv_message()
if msg.is_text and "hello from flare!" in msg.as_text():
print(" β WsMessage echo:", msg.as_text())
found = True
break
if not found:
print(" echo not received within 5 messages")
except e:
print(" [SKIP] echo server unavailable:", String(e))
print()
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# Section 8: BufReader β buffered line-by-line reading over TLS
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def _demo_buf_reader():
print("ββ 8. BufReader over TLS ββ")
try:
var stream = TlsStream.connect("example.com", 443, TlsConfig())
_ = stream.write(
"GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n"
.as_bytes()
)
# Wrap stream in a 4096-byte buffer for efficient reads
var reader = BufReader[TlsStream](stream^, capacity=4096)
# Read the first 4 lines of the HTTP response header
for _ in range(4):
var line = reader.readline()
print(" ", line, end="")
except e:
print(" [SKIP] TLS unavailable:", String(e))
print()
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def main() raises:
print("=== flare Example 07: High-Level Ergonomics API ===")
print()
_demo_oneshot()
_demo_base_url()
_demo_raise_for_status()
_demo_auth()
_demo_iter_bytes()
_demo_http_context_manager()
_demo_ws_high_level()
_demo_buf_reader()
print("=== Example 07 complete ===")