Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions domaintools/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,57 @@ def domain_profile(self, query, **kwargs):
"""Returns a profile for the specified domain name"""
return self._results("domain-profile", "/v1/{0}".format(query))

def domain_history(
self,
query,
include_fields=None,
exclude_fields=None,
page_size=None,
offset=None,
next=None,
parsed_whois=None,
parsed_domain_rdap=None,
**kwargs,
):
"""Returns the history of changes for a given domain name.

Results are returned in reverse chronological order. Each change event includes
a timestamp, the field that changed, and the complete before/after domain state.

Args:
query: The apex domain name to retrieve history for (e.g. "domaintools.com").
include_fields: Comma-separated list of exact field names. Only change events
matching these fields appear in results. Cannot be combined with
exclude_fields. Supports aggregate prefixes (e.g. "all_ssl", "all_ip").
Example: "ip,registrar,all_ssl"
exclude_fields: Comma-separated list of exact field names. Change events
matching these fields are omitted. Cannot be combined with include_fields.
Example: "all_web_trackers,all_ssl"
page_size: Number of change events per page. Maximum and default is 100.
offset: 0-indexed starting point for pagination. Increment by page_size for
each subsequent page.
next: When True, includes a next URL in the response for cursor-based
pagination. Auth parameters must still be included when following it.
parsed_whois: When True, includes the full parsed WHOIS record in the
before/after objects of each change event.
parsed_domain_rdap: When True, includes the full parsed Domain RDAP record
in the before/after objects of each change event.
"""
return self._results(
"domain-history",
"/v1/domain-history",
domain=query,
include_fields=include_fields,
exclude_fields=exclude_fields,
page_size=page_size,
offset=offset,
next=next,
parsed_whois=parsed_whois,
parsed_domain_rdap=parsed_domain_rdap,
items_path=("changes",),
**kwargs,
)

def domain_search(
self,
query,
Expand Down
46 changes: 46 additions & 0 deletions domaintools/cli/commands/domains.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,51 @@ def domain_profile(
DTCLICommand.run(name=c.DOMAIN_PROFILE, params=ctx.params)


@dt_cli.command(
name=c.DOMAIN_HISTORY,
help=get_cli_helptext_by_name(command_name=c.DOMAIN_HISTORY),
)
def domain_history(
ctx: typer.Context,
query: str = typer.Option(..., "-q", "--query", help="The apex domain name to retrieve history for (e.g. domaintools.com)."),
include_fields: str = typer.Option(None, "--include-fields", help="Comma-separated list of exact field names. Only change events matching these fields appear in results. Cannot be combined with --exclude-fields. Example: ip,registrar,all_ssl"),
exclude_fields: str = typer.Option(None, "--exclude-fields", help="Comma-separated list of exact field names. Change events matching these fields are omitted. Cannot be combined with --include-fields. Example: all_web_trackers,all_ssl"),
page_size: int = typer.Option(None, "--page-size", help="Number of change events per page. Maximum is 100 (default: 100)."),
offset: int = typer.Option(None, "--offset", help="0-indexed starting point for pagination. Increment by page-size for each subsequent page."),
next: bool = typer.Option(None, "--next", help="When true, includes a next URL in the response for cursor-based pagination."),
parsed_whois: bool = typer.Option(None, "--parsed-whois", help="When true, includes the full parsed WHOIS record in the before/after objects of each change event."),
parsed_domain_rdap: bool = typer.Option(None, "--parsed-domain-rdap", help="When true, includes the full parsed Domain RDAP record in the before/after objects of each change event."),
user: str = typer.Option(None, "-u", "--user", help="Domaintools API Username."),
key: str = typer.Option(None, "-k", "--key", help="DomainTools API key"),
creds_file: str = typer.Option(
"~/.dtapi",
"-c",
"--credfile",
help="Optional file with API username and API key, one per line.",
),
rate_limit: bool = typer.Option(
False,
"-l",
"--rate-limit",
help="Rate limit API calls against the API based on per minute limits.",
),
format: str = typer.Option(
"json",
"-f",
"--format",
help="Output format in {'list', 'json', 'xml', 'html'}",
callback=DTCLICommand.validate_format_input,
),
out_file: typer.FileTextWrite = typer.Option(sys.stdout, "-o", "--out-file", help="Output file (defaults to stdout)"),
no_verify_ssl: bool = typer.Option(
False,
"--no-verify-ssl",
help="Skip verification of SSL certificate when making HTTPs API calls",
),
):
DTCLICommand.run(name=c.DOMAIN_HISTORY, params=ctx.params)


@dt_cli.command(
name=c.DOMAIN_SEARCH,
help=get_cli_helptext_by_name(command_name=c.DOMAIN_SEARCH),
Expand Down Expand Up @@ -666,6 +711,7 @@ def risk_evidence(

__all__ = [
"brand_monitor",
"domain_history",
"domain_profile",
"domain_search",
"name_server_monitor",
Expand Down
1 change: 1 addition & 0 deletions domaintools/cli/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

# domains
BRAND_MONITOR = "brand_monitor"
DOMAIN_HISTORY = "domain_history"
DOMAIN_PROFILE = "domain_profile"
DOMAIN_SEARCH = "domain_search"
HOSTING_HISTORY = "hosting_history"
Expand Down
1 change: 1 addition & 0 deletions domaintools/cli/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ def _iris_investigate_helptext():
c.IRIS_INVESTIGATE: _iris_investigate_helptext(),
c.IRIS_ENRICH: "Returns back enriched data related to the specified domains using our Iris Enrich service.",
c.BRAND_MONITOR: "Pass in one or more terms as a list or separated by the pipe character ( | )",
c.DOMAIN_HISTORY: "Returns the history of changes for a given domain name.",
c.DOMAIN_PROFILE: "Returns a profile for the specified domain name",
c.DOMAIN_SEARCH: """Each term in the query string must be at least three characters long. Pass in a list or use spaces to separate multiple terms.""",
c.HOSTING_HISTORY: "Returns the hosting history from the given domain name.",
Expand Down
Loading
Loading