- Enable dynamic config loading from DB to respect enabled status - Implement Yahoo Finance Crumb authentication flow - Add browser-like User-Agent and cookie store - Map .SH symbols to .SS for Yahoo compatibility - Add Google DNS to docker-compose to fix container resolution issues
84 lines
2.3 KiB
Rust
84 lines
2.3 KiB
Rust
//!
|
|
//! 数据持久化客户端
|
|
//!
|
|
//! 提供一个类型化的接口,用于与 `data-persistence-service` 进行通信。
|
|
//!
|
|
|
|
use crate::error::Result;
|
|
use common_contracts::{
|
|
config_models::DataSourcesConfig,
|
|
dtos::{CompanyProfileDto, RealtimeQuoteDto, TimeSeriesFinancialBatchDto, TimeSeriesFinancialDto},
|
|
};
|
|
use tracing::info;
|
|
|
|
#[derive(Clone)]
|
|
pub struct PersistenceClient {
|
|
client: reqwest::Client,
|
|
base_url: String,
|
|
}
|
|
|
|
impl PersistenceClient {
|
|
pub fn new(base_url: String) -> Self {
|
|
Self {
|
|
client: reqwest::Client::new(),
|
|
base_url,
|
|
}
|
|
}
|
|
|
|
pub async fn get_data_sources_config(&self) -> Result<DataSourcesConfig> {
|
|
let url = format!("{}/configs/data_sources", self.base_url);
|
|
let config = self.client
|
|
.get(&url)
|
|
.send()
|
|
.await?
|
|
.error_for_status()?
|
|
.json()
|
|
.await?;
|
|
Ok(config)
|
|
}
|
|
|
|
pub async fn upsert_company_profile(&self, profile: CompanyProfileDto) -> Result<()> {
|
|
let url = format!("{}/companies", self.base_url);
|
|
info!("Upserting company profile for {} to {}", profile.symbol, url);
|
|
self.client
|
|
.put(&url)
|
|
.json(&profile)
|
|
.send()
|
|
.await?
|
|
.error_for_status()?;
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn upsert_realtime_quote(&self, quote: RealtimeQuoteDto) -> Result<()> {
|
|
let url = format!("{}/market-data/quotes", self.base_url);
|
|
info!("Upserting realtime quote for {} to {}", quote.symbol, url);
|
|
self.client
|
|
.post(&url)
|
|
.json("e)
|
|
.send()
|
|
.await?
|
|
.error_for_status()?;
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn batch_insert_financials(&self, dtos: Vec<TimeSeriesFinancialDto>) -> Result<()> {
|
|
if dtos.is_empty() {
|
|
return Ok(());
|
|
}
|
|
let url = format!("{}/market-data/financials/batch", self.base_url);
|
|
let symbol = dtos[0].symbol.clone();
|
|
info!("Batch inserting {} financial statements for {} to {}", dtos.len(), symbol, url);
|
|
|
|
let batch = TimeSeriesFinancialBatchDto { records: dtos };
|
|
|
|
self.client
|
|
.post(&url)
|
|
.json(&batch)
|
|
.send()
|
|
.await?
|
|
.error_for_status()?;
|
|
|
|
Ok(())
|
|
}
|
|
}
|