File size: 4,024 Bytes
1f7d0a1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
"""
HTTP client utilities with correlation ID propagation.
"""
import httpx
from typing import Optional, Dict, Any
from app.middleware.correlation_id import get_correlation_id, CORRELATION_ID_HEADER


class CorrelationHttpClient:
    """
    HTTP client that automatically propagates correlation IDs to downstream services.
    """
    
    @staticmethod
    def get_headers_with_correlation_id(additional_headers: Optional[Dict[str, str]] = None) -> Dict[str, str]:
        """
        Get headers with correlation ID included.
        
        Args:
            additional_headers: Optional additional headers to include
            
        Returns:
            Dict[str, str]: Headers with correlation ID
        """
        headers = {}
        
        # Add correlation ID if available
        correlation_id = get_correlation_id()
        if correlation_id:
            headers[CORRELATION_ID_HEADER] = correlation_id
        
        # Add additional headers
        if additional_headers:
            headers.update(additional_headers)
        
        return headers
    
    @staticmethod
    async def get(
        url: str,
        headers: Optional[Dict[str, str]] = None,
        **kwargs
    ) -> httpx.Response:
        """
        Make GET request with correlation ID.
        
        Args:
            url: Request URL
            headers: Optional headers
            **kwargs: Additional arguments for httpx.get
            
        Returns:
            httpx.Response: Response object
        """
        headers_with_correlation = CorrelationHttpClient.get_headers_with_correlation_id(headers)
        
        async with httpx.AsyncClient() as client:
            return await client.get(url, headers=headers_with_correlation, **kwargs)
    
    @staticmethod
    async def post(
        url: str,
        headers: Optional[Dict[str, str]] = None,
        json: Optional[Dict[str, Any]] = None,
        **kwargs
    ) -> httpx.Response:
        """
        Make POST request with correlation ID.
        
        Args:
            url: Request URL
            headers: Optional headers
            json: Optional JSON body
            **kwargs: Additional arguments for httpx.post
            
        Returns:
            httpx.Response: Response object
        """
        headers_with_correlation = CorrelationHttpClient.get_headers_with_correlation_id(headers)
        
        async with httpx.AsyncClient() as client:
            return await client.post(url, headers=headers_with_correlation, json=json, **kwargs)
    
    @staticmethod
    async def put(
        url: str,
        headers: Optional[Dict[str, str]] = None,
        json: Optional[Dict[str, Any]] = None,
        **kwargs
    ) -> httpx.Response:
        """
        Make PUT request with correlation ID.
        
        Args:
            url: Request URL
            headers: Optional headers
            json: Optional JSON body
            **kwargs: Additional arguments for httpx.put
            
        Returns:
            httpx.Response: Response object
        """
        headers_with_correlation = CorrelationHttpClient.get_headers_with_correlation_id(headers)
        
        async with httpx.AsyncClient() as client:
            return await client.put(url, headers=headers_with_correlation, json=json, **kwargs)
    
    @staticmethod
    async def delete(
        url: str,
        headers: Optional[Dict[str, str]] = None,
        **kwargs
    ) -> httpx.Response:
        """
        Make DELETE request with correlation ID.
        
        Args:
            url: Request URL
            headers: Optional headers
            **kwargs: Additional arguments for httpx.delete
            
        Returns:
            httpx.Response: Response object
        """
        headers_with_correlation = CorrelationHttpClient.get_headers_with_correlation_id(headers)
        
        async with httpx.AsyncClient() as client:
            return await client.delete(url, headers=headers_with_correlation, **kwargs)