コード例 #1
0
ファイル: internet.py プロジェクト: bambeyy/mimesis
class Internet(BaseProvider):
    """Class for generating data related to the internet."""
    def __init__(self, *args, **kwargs):
        """Initialize attributes.

        :param args: Arguments.
        :param kwargs: Keyword arguments.
        """
        super().__init__(*args, **kwargs)
        self.__file = File(seed=self.seed)
        self._MAX_IPV4 = (2**32) - 1
        self._MAX_IPV6 = (2**128) - 1

    class Meta:
        """Class for metadata."""

        name = 'internet'

    def content_type(self, mime_type: Optional[MimeType] = None) -> str:
        """Get a random HTTP content type.

        :return: Content type.

        :Example:
            Content-Type: application/json
        """
        fmt = self.__file.mime_type(type_=mime_type)
        return 'Content-Type: {}'.format(fmt)

    def http_status_message(self) -> str:
        """Get a random HTTP status message.

        :return: HTTP status message.

        :Example:
            200 OK
        """
        return self.random.choice(HTTP_STATUS_MSGS)

    def http_status_code(self) -> int:
        """Get a random HTTP status code.

        :return: HTTP status.

        :Example:
            200
        """
        return self.random.choice(HTTP_STATUS_CODES)

    def http_method(self) -> str:
        """Get a random HTTP method.

        :return: HTTP method.

        :Example:
            POST
        """
        return self.random.choice(HTTP_METHODS)

    def ip_v4_object(self) -> IPv4Address:
        """Generate random IPv4Address object.

        See documentation for module ipaddress:
        https://docs.python.org/3.7/library/ipaddress.html

        :return: IPv4Address object.
        """
        return IPv4Address(self.random.randint(0, self._MAX_IPV4), )

    def ip_v4(self,
              with_port: bool = False,
              port_range: PortRange = PortRange.ALL) -> str:
        """Generate a random IPv4 address as string.

        :param port_range: PortRange enum object.
        :param with_port: Add port from PortRange to IP.
        :return: IPv4 address as string.

        :Example:
            19.121.223.58 or 19.121.223.58:8000
        """
        ip = str(self.ip_v4_object())

        if with_port:
            port = self.port(port_range=port_range)
            return '{}:{}'.format(ip, port)

        return ip

    def ip_v6_object(self) -> IPv6Address:
        """Generate random IPv6Address object.

        See documentation for module ipaddress:
        https://docs.python.org/3.7/library/ipaddress.html

        :return: IPv6Address object.
        """
        return IPv6Address(self.random.randint(
            0,
            self._MAX_IPV6,
        ), )

    def ip_v6(self) -> str:
        """Generate a random IPv6 address as string.

        :return: IPv6 address string.

        :Example:
            2001:c244:cf9d:1fb1:c56d:f52c:8a04:94f3
        """
        return str(self.ip_v6_object())

    def mac_address(self) -> str:
        """Generate a random MAC address.

        :return: Random MAC address.

        :Example:
            00:16:3e:25:e7:b1
        """
        mac_hex = [
            0x00,
            0x16,
            0x3e,
            self.random.randint(0x00, 0x7f),
            self.random.randint(0x00, 0xff),
            self.random.randint(0x00, 0xff),
        ]
        mac = ['{:02x}'.format(x) for x in mac_hex]
        return ':'.join(mac)

    def emoji(self) -> str:
        """Get a random emoji shortcut code.

        :return: Emoji code.

        :Example:
            :kissing:
        """
        return self.random.choice(EMOJI)

    @staticmethod
    def image_placeholder(width: Union[int, str] = 1920,
                          height: Union[int, str] = 1080) -> str:
        """Generate a link to the image placeholder.

        :param width: Width of image.
        :param height: Height of image.
        :return: URL to image placeholder.
        """
        url = 'http://placehold.it/{width}x{height}'
        return url.format(width=width, height=height)

    @staticmethod
    def stock_image(width: Union[int, str] = 1920,
                    height: Union[int, str] = 1080,
                    keywords: Optional[KeywordsType] = None,
                    writable: bool = False) -> Union[str, bytes]:
        """Generate random stock image (JPG/JPEG) hosted on Unsplash.

        See «Random search term» on https://source.unsplash.com/
        for more details.

        .. note:: This method required an active HTTP connection
            if you want to get writable object

        :param width: Width of the image.
        :param height: Height of the image.
        :param keywords: List of search keywords.
        :param writable: Return image as sequence ob bytes.
        :return: Link to the image.
        """
        api_url = 'https://source.unsplash.com/{}x{}?{}'

        if keywords is not None:
            keywords_str = ','.join(keywords)
        else:
            keywords_str = ''

        url = api_url.format(width, height, keywords_str)

        if writable:
            try:
                response = urllib.request.urlopen(url)
                return response.read()
            except urllib.error.URLError:
                raise urllib.error.URLError(
                    'Required an active HTTP connection')
        return url

    def hashtags(self, quantity: int = 4) -> Union[str, list]:
        """Generate a list of hashtags.

        :param quantity: The quantity of hashtags.
        :return: The list of hashtags.
        :raises NonEnumerableError: if category is not in Hashtag.

        :Example:
            ['#love', '#sky', '#nice']
        """
        tags = ['#' + self.random.choice(HASHTAGS) for _ in range(quantity)]

        if int(quantity) == 1:
            return tags[0]

        return tags

    def home_page(self, tld_type: Optional[TLDType] = None) -> str:
        """Generate a random home page.

        :param tld_type: TLD type.
        :return: Random home page.

        :Example:
            https://fontir.info
        """
        resource = self.random.choice(USERNAMES)
        domain = self.top_level_domain(tld_type=tld_type, )

        return 'https://{}{}'.format(resource, domain)

    def top_level_domain(self, tld_type: Optional[TLDType] = None) -> str:
        """Return random top level domain.

        :param tld_type: Enum object DomainType
        :return: Top level domain.
        :raises NonEnumerableError: if tld_type not in DomainType.
        """
        key = self._validate_enum(item=tld_type, enum=TLDType)
        return self.random.choice(TLD[key])

    def user_agent(self) -> str:
        """Get a random user agent.

        :return: User agent.

        :Example:
            Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:15.0)
            Gecko/20100101 Firefox/15.0.1
        """
        return self.random.choice(USER_AGENTS)

    def network_protocol(self, layer: Optional[Layer] = None) -> str:
        """Get a random network protocol form OSI model.

        :param layer: Enum object Layer.
        :return: Protocol name.

        :Example:
            AMQP
        """
        key = self._validate_enum(item=layer, enum=Layer)
        protocols = NETWORK_PROTOCOLS[key]
        return self.random.choice(protocols)

    def port(self, port_range: PortRange = PortRange.ALL) -> int:
        """Generate random port.

        :param port_range: PortRange enum object.
        :return: Port number.
        :raises NonEnumerableError: if port_range is not in PortRange.

        :Example:
            8080
        """
        if isinstance(port_range, PortRange):
            return self.random.randint(*port_range.value)

        raise NonEnumerableError(PortRange)
コード例 #2
0
class Internet(BaseProvider):
    """Class for generating data related to the internet."""

    _MAX_IPV4: t.Final[int] = (2**32) - 1
    _MAX_IPV6: t.Final[int] = (2**128) - 1

    def __init__(self, *args: t.Any, **kwargs: t.Any) -> None:
        """Initialize attributes.

        :param args: Arguments.
        :param kwargs: Keyword arguments.
        """
        super().__init__(*args, **kwargs)
        self._file = File(seed=self.seed)
        self._text = Text(locale=Locale.EN, seed=self.seed)
        self._datetime = Datetime(locale=Locale.EN)

    class Meta:
        """Class for metadata."""

        name: t.Final[str] = "internet"

    def content_type(self, mime_type: t.Optional[MimeType] = None) -> str:
        """Get a random HTTP content type.

        :return: Content type.

        :Example:
            Content-Type: application/json
        """
        fmt = self._file.mime_type(type_=mime_type)
        return f"Content-Type: {fmt}"

    def http_status_message(self) -> str:
        """Get a random HTTP status message.

        :return: HTTP status message.

        :Example:
            200 OK
        """
        return self.random.choice(HTTP_STATUS_MSGS)

    def http_status_code(self) -> int:
        """Get a random HTTP status code.

        :return: HTTP status.

        :Example:
            200
        """
        return self.random.choice(HTTP_STATUS_CODES)

    def http_method(self) -> str:
        """Get a random HTTP method.

        :return: HTTP method.

        :Example:
            POST
        """
        return self.random.choice(HTTP_METHODS)

    def ip_v4_object(self) -> IPv4Address:
        """Generate random :py:class:`ipaddress.IPv4Address` object.

        :return: :py:class:`ipaddress.IPv4Address` object.
        """
        return IPv4Address(self.random.randint(0, self._MAX_IPV4), )

    def ip_v4_with_port(self, port_range: PortRange = PortRange.ALL) -> str:
        """Generate a random IPv4 address as string.

        :param port_range: PortRange enum object.
        :return: IPv4 address as string.

        :Example:
            19.121.223.58:8000
        """
        addr = self.ip_v4()
        port = self.port(port_range)
        return f"{addr}:{port}"

    def ip_v4(self) -> str:
        """Generate a random IPv4 address as string.

        :Example:
            19.121.223.58
        """
        return str(self.ip_v4_object())

    def ip_v6_object(self) -> IPv6Address:
        """Generate random :py:class:`ipaddress.IPv6Address` object.

        :return: :py:class:`ipaddress.IPv6Address` object.
        """
        return IPv6Address(self.random.randint(
            0,
            self._MAX_IPV6,
        ), )

    def ip_v6(self) -> str:
        """Generate a random IPv6 address as string.

        :return: IPv6 address string.

        :Example:
            2001:c244:cf9d:1fb1:c56d:f52c:8a04:94f3
        """
        return str(self.ip_v6_object())

    def mac_address(self) -> str:
        """Generate a random MAC address.

        :return: Random MAC address.

        :Example:
            00:16:3e:25:e7:f1
        """
        mac_hex = [
            0x00,
            0x16,
            0x3E,
            self.random.randint(0x00, 0x7F),
            self.random.randint(0x00, 0xFF),
            self.random.randint(0x00, 0xFF),
        ]
        mac = [f"{x:02x}" for x in mac_hex]
        return ":".join(mac)

    def emoji(self) -> str:
        """Get a random emoji shortcut code.

        :return: Emoji code.

        :Example:
            :kissing:
        """
        return self.random.choice(EMOJI)

    @staticmethod
    def stock_image(
        width: t.Union[int, str] = 1920,
        height: t.Union[int, str] = 1080,
        keywords: t.Optional[Keywords] = None,
        writable: bool = False,
    ) -> t.Union[str, bytes]:
        """Generate random stock image (JPG/JPEG) hosted on Unsplash.

        See «Random search term» on https://source.unsplash.com/
        for more details.

        .. note:: This method required an active HTTP connection
            if you want to get a writable object.

        :param width: Width of the image.
        :param height: Height of the image.
        :param keywords: List of search keywords.
        :param writable: Return image as sequence ob bytes.
        :return: Link to the image.
        """
        if keywords is not None:
            keywords_str = ",".join(keywords)
        else:
            keywords_str = ""

        url = f"https://source.unsplash.com/{width}x{height}?{keywords_str}"

        if writable:
            try:
                response = urllib.request.urlopen(url)
                content: bytes = response.read()
                return content
            except urllib.error.URLError:
                raise urllib.error.URLError(
                    "Required an active HTTP connection")
        return url

    def hashtags(self, quantity: int = 4) -> t.List[str]:
        """Generate a list of hashtags.

        :param quantity: The quantity of hashtags.
        :return: The list of hashtags.
        :raises NonEnumerableError: if category is not in Hashtag.

        :Example:
            ['#love', '#sky', '#nice']
        """

        if quantity < 1:
            raise ValueError("Quantity must be a positive integer.")

        return ["#" + self._text.word() for _ in range(quantity)]

    def hostname(
        self,
        tld_type: t.Optional[TLDType] = None,
        subdomains: t.Optional[t.List[str]] = None,
    ) -> str:
        """Generate a random hostname without scheme.

        :param tld_type: TLDType.
        :param subdomains: List of subdomains (make sure they are valid).
        :return: Hostname.
        """
        tld = self.tld(tld_type=tld_type)
        host = self.random.choice(USERNAMES)

        if subdomains:
            subdomain = self.random.choice(subdomains)
            host = f"{subdomain}.{host}"

        return f"{host}{tld}"

    def url(
        self,
        scheme: t.Optional[URLScheme] = URLScheme.HTTPS,
        port_range: t.Optional[PortRange] = None,
        tld_type: t.Optional[TLDType] = None,
        subdomains: t.Optional[t.List[str]] = None,
    ) -> str:
        """Generate random URL.

        :param scheme: Scheme.
        :param port_range: PortRange enum object.
        :param tld_type: TLDType.
        :param subdomains: List of subdomains (make sure they are valid).
        :return: URL.
        """
        host = self.hostname(tld_type, subdomains)
        url_scheme = self.validate_enum(scheme, URLScheme)

        url = f"{url_scheme}://{host}"

        if port_range is not None:
            url = f"{url}:{self.port(port_range)}"

        return f"{url}/"

    def uri(
        self,
        scheme: t.Optional[URLScheme] = URLScheme.HTTPS,
        port_range: t.Optional[PortRange] = None,
        tld_type: t.Optional[TLDType] = None,
        subdomains: t.Optional[t.List[str]] = None,
        query_params_count: t.Optional[int] = None,
    ) -> str:
        """Generate a random URI.

        :param scheme: Scheme.
        :param port_range: PortRange enum object.
        :param tld_type: TLDType.
        :param subdomains: List of subdomains (make sure they are valid).
        :param query_params_count: Query params.
        :return: URI.
        """
        directory = (self._datetime.date(
            start=2010,
            end=self._datetime.CURRENT_YEAR).strftime("%Y-%m-%d").replace(
                "-", "/"))
        url = self.url(scheme, port_range, tld_type, subdomains)
        uri = f"{url}{directory}/{self.slug()}"

        if query_params_count:
            uri += self.query_string(query_params_count)

        return uri

    def query_string(self, length: t.Optional[int] = None) -> str:
        """Generate arbitrary query string of given length.

        :param length: Length of query string.
        :return: Query string.
        """
        return urllib.parse.urlencode(self.query_parameters(length))

    def query_parameters(self,
                         length: t.Optional[int] = None) -> t.Dict[str, str]:
        """Generate arbitrary query parameters as a dict.

        :param length: Length of query parameters dictionary (maximum is 32).
        :return: Dict of query parameters.
        """
        def pick_unique_words(quantity: int = 5) -> t.List[str]:
            words: t.Set[str] = set()

            while len(words) != quantity:
                words.add(self._text.word())

            return list(words)

        if not length:
            length = self.random.randint(1, 10)

        if length > 32:
            raise ValueError(
                "Maximum allowed length of query parameters is 32.")

        return dict(zip(pick_unique_words(length), self._text.words(length)))

    def top_level_domain(self, tld_type: t.Optional[TLDType] = None) -> str:
        """Generates random top level domain.

        :param tld_type: Enum object :class:`enums.TLDType`
        :return: Top level domain.
        :raises NonEnumerableError: if tld_type not in :class:`enums.TLDType`.
        """
        key = self.validate_enum(item=tld_type, enum=TLDType)
        return self.random.choice(TLD[key])

    def tld(self, *args: t.Any, **kwargs: t.Any) -> str:
        """Generates random top level domain.

        An alias for :meth:`top_level_domain`
        """
        return self.top_level_domain(*args, **kwargs)

    def user_agent(self) -> str:
        """Get a random user agent.

        :return: User agent.

        :Example:
            Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:15.0)
            Gecko/20100101 Firefox/15.0.1
        """
        return self.random.choice(USER_AGENTS)

    def port(self, port_range: PortRange = PortRange.ALL) -> int:
        """Generate random port.

        :param port_range: PortRange enum object.
        :return: Port number.
        :raises NonEnumerableError: if port_range is not in PortRange.

        :Example:
            8080
        """

        rng = self.validate_enum(port_range, PortRange)
        return self.random.randint(*rng)

    def slug(self, parts_count: t.Optional[int] = None) -> str:
        """Generate a random slug of given parts count.

        :param parts_count: Slug's parts count.
        :return: Slug.
        """

        if not parts_count:
            parts_count = self.random.randint(2, 12)

        if parts_count > 12:
            raise ValueError("Slug's parts count must be <= 12")

        if parts_count < 2:
            raise ValueError("Slug must contain more than 2 parts")

        return "-".join(self._text.words(parts_count))
コード例 #3
0
class Internet(BaseDataProvider):
    """Class for generating data related to the internet."""

    def __init__(self, *args, **kwargs):
        """Initialize attributes.

        :param args: Arguments.
        :param kwargs: Keyword arguments.
        """
        super().__init__(*args, **kwargs)
        self.__file = File('en', seed=self.seed)

    def content_type(self, mime_type: Optional[MimeType] = None) -> str:
        """Get a random HTTP content type.

        :return: Content type.

        :Example:
            Content-Type: application/json
        """
        fmt = self.__file.mime_type(type_=mime_type)
        return 'Content-Type: {}'.format(fmt)

    def http_status_message(self) -> str:
        """Get a random HTTP status message.

        :return: HTTP status message.

        :Example:
            200 OK
        """
        return self.random.choice(HTTP_STATUS_MSGS)

    def http_status_code(self) -> int:
        """Get a random HTTP status code.

        :return: HTTP status.

        :Example:
            200
        """
        return self.random.choice(HTTP_STATUS_CODES)

    def http_method(self) -> str:
        """Get a random HTTP method.

        :return: HTTP method.

        :Example:
            POST
        """
        return self.random.choice(HTTP_METHODS)

    def ip_v4(self, with_port: bool = False) -> str:
        """Generate a random IPv4 address.

        :param with_port: Add port to IP.
        :return: Random IPv4 address.

        :Example:
            19.121.223.58
        """
        ip = '.'.join(str(self.random.randint(0, 255)) for _ in range(4))

        if with_port:
            ip += ':{}'.format(self.port())

        return ip

    def ip_v6(self) -> str:
        """Generate a random IPv6 address.

        :return: Random IPv6 address.

        :Example:
            2001:c244:cf9d:1fb1:c56d:f52c:8a04:94f3
        """
        ipv6 = IPv6Address(
            self.random.randint(
                0, 2 ** 128 - 1,
            ),
        )
        return str(ipv6)

    def mac_address(self) -> str:
        """Generate a random MAC address.

        :return: Random MAC address.

        :Example:
            00:16:3e:25:e7:b1
        """
        mac_hex = [
            0x00, 0x16, 0x3e,
            self.random.randint(0x00, 0x7f),
            self.random.randint(0x00, 0xff),
            self.random.randint(0x00, 0xff),
        ]
        mac = map(lambda x: '%02x' % x, mac_hex)
        return ':'.join(mac)

    def emoji(self) -> str:
        """Get a random emoji shortcut code.

        :return: Emoji code.

        :Example:
            :kissing:
        """
        return self.random.choice(EMOJI)

    def image_placeholder(self, width: Optional[Size] = None,
                          height: Optional[Size] = None) -> str:
        """Generate a link to the image placeholder.

        :param width: Width of image.
        :type width: str or int
        :param height: Height of image.
        :type height: str or int
        :return: URL to image placeholder.
        """
        url = 'http://placehold.it/{width}x{height}'
        if not width:
            width = self.random.randint(16, 1024)

        if not height:
            height = self.random.randint(16, int(width))

        return url.format(width=width, height=height)

    def stock_image(self, category: str = '',
                    width: Size = 1900, height: Size = 1080) -> str:
        """Generate random stock image hosted on Unsplash.

        :param category: Category of images.
        :param width: Width of the image.
        :type width: str or int
        :param height: Height of the image.
        :type height: str or int
        :return: An image (Link to image).
        """
        url = 'https://source.unsplash.com/category/' \
              '{category}/{width}x{height}'

        if not category:
            categories = [
                'buildings', 'food', 'nature',
                'people', 'technology', 'objects',
            ]
            category = self.random.choice(categories)

        return url.format(category=category, width=width, height=height)

    def image_by_keyword(self, keyword: str = '') -> str:
        """Generate image by keyword.

        :param keyword: Keyword.
        :return: Link to image.
        """
        url = 'https://source.unsplash.com/weekly?{keyword}'

        if not keyword:
            keywords = [
                'cat', 'girl', 'boy', 'beauty',
                'nature', 'woman', 'man', 'tech',
                'space',
            ]
            keyword = self.random.choice(keywords)

        return url.format(keyword=keyword)

    def hashtags(self, quantity: int = 4) -> Union[str, list]:
        """Generate a list of hashtags.

        :param quantity: The quantity of hashtags.
        :return: The list of hashtags.
        :rtype: str or list
        :raises NonEnumerableError: if category is not in Hashtag.

        :Example:
            ['#love', '#sky', '#nice']
        """
        tags = ['#' + self.random.choice(HASHTAGS)
                for _ in range(quantity)]

        if int(quantity) == 1:
            return tags[0]

        return tags

    def home_page(self, tld_type: Optional[TLDType] = None) -> str:
        """Generate a random home page.

        :param tld_type: TLD type.
        :return: Random home page.

        :Example:
            http://www.fontir.info
        """
        resource = self.random.choice(USERNAMES)
        domain = self.top_level_domain(
            tld_type=tld_type,
        )

        return 'http://www.{}{}'.format(
            resource, domain)

    def top_level_domain(self, tld_type: Optional[TLDType] = None) -> str:
        """Return random top level domain.

        :param tld_type: Enum object DomainType
        :return: Top level domain.
        :raises NonEnumerableError: if tld_type not in DomainType.
        """
        key = self._validate_enum(item=tld_type, enum=TLDType)
        return self.random.choice(TLD[key])

    def subreddit(self, nsfw: bool = False,
                  full_url: bool = False) -> str:
        """Get a random subreddit from the list.

        :param nsfw: NSFW subreddit.
        :param full_url: Full URL address.
        :return: Subreddit or URL to subreddit.

        :Example:
            https://www.reddit.com/r/flask/
        """
        url = 'http://www.reddit.com'
        if not nsfw:
            if not full_url:
                return self.random.choice(SUBREDDITS)
            else:
                return url + self.random.choice(SUBREDDITS)

        nsfw_sr = self.random.choice(SUBREDDITS_NSFW)
        result = url + nsfw_sr if full_url else nsfw_sr
        return result

    def user_agent(self) -> str:
        """Get a random user agent.

        :return: User agent.

        :Example:
            Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:15.0)
            Gecko/20100101 Firefox/15.0.1
        """
        return self.random.choice(USER_AGENTS)

    def network_protocol(self, layer: Optional[Layer] = None) -> str:
        """Get a random network protocol form OSI model.

        :param layer: Enum object Layer.
        :return: Protocol name.

        :Example:
            AMQP
        """
        key = self._validate_enum(item=layer, enum=Layer)
        protocols = NETWORK_PROTOCOLS[key]
        return self.random.choice(protocols)

    def port(self, port_range: PortRange = PortRange.ALL) -> int:
        """Generate random port.

        :param port_range: Range enum object.
        :return: Port number.
        :raises NonEnumerableError: if port_range is not in PortRange.

        :Example:
            8080
        """
        if port_range and port_range in PortRange:
            return self.random.randint(*port_range.value)
        else:
            raise NonEnumerableError(PortRange)

    def category_of_website(self):
        """Get random category of torrent portal.

        :return: Category name.

        :Example:
            Video/TV shows
        """
        return self.random.choice(TORRENT_CATEGORIES)
コード例 #4
0
class Internet(BaseDataProvider):
    """Class for generating data related to the internet."""
    def __init__(self, *args, **kwargs):
        """Initialize attributes.

        :param args: Arguments.
        :param kwargs: Keyword arguments.
        """
        super().__init__(*args, **kwargs)
        self.__file = File('en', seed=self.seed)

    def content_type(self, mime_type: Optional[MimeType] = None) -> str:
        """Get a random HTTP content type.

        :return: Content type.

        :Example:
            Content-Type: application/json
        """
        fmt = self.__file.mime_type(type_=mime_type)
        return 'Content-Type: {}'.format(fmt)

    def http_status_message(self) -> str:
        """Get a random HTTP status message.

        :return: HTTP status message.

        :Example:
            200 OK
        """
        return self.random.choice(HTTP_STATUS_MSGS)

    def http_status_code(self) -> int:
        """Get a random HTTP status code.

        :return: HTTP status.

        :Example:
            200
        """
        return self.random.choice(HTTP_STATUS_CODES)

    def http_method(self) -> str:
        """Get a random HTTP method.

        :return: HTTP method.

        :Example:
            POST
        """
        return self.random.choice(HTTP_METHODS)

    def ip_v4(self, with_port: bool = False) -> str:
        """Generate a random IPv4 address.

        :param with_port: Add port to IP.
        :return: Random IPv4 address.

        :Example:
            19.121.223.58
        """
        ip = '.'.join(str(self.random.randint(0, 255)) for _ in range(4))

        if with_port:
            ip += ':{}'.format(self.port())

        return ip

    def ip_v6(self) -> str:
        """Generate a random IPv6 address.

        :return: Random IPv6 address.

        :Example:
            2001:c244:cf9d:1fb1:c56d:f52c:8a04:94f3
        """
        ipv6 = IPv6Address(self.random.randint(
            0,
            2**128 - 1,
        ), )
        return str(ipv6)

    def mac_address(self) -> str:
        """Generate a random MAC address.

        :return: Random MAC address.

        :Example:
            00:16:3e:25:e7:b1
        """
        mac_hex = [
            0x00,
            0x16,
            0x3e,
            self.random.randint(0x00, 0x7f),
            self.random.randint(0x00, 0xff),
            self.random.randint(0x00, 0xff),
        ]
        mac = map(lambda x: '%02x' % x, mac_hex)
        return ':'.join(mac)

    def emoji(self) -> str:
        """Get a random emoji shortcut code.

        :return: Emoji code.

        :Example:
            :kissing:
        """
        return self.random.choice(EMOJI)

    @staticmethod
    def image_placeholder(width: Union[int, str] = 1920,
                          height: Union[int, str] = 1080) -> str:
        """Generate a link to the image placeholder.

        :param width: Width of image.
        :param height: Height of image.
        :return: URL to image placeholder.
        """
        url = 'http://placehold.it/{width}x{height}'
        return url.format(width=width, height=height)

    @staticmethod
    def stock_image(width: Union[int, str] = 1920,
                    height: Union[int, str] = 1080,
                    keywords: Optional[List[str]] = None,
                    writable: bool = False) -> Union[str, bytes]:
        """Generate random stock image (JPEG) hosted on Unsplash.

        .. note:: This method required an active HTTP connection.

        :param width: Width of the image.
        :param height: Height of the image.
        :param keywords: List of search keywords.
        :param writable: Return image as sequence ob bytes.
        :return: Link to the image.
        """
        api = 'https://source.unsplash.com/{}x{}?{}'

        if keywords is not None:
            keywords_str = ','.join(keywords)
        else:
            keywords_str = ''

        url = api.format(width, height, keywords_str)

        try:
            response = urllib.request.urlopen(url)
            if writable:
                return response.read()
            url = response.geturl()
            return url
        except urllib.error.URLError:
            raise urllib.error.URLError('Required an active HTTP connection')

    def hashtags(self, quantity: int = 4) -> Union[str, list]:
        """Generate a list of hashtags.

        :param quantity: The quantity of hashtags.
        :return: The list of hashtags.
        :raises NonEnumerableError: if category is not in Hashtag.

        :Example:
            ['#love', '#sky', '#nice']
        """
        tags = ['#' + self.random.choice(HASHTAGS) for _ in range(quantity)]

        if int(quantity) == 1:
            return tags[0]

        return tags

    def home_page(self, tld_type: Optional[TLDType] = None) -> str:
        """Generate a random home page.

        :param tld_type: TLD type.
        :return: Random home page.

        :Example:
            http://www.fontir.info
        """
        resource = self.random.choice(USERNAMES)
        domain = self.top_level_domain(tld_type=tld_type, )

        return 'http://www.{}{}'.format(resource, domain)

    def top_level_domain(self, tld_type: Optional[TLDType] = None) -> str:
        """Return random top level domain.

        :param tld_type: Enum object DomainType
        :return: Top level domain.
        :raises NonEnumerableError: if tld_type not in DomainType.
        """
        key = self._validate_enum(item=tld_type, enum=TLDType)
        return self.random.choice(TLD[key])

    def subreddit(self, nsfw: bool = False, full_url: bool = False) -> str:
        """Get a random subreddit from the list.

        :param nsfw: NSFW subreddit.
        :param full_url: Full URL address.
        :return: Subreddit or URL to subreddit.

        :Example:
            https://www.reddit.com/r/flask/
        """
        url = 'http://www.reddit.com'
        if not nsfw:
            if not full_url:
                return self.random.choice(SUBREDDITS)
            else:
                return url + self.random.choice(SUBREDDITS)

        nsfw_sr = self.random.choice(SUBREDDITS_NSFW)
        result = url + nsfw_sr if full_url else nsfw_sr
        return result

    def user_agent(self) -> str:
        """Get a random user agent.

        :return: User agent.

        :Example:
            Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:15.0)
            Gecko/20100101 Firefox/15.0.1
        """
        return self.random.choice(USER_AGENTS)

    def network_protocol(self, layer: Optional[Layer] = None) -> str:
        """Get a random network protocol form OSI model.

        :param layer: Enum object Layer.
        :return: Protocol name.

        :Example:
            AMQP
        """
        key = self._validate_enum(item=layer, enum=Layer)
        protocols = NETWORK_PROTOCOLS[key]
        return self.random.choice(protocols)

    def port(self, port_range: PortRange = PortRange.ALL) -> int:
        """Generate random port.

        :param port_range: Range enum object.
        :return: Port number.
        :raises NonEnumerableError: if port_range is not in PortRange.

        :Example:
            8080
        """
        if port_range and port_range in PortRange:
            return self.random.randint(*port_range.value)
        else:
            raise NonEnumerableError(PortRange)

    def category_of_website(self):
        """Get random category of torrent portal.

        :return: Category name.

        :Example:
            Video/TV shows
        """
        return self.random.choice(TORRENT_CATEGORIES)