You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改Polygon.io RESTClient代码解决_session属性错误?

修复Polygon.io API客户端的AttributeError错误及入门指导

问题背景

我参考教程和示例代码编写了从Polygon.io API下载外汇数据的程序,几乎完全复制原代码,但运行时触发错误:AttributeError: 'MyRESTClient' object has no attribute '_session'。我没有正规编程教育背景,不知道如何排查,希望得到修复建议和入门学习指导。

我的代码

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)

错误信息

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. 核心错误修复

这个错误是因为你安装的Polygon Python SDK版本比示例代码新——旧版本的RESTClient用_session(带下划线)管理请求会话,但新版本已经把属性名改成了session(去掉下划线)。

直接修改__init__方法里的代码:

# 原错误代码
self._session.mount('https://', adapter)
# 修改后
self.session.mount('https://', adapter)

2. 额外兼容性修复

示例代码用的df.append()在Pandas 2.0及以上版本已经被弃用,运行时会弹出警告,建议换成pd.concat():

  • 把get_tickers方法里的df = df.append(pd.DataFrame(resp.results))改成:
    df = pd.concat([df, pd.DataFrame(resp.results)], ignore_index=True)
    
  • 把get_bars方法里的df = df.append(new_bars[new_bars['t'] > last_minute])改成:
    df = pd.concat([df, new_bars[new_bars['t'] > last_minute]], ignore_index=True)
    

入门学习指导

  1. 优先查官方文档:遇到SDK相关问题,先看Polygon Python SDK的官方文档,里面会明确属性、方法的变更记录,比几年前的老教程靠谱。
  2. 匹配依赖版本:复制老代码前,先看代码的发布时间,安装对应版本的依赖。比如要完全匹配2021年的示例代码,可执行:
    pip install polygon-api-client==2.0.0
    
  3. 基础调试技巧:遇到“属性不存在”的错误,先打印对象的所有属性看看——比如在super().__init__(auth_key)后面加print(dir(self)),就能看到这个对象到底有哪些可用属性,不用瞎猜。
  4. 从简单到复杂:不要一开始就继承类改代码,先写最基础的调用(比如直接用RESTClient获取一条外汇数据),确认能跑通后,再逐步添加重试逻辑、封装方法。

内容的提问来源于stack exchange,提问作者thetadecay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 02:12:43