quantcli 0.1.14__tar.gz → 0.1.15__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.15}/PKG-INFO +1 -1
- {quantcli-0.1.14 → quantcli-0.1.15}/pyproject.toml +1 -1
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/core/data.py +80 -48
- {quantcli-0.1.14 → quantcli-0.1.15/quantcli.egg-info}/PKG-INFO +1 -1
- {quantcli-0.1.14 → quantcli-0.1.15}/LICENSE +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/README.md +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/cli.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/core/__init__.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/core/backtest.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/core/factor.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/datasources/__init__.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/datasources/akshare.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/datasources/baostock.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/datasources/base.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/datasources/cache.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/datasources/fundamentals/__init__.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/datasources/fundamentals/provider.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/datasources/mixed.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/datasources/mysql.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/datasources/sync/__init__.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/datasources/sync/akshare.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/datasources/sync/base.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/datasources/sync/gm.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/datasources/sync/gm_fundamental.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/__init__.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_001.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_002.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_003.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_004.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_005.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_006.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_007.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_008.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_009.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_010.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_011.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_012.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_013.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_014.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_015.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_016.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_017.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_018.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_019.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_020.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_021.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_022.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_023.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_024.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_025.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_026.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_027.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_028.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_029.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_030.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_031.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_032.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_033.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_034.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_035.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_036.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_037.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_038.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_039.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/alpha101/alpha_040.yaml +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/base.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/compute.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/loader.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/pipeline.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/ranking.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/ranking_executor.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/screening.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/factors/screening_executor.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/models/bar.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/parser/__init__.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/parser/constants.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/parser/formula.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/utils/__init__.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/utils/env.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/utils/logger.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/utils/path.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/utils/symbol_utils.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/utils/time.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli/utils/validate.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli.egg-info/SOURCES.txt +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli.egg-info/dependency_links.txt +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli.egg-info/entry_points.txt +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli.egg-info/requires.txt +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/quantcli.egg-info/top_level.txt +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/setup.cfg +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/tests/test_akshare_integration.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/tests/test_builtin_factors.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/tests/test_cli.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/tests/test_datasources.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/tests/test_factors.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/tests/test_gm_executors.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/tests/test_mixed_datasource.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/tests/test_multi_factor.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/tests/test_pipeline_integration.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/tests/test_symbol_utils.py +0 -0
- {quantcli-0.1.14 → quantcli-0.1.15}/tests/test_time.py +0 -0
|
@@ -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,62 @@ 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:
|
|
323
315
|
"""清理缓存"""
|
|
324
316
|
count = 0
|
|
325
|
-
|
|
317
|
+
|
|
318
|
+
# 清理所有缓存子目录
|
|
319
|
+
cache_subdirs = ["raw", "prices", "stocklist", "calendar"]
|
|
326
320
|
|
|
327
321
|
if older_than:
|
|
328
322
|
from datetime import timedelta
|
|
323
|
+
|
|
329
324
|
cutoff = today() - timedelta(days=older_than)
|
|
330
|
-
for
|
|
331
|
-
|
|
332
|
-
if
|
|
333
|
-
cache_file.
|
|
334
|
-
|
|
325
|
+
for subdir in cache_subdirs:
|
|
326
|
+
dir_path = self.cache_dir / subdir
|
|
327
|
+
if dir_path.exists():
|
|
328
|
+
for cache_file in dir_path.rglob("*.parquet"):
|
|
329
|
+
try:
|
|
330
|
+
mtime = parse_date(cache_file.stat().st_mtime)
|
|
331
|
+
if mtime < cutoff:
|
|
332
|
+
cache_file.unlink()
|
|
333
|
+
count += 1
|
|
334
|
+
except OSError:
|
|
335
|
+
continue
|
|
335
336
|
elif pattern:
|
|
336
|
-
for
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
337
|
+
for subdir in cache_subdirs:
|
|
338
|
+
dir_path = self.cache_dir / subdir
|
|
339
|
+
if dir_path.exists():
|
|
340
|
+
for cache_file in dir_path.rglob(pattern):
|
|
341
|
+
if cache_file.is_file():
|
|
342
|
+
try:
|
|
343
|
+
cache_file.unlink()
|
|
344
|
+
count += 1
|
|
345
|
+
except OSError:
|
|
346
|
+
continue
|
|
340
347
|
else:
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
348
|
+
# 清理所有缓存目录
|
|
349
|
+
for subdir in cache_subdirs:
|
|
350
|
+
dir_path = self.cache_dir / subdir
|
|
351
|
+
if dir_path.exists():
|
|
352
|
+
for cache_file in dir_path.rglob("*.parquet"):
|
|
353
|
+
try:
|
|
354
|
+
cache_file.unlink()
|
|
355
|
+
count += 1
|
|
356
|
+
except OSError:
|
|
357
|
+
continue
|
|
358
|
+
|
|
359
|
+
# 确保目录结构存在
|
|
360
|
+
for subdir in cache_subdirs:
|
|
361
|
+
ensure_dir(self.cache_dir / subdir)
|
|
345
362
|
|
|
346
363
|
logger.info(f"Cleared {count} cache files")
|
|
347
364
|
return count
|
|
@@ -354,7 +371,13 @@ class DataManager:
|
|
|
354
371
|
relative = str(path.relative_to(self.cache_dir))
|
|
355
372
|
sizes[relative] = format_size(path.stat().st_size)
|
|
356
373
|
|
|
357
|
-
sizes["_total"] = format_size(
|
|
374
|
+
sizes["_total"] = format_size(
|
|
375
|
+
sum(
|
|
376
|
+
path.stat().st_size
|
|
377
|
+
for path in self.cache_dir.rglob("*.parquet")
|
|
378
|
+
if path.is_file()
|
|
379
|
+
)
|
|
380
|
+
)
|
|
358
381
|
return sizes
|
|
359
382
|
|
|
360
383
|
# =============================================================================
|
|
@@ -369,7 +392,7 @@ class DataManager:
|
|
|
369
392
|
filter_st: Optional[bool] = None,
|
|
370
393
|
filter_suspended: Optional[bool] = None,
|
|
371
394
|
filter_new: Optional[int] = None,
|
|
372
|
-
inplace: bool = False
|
|
395
|
+
inplace: bool = False,
|
|
373
396
|
) -> pd.DataFrame:
|
|
374
397
|
"""数据清洗"""
|
|
375
398
|
if not inplace:
|
|
@@ -381,7 +404,7 @@ class DataManager:
|
|
|
381
404
|
outlier_count={},
|
|
382
405
|
st_filtered=0,
|
|
383
406
|
suspended_filtered=0,
|
|
384
|
-
new_stock_filtered=0
|
|
407
|
+
new_stock_filtered=0,
|
|
385
408
|
)
|
|
386
409
|
|
|
387
410
|
# 空值填充
|
|
@@ -404,14 +427,20 @@ class DataManager:
|
|
|
404
427
|
report.st_filtered = original_len - len(df)
|
|
405
428
|
|
|
406
429
|
# 过滤停牌
|
|
407
|
-
filter_suspended_flag =
|
|
430
|
+
filter_suspended_flag = (
|
|
431
|
+
filter_suspended
|
|
432
|
+
if filter_suspended is not None
|
|
433
|
+
else self.config.filter_suspended
|
|
434
|
+
)
|
|
408
435
|
if filter_suspended_flag:
|
|
409
436
|
original_len = len(df)
|
|
410
437
|
df = self._filter_suspended(df)
|
|
411
438
|
report.suspended_filtered = original_len - len(df)
|
|
412
439
|
|
|
413
440
|
# 过滤新股
|
|
414
|
-
filter_new_days =
|
|
441
|
+
filter_new_days = (
|
|
442
|
+
filter_new if filter_new is not None else self.config.filter_new
|
|
443
|
+
)
|
|
415
444
|
if filter_new_days and filter_new_days > 0:
|
|
416
445
|
original_len = len(df)
|
|
417
446
|
df = self._filter_new_stocks(df, filter_new_days)
|
|
@@ -506,7 +535,10 @@ class DataManager:
|
|
|
506
535
|
return {
|
|
507
536
|
**status,
|
|
508
537
|
"cache": self.get_cache_size(),
|
|
509
|
-
"config": {
|
|
538
|
+
"config": {
|
|
539
|
+
"source": self.config.source,
|
|
540
|
+
"cache_dir": str(self.cache_dir),
|
|
541
|
+
},
|
|
510
542
|
}
|
|
511
543
|
except Exception as e:
|
|
512
544
|
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
|
|
File without changes
|