Repository: elastic/apm-agent-python

Issue:
AttributeError: 'NoneType' object has no attribute 'config' in Flask Agent
**Describe the bug**: By using the flask agent and opting to [build the application on the fly](https://www.elastic.co/guide/en/apm/agent/python/current/flask-support.html#flask-building-applications-on-the-fly) an error occurs  **AttributeError: 'NoneType' object has no attribute 'config'**.

**To Reproduce**

1. run the following
```python
from elasticapm.contrib.flask import ElasticAPM
from flask import Flask
apm = ElasticAPM()

app = Flask(__name__)
apm.init_app(app)
```

**Environment (please complete the following information)**
- OS: Linux
- Python version: 3.8.5
- Framework and version: Flask 1.1.2 
- APM Server version: NA
- Agent version: NA


**Additional context**

This error does not happen with version 6.0.0. This bug seems to be incorporated into the project in the [PR-1043](https://github.com/elastic/apm-agent-python/pull/1043) with the removal from the [if statement L128 - L129](https://github.com/elastic/apm-agent-python/pull/1043/files#diff-f7d7281cc8ddf8897f2fe37e9ad1facc0aefb57bdda156a5de603db46d1d9b1eL128-L129) in the `init_app()` method that would initiate a possible NoneType client. Based on the efforts of the [PR-1043](https://github.com/elastic/apm-agent-python/pull/1043) to make the client global, it would ideally be initiated in the constructor from the class ElasticAPM. That would only apply [if there's an existent app](https://github.com/elastic/apm-agent-python/pull/1043/files#diff-f7d7281cc8ddf8897f2fe37e9ad1facc0aefb57bdda156a5de603db46d1d9b1eL103) which does not happen if the user opted to [build the application on the fly](https://www.elastic.co/guide/en/apm/agent/python/current/flask-support.html#flask-building-applications-on-the-fly).


Discussion:

Resolving patch:
diff --git a/elasticapm/contrib/flask/__init__.py b/elasticapm/contrib/flask/__init__.py
--- a/elasticapm/contrib/flask/__init__.py
+++ b/elasticapm/contrib/flask/__init__.py
@@ -88,17 +88,9 @@ def __init__(self, app=None, client=None, client_cls=Client, logging=False, **de
         self.app = app
         self.logging = logging
         self.client = client or get_client()
+        self.client_cls = client_cls
 
         if app:
-            if not self.client:
-                config = app.config.get("ELASTIC_APM", {})
-
-                if "framework_name" not in defaults:
-                    defaults["framework_name"] = "flask"
-                    defaults["framework_version"] = getattr(flask, "__version__", "<0.7")
-
-                self.client = client_cls(config, **defaults)
-
             self.init_app(app, **defaults)
 
     def handle_exception(self, *args, **kwargs):
@@ -123,6 +115,14 @@ def handle_exception(self, *args, **kwargs):
 
     def init_app(self, app, **defaults):
         self.app = app
+        if not self.client:
+            config = self.app.config.get("ELASTIC_APM", {})
+
+            if "framework_name" not in defaults:
+                defaults["framework_name"] = "flask"
+                defaults["framework_version"] = getattr(flask, "__version__", "<0.7")
+
+            self.client = self.client_cls(config, **defaults)
 
         # 0 is a valid log level (NOTSET), so we need to check explicitly for it
         if self.logging or self.logging is logging.NOTSET:


Test patch: