Repository: minio/minio-py

Issue:
Minio rejects valid hostnames
The Minio python library rejects hostnames with underscores in them. Since this is a standard separator for docker container names, this causes problems when trying to run Minio as part of a docker compose setup.

For example, with a linked container named `minio_server`, this python session should not raise an error:
```
Python 3.6.8 (default, Mar 27 2019, 08:53:45) 
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from minio import Minio
>>> Minio('minio_server:9000')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.6/site-packages/minio/api.py", line 147, in __init__
    is_valid_endpoint(endpoint)
  File "/usr/local/lib/python3.6/site-packages/minio/helpers.py", line 299, in is_valid_endpoint
    raise InvalidEndpointError('Hostname does not meet URL standards.')
minio.error.InvalidEndpointError: InvalidEndpointError: message: Hostname does not meet URL standards.
```

Discussion:
kannappanr: @Praveenrajmani Please fix the Appveyor build failures
Praveenrajmani: looks like an installation failure. will push again @kannappanr 
kannappanr: ping @nitisht 

Patch:
diff --git a/appveyor.yml b/appveyor.yml
index f6ac53e..c301941 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -7,7 +7,7 @@ environment:
 
 install:
   # We need wheel installed to build wheels
-  - "%PYTHON%\\python.exe -m pip install wheel faker nose"
+  - "%PYTHON%\\python.exe -m pip install wheel faker nose mock"
   - "%PYTHON%\\python.exe setup.py install"
 
 build: off
diff --git a/minio/helpers.py b/minio/helpers.py
index 69881c7..9151b93 100644
--- a/minio/helpers.py
+++ b/minio/helpers.py
@@ -53,7 +53,7 @@ DEFAULT_PART_SIZE = MIN_PART_SIZE # Currently its 5MiB
 
 _VALID_BUCKETNAME_REGEX = re.compile('^[a-z0-9][a-z0-9\\.\\-]+[a-z0-9]$')
 _ALLOWED_HOSTNAME_REGEX = re.compile(
-    '^((?!-)[A-Z\\d-]{1,63}(?<!-)\\.)*((?!-)[A-Z\\d-]{1,63}(?<!-))$',
+    '^((?!-)(?!_)[A-Z\_\\d-]{1,63}(?<!-)(?<!_)\\.)*((?!_)(?!-)[A-Z\_\\d-]{1,63}(?<!-)(?<!_))$',
     re.IGNORECASE)
 
 _EXTRACT_REGION_REGEX = re.compile('s3[.-]?(.+?).amazonaws.com')


Test patch:
diff --git a/tests/unit/get_s3_endpoint_test.py b/tests/unit/get_s3_endpoint_test.py
index 7d3c943..ce536c3 100644
--- a/tests/unit/get_s3_endpoint_test.py
+++ b/tests/unit/get_s3_endpoint_test.py
@@ -27,3 +27,6 @@ class GetS3Endpoint(TestCase):
     def test_is_valid_endpoint(self):
         eq_(True, is_valid_endpoint('s3.amazonaws.com'))
         eq_(True, is_valid_endpoint('s3.cn-north-1.amazonaws.com.cn'))
+        eq_(True, is_valid_endpoint('minio_server:9000'))
+        eq_(True, is_valid_endpoint('s3.server_1.amazonaws.com'))
+