How can I modify this Polygon.io Restclient code such that I don't receive the noted _session error?

426 views Asked by At

I'm trying to use a YouTube guide to build code to download Forex Data from Polygon.io's API. I am nearly copying and pasting the code from GitHub, but I am getting an error relating to "_session" attribute. There seems to be no difference between what I am doing and the guide on youtube. I'm don't have a formal education in this so its hard for me to figure out why this is happening. I would appreciate the help and learning opportunity with any suggestions to fix this issue. (error below the code)

Github:https://github.com/leosmigel/analyzingalpha/blob/master/2021-10-25-get-historical-price-data-polygon/2021-10-25-get-historical-price-data-polygon.ipynb

Video:https://www.youtube.com/watch?v=XPWHiKT_mU0


from polygon import RESTClient
from local_settings import polygon as settings
from datetime import date, datetime
from typing import Any, Optional
import pandas as pd
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

markets = ['crypto', 'stocks', 'fx']

class MyRESTClient(RESTClient):
    def __init__(self, auth_key: str=settings['api_key'], timeout:int=5):
        super().__init__(auth_key)
        retry_strategy = Retry(total=10,
                               backoff_factor=10,
                               status_forcelist=[429, 500, 502, 503, 504])
        adapter = HTTPAdapter(max_retries=retry_strategy)
        self._session.mount('https://', adapter)

    def get_tickers(self, market:str=None) -> pd.DataFrame:
        if not market in markets:
            raise Exception(f'Market must be one of {markets}.')

        resp = self.reference_tickers_v3(market=market)
        if hasattr(resp, 'results'):
            df = pd.DataFrame(resp.results)

            while hasattr(resp, 'next_url'):
                resp = self.reference_tickers_v3(next_url=resp.next_url)
                df = df.append(pd.DataFrame(resp.results))

            if market == 'fx':
                # Only use USD pairings.
                df = df[df['currency_symbol'] == 'USD']
                df['name'] = df['base_currency_name']
                df = df[['ticker', 'name', 'market', 'active']]

            df = df.drop_duplicates(subset='ticker')
            return df
        return None

    def get_bars(self, market:str=None, ticker:str=None, multiplier:int=1,
                 timespan:str='minute', from_:date=None, to:date=None) -> pd.DataFrame:

        if not market in markets:
            raise Exception(f'Market must be one of {markets}.')

        if ticker is None:
            raise Exception('Ticker must not be None.')

        from_ = from_ if from_ else date(2000,1,1)
        to = to if to else date.today()

        if market == 'fx':
            resp = self.fx_aggregates(ticker, multiplier, timespan,
                                          from_.strftime('%Y-%m-%d'), to.strftime('%Y-%m-%d'),
                                          limit=50000)
            df = pd.DataFrame(resp.results)
            last_minute = 0
            while resp.results[-1]['t'] > last_minute:
                last_minute = resp.results[-1]['t'] # Last minute in response
                last_minute_date = datetime.fromtimestamp(last_minute/1000).strftime('%Y-%m-%d')
                resp = self.fx_aggregates(ticker, multiplier, timespan,
                                          last_minute_date, to.strftime('%Y-%m-%d'),
                                          limit=50000)
                new_bars = pd.DataFrame(resp.results)
                df = df.append(new_bars[new_bars['t'] > last_minute])
                
            df['date'] = pd.to_datetime(df['t'], unit='ms')
            df = df.rename(columns={'o':'open',
                                    'h':'high',
                                    'l':'low',
                                    'c':'close',
                                    'v':'volume',
                                    'vw':'vwap',
                                    'n':'transactions'})
            df = df[['date','open','high','low','close','volume']]

            return df
        return None

start = datetime(2023,2,1)
client = MyRESTClient(settings['api_key'])
df = client.get_bars(market='fx', ticker='C:EURUSD', from_=start)
print(df)

Then this is the error I receive when running it:

Traceback (most recent call last):
  File "fxdata.py", line 86, in <module>
    client = MyRESTClient(settings['api_key'])
  File "fxdata.py", line 21, in __init__
    self._session.mount('https://', adapter)
AttributeError: 'MyRESTClient' object has no attribute '_session'
1

There are 1 answers

0
AudioBubble On

Try this:

from polygon import RESTClient
from local_settings import polygon as settings
from datetime import date, datetime
from typing import Any, Optional
import pandas as pd
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
import requests
import string
import secrets

markets = ['crypto', 'stocks', 'fx']

class MyRESTClient(RESTClient):
    def __init__(self, auth_key: str=settings['api_key'], timeout:int=5):
        super().__init__(auth_key)
        self._session = requests.Session()
        retry_strategy = Retry(total=10,
                               backoff_factor=10,
                               status_forcelist=[429, 500, 502, 503, 504])
        adapter = HTTPAdapter(max_retries=retry_strategy)
        self._session.mount('https://', adapter)
        self._session.headers.update({'Authorization': f'Bearer {auth_key}'})

    def get_tickers(self, market:str=None) -> pd.DataFrame:
        if not market in markets:
            raise Exception(f'Market must be one of {markets}.')

        url = f"https://api.polygon.io/v3/reference/tickers?market={market}&active=true&sort=ticker&order=asc&limit=1000&apiKey={self._auth_key}"
        resp = self._session.get(url).json()

        if 'results' in resp:
            df = pd.DataFrame(resp['results'])

            while 'next_url' in resp:
                next_url = resp['next_url']
                resp = self._session.get(next_url).json()
                df = df.append(pd.DataFrame(resp['results']))

            if market == 'fx':
                # Only use USD pairings.
                df = df[df['currency_symbol'] == 'USD']
                df['name'] = df['base_currency_name']
                df = df[['ticker', 'name', 'market', 'active']]

            df = df.drop_duplicates(subset='ticker')
            return df
        return None

    def get_bars(self, market:str=None, ticker:str=None, multiplier:int=1,
                 timespan:str='minute', from_:date=None, to:date=None) -> pd.DataFrame:

        if not market in markets:
            raise Exception(f'Market must be one of {markets}.')

        if ticker is None:
            raise Exception('Ticker must not be None.')

        from_ = from_ if from_ else date(2000,1,1)
        to = to if to else date.today()

        if market == 'fx':
            url = f"https://api.polygon.io/v2/aggs/ticker/{ticker}/range/{multiplier}/{timespan}/{from_.strftime('%Y-%m-%d')}/{to.strftime('%Y-%m-%d')}?apiKey={self._auth_key}"
            resp = self._session.get(url).json()
            df = pd.DataFrame(resp['results'])

            while resp['results'][-1]['t'] > df.iloc[-1]['t']:
                last_minute = df.iloc[-1]['t']
                last_minute_date = datetime.fromtimestamp(last_minute/1000).strftime('%Y-%m-%d')
                url = f"https://api.polygon.io/v2/aggs/ticker/{ticker}/range/{multiplier}/{timespan}/{last_minute_date}/{to.strftime('%Y-%m-%d')}?apiKey={self._auth_key}"
                resp = self._session.get(url).json()
                new_bars = pd.DataFrame(resp['results'])
                df = df.append(new_bars[new_bars['t'] > last_minute])

                        df['date'] = pd.to_datetime(df['t'], unit='ms')
            df = df.rename(columns={'o': 'open',
                                    'h': 'high',
                                    'l': 'low',
                                    'c': 'close',
                                    'v': 'volume',
                                    'vw': 'vwap',
                                    'n': 'transactions'})
            df = df[['date', 'open', 'high', 'low', 'close', 'volume']]

            return df
        return None

start = datetime(2023, 2, 1)
client = MyRESTClient(settings['api_key'])
df = client.get_bars(market='fx', ticker='C:EURUSD', from_=start)
print(df)