@@ -1886,8 +1886,7 @@ def test_host_header_url_construction(self):
18861886 """Test that URLs use Host header value instead of server IP when available."""
18871887 # Test with a custom Host header - should use the domain name
18881888 resp = self ._client .get (
1889- "/foobar?param=value" ,
1890- headers = {"host" : "api.mycompany.com" }
1889+ "/foobar?param=value" , headers = {"host" : "api.mycompany.com" }
18911890 )
18921891 self .assertEqual (200 , resp .status_code )
18931892
@@ -1901,26 +1900,31 @@ def test_host_header_url_construction(self):
19011900 server_span = span
19021901 break
19031902
1904- self .assertIsNotNone (server_span , "Server span with HTTP_URL not found" )
1903+ self .assertIsNotNone (
1904+ server_span , "Server span with HTTP_URL not found"
1905+ )
19051906
19061907 # Verify the URL uses the Host header domain instead of testserver
19071908 expected_url = "https://api.mycompany.com/foobar?param=value"
19081909 actual_url = server_span .attributes [HTTP_URL ]
19091910 self .assertEqual (expected_url , actual_url )
19101911
19111912 # Also verify that the server name attribute is set correctly
1912- self .assertEqual ("api.mycompany.com" , server_span .attributes .get ("http.server_name" ))
1913+ self .assertEqual (
1914+ "api.mycompany.com" , server_span .attributes .get ("http.server_name" )
1915+ )
19131916
19141917 def test_host_header_with_port_url_construction (self ):
19151918 """Test Host header URL construction when host includes port."""
19161919 resp = self ._client .get (
1917- "/user/123" ,
1918- headers = {"host" : "staging.myapp.com:8443" }
1920+ "/user/123" , headers = {"host" : "staging.myapp.com:8443" }
19191921 )
19201922 self .assertEqual (200 , resp .status_code )
19211923
19221924 spans = self .memory_exporter .get_finished_spans ()
1923- server_span = next ((span for span in spans if HTTP_URL in span .attributes ), None )
1925+ server_span = next (
1926+ (span for span in spans if HTTP_URL in span .attributes ), None
1927+ )
19241928 self .assertIsNotNone (server_span )
19251929
19261930 # Should use the host header value with non-standard port included
@@ -1935,7 +1939,9 @@ def test_no_host_header_fallback_behavior(self):
19351939 self .assertEqual (200 , resp .status_code )
19361940
19371941 spans = self .memory_exporter .get_finished_spans ()
1938- server_span = next ((span for span in spans if HTTP_URL in span .attributes ), None )
1942+ server_span = next (
1943+ (span for span in spans if HTTP_URL in span .attributes ), None
1944+ )
19391945 self .assertIsNotNone (server_span )
19401946
19411947 # Should fallback to testserver (TestClient default, standard port stripped)
@@ -1947,16 +1953,20 @@ def test_production_scenario_host_header(self):
19471953 """Test a realistic production scenario with Host header."""
19481954 # Simulate a production request with public domain in Host header
19491955 resp = self ._client .get (
1950- "/foobar?limit=10&offset=20" ,
1956+ "/foobar?limit=10&offset=20" ,
19511957 headers = {
19521958 "host" : "prod-api.example.com" ,
1953- "user-agent" : "ProductionClient/1.0"
1954- }
1959+ "user-agent" : "ProductionClient/1.0" ,
1960+ },
19551961 )
1956- self .assertEqual (200 , resp .status_code ) # Valid route should return 200
1962+ self .assertEqual (
1963+ 200 , resp .status_code
1964+ ) # Valid route should return 200
19571965
19581966 spans = self .memory_exporter .get_finished_spans ()
1959- server_span = next ((span for span in spans if HTTP_URL in span .attributes ), None )
1967+ server_span = next (
1968+ (span for span in spans if HTTP_URL in span .attributes ), None
1969+ )
19601970 self .assertIsNotNone (server_span )
19611971
19621972 # URL should use the production domain from Host header (AS-IS, no default port)
@@ -1967,30 +1977,44 @@ def test_production_scenario_host_header(self):
19671977 # Verify other attributes are still correct
19681978 self .assertEqual ("GET" , server_span .attributes [HTTP_METHOD ])
19691979 self .assertEqual ("/foobar" , server_span .attributes [HTTP_TARGET ])
1970- self .assertEqual ("prod-api.example.com" , server_span .attributes .get ("http.server_name" ))
1980+ self .assertEqual (
1981+ "prod-api.example.com" ,
1982+ server_span .attributes .get ("http.server_name" ),
1983+ )
19711984
19721985 def test_host_header_with_special_characters (self ):
19731986 """Test Host header handling with special characters and edge cases."""
19741987 test_cases = [
1975- ("api-v2.test-domain.com" , "https://api-v2.test-domain.com/foobar" ),
1988+ (
1989+ "api-v2.test-domain.com" ,
1990+ "https://api-v2.test-domain.com/foobar" ,
1991+ ),
19761992 ("localhost" , "https://localhost/foobar" ),
1977- ("192.168.1.100" , "https://192.168.1.100/foobar" ), # IP address as host
1978- ("test.domain.co.uk" , "https://test.domain.co.uk/foobar" ), # Multiple dots
1993+ (
1994+ "192.168.1.100" ,
1995+ "https://192.168.1.100/foobar" ,
1996+ ), # IP address as host
1997+ (
1998+ "test.domain.co.uk" ,
1999+ "https://test.domain.co.uk/foobar" ,
2000+ ), # Multiple dots
19792001 ]
19802002
19812003 for host_value , expected_url in test_cases :
19822004 with self .subTest (host = host_value ):
19832005 # Clear previous spans
19842006 self .memory_exporter .clear ()
1985-
2007+
19862008 resp = self ._client .get (
1987- "/foobar" ,
1988- headers = {"host" : host_value }
2009+ "/foobar" , headers = {"host" : host_value }
19892010 )
19902011 self .assertEqual (200 , resp .status_code )
19912012
19922013 spans = self .memory_exporter .get_finished_spans ()
1993- server_span = next ((span for span in spans if HTTP_URL in span .attributes ), None )
2014+ server_span = next (
2015+ (span for span in spans if HTTP_URL in span .attributes ),
2016+ None ,
2017+ )
19942018 self .assertIsNotNone (server_span )
19952019
19962020 actual_url = server_span .attributes [HTTP_URL ]
@@ -2000,13 +2024,14 @@ def test_host_header_bytes_handling(self):
20002024 """Test that Host header values are properly decoded from bytes."""
20012025 # This test verifies the fix for bytes vs string handling in our implementation
20022026 resp = self ._client .get (
2003- "/foobar" ,
2004- headers = {"host" : "bytes-test.example.com" }
2027+ "/foobar" , headers = {"host" : "bytes-test.example.com" }
20052028 )
20062029 self .assertEqual (200 , resp .status_code )
20072030
20082031 spans = self .memory_exporter .get_finished_spans ()
2009- server_span = next ((span for span in spans if HTTP_URL in span .attributes ), None )
2032+ server_span = next (
2033+ (span for span in spans if HTTP_URL in span .attributes ), None
2034+ )
20102035 self .assertIsNotNone (server_span )
20112036
20122037 # Should properly decode and use the host header
@@ -2020,29 +2045,37 @@ def test_host_header_maintains_span_attributes(self):
20202045 "/user/testuser?debug=true" ,
20212046 headers = {
20222047 "host" : "api.testapp.com" ,
2023- "user-agent" : "TestClient/1.0"
2024- }
2048+ "user-agent" : "TestClient/1.0" ,
2049+ },
20252050 )
20262051 self .assertEqual (200 , resp .status_code )
20272052
20282053 spans = self .memory_exporter .get_finished_spans ()
2029- server_span = next ((span for span in spans if HTTP_URL in span .attributes ), None )
2054+ server_span = next (
2055+ (span for span in spans if HTTP_URL in span .attributes ), None
2056+ )
20302057 self .assertIsNotNone (server_span )
20312058
20322059 # Verify URL uses Host header
2033- self .assertEqual ("https://api.testapp.com/user/testuser?debug=true" ,
2034- server_span .attributes [HTTP_URL ])
2060+ self .assertEqual (
2061+ "https://api.testapp.com/user/testuser?debug=true" ,
2062+ server_span .attributes [HTTP_URL ],
2063+ )
20352064
20362065 # Verify all other attributes are still present and correct
20372066 self .assertEqual ("GET" , server_span .attributes [HTTP_METHOD ])
20382067 self .assertEqual ("/user/testuser" , server_span .attributes [HTTP_TARGET ])
20392068 self .assertEqual ("https" , server_span .attributes [HTTP_SCHEME ])
2040- self .assertEqual ("api.testapp.com" , server_span .attributes .get ("http.server_name" ))
2069+ self .assertEqual (
2070+ "api.testapp.com" , server_span .attributes .get ("http.server_name" )
2071+ )
20412072 self .assertEqual (200 , server_span .attributes [HTTP_STATUS_CODE ])
20422073
20432074 # Check that route attribute is still set correctly
20442075 if HTTP_ROUTE in server_span .attributes :
2045- self .assertEqual ("/user/{username}" , server_span .attributes [HTTP_ROUTE ])
2076+ self .assertEqual (
2077+ "/user/{username}" , server_span .attributes [HTTP_ROUTE ]
2078+ )
20462079
20472080
20482081class TestFastAPIHostHeaderURLNewSemconv (TestFastAPIHostHeaderURL ):
@@ -2056,14 +2089,15 @@ def test_host_header_url_new_semconv(self):
20562089 Host header support may work differently with new semantic conventions.
20572090 """
20582091 resp = self ._client .get (
2059- "/foobar?test=new_semconv" ,
2060- headers = {"host" : "newapi.example.com" }
2092+ "/foobar?test=new_semconv" , headers = {"host" : "newapi.example.com" }
20612093 )
20622094 self .assertEqual (200 , resp .status_code )
20632095
20642096 spans = self .memory_exporter .get_finished_spans ()
20652097 # With new semantic conventions, look for the main HTTP span with route information
2066- server_span = next ((span for span in spans if "http.route" in span .attributes ), None )
2098+ server_span = next (
2099+ (span for span in spans if "http.route" in span .attributes ), None
2100+ )
20672101 self .assertIsNotNone (server_span )
20682102
20692103 # Verify we have the new semantic convention attributes
@@ -2081,16 +2115,18 @@ def test_host_header_url_new_semconv(self):
20812115
20822116class TestFastAPIHostHeaderURLBothSemconv (TestFastAPIHostHeaderURL ):
20832117 """Test Host header URL functionality with both old and new semantic conventions."""
2118+
20842119 def test_host_header_url_both_semconv (self ):
20852120 """Test Host header URL construction with both semantic conventions enabled."""
20862121 resp = self ._client .get (
2087- "/foobar?test=both_semconv" ,
2088- headers = {"host" : "dual.example.com" }
2122+ "/foobar?test=both_semconv" , headers = {"host" : "dual.example.com" }
20892123 )
20902124 self .assertEqual (200 , resp .status_code )
20912125
20922126 spans = self .memory_exporter .get_finished_spans ()
2093- server_span = next ((span for span in spans if HTTP_URL in span .attributes ), None )
2127+ server_span = next (
2128+ (span for span in spans if HTTP_URL in span .attributes ), None
2129+ )
20942130 self .assertIsNotNone (server_span )
20952131
20962132 # Should use Host header for URL construction regardless of semantic convention mode
@@ -2100,7 +2136,9 @@ def test_host_header_url_both_semconv(self):
21002136
21012137 def test_fastapi_unhandled_exception (self ):
21022138 """Override inherited test - use the both_semconv version instead."""
2103- self .skipTest ("Use test_fastapi_unhandled_exception_both_semconv instead" )
2139+ self .skipTest (
2140+ "Use test_fastapi_unhandled_exception_both_semconv instead"
2141+ )
21042142
21052143 def test_fastapi_unhandled_exception_both_semconv (self ):
21062144 """If the application has an unhandled error the instrumentation should capture that a 500 response is returned."""
@@ -2117,14 +2155,24 @@ def test_fastapi_unhandled_exception_both_semconv(self):
21172155 spans = self .memory_exporter .get_finished_spans ()
21182156 # With both semantic conventions enabled, we expect 3 spans:
21192157 # 1. Server span (main HTTP span)
2120- # 2. ASGI receive span
2158+ # 2. ASGI receive span
21212159 # 3. ASGI send span (for error response)
21222160 self .assertEqual (len (spans ), 3 )
21232161
21242162 # Find the server span (it should have HTTP attributes)
2125- server_spans = [span for span in spans if hasattr (span , 'attributes' ) and span .attributes and HTTP_URL in span .attributes ]
2163+ server_spans = [
2164+ span
2165+ for span in spans
2166+ if hasattr (span , "attributes" )
2167+ and span .attributes
2168+ and HTTP_URL in span .attributes
2169+ ]
21262170
2127- self .assertEqual (len (server_spans ), 1 , "Expected exactly one server span with HTTP_URL" )
2171+ self .assertEqual (
2172+ len (server_spans ),
2173+ 1 ,
2174+ "Expected exactly one server span with HTTP_URL" ,
2175+ )
21282176 server_span = server_spans [0 ]
21292177
21302178 # Ensure server_span is not None
0 commit comments