Repository: elastic/apm-agent-python

Issue:
Docker Python no longer working as soon as elastic-apm is installed
**Describe the bug**
It seems like some patches to requests destroy the functionality of the docker python package.

ValueError: invalid literal for int() with base 10: 'None'

```
Traceback (most recent call last):
  File "project\venv\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
    response = get_response(request)
  File "project\venv\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "project\venv\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "project\tool\src\company_tool\web\api\decorators.py", line 21, in wrapper_view_func
    return view_func(request, json_data=data, *args, **kwargs)
  File "project\venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "project\venv\lib\site-packages\django\views\decorators\http.py", line 40, in inner
    return func(request, *args, **kwargs)
  File "project\tool\src\company_tool\web\api\views.py", line 27, in start
    container_status = client.containers.run(image=container, command=arguments, detach=True, stdin_open=True, tty=True)
  File "project\venv\lib\site-packages\docker\models\containers.py", line 802, in run
    container = self.create(image=image, command=command,
  File "project\venv\lib\site-packages\docker\models\containers.py", line 861, in create
    resp = self.client.api.create_container(**create_kwargs)
  File "project\venv\lib\site-packages\docker\api\container.py", line 430, in create_container
    return self.create_container_from_config(config, name)
  File "project\venv\lib\site-packages\docker\api\container.py", line 440, in create_container_from_config
    res = self._post_json(u, data=config, params=params)
  File "project\venv\lib\site-packages\docker\api\client.py", line 289, in _post_json
    return self._post(url, data=json.dumps(data2), **kwargs)
  File "project\venv\lib\site-packages\docker\utils\decorators.py", line 46, in inner
    return f(self, *args, **kwargs)
  File "project\venv\lib\site-packages\docker\api\client.py", line 226, in _post
    return self.post(url, **self._set_request_timeout(kwargs))
  File "project\venv\lib\site-packages\requests\sessions.py", line 578, in post
    return self.request('POST', url, data=data, json=json, **kwargs)
  File "project\venv\lib\site-packages\requests\sessions.py", line 530, in request
    resp = self.send(prep, **send_kwargs)
  File "project\venv\lib\site-packages\elasticapm\utils\wrapt\wrappers.py", line 561, in __call__
    return self._self_wrapper(self.__wrapped__, self._self_instance,
  File "project\venv\lib\site-packages\elasticapm\instrumentation\packages\base.py", line 210, in call_if_sampling
    return self.call(module, method, wrapped, instance, args, kwargs)
  File "project\venv\lib\site-packages\elasticapm\instrumentation\packages\requests.py", line 59, in call
    return wrapped(*args, **kwargs)
  File "project\venv\lib\site-packages\requests\sessions.py", line 643, in send
    r = adapter.send(request, **kwargs)
  File "project\venv\lib\site-packages\requests\adapters.py", line 439, in send
    resp = conn.urlopen(
  File "project\venv\lib\site-packages\elasticapm\utils\wrapt\wrappers.py", line 561, in __call__
    return self._self_wrapper(self.__wrapped__, self._self_instance,
  File "project\venv\lib\site-packages\elasticapm\instrumentation\packages\base.py", line 210, in call_if_sampling
    return self.call(module, method, wrapped, instance, args, kwargs)
  File "project\venv\lib\site-packages\elasticapm\instrumentation\packages\urllib3.py", line 74, in call
    destination = url_to_destination(url)
  File "project\venv\lib\site-packages\elasticapm\utils\__init__.py", line 146, in url_to_destination
    port = parts.port
  File "C:\Python38\lib\urllib\parse.py", line 174, in port
    raise ValueError(message) from None
ValueError: Port could not be cast to integer value as 'None'
```

**To Reproduce**
Steps to reproduce the behavior:
1. Install "docker" and "elastic-apm" python package within a django app
2. Load APM using default django config
2. Try to use docker 

**Expected behavior**
Docker still works






Discussion:
Hello @Patralos! I took the liberty of transferring your issue to the `apm-agent-python` repo, since it's python-specific. We appreciate the report and I'm going to look into this today or tomorrow.

Resolving patch:
diff --git a/elasticapm/utils/__init__.py b/elasticapm/utils/__init__.py
--- a/elasticapm/utils/__init__.py
+++ b/elasticapm/utils/__init__.py
@@ -143,7 +143,11 @@ def url_to_destination(url, service_type="external"):
     # preserve brackets for IPv6 URLs
     if "://[" in url:
         hostname = "[%s]" % hostname
-    port = parts.port
+    try:
+        port = parts.port
+    except ValueError:
+        # Malformed port, just use None rather than raising an exception
+        port = None
     default_port = default_ports.get(parts.scheme, None)
     name = "%s://%s" % (parts.scheme, hostname)
     resource = hostname


Test patch:
diff --git a/tests/utils/tests.py b/tests/utils/tests.py
--- a/tests/utils/tests.py
+++ b/tests/utils/tests.py
@@ -214,3 +214,8 @@ def test_url_to_destination(url, name, resource):
     destination = url_to_destination(url)
     assert destination["service"]["name"] == name
     assert destination["service"]["resource"] == resource
+
+
+def test_url_to_destination_bad_port():
+    destination = url_to_destination("https://www.elastic.co:bad")
+    assert destination["service"]["resource"] == "www.elastic.co:443"