### Install sectxt with pip Source: https://github.com/digitaltrustcenter/sectxt/blob/main/README.md Install the sectxt package from PyPI using pip. ```console > python -m pip install sectxt ``` -------------------------------- ### Example: accessing errors, recommendations, and notifications Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/parser.md Parses a file with a custom field and prints the three lists. Shows expected outputs for errors, recommendations, and notifications. ```python from sectxt import Parser content = ( "Contact: https://example.com/security\n" "Expires: 2030-12-31T23:59:59Z\n" "X-Custom-Field: value\n" ).encode() p = Parser(content) print(p.errors) # [] print(p.recommendations) # [{'code': 'not_signed', 'message': 'security.txt should be digitally signed.', 'line': None}] print(p.notifications) # [{'code': 'unknown_field', 'message': 'security.txt contains an unknown field. ...', 'line': 3}] ``` -------------------------------- ### Example: using is_valid with a minimal file Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/parser.md Parses a minimal security.txt file and prints the validity. If invalid, iterates over errors to print line, code, and message. ```python from sectxt import Parser content = ( "Contact: mailto:security@example.com\n" "Expires: 2030-12-31T23:59:59Z\n" ).encode() p = Parser(content) print(p.is_valid()) # True — a well-formed minimal file if not p.is_valid(): for e in p.errors: print(e["line"], e["code"], e["message"]) ``` -------------------------------- ### Example: iterating over parsed lines Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/parser.md Parses a file with a comment, an Expires field, and a trailing newline, then prints the type, field name, and value for each line. ```python from sectxt import Parser p = Parser(b"# comment\nExpires: 2030-12-31T23:59:59Z\n") for line in p.lines: print(line["type"], line["field_name"], repr(line["value"])) # comment None '# comment' # field 'expires' '2030-12-31T23:59:59Z' # empty None '' ``` -------------------------------- ### Console script entry point configuration in setup.cfg Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/command-line.md Registers the `sectxt` console script to call `sectxt.command_line:main`. ```ini [options.entry_points] console_scripts = sectxt = sectxt.command_line:main ``` -------------------------------- ### main() function in sectxt/command_line.py Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/command-line.md Parses CLI arguments, creates a SecurityTXT instance, and prints output messages. Returns 0 if the file is valid, otherwise 1. Errors are always included; recommendations and notifications are only included when the corresponding flags are set. ```python def main() -> int: """Main function which parses the arguments, calls SecurityTXT() and prints output messages. Returns: 0 if the security.txt file does not contain any errors; otherwise, 1 """ parser = argparse.ArgumentParser(description="Parse and validate security.txt") parser.add_argument("address", help="website URL or path to local file to check") parser.add_argument( "--json", action="store_true", help="output the results in JSON format" ) parser.add_argument( "--no-recommend-unknown-fields", action="store_true", help="do not issue notifications for unknown fields", ) parser.add_argument( "--show-notifications", action="store_true", help="show notifications" ) parser.add_argument( "--show-recommendations", action="store_true", help="show recommendations" ) parser.add_argument( "--version", action="version", version="%(prog)s " + __version__ ) args = parser.parse_args() address_is_local = not valid_url(args.address) s = SecurityTXT( args.address, recommend_unknown_fields=not args.no_recommend_unknown_fields, is_local=address_is_local, ) output_messages = tag_messages(s.errors, "ERROR") if args.show_recommendations: output_messages += tag_messages(s.recommendations, "REC") if args.show_notifications: output_messages += tag_messages(s.notifications, "NOTE") if args.json: print(output_messages) else: human_readable_print(output_messages) return 0 if s.is_valid() else 1 ``` -------------------------------- ### SecurityTXT.__init__ signature Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/configuration.md Constructor for the SecurityTXT class. Takes a URL or local file path, a flag to recommend unknown fields, and a local flag. Defaults: recommend_unknown_fields=True, is_local=False. ```python def __init__(self, url: str, recommend_unknown_fields: bool = True, is_local: bool = False): ``` -------------------------------- ### SecurityTXT.__init__ Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/securitytxt.md Constructs a SecurityTXT instance, triggering the full scrape and parse pipeline. In remote mode, it scrapes up to four candidate URLs; in local mode, it reads a file from disk. ```APIDOC ## SecurityTXT.__init__ ### Description Constructs a SecurityTXT instance, which immediately scrapes or reads the security.txt content and parses it. In remote mode, it attempts up to four candidate URLs in a fixed order. In local mode, it reads the given file path. ### Method Constructor ### Signature ```python def __init__(self, url: str, recommend_unknown_fields: bool = True, is_local: bool = False): ``` ### Parameters - **url** (str) - Required - Website address or path to a local file to check. If it contains a scheme (e.g. `https://example.com`) and `is_local` is `False`, the netloc part is extracted and used as the host to scrape; otherwise the string is used verbatim as the local path or bare host. - **recommend_unknown_fields** (bool) - Optional, default `True` - When `True`, fields not in the RFC 9116 known set produce a `unknown_field` notification; when `False`, they are silently ignored (RFC 9116 §2.4 behavior). - **is_local** (bool) - Optional, default `False` - When `True`, `url` is treated as a filesystem path and the file is read and validated locally; no network requests are made and the scheme/netloc logic is skipped. ### Return `SecurityTXT` instance. Construction triggers the full scrape + parse pipeline synchronously (via the `Parser.__init__` → `_process()` chain); no separate `parse()` call is needed. ### Raises - **ValueError** - If `is_local=False` and `url` has a scheme (e.g. `https://...`) but an empty netloc (e.g. `"https://"`). Message: `"Invalid URL"`. ### Notes - `urlsplit(url).netloc` includes the port when present; a host with a scheme is stored stripped of the scheme in `self._loc`. In local mode the string is passed through unmodified. ### Remote Mode Candidate URLs In remote mode, the following URLs are scraped in order: 1. `https:///.well-known/security.txt` 2. `https:///security.txt` 3. `http:///.well-known/security.txt` 4. `http:///security.txt` The first HTTP 200 response whose final URL (after redirects) ends with the requested path is validated. ### Local Mode When `is_local=True`, the given path is read from disk as bytes and validated only the file contents. ``` -------------------------------- ### Parser.__init__ Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/parser.md Constructs a Parser instance with raw content bytes and optional URLs. It immediately parses and validates the content, storing results in properties. All problems are recorded as entries in errors, recommendations, or notifications rather than raised. ```APIDOC ## Parser.__init__ ### Description Constructs a Parser instance with raw content bytes and optional URLs. It immediately parses and validates the content, storing results in properties. All problems are recorded as entries in errors, recommendations, or notifications rather than raised. ### Method Constructor ### Signature ```python def __init__( self, content: bytes, urls: Optional[str] = None, recommend_unknown_fields: bool = True, is_local: bool = False ): ``` ### Parameters - `content` (bytes) - Required - Raw bytes of the security.txt file (UTF-8 expected). Decoded and parsed immediately. - `urls` (Optional[str]) - Optional - The web URI(s) where the content was located, passed through `strlist_from_arg` — a `List[str]` is also accepted at runtime. Used only for the `no_canonical_match` check: if any declared `Canonical` value does not contain any of these URLs, an error is added. Pass `None` (or omit) to skip the canonical match check. - `recommend_unknown_fields` (bool) - Optional - When `True`, non-standard fields yield a `unknown_field` notification; when `False` they are ignored. - `is_local` (bool) - Optional - Stored as `self.is_local` and used by the *subclass* `SecurityTXT` to decide scrape vs. local-file acquisition. For a bare `Parser` it has no effect on parsing. ### Return Parser instance. Construction runs the full parse pipeline synchronously (`__init__` → `_process()` → `validate_contents()`). ### Raises None. All problems are recorded as entries in `errors`/`recommendations`/`notifications` rather than raised. The sole exception: construction with a string instead of bytes fails with a `TypeError`/`AttributeError` from `codecs`/`bytes` operations (e.g. `content.replace`) — the parameter type `bytes` is not enforced. ``` -------------------------------- ### Parser.__init__ signature Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/configuration.md Constructor for the Parser class. Accepts raw security.txt content as bytes, optional URLs for canonical-match checking, a flag to recommend unknown fields, and a local flag. Defaults: recommend_unknown_fields=True, is_local=False. ```python def __init__( self, content: bytes, urls: Optional[str] = None, recommend_unknown_fields: bool = True, is_local: bool = False ): ``` -------------------------------- ### Use sectxt helper functions directly Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/command-line.md Use the helper functions directly. valid_url() checks if a URL is valid, returning True for https://example.com and False for a local path. tag_messages() tags errors and recommendations, and human_readable_print() prints them. ```python from sectxt.command_line import tag_messages, human_readable_print, valid_url from sectxt import SecurityTXT print(valid_url("https://example.com")) # True print(valid_url("/tmp/security.txt")) # False s = SecurityTXT("https://example.com") tagged = tag_messages(s.errors, "ERROR") + tag_messages(s.recommendations, "REC") human_readable_print(tagged) ``` -------------------------------- ### Validate security.txt with SecurityTXT Source: https://github.com/digitaltrustcenter/sectxt/blob/main/README.md Create a SecurityTXT instance for a domain and check if the security.txt file is valid. ```python >>> from sectxt import SecurityTXT >>> s = SecurityTXT("www.example.com") >>> s.is_valid() True ``` -------------------------------- ### SecurityTXT __init__ constructor Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/securitytxt.md Constructor for SecurityTXT. It extracts the netloc from the URL when a scheme is present and is_local is False, otherwise uses the string verbatim. Raises ValueError with message "Invalid URL" if the URL has a scheme but an empty netloc. Construction triggers the full scrape and parse pipeline synchronously. ```python def __init__(self, url: str, recommend_unknown_fields: bool = True, is_local: bool = False): url_parts = urlsplit(url) if url_parts.scheme and not is_local: if not url_parts.netloc: raise ValueError("Invalid URL") loc = url_parts.netloc else: loc = url self._loc = loc self._path: Optional[str] = None self._url: Optional[str] = None super().__init__(b'', recommend_unknown_fields=recommend_unknown_fields, is_local=is_local) ``` -------------------------------- ### Map CLI arguments to SecurityTXT constructor Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/configuration.md Maps command-line arguments to the SecurityTXT constructor. The positional address is converted to a local flag via valid_url, and the --no-recommend-unknown-fields flag inverts the recommend_unknown_fields parameter. ```python address_is_local = not valid_url(args.address) s = SecurityTXT( args.address, recommend_unknown_fields=not args.no_recommend_unknown_fields, is_local=address_is_local, ) ``` -------------------------------- ### recommendations property Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/parser.md Returns a list of non-blocking improvement suggestions, such as long_expiry or not_signed. Recommendations never affect is_valid(). ```APIDOC ## `recommendations` ### Description Returns `List[ErrorDict]` — non-blocking improvement suggestions (e.g. `long_expiry`, `not_signed`). Recommendations never affect `is_valid()`. ### Method `recommendations` (property) ### Parameters None. ### Return `List[ErrorDict]` — list of recommendation errors. ``` -------------------------------- ### Run sectxt CLI from the shell Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/command-line.md Run the sectxt CLI from the shell. The first two commands check a remote URL and a local file, respectively. The last two enable JSON output and toggle notification/recommendation flags. ```console > sectxt https://example.com > sectxt /path/to/local/security.txt > sectxt --json --show-notifications --show-recommendations https://example.com > sectxt --show-recommendations --no-recommend-unknown-fields https://example.com ``` -------------------------------- ### Programmatically invoke sectxt CLI with main() Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/command-line.md Invoke the CLI programmatically from Python. The main() function parses sys.argv and returns an exit code (0 or 1), which is then passed to sys.exit(). ```python import sys from sectxt.command_line import main # Runs argparse against sys.argv; returns 0/1 exit_code = main() sys.exit(exit_code) ``` -------------------------------- ### Handle SecurityTXT exceptions (invalid URL, missing local file) Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/securitytxt.md Handle the two exception paths for SecurityTXT: ValueError when the URL has a scheme but no host, and FileNotFoundError when a local file is missing. Also shows that an unreachable remote host does not raise an exception; instead, the error is reported through the errors property with code 'no_security_txt'. ```python from sectxt import SecurityTXT # 1. ValueError at construction time: scheme present but no host try: s = SecurityTXT("https://") except ValueError as exc: print("Invalid URL:", exc) # 2. Local mode: missing file raises (not caught by the library) try: s = SecurityTXT("/no/such/security.txt", is_local=True) except FileNotFoundError as exc: print("Local file not found:", exc) # 3. Remote mode with unreachable host: no exception; error is reported via the API s = SecurityTXT("nonexistent.invalid.tld") print(s.errors) # [{'code': 'no_security_txt', 'message': 'security.txt could not be located.', 'line': None}] ``` -------------------------------- ### Validate local security.txt file with is_local=True Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/securitytxt.md Validate a local security.txt file by passing a filesystem path and is_local=True. The snippet prints the validation result, the errors list, and the recommendations list. ```python from sectxt import SecurityTXT s = SecurityTXT("/home/example/security.txt", is_local=True) print("valid:", s.is_valid()) print("errors:", s.errors) print("recommendations:", s.recommendations) ``` -------------------------------- ### recommendations property definition Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/parser.md Returns a list of non-blocking improvement suggestions (e.g., long_expiry, not_signed). Recommendations never affect is_valid(). ```python @property def recommendations(self) -> List[ErrorDict]: ``` -------------------------------- ### Inspect errors and recommendations Source: https://github.com/digitaltrustcenter/sectxt/blob/main/README.md Inspect validation errors and recommendations for a security.txt file. The errors list contains entries with codes like 'no_uri' and 'no_expire', while recommendations may include 'long_expiry'. ```python >>> from sectxt import SecurityTXT >>> s = SecurityTXT("www.example.com") >>> s.errors [{'code': 'no_uri', 'message': 'Field policy value must be an URI', 'line': 2}, {'code': 'no_expire', 'message': 'The Expires field is missing', 'line': None}] >>> s.recommendations [{'code': 'long_expiry', 'message': 'Expiry date is more than one year in the future', 'line': 3}] ``` -------------------------------- ### strlist_from_arg helper function Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/sectxt-module.md Wraps a single string in a one-element list; lists and None are passed through unchanged. Used in Parser.__init__ to accept a List[str] for the urls parameter despite its Optional[str] annotation. ```python def strlist_from_arg(arg: Union[str, List[str], None]) -> Union[List[str], None]: if isinstance(arg, str): return [arg] return arg ``` -------------------------------- ### lines property Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/parser.md Returns one entry per parsed source line, each of type field, comment, empty, error, or pgp_envelope. ```APIDOC ## `lines` ### Description Returns `List[LineDict]` — one entry per parsed source line (in order), each of type `field`, `comment`, `empty`, `error`, or `pgp_envelope`. ### Method `lines` (property) ### Parameters None. ### Return `List[LineDict]` — list of line dictionaries. ### Example ```python from sectxt import Parser p = Parser(b"# comment\nExpires: 2030-12-31T23:59:59Z\n") for line in p.lines: print(line["type"], line["field_name"], repr(line["value"])) # comment None '# comment' # field 'expires' '2030-12-31T23:59:59Z' # empty None '' ``` ``` -------------------------------- ### human_readable_print(messages_list) Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/command-line.md Prints tagged messages in a human-readable format to stdout. If the list is empty, prints a success message. ```APIDOC ## Function: `human_readable_print` ### Description Prints tagged messages in a human-readable format to stdout. If the list is empty, prints a success message. ### Signature ```python def human_readable_print(messages_list: List[TaggedErrorDict]) -> None: ``` ### Parameters - **messages_list** (`List[TaggedErrorDict]`) - Required - Tagged messages to print. ### Return `None` (prints to stdout). Line-level entries print as `[TAG] L: : `; file-level entries (line `None`) print as `[TAG] : `. An empty list prints `✓ No issues were detected!`. ### Source `sectxt/command_line.py:31-45`. ``` -------------------------------- ### lines property definition Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/parser.md Returns a list of parsed source lines in order, each of type field, comment, empty, error, or pgp_envelope. ```python @property def lines(self) -> List[LineDict]: ``` -------------------------------- ### is_valid() Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/parser.md Returns True if the parsed security.txt content has no validation errors. Recommendations and notifications do not affect validity. ```APIDOC ## `is_valid` ### Description Returns `True` if and only if the `errors` list is empty. Recommendations and notifications do not affect validity. ### Method `is_valid()` ### Parameters None. ### Return `bool` — `True` if the `errors` list is empty, otherwise `False`. ### Example ```python from sectxt import Parser content = ( "Contact: mailto:security@example.com\n" "Expires: 2030-12-31T23:59:59Z\n" ).encode() p = Parser(content) print(p.is_valid()) # True — a well-formed minimal file if not p.is_valid(): for e in p.errors: print(e["line"], e["code"], e["message"]) ``` ``` -------------------------------- ### Extract contact channels from SecurityTXT Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/securitytxt.md Extract contact channel information from a scraped security.txt file. The snippet prints the first email, all emails, the first URL, and the first phone (tel: value) using the corresponding properties on a SecurityTXT instance. ```python from sectxt import SecurityTXT s = SecurityTXT("www.example.com") print("first email:", s.contact_email) # e.g. "security@example.com" print("all emails:", s.contact_emails) print("first URL:", s.contact_url) print("first phone (tel: value):", s.contact_tel) ``` -------------------------------- ### notifications property definition Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/parser.md Returns a list of informational findings (currently only unknown_field), gated by recommend_unknown_fields. ```python @property def notifications(self) -> List[ErrorDict]: ``` -------------------------------- ### notifications property Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/parser.md Returns a list of informational findings, currently only unknown_field, gated by recommend_unknown_fields. ```APIDOC ## `notifications` ### Description Returns `List[ErrorDict]` — informational findings (currently only `unknown_field`), gated by `recommend_unknown_fields`. ### Method `notifications` (property) ### Parameters None. ### Return `List[ErrorDict]` — list of notification errors. ### Example ```python from sectxt import Parser content = ( "Contact: https://example.com/security\n" "Expires: 2030-12-31T23:59:59Z\n" "X-Custom-Field: value\n" ).encode() p = Parser(content) print(p.errors) # [] print(p.recommendations) # [{'code': 'not_signed', 'message': 'security.txt should be digitally signed.', 'line': None}] print(p.notifications) # [{'code': 'unknown_field', 'message': 'security.txt contains an unknown field. ...', 'line': 3}] ``` ``` -------------------------------- ### Recognized RFC 9116 field sets Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/parser.md Defines the list of URI fields and the known fields (URI fields plus preferred-languages and expires). ```python uri_fields = [ "acknowledgments", "canonical", "contact", "encryption", "hiring", "policy", "csaf", ] known_fields = uri_fields + [PREFERRED_LANGUAGES, "expires"] ``` -------------------------------- ### Validate remote security.txt with SecurityTXT Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/securitytxt.md Perform remote validation of a security.txt file and inspect errors if validation fails. The snippet constructs a SecurityTXT instance with a domain, calls is_valid(), and prints a success message or iterates over the errors list, each containing 'line', 'code', and 'message' keys. ```python from sectxt import SecurityTXT s = SecurityTXT("www.example.com") if s.is_valid(): print("security.txt is valid") else: for e in s.errors: print(f"line {e['line']}: [{e['code']}] {e['message']}") ``` -------------------------------- ### errors property Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/parser.md Returns a list of validation errors, ordered by discovery. is_valid() is False iff this list is non-empty. ```APIDOC ## `errors` ### Description Returns `List[ErrorDict]` — every validation error, ordered by discovery. `is_valid()` is `False` iff this list is non-empty. All error codes are catalogued in errors.md. ### Method `errors` (property) ### Parameters None. ### Return `List[ErrorDict]` — list of validation errors. ``` -------------------------------- ### is_valid method definition Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/parser.md Returns True if the errors list is empty. Recommendations and notifications do not affect validity. ```python def is_valid(self) -> bool: return not self._errors ``` -------------------------------- ### SecurityTXT class declaration Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/securitytxt.md Defines the SecurityTXT class as a subclass of Parser. This is the main entry point of the library, inheriting all parsing, validation, error collection, and contact-extraction behavior from Parser. ```python class SecurityTXT(Parser): ``` -------------------------------- ### strlist_from_arg Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/sectxt-module.md Helper function that normalizes a string, list of strings, or None into a list of strings. It wraps a single string in a one-element list and passes through lists and None unchanged. ```APIDOC ## Function: `strlist_from_arg` ### Description Normalizes a field value that may be a single string, a list of strings, or `None` into a list of strings. A single string is wrapped in a one-element list; lists and `None` are passed through unchanged. ### Signature ```python def strlist_from_arg(arg: Union[str, List[str], None]) -> Union[List[str], None]: ``` ### Parameters - **arg** (`Union[str, List[str], None]`) - Required - A field value that may be a single string, a list of strings, or `None`. ### Return `Union[List[str], None]` - A single string wrapped in a one-element list; lists and `None` passed through unchanged. ### Behavior Note Although the `Parser.__init__` parameter `urls` is annotated `Optional[str]`, it is passed through this helper, so a `List[str]` is accepted at runtime. The helper is used once, in `Parser.__init__` (`sectxt/__init__.py:72`). ``` -------------------------------- ### Parser class definition Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/parser.md Defines the Parser class. It performs parsing and validation of security.txt content without network I/O. ```python class Parser: ``` -------------------------------- ### Inspect SecurityTXT errors in consumer code Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/errors.md Iterate over the `errors` list on a `SecurityTXT` instance to inspect blocking problems, check for a specific error code, and test validity. The `is_valid()` method returns `False` when `errors` is non-empty. ```python from sectxt import SecurityTXT s = SecurityTXT("www.example.com") for e in s.errors: # blocking problems print(e["code"], "|", e["line"], "|", e["message"]) if any(e["code"] == "no_expire" for e in s.errors): print("Expires field is missing") print(s.is_valid()) # False if errors is non-empty ``` -------------------------------- ### preferred_languages property definition Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/parser.md Returns the parsed Preferred-Languages field as a list of strings (comma-split, whitespace stripped), or None if absent. ```python @property def preferred_languages(self) -> Union[List[str], None]: ``` -------------------------------- ### preferred_languages property Source: https://github.com/digitaltrustcenter/sectxt/blob/main/_autodocs/api-reference/parser.md Returns the parsed Preferred-Languages field as a list of strings, or None if the field is absent. ```APIDOC ## `preferred_languages` ### Description Returns the parsed `Preferred-Languages` field as a `List[str]` (comma-split, whitespace stripped), or `None` if the field is absent. ### Method `preferred_languages` (property) ### Parameters None. ### Return `Union[List[str], None]` — list of language tags or `None`. ```