We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Remove download_image function.
# Bug report

This is not a kind of problem mimesis solves. So it's pretty annoying when tests fail because of it all the time. It's better just remove it.

--- 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/shortcuts.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 
3 """This module is provide internal util functions."""
4 
5 import ssl
6 from os import path
7 from typing import Union
8 from urllib import request
9 from uuid import uuid4
10 
11 __all__ = ['download_image', 'luhn_checksum']
12 
13 
14 def luhn_checksum(num: str) -> str:
15     """Calculate a checksum for num using the Luhn algorithm.
16 
17     :param num: The number to calculate a checksum for as a string.
18     :return: Checksum for number.
19     """
20     check = 0
21     for i, s in enumerate(reversed(num)):
22         sx = int(s)
23         sx = sx * 2 if i % 2 == 0 else sx
24         sx = sx - 9 if sx > 9 else sx
25         check += sx
26     return str(check * 9 % 10)
27 
28 
29 def download_image(url: str = '', save_path: str = '',
30                    unverified_ctx: bool = False) -> Union[None, str]:
31     """Download image and save in current directory on local machine.
32 
33     :param url: URL to image.
34     :param save_path: Saving path.
35     :param unverified_ctx: Create unverified context.
36     :return: Path to downloaded image.
37     :rtype: str or None
38     """
39     if unverified_ctx:
40         ssl._create_default_https_context = ssl._create_unverified_context
41 
42     if url:
43         image_name = url.rsplit('/')[-1]
44 
45         splitted_name = image_name.rsplit('.')
46         if len(splitted_name) < 2:
47             image_name = '{}.jpg'.format(uuid4())
48         else:
49             image_name = '{}.{}'.format(uuid4(), splitted_name[-1])
50         full_image_path = path.join(save_path, image_name)
51         request.urlretrieve(url, full_image_path)
52         return full_image_path
53     return None
54
```

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 IPv4Address, 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         self._MAX_IPV4 = (2 ** 32) - 1
41         self._MAX_IPV6 = (2 ** 128) - 1
42 
43     class Meta:
44         """Class for metadata."""
45 
46         name = 'internet'
47 
48     def content_type(self, mime_type: Optional[MimeType] = None) -> str:
49         """Get a random HTTP content type.
50 
51         :return: Content type.
52 
53         :Example:
54             Content-Type: application/json
55         """
56         fmt = self.__file.mime_type(type_=mime_type)
57         return 'Content-Type: {}'.format(fmt)
58 
59     def http_status_message(self) -> str:
60         """Get a random HTTP status message.
61 
62         :return: HTTP status message.
63 
64         :Example:
65             200 OK
66         """
67         return self.random.choice(HTTP_STATUS_MSGS)
68 
69     def http_status_code(self) -> int:
70         """Get a random HTTP status code.
71 
72         :return: HTTP status.
73 
74         :Example:
75             200
76         """
77         return self.random.choice(HTTP_STATUS_CODES)
78 
79     def http_method(self) -> str:
80         """Get a random HTTP method.
81 
82         :return: HTTP method.
83 
84         :Example:
85             POST
86         """
87         return self.random.choice(HTTP_METHODS)
88 
89     def ip_v4_object(self) -> IPv4Address:
90         """Generate random IPv4Address object.
91 
92         See documentation for module ipaddress:
93         https://docs.python.org/3.7/library/ipaddress.html
94 
95         :return: IPv4Address object.
96         """
97         return IPv4Address(
98             self.random.randint(0, self._MAX_IPV4),
99         )
100 
101     def ip_v4(self, with_port: bool = False,
102               port_range: PortRange = PortRange.ALL) -> str:
103         """Generate a random IPv4 address as string.
104 
105         :param port_range: PortRange enum object.
106         :param with_port: Add port from PortRange to IP.
107         :return: IPv4 address as string.
108 
109         :Example:
110             19.121.223.58 or 19.121.223.58:8000
111         """
112         ip = str(self.ip_v4_object())
113 
114         if with_port:
115             port = self.port(port_range=port_range)
116             return '{}:{}'.format(ip, port)
117 
118         return ip
119 
120     def ip_v6_object(self) -> IPv6Address:
121         """Generate random IPv6Address object.
122 
123         See documentation for module ipaddress:
124         https://docs.python.org/3.7/library/ipaddress.html
125 
126         :return: IPv6Address object.
127         """
128         return IPv6Address(
129             self.random.randint(
130                 0, self._MAX_IPV6,
131             ),
132         )
133 
134     def ip_v6(self) -> str:
135         """Generate a random IPv6 address as string.
136 
137         :return: IPv6 address string.
138 
139         :Example:
140             2001:c244:cf9d:1fb1:c56d:f52c:8a04:94f3
141         """
142         return str(self.ip_v6_object())
143 
144     def mac_address(self) -> str:
145         """Generate a random MAC address.
146 
147         :return: Random MAC address.
148 
149         :Example:
150             00:16:3e:25:e7:b1
151         """
152         mac_hex = [
153             0x00, 0x16, 0x3e,
154             self.random.randint(0x00, 0x7f),
155             self.random.randint(0x00, 0xff),
156             self.random.randint(0x00, 0xff),
157         ]
158         mac = map(lambda x: '{:02x}'.format(x), mac_hex)
159         return ':'.join(mac)
160 
161     def emoji(self) -> str:
162         """Get a random emoji shortcut code.
163 
164         :return: Emoji code.
165 
166         :Example:
167             :kissing:
168         """
169         return self.random.choice(EMOJI)
170 
171     @staticmethod
172     def image_placeholder(width: Union[int, str] = 1920,
173                           height: Union[int, str] = 1080) -> str:
174         """Generate a link to the image placeholder.
175 
176         :param width: Width of image.
177         :param height: Height of image.
178         :return: URL to image placeholder.
179         """
180         url = 'http://placehold.it/{width}x{height}'
181         return url.format(width=width, height=height)
182 
183     @staticmethod
184     def stock_image(width: Union[int, str] = 1920,
185                     height: Union[int, str] = 1080,
186                     keywords: Optional[List[str]] = None,
187                     writable: bool = False) -> Union[str, bytes]:
188         """Generate random stock image (JPEG) hosted on Unsplash.
189 
190         See «Random search term» on https://source.unsplash.com/
191         for more details.
192 
193         .. note:: This method required an active HTTP connection.
194 
195         :param width: Width of the image.
196         :param height: Height of the image.
197         :param keywords: List of search keywords.
198         :param writable: Return image as sequence ob bytes.
199         :return: Link to the image.
200         """
201         api = 'https://source.unsplash.com/{}x{}?{}'
202 
203         if keywords is not None:
204             keywords_str = ','.join(keywords)
205         else:
206             keywords_str = ''
207 
208         url = api.format(width, height, keywords_str)
209 
210         try:
211             response = urllib.request.urlopen(url)
212             if writable:
213                 return response.read()
214             url = response.geturl()
215             return url
216         except urllib.error.URLError:
217             raise urllib.error.URLError(
218                 'Required an active HTTP connection')
219 
220     def hashtags(self, quantity: int = 4) -> Union[str, list]:
221         """Generate a list of hashtags.
222 
223         :param quantity: The quantity of hashtags.
224         :return: The list of hashtags.
225         :raises NonEnumerableError: if category is not in Hashtag.
226 
227         :Example:
228             ['#love', '#sky', '#nice']
229         """
230         tags = ['#' + self.random.choice(HASHTAGS)
231                 for _ in range(quantity)]
232 
233         if int(quantity) == 1:
234             return tags[0]
235 
236         return tags
237 
238     def home_page(self, tld_type: Optional[TLDType] = None) -> str:
239         """Generate a random home page.
240 
241         :param tld_type: TLD type.
242         :return: Random home page.
243 
244         :Example:
245             https://fontir.info
246         """
247         resource = self.random.choice(USERNAMES)
248         domain = self.top_level_domain(
249             tld_type=tld_type,
250         )
251 
252         return 'https://{}{}'.format(
253             resource, domain)
254 
255     def top_level_domain(self, tld_type: Optional[TLDType] = None) -> str:
256         """Return random top level domain.
257 
258         :param tld_type: Enum object DomainType
259         :return: Top level domain.
260         :raises NonEnumerableError: if tld_type not in DomainType.
261         """
262         key = self._validate_enum(item=tld_type, enum=TLDType)
263         return self.random.choice(TLD[key])
264 
265     def user_agent(self) -> str:
266         """Get a random user agent.
267 
268         :return: User agent.
269 
270         :Example:
271             Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:15.0)
272             Gecko/20100101 Firefox/15.0.1
273         """
274         return self.random.choice(USER_AGENTS)
275 
276     def network_protocol(self, layer: Optional[Layer] = None) -> str:
277         """Get a random network protocol form OSI model.
278 
279         :param layer: Enum object Layer.
280         :return: Protocol name.
281 
282         :Example:
283             AMQP
284         """
285         key = self._validate_enum(item=layer, enum=Layer)
286         protocols = NETWORK_PROTOCOLS[key]
287         return self.random.choice(protocols)
288 
289     def port(self, port_range: PortRange = PortRange.ALL) -> int:
290         """Generate random port.
291 
292         :param port_range: PortRange enum object.
293         :return: Port number.
294         :raises NonEnumerableError: if port_range is not in PortRange.
295 
296         :Example:
297             8080
298         """
299         if isinstance(port_range, PortRange):
300             return self.random.randint(*port_range.value)
301         else:
302             raise NonEnumerableError(PortRange)
303
```
--- 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
@@ -185,12 +185,13 @@
                     height: Union[int, str] = 1080,
                     keywords: Optional[List[str]] = None,
                     writable: bool = False) -> Union[str, bytes]:
-        """Generate random stock image (JPEG) hosted on Unsplash.
+        """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.
+        .. 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.
@@ -198,24 +199,23 @@
         :param writable: Return image as sequence ob bytes.
         :return: Link to the image.
         """
-        api = 'https://source.unsplash.com/{}x{}?{}'
+        api_url = 'https://source.unsplash.com/{}x{}?{}'
 
         if keywords is not None:
             keywords_str = ','.join(keywords)
         else:
             keywords_str = ''
 
-        url = api.format(width, height, keywords_str)
+        url = api_url.format(width, height, keywords_str)
 
-        try:
-            response = urllib.request.urlopen(url)
-            if writable:
+        if writable:
+            try:
+                response = urllib.request.urlopen(url)
                 return response.read()
-            url = response.geturl()
-            return url
-        except urllib.error.URLError:
-            raise urllib.error.URLError(
-                'Required an active HTTP connection')
+            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.
diff --git a/mimesis/shortcuts.py b/mimesis/shortcuts.py
--- a/mimesis/shortcuts.py
+++ b/mimesis/shortcuts.py
@@ -8,7 +8,7 @@
 from urllib import request
 from uuid import uuid4
 
-__all__ = ['download_image', 'luhn_checksum']
+__all__ = ['luhn_checksum']
 
 
 def luhn_checksum(num: str) -> str:
@@ -24,30 +24,3 @@
         sx = sx - 9 if sx > 9 else sx
         check += sx
     return str(check * 9 % 10)
-
-
-def download_image(url: str = '', save_path: str = '',
-                   unverified_ctx: bool = False) -> Union[None, str]:
-    """Download image and save in current directory on local machine.
-
-    :param url: URL to image.
-    :param save_path: Saving path.
-    :param unverified_ctx: Create unverified context.
-    :return: Path to downloaded image.
-    :rtype: str or None
-    """
-    if unverified_ctx:
-        ssl._create_default_https_context = ssl._create_unverified_context
-
-    if url:
-        image_name = url.rsplit('/')[-1]
-
-        splitted_name = image_name.rsplit('.')
-        if len(splitted_name) < 2:
-            image_name = '{}.jpg'.format(uuid4())
-        else:
-            image_name = '{}.{}'.format(uuid4(), splitted_name[-1])
-        full_image_path = path.join(save_path, image_name)
-        request.urlretrieve(url, full_image_path)
-        return full_image_path
-    return None

{"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@@ -185,12 +185,13 @@\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+        \"\"\"Generate random stock image (JPG/JPEG) hosted on Unsplash.\n \n         See \u00abRandom search term\u00bb on https://source.unsplash.com/\n         for more details.\n \n-        .. note:: This method required an active HTTP connection.\n+        .. note:: This method required an active HTTP connection\n+            if you want to get writable object\n \n         :param width: Width of the image.\n         :param height: Height of the image.\n@@ -198,24 +199,23 @@\n         :param writable: Return image as sequence ob bytes.\n         :return: Link to the image.\n         \"\"\"\n-        api = 'https://source.unsplash.com/{}x{}?{}'\n+        api_url = '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+        url = api_url.format(width, height, keywords_str)\n \n-        try:\n-            response = urllib.request.urlopen(url)\n-            if writable:\n+        if writable:\n+            try:\n+                response = urllib.request.urlopen(url)\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+            except urllib.error.URLError:\n+                raise urllib.error.URLError(\n+                    'Required an active HTTP connection')\n+        return url\n \n     def hashtags(self, quantity: int = 4) -> Union[str, list]:\n         \"\"\"Generate a list of hashtags.\ndiff --git a/mimesis/shortcuts.py b/mimesis/shortcuts.py\n--- a/mimesis/shortcuts.py\n+++ b/mimesis/shortcuts.py\n@@ -8,7 +8,7 @@\n from urllib import request\n from uuid import uuid4\n \n-__all__ = ['download_image', 'luhn_checksum']\n+__all__ = ['luhn_checksum']\n \n \n def luhn_checksum(num: str) -> str:\n@@ -24,30 +24,3 @@\n         sx = sx - 9 if sx > 9 else sx\n         check += sx\n     return str(check * 9 % 10)\n-\n-\n-def download_image(url: str = '', save_path: str = '',\n-                   unverified_ctx: bool = False) -> Union[None, str]:\n-    \"\"\"Download image and save in current directory on local machine.\n-\n-    :param url: URL to image.\n-    :param save_path: Saving path.\n-    :param unverified_ctx: Create unverified context.\n-    :return: Path to downloaded image.\n-    :rtype: str or None\n-    \"\"\"\n-    if unverified_ctx:\n-        ssl._create_default_https_context = ssl._create_unverified_context\n-\n-    if url:\n-        image_name = url.rsplit('/')[-1]\n-\n-        splitted_name = image_name.rsplit('.')\n-        if len(splitted_name) < 2:\n-            image_name = '{}.jpg'.format(uuid4())\n-        else:\n-            image_name = '{}.{}'.format(uuid4(), splitted_name[-1])\n-        full_image_path = path.join(save_path, image_name)\n-        request.urlretrieve(url, full_image_path)\n-        return full_image_path\n-    return None\n", "issue": "Remove download_image function.\n# Bug report\r\n\r\nThis is not a kind of problem mimesis solves. So it's pretty annoying when tests fail because of it all the time. It's better just remove it.\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\n\"\"\"This module is provide internal util functions.\"\"\"\n\nimport ssl\nfrom os import path\nfrom typing import Union\nfrom urllib import request\nfrom uuid import uuid4\n\n__all__ = ['download_image', 'luhn_checksum']\n\n\ndef luhn_checksum(num: str) -> str:\n    \"\"\"Calculate a checksum for num using the Luhn algorithm.\n\n    :param num: The number to calculate a checksum for as a string.\n    :return: Checksum for number.\n    \"\"\"\n    check = 0\n    for i, s in enumerate(reversed(num)):\n        sx = int(s)\n        sx = sx * 2 if i % 2 == 0 else sx\n        sx = sx - 9 if sx > 9 else sx\n        check += sx\n    return str(check * 9 % 10)\n\n\ndef download_image(url: str = '', save_path: str = '',\n                   unverified_ctx: bool = False) -> Union[None, str]:\n    \"\"\"Download image and save in current directory on local machine.\n\n    :param url: URL to image.\n    :param save_path: Saving path.\n    :param unverified_ctx: Create unverified context.\n    :return: Path to downloaded image.\n    :rtype: str or None\n    \"\"\"\n    if unverified_ctx:\n        ssl._create_default_https_context = ssl._create_unverified_context\n\n    if url:\n        image_name = url.rsplit('/')[-1]\n\n        splitted_name = image_name.rsplit('.')\n        if len(splitted_name) < 2:\n            image_name = '{}.jpg'.format(uuid4())\n        else:\n            image_name = '{}.{}'.format(uuid4(), splitted_name[-1])\n        full_image_path = path.join(save_path, image_name)\n        request.urlretrieve(url, full_image_path)\n        return full_image_path\n    return None\n", "path": "mimesis/shortcuts.py"}, {"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_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_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_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}'.format(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        See \u00abRandom search term\u00bb on https://source.unsplash.com/\n        for more details.\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            https://fontir.info\n        \"\"\"\n        resource = self.random.choice(USERNAMES)\n        domain = self.top_level_domain(\n            tld_type=tld_type,\n        )\n\n        return 'https://{}{}'.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"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\n\"\"\"This module is provide internal util functions.\"\"\"\n\nimport ssl\nfrom os import path\nfrom typing import Union\nfrom urllib import request\nfrom uuid import uuid4\n\n__all__ = ['luhn_checksum']\n\n\ndef luhn_checksum(num: str) -> str:\n    \"\"\"Calculate a checksum for num using the Luhn algorithm.\n\n    :param num: The number to calculate a checksum for as a string.\n    :return: Checksum for number.\n    \"\"\"\n    check = 0\n    for i, s in enumerate(reversed(num)):\n        sx = int(s)\n        sx = sx * 2 if i % 2 == 0 else sx\n        sx = sx - 9 if sx > 9 else sx\n        check += sx\n    return str(check * 9 % 10)\n", "path": "mimesis/shortcuts.py"}, {"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_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_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_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}'.format(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 (JPG/JPEG) hosted on Unsplash.\n\n        See \u00abRandom search term\u00bb on https://source.unsplash.com/\n        for more details.\n\n        .. note:: This method required an active HTTP connection\n            if you want to get writable object\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_url = '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_url.format(width, height, keywords_str)\n\n        if writable:\n            try:\n                response = urllib.request.urlopen(url)\n                return response.read()\n            except urllib.error.URLError:\n                raise urllib.error.URLError(\n                    'Required an active HTTP connection')\n        return url\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            https://fontir.info\n        \"\"\"\n        resource = self.random.choice(USERNAMES)\n        domain = self.top_level_domain(\n            tld_type=tld_type,\n        )\n\n        return 'https://{}{}'.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"}]}