Beispiel #1
0
def test_prepate():
    data = "test data"
    event_id = "1"
    event = "2"
    retry = 3

    result = Sse._prepare(data, event_id=event_id, event=event, retry=retry)

    assert (result ==
            "id: {}\r\nevent: {}\r\ndata: {}\r\nretry: {}\r\n\r\n".format(
                event_id, event, data, retry).encode())

    with pytest.raises(TypeError):
        Sse._prepare(data, retry="3")
Beispiel #2
0
async def test_listeners():
    sanic_app = Sanic()
    sse = Sse()
    sse.init_app(sanic_app)

    sanic_app.listeners["after_server_start"][0](sanic_app,
                                                 asyncio.get_event_loop())

    assert sse._ping_task is not None

    await sanic_app.listeners["before_server_stop"][0](
        sanic_app, asyncio.get_event_loop())

    assert sse._ping_task.cancelled()
Beispiel #3
0
def test_create():
    sanic_app = Sanic()
    sse = Sse(sanic_app)

    assert sse._url == Sse._DEFAULT_URL
    assert sse._ping_task is None
    assert sse._ping_interval == Sse._DEFAULT_PING_INTERVAL
Beispiel #4
0
async def test_streaming_fn():
    sanic_app = Sanic()

    sse = Sse(sanic_app)

    class Request:  # pylint: disable=too-few-public-methods
        args = {"channel_id": "1"}

    counter = 0

    class Response:  # pylint: disable=too-few-public-methods
        @staticmethod
        async def write(data):
            nonlocal counter
            counter += 1
            assert data == b"data: test\r\n\r\n"

    str_response = await sanic_app.router.routes_all["/sse"].handler(Request())

    fut = asyncio.ensure_future(str_response.streaming_fn(Response()))

    await sanic_app.sse_send("test")  # pylint: disable=no-member
    await sse._pubsub.close()

    fut.cancel()
    with contextlib.suppress(asyncio.CancelledError):
        await fut

    assert counter == 1
Beispiel #5
0
async def test_before_request_callback_bad():
    sanic_app = Sanic()

    def test_func1(_):
        assert True

    with pytest.raises(TypeError):
        Sse(sanic_app, before_request_func=test_func1)

    async def test_func2(_, __):
        assert True

    with pytest.raises(ValueError):
        Sse(sanic_app, before_request_func=test_func2)

    test_func3 = ""
    with pytest.raises(TypeError):
        Sse(sanic_app, before_request_func=test_func3)
Beispiel #6
0
async def test_before_request_callback():
    sanic_app = Sanic()

    async def test_func(request):
        assert "channel_id" in request.args

    Sse(sanic_app, before_request_func=test_func)

    class Request:  # pylint: disable=too-few-public-methods
        args = {"channel_id": "1"}

    await sanic_app.router.routes_all["/sse"].handler(Request())
Beispiel #7
0
async def test_register_two_subscribers():
    sanic_app = Sanic()

    Sse(sanic_app)

    class Request:  # pylint: disable=too-few-public-methods
        args = {"channel_id": "1"}

    await sanic_app.router.routes_all["/sse"].handler(Request())

    with pytest.raises(InvalidUsage):
        await sanic_app.router.routes_all["/sse"].handler(Request())
Beispiel #8
0
async def test_ping():
    sanic_app = Sanic()
    sse = Sse(sanic_app, ping_interval=0.1)

    channel_id = sse._pubsub.register()

    sanic_app.listeners["after_server_start"][0](sanic_app,
                                                 asyncio.get_event_loop())

    await asyncio.sleep(0)

    data = await sse._pubsub.get(channel_id)

    assert data == b": ping\r\n\r\n"

    await sanic_app.listeners["before_server_stop"][0](
        sanic_app, asyncio.get_event_loop())
Beispiel #9
0
async def test_send_nowait():
    sanic_app = Sanic()
    sse = Sse(sanic_app)

    channel_id = sse._pubsub.register()

    data = "test data"
    event_id = "1"
    event = "2"
    retry = 3

    sanic_app.sse_send(  # pylint: disable=no-member
        data,
        event_id=event_id,
        event=event,
        retry=retry)

    await asyncio.sleep(0)

    result = await sse._pubsub.get(channel_id)

    assert (result ==
            "id: {}\r\nevent: {}\r\ndata: {}\r\nretry: {}\r\n\r\n".format(
                event_id, event, data, retry).encode())
Beispiel #10
0
async def test_transport_closed():
    sanic_app = Sanic()

    sse = Sse(sanic_app)

    class Request:  # pylint: disable=too-few-public-methods
        args = {"channel_id": "1"}

    class Response:  # pylint: disable=too-few-public-methods
        @staticmethod
        def write(data):
            raise Exception

    str_response = await sanic_app.router.routes_all["/sse"].handler(Request())

    fut = asyncio.ensure_future(str_response.streaming_fn(Response()))

    await sanic_app.sse_send("test")  # pylint: disable=no-member

    fut.cancel()
    with contextlib.suppress(Exception):
        await fut

    assert len(sse._pubsub._channels[None]) == 0
SOCKETS_BP = Blueprint("sockets", url_prefix="")

start_timer = None


async def before_sse_request(request):
    if request.headers.get("Auth", "") != "some_token":
        pass
        #abort(HTTPStatus.UNAUTHORIZED, "Bad auth token")


#sanic_app = Sanic()

# The default sse url is /sse but you can set it via init argument url.
Sse(app, url="/events",
    before_request_func=before_sse_request)  # or you can use init_app method


@SOCKETS_BP.post('send')
async def send_event(request):

    # if channel_id is None than event will be send to all subscribers
    channel_id = request.json.get("channel_id")
    logger.success(f"Message {request.json} on {channel_id}")

    # optional arguments: event_id - str, event - str, retry - int
    # data should always be str
    # also you can use sse_send_nowait for send event without waiting
    try:
        await request.app.sse_send(json_dumps(request.json),
                                   channel_id=channel_id)
Beispiel #12
0
from sanic import Sanic
from sanic_session import Session, InMemorySessionInterface
from jinja2 import Environment, PackageLoader
from sanic_sse import Sse

app = Sanic('OPhO')
Sse(app, url="/events")

from app.listeners import listeners
from app.root import root
from app.opho import opho

from app.config import Config


def create_app(config=Config):
    app.update_config(config)

    app.ctx.env = Environment(loader=PackageLoader('app', 'templates'),
                              enable_async=True)
    Session(app, interface=InMemorySessionInterface())

    app.static('/static', './app/static')
    app.static('/favicon.ico',
               './app/static/files/favicon.ico?',
               name='favicon')

    app.blueprint(root)
    app.blueprint(opho)
    app.blueprint(listeners)