v0.9.0 — TEFAS v2 migration completes
Breaking change
TEFAS production'ı Nisan 2026'da tamamen yeni Next.js mimarisine geçti. Tüm /api/DB/* legacy endpointleri 404 dönüyor. Bu sürüm Fund.history(), Fund.info ve Fund.allocation'ı yeni /api/funds/* v2 mimarisine taşıyor.
PR #16 (@muhammedaksam) ilk yarıyı (info/screen/search/management_fees) geçirdi; v0.9.0 kalan kısmı tamamlıyor ve allocation için Akamai WAF bypass çözümü ekliyor.
Closes #15.
Migrated
Fund.history() → fonFiyatBilgiGetir
Sabit periyod enum'una map ediliyor:
| Period | periyod |
~Rows |
|---|---|---|
1d/5d |
13 (haftalık) | 5 |
1mo |
1 | 22 |
3mo |
3 | 62 |
6mo |
6 | 127 |
ytd |
0 | (değişken) |
1y |
12 | 253 |
3y |
36 | 753 |
5y/max |
60 | 1255 |
- Maksimum 5 yıl geçmiş — yeni API'nin sertçe sabit aralıkları var
- Keyfi
start/endaralıkları en küçük kapsayan bucket'tan client-side filtreli FundSize/Investorssütunları yeni API'de yok → backwards-compat için NaN/0 dolduruluyor
Fund.info — restore edilen alanlar (fonProfilBilgiGetir)
PR #16'nın None yaptığı alanlar tekrar geliyor:
isin(ISIN kodu)kap_link(KAP fon bilgi sayfası — bu sayedeFund.get_holdings()tekrar çalışıyor)first_trading_time/last_trading_time(işlem saatleri)buy_valor/sell_valor(alış/satış valörü gün sayısı)entry_fee/exit_fee(komisyonlar)min_purchase/min_redemption/max_purchase/max_redemptiontefas_status- Yeni alan:
fund_class("YAT" veya "EMK") —fonGetiriBazliBilgiGetirüzerinden iki listeye düşerek otomatik tespit
Hâlâ yok:
weekly_return(None döner — yeni API döndürmüyor)
Fund.allocation → Scrapling/Camoufox StealthyFetcher
TEFAS yeni Next.js sitesi allocation'ı SSR HTML içine varlikData JSON'u olarak embed ediyor. Akamai TSPD JS challenge plain headless Chromium'u da yakaladığı için Scrapling'in Camoufox tabanlı StealthyFetcher'ı (stealth Firefox build) kullanılıyor.
```bash
pip install borsapy[allocation]
camoufox fetch # tek seferlik tarayıcı binary indirme (~80 MB)
```
```python
import borsapy as bp
fon = bp.Fund("AAK")
fon.allocation
Date asset_type asset_name weight
2026-05-03 Vadeli İşlemler Nakit Teminatları Futures Margin 54.68
2026-05-03 Hisse Senedi Stocks 29.75
2026-05-03 Yatırım Fonları Katılma Payları Fund Shares 8.89
2026-05-03 Finansman Bonosu Commercial Paper 5.40
2026-05-03 Özel Sektör Tahvili Corporate Bonds 1.28
```
Sadece güncel snapshot dönüyor (tek tarih).
Fund.allocation_history() — deprecated
TEFAS yeni mimaride tarihsel allocation'ı hiçbir endpointte sunmuyor. Method DeprecationWarning ile aynı anlık snapshot'ı döndürüyor; date-range argümanları kabul ediliyor ama yok sayılıyor.
Removed
_get_history_chunked(),_fetch_history_chunk()(eski 90 günlük WAF chunking artık gereksiz)BASE_URL_LEGACY,MAX_CHUNK_DAYSconstants
New optional dependency
```bash
pip install borsapy[allocation] # → scrapling[fetchers]>=0.4.0
camoufox fetch # → ~80 MB Camoufox binary
```
Tests
- 813 passed, 63 skipped
- 21 yeni unit test (
tests/test_tefas_v2.py): periyod mapping, history mock, profile merge, fund_class detection, HTML allocation parsing, Scrapling lazy-import tests/test_management_fees.pymock'ları yeni v2 envelope shape'ine güncellendi (camelCase +{errorCode, errorMessage, resultList})- Ruff clean
Migration guide (v0.8.x → v0.9.0)
| Use case | v0.8.x | v0.9.0 |
|---|---|---|
fund.history(period=\"1mo\") |
OHLCV-like 3 sütun | Price çalışır; FundSize/Investors artık NaN/0 |
fund.history(period=\"max\") |
~5 yıl | Aynı (5 yıl üst limit) |
fund.history(start=..., end=...) |
Chunked WAF requests | Tek bucket + client-side filter |
fund.info[\"isin\"] |
None (PR #16 sonrası) | Restore edildi |
fund.info[\"kap_link\"] |
None | Restore edildi |
fund.info[\"weekly_return\"] |
Vardı (eski) | None (yeni API yok) |
fund.allocation |
Lokal/eski API | Scrapling gerekli |
fund.allocation_history(period=\"3mo\") |
90 günlük geçmiş | DeprecationWarning + güncel snapshot |
fund.get_holdings(api_key=...) |
PR #16 sonrası kırık | Çalışıyor (kap_link restore edildi) |