Skip to content

89sundown/code_test

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

81 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RDAP_parse

Running the program

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

checked output

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

Building the executable

uv run pyinstaller --onefile RDAP_parse.py and the executable will be located in ~/dev/dist

Tests

uv run pytest tests_RDAP.py

Dependencies

  • Package Manager

    • uv: install with curl -LsSf https://astral.sh/uv/install.sh | sh
    • Run uv sync inside 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

Notes on Class / Functions

RDAPEnvelope

  • Isolated the envelope into its own class and added the status checker in case of an error on a RDAP call
  • _parse_date() uses the dateutil.parser.isoparse to handle ISO 8601 format translation

DomainParser

  • accepts rdap_dict
  • _parse_links() captures both the value and href urls into the list to match .expected.jsonl
  • _parse_src() captures the rel=self link 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.

NameserverParser

  • _parse_nameservers() parses ldhName for the nameservers list and uses .lower() to meet formatting requirements.

EntityParser

  • _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.

main() Execution Loop

  • 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.stdin to accept piped input, and prints directly to stdout.
  • The src attribute falls back to the top-level envelope link if 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.JSONDecodeError to sys.stderr to prevent errors from outputting to stdout.

RFC9083 / RFC7095 / RFC6350

RFC9083 JSON Responses for RDAP

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

RFC7095 & RFC6350 jCard and vCard documentation

https://datatracker.ietf.org/doc/html/rfc7095

https://www.rfc-editor.org/rfc/rfc6350.html

Example template

### 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"                ]

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages