1use just_common::transport::http::{endpoint_url, ensure_success, parse_json};
4use reqwest::header::CONTENT_TYPE;
5
6use crate::{
7 Error,
8 types::{
9 balance::GetUserBalanceResponse,
10 chat::{ChatCompletion, ChatCompletionRequest},
11 models::ListModelsResponse,
12 },
13};
14
15#[derive(Clone, Debug)]
20pub struct DeepSeekClient {
21 http: reqwest::Client,
22 base_url: String,
23}
24
25impl DeepSeekClient {
26 pub fn new(http: reqwest::Client, base_url: String) -> Self {
33 Self { http, base_url }
34 }
35
36 pub fn builder() -> crate::client_builder::DeepSeekClientBuilder {
38 crate::client_builder::DeepSeekClientBuilder::new()
39 }
40
41 pub fn http_client(&self) -> &reqwest::Client {
43 &self.http
44 }
45
46 pub fn base_url(&self) -> &str {
48 &self.base_url
49 }
50
51 pub fn prepare(&self, request: ChatCompletionRequest) -> Result<reqwest::Request, Error> {
56 if request.stream.unwrap_or(false) {
57 return Err(Error::InvalidRequest(
58 "stream=true is not supported by prepare; use prepare_streaming instead".into(),
59 ));
60 }
61 self.build_request(request, "/chat/completions")
62 }
63
64 pub fn prepare_streaming(
69 &self,
70 mut request: ChatCompletionRequest,
71 ) -> Result<reqwest::Request, Error> {
72 request.stream = Some(true);
73 self.build_request(request, "/chat/completions")
74 }
75
76 pub async fn send(&self, request: reqwest::Request) -> Result<reqwest::Response, Error> {
82 self.http
83 .execute(request)
84 .await
85 .map_err(just_common::error::TransportError::Transport)
86 .map_err(Error::from)
87 }
88
89 fn build_request(
91 &self,
92 body: impl serde::Serialize,
93 path: &str,
94 ) -> Result<reqwest::Request, Error> {
95 let url = endpoint_url(&self.base_url, path)?;
96 let payload = serde_json::to_vec(&body)?;
97 self.http
98 .post(url)
99 .header(CONTENT_TYPE, "application/json")
100 .body(payload)
101 .build()
102 .map_err(just_common::error::TransportError::Transport)
103 .map_err(Error::from)
104 }
105}
106
107impl DeepSeekClient {
108 pub async fn parse(&self, response: reqwest::Response) -> Result<ChatCompletion, Error> {
116 parse_json(response).await
117 }
118
119 pub async fn parse_streaming(
123 &self,
124 response: reqwest::Response,
125 ) -> Result<crate::ChatCompletionStream, Error> {
126 let response = ensure_success(response).await?;
127 crate::ChatCompletionStream::from_response(response).map_err(Error::Transport)
128 }
129
130 pub async fn chat_completion(
132 &self,
133 request: ChatCompletionRequest,
134 ) -> Result<ChatCompletion, Error> {
135 let response = self.send(self.prepare(request)?).await?;
136 self.parse(response).await
137 }
138
139 pub async fn stream_chat_completion(
141 &self,
142 request: ChatCompletionRequest,
143 ) -> Result<crate::ChatCompletionStream, Error> {
144 let response = self.send(self.prepare_streaming(request)?).await?;
145 self.parse_streaming(response).await
146 }
147
148 pub async fn list_models(&self) -> Result<ListModelsResponse, Error> {
150 let url = endpoint_url(&self.base_url, "/models")?;
151 let response = self
152 .http
153 .get(url)
154 .send()
155 .await
156 .map_err(just_common::error::TransportError::Transport)?;
157 parse_json(response).await
158 }
159
160 pub async fn get_user_balance(&self) -> Result<GetUserBalanceResponse, Error> {
162 let url = endpoint_url(&self.base_url, "/user/balance")?;
163 let response = self
164 .http
165 .get(url)
166 .send()
167 .await
168 .map_err(just_common::error::TransportError::Transport)?;
169 parse_json(response).await
170 }
171}