Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 4 additions & 115 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,119 +9,8 @@ Python client for the [Polygon.io API](https://polygon.io).

`pip install polygon-api-client`

Requires python version >= 3.7
Requires Python >= 3.7.

## REST getting started
### Getting aggs
```python
from polygon import RESTClient

client = RESTClient() # Uses POLYGON_API_KEY env var. Can optionally supply your key.
aggs = client.get_aggs("AAPL", 1, "day", "2005-04-01", "2005-04-04")
```

### Getting trades
```python
from polygon import RESTClient
from polygon.rest.models import Sort

client = RESTClient() # Uses POLYGON_API_KEY env var. Can optionally supply your key.

trades = []
for t in client.list_trades("AAA", timestamp="2022-04-20", limit=5, sort=Sort.ASC):
trades.append(t)
```

### Getting raw response
To handle the raw [urllib3 response](https://urllib3.readthedocs.io/en/stable/reference/urllib3.response.html?highlight=response#response) yourself, pass `raw=True`:

```python
from polygon import RESTClient

client = RESTClient() # Uses POLYGON_API_KEY env var. Can optionally supply your key.
response = client.get_aggs("AAPL", 1, "day", "2005-04-01", "2005-04-04", raw=True)
```

## WebSocket getting started

### Simple synchronous callback
```python
from polygon import WebSocketClient
from polygon.websocket.models import WebSocketMessage
from typing import List

c = WebSocketClient(subscriptions=['T.AAPL']) # Uses POLYGON_API_KEY env var. Can optionally supply your key.

def handle_msg(msgs: List[WebSocketMessage]):
for m in msgs:
print(m)

c.run(handle_msg)
```

### Synchronous aggregates
```python
from polygon import WebSocketClient
from polygon.websocket.models import WebSocketMessage
from typing import List

class MessageHandler:
count = 0

def handle_msg(self, msgs: List[WebSocketMessage]):
for m in msgs:
if type(m) == EquityTrade:
print(self.count, m)
self.count += 1

h = MessageHandler()

def handle_msg(msgs: List[WebSocketMessage]):
h.handle_msg(msgs)

c.run(handle_msg)
```

### Asynchronous callback
```python
from polygon import WebSocketClient
from polygon.websocket.models import WebSocketMessage
from typing import List

c = WebSocketClient(subscriptions=['T.AAPL']) # Uses POLYGON_API_KEY env var. Can optionally supply your key.

async def handle_msg(msgs: List[WebSocketMessage]):
for m in msgs:
print(m)

async def timeout():
await asyncio.sleep(1)
print('unsubscribe_all')
c.unsubscribe_all()
await asyncio.sleep(1)
print('close')
await c.close()

async def main():
await asyncio.gather(
c.connect(handle_msg),
timeout()
)

asyncio.run(main())
```

### Getting raw response
```python
from polygon import WebSocketClient
from polygon.websocket.models import WebSocketMessage
from typing import Union
import json

c = WebSocketClient(subscriptions=['T.*'], raw=True)

def handle_msg(msgs: Union[str, bytes]):
print(json.loads(msgs))

c.run(handle_msg)
```
## Getting started
See the [Getting Started](https://polygon-api-client.readthedocs.io/en/latest/Getting-Started.html)
section in our docs or view the [examples](./examples) directory.
212 changes: 10 additions & 202 deletions docs/source/Getting-Started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,11 @@ You can pass your API key via the environment variable :code:`POLYGON_API_KEY` o

For non-paginated endpoints call :code:`get_*`:

.. code-block:: python

aggs = client.get_aggs("AAPL", 1, "day", "2022-04-01", "2022-04-04")
print(aggs)
.. literalinclude:: ../../examples/rest/simple-get.py

For paginated endpoints call :code:`list_*` and use the provided iterator:

.. code-block:: python

trades = []
for t in client.list_trades("AAA", timestamp="2022-04-20", limit=5, sort=Sort.ASC)
trades.append(t)
print(trades)
.. literalinclude:: ../../examples/rest/simple-list.py

.. note::
The number of network requests made by the iterator depends on the value of the parameter :code:`limit`.
Expand All @@ -55,125 +47,11 @@ For endpoints that have a set of parameters you can use the provided :doc:`enums

To handle the raw `urllib3 response <https://urllib3.readthedocs.io/en/stable/reference/urllib3.response.html?highlight=response#response) yourself, pass `raw=True>`_ yourself pass :code:`raw=True`:

.. code-block:: python

aggs = client.get_aggs("AAPL", 1, "day", "2022-04-01", "2022-04-04", raw=True)
print(aggs.geturl())
# https://api.polygon.io/v2/aggs/ticker/AAPL/range/1/day/2022-04-01/2022-04-04
print(aggs.status)
# 200
print(aggs.data)
# b'{
# "ticker": "AAPL",
# "queryCount": 2,
# "resultsCount": 2,
# "adjusted": true,
# "results": [
# {
# "v": 78251328,
# "vw": 173.4143,
# "o": 174.03,
# "c": 174.31,
# "h": 174.88,
# "l": 171.94,
# "t": 1648785600000,
# "n": 661160
# },
# {
# "v": 76545983,
# "vw": 177.4855,
# "o": 174.57,
# "c": 178.44,
# "h": 178.49,
# "l": 174.44,
# "t": 1649044800000,
# "n": 630374
# }
# ],
# "status": "OK",
# "request_id": "d8882a9d5194978819777f49c44b09c6",
# "count": 2
# }'
.. literalinclude:: ../../examples/rest/raw-get.py

If it is a paginated :code:`list_*` response it's up to you to handle the "next_url" iteration:

.. code-block:: python

trades = client.list_trades("AAA", timestamp="2022-04-20", limit=5)
print(aggs.data)
# b'{
# "results": [
# {
# "conditions": [
# 15
# ],
# "exchange": 11,
# "id": "52983575627601",
# "participant_timestamp": 1650499200029279200,
# "price": 24.875,
# "sequence_number": 1591291,
# "sip_timestamp": 1650499200029316600,
# "size": 100,
# "tape": 1
# },
# {
# "conditions": [
# 38,
# 41
# ],
# "exchange": 11,
# "id": "52983575627600",
# "participant_timestamp": 1650499200029279200,
# "price": 24.875,
# "sequence_number": 1591290,
# "sip_timestamp": 1650499200029316600,
# "tape": 1
# },
# {
# "conditions": [
# 15
# ],
# "exchange": 11,
# "id": "52983575622470",
# "participant_timestamp": 1650493800003024000,
# "price": 24.875,
# "sequence_number": 1571279,
# "sip_timestamp": 1650493800003645400,
# "size": 100,
# "tape": 1
# },
# {
# "conditions": [
# 38,
# 41
# ],
# "exchange": 11,
# "id": "52983575622469",
# "participant_timestamp": 1650493800003024000,
# "price": 24.875,
# "sequence_number": 1571276,
# "sip_timestamp": 1650493800003635500,
# "tape": 1
# },
# {
# "conditions": [
# 15
# ],
# "exchange": 11,
# "id": "52983575556178",
# "participant_timestamp": 1650485400002987800,
# "price": 24.875,
# "sequence_number": 1536223,
# "sip_timestamp": 1650485400003870000,
# "size": 100,
# "tape": 1
# }
# ],
# "status": "OK",
# "request_id": "618bb99e7a632ed9f55454a541404b44",
# "next_url": "https://api.polygon.io/v3/trades/AAA?cursor=YXA9NSZhcz0mbGltaXQ9NSZvcmRlcj1kZXNjJnNvcnQ9dGltZXN0YW1wJnRpbWVzdGFtcC5ndGU9MjAyMi0wNC0yMFQwNCUzQTAwJTNBMDBaJnRpbWVzdGFtcC5sdGU9MjAyMi0wNC0yMFQyMCUzQTEwJTNBMDAuMDAzODY5OTUyWg"
# }'

.. literalinclude:: ../../examples/rest/raw-list.py

WebSocket client usage
----------------------
Expand All @@ -182,93 +60,23 @@ WebSocket client usage

The simplest way to use the websocket client is to just provide a callback:

.. code-block:: python

from polygon import WebSocketClient
from polygon.websocket.models import WebSocketMessage
from typing import List

c = WebSocketClient(subscriptions=['T.AAPL'])

def handle_msg(msgs: List[WebSocketMessage]):
for m in msgs:
print(m)

c.run(handle_msg)
.. literalinclude:: ../../examples/websocket/simple.py

.. note::
Raises :code:`AuthError` if invalid API key is provided.

If you want to capture state you can use a global variable inside the callback.
Alternatively, you can wrap a class method in a closure.

.. code-block:: python

from polygon import WebSocketClient
from polygon.websocket.models import WebSocketMessage
from typing import List

class MessageHandler:
count = 0

def handle_msg(self, msgs: List[WebSocketMessage]):
for m in msgs:
if type(m) == EquityTrade:
print(self.count, m)
self.count += 1

h = MessageHandler()

def handle_msg(msgs: List[WebSocketMessage]):
h.handle_msg(msgs)

c.run(handle_msg)
.. literalinclude:: ../../examples/websocket/aggs.py

Under the hood our client uses an asynchronous runtime. To manage the runtime
yourself (including unsubscribing and subscribing) you'll need to use asyncio
and the :code:`.connect` method:

.. code-block:: python

from polygon import WebSocketClient
from polygon.websocket.models import WebSocketMessage
from typing import List

c = WebSocketClient(subscriptions=['T.AAPL']) # Uses POLYGON_API_KEY env var. Can optionally supply your key.
yourself (including unsubscribing and subscribing) you can use asyncio and the
:code:`.connect` method:

async def handle_msg(msgs: List[WebSocketMessage]):
for m in msgs:
print(m)

async def timeout():
await asyncio.sleep(1)
print('unsubscribe_all')
c.unsubscribe_all()
await asyncio.sleep(1)
print('close')
await c.close()

async def main():
await asyncio.gather(
c.connect(handle_msg),
timeout()
)

asyncio.run(main())
.. literalinclude:: ../../examples/websocket/async.py

To handle raw messages yourself pass `raw=True`:

.. code-block:: python

from polygon import WebSocketClient
from polygon.websocket.models import WebSocketMessage
from typing import Union
import json

c = WebSocketClient(subscriptions=['T.*'], raw=True)

def handle_msg(msgs: Union[str, bytes]):
print(json.loads(msgs))

c.run(handle_msg)
.. literalinclude:: ../../examples/websocket/raw.py

1 change: 1 addition & 0 deletions docs/source/WebSocket.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ WebSocket
Init client
===========
.. automethod:: polygon.WebSocketClient.__init__
:noindex:

============================
Connect
Expand Down
4 changes: 2 additions & 2 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ This documentation is for the Python client only. For details about the response
:maxdepth: 1
:caption: Contents:

Getting-Started
Getting-started
Aggs
WebSocket
Snapshot
Expand All @@ -17,7 +17,7 @@ This documentation is for the Python client only. For details about the response
vX
Models
Enums
WebSocket-Enums
WebSocket-enums

Indices and tables
==================
Expand Down
Loading