cat answers.20260324T184522Z.1774377922.730748177.c1c447f0-a02a-4209-8227-8f61afc60a14.jsonl | ./RDAP_parse > final_output_8f61a.txt
cat answers.20260324T175046Z.1774374646.515197515.f9fdcde0-675a-4081-b955-c1d02c218331.jsonl | ./RDAP_parse > final_output_c1d02c2.txt
diff final_output_8f61a.txt answers.20260324T184522Z.1774377922.730748177.c1c447f0-a02a-4209-8227-8f61afc60a14.expected.jsonl
diff final_output_c1d02c2.txt answers.20260324T175046Z.1774374646.515197515.f9fdcde0-675a-4081-b955-c1d02c218331.expected.jsonl
uv run pyinstaller --onefile RDAP_parse.py and the executable will be located in ~/dev/dist
uv run pytest tests_RDAP.py
-
Package Manager
uv: install withcurl -LsSf https://astral.sh/uv/install.sh | sh- Run
uv syncinside the project directory to build the environment. - use
uv run <executable>to run inside the project environment.
-
Core Runtime:
- python (>=3.10)
-
Main Dependencies:
- python-dateutil
-
Development Dependencies:
- black
- pyinstaller
- ruff
- pytest
-
parse a line of .jsonl and translates every nested string/object into its corresponding Python datatype.
-
serializes a Python object into a JSON formatted string and used
separators=(",", ":"), to eliminate whitespace. -
dateutil in python 3.10 cannot handle automatic iso conversion
-
used dateutil to automatically parse the ISO for more robust time handling
- Isolated the envelope into its own class and added the status checker in case of an error on a RDAP call
_parse_date()uses thedateutil.parser.isoparseto handle ISO 8601 format translation
- accepts rdap_dict
_parse_links()captures both thevalueandhrefurls into the list to match.expected.jsonl_parse_src()captures therel=selflink to match.expected.jsonl_parse_status()extracts the single array from the domain data type and appends to output._parse_sDNS()extracts boolean based on delegationSigned in RDAP_parse_events()iterates through the events array, and maps eventAction strings to keys reg, chng, exp, upd.
_parse_nameservers()parses ldhName for the nameservers list and uses.lower()to meet formatting requirements.
_parse_entities()Uses a while loop and a stack instead of recursion to simplify debugging, increase readability, and decrease complexity.stack.extend(nested_ent)uses.extend()which extracts each individual element from an iterable datatype and then pushes it onto a stack without being nested.- Parses the RFC 7095 vcardArray to extract email and tel properties.
- The loop logic for vcard parsing is hardcoded to match the vCard & jCard RFC.
- Takes a single line of jsonl as input and then builds the required output with some built in safety checks.
- Reads each line from
sys.stdinto accept piped input, and prints directly to stdout. - The
srcattribute falls back to the top-level envelopelinkif the RDAP payload is missing or corrupted. - Designed to always output the same set of keys specified in the challenge.md document.
- Implements try/except blocks to catch and log
json.JSONDecodeErrortosys.stderrto prevent errors from outputting to stdout.
https://www.rfc-editor.org/rfc/rfc9083.html+
-
roles -- an array of strings, each signifying the relationship an object would have with its closest containing object (see Section 10.2.4 for a list of values)
-
entities -- an array of entity objects as defined by this section
-
Entity class includes nested children entites
https://datatracker.ietf.org/doc/html/rfc7095
https://www.rfc-editor.org/rfc/rfc6350.html
### THE FULL vCARD ARRAY
[
"vcard",
[
# [0]: property-name, [1]: parameters-dict, [2]: type-identifier, [3]: value(s)
["version", {}, "text", "4.0"],
# 1. FORMATTED NAME
["fn", {}, "text", "John Doe"],
# 2. EMAIL ADDRESS
["email", { "type": "work" }, "text", "abuse-complaints@squarespace.com"],
# 3. TELEPHONE (VOICE vs FAX)
# The "type" parameter dictates what kind of phone number it is.
["tel", { "type": "voice" }, "uri", "tel:+1.6466935324"],
["tel", { "type": ["work", "fax"] }, "uri", "tel:+1.555.555.1234"],
# 4. DELIVERY ADDRESS
# The value at index [3] is ALWAYS a list of exactly 7 components.
# Format: [PO Box, Extended, Street, City, State/Region, Postal Code, Country]
["adr", { "type": "work" }, "text",
[
"", # 0: Post Office Box
"Suite 901", # 1: Extended Address (Suite/Apt)
"123 Maple Ave",# 2: Street Address
"Vancouver", # 3: Locality (City)
"BC", # 4: Region (State/Province)
"A1B 2C9", # 5: Postal Code
"Canada" # 6: Country
]
]
]
]
### THE TEMPLATE EXTRACTION PATTERNS
# Email Template
[ "property-name", { "parameter-key": "parameter-val" }, "type-id", "value" ]
[ "email", { "type": "work" }, "text", "abuse-complaints@squarespace.com" ]
# Phone Template (Voice)
[ "property-name", { "parameter-key": "parameter-val" }, "type-id", "value" ]
[ "tel", { "type": "voice" }, "uri", "tel:+1.6466935324" ]
# Phone Template (Fax)
[ "property-name", { "parameter-key": "parameter-val" }, "type-id", "value" ]
[ "tel", { "type": ["work", "fax"] }, "uri", "tel:+1.555.555.1234" ]