mirror of
https://github.com/eitchtee/WYGIWYH.git
synced 2026-04-25 01:58:54 +02:00
Merge pull request #196
feat(automatic-exchange-rates): add Synth Finance Stock
This commit is contained in:
@@ -6,6 +6,7 @@ from django.utils import timezone
|
|||||||
|
|
||||||
from apps.currencies.exchange_rates.providers import (
|
from apps.currencies.exchange_rates.providers import (
|
||||||
SynthFinanceProvider,
|
SynthFinanceProvider,
|
||||||
|
SynthFinanceStockProvider,
|
||||||
CoinGeckoFreeProvider,
|
CoinGeckoFreeProvider,
|
||||||
CoinGeckoProProvider,
|
CoinGeckoProProvider,
|
||||||
)
|
)
|
||||||
@@ -17,6 +18,7 @@ logger = logging.getLogger(__name__)
|
|||||||
# Map service types to provider classes
|
# Map service types to provider classes
|
||||||
PROVIDER_MAPPING = {
|
PROVIDER_MAPPING = {
|
||||||
"synth_finance": SynthFinanceProvider,
|
"synth_finance": SynthFinanceProvider,
|
||||||
|
"synth_finance_stock": SynthFinanceStockProvider,
|
||||||
"coingecko_free": CoinGeckoFreeProvider,
|
"coingecko_free": CoinGeckoFreeProvider,
|
||||||
"coingecko_pro": CoinGeckoProProvider,
|
"coingecko_pro": CoinGeckoProProvider,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,3 +150,68 @@ class CoinGeckoProProvider(CoinGeckoFreeProvider):
|
|||||||
super().__init__(api_key)
|
super().__init__(api_key)
|
||||||
self.session = requests.Session()
|
self.session = requests.Session()
|
||||||
self.session.headers.update({"x-cg-pro-api-key": api_key})
|
self.session.headers.update({"x-cg-pro-api-key": api_key})
|
||||||
|
|
||||||
|
|
||||||
|
class SynthFinanceStockProvider(ExchangeRateProvider):
|
||||||
|
"""Implementation for Synth Finance API Real-Time Prices endpoint (synthfinance.com)"""
|
||||||
|
|
||||||
|
BASE_URL = "https://api.synthfinance.com/tickers"
|
||||||
|
rates_inverted = True
|
||||||
|
|
||||||
|
def __init__(self, api_key: str = None):
|
||||||
|
super().__init__(api_key)
|
||||||
|
self.session = requests.Session()
|
||||||
|
self.session.headers.update(
|
||||||
|
{"Authorization": f"Bearer {self.api_key}", "accept": "application/json"}
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_rates(
|
||||||
|
self, target_currencies: QuerySet, exchange_currencies: set
|
||||||
|
) -> List[Tuple[Currency, Currency, Decimal]]:
|
||||||
|
results = []
|
||||||
|
|
||||||
|
for currency in target_currencies:
|
||||||
|
if currency.exchange_currency not in exchange_currencies:
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Same currency has rate of 1
|
||||||
|
if currency.code == currency.exchange_currency.code:
|
||||||
|
rate = Decimal("1")
|
||||||
|
results.append((currency.exchange_currency, currency, rate))
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Fetch real-time price for this ticker
|
||||||
|
response = self.session.get(
|
||||||
|
f"{self.BASE_URL}/{currency.code}/real-time"
|
||||||
|
)
|
||||||
|
response.raise_for_status()
|
||||||
|
data = response.json()
|
||||||
|
|
||||||
|
# Use fair market value as the rate
|
||||||
|
rate = Decimal(data["data"]["fair_market_value"])
|
||||||
|
results.append((currency.exchange_currency, currency, rate))
|
||||||
|
|
||||||
|
# Log API usage
|
||||||
|
credits_used = data["meta"]["credits_used"]
|
||||||
|
credits_remaining = data["meta"]["credits_remaining"]
|
||||||
|
logger.info(
|
||||||
|
f"Synth Finance API call for {currency.code}: {credits_used} credits used, {credits_remaining} remaining"
|
||||||
|
)
|
||||||
|
except requests.RequestException as e:
|
||||||
|
logger.error(
|
||||||
|
f"Error fetching rate from Synth Finance API for ticker {currency.code}: {e}",
|
||||||
|
exc_info=True,
|
||||||
|
)
|
||||||
|
except KeyError as e:
|
||||||
|
logger.error(
|
||||||
|
f"Unexpected response structure from Synth Finance API for ticker {currency.code}: {e}",
|
||||||
|
exc_info=True,
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(
|
||||||
|
f"Unexpected error processing Synth Finance data for ticker {currency.code}: {e}",
|
||||||
|
exc_info=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
return results
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 5.1.6 on 2025-03-02 01:28
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('currencies', '0011_remove_exchangerateservice_fetch_interval_hours_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='exchangerateservice',
|
||||||
|
name='service_type',
|
||||||
|
field=models.CharField(choices=[('synth_finance', 'Synth Finance'), ('synth_finance_stock', 'Synth Finance Stock'), ('coingecko_free', 'CoinGecko (Demo/Free)'), ('coingecko_pro', 'CoinGecko (Pro)')], max_length=255, verbose_name='Service Type'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -92,6 +92,7 @@ class ExchangeRateService(models.Model):
|
|||||||
|
|
||||||
class ServiceType(models.TextChoices):
|
class ServiceType(models.TextChoices):
|
||||||
SYNTH_FINANCE = "synth_finance", "Synth Finance"
|
SYNTH_FINANCE = "synth_finance", "Synth Finance"
|
||||||
|
SYNTH_FINANCE_STOCK = "synth_finance_stock", "Synth Finance Stock"
|
||||||
COINGECKO_FREE = "coingecko_free", "CoinGecko (Demo/Free)"
|
COINGECKO_FREE = "coingecko_free", "CoinGecko (Demo/Free)"
|
||||||
COINGECKO_PRO = "coingecko_pro", "CoinGecko (Pro)"
|
COINGECKO_PRO = "coingecko_pro", "CoinGecko (Pro)"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user