quantcli 0.1.14__tar.gz → 0.1.16__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {quantcli-0.1.14/quantcli.egg-info → quantcli-0.1.16}/PKG-INFO +1 -1
- {quantcli-0.1.14 → quantcli-0.1.16}/pyproject.toml +1 -1
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/cli.py +3 -1
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/core/data.py +71 -48
- {quantcli-0.1.14 → quantcli-0.1.16/quantcli.egg-info}/PKG-INFO +1 -1
- {quantcli-0.1.14 → quantcli-0.1.16}/LICENSE +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/README.md +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/core/__init__.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/core/backtest.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/core/factor.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/datasources/__init__.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/datasources/akshare.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/datasources/baostock.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/datasources/base.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/datasources/cache.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/datasources/fundamentals/__init__.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/datasources/fundamentals/provider.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/datasources/mixed.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/datasources/mysql.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/datasources/sync/__init__.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/datasources/sync/akshare.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/datasources/sync/base.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/datasources/sync/gm.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/datasources/sync/gm_fundamental.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/__init__.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_001.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_002.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_003.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_004.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_005.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_006.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_007.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_008.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_009.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_010.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_011.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_012.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_013.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_014.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_015.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_016.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_017.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_018.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_019.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_020.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_021.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_022.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_023.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_024.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_025.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_026.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_027.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_028.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_029.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_030.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_031.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_032.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_033.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_034.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_035.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_036.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_037.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_038.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_039.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/alpha101/alpha_040.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/base.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/compute.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/loader.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/pipeline.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/ranking.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/ranking_executor.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/screening.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/factors/screening_executor.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/models/bar.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/parser/__init__.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/parser/constants.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/parser/formula.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/utils/__init__.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/utils/env.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/utils/logger.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/utils/path.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/utils/symbol_utils.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/utils/time.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli/utils/validate.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli.egg-info/SOURCES.txt +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli.egg-info/dependency_links.txt +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli.egg-info/entry_points.txt +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli.egg-info/requires.txt +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/quantcli.egg-info/top_level.txt +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/setup.cfg +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/tests/test_akshare_integration.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/tests/test_builtin_factors.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/tests/test_cli.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/tests/test_datasources.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/tests/test_factors.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/tests/test_gm_executors.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/tests/test_mixed_datasource.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/tests/test_multi_factor.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/tests/test_pipeline_integration.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/tests/test_symbol_utils.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.16}/tests/test_time.py +0 -0
|
@@ -78,10 +78,12 @@ def quantcli(ctx, verbose):
|
|
|
78
78
|
|
|
79
79
|
if verbose:
|
|
80
80
|
import logging
|
|
81
|
+
import importlib.metadata
|
|
81
82
|
|
|
82
83
|
logging.basicConfig(level=logging.DEBUG)
|
|
83
84
|
|
|
84
|
-
|
|
85
|
+
version = importlib.metadata.version("quantcli")
|
|
86
|
+
logger.info(f"QuantCLI v{version} started")
|
|
85
87
|
|
|
86
88
|
|
|
87
89
|
# =============================================================================
|
|
@@ -21,10 +21,7 @@ from pathlib import Path
|
|
|
21
21
|
import pandas as pd
|
|
22
22
|
|
|
23
23
|
from ..datasources import create_datasource, DataSource, StockInfo
|
|
24
|
-
from ..utils import
|
|
25
|
-
get_logger, project_root, ensure_dir, format_size,
|
|
26
|
-
parse_date, today
|
|
27
|
-
)
|
|
24
|
+
from ..utils import get_logger, project_root, ensure_dir, format_size, parse_date, today
|
|
28
25
|
|
|
29
26
|
logger = get_logger(__name__)
|
|
30
27
|
|
|
@@ -32,6 +29,7 @@ logger = get_logger(__name__)
|
|
|
32
29
|
@dataclass
|
|
33
30
|
class DataConfig:
|
|
34
31
|
"""数据管理配置"""
|
|
32
|
+
|
|
35
33
|
source: str = "akshare"
|
|
36
34
|
cache_dir: str = "./data"
|
|
37
35
|
parallel: int = 4
|
|
@@ -54,6 +52,7 @@ class DataConfig:
|
|
|
54
52
|
@dataclass
|
|
55
53
|
class DataQualityReport:
|
|
56
54
|
"""数据质量报告"""
|
|
55
|
+
|
|
57
56
|
total_rows: int
|
|
58
57
|
null_count: Dict[str, int]
|
|
59
58
|
outlier_count: Dict[str, int]
|
|
@@ -113,12 +112,7 @@ class DataManager:
|
|
|
113
112
|
# =============================================================================
|
|
114
113
|
|
|
115
114
|
def get_daily(
|
|
116
|
-
self,
|
|
117
|
-
symbol: str,
|
|
118
|
-
start_date,
|
|
119
|
-
end_date,
|
|
120
|
-
use_cache: bool = True,
|
|
121
|
-
**kwargs
|
|
115
|
+
self, symbol: str, start_date, end_date, use_cache: bool = True, **kwargs
|
|
122
116
|
) -> pd.DataFrame:
|
|
123
117
|
"""获取单只股票日线数据"""
|
|
124
118
|
cache_file = self.cache_dir / "raw" / "stock_daily" / f"{symbol}.parquet"
|
|
@@ -151,7 +145,7 @@ class DataManager:
|
|
|
151
145
|
start_date,
|
|
152
146
|
end_date,
|
|
153
147
|
use_cache: bool = True,
|
|
154
|
-
parallel: bool = False
|
|
148
|
+
parallel: bool = False,
|
|
155
149
|
) -> pd.DataFrame:
|
|
156
150
|
"""批量获取多只股票日线数据"""
|
|
157
151
|
if not symbols:
|
|
@@ -161,6 +155,7 @@ class DataManager:
|
|
|
161
155
|
|
|
162
156
|
if parallel and len(symbols) > 1:
|
|
163
157
|
from concurrent.futures import ThreadPoolExecutor
|
|
158
|
+
|
|
164
159
|
with ThreadPoolExecutor(max_workers=self.config.parallel) as executor:
|
|
165
160
|
futures = [
|
|
166
161
|
executor.submit(self.get_daily, s, start_date, end_date, use_cache)
|
|
@@ -192,10 +187,7 @@ class DataManager:
|
|
|
192
187
|
return result
|
|
193
188
|
|
|
194
189
|
def get_universe(
|
|
195
|
-
self,
|
|
196
|
-
universe: str = "all",
|
|
197
|
-
market: str = "all",
|
|
198
|
-
use_cache: bool = True
|
|
190
|
+
self, universe: str = "all", market: str = "all", use_cache: bool = True
|
|
199
191
|
) -> List[StockInfo]:
|
|
200
192
|
"""获取股票池"""
|
|
201
193
|
cache_file = self.cache_dir / "cache" / f"stock_list_{market}.json"
|
|
@@ -221,9 +213,7 @@ class DataManager:
|
|
|
221
213
|
return stocks
|
|
222
214
|
|
|
223
215
|
def get_trading_calendar(
|
|
224
|
-
self,
|
|
225
|
-
exchange: str = "SSE",
|
|
226
|
-
use_cache: bool = True
|
|
216
|
+
self, exchange: str = "SSE", use_cache: bool = True
|
|
227
217
|
) -> List:
|
|
228
218
|
"""获取交易日历"""
|
|
229
219
|
cache_file = self.cache_dir / "cache" / f"trading_calendar_{exchange}.json"
|
|
@@ -244,11 +234,7 @@ class DataManager:
|
|
|
244
234
|
return trading_days
|
|
245
235
|
|
|
246
236
|
def get_index_daily(
|
|
247
|
-
self,
|
|
248
|
-
symbol: str,
|
|
249
|
-
start_date,
|
|
250
|
-
end_date,
|
|
251
|
-
use_cache: bool = True
|
|
237
|
+
self, symbol: str, start_date, end_date, use_cache: bool = True
|
|
252
238
|
) -> pd.DataFrame:
|
|
253
239
|
"""获取指数日线数据"""
|
|
254
240
|
cache_file = self.cache_dir / "raw" / "index_daily" / f"{symbol}.parquet"
|
|
@@ -268,7 +254,9 @@ class DataManager:
|
|
|
268
254
|
|
|
269
255
|
return df
|
|
270
256
|
|
|
271
|
-
def _filter_universe(
|
|
257
|
+
def _filter_universe(
|
|
258
|
+
self, stocks: List[StockInfo], universe: str
|
|
259
|
+
) -> List[StockInfo]:
|
|
272
260
|
"""根据股票池名称过滤股票"""
|
|
273
261
|
return stocks
|
|
274
262
|
|
|
@@ -303,8 +291,10 @@ class DataManager:
|
|
|
303
291
|
try:
|
|
304
292
|
existing = pd.read_parquet(cache_file)
|
|
305
293
|
df_copy = pd.concat([existing, df_copy]).drop_duplicates(
|
|
306
|
-
subset=["date"]
|
|
307
|
-
|
|
294
|
+
subset=["date"]
|
|
295
|
+
if "symbol" not in df_copy.columns
|
|
296
|
+
else ["date", "symbol"],
|
|
297
|
+
keep="last",
|
|
308
298
|
)
|
|
309
299
|
except Exception:
|
|
310
300
|
pass
|
|
@@ -313,35 +303,53 @@ class DataManager:
|
|
|
313
303
|
|
|
314
304
|
self._cache_metadata[cache_key] = {
|
|
315
305
|
"last_updated": datetime.now().isoformat(),
|
|
316
|
-
"rows": len(df_copy)
|
|
306
|
+
"rows": len(df_copy),
|
|
317
307
|
}
|
|
318
308
|
self._save_metadata()
|
|
319
309
|
|
|
320
310
|
logger.debug(f"Cached {len(df_copy)} rows to {cache_file}")
|
|
321
311
|
|
|
322
|
-
def clear_cache(
|
|
312
|
+
def clear_cache(
|
|
313
|
+
self, older_than: Optional[int] = None, pattern: Optional[str] = None
|
|
314
|
+
) -> int:
|
|
315
|
+
"""清理缓存"""
|
|
316
|
+
count = 0
|
|
317
|
+
|
|
318
|
+
def clear_cache(
|
|
319
|
+
self, older_than: Optional[int] = None, pattern: Optional[str] = None
|
|
320
|
+
) -> int:
|
|
323
321
|
"""清理缓存"""
|
|
324
322
|
count = 0
|
|
325
|
-
raw_dir = self.cache_dir / "raw"
|
|
326
323
|
|
|
327
324
|
if older_than:
|
|
328
325
|
from datetime import timedelta
|
|
326
|
+
|
|
329
327
|
cutoff = today() - timedelta(days=older_than)
|
|
330
|
-
for cache_file in
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
328
|
+
for cache_file in self.cache_dir.rglob("*.parquet"):
|
|
329
|
+
try:
|
|
330
|
+
if cache_file.is_file():
|
|
331
|
+
mtime = parse_date(cache_file.stat().st_mtime)
|
|
332
|
+
if mtime < cutoff:
|
|
333
|
+
cache_file.unlink()
|
|
334
|
+
count += 1
|
|
335
|
+
except OSError:
|
|
336
|
+
continue
|
|
335
337
|
elif pattern:
|
|
336
|
-
for cache_file in
|
|
337
|
-
|
|
338
|
-
cache_file.
|
|
339
|
-
|
|
338
|
+
for cache_file in self.cache_dir.rglob(pattern):
|
|
339
|
+
try:
|
|
340
|
+
if cache_file.is_file():
|
|
341
|
+
cache_file.unlink()
|
|
342
|
+
count += 1
|
|
343
|
+
except OSError:
|
|
344
|
+
continue
|
|
340
345
|
else:
|
|
341
|
-
for cache_file in
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
346
|
+
for cache_file in self.cache_dir.rglob("*.parquet"):
|
|
347
|
+
try:
|
|
348
|
+
if cache_file.is_file():
|
|
349
|
+
cache_file.unlink()
|
|
350
|
+
count += 1
|
|
351
|
+
except OSError:
|
|
352
|
+
continue
|
|
345
353
|
|
|
346
354
|
logger.info(f"Cleared {count} cache files")
|
|
347
355
|
return count
|
|
@@ -354,7 +362,13 @@ class DataManager:
|
|
|
354
362
|
relative = str(path.relative_to(self.cache_dir))
|
|
355
363
|
sizes[relative] = format_size(path.stat().st_size)
|
|
356
364
|
|
|
357
|
-
sizes["_total"] = format_size(
|
|
365
|
+
sizes["_total"] = format_size(
|
|
366
|
+
sum(
|
|
367
|
+
path.stat().st_size
|
|
368
|
+
for path in self.cache_dir.rglob("*.parquet")
|
|
369
|
+
if path.is_file()
|
|
370
|
+
)
|
|
371
|
+
)
|
|
358
372
|
return sizes
|
|
359
373
|
|
|
360
374
|
# =============================================================================
|
|
@@ -369,7 +383,7 @@ class DataManager:
|
|
|
369
383
|
filter_st: Optional[bool] = None,
|
|
370
384
|
filter_suspended: Optional[bool] = None,
|
|
371
385
|
filter_new: Optional[int] = None,
|
|
372
|
-
inplace: bool = False
|
|
386
|
+
inplace: bool = False,
|
|
373
387
|
) -> pd.DataFrame:
|
|
374
388
|
"""数据清洗"""
|
|
375
389
|
if not inplace:
|
|
@@ -381,7 +395,7 @@ class DataManager:
|
|
|
381
395
|
outlier_count={},
|
|
382
396
|
st_filtered=0,
|
|
383
397
|
suspended_filtered=0,
|
|
384
|
-
new_stock_filtered=0
|
|
398
|
+
new_stock_filtered=0,
|
|
385
399
|
)
|
|
386
400
|
|
|
387
401
|
# 空值填充
|
|
@@ -404,14 +418,20 @@ class DataManager:
|
|
|
404
418
|
report.st_filtered = original_len - len(df)
|
|
405
419
|
|
|
406
420
|
# 过滤停牌
|
|
407
|
-
filter_suspended_flag =
|
|
421
|
+
filter_suspended_flag = (
|
|
422
|
+
filter_suspended
|
|
423
|
+
if filter_suspended is not None
|
|
424
|
+
else self.config.filter_suspended
|
|
425
|
+
)
|
|
408
426
|
if filter_suspended_flag:
|
|
409
427
|
original_len = len(df)
|
|
410
428
|
df = self._filter_suspended(df)
|
|
411
429
|
report.suspended_filtered = original_len - len(df)
|
|
412
430
|
|
|
413
431
|
# 过滤新股
|
|
414
|
-
filter_new_days =
|
|
432
|
+
filter_new_days = (
|
|
433
|
+
filter_new if filter_new is not None else self.config.filter_new
|
|
434
|
+
)
|
|
415
435
|
if filter_new_days and filter_new_days > 0:
|
|
416
436
|
original_len = len(df)
|
|
417
437
|
df = self._filter_new_stocks(df, filter_new_days)
|
|
@@ -506,7 +526,10 @@ class DataManager:
|
|
|
506
526
|
return {
|
|
507
527
|
**status,
|
|
508
528
|
"cache": self.get_cache_size(),
|
|
509
|
-
"config": {
|
|
529
|
+
"config": {
|
|
530
|
+
"source": self.config.source,
|
|
531
|
+
"cache_dir": str(self.cache_dir),
|
|
532
|
+
},
|
|
510
533
|
}
|
|
511
534
|
except Exception as e:
|
|
512
535
|
return {"status": "error", "error": str(e)}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|