Repository: elastic/apm-agent-python

Issue:
Transaction.Response.StatusCode is expected to be Number not String
I experienced an `error` being sent to the `transactions` endpoint. It clearly happened in a development scenario, when I applied a change in a running Django app. Feel free to disregard this 'bug' report if it cannot happen in a 'real-world-scenario'.

Django console logging:
```
HTTP 400:
Failed to submit message: '<no message value>'
Traceback (most recent call last):
  File "/Users/simitt/.pyenv/versions/django-test-3.6.2/lib/python3.6/site-packages/elasticapm/transport/http_urllib3.py", line 75, in send_sync
    url = Urllib3Transport.send(self, data, headers)
  File "/Users/simitt/.pyenv/versions/django-test-3.6.2/lib/python3.6/site-packages/elasticapm/transport/http_urllib3.py", line 61, in send
    raise TransportException(message, data, print_trace=print_trace)
elasticapm.transport.base.TransportException: HTTP 400:
```

APM Server logging:
```
  I[#/transactions/0/context/response/status_code] S[#/properties/transactions/items/properties/context/properties/response/properties/status_code/type] expected number or null, but got string, code=400
```


Discussion:
Hmm, we actually turn the status code into a string, is that wrong?

https://github.com/elastic/apm-agent-python/blob/901ff92c12cea50c6f2e8ec659fe1fb52d9498da/elasticapm/contrib/django/client.py#L159
In the current version it is expected to be a [number](https://github.com/elastic/apm-server/blob/master/docs/spec/context.json#L35).

But we could also implement it to allow `number,string,null` as we do for [error.exception.code](https://github.com/elastic/apm-server/blob/master/docs/spec/errors/error.json#L18).
But in either case, shouldn't the exception above be rather sent to the `errors` endpoint than to the `transactions` endpoint?
I don't think this was an exception, but a transaction, and during sending of the transaction, an error happened.
I updated the title. After trying to monitor performance requests I figured out that this is a general issue sending transactions. This seems to be urgent, since no performance data including a `response.status_code` can be processed right now on the APM server.

Resolving patch:
diff --git a/elasticapm/contrib/django/client.py b/elasticapm/contrib/django/client.py
--- a/elasticapm/contrib/django/client.py
+++ b/elasticapm/contrib/django/client.py
@@ -156,7 +156,7 @@ def get_data_from_request(self, request):
         return result
 
     def get_data_from_response(self, response):
-        result = {'status_code': str(response.status_code)}
+        result = {'status_code': response.status_code}
 
         # Django does not expose a public API to iterate over the headers of a response.
         # Unfortunately, we have to access the private _headers dictionary here, which is


Test patch:
diff --git a/tests/contrib/django/django_tests.py b/tests/contrib/django/django_tests.py
--- a/tests/contrib/django/django_tests.py
+++ b/tests/contrib/django/django_tests.py
@@ -656,7 +656,7 @@ def test_transaction_request_response_data(self):
 
         assert 'response' in transaction['context']
         response = transaction['context']['response']
-        assert response['status_code'] == '200'
+        assert response['status_code'] == 200
         assert response['headers']['my-header'] == 'foo'
 
     def test_transaction_metrics(self):