3 market api (#8)
* Creazione branch tool, refactor degli import e soppressione dei warning * Update pytest configuration and dependencies in pyproject.toml * Add news API integration and related configurations - Update .env.example to include NEWS_API_KEY configuration - Add newsapi-python dependency in pyproject.toml - Implement NewsAPI class for fetching news articles - Create Article model for structured news data - Add tests for NewsAPI functionality in test_news_api.py - Update pytest configuration to include news marker * Add news API functionality and update tests for article retrieval * ToDo: 1. Aggiungere un aggregator per i dati recuperati dai provider. 2. Lavorare effettivamente all'issue Done: 1. creati test per i provider 2. creato market_providers_api_demo.py per mostrare i dati recuperati dalle api dei providers 3. aggiornato i provider 4. creato il provider binance sia pubblico che con chiave 5. creato error_handler.py per gestire decoratori e utilità: retry automatico, gestione timeout... * Refactor news API integration to use NewsApiWrapper and GnewsWrapper; add tests for Gnews API functionality * Add CryptoPanic API integration and related tests; update .env.example and test configurations * Implement WrapperHandler for managing multiple news API wrappers; add tests for wrapper functionality * Enhance WrapperHandler - docstrings - add try_call_all method - update tests * pre merge con phil * Add DuckDuckGo and Google News wrappers; refactor CryptoPanic and NewsAPI - Implemented DuckDuckGoWrapper for news retrieval using DuckDuckGo tools. - Added GoogleNewsWrapper for accessing Google News RSS feed. - Refactored CryptoPanicWrapper to unify get_top_headlines and get_latest_news methods. - Updated NewsApiWrapper to simplify top headlines retrieval. - Added tests for DuckDuckGo and Google News wrappers. - Enhanced documentation for CryptoPanicWrapper and NewsApiWrapper. - Created base module for social media integrations. * - Refactor struttura progetto: divisione tra agent e toolkit * Refactor try_call_all method to return a dictionary of results; update tests for success and partial failures * Fix class and test method names for DuckDuckGoWrapper * Add Reddit API wrapper and related tests; update environment configuration * pre merge con giacomo * Fix import statements * Fixes - separated tests - fix tests - fix bugs reintroduced my previous merge * Refactor market API wrappers to streamline product and price retrieval methods * Add BinanceWrapper to market API exports * Finito ISSUE 3 * Final review - rm PublicBinanceAgent & updated demo - moved in the correct folder some tests - fix binance bug --------- Co-authored-by: trojanhorse47 <cosmomemory@hotmail.it> Co-authored-by: Berack96 <giacomobertolazzi7@gmail.com> Co-authored-by: Giacomo Bertolazzi <31776951+Berack96@users.noreply.github.com>
This commit was merged in pull request #8.
This commit is contained in:
@@ -1,6 +1,28 @@
|
||||
import os
|
||||
import requests
|
||||
from app.markets.base import ProductInfo, BaseWrapper, Price
|
||||
from typing import Optional, Dict, Any
|
||||
from .base import ProductInfo, BaseWrapper, Price
|
||||
|
||||
|
||||
def get_product(asset_data: dict) -> 'ProductInfo':
|
||||
product = ProductInfo()
|
||||
product.id = asset_data['FROMSYMBOL'] + '-' + asset_data['TOSYMBOL']
|
||||
product.symbol = asset_data['FROMSYMBOL']
|
||||
product.price = float(asset_data['PRICE'])
|
||||
product.volume_24h = float(asset_data['VOLUME24HOUR'])
|
||||
product.status = "" # Cryptocompare does not provide status
|
||||
return product
|
||||
|
||||
def get_price(price_data: dict) -> 'Price':
|
||||
price = Price()
|
||||
price.high = float(price_data['high'])
|
||||
price.low = float(price_data['low'])
|
||||
price.open = float(price_data['open'])
|
||||
price.close = float(price_data['close'])
|
||||
price.volume = float(price_data['volumeto'])
|
||||
price.time = str(price_data['time'])
|
||||
return price
|
||||
|
||||
|
||||
BASE_URL = "https://min-api.cryptocompare.com"
|
||||
|
||||
@@ -10,15 +32,14 @@ class CryptoCompareWrapper(BaseWrapper):
|
||||
La documentazione delle API è disponibile qui: https://developers.coindesk.com/documentation/legacy/Price/SingleSymbolPriceEndpoint
|
||||
!!ATTENZIONE!! sembra essere una API legacy e potrebbe essere deprecata in futuro.
|
||||
"""
|
||||
def __init__(self, api_key:str = None, currency:str='USD'):
|
||||
if api_key is None:
|
||||
api_key = os.getenv("CRYPTOCOMPARE_API_KEY")
|
||||
def __init__(self, currency:str='USD'):
|
||||
api_key = os.getenv("CRYPTOCOMPARE_API_KEY")
|
||||
assert api_key is not None, "API key is required"
|
||||
|
||||
self.api_key = api_key
|
||||
self.currency = currency
|
||||
|
||||
def __request(self, endpoint: str, params: dict = None) -> dict:
|
||||
def __request(self, endpoint: str, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
|
||||
if params is None:
|
||||
params = {}
|
||||
params['api_key'] = self.api_key
|
||||
@@ -32,7 +53,7 @@ class CryptoCompareWrapper(BaseWrapper):
|
||||
"tsyms": self.currency
|
||||
})
|
||||
data = response.get('RAW', {}).get(asset_id, {}).get(self.currency, {})
|
||||
return ProductInfo.from_cryptocompare(data)
|
||||
return get_product(data)
|
||||
|
||||
def get_products(self, asset_ids: list[str]) -> list[ProductInfo]:
|
||||
response = self.__request("/data/pricemultifull", params = {
|
||||
@@ -43,20 +64,20 @@ class CryptoCompareWrapper(BaseWrapper):
|
||||
data = response.get('RAW', {})
|
||||
for asset_id in asset_ids:
|
||||
asset_data = data.get(asset_id, {}).get(self.currency, {})
|
||||
assets.append(ProductInfo.from_cryptocompare(asset_data))
|
||||
assets.append(get_product(asset_data))
|
||||
return assets
|
||||
|
||||
def get_all_products(self) -> list[ProductInfo]:
|
||||
raise NotImplementedError("CryptoCompare does not support fetching all assets")
|
||||
# TODO serve davvero il workaroud qui? Possiamo prendere i dati da un altro endpoint intanto
|
||||
raise NotImplementedError("get_all_products is not supported by CryptoCompare API")
|
||||
|
||||
def get_historical_prices(self, asset_id: str, day_back: int = 10) -> list[dict]:
|
||||
assert day_back <= 30, "day_back should be less than or equal to 30"
|
||||
def get_historical_prices(self, asset_id: str, limit: int = 100) -> list[dict]:
|
||||
response = self.__request("/data/v2/histohour", params = {
|
||||
"fsym": asset_id,
|
||||
"tsym": self.currency,
|
||||
"limit": day_back * 24
|
||||
"limit": limit-1 # because the API returns limit+1 items (limit + current)
|
||||
})
|
||||
|
||||
data = response.get('Data', {}).get('Data', [])
|
||||
prices = [Price.from_cryptocompare(price_data) for price_data in data]
|
||||
prices = [get_price(price_data) for price_data in data]
|
||||
return prices
|
||||
|
||||
Reference in New Issue
Block a user