client.mojo (4096B)
1 from std.collections import Optional 2 from std.time import perf_counter_ns 3 4 from json import Value 5 from flare.http import HttpClient 6 7 from hyf_provider.config import MaxLocalProviderConfig 8 9 10 @fieldwise_init 11 struct MaxLocalTransportResponse(Copyable, Movable): 12 var status: Int 13 var body_text: String 14 var latency_ms: Int 15 16 17 @fieldwise_init 18 struct MaxLocalTransportFailure(Copyable, Movable): 19 var kind: String 20 var reason: String 21 22 23 @fieldwise_init 24 struct MaxLocalTransportOutcome(Copyable, Movable): 25 var response: Optional[MaxLocalTransportResponse] 26 var failure: Optional[MaxLocalTransportFailure] 27 28 29 def _trim_trailing_slash(url: String) -> String: 30 if url.endswith("/") and url.byte_length() > 1: 31 return String(url[byte = 0 : url.byte_length() - 1]) 32 return String(url) 33 34 35 def _http_url(url: String) -> Bool: 36 return url.startswith("http://") or url.startswith("https://") 37 38 39 def _elapsed_ms_since(start_ns: UInt) -> Int: 40 return Int((perf_counter_ns() - start_ns) // 1_000_000) 41 42 43 def _transport_response_outcome( 44 status: Int, body_text: String, latency_ms: Int 45 ) -> MaxLocalTransportOutcome: 46 return MaxLocalTransportOutcome( 47 response=Optional[MaxLocalTransportResponse]( 48 MaxLocalTransportResponse( 49 status=status, 50 body_text=String(body_text), 51 latency_ms=latency_ms, 52 ) 53 ), 54 failure=Optional[MaxLocalTransportFailure](None), 55 ) 56 57 58 def _transport_failure_outcome( 59 kind: String, reason: String 60 ) -> MaxLocalTransportOutcome: 61 return MaxLocalTransportOutcome( 62 response=Optional[MaxLocalTransportResponse](None), 63 failure=Optional[MaxLocalTransportFailure]( 64 MaxLocalTransportFailure( 65 kind=String(kind), reason=String(reason) 66 ) 67 ), 68 ) 69 70 71 def _transport_exception_reason( 72 start_ns: UInt, request_timeout_ms: Int 73 ) -> String: 74 if _elapsed_ms_since(start_ns) >= request_timeout_ms: 75 return "timeout" 76 return "unknown_transport" 77 78 79 def make_max_local_http_client(config: MaxLocalProviderConfig) -> HttpClient: 80 return HttpClient(timeout_ms=config.request_timeout_ms) 81 82 83 def max_local_chat_completions_url(config: MaxLocalProviderConfig) -> String: 84 return _trim_trailing_slash(config.base_url) + "/chat/completions" 85 86 87 def get_max_local_health( 88 config: MaxLocalProviderConfig, 89 ) -> MaxLocalTransportOutcome: 90 if not _http_url(config.health_url): 91 return _transport_failure_outcome("transport", "invalid_url") 92 93 var start_ns = perf_counter_ns() 94 try: 95 with make_max_local_http_client(config) as client: 96 var response = client.get(config.health_url) 97 var latency_ms = _elapsed_ms_since(start_ns) 98 if not response.ok(): 99 return _transport_failure_outcome("http_status", "non_2xx") 100 return _transport_response_outcome( 101 response.status, response.text(), latency_ms 102 ) 103 except: 104 return _transport_failure_outcome( 105 "transport", 106 _transport_exception_reason(start_ns, config.request_timeout_ms), 107 ) 108 109 110 def post_max_local_chat_completion( 111 config: MaxLocalProviderConfig, body: Value 112 ) -> MaxLocalTransportOutcome: 113 var url = max_local_chat_completions_url(config) 114 if not _http_url(url): 115 return _transport_failure_outcome("transport", "invalid_url") 116 117 var start_ns = perf_counter_ns() 118 try: 119 with make_max_local_http_client(config) as client: 120 var response = client.post(url, body) 121 var latency_ms = _elapsed_ms_since(start_ns) 122 if not response.ok(): 123 return _transport_failure_outcome( 124 "http_status", "provider_non_2xx" 125 ) 126 return _transport_response_outcome( 127 response.status, response.text(), latency_ms 128 ) 129 except: 130 return _transport_failure_outcome( 131 "transport", 132 _transport_exception_reason(start_ns, config.request_timeout_ms), 133 )