Skip to content

🌐 Domains

Domain management operations and types.

🚀 Quick Examples

List All Domains

from oinker import AsyncPiglet

async with AsyncPiglet() as piglet:
    # List all domains in account
    domains = await piglet.domains.list()
    for domain in domains:
        print(f"{domain.domain} - expires {domain.expire_date}")

    # Include label information
    domains = await piglet.domains.list(include_labels=True)
    for domain in domains:
        if domain.labels:
            labels = ", ".join(label.title for label in domain.labels)
            print(f"{domain.domain} [{labels}]")

Nameservers

async with AsyncPiglet() as piglet:
    # Get current nameservers
    nameservers = await piglet.domains.get_nameservers("example.com")
    print(f"Current nameservers: {nameservers}")

    # Update nameservers
    await piglet.domains.update_nameservers("example.com", [
        "ns1.example.com",
        "ns2.example.com",
    ])

URL Forwarding

from oinker import URLForwardCreate

async with AsyncPiglet() as piglet:
    # Get existing forwards
    forwards = await piglet.domains.get_url_forwards("example.com")
    for forward in forwards:
        print(f"{forward.subdomain or '@'} -> {forward.location}")

    # Add a new forward
    await piglet.domains.add_url_forward(
        "example.com",
        URLForwardCreate(
            subdomain="blog",
            location="https://blog.example.com",
            forward_type="permanent",
            include_path=True,
            wildcard=False,
        )
    )

    # Delete a forward by ID
    await piglet.domains.delete_url_forward("example.com", forward_id="12345")

Check Domain Availability

async with AsyncPiglet() as piglet:
    availability = await piglet.domains.check("coolname.com")
    if availability.available:
        print(f"Available! Price: ${availability.pricing.registration}")
    else:
        print("Domain is taken")

Glue Records

Glue records are used when you run your own nameservers on subdomains of your domain.

async with AsyncPiglet() as piglet:
    # Get existing glue records
    glue_records = await piglet.domains.get_glue_records("example.com")
    for record in glue_records:
        print(f"{record.host}: IPv4={record.ipv4}, IPv6={record.ipv6}")

    # Create a glue record for ns1.example.com
    await piglet.domains.create_glue_record(
        "example.com",
        subdomain="ns1",
        ips=["192.168.1.1", "2001:db8::1"]
    )

    # Update a glue record
    await piglet.domains.update_glue_record(
        "example.com",
        subdomain="ns1",
        ips=["192.168.1.2", "2001:db8::2"]
    )

    # Delete a glue record
    await piglet.domains.delete_glue_record("example.com", subdomain="ns1")

Operations

AsyncDomainsAPI

oinker.domains.AsyncDomainsAPI

AsyncDomainsAPI(http: HttpClient)

Async domain operations for the Porkbun API.

Accessed via piglet.domains.* methods.

Initialize Domains API.

Parameters:

Name Type Description Default
http HttpClient

The HTTP client for making requests.

required
Source code in src/oinker/domains/_api.py
def __init__(self, http: HttpClient) -> None:
    """Initialize Domains API.

    Args:
        http: The HTTP client for making requests.
    """
    self._http = http

list async

list(
    start: int = 0, include_labels: bool = False
) -> builtins.list[DomainInfo]

List all domains in the account.

Domains are returned in chunks of 1000. Increment start by 1000 until you receive an empty list to get all domains.

Parameters:

Name Type Description Default
start int

Index to start from (default 0).

0
include_labels bool

Whether to include label info (default False).

False

Returns:

Type Description
list[DomainInfo]

List of domain info objects.

Raises:

Type Description
AuthenticationError

If credentials are invalid.

APIError

If the request fails.

Source code in src/oinker/domains/_api.py
async def list(
    self,
    start: int = 0,
    include_labels: bool = False,
) -> builtins.list[DomainInfo]:
    """List all domains in the account.

    Domains are returned in chunks of 1000. Increment start by 1000 until
    you receive an empty list to get all domains.

    Args:
        start: Index to start from (default 0).
        include_labels: Whether to include label info (default False).

    Returns:
        List of domain info objects.

    Raises:
        AuthenticationError: If credentials are invalid.
        APIError: If the request fails.
    """
    body: dict[str, Any] = {"start": str(start)}
    if include_labels:
        body["includeLabels"] = "yes"

    data = await self._http.post("/domain/listAll", body)
    domains = data.get("domains", [])
    return [DomainInfo.from_api_response(d) for d in domains]

get_nameservers async

get_nameservers(domain: str) -> builtins.list[str]

Get the authoritative nameservers for a domain.

Parameters:

Name Type Description Default
domain str

The domain name (e.g., "example.com").

required

Returns:

Type Description
list[str]

List of nameserver hostnames.

Raises:

Type Description
AuthenticationError

If credentials are invalid.

NotFoundError

If domain is not found.

APIError

If the request fails.

Source code in src/oinker/domains/_api.py
async def get_nameservers(self, domain: str) -> builtins.list[str]:
    """Get the authoritative nameservers for a domain.

    Args:
        domain: The domain name (e.g., "example.com").

    Returns:
        List of nameserver hostnames.

    Raises:
        AuthenticationError: If credentials are invalid.
        NotFoundError: If domain is not found.
        APIError: If the request fails.
    """
    data = await self._http.post(f"/domain/getNs/{domain}")
    return data.get("ns", [])

update_nameservers async

update_nameservers(
    domain: str, nameservers: list[str]
) -> None

Update the nameservers for a domain.

Parameters:

Name Type Description Default
domain str

The domain name (e.g., "example.com").

required
nameservers list[str]

List of nameserver hostnames.

required

Raises:

Type Description
AuthenticationError

If credentials are invalid.

NotFoundError

If domain is not found.

APIError

If the request fails.

Source code in src/oinker/domains/_api.py
async def update_nameservers(
    self,
    domain: str,
    nameservers: builtins.list[str],
) -> None:
    """Update the nameservers for a domain.

    Args:
        domain: The domain name (e.g., "example.com").
        nameservers: List of nameserver hostnames.

    Raises:
        AuthenticationError: If credentials are invalid.
        NotFoundError: If domain is not found.
        APIError: If the request fails.
    """
    await self._http.post(f"/domain/updateNs/{domain}", {"ns": nameservers})

get_url_forwards async

get_url_forwards(domain: str) -> builtins.list[URLForward]

Get URL forwarding rules for a domain.

Parameters:

Name Type Description Default
domain str

The domain name (e.g., "example.com").

required

Returns:

Type Description
list[URLForward]

List of URL forwarding rules.

Raises:

Type Description
AuthenticationError

If credentials are invalid.

NotFoundError

If domain is not found.

APIError

If the request fails.

Source code in src/oinker/domains/_api.py
async def get_url_forwards(self, domain: str) -> builtins.list[URLForward]:
    """Get URL forwarding rules for a domain.

    Args:
        domain: The domain name (e.g., "example.com").

    Returns:
        List of URL forwarding rules.

    Raises:
        AuthenticationError: If credentials are invalid.
        NotFoundError: If domain is not found.
        APIError: If the request fails.
    """
    data = await self._http.post(f"/domain/getUrlForwarding/{domain}")
    forwards = data.get("forwards", [])
    return [URLForward.from_api_response(f) for f in forwards]

add_url_forward async

add_url_forward(
    domain: str, forward: URLForwardCreate
) -> None

Add a URL forwarding rule for a domain.

Parameters:

Name Type Description Default
domain str

The domain name (e.g., "example.com").

required
forward URLForwardCreate

The URL forward configuration.

required

Raises:

Type Description
AuthenticationError

If credentials are invalid.

NotFoundError

If domain is not found.

APIError

If the request fails.

Source code in src/oinker/domains/_api.py
async def add_url_forward(self, domain: str, forward: URLForwardCreate) -> None:
    """Add a URL forwarding rule for a domain.

    Args:
        domain: The domain name (e.g., "example.com").
        forward: The URL forward configuration.

    Raises:
        AuthenticationError: If credentials are invalid.
        NotFoundError: If domain is not found.
        APIError: If the request fails.
    """
    body: dict[str, Any] = {
        "location": forward.location,
        "type": forward.type,
        "includePath": "yes" if forward.include_path else "no",
        "wildcard": "yes" if forward.wildcard else "no",
    }
    if forward.subdomain is not None:
        body["subdomain"] = forward.subdomain
    else:
        body["subdomain"] = ""

    await self._http.post(f"/domain/addUrlForward/{domain}", body)

delete_url_forward async

delete_url_forward(domain: str, forward_id: str) -> None

Delete a URL forwarding rule.

Parameters:

Name Type Description Default
domain str

The domain name (e.g., "example.com").

required
forward_id str

The forwarding rule ID to delete.

required

Raises:

Type Description
AuthenticationError

If credentials are invalid.

NotFoundError

If domain or forward is not found.

APIError

If the request fails.

Source code in src/oinker/domains/_api.py
async def delete_url_forward(self, domain: str, forward_id: str) -> None:
    """Delete a URL forwarding rule.

    Args:
        domain: The domain name (e.g., "example.com").
        forward_id: The forwarding rule ID to delete.

    Raises:
        AuthenticationError: If credentials are invalid.
        NotFoundError: If domain or forward is not found.
        APIError: If the request fails.
    """
    await self._http.post(f"/domain/deleteUrlForward/{domain}/{forward_id}")

check async

check(domain: str) -> DomainAvailability

Check a domain's availability.

Note: Domain checks are rate limited.

Parameters:

Name Type Description Default
domain str

The domain name to check (e.g., "example.com").

required

Returns:

Type Description
DomainAvailability

Domain availability information including pricing.

Raises:

Type Description
AuthenticationError

If credentials are invalid.

RateLimitError

If rate limit exceeded.

APIError

If the request fails.

Source code in src/oinker/domains/_api.py
async def check(self, domain: str) -> DomainAvailability:
    """Check a domain's availability.

    Note: Domain checks are rate limited.

    Args:
        domain: The domain name to check (e.g., "example.com").

    Returns:
        Domain availability information including pricing.

    Raises:
        AuthenticationError: If credentials are invalid.
        RateLimitError: If rate limit exceeded.
        APIError: If the request fails.
    """
    data = await self._http.post(f"/domain/checkDomain/{domain}")
    return DomainAvailability.from_api_response(data.get("response", {}))

get_glue_records async

get_glue_records(domain: str) -> builtins.list[GlueRecord]

Get glue records for a domain.

Parameters:

Name Type Description Default
domain str

The domain name (e.g., "example.com").

required

Returns:

Type Description
list[GlueRecord]

List of glue records.

Raises:

Type Description
AuthenticationError

If credentials are invalid.

NotFoundError

If domain is not found.

APIError

If the request fails.

Source code in src/oinker/domains/_api.py
async def get_glue_records(self, domain: str) -> builtins.list[GlueRecord]:
    """Get glue records for a domain.

    Args:
        domain: The domain name (e.g., "example.com").

    Returns:
        List of glue records.

    Raises:
        AuthenticationError: If credentials are invalid.
        NotFoundError: If domain is not found.
        APIError: If the request fails.
    """
    data = await self._http.post(f"/domain/getGlue/{domain}")
    hosts = data.get("hosts", [])
    return [GlueRecord.from_api_response(tuple(h)) for h in hosts]

create_glue_record async

create_glue_record(
    domain: str, subdomain: str, ips: list[str]
) -> None

Create a glue record for a domain.

Parameters:

Name Type Description Default
domain str

The domain name (e.g., "example.com").

required
subdomain str

The glue host subdomain (e.g., "ns1").

required
ips list[str]

List of IP addresses (IPv4 and/or IPv6).

required

Raises:

Type Description
AuthenticationError

If credentials are invalid.

NotFoundError

If domain is not found.

APIError

If the request fails.

Source code in src/oinker/domains/_api.py
async def create_glue_record(
    self,
    domain: str,
    subdomain: str,
    ips: builtins.list[str],
) -> None:
    """Create a glue record for a domain.

    Args:
        domain: The domain name (e.g., "example.com").
        subdomain: The glue host subdomain (e.g., "ns1").
        ips: List of IP addresses (IPv4 and/or IPv6).

    Raises:
        AuthenticationError: If credentials are invalid.
        NotFoundError: If domain is not found.
        APIError: If the request fails.
    """
    await self._http.post(
        f"/domain/createGlue/{domain}/{subdomain}",
        {"ips": ips},
    )

update_glue_record async

update_glue_record(
    domain: str, subdomain: str, ips: list[str]
) -> None

Update a glue record for a domain.

Replaces all existing IP addresses with the new list.

Parameters:

Name Type Description Default
domain str

The domain name (e.g., "example.com").

required
subdomain str

The glue host subdomain (e.g., "ns1").

required
ips list[str]

List of IP addresses (IPv4 and/or IPv6).

required

Raises:

Type Description
AuthenticationError

If credentials are invalid.

NotFoundError

If domain or glue record is not found.

APIError

If the request fails.

Source code in src/oinker/domains/_api.py
async def update_glue_record(
    self,
    domain: str,
    subdomain: str,
    ips: builtins.list[str],
) -> None:
    """Update a glue record for a domain.

    Replaces all existing IP addresses with the new list.

    Args:
        domain: The domain name (e.g., "example.com").
        subdomain: The glue host subdomain (e.g., "ns1").
        ips: List of IP addresses (IPv4 and/or IPv6).

    Raises:
        AuthenticationError: If credentials are invalid.
        NotFoundError: If domain or glue record is not found.
        APIError: If the request fails.
    """
    await self._http.post(
        f"/domain/updateGlue/{domain}/{subdomain}",
        {"ips": ips},
    )

delete_glue_record async

delete_glue_record(domain: str, subdomain: str) -> None

Delete a glue record for a domain.

Parameters:

Name Type Description Default
domain str

The domain name (e.g., "example.com").

required
subdomain str

The glue host subdomain (e.g., "ns1").

required

Raises:

Type Description
AuthenticationError

If credentials are invalid.

NotFoundError

If domain or glue record is not found.

APIError

If the request fails.

Source code in src/oinker/domains/_api.py
async def delete_glue_record(self, domain: str, subdomain: str) -> None:
    """Delete a glue record for a domain.

    Args:
        domain: The domain name (e.g., "example.com").
        subdomain: The glue host subdomain (e.g., "ns1").

    Raises:
        AuthenticationError: If credentials are invalid.
        NotFoundError: If domain or glue record is not found.
        APIError: If the request fails.
    """
    await self._http.post(f"/domain/deleteGlue/{domain}/{subdomain}")

SyncDomainsAPI

oinker.domains.SyncDomainsAPI

SyncDomainsAPI(
    async_api: AsyncAPIType, runner: Callable[..., Any]
)

Bases: SyncAPIBase['AsyncDomainsAPI']

Synchronous domain operations for the Porkbun API.

Accessed via piglet.domains.* methods.

Source code in src/oinker/_sync_base.py
def __init__(
    self,
    async_api: AsyncAPIType,
    runner: Callable[..., Any],
) -> None:
    self._async_api = async_api
    self._run = runner

list

list(
    start: int = 0, include_labels: bool = False
) -> builtins.list[DomainInfo]

See :meth:AsyncDomainsAPI.list.

Source code in src/oinker/domains/_sync.py
def list(
    self,
    start: int = 0,
    include_labels: bool = False,
) -> builtins.list[DomainInfo]:
    """See :meth:`AsyncDomainsAPI.list`."""
    return self._run(self._async_api.list(start, include_labels))

get_nameservers

get_nameservers(domain: str) -> builtins.list[str]

See :meth:AsyncDomainsAPI.get_nameservers.

Source code in src/oinker/domains/_sync.py
def get_nameservers(self, domain: str) -> builtins.list[str]:
    """See :meth:`AsyncDomainsAPI.get_nameservers`."""
    return self._run(self._async_api.get_nameservers(domain))

update_nameservers

update_nameservers(
    domain: str, nameservers: list[str]
) -> None

See :meth:AsyncDomainsAPI.update_nameservers.

Source code in src/oinker/domains/_sync.py
def update_nameservers(
    self,
    domain: str,
    nameservers: builtins.list[str],
) -> None:
    """See :meth:`AsyncDomainsAPI.update_nameservers`."""
    self._run(self._async_api.update_nameservers(domain, nameservers))

get_url_forwards

get_url_forwards(domain: str) -> builtins.list[URLForward]

See :meth:AsyncDomainsAPI.get_url_forwards.

Source code in src/oinker/domains/_sync.py
def get_url_forwards(self, domain: str) -> builtins.list[URLForward]:
    """See :meth:`AsyncDomainsAPI.get_url_forwards`."""
    return self._run(self._async_api.get_url_forwards(domain))

add_url_forward

add_url_forward(
    domain: str, forward: URLForwardCreate
) -> None

See :meth:AsyncDomainsAPI.add_url_forward.

Source code in src/oinker/domains/_sync.py
def add_url_forward(self, domain: str, forward: URLForwardCreate) -> None:
    """See :meth:`AsyncDomainsAPI.add_url_forward`."""
    self._run(self._async_api.add_url_forward(domain, forward))

delete_url_forward

delete_url_forward(domain: str, forward_id: str) -> None

See :meth:AsyncDomainsAPI.delete_url_forward.

Source code in src/oinker/domains/_sync.py
def delete_url_forward(self, domain: str, forward_id: str) -> None:
    """See :meth:`AsyncDomainsAPI.delete_url_forward`."""
    self._run(self._async_api.delete_url_forward(domain, forward_id))

check

check(domain: str) -> DomainAvailability

See :meth:AsyncDomainsAPI.check.

Source code in src/oinker/domains/_sync.py
def check(self, domain: str) -> DomainAvailability:
    """See :meth:`AsyncDomainsAPI.check`."""
    return self._run(self._async_api.check(domain))

get_glue_records

get_glue_records(domain: str) -> builtins.list[GlueRecord]

See :meth:AsyncDomainsAPI.get_glue_records.

Source code in src/oinker/domains/_sync.py
def get_glue_records(self, domain: str) -> builtins.list[GlueRecord]:
    """See :meth:`AsyncDomainsAPI.get_glue_records`."""
    return self._run(self._async_api.get_glue_records(domain))

create_glue_record

create_glue_record(
    domain: str, subdomain: str, ips: list[str]
) -> None

See :meth:AsyncDomainsAPI.create_glue_record.

Source code in src/oinker/domains/_sync.py
def create_glue_record(
    self,
    domain: str,
    subdomain: str,
    ips: builtins.list[str],
) -> None:
    """See :meth:`AsyncDomainsAPI.create_glue_record`."""
    self._run(self._async_api.create_glue_record(domain, subdomain, ips))

update_glue_record

update_glue_record(
    domain: str, subdomain: str, ips: list[str]
) -> None

See :meth:AsyncDomainsAPI.update_glue_record.

Source code in src/oinker/domains/_sync.py
def update_glue_record(
    self,
    domain: str,
    subdomain: str,
    ips: builtins.list[str],
) -> None:
    """See :meth:`AsyncDomainsAPI.update_glue_record`."""
    self._run(self._async_api.update_glue_record(domain, subdomain, ips))

delete_glue_record

delete_glue_record(domain: str, subdomain: str) -> None

See :meth:AsyncDomainsAPI.delete_glue_record.

Source code in src/oinker/domains/_sync.py
def delete_glue_record(self, domain: str, subdomain: str) -> None:
    """See :meth:`AsyncDomainsAPI.delete_glue_record`."""
    self._run(self._async_api.delete_glue_record(domain, subdomain))

Types

DomainInfo

oinker.DomainInfo dataclass

DomainInfo(
    domain: str,
    status: str,
    tld: str,
    create_date: datetime | None,
    expire_date: datetime | None,
    security_lock: bool,
    whois_privacy: bool,
    auto_renew: bool,
    not_local: bool,
    labels: tuple[DomainLabel, ...],
)

Information about a domain in the account.

Attributes:

Name Type Description
domain str

The domain name.

status str

The domain status (e.g., "ACTIVE").

tld str

The top-level domain.

create_date datetime | None

When the domain was created.

expire_date datetime | None

When the domain expires.

security_lock bool

Whether security lock is enabled.

whois_privacy bool

Whether WHOIS privacy is enabled.

auto_renew bool

Whether auto-renew is enabled.

not_local bool

Whether the domain is not local.

labels tuple[DomainLabel, ...]

Labels attached to the domain.

from_api_response classmethod

from_api_response(data: dict[str, Any]) -> DomainInfo

Create from API response data.

Parameters:

Name Type Description Default
data dict[str, Any]

The API response dictionary.

required

Returns:

Type Description
DomainInfo

A DomainInfo instance.

Source code in src/oinker/domains/_types.py
@classmethod
def from_api_response(cls, data: dict[str, Any]) -> DomainInfo:
    """Create from API response data.

    Args:
        data: The API response dictionary.

    Returns:
        A DomainInfo instance.
    """

    def parse_date(value: str | None) -> datetime | None:
        if not value:
            return None
        try:
            return datetime.strptime(value, "%Y-%m-%d %H:%M:%S")
        except ValueError:
            return None

    labels_data = data.get("labels", [])
    labels = tuple(DomainLabel.from_api_response(lbl) for lbl in labels_data)

    return cls(
        domain=data.get("domain", ""),
        status=data.get("status", ""),
        tld=data.get("tld", ""),
        create_date=parse_date(data.get("createDate")),
        expire_date=parse_date(data.get("expireDate")),
        security_lock=data.get("securityLock") == "1" or data.get("securityLock") is True,
        whois_privacy=data.get("whoisPrivacy") == "1" or data.get("whoisPrivacy") is True,
        auto_renew=bool(data.get("autoRenew")),
        not_local=bool(data.get("notLocal")),
        labels=labels,
    )

DomainLabel

oinker.DomainLabel dataclass

DomainLabel(id: str, title: str, color: str)

A label attached to a domain.

Attributes:

Name Type Description
id str

The label ID.

title str

The label title.

color str

The label color (hex format).

from_api_response classmethod

from_api_response(data: dict[str, Any]) -> DomainLabel

Create from API response data.

Parameters:

Name Type Description Default
data dict[str, Any]

The API response dictionary.

required

Returns:

Type Description
DomainLabel

A DomainLabel instance.

Source code in src/oinker/domains/_types.py
@classmethod
def from_api_response(cls, data: dict[str, Any]) -> DomainLabel:
    """Create from API response data.

    Args:
        data: The API response dictionary.

    Returns:
        A DomainLabel instance.
    """
    return cls(
        id=str(data.get("id", "")),
        title=data.get("title", ""),
        color=data.get("color", ""),
    )

DomainAvailability

oinker.DomainAvailability dataclass

DomainAvailability(
    available: bool,
    type: str,
    price: str,
    regular_price: str,
    first_year_promo: bool,
    premium: bool,
    renewal: DomainPricing | None,
    transfer: DomainPricing | None,
)

Domain availability check result.

Attributes:

Name Type Description
available bool

Whether the domain is available for registration.

type str

The operation type (registration).

price str

The current price.

regular_price str

The regular (non-promo) price.

first_year_promo bool

Whether first year promo pricing applies.

premium bool

Whether this is a premium domain.

renewal DomainPricing | None

Renewal pricing info.

transfer DomainPricing | None

Transfer pricing info.

from_api_response classmethod

from_api_response(
    data: dict[str, Any],
) -> DomainAvailability

Create from API response data.

Parameters:

Name Type Description Default
data dict[str, Any]

The "response" dictionary from API.

required

Returns:

Type Description
DomainAvailability

A DomainAvailability instance.

Source code in src/oinker/domains/_types.py
@classmethod
def from_api_response(cls, data: dict[str, Any]) -> DomainAvailability:
    """Create from API response data.

    Args:
        data: The "response" dictionary from API.

    Returns:
        A DomainAvailability instance.
    """
    additional = data.get("additional", {})
    renewal_data = additional.get("renewal")
    transfer_data = additional.get("transfer")

    renewal = None
    if renewal_data:
        renewal = DomainPricing(
            type=renewal_data.get("type", "renewal"),
            price=renewal_data.get("price", ""),
            regular_price=renewal_data.get("regularPrice", ""),
        )

    transfer = None
    if transfer_data:
        transfer = DomainPricing(
            type=transfer_data.get("type", "transfer"),
            price=transfer_data.get("price", ""),
            regular_price=transfer_data.get("regularPrice", ""),
        )

    return cls(
        available=data.get("avail") == "yes",
        type=data.get("type", ""),
        price=data.get("price", ""),
        regular_price=data.get("regularPrice", ""),
        first_year_promo=data.get("firstYearPromo") == "yes",
        premium=data.get("premium") == "yes",
        renewal=renewal,
        transfer=transfer,
    )

DomainPricing

oinker.DomainPricing dataclass

DomainPricing(type: str, price: str, regular_price: str)

Pricing information for a domain operation.

Attributes:

Name Type Description
type str

The operation type (registration, renewal, transfer).

price str

The current price.

regular_price str

The regular (non-promo) price.

URLForward

oinker.URLForward dataclass

URLForward(
    id: str,
    subdomain: str,
    location: str,
    type: URLForwardType,
    include_path: bool,
    wildcard: bool,
)

A URL forwarding rule for a domain.

Attributes:

Name Type Description
id str

The forward rule ID.

subdomain str

The subdomain being forwarded (empty for root).

location str

The destination URL.

type URLForwardType

The redirect type ("temporary" or "permanent").

include_path bool

Whether to include the URI path in redirection.

wildcard bool

Whether to forward all subdomains.

from_api_response classmethod

from_api_response(data: dict[str, Any]) -> URLForward

Create from API response data.

Parameters:

Name Type Description Default
data dict[str, Any]

The API response dictionary.

required

Returns:

Type Description
URLForward

A URLForward instance.

Source code in src/oinker/domains/_types.py
@classmethod
def from_api_response(cls, data: dict[str, Any]) -> URLForward:
    """Create from API response data.

    Args:
        data: The API response dictionary.

    Returns:
        A URLForward instance.
    """
    forward_type = data.get("type", "temporary")
    if forward_type not in ("temporary", "permanent"):
        forward_type = "temporary"

    return cls(
        id=str(data.get("id", "")),
        subdomain=data.get("subdomain", ""),
        location=data.get("location", ""),
        type=forward_type,
        include_path=data.get("includePath") == "yes",
        wildcard=data.get("wildcard") == "yes",
    )

URLForwardCreate

oinker.URLForwardCreate dataclass

URLForwardCreate(
    location: str,
    type: URLForwardType = "temporary",
    subdomain: str | None = None,
    include_path: bool = False,
    wildcard: bool = False,
)

Parameters for creating a URL forward.

Attributes:

Name Type Description
location str

Where to forward the domain to.

type URLForwardType

The redirect type ("temporary" or "permanent").

subdomain str | None

The subdomain to forward (None for root).

include_path bool

Whether to include the URI path in redirection.

wildcard bool

Whether to forward all subdomains.

GlueRecord

oinker.GlueRecord dataclass

GlueRecord(
    hostname: str,
    ipv4: tuple[str, ...],
    ipv6: tuple[str, ...],
)

A glue record (name server with IP addresses).

Attributes:

Name Type Description
hostname str

The full hostname (e.g., "ns1.example.com").

ipv4 tuple[str, ...]

List of IPv4 addresses.

ipv6 tuple[str, ...]

List of IPv6 addresses.

from_api_response classmethod

from_api_response(
    host_data: tuple[str, dict[str, Any]],
) -> GlueRecord

Create from API response data.

The API returns glue records as a tuple of [hostname, {v4: [...], v6: [...]}].

Parameters:

Name Type Description Default
host_data tuple[str, dict[str, Any]]

The host data tuple from API response.

required

Returns:

Type Description
GlueRecord

A GlueRecord instance.

Source code in src/oinker/domains/_types.py
@classmethod
def from_api_response(cls, host_data: tuple[str, dict[str, Any]]) -> GlueRecord:
    """Create from API response data.

    The API returns glue records as a tuple of [hostname, {v4: [...], v6: [...]}].

    Args:
        host_data: The host data tuple from API response.

    Returns:
        A GlueRecord instance.
    """
    hostname, ips = host_data
    return cls(
        hostname=hostname,
        ipv4=tuple(ips.get("v4", [])),
        ipv6=tuple(ips.get("v6", [])),
    )