We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
username and email deesn't get included even though send_default_pii=True
I am running Flask app with Flask-Login. According to https://docs.sentry.io/platforms/python/flask/:

> If you use flask-login and have set send_default_pii=True in your call to init, user data (current user id,
> email address, username) is attached to the event.

I have set send_default_pii=True. However, the event notification payload doesn't contain username and email. It contains only ID and IP Address:

```json
user: {
ip_address: "127.0.0.1",
id: "2"
}
```

UI show "?" on the "User" section implying that there could be some extra info but it appears to be static (no link, no popup):

![2019-02-13 12-13-59](https://user-images.githubusercontent.com/177266/52674667-2c31d880-2f89-11e9-8f83-348c8a902aaa.png)




--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `sentry_sdk/integrations/flask.py`
Content:
```
1 from __future__ import absolute_import
2 
3 import weakref
4 
5 from sentry_sdk.hub import Hub, _should_send_default_pii
6 from sentry_sdk.utils import capture_internal_exceptions, event_from_exception
7 from sentry_sdk.integrations import Integration
8 from sentry_sdk.integrations.wsgi import SentryWsgiMiddleware
9 from sentry_sdk.integrations._wsgi_common import RequestExtractor
10 
11 try:
12     import flask_login
13 except ImportError:
14     flask_login = None
15 
16 from flask import Flask, _request_ctx_stack, _app_ctx_stack
17 from flask.signals import (
18     appcontext_pushed,
19     appcontext_tearing_down,
20     got_request_exception,
21     request_started,
22 )
23 
24 
25 class FlaskIntegration(Integration):
26     identifier = "flask"
27 
28     transaction_style = None
29 
30     def __init__(self, transaction_style="endpoint"):
31         TRANSACTION_STYLE_VALUES = ("endpoint", "url")
32         if transaction_style not in TRANSACTION_STYLE_VALUES:
33             raise ValueError(
34                 "Invalid value for transaction_style: %s (must be in %s)"
35                 % (transaction_style, TRANSACTION_STYLE_VALUES)
36             )
37         self.transaction_style = transaction_style
38 
39     @staticmethod
40     def setup_once():
41         appcontext_pushed.connect(_push_appctx)
42         appcontext_tearing_down.connect(_pop_appctx)
43         request_started.connect(_request_started)
44         got_request_exception.connect(_capture_exception)
45 
46         old_app = Flask.__call__
47 
48         def sentry_patched_wsgi_app(self, environ, start_response):
49             if Hub.current.get_integration(FlaskIntegration) is None:
50                 return old_app(self, environ, start_response)
51 
52             return SentryWsgiMiddleware(lambda *a, **kw: old_app(self, *a, **kw))(
53                 environ, start_response
54             )
55 
56         Flask.__call__ = sentry_patched_wsgi_app
57 
58 
59 def _push_appctx(*args, **kwargs):
60     hub = Hub.current
61     if hub.get_integration(FlaskIntegration) is not None:
62         # always want to push scope regardless of whether WSGI app might already
63         # have (not the case for CLI for example)
64         scope_manager = hub.push_scope()
65         scope_manager.__enter__()
66         _app_ctx_stack.top.sentry_sdk_scope_manager = scope_manager
67         with hub.configure_scope() as scope:
68             scope._name = "flask"
69 
70 
71 def _pop_appctx(*args, **kwargs):
72     scope_manager = getattr(_app_ctx_stack.top, "sentry_sdk_scope_manager", None)
73     if scope_manager is not None:
74         scope_manager.__exit__(None, None, None)
75 
76 
77 def _request_started(sender, **kwargs):
78     hub = Hub.current
79     integration = hub.get_integration(FlaskIntegration)
80     if integration is None:
81         return
82 
83     weak_request = weakref.ref(_request_ctx_stack.top.request)
84     app = _app_ctx_stack.top.app
85     with hub.configure_scope() as scope:
86         scope.add_event_processor(
87             _make_request_event_processor(app, weak_request, integration)
88         )
89 
90 
91 class FlaskRequestExtractor(RequestExtractor):
92     def env(self):
93         return self.request.environ
94 
95     def cookies(self):
96         return self.request.cookies
97 
98     def raw_data(self):
99         return self.request.data
100 
101     def form(self):
102         return self.request.form
103 
104     def files(self):
105         return self.request.files
106 
107     def size_of_file(self, file):
108         return file.content_length
109 
110 
111 def _make_request_event_processor(app, weak_request, integration):
112     def inner(event, hint):
113         request = weak_request()
114 
115         # if the request is gone we are fine not logging the data from
116         # it.  This might happen if the processor is pushed away to
117         # another thread.
118         if request is None:
119             return event
120 
121         try:
122             if integration.transaction_style == "endpoint":
123                 event["transaction"] = request.url_rule.endpoint
124             elif integration.transaction_style == "url":
125                 event["transaction"] = request.url_rule.rule
126         except Exception:
127             pass
128 
129         with capture_internal_exceptions():
130             FlaskRequestExtractor(request).extract_into_event(event)
131 
132         if _should_send_default_pii():
133             with capture_internal_exceptions():
134                 _add_user_to_event(event)
135 
136         return event
137 
138     return inner
139 
140 
141 def _capture_exception(sender, exception, **kwargs):
142     hub = Hub.current
143     if hub.get_integration(FlaskIntegration) is None:
144         return
145     event, hint = event_from_exception(
146         exception,
147         client_options=hub.client.options,
148         mechanism={"type": "flask", "handled": False},
149     )
150 
151     hub.capture_event(event, hint=hint)
152 
153 
154 def _add_user_to_event(event):
155     if flask_login is None:
156         return
157 
158     user = flask_login.current_user
159     if user is None:
160         return
161 
162     with capture_internal_exceptions():
163         # Access this object as late as possible as accessing the user
164         # is relatively costly
165 
166         user_info = event.setdefault("user", {})
167 
168         try:
169             user_info["id"] = user.get_id()
170             # TODO: more configurable user attrs here
171         except AttributeError:
172             # might happen if:
173             # - flask_login could not be imported
174             # - flask_login is not configured
175             # - no user is logged in
176             pass
177
```
--- 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/sentry_sdk/integrations/flask.py b/sentry_sdk/integrations/flask.py
--- a/sentry_sdk/integrations/flask.py
+++ b/sentry_sdk/integrations/flask.py
@@ -174,3 +174,20 @@
             # - flask_login is not configured
             # - no user is logged in
             pass
+
+        # The following attribute accesses are ineffective for the general
+        # Flask-Login case, because the User interface of Flask-Login does not
+        # care about anything but the ID. However, Flask-User (based on
+        # Flask-Login) documents a few optional extra attributes.
+        #
+        # https://github.com/lingthio/Flask-User/blob/a379fa0a281789618c484b459cb41236779b95b1/docs/source/data_models.rst#fixed-data-model-property-names
+
+        try:
+            user_info["email"] = user_info["username"] = user.email
+        except Exception:
+            pass
+
+        try:
+            user_info["username"] = user.username
+        except Exception:
+            pass

{"golden_diff": "diff --git a/sentry_sdk/integrations/flask.py b/sentry_sdk/integrations/flask.py\n--- a/sentry_sdk/integrations/flask.py\n+++ b/sentry_sdk/integrations/flask.py\n@@ -174,3 +174,20 @@\n             # - flask_login is not configured\n             # - no user is logged in\n             pass\n+\n+        # The following attribute accesses are ineffective for the general\n+        # Flask-Login case, because the User interface of Flask-Login does not\n+        # care about anything but the ID. However, Flask-User (based on\n+        # Flask-Login) documents a few optional extra attributes.\n+        #\n+        # https://github.com/lingthio/Flask-User/blob/a379fa0a281789618c484b459cb41236779b95b1/docs/source/data_models.rst#fixed-data-model-property-names\n+\n+        try:\n+            user_info[\"email\"] = user_info[\"username\"] = user.email\n+        except Exception:\n+            pass\n+\n+        try:\n+            user_info[\"username\"] = user.username\n+        except Exception:\n+            pass\n", "issue": "username and email deesn't get included even though send_default_pii=True\nI am running Flask app with Flask-Login. According to https://docs.sentry.io/platforms/python/flask/:\r\n\r\n> If you use flask-login and have set send_default_pii=True in your call to init, user data (current user id,\r\n> email address, username) is attached to the event.\r\n\r\nI have set send_default_pii=True. However, the event notification payload doesn't contain username and email. It contains only ID and IP Address:\r\n\r\n```json\r\nuser: {\r\nip_address: \"127.0.0.1\",\r\nid: \"2\"\r\n}\r\n```\r\n\r\nUI show \"?\" on the \"User\" section implying that there could be some extra info but it appears to be static (no link, no popup):\r\n\r\n![2019-02-13 12-13-59](https://user-images.githubusercontent.com/177266/52674667-2c31d880-2f89-11e9-8f83-348c8a902aaa.png)\r\n\r\n\r\n\n", "before_files": [{"content": "from __future__ import absolute_import\n\nimport weakref\n\nfrom sentry_sdk.hub import Hub, _should_send_default_pii\nfrom sentry_sdk.utils import capture_internal_exceptions, event_from_exception\nfrom sentry_sdk.integrations import Integration\nfrom sentry_sdk.integrations.wsgi import SentryWsgiMiddleware\nfrom sentry_sdk.integrations._wsgi_common import RequestExtractor\n\ntry:\n    import flask_login\nexcept ImportError:\n    flask_login = None\n\nfrom flask import Flask, _request_ctx_stack, _app_ctx_stack\nfrom flask.signals import (\n    appcontext_pushed,\n    appcontext_tearing_down,\n    got_request_exception,\n    request_started,\n)\n\n\nclass FlaskIntegration(Integration):\n    identifier = \"flask\"\n\n    transaction_style = None\n\n    def __init__(self, transaction_style=\"endpoint\"):\n        TRANSACTION_STYLE_VALUES = (\"endpoint\", \"url\")\n        if transaction_style not in TRANSACTION_STYLE_VALUES:\n            raise ValueError(\n                \"Invalid value for transaction_style: %s (must be in %s)\"\n                % (transaction_style, TRANSACTION_STYLE_VALUES)\n            )\n        self.transaction_style = transaction_style\n\n    @staticmethod\n    def setup_once():\n        appcontext_pushed.connect(_push_appctx)\n        appcontext_tearing_down.connect(_pop_appctx)\n        request_started.connect(_request_started)\n        got_request_exception.connect(_capture_exception)\n\n        old_app = Flask.__call__\n\n        def sentry_patched_wsgi_app(self, environ, start_response):\n            if Hub.current.get_integration(FlaskIntegration) is None:\n                return old_app(self, environ, start_response)\n\n            return SentryWsgiMiddleware(lambda *a, **kw: old_app(self, *a, **kw))(\n                environ, start_response\n            )\n\n        Flask.__call__ = sentry_patched_wsgi_app\n\n\ndef _push_appctx(*args, **kwargs):\n    hub = Hub.current\n    if hub.get_integration(FlaskIntegration) is not None:\n        # always want to push scope regardless of whether WSGI app might already\n        # have (not the case for CLI for example)\n        scope_manager = hub.push_scope()\n        scope_manager.__enter__()\n        _app_ctx_stack.top.sentry_sdk_scope_manager = scope_manager\n        with hub.configure_scope() as scope:\n            scope._name = \"flask\"\n\n\ndef _pop_appctx(*args, **kwargs):\n    scope_manager = getattr(_app_ctx_stack.top, \"sentry_sdk_scope_manager\", None)\n    if scope_manager is not None:\n        scope_manager.__exit__(None, None, None)\n\n\ndef _request_started(sender, **kwargs):\n    hub = Hub.current\n    integration = hub.get_integration(FlaskIntegration)\n    if integration is None:\n        return\n\n    weak_request = weakref.ref(_request_ctx_stack.top.request)\n    app = _app_ctx_stack.top.app\n    with hub.configure_scope() as scope:\n        scope.add_event_processor(\n            _make_request_event_processor(app, weak_request, integration)\n        )\n\n\nclass FlaskRequestExtractor(RequestExtractor):\n    def env(self):\n        return self.request.environ\n\n    def cookies(self):\n        return self.request.cookies\n\n    def raw_data(self):\n        return self.request.data\n\n    def form(self):\n        return self.request.form\n\n    def files(self):\n        return self.request.files\n\n    def size_of_file(self, file):\n        return file.content_length\n\n\ndef _make_request_event_processor(app, weak_request, integration):\n    def inner(event, hint):\n        request = weak_request()\n\n        # if the request is gone we are fine not logging the data from\n        # it.  This might happen if the processor is pushed away to\n        # another thread.\n        if request is None:\n            return event\n\n        try:\n            if integration.transaction_style == \"endpoint\":\n                event[\"transaction\"] = request.url_rule.endpoint\n            elif integration.transaction_style == \"url\":\n                event[\"transaction\"] = request.url_rule.rule\n        except Exception:\n            pass\n\n        with capture_internal_exceptions():\n            FlaskRequestExtractor(request).extract_into_event(event)\n\n        if _should_send_default_pii():\n            with capture_internal_exceptions():\n                _add_user_to_event(event)\n\n        return event\n\n    return inner\n\n\ndef _capture_exception(sender, exception, **kwargs):\n    hub = Hub.current\n    if hub.get_integration(FlaskIntegration) is None:\n        return\n    event, hint = event_from_exception(\n        exception,\n        client_options=hub.client.options,\n        mechanism={\"type\": \"flask\", \"handled\": False},\n    )\n\n    hub.capture_event(event, hint=hint)\n\n\ndef _add_user_to_event(event):\n    if flask_login is None:\n        return\n\n    user = flask_login.current_user\n    if user is None:\n        return\n\n    with capture_internal_exceptions():\n        # Access this object as late as possible as accessing the user\n        # is relatively costly\n\n        user_info = event.setdefault(\"user\", {})\n\n        try:\n            user_info[\"id\"] = user.get_id()\n            # TODO: more configurable user attrs here\n        except AttributeError:\n            # might happen if:\n            # - flask_login could not be imported\n            # - flask_login is not configured\n            # - no user is logged in\n            pass\n", "path": "sentry_sdk/integrations/flask.py"}], "after_files": [{"content": "from __future__ import absolute_import\n\nimport weakref\n\nfrom sentry_sdk.hub import Hub, _should_send_default_pii\nfrom sentry_sdk.utils import capture_internal_exceptions, event_from_exception\nfrom sentry_sdk.integrations import Integration\nfrom sentry_sdk.integrations.wsgi import SentryWsgiMiddleware\nfrom sentry_sdk.integrations._wsgi_common import RequestExtractor\n\ntry:\n    import flask_login\nexcept ImportError:\n    flask_login = None\n\nfrom flask import Flask, _request_ctx_stack, _app_ctx_stack\nfrom flask.signals import (\n    appcontext_pushed,\n    appcontext_tearing_down,\n    got_request_exception,\n    request_started,\n)\n\n\nclass FlaskIntegration(Integration):\n    identifier = \"flask\"\n\n    transaction_style = None\n\n    def __init__(self, transaction_style=\"endpoint\"):\n        TRANSACTION_STYLE_VALUES = (\"endpoint\", \"url\")\n        if transaction_style not in TRANSACTION_STYLE_VALUES:\n            raise ValueError(\n                \"Invalid value for transaction_style: %s (must be in %s)\"\n                % (transaction_style, TRANSACTION_STYLE_VALUES)\n            )\n        self.transaction_style = transaction_style\n\n    @staticmethod\n    def setup_once():\n        appcontext_pushed.connect(_push_appctx)\n        appcontext_tearing_down.connect(_pop_appctx)\n        request_started.connect(_request_started)\n        got_request_exception.connect(_capture_exception)\n\n        old_app = Flask.__call__\n\n        def sentry_patched_wsgi_app(self, environ, start_response):\n            if Hub.current.get_integration(FlaskIntegration) is None:\n                return old_app(self, environ, start_response)\n\n            return SentryWsgiMiddleware(lambda *a, **kw: old_app(self, *a, **kw))(\n                environ, start_response\n            )\n\n        Flask.__call__ = sentry_patched_wsgi_app\n\n\ndef _push_appctx(*args, **kwargs):\n    hub = Hub.current\n    if hub.get_integration(FlaskIntegration) is not None:\n        # always want to push scope regardless of whether WSGI app might already\n        # have (not the case for CLI for example)\n        scope_manager = hub.push_scope()\n        scope_manager.__enter__()\n        _app_ctx_stack.top.sentry_sdk_scope_manager = scope_manager\n        with hub.configure_scope() as scope:\n            scope._name = \"flask\"\n\n\ndef _pop_appctx(*args, **kwargs):\n    scope_manager = getattr(_app_ctx_stack.top, \"sentry_sdk_scope_manager\", None)\n    if scope_manager is not None:\n        scope_manager.__exit__(None, None, None)\n\n\ndef _request_started(sender, **kwargs):\n    hub = Hub.current\n    integration = hub.get_integration(FlaskIntegration)\n    if integration is None:\n        return\n\n    weak_request = weakref.ref(_request_ctx_stack.top.request)\n    app = _app_ctx_stack.top.app\n    with hub.configure_scope() as scope:\n        scope.add_event_processor(\n            _make_request_event_processor(app, weak_request, integration)\n        )\n\n\nclass FlaskRequestExtractor(RequestExtractor):\n    def env(self):\n        return self.request.environ\n\n    def cookies(self):\n        return self.request.cookies\n\n    def raw_data(self):\n        return self.request.data\n\n    def form(self):\n        return self.request.form\n\n    def files(self):\n        return self.request.files\n\n    def size_of_file(self, file):\n        return file.content_length\n\n\ndef _make_request_event_processor(app, weak_request, integration):\n    def inner(event, hint):\n        request = weak_request()\n\n        # if the request is gone we are fine not logging the data from\n        # it.  This might happen if the processor is pushed away to\n        # another thread.\n        if request is None:\n            return event\n\n        try:\n            if integration.transaction_style == \"endpoint\":\n                event[\"transaction\"] = request.url_rule.endpoint\n            elif integration.transaction_style == \"url\":\n                event[\"transaction\"] = request.url_rule.rule\n        except Exception:\n            pass\n\n        with capture_internal_exceptions():\n            FlaskRequestExtractor(request).extract_into_event(event)\n\n        if _should_send_default_pii():\n            with capture_internal_exceptions():\n                _add_user_to_event(event)\n\n        return event\n\n    return inner\n\n\ndef _capture_exception(sender, exception, **kwargs):\n    hub = Hub.current\n    if hub.get_integration(FlaskIntegration) is None:\n        return\n    event, hint = event_from_exception(\n        exception,\n        client_options=hub.client.options,\n        mechanism={\"type\": \"flask\", \"handled\": False},\n    )\n\n    hub.capture_event(event, hint=hint)\n\n\ndef _add_user_to_event(event):\n    if flask_login is None:\n        return\n\n    user = flask_login.current_user\n    if user is None:\n        return\n\n    with capture_internal_exceptions():\n        # Access this object as late as possible as accessing the user\n        # is relatively costly\n\n        user_info = event.setdefault(\"user\", {})\n\n        try:\n            user_info[\"id\"] = user.get_id()\n            # TODO: more configurable user attrs here\n        except AttributeError:\n            # might happen if:\n            # - flask_login could not be imported\n            # - flask_login is not configured\n            # - no user is logged in\n            pass\n\n        # The following attribute accesses are ineffective for the general\n        # Flask-Login case, because the User interface of Flask-Login does not\n        # care about anything but the ID. However, Flask-User (based on\n        # Flask-Login) documents a few optional extra attributes.\n        #\n        # https://github.com/lingthio/Flask-User/blob/a379fa0a281789618c484b459cb41236779b95b1/docs/source/data_models.rst#fixed-data-model-property-names\n\n        try:\n            user_info[\"email\"] = user_info[\"username\"] = user.email\n        except Exception:\n            pass\n\n        try:\n            user_info[\"username\"] = user.username\n        except Exception:\n            pass\n", "path": "sentry_sdk/integrations/flask.py"}]}