We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Improve IPv4/IPv6 generators for Internet()
We can improve how `.ip_v4()` and `.ip_v6()` works.

I suggest using `ipaddress` module from the standard library, just like this:

```python
    def ip_v4(self, with_port: bool = False, stringify: bool = True) -> Union[str, IPv4Address]:
        """Generate a random IPv4 address.

        :param stringify:  Return IPv4 as string (True by default).
        :param with_port: Add port to IP.
        :return: Random IPv4 address.

        :Example:
            19.121.223.58
        """
        ipv4 = IPv4Address(self.random.getrandbits(32))

        if not stringify:
            return ipv4

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

        return ipv4
```

The idea is to support IP addresses as objects to make them more useful than just strings.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `mimesis/providers/internet.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 
3 """Provides data related to internet."""
4 
5 import urllib.error
6 import urllib.request
7 from ipaddress import IPv6Address
8 from typing import List, Optional, Union
9 
10 from mimesis.data import (
11     EMOJI,
12     HASHTAGS,
13     HTTP_METHODS,
14     HTTP_STATUS_CODES,
15     HTTP_STATUS_MSGS,
16     NETWORK_PROTOCOLS,
17     TLD,
18     USER_AGENTS,
19     USERNAMES,
20 )
21 from mimesis.enums import Layer, MimeType, PortRange, TLDType
22 from mimesis.exceptions import NonEnumerableError
23 from mimesis.providers.base import BaseProvider
24 from mimesis.providers.file import File
25 
26 __all__ = ['Internet']
27 
28 
29 class Internet(BaseProvider):
30     """Class for generating data related to the internet."""
31 
32     def __init__(self, *args, **kwargs):
33         """Initialize attributes.
34 
35         :param args: Arguments.
36         :param kwargs: Keyword arguments.
37         """
38         super().__init__(*args, **kwargs)
39         self.__file = File(seed=self.seed)
40 
41     class Meta:
42         """Class for metadata."""
43 
44         name = 'internet'
45 
46     def content_type(self, mime_type: Optional[MimeType] = None) -> str:
47         """Get a random HTTP content type.
48 
49         :return: Content type.
50 
51         :Example:
52             Content-Type: application/json
53         """
54         fmt = self.__file.mime_type(type_=mime_type)
55         return 'Content-Type: {}'.format(fmt)
56 
57     def http_status_message(self) -> str:
58         """Get a random HTTP status message.
59 
60         :return: HTTP status message.
61 
62         :Example:
63             200 OK
64         """
65         return self.random.choice(HTTP_STATUS_MSGS)
66 
67     def http_status_code(self) -> int:
68         """Get a random HTTP status code.
69 
70         :return: HTTP status.
71 
72         :Example:
73             200
74         """
75         return self.random.choice(HTTP_STATUS_CODES)
76 
77     def http_method(self) -> str:
78         """Get a random HTTP method.
79 
80         :return: HTTP method.
81 
82         :Example:
83             POST
84         """
85         return self.random.choice(HTTP_METHODS)
86 
87     def ip_v4(self, with_port: bool = False) -> str:
88         """Generate a random IPv4 address.
89 
90         :param with_port: Add port to IP.
91         :return: Random IPv4 address.
92 
93         :Example:
94             19.121.223.58
95         """
96         ip = '.'.join(str(self.random.randint(0, 255)) for _ in range(4))
97 
98         if with_port:
99             ip += ':{}'.format(self.port())
100 
101         return ip
102 
103     def ip_v6(self) -> str:
104         """Generate a random IPv6 address.
105 
106         :return: Random IPv6 address.
107 
108         :Example:
109             2001:c244:cf9d:1fb1:c56d:f52c:8a04:94f3
110         """
111         ipv6 = IPv6Address(
112             self.random.randint(
113                 0, 2 ** 128 - 1,
114             ),
115         )
116         return str(ipv6)
117 
118     def mac_address(self) -> str:
119         """Generate a random MAC address.
120 
121         :return: Random MAC address.
122 
123         :Example:
124             00:16:3e:25:e7:b1
125         """
126         mac_hex = [
127             0x00, 0x16, 0x3e,
128             self.random.randint(0x00, 0x7f),
129             self.random.randint(0x00, 0xff),
130             self.random.randint(0x00, 0xff),
131         ]
132         mac = map(lambda x: '%02x' % x, mac_hex)
133         return ':'.join(mac)
134 
135     def emoji(self) -> str:
136         """Get a random emoji shortcut code.
137 
138         :return: Emoji code.
139 
140         :Example:
141             :kissing:
142         """
143         return self.random.choice(EMOJI)
144 
145     @staticmethod
146     def image_placeholder(width: Union[int, str] = 1920,
147                           height: Union[int, str] = 1080) -> str:
148         """Generate a link to the image placeholder.
149 
150         :param width: Width of image.
151         :param height: Height of image.
152         :return: URL to image placeholder.
153         """
154         url = 'http://placehold.it/{width}x{height}'
155         return url.format(width=width, height=height)
156 
157     @staticmethod
158     def stock_image(width: Union[int, str] = 1920,
159                     height: Union[int, str] = 1080,
160                     keywords: Optional[List[str]] = None,
161                     writable: bool = False) -> Union[str, bytes]:
162         """Generate random stock image (JPEG) hosted on Unsplash.
163 
164         .. note:: This method required an active HTTP connection.
165 
166         :param width: Width of the image.
167         :param height: Height of the image.
168         :param keywords: List of search keywords.
169         :param writable: Return image as sequence ob bytes.
170         :return: Link to the image.
171         """
172         api = 'https://source.unsplash.com/{}x{}?{}'
173 
174         if keywords is not None:
175             keywords_str = ','.join(keywords)
176         else:
177             keywords_str = ''
178 
179         url = api.format(width, height, keywords_str)
180 
181         try:
182             response = urllib.request.urlopen(url)
183             if writable:
184                 return response.read()
185             url = response.geturl()
186             return url
187         except urllib.error.URLError:
188             raise urllib.error.URLError(
189                 'Required an active HTTP connection')
190 
191     def hashtags(self, quantity: int = 4) -> Union[str, list]:
192         """Generate a list of hashtags.
193 
194         :param quantity: The quantity of hashtags.
195         :return: The list of hashtags.
196         :raises NonEnumerableError: if category is not in Hashtag.
197 
198         :Example:
199             ['#love', '#sky', '#nice']
200         """
201         tags = ['#' + self.random.choice(HASHTAGS)
202                 for _ in range(quantity)]
203 
204         if int(quantity) == 1:
205             return tags[0]
206 
207         return tags
208 
209     def home_page(self, tld_type: Optional[TLDType] = None) -> str:
210         """Generate a random home page.
211 
212         :param tld_type: TLD type.
213         :return: Random home page.
214 
215         :Example:
216             http://www.fontir.info
217         """
218         resource = self.random.choice(USERNAMES)
219         domain = self.top_level_domain(
220             tld_type=tld_type,
221         )
222 
223         return 'http://www.{}{}'.format(
224             resource, domain)
225 
226     def top_level_domain(self, tld_type: Optional[TLDType] = None) -> str:
227         """Return random top level domain.
228 
229         :param tld_type: Enum object DomainType
230         :return: Top level domain.
231         :raises NonEnumerableError: if tld_type not in DomainType.
232         """
233         key = self._validate_enum(item=tld_type, enum=TLDType)
234         return self.random.choice(TLD[key])
235 
236     def user_agent(self) -> str:
237         """Get a random user agent.
238 
239         :return: User agent.
240 
241         :Example:
242             Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:15.0)
243             Gecko/20100101 Firefox/15.0.1
244         """
245         return self.random.choice(USER_AGENTS)
246 
247     def network_protocol(self, layer: Optional[Layer] = None) -> str:
248         """Get a random network protocol form OSI model.
249 
250         :param layer: Enum object Layer.
251         :return: Protocol name.
252 
253         :Example:
254             AMQP
255         """
256         key = self._validate_enum(item=layer, enum=Layer)
257         protocols = NETWORK_PROTOCOLS[key]
258         return self.random.choice(protocols)
259 
260     def port(self, port_range: PortRange = PortRange.ALL) -> int:
261         """Generate random port.
262 
263         :param port_range: Range enum object.
264         :return: Port number.
265         :raises NonEnumerableError: if port_range is not in PortRange.
266 
267         :Example:
268             8080
269         """
270         if isinstance(port_range, PortRange):
271             return self.random.randint(*port_range.value)
272         else:
273             raise NonEnumerableError(PortRange)
274
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/mimesis/providers/internet.py b/mimesis/providers/internet.py
--- a/mimesis/providers/internet.py
+++ b/mimesis/providers/internet.py
@@ -4,7 +4,7 @@
 
 import urllib.error
 import urllib.request
-from ipaddress import IPv6Address
+from ipaddress import IPv4Address, IPv6Address
 from typing import List, Optional, Union
 
 from mimesis.data import (
@@ -37,6 +37,8 @@
         """
         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."""
@@ -84,36 +86,60 @@
         """
         return self.random.choice(HTTP_METHODS)
 
-    def ip_v4(self, with_port: bool = False) -> str:
-        """Generate a random IPv4 address.
+    def ip_v4_object(self) -> IPv4Address:
+        """Generate random IPv4Address object.
 
-        :param with_port: Add port to IP.
-        :return: Random IPv4 address.
+        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_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_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
+            19.121.223.58 or 19.121.223.58:8000
         """
-        ip = '.'.join(str(self.random.randint(0, 255)) for _ in range(4))
+        ip = str(self.ip_v4_object())
 
         if with_port:
-            ip += ':{}'.format(self.port())
+            port = self.port(port_range=port_range)
+            return '{}:{}'.format(ip, port)
 
         return ip
 
     def ip_v6(self) -> str:
-        """Generate a random IPv6 address.
+        """Generate a random IPv6 address as string.
 
-        :return: Random IPv6 address.
+        :return: IPv6 address string.
 
         :Example:
             2001:c244:cf9d:1fb1:c56d:f52c:8a04:94f3
         """
-        ipv6 = IPv6Address(
-            self.random.randint(
-                0, 2 ** 128 - 1,
-            ),
-        )
-        return str(ipv6)
+        return str(self.ip_v6_object())
 
     def mac_address(self) -> str:
         """Generate a random MAC address.
@@ -260,7 +286,7 @@
     def port(self, port_range: PortRange = PortRange.ALL) -> int:
         """Generate random port.
 
-        :param port_range: Range enum object.
+        :param port_range: PortRange enum object.
         :return: Port number.
         :raises NonEnumerableError: if port_range is not in PortRange.

{"golden_diff": "diff --git a/mimesis/providers/internet.py b/mimesis/providers/internet.py\n--- a/mimesis/providers/internet.py\n+++ b/mimesis/providers/internet.py\n@@ -4,7 +4,7 @@\n \n import urllib.error\n import urllib.request\n-from ipaddress import IPv6Address\n+from ipaddress import IPv4Address, IPv6Address\n from typing import List, Optional, Union\n \n from mimesis.data import (\n@@ -37,6 +37,8 @@\n         \"\"\"\n         super().__init__(*args, **kwargs)\n         self.__file = File(seed=self.seed)\n+        self._MAX_IPV4 = (2 ** 32) - 1\n+        self._MAX_IPV6 = (2 ** 128) - 1\n \n     class Meta:\n         \"\"\"Class for metadata.\"\"\"\n@@ -84,36 +86,60 @@\n         \"\"\"\n         return self.random.choice(HTTP_METHODS)\n \n-    def ip_v4(self, with_port: bool = False) -> str:\n-        \"\"\"Generate a random IPv4 address.\n+    def ip_v4_object(self) -> IPv4Address:\n+        \"\"\"Generate random IPv4Address object.\n \n-        :param with_port: Add port to IP.\n-        :return: Random IPv4 address.\n+        See documentation for module ipaddress:\n+        https://docs.python.org/3.7/library/ipaddress.html\n+\n+        :return: IPv4Address object.\n+        \"\"\"\n+        return IPv4Address(\n+            self.random.randint(0, self._MAX_IPV4),\n+        )\n+\n+    def ip_v6_object(self) -> IPv6Address:\n+        \"\"\"Generate random IPv6Address object.\n+\n+        See documentation for module ipaddress:\n+        https://docs.python.org/3.7/library/ipaddress.html\n+\n+        :return: IPv6Address object.\n+        \"\"\"\n+        return IPv6Address(\n+            self.random.randint(\n+                0, self._MAX_IPV6,\n+            ),\n+        )\n+\n+    def ip_v4(self, with_port: bool = False,\n+              port_range: PortRange = PortRange.ALL) -> str:\n+        \"\"\"Generate a random IPv4 address as string.\n+\n+        :param port_range: PortRange enum object.\n+        :param with_port: Add port from PortRange to IP.\n+        :return: IPv4 address as string.\n \n         :Example:\n-            19.121.223.58\n+            19.121.223.58 or 19.121.223.58:8000\n         \"\"\"\n-        ip = '.'.join(str(self.random.randint(0, 255)) for _ in range(4))\n+        ip = str(self.ip_v4_object())\n \n         if with_port:\n-            ip += ':{}'.format(self.port())\n+            port = self.port(port_range=port_range)\n+            return '{}:{}'.format(ip, port)\n \n         return ip\n \n     def ip_v6(self) -> str:\n-        \"\"\"Generate a random IPv6 address.\n+        \"\"\"Generate a random IPv6 address as string.\n \n-        :return: Random IPv6 address.\n+        :return: IPv6 address string.\n \n         :Example:\n             2001:c244:cf9d:1fb1:c56d:f52c:8a04:94f3\n         \"\"\"\n-        ipv6 = IPv6Address(\n-            self.random.randint(\n-                0, 2 ** 128 - 1,\n-            ),\n-        )\n-        return str(ipv6)\n+        return str(self.ip_v6_object())\n \n     def mac_address(self) -> str:\n         \"\"\"Generate a random MAC address.\n@@ -260,7 +286,7 @@\n     def port(self, port_range: PortRange = PortRange.ALL) -> int:\n         \"\"\"Generate random port.\n \n-        :param port_range: Range enum object.\n+        :param port_range: PortRange enum object.\n         :return: Port number.\n         :raises NonEnumerableError: if port_range is not in PortRange.\n", "issue": "Improve IPv4/IPv6 generators for Internet()\nWe can improve how `.ip_v4()` and `.ip_v6()` works.\r\n\r\nI suggest using `ipaddress` module from the standard library, just like this:\r\n\r\n```python\r\n    def ip_v4(self, with_port: bool = False, stringify: bool = True) -> Union[str, IPv4Address]:\r\n        \"\"\"Generate a random IPv4 address.\r\n\r\n        :param stringify:  Return IPv4 as string (True by default).\r\n        :param with_port: Add port to IP.\r\n        :return: Random IPv4 address.\r\n\r\n        :Example:\r\n            19.121.223.58\r\n        \"\"\"\r\n        ipv4 = IPv4Address(self.random.getrandbits(32))\r\n\r\n        if not stringify:\r\n            return ipv4\r\n\r\n        if with_port:\r\n            ipv4 += ':{}'.format(self.port())\r\n\r\n        return ipv4\r\n```\r\n\r\nThe idea is to support IP addresses as objects to make them more useful than just strings.\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\n\"\"\"Provides data related to internet.\"\"\"\n\nimport urllib.error\nimport urllib.request\nfrom ipaddress import IPv6Address\nfrom typing import List, Optional, Union\n\nfrom mimesis.data import (\n    EMOJI,\n    HASHTAGS,\n    HTTP_METHODS,\n    HTTP_STATUS_CODES,\n    HTTP_STATUS_MSGS,\n    NETWORK_PROTOCOLS,\n    TLD,\n    USER_AGENTS,\n    USERNAMES,\n)\nfrom mimesis.enums import Layer, MimeType, PortRange, TLDType\nfrom mimesis.exceptions import NonEnumerableError\nfrom mimesis.providers.base import BaseProvider\nfrom mimesis.providers.file import File\n\n__all__ = ['Internet']\n\n\nclass Internet(BaseProvider):\n    \"\"\"Class for generating data related to the internet.\"\"\"\n\n    def __init__(self, *args, **kwargs):\n        \"\"\"Initialize attributes.\n\n        :param args: Arguments.\n        :param kwargs: Keyword arguments.\n        \"\"\"\n        super().__init__(*args, **kwargs)\n        self.__file = File(seed=self.seed)\n\n    class Meta:\n        \"\"\"Class for metadata.\"\"\"\n\n        name = 'internet'\n\n    def content_type(self, mime_type: Optional[MimeType] = None) -> str:\n        \"\"\"Get a random HTTP content type.\n\n        :return: Content type.\n\n        :Example:\n            Content-Type: application/json\n        \"\"\"\n        fmt = self.__file.mime_type(type_=mime_type)\n        return 'Content-Type: {}'.format(fmt)\n\n    def http_status_message(self) -> str:\n        \"\"\"Get a random HTTP status message.\n\n        :return: HTTP status message.\n\n        :Example:\n            200 OK\n        \"\"\"\n        return self.random.choice(HTTP_STATUS_MSGS)\n\n    def http_status_code(self) -> int:\n        \"\"\"Get a random HTTP status code.\n\n        :return: HTTP status.\n\n        :Example:\n            200\n        \"\"\"\n        return self.random.choice(HTTP_STATUS_CODES)\n\n    def http_method(self) -> str:\n        \"\"\"Get a random HTTP method.\n\n        :return: HTTP method.\n\n        :Example:\n            POST\n        \"\"\"\n        return self.random.choice(HTTP_METHODS)\n\n    def ip_v4(self, with_port: bool = False) -> str:\n        \"\"\"Generate a random IPv4 address.\n\n        :param with_port: Add port to IP.\n        :return: Random IPv4 address.\n\n        :Example:\n            19.121.223.58\n        \"\"\"\n        ip = '.'.join(str(self.random.randint(0, 255)) for _ in range(4))\n\n        if with_port:\n            ip += ':{}'.format(self.port())\n\n        return ip\n\n    def ip_v6(self) -> str:\n        \"\"\"Generate a random IPv6 address.\n\n        :return: Random IPv6 address.\n\n        :Example:\n            2001:c244:cf9d:1fb1:c56d:f52c:8a04:94f3\n        \"\"\"\n        ipv6 = IPv6Address(\n            self.random.randint(\n                0, 2 ** 128 - 1,\n            ),\n        )\n        return str(ipv6)\n\n    def mac_address(self) -> str:\n        \"\"\"Generate a random MAC address.\n\n        :return: Random MAC address.\n\n        :Example:\n            00:16:3e:25:e7:b1\n        \"\"\"\n        mac_hex = [\n            0x00, 0x16, 0x3e,\n            self.random.randint(0x00, 0x7f),\n            self.random.randint(0x00, 0xff),\n            self.random.randint(0x00, 0xff),\n        ]\n        mac = map(lambda x: '%02x' % x, mac_hex)\n        return ':'.join(mac)\n\n    def emoji(self) -> str:\n        \"\"\"Get a random emoji shortcut code.\n\n        :return: Emoji code.\n\n        :Example:\n            :kissing:\n        \"\"\"\n        return self.random.choice(EMOJI)\n\n    @staticmethod\n    def image_placeholder(width: Union[int, str] = 1920,\n                          height: Union[int, str] = 1080) -> str:\n        \"\"\"Generate a link to the image placeholder.\n\n        :param width: Width of image.\n        :param height: Height of image.\n        :return: URL to image placeholder.\n        \"\"\"\n        url = 'http://placehold.it/{width}x{height}'\n        return url.format(width=width, height=height)\n\n    @staticmethod\n    def stock_image(width: Union[int, str] = 1920,\n                    height: Union[int, str] = 1080,\n                    keywords: Optional[List[str]] = None,\n                    writable: bool = False) -> Union[str, bytes]:\n        \"\"\"Generate random stock image (JPEG) hosted on Unsplash.\n\n        .. note:: This method required an active HTTP connection.\n\n        :param width: Width of the image.\n        :param height: Height of the image.\n        :param keywords: List of search keywords.\n        :param writable: Return image as sequence ob bytes.\n        :return: Link to the image.\n        \"\"\"\n        api = 'https://source.unsplash.com/{}x{}?{}'\n\n        if keywords is not None:\n            keywords_str = ','.join(keywords)\n        else:\n            keywords_str = ''\n\n        url = api.format(width, height, keywords_str)\n\n        try:\n            response = urllib.request.urlopen(url)\n            if writable:\n                return response.read()\n            url = response.geturl()\n            return url\n        except urllib.error.URLError:\n            raise urllib.error.URLError(\n                'Required an active HTTP connection')\n\n    def hashtags(self, quantity: int = 4) -> Union[str, list]:\n        \"\"\"Generate a list of hashtags.\n\n        :param quantity: The quantity of hashtags.\n        :return: The list of hashtags.\n        :raises NonEnumerableError: if category is not in Hashtag.\n\n        :Example:\n            ['#love', '#sky', '#nice']\n        \"\"\"\n        tags = ['#' + self.random.choice(HASHTAGS)\n                for _ in range(quantity)]\n\n        if int(quantity) == 1:\n            return tags[0]\n\n        return tags\n\n    def home_page(self, tld_type: Optional[TLDType] = None) -> str:\n        \"\"\"Generate a random home page.\n\n        :param tld_type: TLD type.\n        :return: Random home page.\n\n        :Example:\n            http://www.fontir.info\n        \"\"\"\n        resource = self.random.choice(USERNAMES)\n        domain = self.top_level_domain(\n            tld_type=tld_type,\n        )\n\n        return 'http://www.{}{}'.format(\n            resource, domain)\n\n    def top_level_domain(self, tld_type: Optional[TLDType] = None) -> str:\n        \"\"\"Return random top level domain.\n\n        :param tld_type: Enum object DomainType\n        :return: Top level domain.\n        :raises NonEnumerableError: if tld_type not in DomainType.\n        \"\"\"\n        key = self._validate_enum(item=tld_type, enum=TLDType)\n        return self.random.choice(TLD[key])\n\n    def user_agent(self) -> str:\n        \"\"\"Get a random user agent.\n\n        :return: User agent.\n\n        :Example:\n            Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:15.0)\n            Gecko/20100101 Firefox/15.0.1\n        \"\"\"\n        return self.random.choice(USER_AGENTS)\n\n    def network_protocol(self, layer: Optional[Layer] = None) -> str:\n        \"\"\"Get a random network protocol form OSI model.\n\n        :param layer: Enum object Layer.\n        :return: Protocol name.\n\n        :Example:\n            AMQP\n        \"\"\"\n        key = self._validate_enum(item=layer, enum=Layer)\n        protocols = NETWORK_PROTOCOLS[key]\n        return self.random.choice(protocols)\n\n    def port(self, port_range: PortRange = PortRange.ALL) -> int:\n        \"\"\"Generate random port.\n\n        :param port_range: Range enum object.\n        :return: Port number.\n        :raises NonEnumerableError: if port_range is not in PortRange.\n\n        :Example:\n            8080\n        \"\"\"\n        if isinstance(port_range, PortRange):\n            return self.random.randint(*port_range.value)\n        else:\n            raise NonEnumerableError(PortRange)\n", "path": "mimesis/providers/internet.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\n\"\"\"Provides data related to internet.\"\"\"\n\nimport urllib.error\nimport urllib.request\nfrom ipaddress import IPv4Address, IPv6Address\nfrom typing import List, Optional, Union\n\nfrom mimesis.data import (\n    EMOJI,\n    HASHTAGS,\n    HTTP_METHODS,\n    HTTP_STATUS_CODES,\n    HTTP_STATUS_MSGS,\n    NETWORK_PROTOCOLS,\n    TLD,\n    USER_AGENTS,\n    USERNAMES,\n)\nfrom mimesis.enums import Layer, MimeType, PortRange, TLDType\nfrom mimesis.exceptions import NonEnumerableError\nfrom mimesis.providers.base import BaseProvider\nfrom mimesis.providers.file import File\n\n__all__ = ['Internet']\n\n\nclass Internet(BaseProvider):\n    \"\"\"Class for generating data related to the internet.\"\"\"\n\n    def __init__(self, *args, **kwargs):\n        \"\"\"Initialize attributes.\n\n        :param args: Arguments.\n        :param kwargs: Keyword arguments.\n        \"\"\"\n        super().__init__(*args, **kwargs)\n        self.__file = File(seed=self.seed)\n        self._MAX_IPV4 = (2 ** 32) - 1\n        self._MAX_IPV6 = (2 ** 128) - 1\n\n    class Meta:\n        \"\"\"Class for metadata.\"\"\"\n\n        name = 'internet'\n\n    def content_type(self, mime_type: Optional[MimeType] = None) -> str:\n        \"\"\"Get a random HTTP content type.\n\n        :return: Content type.\n\n        :Example:\n            Content-Type: application/json\n        \"\"\"\n        fmt = self.__file.mime_type(type_=mime_type)\n        return 'Content-Type: {}'.format(fmt)\n\n    def http_status_message(self) -> str:\n        \"\"\"Get a random HTTP status message.\n\n        :return: HTTP status message.\n\n        :Example:\n            200 OK\n        \"\"\"\n        return self.random.choice(HTTP_STATUS_MSGS)\n\n    def http_status_code(self) -> int:\n        \"\"\"Get a random HTTP status code.\n\n        :return: HTTP status.\n\n        :Example:\n            200\n        \"\"\"\n        return self.random.choice(HTTP_STATUS_CODES)\n\n    def http_method(self) -> str:\n        \"\"\"Get a random HTTP method.\n\n        :return: HTTP method.\n\n        :Example:\n            POST\n        \"\"\"\n        return self.random.choice(HTTP_METHODS)\n\n    def ip_v4_object(self) -> IPv4Address:\n        \"\"\"Generate random IPv4Address object.\n\n        See documentation for module ipaddress:\n        https://docs.python.org/3.7/library/ipaddress.html\n\n        :return: IPv4Address object.\n        \"\"\"\n        return IPv4Address(\n            self.random.randint(0, self._MAX_IPV4),\n        )\n\n    def ip_v6_object(self) -> IPv6Address:\n        \"\"\"Generate random IPv6Address object.\n\n        See documentation for module ipaddress:\n        https://docs.python.org/3.7/library/ipaddress.html\n\n        :return: IPv6Address object.\n        \"\"\"\n        return IPv6Address(\n            self.random.randint(\n                0, self._MAX_IPV6,\n            ),\n        )\n\n    def ip_v4(self, with_port: bool = False,\n              port_range: PortRange = PortRange.ALL) -> str:\n        \"\"\"Generate a random IPv4 address as string.\n\n        :param port_range: PortRange enum object.\n        :param with_port: Add port from PortRange to IP.\n        :return: IPv4 address as string.\n\n        :Example:\n            19.121.223.58 or 19.121.223.58:8000\n        \"\"\"\n        ip = str(self.ip_v4_object())\n\n        if with_port:\n            port = self.port(port_range=port_range)\n            return '{}:{}'.format(ip, port)\n\n        return ip\n\n    def ip_v6(self) -> str:\n        \"\"\"Generate a random IPv6 address as string.\n\n        :return: IPv6 address string.\n\n        :Example:\n            2001:c244:cf9d:1fb1:c56d:f52c:8a04:94f3\n        \"\"\"\n        return str(self.ip_v6_object())\n\n    def mac_address(self) -> str:\n        \"\"\"Generate a random MAC address.\n\n        :return: Random MAC address.\n\n        :Example:\n            00:16:3e:25:e7:b1\n        \"\"\"\n        mac_hex = [\n            0x00, 0x16, 0x3e,\n            self.random.randint(0x00, 0x7f),\n            self.random.randint(0x00, 0xff),\n            self.random.randint(0x00, 0xff),\n        ]\n        mac = map(lambda x: '%02x' % x, mac_hex)\n        return ':'.join(mac)\n\n    def emoji(self) -> str:\n        \"\"\"Get a random emoji shortcut code.\n\n        :return: Emoji code.\n\n        :Example:\n            :kissing:\n        \"\"\"\n        return self.random.choice(EMOJI)\n\n    @staticmethod\n    def image_placeholder(width: Union[int, str] = 1920,\n                          height: Union[int, str] = 1080) -> str:\n        \"\"\"Generate a link to the image placeholder.\n\n        :param width: Width of image.\n        :param height: Height of image.\n        :return: URL to image placeholder.\n        \"\"\"\n        url = 'http://placehold.it/{width}x{height}'\n        return url.format(width=width, height=height)\n\n    @staticmethod\n    def stock_image(width: Union[int, str] = 1920,\n                    height: Union[int, str] = 1080,\n                    keywords: Optional[List[str]] = None,\n                    writable: bool = False) -> Union[str, bytes]:\n        \"\"\"Generate random stock image (JPEG) hosted on Unsplash.\n\n        .. note:: This method required an active HTTP connection.\n\n        :param width: Width of the image.\n        :param height: Height of the image.\n        :param keywords: List of search keywords.\n        :param writable: Return image as sequence ob bytes.\n        :return: Link to the image.\n        \"\"\"\n        api = 'https://source.unsplash.com/{}x{}?{}'\n\n        if keywords is not None:\n            keywords_str = ','.join(keywords)\n        else:\n            keywords_str = ''\n\n        url = api.format(width, height, keywords_str)\n\n        try:\n            response = urllib.request.urlopen(url)\n            if writable:\n                return response.read()\n            url = response.geturl()\n            return url\n        except urllib.error.URLError:\n            raise urllib.error.URLError(\n                'Required an active HTTP connection')\n\n    def hashtags(self, quantity: int = 4) -> Union[str, list]:\n        \"\"\"Generate a list of hashtags.\n\n        :param quantity: The quantity of hashtags.\n        :return: The list of hashtags.\n        :raises NonEnumerableError: if category is not in Hashtag.\n\n        :Example:\n            ['#love', '#sky', '#nice']\n        \"\"\"\n        tags = ['#' + self.random.choice(HASHTAGS)\n                for _ in range(quantity)]\n\n        if int(quantity) == 1:\n            return tags[0]\n\n        return tags\n\n    def home_page(self, tld_type: Optional[TLDType] = None) -> str:\n        \"\"\"Generate a random home page.\n\n        :param tld_type: TLD type.\n        :return: Random home page.\n\n        :Example:\n            http://www.fontir.info\n        \"\"\"\n        resource = self.random.choice(USERNAMES)\n        domain = self.top_level_domain(\n            tld_type=tld_type,\n        )\n\n        return 'http://www.{}{}'.format(\n            resource, domain)\n\n    def top_level_domain(self, tld_type: Optional[TLDType] = None) -> str:\n        \"\"\"Return random top level domain.\n\n        :param tld_type: Enum object DomainType\n        :return: Top level domain.\n        :raises NonEnumerableError: if tld_type not in DomainType.\n        \"\"\"\n        key = self._validate_enum(item=tld_type, enum=TLDType)\n        return self.random.choice(TLD[key])\n\n    def user_agent(self) -> str:\n        \"\"\"Get a random user agent.\n\n        :return: User agent.\n\n        :Example:\n            Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:15.0)\n            Gecko/20100101 Firefox/15.0.1\n        \"\"\"\n        return self.random.choice(USER_AGENTS)\n\n    def network_protocol(self, layer: Optional[Layer] = None) -> str:\n        \"\"\"Get a random network protocol form OSI model.\n\n        :param layer: Enum object Layer.\n        :return: Protocol name.\n\n        :Example:\n            AMQP\n        \"\"\"\n        key = self._validate_enum(item=layer, enum=Layer)\n        protocols = NETWORK_PROTOCOLS[key]\n        return self.random.choice(protocols)\n\n    def port(self, port_range: PortRange = PortRange.ALL) -> int:\n        \"\"\"Generate random port.\n\n        :param port_range: PortRange enum object.\n        :return: Port number.\n        :raises NonEnumerableError: if port_range is not in PortRange.\n\n        :Example:\n            8080\n        \"\"\"\n        if isinstance(port_range, PortRange):\n            return self.random.randint(*port_range.value)\n        else:\n            raise NonEnumerableError(PortRange)\n", "path": "mimesis/providers/internet.py"}]}