Qluxzz / avanza

A Python library for the unofficial Avanza API
https://qluxzz.github.io/avanza/
MIT License
91 stars 41 forks source link

Cancelling a subscription #10

Open robiwano opened 3 years ago

robiwano commented 3 years ago

It seems it's not possible to cancel a avanza.subscription_id. The following code shows this. Idea is that task is created with ensure_future, and then cancelled after ten seconds. The subscription data continues to pour in after this.

import asyncio
from avanza import Avanza, ChannelType
import signal

user = ...
passw = ...
totpSecret = ...

def callback(data):
    # Do something with the quotes data here
    print(data)

async def subscribe_to_channel(avanza: Avanza):
    await avanza.subscribe_to_id(
        ChannelType.QUOTES,
        "19002",  # OMX Stockholm 30
        callback)

def cancel_request(unused_signum, unused_frame):
    asyncio.get_event_loop().stop()

async def cancel_task(task: asyncio.Task):
    await asyncio.sleep(10.0)
    print("Cancelling task " + task.get_name())
    task.cancel()

def main():
    signal.signal(signal.SIGINT, cancel_request)

    avanza = Avanza({
        'username': user,
        'password': passw,
        'totpSecret': totpSecret
    })

    task = asyncio.ensure_future(subscribe_to_channel(avanza))
    task.set_name("Subscription")

    asyncio.ensure_future(cancel_task(task))

    asyncio.get_event_loop().run_forever()
    print("Loop stopped")

if __name__ == "__main__":
    main()
robiwano commented 3 years ago

Meanwhile I'll follow the suggestion to have a publish/subscribe proxy.

ridulfo commented 3 years ago

Hello @robiwano Did you solve the problem, and if so how? I saw that this library provides a function called _disconnect().

robiwano commented 3 years ago

Unfortunately not.

vonDassendorf commented 3 years ago

adding this function to the socket and then calling it from Avanza class with a wrapper method should do the trick:

async def __socket_unsubscribe(
        self,
        subscription_string
    ):
        await self.__send({
            'channel': '/meta/unsubscribe',
            'clientId': self._client_id,
            'subscription': subscription_string
        })

I haven't tested this yet but that is how fhqvist is doing it in his javascript wrapper.

Qluxzz commented 3 years ago

I'm not all that up to speed with async in Python and I haven't had time to really test it but I've created a draft with the functionality added if any of you could try it out and reiterate upon it if needed.

https://github.com/Qluxzz/avanza/pull/30