tastyware / tastytrade

An unofficial Python SDK for Tastytrade!
MIT License
98 stars 33 forks source link

TLS local issuer certificate error #118

Closed ArthurMoore709 closed 5 months ago

ArthurMoore709 commented 5 months ago

This happens when sending the websocket connection using the method described in the documentation. The same error occurs when using DXFeedStreamer and DXLinkStreamer.

Traceback (most recent call last):
  File "/Users/user/PycharmProjects/project/main.py", line 63, in <module>
    asyncio.run(main())
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/runners.py", line 194, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/base_events.py", line 664, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/Users/user/PycharmProjects/project/main.py", line 52, in main
    async with DXFeedStreamer(session) as streamer:
  File "/Users/user/Library/Caches/pypoetry/virtualenvs/EcDFx_qL-py3.12/lib/python3.12/site-packages/tastytrade/streamer.py", line 294, in __aenter__
    raise TastytradeError('Connection timed out')
tastytrade.utils.TastytradeError: Connection timed out
Task exception was never retrieved
future: <Task finished name='Task-2' coro=<DXFeedStreamer._connect() done, defined at /Users/user/Library/Caches/pypoetry/virtualenvs/EcDFx_qL-py3.12/lib/python3.12/site-packages/tastytrade/streamer.py:318> exception=SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1000)')>
Traceback (most recent call last):
  File "/Users/user/Library/Caches/pypoetry/virtualenvs/EcDFx_qL-py3.12/lib/python3.12/site-packages/tastytrade/streamer.py", line 325, in _connect
    async with websockets.connect(  # type: ignore
  File "/Users/user/Library/Caches/pypoetry/virtualenvs/EcDFx_qL-py3.12/lib/python3.12/site-packages/websockets/legacy/client.py", line 629, in __aenter__
    return await self
           ^^^^^^^^^^
  File "/Users/user/Library/Caches/pypoetry/virtualenvs/EcDFx_qL-py3.12/lib/python3.12/site-packages/websockets/legacy/client.py", line 647, in __await_impl_timeout__
    return await self.__await_impl__()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Library/Caches/pypoetry/virtualenvs/EcDFx_qL-py3.12/lib/python3.12/site-packages/websockets/legacy/client.py", line 651, in __await_impl__
    _transport, _protocol = await self._create_connection()
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/base_events.py", line 1126, in create_connection
    transport, protocol = await self._create_connection_transport(
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/base_events.py", line 1159, in _create_connection_transport
    await waiter
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/sslproto.py", line 575, in _on_handshake_complete
    raise handshake_exc
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/sslproto.py", line 557, in _do_handshake
    self._sslobj.do_handshake()
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/ssl.py", line 917, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1000)

Process finished with exit code 1

How to reproduce

from tastytrade import ProductionSession, DXFeedStreamer
from tastytrade.dxfeed import EventType

import os
import asyncio

async def main():

    session = ProductionSession('username', 'password')

    # get the current price of ES and NQ Futures
    async with DXFeedStreamer(session) as streamer:
        await streamer.subscribe(EventType.QUOTE, symbols=['SPY', 'QQQ'])
        quotes = []
        async for quote in streamer.listen(EventType.QUOTE):
            quotes.append(quote)
            if len(quotes) == 2:
                break
        print(quotes)

if __name__ == '__main__':
    asyncio.run(main())

I'm not sure if maybe this is related to the TLS cutoff?

image

ArthurMoore709 commented 5 months ago

Oddly had to go run the "Install Certificates" executable. https://stackoverflow.com/questions/50236117/scraping-ssl-certificate-verify-failed-error-for-http-en-wikipedia-org