yfin-mcp 0.1.0__tar.gz → 0.2.5__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.
- {yfin_mcp-0.1.0/yfin_mcp.egg-info → yfin_mcp-0.2.5}/PKG-INFO +93 -23
- {yfin_mcp-0.1.0 → yfin_mcp-0.2.5}/README.md +91 -20
- {yfin_mcp-0.1.0 → yfin_mcp-0.2.5}/pyproject.toml +5 -3
- yfin_mcp-0.2.5/src/yfin_mcp/__init__.py +1 -0
- yfin_mcp-0.2.5/src/yfin_mcp/__main__.py +4 -0
- yfin_mcp-0.2.5/src/yfin_mcp/cache_manager.py +150 -0
- yfin_mcp-0.2.5/src/yfin_mcp/pagination_utils.py +285 -0
- yfin_mcp-0.2.5/src/yfin_mcp/server.py +566 -0
- {yfin_mcp-0.1.0 → yfin_mcp-0.2.5/src/yfin_mcp.egg-info}/PKG-INFO +93 -23
- yfin_mcp-0.2.5/src/yfin_mcp.egg-info/SOURCES.txt +14 -0
- yfin_mcp-0.2.5/src/yfin_mcp.egg-info/entry_points.txt +2 -0
- yfin_mcp-0.2.5/src/yfin_mcp.egg-info/top_level.txt +1 -0
- yfin_mcp-0.1.0/yfin_mcp.egg-info/SOURCES.txt +0 -8
- yfin_mcp-0.1.0/yfin_mcp.egg-info/top_level.txt +0 -1
- {yfin_mcp-0.1.0 → yfin_mcp-0.2.5}/LICENSE +0 -0
- {yfin_mcp-0.1.0 → yfin_mcp-0.2.5}/setup.cfg +0 -0
- {yfin_mcp-0.1.0 → yfin_mcp-0.2.5/src}/yfin_mcp.egg-info/dependency_links.txt +0 -0
- {yfin_mcp-0.1.0 → yfin_mcp-0.2.5/src}/yfin_mcp.egg-info/requires.txt +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: yfin-mcp
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.5
|
|
4
4
|
Summary: Enhanced Yahoo Finance MCP Server with intelligent pagination, caching, and LLM-optimized responses
|
|
5
5
|
Author: AlexYoung (Original Author)
|
|
6
6
|
Author-email: fritzprix <innocentevil0914@gmail.com>
|
|
7
|
-
License: MIT
|
|
7
|
+
License-Expression: MIT
|
|
8
8
|
Project-URL: Homepage, https://github.com/fritzprix/yahoo-finance-mcp
|
|
9
9
|
Project-URL: Repository, https://github.com/fritzprix/yahoo-finance-mcp
|
|
10
10
|
Project-URL: Issues, https://github.com/fritzprix/yahoo-finance-mcp/issues
|
|
@@ -13,7 +13,6 @@ Keywords: mcp,model-context-protocol,yahoo-finance,yfinance,financial-data,stock
|
|
|
13
13
|
Classifier: Development Status :: 4 - Beta
|
|
14
14
|
Classifier: Intended Audience :: Developers
|
|
15
15
|
Classifier: Intended Audience :: Financial and Insurance Industry
|
|
16
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
17
16
|
Classifier: Programming Language :: Python :: 3
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
@@ -173,11 +172,21 @@ With this MCP server, you can use Claude to:
|
|
|
173
172
|
- pydantic
|
|
174
173
|
- and other packages for data processing
|
|
175
174
|
|
|
176
|
-
##
|
|
175
|
+
## Installation
|
|
176
|
+
|
|
177
|
+
### From PyPI (Recommended)
|
|
178
|
+
|
|
179
|
+
Install the package directly from PyPI:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
pip install yfin-mcp
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### From Source
|
|
177
186
|
|
|
178
187
|
1. Clone this repository:
|
|
179
188
|
```bash
|
|
180
|
-
git clone https://github.com/
|
|
189
|
+
git clone https://github.com/fritzprix/yahoo-finance-mcp.git
|
|
181
190
|
cd yahoo-finance-mcp
|
|
182
191
|
```
|
|
183
192
|
|
|
@@ -190,27 +199,47 @@ With this MCP server, you can use Claude to:
|
|
|
190
199
|
|
|
191
200
|
## Usage
|
|
192
201
|
|
|
193
|
-
###
|
|
202
|
+
### Integration with Claude for Desktop
|
|
194
203
|
|
|
195
|
-
|
|
204
|
+
After installing the package, you can integrate it with Claude for Desktop:
|
|
196
205
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
206
|
+
1. **Install the package** (if not already installed):
|
|
207
|
+
```bash
|
|
208
|
+
pip install yfin-mcp
|
|
209
|
+
```
|
|
200
210
|
|
|
201
|
-
|
|
211
|
+
2. **Configure Claude Desktop**:
|
|
212
|
+
- MacOS: Edit `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
213
|
+
- Windows: Edit `%APPDATA%\Claude\claude_desktop_config.json`
|
|
202
214
|
|
|
203
|
-
|
|
215
|
+
3. **Add the server configuration**:
|
|
204
216
|
|
|
205
|
-
|
|
217
|
+
**Using uvx (Recommended - No installation needed)**:
|
|
218
|
+
```json
|
|
219
|
+
{
|
|
220
|
+
"mcpServers": {
|
|
221
|
+
"yfinance": {
|
|
222
|
+
"command": "uvx",
|
|
223
|
+
"args": ["yfin-mcp"]
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
```
|
|
206
228
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
229
|
+
**Using Python directly (if installed via pip)**:
|
|
230
|
+
```json
|
|
231
|
+
{
|
|
232
|
+
"mcpServers": {
|
|
233
|
+
"yfinance": {
|
|
234
|
+
"command": "python",
|
|
235
|
+
"args": ["-m", "yfin_mcp"]
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
```
|
|
211
240
|
|
|
212
|
-
|
|
213
|
-
- macOS:
|
|
241
|
+
**For development/source installation**:
|
|
242
|
+
- macOS:
|
|
214
243
|
```json
|
|
215
244
|
{
|
|
216
245
|
"mcpServers": {
|
|
@@ -218,7 +247,7 @@ To integrate this server with Claude for Desktop:
|
|
|
218
247
|
"command": "uv",
|
|
219
248
|
"args": [
|
|
220
249
|
"--directory",
|
|
221
|
-
"/ABSOLUTE/PATH/TO/
|
|
250
|
+
"/ABSOLUTE/PATH/TO/yahoo-finance-mcp",
|
|
222
251
|
"run",
|
|
223
252
|
"server.py"
|
|
224
253
|
]
|
|
@@ -234,7 +263,7 @@ To integrate this server with Claude for Desktop:
|
|
|
234
263
|
"command": "uv",
|
|
235
264
|
"args": [
|
|
236
265
|
"--directory",
|
|
237
|
-
"C:\\ABSOLUTE\\PATH\\TO\\
|
|
266
|
+
"C:\\ABSOLUTE\\PATH\\TO\\yahoo-finance-mcp",
|
|
238
267
|
"run",
|
|
239
268
|
"server.py"
|
|
240
269
|
]
|
|
@@ -243,9 +272,50 @@ To integrate this server with Claude for Desktop:
|
|
|
243
272
|
}
|
|
244
273
|
```
|
|
245
274
|
|
|
246
|
-
|
|
275
|
+
4. **Restart Claude for Desktop**
|
|
276
|
+
|
|
277
|
+
### Development Mode
|
|
278
|
+
|
|
279
|
+
For testing with MCP Inspector:
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
# From source
|
|
283
|
+
uv run yfin-mcp
|
|
284
|
+
|
|
285
|
+
# Or if installed via pip
|
|
286
|
+
python -m yfin_mcp
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## Publishing to PyPI
|
|
290
|
+
|
|
291
|
+
To build and publish the package, use the provided scripts. You can optionally provide an argument to bump the version:
|
|
292
|
+
|
|
293
|
+
### Windows
|
|
294
|
+
```bash
|
|
295
|
+
# Just build and publish current version
|
|
296
|
+
publish_package.bat
|
|
297
|
+
|
|
298
|
+
# Bump version and then publish
|
|
299
|
+
publish_package.bat patch
|
|
300
|
+
publish_package.bat minor
|
|
301
|
+
publish_package.bat major
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### macOS/Linux
|
|
305
|
+
```bash
|
|
306
|
+
chmod +x publish_package.sh
|
|
307
|
+
|
|
308
|
+
# Just build and publish current version
|
|
309
|
+
./publish_package.sh
|
|
310
|
+
|
|
311
|
+
# Bump version and then publish
|
|
312
|
+
./publish_package.sh patch
|
|
313
|
+
./publish_package.sh minor
|
|
314
|
+
./publish_package.sh major
|
|
315
|
+
```
|
|
247
316
|
|
|
248
|
-
|
|
317
|
+
> [!NOTE]
|
|
318
|
+
> The scripts will build the package into the `dist/` directory and then use `twine` to upload it. Ensure you have your PyPI credentials configured in `~/.pypirc` (or `%HOME%\.pypirc` on Windows) or set the `TWINE_PASSWORD` environment variable.
|
|
249
319
|
|
|
250
320
|
## License
|
|
251
321
|
|
|
@@ -140,11 +140,21 @@ With this MCP server, you can use Claude to:
|
|
|
140
140
|
- pydantic
|
|
141
141
|
- and other packages for data processing
|
|
142
142
|
|
|
143
|
-
##
|
|
143
|
+
## Installation
|
|
144
|
+
|
|
145
|
+
### From PyPI (Recommended)
|
|
146
|
+
|
|
147
|
+
Install the package directly from PyPI:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
pip install yfin-mcp
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### From Source
|
|
144
154
|
|
|
145
155
|
1. Clone this repository:
|
|
146
156
|
```bash
|
|
147
|
-
git clone https://github.com/
|
|
157
|
+
git clone https://github.com/fritzprix/yahoo-finance-mcp.git
|
|
148
158
|
cd yahoo-finance-mcp
|
|
149
159
|
```
|
|
150
160
|
|
|
@@ -157,27 +167,47 @@ With this MCP server, you can use Claude to:
|
|
|
157
167
|
|
|
158
168
|
## Usage
|
|
159
169
|
|
|
160
|
-
###
|
|
170
|
+
### Integration with Claude for Desktop
|
|
161
171
|
|
|
162
|
-
|
|
172
|
+
After installing the package, you can integrate it with Claude for Desktop:
|
|
163
173
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
174
|
+
1. **Install the package** (if not already installed):
|
|
175
|
+
```bash
|
|
176
|
+
pip install yfin-mcp
|
|
177
|
+
```
|
|
167
178
|
|
|
168
|
-
|
|
179
|
+
2. **Configure Claude Desktop**:
|
|
180
|
+
- MacOS: Edit `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
181
|
+
- Windows: Edit `%APPDATA%\Claude\claude_desktop_config.json`
|
|
169
182
|
|
|
170
|
-
|
|
183
|
+
3. **Add the server configuration**:
|
|
171
184
|
|
|
172
|
-
|
|
185
|
+
**Using uvx (Recommended - No installation needed)**:
|
|
186
|
+
```json
|
|
187
|
+
{
|
|
188
|
+
"mcpServers": {
|
|
189
|
+
"yfinance": {
|
|
190
|
+
"command": "uvx",
|
|
191
|
+
"args": ["yfin-mcp"]
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
```
|
|
173
196
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
197
|
+
**Using Python directly (if installed via pip)**:
|
|
198
|
+
```json
|
|
199
|
+
{
|
|
200
|
+
"mcpServers": {
|
|
201
|
+
"yfinance": {
|
|
202
|
+
"command": "python",
|
|
203
|
+
"args": ["-m", "yfin_mcp"]
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
```
|
|
178
208
|
|
|
179
|
-
|
|
180
|
-
- macOS:
|
|
209
|
+
**For development/source installation**:
|
|
210
|
+
- macOS:
|
|
181
211
|
```json
|
|
182
212
|
{
|
|
183
213
|
"mcpServers": {
|
|
@@ -185,7 +215,7 @@ To integrate this server with Claude for Desktop:
|
|
|
185
215
|
"command": "uv",
|
|
186
216
|
"args": [
|
|
187
217
|
"--directory",
|
|
188
|
-
"/ABSOLUTE/PATH/TO/
|
|
218
|
+
"/ABSOLUTE/PATH/TO/yahoo-finance-mcp",
|
|
189
219
|
"run",
|
|
190
220
|
"server.py"
|
|
191
221
|
]
|
|
@@ -201,7 +231,7 @@ To integrate this server with Claude for Desktop:
|
|
|
201
231
|
"command": "uv",
|
|
202
232
|
"args": [
|
|
203
233
|
"--directory",
|
|
204
|
-
"C:\\ABSOLUTE\\PATH\\TO\\
|
|
234
|
+
"C:\\ABSOLUTE\\PATH\\TO\\yahoo-finance-mcp",
|
|
205
235
|
"run",
|
|
206
236
|
"server.py"
|
|
207
237
|
]
|
|
@@ -210,9 +240,50 @@ To integrate this server with Claude for Desktop:
|
|
|
210
240
|
}
|
|
211
241
|
```
|
|
212
242
|
|
|
213
|
-
|
|
243
|
+
4. **Restart Claude for Desktop**
|
|
244
|
+
|
|
245
|
+
### Development Mode
|
|
246
|
+
|
|
247
|
+
For testing with MCP Inspector:
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
# From source
|
|
251
|
+
uv run yfin-mcp
|
|
252
|
+
|
|
253
|
+
# Or if installed via pip
|
|
254
|
+
python -m yfin_mcp
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## Publishing to PyPI
|
|
258
|
+
|
|
259
|
+
To build and publish the package, use the provided scripts. You can optionally provide an argument to bump the version:
|
|
260
|
+
|
|
261
|
+
### Windows
|
|
262
|
+
```bash
|
|
263
|
+
# Just build and publish current version
|
|
264
|
+
publish_package.bat
|
|
265
|
+
|
|
266
|
+
# Bump version and then publish
|
|
267
|
+
publish_package.bat patch
|
|
268
|
+
publish_package.bat minor
|
|
269
|
+
publish_package.bat major
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### macOS/Linux
|
|
273
|
+
```bash
|
|
274
|
+
chmod +x publish_package.sh
|
|
275
|
+
|
|
276
|
+
# Just build and publish current version
|
|
277
|
+
./publish_package.sh
|
|
278
|
+
|
|
279
|
+
# Bump version and then publish
|
|
280
|
+
./publish_package.sh patch
|
|
281
|
+
./publish_package.sh minor
|
|
282
|
+
./publish_package.sh major
|
|
283
|
+
```
|
|
214
284
|
|
|
215
|
-
|
|
285
|
+
> [!NOTE]
|
|
286
|
+
> The scripts will build the package into the `dist/` directory and then use `twine` to upload it. Ensure you have your PyPI credentials configured in `~/.pypirc` (or `%HOME%\.pypirc` on Windows) or set the `TWINE_PASSWORD` environment variable.
|
|
216
287
|
|
|
217
288
|
## License
|
|
218
289
|
|
|
@@ -4,11 +4,11 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "yfin-mcp"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.2.5"
|
|
8
8
|
description = "Enhanced Yahoo Finance MCP Server with intelligent pagination, caching, and LLM-optimized responses"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
11
|
-
license =
|
|
11
|
+
license = "MIT"
|
|
12
12
|
authors = [
|
|
13
13
|
{name = "fritzprix", email = "innocentevil0914@gmail.com"},
|
|
14
14
|
{name = "AlexYoung (Original Author)"}
|
|
@@ -27,7 +27,6 @@ classifiers = [
|
|
|
27
27
|
"Development Status :: 4 - Beta",
|
|
28
28
|
"Intended Audience :: Developers",
|
|
29
29
|
"Intended Audience :: Financial and Insurance Industry",
|
|
30
|
-
"License :: OSI Approved :: MIT License",
|
|
31
30
|
"Programming Language :: Python :: 3",
|
|
32
31
|
"Programming Language :: Python :: 3.11",
|
|
33
32
|
"Programming Language :: Python :: 3.12",
|
|
@@ -40,6 +39,9 @@ dependencies = [
|
|
|
40
39
|
"pandas>=2.0.0",
|
|
41
40
|
]
|
|
42
41
|
|
|
42
|
+
[project.scripts]
|
|
43
|
+
yfin-mcp = "yfin_mcp.server:main"
|
|
44
|
+
|
|
43
45
|
[project.urls]
|
|
44
46
|
Homepage = "https://github.com/fritzprix/yahoo-finance-mcp"
|
|
45
47
|
Repository = "https://github.com/fritzprix/yahoo-finance-mcp"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# yfin_mcp package
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Thread-safe LRU cache manager with TTL support for Yahoo Finance MCP server.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import threading
|
|
6
|
+
import time
|
|
7
|
+
from collections import OrderedDict
|
|
8
|
+
from typing import Any, Callable, Optional, Tuple
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class CacheManager:
|
|
12
|
+
"""Thread-safe LRU cache with TTL (Time To Live) support."""
|
|
13
|
+
|
|
14
|
+
def __init__(self, max_size: int = 100):
|
|
15
|
+
"""
|
|
16
|
+
Initialize cache manager.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
max_size: Maximum number of entries in cache (LRU eviction)
|
|
20
|
+
"""
|
|
21
|
+
self._cache: OrderedDict[str, Tuple[Any, float, float]] = OrderedDict()
|
|
22
|
+
self._max_size = max_size
|
|
23
|
+
self._lock = threading.Lock()
|
|
24
|
+
self._hits = 0
|
|
25
|
+
self._misses = 0
|
|
26
|
+
|
|
27
|
+
def get(self, key: str) -> Optional[Tuple[Any, float]]:
|
|
28
|
+
"""
|
|
29
|
+
Get value from cache if it exists and hasn't expired.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
key: Cache key
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
Tuple of (value, age_seconds) if found and valid, None otherwise
|
|
36
|
+
"""
|
|
37
|
+
with self._lock:
|
|
38
|
+
if key not in self._cache:
|
|
39
|
+
self._misses += 1
|
|
40
|
+
return None
|
|
41
|
+
|
|
42
|
+
value, timestamp, ttl = self._cache[key]
|
|
43
|
+
age = time.time() - timestamp
|
|
44
|
+
|
|
45
|
+
# Check if expired
|
|
46
|
+
if age > ttl:
|
|
47
|
+
del self._cache[key]
|
|
48
|
+
self._misses += 1
|
|
49
|
+
return None
|
|
50
|
+
|
|
51
|
+
# Move to end (most recently used)
|
|
52
|
+
self._cache.move_to_end(key)
|
|
53
|
+
self._hits += 1
|
|
54
|
+
return (value, age)
|
|
55
|
+
|
|
56
|
+
def set(self, key: str, value: Any, ttl_seconds: float):
|
|
57
|
+
"""
|
|
58
|
+
Set value in cache with TTL.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
key: Cache key
|
|
62
|
+
value: Value to cache
|
|
63
|
+
ttl_seconds: Time to live in seconds
|
|
64
|
+
"""
|
|
65
|
+
with self._lock:
|
|
66
|
+
# Remove oldest if at capacity
|
|
67
|
+
if len(self._cache) >= self._max_size and key not in self._cache:
|
|
68
|
+
self._cache.popitem(last=False)
|
|
69
|
+
|
|
70
|
+
self._cache[key] = (value, time.time(), ttl_seconds)
|
|
71
|
+
self._cache.move_to_end(key)
|
|
72
|
+
|
|
73
|
+
def get_or_set(
|
|
74
|
+
self,
|
|
75
|
+
key: str,
|
|
76
|
+
factory_func: Callable[[], Any],
|
|
77
|
+
ttl_seconds: float
|
|
78
|
+
) -> Tuple[Any, Optional[float]]:
|
|
79
|
+
"""
|
|
80
|
+
Get from cache or compute and cache if missing/expired.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
key: Cache key
|
|
84
|
+
factory_func: Function to call if cache miss
|
|
85
|
+
ttl_seconds: TTL for new cache entries
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
Tuple of (value, age_seconds). age_seconds is None for cache miss.
|
|
89
|
+
"""
|
|
90
|
+
# Try to get from cache
|
|
91
|
+
cached = self.get(key)
|
|
92
|
+
if cached is not None:
|
|
93
|
+
return cached
|
|
94
|
+
|
|
95
|
+
# Cache miss - compute value
|
|
96
|
+
try:
|
|
97
|
+
value = factory_func()
|
|
98
|
+
self.set(key, value, ttl_seconds)
|
|
99
|
+
return (value, None) # None age indicates fresh data
|
|
100
|
+
except Exception as e:
|
|
101
|
+
# Don't cache errors
|
|
102
|
+
raise e
|
|
103
|
+
|
|
104
|
+
def clear(self):
|
|
105
|
+
"""Clear all cache entries."""
|
|
106
|
+
with self._lock:
|
|
107
|
+
self._cache.clear()
|
|
108
|
+
self._hits = 0
|
|
109
|
+
self._misses = 0
|
|
110
|
+
|
|
111
|
+
def get_stats(self) -> dict:
|
|
112
|
+
"""
|
|
113
|
+
Get cache statistics.
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
Dict with hits, misses, size, and hit rate
|
|
117
|
+
"""
|
|
118
|
+
with self._lock:
|
|
119
|
+
total = self._hits + self._misses
|
|
120
|
+
hit_rate = (self._hits / total * 100) if total > 0 else 0
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
"hits": self._hits,
|
|
124
|
+
"misses": self._misses,
|
|
125
|
+
"size": len(self._cache),
|
|
126
|
+
"max_size": self._max_size,
|
|
127
|
+
"hit_rate": f"{hit_rate:.1f}%"
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
# Global cache instance
|
|
132
|
+
_global_cache: Optional[CacheManager] = None
|
|
133
|
+
_cache_lock = threading.Lock()
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def get_cache() -> CacheManager:
|
|
137
|
+
"""
|
|
138
|
+
Get the global cache instance (singleton pattern).
|
|
139
|
+
|
|
140
|
+
Returns:
|
|
141
|
+
Global CacheManager instance
|
|
142
|
+
"""
|
|
143
|
+
global _global_cache
|
|
144
|
+
|
|
145
|
+
if _global_cache is None:
|
|
146
|
+
with _cache_lock:
|
|
147
|
+
if _global_cache is None:
|
|
148
|
+
_global_cache = CacheManager(max_size=100)
|
|
149
|
+
|
|
150
|
+
return _global_cache
|