Repository: open-telemetry/opentelemetry-python-contrib

Issue:
Add support for Flask 3.0.0 
**Describe your environment**
* Python 3.11
* Otel Python API/SDK 1.20.0
* opentelemetry-instrument 0.41b0
* Flask 3.0.0, released 2 days ago: https://github.com/pallets/flask/releases/tag/3.0.0
* Running on local in docker container `FROM python:3.11`

Attempting to do `opentelemetry-bootstrap` after installing Flask 3 results in a quiet message: `instrumentation for package flask<3.0,>=1.0 is available but version flask==3.0.0 is installed. Skipping.`

Attempting to manually install `opentelemetry-instrumentation-flask` gives a different message: `DependencyConflict: requested: "flask >= 1.0, < 3.0" but found: "flask 3.0.0"`

The Flask app successfully loads and Otel API can be used to manually create spans (`tracer.start_as_current_span`). But `SERVER` spans are not created for requests accepted by the Flask app that should be intercepted by instrumentation. Here is an example 1-span trace exported to console with only the `INTERNAL` type span:

```
172.26.0.1 - - [02/Oct/2023 22:19:02] "GET /test/ HTTP/1.1" 200 -
{
    "name": "my_test_trace",
    "context": {
        "trace_id": "0x3c881a21a3f4f695ebf19c55be7d36c5",
        "span_id": "0xd58cce9986a06144",
        "trace_state": "[]"
    },
    "kind": "SpanKind.INTERNAL",
    "parent_id": null,
    "start_time": "2023-10-02T22:19:02.966587Z",
    "end_time": "2023-10-02T22:19:02.966610Z",
    "status": {
        "status_code": "UNSET"
    },
    "attributes": {},
    "events": [],
    "links": [],
    "resource": {
        "attributes": {
            "telemetry.sdk.language": "python",
            "telemetry.sdk.name": "opentelemetry",
            "telemetry.sdk.version": "1.20.0",
            "service.name": "unknown_service"
        },
        "schema_url": ""
    }
}
```

**Steps to reproduce**
I've posted a repo here with two ways to reproduce: https://github.com/tammy-baylis-swi/otel-flask-three

**What is the expected behavior?**
There should be no errors at bootstrap or manual install/instrument of Flask, and traces should include `SERVER` type spans when the Flask app receives a request. I think instrumentation should support Flask 3 at some point.

**What is the actual behavior?**
There are error messages (see above) and traces do not include `SERVER` type spans when the Flask app receives a request.

**Additional context**
I think it's from this version requirement in [opentelemetry-instrumentation-flask](https://github.com/open-telemetry/opentelemetry-python-contrib/blob/e318c947a23152c8ff1700f0aad44261be0588cd/instrumentation/opentelemetry-instrumentation-flask/pyproject.toml#L37-L39). Upgrading to [Flask 3](https://github.com/pallets/flask/releases/tag/3.0.0) from the previous 2.3.3 might be breaking so some testing is needed. 

```
[project.optional-dependencies]
instruments = [
  "flask >= 1.0, < 3.0",
]
```



Discussion:
Yes, we currently don't support Flask >= 3.0.0
Thanks @ocelotl for Label and Title fix!

Resolving patch:
diff --git a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py
--- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py
+++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py
@@ -251,6 +251,16 @@ def response_hook(span: Span, status: str, response_headers: List):
 from opentelemetry import context, trace
 from opentelemetry.instrumentation.flask.package import _instruments
 from opentelemetry.instrumentation.flask.version import __version__
+
+try:
+    flask_version = flask.__version__
+except AttributeError:
+    try:
+        from importlib import metadata
+    except ImportError:
+        import importlib_metadata as metadata
+    flask_version = metadata.version("flask")
+
 from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
 from opentelemetry.instrumentation.propagators import (
     get_global_response_propagator,
@@ -271,7 +281,7 @@ def response_hook(span: Span, status: str, response_headers: List):
 
 _excluded_urls_from_env = get_excluded_urls("FLASK")
 
-if package_version.parse(flask.__version__) >= package_version.parse("2.2.0"):
+if package_version.parse(flask_version) >= package_version.parse("2.2.0"):
 
     def _request_ctx_ref() -> weakref.ReferenceType:
         return weakref.ref(flask.globals.request_ctx._get_current_object())
@@ -420,7 +430,7 @@ def _before_request():
             # https://flask.palletsprojects.com/en/1.1.x/api/#flask.has_request_context
             if flask and flask.request:
                 if commenter_options.get("framework", True):
-                    flask_info["framework"] = f"flask:{flask.__version__}"
+                    flask_info["framework"] = f"flask:{flask_version}"
                 if (
                     commenter_options.get("controller", True)
                     and flask.request.endpoint
diff --git a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/package.py b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/package.py
--- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/package.py
+++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/package.py
@@ -13,6 +13,6 @@
 # limitations under the License.
 
 
-_instruments = ("flask >= 1.0, < 3.0",)
+_instruments = ("flask >= 1.0",)
 
 _supports_metrics = True
diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py
--- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py
+++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py
@@ -85,11 +85,11 @@
         "instrumentation": "opentelemetry-instrumentation-fastapi==0.44b0.dev",
     },
     {
-        "library": "flask >= 1.0, < 3.0",
+        "library": "werkzeug < 3.0.0",
         "instrumentation": "opentelemetry-instrumentation-flask==0.44b0.dev",
     },
     {
-        "library": "werkzeug < 3.0.0",
+        "library": "flask >= 1.0",
         "instrumentation": "opentelemetry-instrumentation-flask==0.44b0.dev",
     },
     {


Test patch: