This course turns the earlier HTTP policy lab into a working local integration. You will fetch order pages from a bundled HTTP server and export a deterministic report. The public runner continues to use supplied transports and exchanges; it receives no new outbound network access.
A request starts as data: method, URL and headers. Construct those components deliberately instead of splicing untrusted strings into a URL. Our helper builds GET requests; later lessons control the transport and response contract.
A slash between segments is structure; a slash inside a segment is data. quote(segment, safe="") encodes the latter before joining segments. Query encoding has different conventions: urlencode converts spaces to plus and a literal plus to %2B.
Keep ordered pairs when repeated parameters are meaningful. dict(query) loses earlier values for duplicate keys.
from urllib.parse import quote, urlencode
segments = ["team/a", "orders"]
path = "/" + "/".join(quote(s,safe="") for s in segments)
query = urlencode([("tag","C++ & Python"),("tag","x/y")])
print(path)
print(query)The supplied validation accepts a bounded absolute HTTP(S) origin and rejects embedded credentials, extra path/query/fragment and control characters. Header construction sets Accept and User-Agent and can add a validated synthetic bearer token. The lab does not need a real account or credential.
Never put bearer tokens in a query or print them in request logs. This builder keeps them in a separate header field. It does not itself authorize destinations or prevent every server-side routing interpretation. The downloadable transport has a narrower policy: literal 127.0.0.1 HTTP to the bundled API, no proxy lookup and no redirect following.
The optional Corey Schafer video uses Requests to explain HTTP. Our artifact uses the standard library and an injected adapter, so you can finish it without installing Requests. Broader external HTTPS communication is a later continuation.
from urllib.parse import urlencode
pairs = [("tag","first"),("tag","second")]
print("preserved:", urlencode(pairs))
print("collapsed:", urlencode(dict(pairs)))Complete the final assembly block and test an embedded slash, repeated keys, Unicode text and an empty query. Keep inputs unchanged and use synthetic authorization values only in exercises.
Next the transport will open a response with a timeout, read at most the configured body limit plus one detection byte, and close it on every exit.