We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
since 4.3 can´t connect behind proxy
<!--
Thanks for reporting issues of python-telegram-bot!
To make it easier for us to help you please enter detailed information below.
-->
### Steps to reproduce
1. pip3 install python-telegram-bot --upgrade
2. Don´t send anything
3. pip3 install python-telegram-bot-4.2.1
4. Works again!
### Expected behaviour

Tell us what should happen
### Actual behaviour

Tell us what happens instead
### Configuration

**Operating System:**

**Version of Python:**

`$ python -V` 3.5

**Version of python-telegram-bot:**
4.3.2,  4.2.1
`$ python -c 'import telegram; print(telegram.__version__)'`
### Logs

Insert logs here (if necessary)


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `telegram/utils/request.py`
Content:
```
1 #!/usr/bin/env python
2 #
3 # A library that provides a Python interface to the Telegram Bot API
4 # Copyright (C) 2015-2016
5 # Leandro Toledo de Souza <devs@python-telegram-bot.org>
6 #
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Lesser Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU Lesser Public License for more details.
16 #
17 # You should have received a copy of the GNU Lesser Public License
18 # along with this program.  If not, see [http://www.gnu.org/licenses/].
19 """This module contains methods to make POST and GET requests"""
20 
21 import json
22 import socket
23 import logging
24 
25 import certifi
26 import urllib3
27 from urllib3.connection import HTTPConnection
28 
29 from telegram import (InputFile, TelegramError)
30 from telegram.error import Unauthorized, NetworkError, TimedOut, BadRequest
31 
32 _CON_POOL = None
33 """:type: urllib3.PoolManager"""
34 CON_POOL_SIZE = 1
35 
36 logging.getLogger('urllib3').setLevel(logging.WARNING)
37 
38 
39 def _get_con_pool():
40     global _CON_POOL
41 
42     if _CON_POOL is not None:
43         return _CON_POOL
44 
45     _CON_POOL = urllib3.PoolManager(maxsize=CON_POOL_SIZE,
46                                     cert_reqs='CERT_REQUIRED',
47                                     ca_certs=certifi.where(),
48                                     socket_options=HTTPConnection.default_socket_options + [
49                                         (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),
50                                     ])
51     return _CON_POOL
52 
53 
54 def is_con_pool_initialized():
55     return _CON_POOL is not None
56 
57 
58 def stop_con_pool():
59     global _CON_POOL
60     if _CON_POOL is not None:
61         _CON_POOL.clear()
62         _CON_POOL = None
63 
64 
65 def _parse(json_data):
66     """Try and parse the JSON returned from Telegram.
67 
68     Returns:
69         dict: A JSON parsed as Python dict with results - on error this dict will be empty.
70 
71     """
72     decoded_s = json_data.decode('utf-8')
73     try:
74         data = json.loads(decoded_s)
75     except ValueError:
76         raise TelegramError('Invalid server response')
77 
78     if not data.get('ok') and data.get('description'):
79         return data['description']
80 
81     return data['result']
82 
83 
84 def _request_wrapper(*args, **kwargs):
85     """Wraps urllib3 request for handling known exceptions.
86 
87     Args:
88         args: unnamed arguments, passed to urllib3 request.
89         kwargs: keyword arguments, passed tp urllib3 request.
90 
91     Returns:
92         str: A non-parsed JSON text.
93 
94     Raises:
95         TelegramError
96 
97     """
98 
99     try:
100         resp = _get_con_pool().request(*args, **kwargs)
101     except urllib3.exceptions.TimeoutError as error:
102         raise TimedOut()
103     except urllib3.exceptions.HTTPError as error:
104         # HTTPError must come last as its the base urllib3 exception class
105         # TODO: do something smart here; for now just raise NetworkError
106         raise NetworkError('urllib3 HTTPError {0}'.format(error))
107 
108     if 200 <= resp.status <= 299:
109         # 200-299 range are HTTP success statuses
110         return resp.data
111 
112     try:
113         message = _parse(resp.data)
114     except ValueError:
115         raise NetworkError('Unknown HTTPError {0}'.format(resp.status))
116 
117     if resp.status in (401, 403):
118         raise Unauthorized()
119     elif resp.status == 400:
120         raise BadRequest(repr(message))
121     elif resp.status == 502:
122         raise NetworkError('Bad Gateway')
123     else:
124         raise NetworkError('{0} ({1})'.format(message, resp.status))
125 
126 
127 def get(url):
128     """Request an URL.
129     Args:
130       url:
131         The web location we want to retrieve.
132 
133     Returns:
134       A JSON object.
135 
136     """
137     result = _request_wrapper('GET', url)
138 
139     return _parse(result)
140 
141 
142 def post(url, data, timeout=None):
143     """Request an URL.
144     Args:
145       url:
146         The web location we want to retrieve.
147       data:
148         A dict of (str, unicode) key/value pairs.
149       timeout:
150         float. If this value is specified, use it as the definitive timeout (in
151         seconds) for urlopen() operations. [Optional]
152 
153     Notes:
154       If neither `timeout` nor `data['timeout']` is specified. The underlying
155       defaults are used.
156 
157     Returns:
158       A JSON object.
159 
160     """
161     urlopen_kwargs = {}
162 
163     if timeout is not None:
164         urlopen_kwargs['timeout'] = timeout
165 
166     if InputFile.is_inputfile(data):
167         data = InputFile(data)
168         result = _request_wrapper('POST', url, body=data.to_form(), headers=data.headers)
169     else:
170         data = json.dumps(data)
171         result = _request_wrapper('POST',
172                                   url,
173                                   body=data.encode(),
174                                   headers={'Content-Type': 'application/json'},
175                                   **urlopen_kwargs)
176 
177     return _parse(result)
178 
179 
180 def download(url, filename):
181     """Download a file by its URL.
182     Args:
183       url:
184         The web location we want to retrieve.
185 
186       filename:
187         The filename within the path to download the file.
188 
189     """
190     buf = _request_wrapper('GET', url)
191     with open(filename, 'wb') as fobj:
192         fobj.write(buf)
193
```
--- 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/telegram/utils/request.py b/telegram/utils/request.py
--- a/telegram/utils/request.py
+++ b/telegram/utils/request.py
@@ -19,6 +19,7 @@
 """This module contains methods to make POST and GET requests"""
 
 import json
+import os
 import socket
 import logging
 
@@ -31,26 +32,41 @@
 
 _CON_POOL = None
 """:type: urllib3.PoolManager"""
+_CON_POOL_PROXY = None
+_CON_POOL_PROXY_KWARGS = {}
 CON_POOL_SIZE = 1
 
 logging.getLogger('urllib3').setLevel(logging.WARNING)
 
 
 def _get_con_pool():
-    global _CON_POOL
-
     if _CON_POOL is not None:
         return _CON_POOL
 
-    _CON_POOL = urllib3.PoolManager(maxsize=CON_POOL_SIZE,
-                                    cert_reqs='CERT_REQUIRED',
-                                    ca_certs=certifi.where(),
-                                    socket_options=HTTPConnection.default_socket_options + [
-                                        (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),
-                                    ])
+    _init_con_pool()
     return _CON_POOL
 
 
+def _init_con_pool():
+    global _CON_POOL
+    kwargs = dict(maxsize=CON_POOL_SIZE,
+                  cert_reqs='CERT_REQUIRED',
+                  ca_certs=certifi.where(),
+                  socket_options=HTTPConnection.default_socket_options + [
+                      (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),
+                  ])
+    proxy_url = _get_con_pool_proxy()
+    if not proxy_url:
+        mgr = urllib3.PoolManager
+    else:
+        kwargs['proxy_url'] = proxy_url
+        if _CON_POOL_PROXY_KWARGS:
+            kwargs.update(_CON_POOL_PROXY_KWARGS)
+        mgr = urllib3.ProxyManager
+
+    _CON_POOL = mgr(**kwargs)
+
+
 def is_con_pool_initialized():
     return _CON_POOL is not None
 
@@ -62,6 +78,47 @@
         _CON_POOL = None
 
 
+def set_con_pool_proxy(url, **urllib3_kwargs):
+    """Setup connection pool behind a proxy
+
+    Args:
+        url (str): The URL to the proxy server. For example: `http://127.0.0.1:3128`
+        urllib3_kwargs (dict): Arbitrary arguments passed as-is to `urllib3.ProxyManager`
+
+    """
+    global _CON_POOL_PROXY
+    global _CON_POOL_PROXY_KWARGS
+
+    if is_con_pool_initialized():
+        raise TelegramError('conpool already initialized')
+
+    _CON_POOL_PROXY = url
+    _CON_POOL_PROXY_KWARGS = urllib3_kwargs
+
+
+def _get_con_pool_proxy():
+    """Return the user configured proxy according to the following order:
+
+      * proxy configured using `set_con_pool_proxy()`.
+      * proxy set in `HTTPS_PROXY` env. var.
+      * proxy set in `https_proxy` env. var.
+      * None (if no proxy is configured)
+
+      Returns:
+          str | None
+
+    """
+    if _CON_POOL_PROXY:
+        return _CON_POOL_PROXY
+    from_env = os.environ.get('HTTPS_PROXY')
+    if from_env:
+        return from_env
+    from_env = os.environ.get('https_proxy')
+    if from_env:
+        return from_env
+    return None
+
+
 def _parse(json_data):
     """Try and parse the JSON returned from Telegram.

{"golden_diff": "diff --git a/telegram/utils/request.py b/telegram/utils/request.py\n--- a/telegram/utils/request.py\n+++ b/telegram/utils/request.py\n@@ -19,6 +19,7 @@\n \"\"\"This module contains methods to make POST and GET requests\"\"\"\n \n import json\n+import os\n import socket\n import logging\n \n@@ -31,26 +32,41 @@\n \n _CON_POOL = None\n \"\"\":type: urllib3.PoolManager\"\"\"\n+_CON_POOL_PROXY = None\n+_CON_POOL_PROXY_KWARGS = {}\n CON_POOL_SIZE = 1\n \n logging.getLogger('urllib3').setLevel(logging.WARNING)\n \n \n def _get_con_pool():\n-    global _CON_POOL\n-\n     if _CON_POOL is not None:\n         return _CON_POOL\n \n-    _CON_POOL = urllib3.PoolManager(maxsize=CON_POOL_SIZE,\n-                                    cert_reqs='CERT_REQUIRED',\n-                                    ca_certs=certifi.where(),\n-                                    socket_options=HTTPConnection.default_socket_options + [\n-                                        (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),\n-                                    ])\n+    _init_con_pool()\n     return _CON_POOL\n \n \n+def _init_con_pool():\n+    global _CON_POOL\n+    kwargs = dict(maxsize=CON_POOL_SIZE,\n+                  cert_reqs='CERT_REQUIRED',\n+                  ca_certs=certifi.where(),\n+                  socket_options=HTTPConnection.default_socket_options + [\n+                      (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),\n+                  ])\n+    proxy_url = _get_con_pool_proxy()\n+    if not proxy_url:\n+        mgr = urllib3.PoolManager\n+    else:\n+        kwargs['proxy_url'] = proxy_url\n+        if _CON_POOL_PROXY_KWARGS:\n+            kwargs.update(_CON_POOL_PROXY_KWARGS)\n+        mgr = urllib3.ProxyManager\n+\n+    _CON_POOL = mgr(**kwargs)\n+\n+\n def is_con_pool_initialized():\n     return _CON_POOL is not None\n \n@@ -62,6 +78,47 @@\n         _CON_POOL = None\n \n \n+def set_con_pool_proxy(url, **urllib3_kwargs):\n+    \"\"\"Setup connection pool behind a proxy\n+\n+    Args:\n+        url (str): The URL to the proxy server. For example: `http://127.0.0.1:3128`\n+        urllib3_kwargs (dict): Arbitrary arguments passed as-is to `urllib3.ProxyManager`\n+\n+    \"\"\"\n+    global _CON_POOL_PROXY\n+    global _CON_POOL_PROXY_KWARGS\n+\n+    if is_con_pool_initialized():\n+        raise TelegramError('conpool already initialized')\n+\n+    _CON_POOL_PROXY = url\n+    _CON_POOL_PROXY_KWARGS = urllib3_kwargs\n+\n+\n+def _get_con_pool_proxy():\n+    \"\"\"Return the user configured proxy according to the following order:\n+\n+      * proxy configured using `set_con_pool_proxy()`.\n+      * proxy set in `HTTPS_PROXY` env. var.\n+      * proxy set in `https_proxy` env. var.\n+      * None (if no proxy is configured)\n+\n+      Returns:\n+          str | None\n+\n+    \"\"\"\n+    if _CON_POOL_PROXY:\n+        return _CON_POOL_PROXY\n+    from_env = os.environ.get('HTTPS_PROXY')\n+    if from_env:\n+        return from_env\n+    from_env = os.environ.get('https_proxy')\n+    if from_env:\n+        return from_env\n+    return None\n+\n+\n def _parse(json_data):\n     \"\"\"Try and parse the JSON returned from Telegram.\n", "issue": "since 4.3 can\u00b4t connect behind proxy\n<!--\nThanks for reporting issues of python-telegram-bot!\nTo make it easier for us to help you please enter detailed information below.\n-->\n### Steps to reproduce\n1. pip3 install python-telegram-bot --upgrade\n2. Don\u00b4t send anything\n3. pip3 install python-telegram-bot-4.2.1\n4. Works again!\n### Expected behaviour\n\nTell us what should happen\n### Actual behaviour\n\nTell us what happens instead\n### Configuration\n\n**Operating System:**\n\n**Version of Python:**\n\n`$ python -V` 3.5\n\n**Version of python-telegram-bot:**\n4.3.2,  4.2.1\n`$ python -c 'import telegram; print(telegram.__version__)'`\n### Logs\n\nInsert logs here (if necessary)\n\n", "before_files": [{"content": "#!/usr/bin/env python\n#\n# A library that provides a Python interface to the Telegram Bot API\n# Copyright (C) 2015-2016\n# Leandro Toledo de Souza <devs@python-telegram-bot.org>\n#\n# This program is free software: you can redistribute it and/or modify\n# it under the terms of the GNU Lesser Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU Lesser Public License for more details.\n#\n# You should have received a copy of the GNU Lesser Public License\n# along with this program.  If not, see [http://www.gnu.org/licenses/].\n\"\"\"This module contains methods to make POST and GET requests\"\"\"\n\nimport json\nimport socket\nimport logging\n\nimport certifi\nimport urllib3\nfrom urllib3.connection import HTTPConnection\n\nfrom telegram import (InputFile, TelegramError)\nfrom telegram.error import Unauthorized, NetworkError, TimedOut, BadRequest\n\n_CON_POOL = None\n\"\"\":type: urllib3.PoolManager\"\"\"\nCON_POOL_SIZE = 1\n\nlogging.getLogger('urllib3').setLevel(logging.WARNING)\n\n\ndef _get_con_pool():\n    global _CON_POOL\n\n    if _CON_POOL is not None:\n        return _CON_POOL\n\n    _CON_POOL = urllib3.PoolManager(maxsize=CON_POOL_SIZE,\n                                    cert_reqs='CERT_REQUIRED',\n                                    ca_certs=certifi.where(),\n                                    socket_options=HTTPConnection.default_socket_options + [\n                                        (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),\n                                    ])\n    return _CON_POOL\n\n\ndef is_con_pool_initialized():\n    return _CON_POOL is not None\n\n\ndef stop_con_pool():\n    global _CON_POOL\n    if _CON_POOL is not None:\n        _CON_POOL.clear()\n        _CON_POOL = None\n\n\ndef _parse(json_data):\n    \"\"\"Try and parse the JSON returned from Telegram.\n\n    Returns:\n        dict: A JSON parsed as Python dict with results - on error this dict will be empty.\n\n    \"\"\"\n    decoded_s = json_data.decode('utf-8')\n    try:\n        data = json.loads(decoded_s)\n    except ValueError:\n        raise TelegramError('Invalid server response')\n\n    if not data.get('ok') and data.get('description'):\n        return data['description']\n\n    return data['result']\n\n\ndef _request_wrapper(*args, **kwargs):\n    \"\"\"Wraps urllib3 request for handling known exceptions.\n\n    Args:\n        args: unnamed arguments, passed to urllib3 request.\n        kwargs: keyword arguments, passed tp urllib3 request.\n\n    Returns:\n        str: A non-parsed JSON text.\n\n    Raises:\n        TelegramError\n\n    \"\"\"\n\n    try:\n        resp = _get_con_pool().request(*args, **kwargs)\n    except urllib3.exceptions.TimeoutError as error:\n        raise TimedOut()\n    except urllib3.exceptions.HTTPError as error:\n        # HTTPError must come last as its the base urllib3 exception class\n        # TODO: do something smart here; for now just raise NetworkError\n        raise NetworkError('urllib3 HTTPError {0}'.format(error))\n\n    if 200 <= resp.status <= 299:\n        # 200-299 range are HTTP success statuses\n        return resp.data\n\n    try:\n        message = _parse(resp.data)\n    except ValueError:\n        raise NetworkError('Unknown HTTPError {0}'.format(resp.status))\n\n    if resp.status in (401, 403):\n        raise Unauthorized()\n    elif resp.status == 400:\n        raise BadRequest(repr(message))\n    elif resp.status == 502:\n        raise NetworkError('Bad Gateway')\n    else:\n        raise NetworkError('{0} ({1})'.format(message, resp.status))\n\n\ndef get(url):\n    \"\"\"Request an URL.\n    Args:\n      url:\n        The web location we want to retrieve.\n\n    Returns:\n      A JSON object.\n\n    \"\"\"\n    result = _request_wrapper('GET', url)\n\n    return _parse(result)\n\n\ndef post(url, data, timeout=None):\n    \"\"\"Request an URL.\n    Args:\n      url:\n        The web location we want to retrieve.\n      data:\n        A dict of (str, unicode) key/value pairs.\n      timeout:\n        float. If this value is specified, use it as the definitive timeout (in\n        seconds) for urlopen() operations. [Optional]\n\n    Notes:\n      If neither `timeout` nor `data['timeout']` is specified. The underlying\n      defaults are used.\n\n    Returns:\n      A JSON object.\n\n    \"\"\"\n    urlopen_kwargs = {}\n\n    if timeout is not None:\n        urlopen_kwargs['timeout'] = timeout\n\n    if InputFile.is_inputfile(data):\n        data = InputFile(data)\n        result = _request_wrapper('POST', url, body=data.to_form(), headers=data.headers)\n    else:\n        data = json.dumps(data)\n        result = _request_wrapper('POST',\n                                  url,\n                                  body=data.encode(),\n                                  headers={'Content-Type': 'application/json'},\n                                  **urlopen_kwargs)\n\n    return _parse(result)\n\n\ndef download(url, filename):\n    \"\"\"Download a file by its URL.\n    Args:\n      url:\n        The web location we want to retrieve.\n\n      filename:\n        The filename within the path to download the file.\n\n    \"\"\"\n    buf = _request_wrapper('GET', url)\n    with open(filename, 'wb') as fobj:\n        fobj.write(buf)\n", "path": "telegram/utils/request.py"}], "after_files": [{"content": "#!/usr/bin/env python\n#\n# A library that provides a Python interface to the Telegram Bot API\n# Copyright (C) 2015-2016\n# Leandro Toledo de Souza <devs@python-telegram-bot.org>\n#\n# This program is free software: you can redistribute it and/or modify\n# it under the terms of the GNU Lesser Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU Lesser Public License for more details.\n#\n# You should have received a copy of the GNU Lesser Public License\n# along with this program.  If not, see [http://www.gnu.org/licenses/].\n\"\"\"This module contains methods to make POST and GET requests\"\"\"\n\nimport json\nimport os\nimport socket\nimport logging\n\nimport certifi\nimport urllib3\nfrom urllib3.connection import HTTPConnection\n\nfrom telegram import (InputFile, TelegramError)\nfrom telegram.error import Unauthorized, NetworkError, TimedOut, BadRequest\n\n_CON_POOL = None\n\"\"\":type: urllib3.PoolManager\"\"\"\n_CON_POOL_PROXY = None\n_CON_POOL_PROXY_KWARGS = {}\nCON_POOL_SIZE = 1\n\nlogging.getLogger('urllib3').setLevel(logging.WARNING)\n\n\ndef _get_con_pool():\n    if _CON_POOL is not None:\n        return _CON_POOL\n\n    _init_con_pool()\n    return _CON_POOL\n\n\ndef _init_con_pool():\n    global _CON_POOL\n    kwargs = dict(maxsize=CON_POOL_SIZE,\n                  cert_reqs='CERT_REQUIRED',\n                  ca_certs=certifi.where(),\n                  socket_options=HTTPConnection.default_socket_options + [\n                      (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),\n                  ])\n    proxy_url = _get_con_pool_proxy()\n    if not proxy_url:\n        mgr = urllib3.PoolManager\n    else:\n        kwargs['proxy_url'] = proxy_url\n        if _CON_POOL_PROXY_KWARGS:\n            kwargs.update(_CON_POOL_PROXY_KWARGS)\n        mgr = urllib3.ProxyManager\n\n    _CON_POOL = mgr(**kwargs)\n\n\ndef is_con_pool_initialized():\n    return _CON_POOL is not None\n\n\ndef stop_con_pool():\n    global _CON_POOL\n    if _CON_POOL is not None:\n        _CON_POOL.clear()\n        _CON_POOL = None\n\n\ndef set_con_pool_proxy(url, **urllib3_kwargs):\n    \"\"\"Setup connection pool behind a proxy\n\n    Args:\n        url (str): The URL to the proxy server. For example: `http://127.0.0.1:3128`\n        urllib3_kwargs (dict): Arbitrary arguments passed as-is to `urllib3.ProxyManager`\n\n    \"\"\"\n    global _CON_POOL_PROXY\n    global _CON_POOL_PROXY_KWARGS\n\n    if is_con_pool_initialized():\n        raise TelegramError('conpool already initialized')\n\n    _CON_POOL_PROXY = url\n    _CON_POOL_PROXY_KWARGS = urllib3_kwargs\n\n\ndef _get_con_pool_proxy():\n    \"\"\"Return the user configured proxy according to the following order:\n\n      * proxy configured using `set_con_pool_proxy()`.\n      * proxy set in `HTTPS_PROXY` env. var.\n      * proxy set in `https_proxy` env. var.\n      * None (if no proxy is configured)\n\n      Returns:\n          str | None\n\n    \"\"\"\n    if _CON_POOL_PROXY:\n        return _CON_POOL_PROXY\n    from_env = os.environ.get('HTTPS_PROXY')\n    if from_env:\n        return from_env\n    from_env = os.environ.get('https_proxy')\n    if from_env:\n        return from_env\n    return None\n\n\ndef _parse(json_data):\n    \"\"\"Try and parse the JSON returned from Telegram.\n\n    Returns:\n        dict: A JSON parsed as Python dict with results - on error this dict will be empty.\n\n    \"\"\"\n    decoded_s = json_data.decode('utf-8')\n    try:\n        data = json.loads(decoded_s)\n    except ValueError:\n        raise TelegramError('Invalid server response')\n\n    if not data.get('ok') and data.get('description'):\n        return data['description']\n\n    return data['result']\n\n\ndef _request_wrapper(*args, **kwargs):\n    \"\"\"Wraps urllib3 request for handling known exceptions.\n\n    Args:\n        args: unnamed arguments, passed to urllib3 request.\n        kwargs: keyword arguments, passed tp urllib3 request.\n\n    Returns:\n        str: A non-parsed JSON text.\n\n    Raises:\n        TelegramError\n\n    \"\"\"\n\n    try:\n        resp = _get_con_pool().request(*args, **kwargs)\n    except urllib3.exceptions.TimeoutError as error:\n        raise TimedOut()\n    except urllib3.exceptions.HTTPError as error:\n        # HTTPError must come last as its the base urllib3 exception class\n        # TODO: do something smart here; for now just raise NetworkError\n        raise NetworkError('urllib3 HTTPError {0}'.format(error))\n\n    if 200 <= resp.status <= 299:\n        # 200-299 range are HTTP success statuses\n        return resp.data\n\n    try:\n        message = _parse(resp.data)\n    except ValueError:\n        raise NetworkError('Unknown HTTPError {0}'.format(resp.status))\n\n    if resp.status in (401, 403):\n        raise Unauthorized()\n    elif resp.status == 400:\n        raise BadRequest(repr(message))\n    elif resp.status == 502:\n        raise NetworkError('Bad Gateway')\n    else:\n        raise NetworkError('{0} ({1})'.format(message, resp.status))\n\n\ndef get(url):\n    \"\"\"Request an URL.\n    Args:\n      url:\n        The web location we want to retrieve.\n\n    Returns:\n      A JSON object.\n\n    \"\"\"\n    result = _request_wrapper('GET', url)\n\n    return _parse(result)\n\n\ndef post(url, data, timeout=None):\n    \"\"\"Request an URL.\n    Args:\n      url:\n        The web location we want to retrieve.\n      data:\n        A dict of (str, unicode) key/value pairs.\n      timeout:\n        float. If this value is specified, use it as the definitive timeout (in\n        seconds) for urlopen() operations. [Optional]\n\n    Notes:\n      If neither `timeout` nor `data['timeout']` is specified. The underlying\n      defaults are used.\n\n    Returns:\n      A JSON object.\n\n    \"\"\"\n    urlopen_kwargs = {}\n\n    if timeout is not None:\n        urlopen_kwargs['timeout'] = timeout\n\n    if InputFile.is_inputfile(data):\n        data = InputFile(data)\n        result = _request_wrapper('POST', url, body=data.to_form(), headers=data.headers)\n    else:\n        data = json.dumps(data)\n        result = _request_wrapper('POST',\n                                  url,\n                                  body=data.encode(),\n                                  headers={'Content-Type': 'application/json'},\n                                  **urlopen_kwargs)\n\n    return _parse(result)\n\n\ndef download(url, filename):\n    \"\"\"Download a file by its URL.\n    Args:\n      url:\n        The web location we want to retrieve.\n\n      filename:\n        The filename within the path to download the file.\n\n    \"\"\"\n    buf = _request_wrapper('GET', url)\n    with open(filename, 'wb') as fobj:\n        fobj.write(buf)\n", "path": "telegram/utils/request.py"}]}