[{"data":1,"prerenderedAt":1665},["ShallowReactive",2],{"docs:/docs/sdks/python":3},{"id":4,"title":5,"body":6,"description":1658,"extension":1659,"meta":1660,"navigation":64,"path":1661,"seo":1662,"stem":1663,"__hash__":1664},"docs/docs/sdks/python.md","Python SDK",{"type":7,"value":8,"toc":1639},"minimark",[9,13,17,22,104,108,275,279,364,368,371,474,478,488,581,585,653,657,664,780,784,844,848,859,918,922,1063,1067,1180,1184,1240,1244,1247,1382,1386,1389,1476,1480,1580,1584,1600,1604,1635],[10,11,5],"h1",{"id":12},"python-sdk",[14,15,16],"p",{},"The official NoLag SDK for Python. Full async/await support with type hints\nfor Python 3.10+.",[18,19,21],"h2",{"id":20},"installation","Installation",[23,24,25],"code-tabs",{},[26,27,33],"pre",{"className":28,"code":29,"filename":30,"language":31,"meta":32,"style":32},"language-bash shiki shiki-themes github-light github-dark","# pip\npip install nolag\n\n# poetry\npoetry add nolag\n\n# uv\nuv add nolag\n","Terminal","bash","",[34,35,36,45,59,66,72,83,88,94],"code",{"__ignoreMap":32},[37,38,41],"span",{"class":39,"line":40},"line",1,[37,42,44],{"class":43},"sJ8bj","# pip\n",[37,46,48,52,56],{"class":39,"line":47},2,[37,49,51],{"class":50},"sScJk","pip",[37,53,55],{"class":54},"sZZnC"," install",[37,57,58],{"class":54}," nolag\n",[37,60,62],{"class":39,"line":61},3,[37,63,65],{"emptyLinePlaceholder":64},true,"\n",[37,67,69],{"class":39,"line":68},4,[37,70,71],{"class":43},"# poetry\n",[37,73,75,78,81],{"class":39,"line":74},5,[37,76,77],{"class":50},"poetry",[37,79,80],{"class":54}," add",[37,82,58],{"class":54},[37,84,86],{"class":39,"line":85},6,[37,87,65],{"emptyLinePlaceholder":64},[37,89,91],{"class":39,"line":90},7,[37,92,93],{"class":43},"# uv\n",[37,95,97,100,102],{"class":39,"line":96},8,[37,98,99],{"class":50},"uv",[37,101,80],{"class":54},[37,103,58],{"class":54},[18,105,107],{"id":106},"quick-start","Quick Start",[23,109,110],{},[26,111,116],{"className":112,"code":113,"filename":114,"language":115,"meta":32,"style":32},"language-python shiki shiki-themes github-light github-dark","import asyncio\nfrom nolag import NoLag\n\nasync def main():\n    # Create client with your actor token\n    client = NoLag(\"your-actor-token\")\n\n    # Connect to NoLag\n    await client.connect()\n\n    # Subscribe to a topic\n    await client.subscribe(\"my-topic\")\n\n    # Listen for messages on that topic\n    def on_message(data, meta):\n        print(f\"Received: {data}\")\n\n    client.on(\"my-topic\", on_message)\n\n    # Publish a message\n    await client.emit(\"my-topic\", {\"hello\": \"world\"})\n\n    # Keep running\n    await asyncio.sleep(60)\n\n    # Disconnect when done (synchronous)\n    client.disconnect()\n\nasyncio.run(main())\n","Python","python",[34,117,118,123,128,132,137,142,147,151,156,162,167,173,179,184,190,196,202,207,213,218,224,230,235,241,247,252,258,264,269],{"__ignoreMap":32},[37,119,120],{"class":39,"line":40},[37,121,122],{},"import asyncio\n",[37,124,125],{"class":39,"line":47},[37,126,127],{},"from nolag import NoLag\n",[37,129,130],{"class":39,"line":61},[37,131,65],{"emptyLinePlaceholder":64},[37,133,134],{"class":39,"line":68},[37,135,136],{},"async def main():\n",[37,138,139],{"class":39,"line":74},[37,140,141],{},"    # Create client with your actor token\n",[37,143,144],{"class":39,"line":85},[37,145,146],{},"    client = NoLag(\"your-actor-token\")\n",[37,148,149],{"class":39,"line":90},[37,150,65],{"emptyLinePlaceholder":64},[37,152,153],{"class":39,"line":96},[37,154,155],{},"    # Connect to NoLag\n",[37,157,159],{"class":39,"line":158},9,[37,160,161],{},"    await client.connect()\n",[37,163,165],{"class":39,"line":164},10,[37,166,65],{"emptyLinePlaceholder":64},[37,168,170],{"class":39,"line":169},11,[37,171,172],{},"    # Subscribe to a topic\n",[37,174,176],{"class":39,"line":175},12,[37,177,178],{},"    await client.subscribe(\"my-topic\")\n",[37,180,182],{"class":39,"line":181},13,[37,183,65],{"emptyLinePlaceholder":64},[37,185,187],{"class":39,"line":186},14,[37,188,189],{},"    # Listen for messages on that topic\n",[37,191,193],{"class":39,"line":192},15,[37,194,195],{},"    def on_message(data, meta):\n",[37,197,199],{"class":39,"line":198},16,[37,200,201],{},"        print(f\"Received: {data}\")\n",[37,203,205],{"class":39,"line":204},17,[37,206,65],{"emptyLinePlaceholder":64},[37,208,210],{"class":39,"line":209},18,[37,211,212],{},"    client.on(\"my-topic\", on_message)\n",[37,214,216],{"class":39,"line":215},19,[37,217,65],{"emptyLinePlaceholder":64},[37,219,221],{"class":39,"line":220},20,[37,222,223],{},"    # Publish a message\n",[37,225,227],{"class":39,"line":226},21,[37,228,229],{},"    await client.emit(\"my-topic\", {\"hello\": \"world\"})\n",[37,231,233],{"class":39,"line":232},22,[37,234,65],{"emptyLinePlaceholder":64},[37,236,238],{"class":39,"line":237},23,[37,239,240],{},"    # Keep running\n",[37,242,244],{"class":39,"line":243},24,[37,245,246],{},"    await asyncio.sleep(60)\n",[37,248,250],{"class":39,"line":249},25,[37,251,65],{"emptyLinePlaceholder":64},[37,253,255],{"class":39,"line":254},26,[37,256,257],{},"    # Disconnect when done (synchronous)\n",[37,259,261],{"class":39,"line":260},27,[37,262,263],{},"    client.disconnect()\n",[37,265,267],{"class":39,"line":266},28,[37,268,65],{"emptyLinePlaceholder":64},[37,270,272],{"class":39,"line":271},29,[37,273,274],{},"asyncio.run(main())\n",[18,276,278],{"id":277},"configuration","Configuration",[23,280,281],{},[26,282,284],{"className":112,"code":283,"filename":114,"language":115,"meta":32,"style":32},"from nolag import NoLag, NoLagOptions, QoS\n\noptions = NoLagOptions(\n    url=\"wss://broker.nolag.app/ws\",  # Custom broker URL\n    reconnect=True,                     # Auto-reconnect on disconnect\n    reconnect_interval=5.0,             # Seconds between reconnect attempts\n    max_reconnect_attempts=10,          # Max reconnect attempts (0 = infinite)\n    heartbeat_interval=30.0,            # Heartbeat interval (0 to disable)\n    disconnect_on_hidden=False,         # Disconnect when tab is hidden\n    qos=QoS.AT_LEAST_ONCE,              # Default QoS level\n    load_balance=False,                 # Enable load balancing\n    load_balance_group=None,            # Load balance group name\n    debug=True,                         # Enable debug logging\n)\n\nclient = NoLag(\"your-actor-token\", options)\n",[34,285,286,291,295,300,305,310,315,320,325,330,335,340,345,350,355,359],{"__ignoreMap":32},[37,287,288],{"class":39,"line":40},[37,289,290],{},"from nolag import NoLag, NoLagOptions, QoS\n",[37,292,293],{"class":39,"line":47},[37,294,65],{"emptyLinePlaceholder":64},[37,296,297],{"class":39,"line":61},[37,298,299],{},"options = NoLagOptions(\n",[37,301,302],{"class":39,"line":68},[37,303,304],{},"    url=\"wss://broker.nolag.app/ws\",  # Custom broker URL\n",[37,306,307],{"class":39,"line":74},[37,308,309],{},"    reconnect=True,                     # Auto-reconnect on disconnect\n",[37,311,312],{"class":39,"line":85},[37,313,314],{},"    reconnect_interval=5.0,             # Seconds between reconnect attempts\n",[37,316,317],{"class":39,"line":90},[37,318,319],{},"    max_reconnect_attempts=10,          # Max reconnect attempts (0 = infinite)\n",[37,321,322],{"class":39,"line":96},[37,323,324],{},"    heartbeat_interval=30.0,            # Heartbeat interval (0 to disable)\n",[37,326,327],{"class":39,"line":158},[37,328,329],{},"    disconnect_on_hidden=False,         # Disconnect when tab is hidden\n",[37,331,332],{"class":39,"line":164},[37,333,334],{},"    qos=QoS.AT_LEAST_ONCE,              # Default QoS level\n",[37,336,337],{"class":39,"line":169},[37,338,339],{},"    load_balance=False,                 # Enable load balancing\n",[37,341,342],{"class":39,"line":175},[37,343,344],{},"    load_balance_group=None,            # Load balance group name\n",[37,346,347],{"class":39,"line":181},[37,348,349],{},"    debug=True,                         # Enable debug logging\n",[37,351,352],{"class":39,"line":186},[37,353,354],{},")\n",[37,356,357],{"class":39,"line":192},[37,358,65],{"emptyLinePlaceholder":64},[37,360,361],{"class":39,"line":198},[37,362,363],{},"client = NoLag(\"your-actor-token\", options)\n",[18,365,367],{"id":366},"fluent-api","Fluent API",[14,369,370],{},"The fluent API lets you scope operations to a specific app and room,\nso you don't need to repeat the full topic path every time.",[23,372,373],{},[26,374,376],{"className":112,"code":375,"filename":114,"language":115,"meta":32,"style":32},"# Use the fluent API to scope topics to an app and room\nroom = client.set_app(\"chat\").set_room(\"general\")\n\n# Subscribe, listen, and emit within the room\nawait room.subscribe(\"messages\")\nroom.on(\"messages\", lambda data, meta: print(data))\nawait room.emit(\"messages\", {\"text\": \"Hello from general!\"})\n\n# This is equivalent to using full topic paths:\n# await client.subscribe(\"chat/general/messages\")\n# client.on(\"chat/general/messages\", handler)\n# await client.emit(\"chat/general/messages\", data)\n\n# Room also supports filter management\nawait room.set_filters(\"messages\", [\"lang:en\", \"lang:fr\"])\nawait room.add_filters(\"messages\", [\"lang:de\"])\nawait room.remove_filters(\"messages\", [\"lang:fr\"])\n\n# Unsubscribe within the room\nawait room.unsubscribe(\"messages\")\n",[34,377,378,383,388,392,397,402,407,412,416,421,426,431,436,440,445,450,455,460,464,469],{"__ignoreMap":32},[37,379,380],{"class":39,"line":40},[37,381,382],{},"# Use the fluent API to scope topics to an app and room\n",[37,384,385],{"class":39,"line":47},[37,386,387],{},"room = client.set_app(\"chat\").set_room(\"general\")\n",[37,389,390],{"class":39,"line":61},[37,391,65],{"emptyLinePlaceholder":64},[37,393,394],{"class":39,"line":68},[37,395,396],{},"# Subscribe, listen, and emit within the room\n",[37,398,399],{"class":39,"line":74},[37,400,401],{},"await room.subscribe(\"messages\")\n",[37,403,404],{"class":39,"line":85},[37,405,406],{},"room.on(\"messages\", lambda data, meta: print(data))\n",[37,408,409],{"class":39,"line":90},[37,410,411],{},"await room.emit(\"messages\", {\"text\": \"Hello from general!\"})\n",[37,413,414],{"class":39,"line":96},[37,415,65],{"emptyLinePlaceholder":64},[37,417,418],{"class":39,"line":158},[37,419,420],{},"# This is equivalent to using full topic paths:\n",[37,422,423],{"class":39,"line":164},[37,424,425],{},"# await client.subscribe(\"chat/general/messages\")\n",[37,427,428],{"class":39,"line":169},[37,429,430],{},"# client.on(\"chat/general/messages\", handler)\n",[37,432,433],{"class":39,"line":175},[37,434,435],{},"# await client.emit(\"chat/general/messages\", data)\n",[37,437,438],{"class":39,"line":181},[37,439,65],{"emptyLinePlaceholder":64},[37,441,442],{"class":39,"line":186},[37,443,444],{},"# Room also supports filter management\n",[37,446,447],{"class":39,"line":192},[37,448,449],{},"await room.set_filters(\"messages\", [\"lang:en\", \"lang:fr\"])\n",[37,451,452],{"class":39,"line":198},[37,453,454],{},"await room.add_filters(\"messages\", [\"lang:de\"])\n",[37,456,457],{"class":39,"line":204},[37,458,459],{},"await room.remove_filters(\"messages\", [\"lang:fr\"])\n",[37,461,462],{"class":39,"line":209},[37,463,65],{"emptyLinePlaceholder":64},[37,465,466],{"class":39,"line":215},[37,467,468],{},"# Unsubscribe within the room\n",[37,470,471],{"class":39,"line":220},[37,472,473],{},"await room.unsubscribe(\"messages\")\n",[18,475,477],{"id":476},"subscribing-to-topics","Subscribing to Topics",[14,479,480,483,484,487],{},[34,481,482],{},"subscribe()"," registers interest in a topic.\nUse ",[34,485,486],{},"on()"," separately to attach a message handler.",[23,489,490],{},[26,491,493],{"className":112,"code":492,"filename":114,"language":115,"meta":32,"style":32},"from nolag import SubscribeOptions, QoS\n\n# Basic subscription + handler\nawait client.subscribe(\"chat/messages\")\nclient.on(\"chat/messages\", lambda data, meta: print(data))\n\n# With options (filters, load balancing)\noptions = SubscribeOptions(\n    qos=QoS.EXACTLY_ONCE,\n    load_balance=True,\n    load_balance_group=\"workers\",\n    filters=[\"priority:high\", \"region:us\"]\n)\nawait client.subscribe(\"tasks\", options)\nclient.on(\"tasks\", lambda data, meta: print(f\"Task: {data}\"))\n\n# Unsubscribe\nawait client.unsubscribe(\"chat/messages\")\n",[34,494,495,500,504,509,514,519,523,528,533,538,543,548,553,557,562,567,571,576],{"__ignoreMap":32},[37,496,497],{"class":39,"line":40},[37,498,499],{},"from nolag import SubscribeOptions, QoS\n",[37,501,502],{"class":39,"line":47},[37,503,65],{"emptyLinePlaceholder":64},[37,505,506],{"class":39,"line":61},[37,507,508],{},"# Basic subscription + handler\n",[37,510,511],{"class":39,"line":68},[37,512,513],{},"await client.subscribe(\"chat/messages\")\n",[37,515,516],{"class":39,"line":74},[37,517,518],{},"client.on(\"chat/messages\", lambda data, meta: print(data))\n",[37,520,521],{"class":39,"line":85},[37,522,65],{"emptyLinePlaceholder":64},[37,524,525],{"class":39,"line":90},[37,526,527],{},"# With options (filters, load balancing)\n",[37,529,530],{"class":39,"line":96},[37,531,532],{},"options = SubscribeOptions(\n",[37,534,535],{"class":39,"line":158},[37,536,537],{},"    qos=QoS.EXACTLY_ONCE,\n",[37,539,540],{"class":39,"line":164},[37,541,542],{},"    load_balance=True,\n",[37,544,545],{"class":39,"line":169},[37,546,547],{},"    load_balance_group=\"workers\",\n",[37,549,550],{"class":39,"line":175},[37,551,552],{},"    filters=[\"priority:high\", \"region:us\"]\n",[37,554,555],{"class":39,"line":181},[37,556,354],{},[37,558,559],{"class":39,"line":186},[37,560,561],{},"await client.subscribe(\"tasks\", options)\n",[37,563,564],{"class":39,"line":192},[37,565,566],{},"client.on(\"tasks\", lambda data, meta: print(f\"Task: {data}\"))\n",[37,568,569],{"class":39,"line":198},[37,570,65],{"emptyLinePlaceholder":64},[37,572,573],{"class":39,"line":204},[37,574,575],{},"# Unsubscribe\n",[37,577,578],{"class":39,"line":209},[37,579,580],{},"await client.unsubscribe(\"chat/messages\")\n",[18,582,584],{"id":583},"publishing-messages","Publishing Messages",[23,586,587],{},[26,588,590],{"className":112,"code":589,"filename":114,"language":115,"meta":32,"style":32},"from nolag import EmitOptions, QoS\n\n# Publish any data (dict, list, string, bytes, etc.)\nawait client.emit(\"chat/messages\", {\"text\": \"Hello!\"})\n\n# With options\noptions = EmitOptions(\n    qos=QoS.EXACTLY_ONCE,\n    retain=True,          # Retain last message for new subscribers\n    echo=False,           # Don't receive your own message back\n    filter=\"priority:high\" # Publish with a filter value\n)\nawait client.emit(\"status\", {\"online\": True}, options)\n",[34,591,592,597,601,606,611,615,620,625,629,634,639,644,648],{"__ignoreMap":32},[37,593,594],{"class":39,"line":40},[37,595,596],{},"from nolag import EmitOptions, QoS\n",[37,598,599],{"class":39,"line":47},[37,600,65],{"emptyLinePlaceholder":64},[37,602,603],{"class":39,"line":61},[37,604,605],{},"# Publish any data (dict, list, string, bytes, etc.)\n",[37,607,608],{"class":39,"line":68},[37,609,610],{},"await client.emit(\"chat/messages\", {\"text\": \"Hello!\"})\n",[37,612,613],{"class":39,"line":74},[37,614,65],{"emptyLinePlaceholder":64},[37,616,617],{"class":39,"line":85},[37,618,619],{},"# With options\n",[37,621,622],{"class":39,"line":90},[37,623,624],{},"options = EmitOptions(\n",[37,626,627],{"class":39,"line":96},[37,628,537],{},[37,630,631],{"class":39,"line":158},[37,632,633],{},"    retain=True,          # Retain last message for new subscribers\n",[37,635,636],{"class":39,"line":164},[37,637,638],{},"    echo=False,           # Don't receive your own message back\n",[37,640,641],{"class":39,"line":169},[37,642,643],{},"    filter=\"priority:high\" # Publish with a filter value\n",[37,645,646],{"class":39,"line":175},[37,647,354],{},[37,649,650],{"class":39,"line":181},[37,651,652],{},"await client.emit(\"status\", {\"online\": True}, options)\n",[18,654,656],{"id":655},"filters","Filters",[14,658,659,660,663],{},"Filters let subscribers receive only messages matching specific criteria.\nPublishers tag messages with a filter value via ",[34,661,662],{},"EmitOptions.filter",",\nand subscribers set which filters they care about.",[23,665,666],{},[26,667,669],{"className":112,"code":668,"filename":114,"language":115,"meta":32,"style":32},"from nolag import SubscribeOptions, EmitOptions\n\n# Subscribe with initial filters\nawait client.subscribe(\"events\", SubscribeOptions(\n    filters=[\"region:us\", \"priority:high\"]\n))\nclient.on(\"events\", lambda data, meta: print(data, meta.filter))\n\n# Replace all filters for a topic\nawait client.set_filters(\"events\", [\"region:eu\"])\n\n# Add filters to the existing set\nawait client.add_filters(\"events\", [\"priority:critical\"])\n\n# Remove specific filters\nawait client.remove_filters(\"events\", [\"region:eu\"])\n\n# Clear all filters (switches back to wildcard / receive all)\nawait client.set_filters(\"events\", [])\n\n# Publish with a filter value\nawait client.emit(\"events\", {\"msg\": \"US high-priority\"},\n    EmitOptions(filter=\"region:us\"))\n",[34,670,671,676,680,685,690,695,700,705,709,714,719,723,728,733,737,742,747,751,756,761,765,770,775],{"__ignoreMap":32},[37,672,673],{"class":39,"line":40},[37,674,675],{},"from nolag import SubscribeOptions, EmitOptions\n",[37,677,678],{"class":39,"line":47},[37,679,65],{"emptyLinePlaceholder":64},[37,681,682],{"class":39,"line":61},[37,683,684],{},"# Subscribe with initial filters\n",[37,686,687],{"class":39,"line":68},[37,688,689],{},"await client.subscribe(\"events\", SubscribeOptions(\n",[37,691,692],{"class":39,"line":74},[37,693,694],{},"    filters=[\"region:us\", \"priority:high\"]\n",[37,696,697],{"class":39,"line":85},[37,698,699],{},"))\n",[37,701,702],{"class":39,"line":90},[37,703,704],{},"client.on(\"events\", lambda data, meta: print(data, meta.filter))\n",[37,706,707],{"class":39,"line":96},[37,708,65],{"emptyLinePlaceholder":64},[37,710,711],{"class":39,"line":158},[37,712,713],{},"# Replace all filters for a topic\n",[37,715,716],{"class":39,"line":164},[37,717,718],{},"await client.set_filters(\"events\", [\"region:eu\"])\n",[37,720,721],{"class":39,"line":169},[37,722,65],{"emptyLinePlaceholder":64},[37,724,725],{"class":39,"line":175},[37,726,727],{},"# Add filters to the existing set\n",[37,729,730],{"class":39,"line":181},[37,731,732],{},"await client.add_filters(\"events\", [\"priority:critical\"])\n",[37,734,735],{"class":39,"line":186},[37,736,65],{"emptyLinePlaceholder":64},[37,738,739],{"class":39,"line":192},[37,740,741],{},"# Remove specific filters\n",[37,743,744],{"class":39,"line":198},[37,745,746],{},"await client.remove_filters(\"events\", [\"region:eu\"])\n",[37,748,749],{"class":39,"line":204},[37,750,65],{"emptyLinePlaceholder":64},[37,752,753],{"class":39,"line":209},[37,754,755],{},"# Clear all filters (switches back to wildcard / receive all)\n",[37,757,758],{"class":39,"line":215},[37,759,760],{},"await client.set_filters(\"events\", [])\n",[37,762,763],{"class":39,"line":220},[37,764,65],{"emptyLinePlaceholder":64},[37,766,767],{"class":39,"line":226},[37,768,769],{},"# Publish with a filter value\n",[37,771,772],{"class":39,"line":232},[37,773,774],{},"await client.emit(\"events\", {\"msg\": \"US high-priority\"},\n",[37,776,777],{"class":39,"line":237},[37,778,779],{},"    EmitOptions(filter=\"region:us\"))\n",[18,781,783],{"id":782},"connection-events","Connection Events",[23,785,786],{},[26,787,789],{"className":112,"code":788,"filename":114,"language":115,"meta":32,"style":32},"from nolag import ConnectionStatus\n\n# Listen for connection events\nclient.on(\"connect\", lambda: print(\"Connected!\"))\nclient.on(\"disconnect\", lambda reason: print(f\"Disconnected: {reason}\"))\nclient.on(\"reconnect\", lambda: print(\"Reconnected!\"))\nclient.on(\"error\", lambda err: print(f\"Error: {err}\"))\n\n# Check connection status\nif client.status == ConnectionStatus.CONNECTED:\n    print(\"We're connected!\")\n",[34,790,791,796,800,805,810,815,820,825,829,834,839],{"__ignoreMap":32},[37,792,793],{"class":39,"line":40},[37,794,795],{},"from nolag import ConnectionStatus\n",[37,797,798],{"class":39,"line":47},[37,799,65],{"emptyLinePlaceholder":64},[37,801,802],{"class":39,"line":61},[37,803,804],{},"# Listen for connection events\n",[37,806,807],{"class":39,"line":68},[37,808,809],{},"client.on(\"connect\", lambda: print(\"Connected!\"))\n",[37,811,812],{"class":39,"line":74},[37,813,814],{},"client.on(\"disconnect\", lambda reason: print(f\"Disconnected: {reason}\"))\n",[37,816,817],{"class":39,"line":85},[37,818,819],{},"client.on(\"reconnect\", lambda: print(\"Reconnected!\"))\n",[37,821,822],{"class":39,"line":90},[37,823,824],{},"client.on(\"error\", lambda err: print(f\"Error: {err}\"))\n",[37,826,827],{"class":39,"line":96},[37,828,65],{"emptyLinePlaceholder":64},[37,830,831],{"class":39,"line":158},[37,832,833],{},"# Check connection status\n",[37,835,836],{"class":39,"line":164},[37,837,838],{},"if client.status == ConnectionStatus.CONNECTED:\n",[37,840,841],{"class":39,"line":169},[37,842,843],{},"    print(\"We're connected!\")\n",[18,845,847],{"id":846},"wildcard-handler-on_any-off_any","Wildcard Handler (on_any / off_any)",[14,849,850,851,854,855,858],{},"Use ",[34,852,853],{},"on_any()"," to receive every message regardless of topic.\nThe handler receives ",[34,856,857],{},"(topic, data, meta)",".",[23,860,861],{},[26,862,864],{"className":112,"code":863,"filename":114,"language":115,"meta":32,"style":32},"# Listen for ALL messages regardless of topic\ndef log_all(topic, data, meta):\n    print(f\"[{topic}] {data} (from: {meta.sender})\")\n\nclient.on_any(log_all)\n\n# Remove a specific on_any handler\nclient.off_any(log_all)\n\n# Remove ALL on_any handlers\nclient.off_any()\n",[34,865,866,871,876,881,885,890,894,899,904,908,913],{"__ignoreMap":32},[37,867,868],{"class":39,"line":40},[37,869,870],{},"# Listen for ALL messages regardless of topic\n",[37,872,873],{"class":39,"line":47},[37,874,875],{},"def log_all(topic, data, meta):\n",[37,877,878],{"class":39,"line":61},[37,879,880],{},"    print(f\"[{topic}] {data} (from: {meta.sender})\")\n",[37,882,883],{"class":39,"line":68},[37,884,65],{"emptyLinePlaceholder":64},[37,886,887],{"class":39,"line":74},[37,888,889],{},"client.on_any(log_all)\n",[37,891,892],{"class":39,"line":85},[37,893,65],{"emptyLinePlaceholder":64},[37,895,896],{"class":39,"line":90},[37,897,898],{},"# Remove a specific on_any handler\n",[37,900,901],{"class":39,"line":96},[37,902,903],{},"client.off_any(log_all)\n",[37,905,906],{"class":39,"line":158},[37,907,65],{"emptyLinePlaceholder":64},[37,909,910],{"class":39,"line":164},[37,911,912],{},"# Remove ALL on_any handlers\n",[37,914,915],{"class":39,"line":169},[37,916,917],{},"client.off_any()\n",[18,919,921],{"id":920},"presence","Presence",[23,923,924],{},[26,925,927],{"className":112,"code":926,"filename":114,"language":115,"meta":32,"style":32},"# Set presence scoped to a room (recommended)\nroom = client.set_app(\"my-app\").set_room(\"general\")\nawait room.set_presence({\"status\": \"online\", \"username\": \"alice\"})\n\n# Or set presence with explicit room ID\nawait client.set_presence({\"status\": \"online\"}, room_id=\"general\")\n\n# Fetch presence list for a room\nactors = await room.fetch_presence()\nfor actor in actors:\n    print(f\"{actor['actorTokenId']}: {actor['presence']}\")\n\n# Get cached presence for a specific actor\nactor = client.get_presence(\"some-actor-token-id\")\nif actor:\n    print(f\"{actor.actor_token_id}: {actor.presence}\")\n\n# Get all cached presence data\nfor actor in client.get_all_presence():\n    print(f\"{actor.actor_token_id} ({actor.actor_type}): {actor.presence}\")\n\n# Clear your presence\nawait client.clear_presence()\n\n# Listen for presence events (real-time)\nclient.on(\"presence:join\", lambda actor: print(f\"Joined: {actor.actor_token_id}\"))\nclient.on(\"presence:leave\", lambda actor: print(f\"Left: {actor.actor_token_id}\"))\nclient.on(\"presence:update\", lambda actor: print(f\"Updated: {actor.presence}\"))\n",[34,928,929,934,939,944,948,953,958,962,967,972,977,982,986,991,996,1001,1006,1010,1015,1020,1025,1029,1034,1039,1043,1048,1053,1058],{"__ignoreMap":32},[37,930,931],{"class":39,"line":40},[37,932,933],{},"# Set presence scoped to a room (recommended)\n",[37,935,936],{"class":39,"line":47},[37,937,938],{},"room = client.set_app(\"my-app\").set_room(\"general\")\n",[37,940,941],{"class":39,"line":61},[37,942,943],{},"await room.set_presence({\"status\": \"online\", \"username\": \"alice\"})\n",[37,945,946],{"class":39,"line":68},[37,947,65],{"emptyLinePlaceholder":64},[37,949,950],{"class":39,"line":74},[37,951,952],{},"# Or set presence with explicit room ID\n",[37,954,955],{"class":39,"line":85},[37,956,957],{},"await client.set_presence({\"status\": \"online\"}, room_id=\"general\")\n",[37,959,960],{"class":39,"line":90},[37,961,65],{"emptyLinePlaceholder":64},[37,963,964],{"class":39,"line":96},[37,965,966],{},"# Fetch presence list for a room\n",[37,968,969],{"class":39,"line":158},[37,970,971],{},"actors = await room.fetch_presence()\n",[37,973,974],{"class":39,"line":164},[37,975,976],{},"for actor in actors:\n",[37,978,979],{"class":39,"line":169},[37,980,981],{},"    print(f\"{actor['actorTokenId']}: {actor['presence']}\")\n",[37,983,984],{"class":39,"line":175},[37,985,65],{"emptyLinePlaceholder":64},[37,987,988],{"class":39,"line":181},[37,989,990],{},"# Get cached presence for a specific actor\n",[37,992,993],{"class":39,"line":186},[37,994,995],{},"actor = client.get_presence(\"some-actor-token-id\")\n",[37,997,998],{"class":39,"line":192},[37,999,1000],{},"if actor:\n",[37,1002,1003],{"class":39,"line":198},[37,1004,1005],{},"    print(f\"{actor.actor_token_id}: {actor.presence}\")\n",[37,1007,1008],{"class":39,"line":204},[37,1009,65],{"emptyLinePlaceholder":64},[37,1011,1012],{"class":39,"line":209},[37,1013,1014],{},"# Get all cached presence data\n",[37,1016,1017],{"class":39,"line":215},[37,1018,1019],{},"for actor in client.get_all_presence():\n",[37,1021,1022],{"class":39,"line":220},[37,1023,1024],{},"    print(f\"{actor.actor_token_id} ({actor.actor_type}): {actor.presence}\")\n",[37,1026,1027],{"class":39,"line":226},[37,1028,65],{"emptyLinePlaceholder":64},[37,1030,1031],{"class":39,"line":232},[37,1032,1033],{},"# Clear your presence\n",[37,1035,1036],{"class":39,"line":237},[37,1037,1038],{},"await client.clear_presence()\n",[37,1040,1041],{"class":39,"line":243},[37,1042,65],{"emptyLinePlaceholder":64},[37,1044,1045],{"class":39,"line":249},[37,1046,1047],{},"# Listen for presence events (real-time)\n",[37,1049,1050],{"class":39,"line":254},[37,1051,1052],{},"client.on(\"presence:join\", lambda actor: print(f\"Joined: {actor.actor_token_id}\"))\n",[37,1054,1055],{"class":39,"line":260},[37,1056,1057],{},"client.on(\"presence:leave\", lambda actor: print(f\"Left: {actor.actor_token_id}\"))\n",[37,1059,1060],{"class":39,"line":266},[37,1061,1062],{},"client.on(\"presence:update\", lambda actor: print(f\"Updated: {actor.presence}\"))\n",[18,1064,1066],{"id":1065},"error-handling","Error Handling",[23,1068,1069],{},[26,1070,1072],{"className":112,"code":1071,"filename":114,"language":115,"meta":32,"style":32},"import asyncio\nfrom nolag import NoLag\n\nasync def main():\n    client = NoLag(\"your-actor-token\")\n\n    try:\n        await client.connect()\n    except Exception as e:\n        print(f\"Connection failed: {e}\")\n        return\n\n    # Handle errors during operation\n    client.on(\"error\", lambda err: print(f\"Error: {err}\"))\n\n    try:\n        await client.emit(\"topic\", {\"data\": \"value\"})\n    except Exception as e:\n        print(f\"Emit failed: {e}\")\n\n    # Disconnect is synchronous, no await needed\n    client.disconnect()\n\nasyncio.run(main())\n",[34,1073,1074,1078,1082,1086,1090,1094,1098,1103,1108,1113,1118,1123,1127,1132,1137,1141,1145,1150,1154,1159,1163,1168,1172,1176],{"__ignoreMap":32},[37,1075,1076],{"class":39,"line":40},[37,1077,122],{},[37,1079,1080],{"class":39,"line":47},[37,1081,127],{},[37,1083,1084],{"class":39,"line":61},[37,1085,65],{"emptyLinePlaceholder":64},[37,1087,1088],{"class":39,"line":68},[37,1089,136],{},[37,1091,1092],{"class":39,"line":74},[37,1093,146],{},[37,1095,1096],{"class":39,"line":85},[37,1097,65],{"emptyLinePlaceholder":64},[37,1099,1100],{"class":39,"line":90},[37,1101,1102],{},"    try:\n",[37,1104,1105],{"class":39,"line":96},[37,1106,1107],{},"        await client.connect()\n",[37,1109,1110],{"class":39,"line":158},[37,1111,1112],{},"    except Exception as e:\n",[37,1114,1115],{"class":39,"line":164},[37,1116,1117],{},"        print(f\"Connection failed: {e}\")\n",[37,1119,1120],{"class":39,"line":169},[37,1121,1122],{},"        return\n",[37,1124,1125],{"class":39,"line":175},[37,1126,65],{"emptyLinePlaceholder":64},[37,1128,1129],{"class":39,"line":181},[37,1130,1131],{},"    # Handle errors during operation\n",[37,1133,1134],{"class":39,"line":186},[37,1135,1136],{},"    client.on(\"error\", lambda err: print(f\"Error: {err}\"))\n",[37,1138,1139],{"class":39,"line":192},[37,1140,65],{"emptyLinePlaceholder":64},[37,1142,1143],{"class":39,"line":198},[37,1144,1102],{},[37,1146,1147],{"class":39,"line":204},[37,1148,1149],{},"        await client.emit(\"topic\", {\"data\": \"value\"})\n",[37,1151,1152],{"class":39,"line":209},[37,1153,1112],{},[37,1155,1156],{"class":39,"line":215},[37,1157,1158],{},"        print(f\"Emit failed: {e}\")\n",[37,1160,1161],{"class":39,"line":220},[37,1162,65],{"emptyLinePlaceholder":64},[37,1164,1165],{"class":39,"line":226},[37,1166,1167],{},"    # Disconnect is synchronous, no await needed\n",[37,1169,1170],{"class":39,"line":232},[37,1171,263],{},[37,1173,1174],{"class":39,"line":237},[37,1175,65],{"emptyLinePlaceholder":64},[37,1177,1178],{"class":39,"line":243},[37,1179,274],{},[18,1181,1183],{"id":1182},"qos-levels","QoS Levels",[1185,1186,1187,1203],"table",{},[1188,1189,1190],"thead",{},[1191,1192,1193,1197,1200],"tr",{},[1194,1195,1196],"th",{},"Level",[1194,1198,1199],{},"Name",[1194,1201,1202],{},"Description",[1204,1205,1206,1218,1229],"tbody",{},[1191,1207,1208,1212,1215],{},[1209,1210,1211],"td",{},"0",[1209,1213,1214],{},"AT_MOST_ONCE",[1209,1216,1217],{},"Fire and forget, no acknowledgment",[1191,1219,1220,1223,1226],{},[1209,1221,1222],{},"1",[1209,1224,1225],{},"AT_LEAST_ONCE",[1209,1227,1228],{},"Guaranteed delivery, may have duplicates",[1191,1230,1231,1234,1237],{},[1209,1232,1233],{},"2",[1209,1235,1236],{},"EXACTLY_ONCE",[1209,1238,1239],{},"Guaranteed exactly one delivery",[18,1241,1243],{"id":1242},"rest-api-client","REST API Client",[14,1245,1246],{},"The SDK also includes a REST API client for managing apps, rooms, and actors:",[23,1248,1249],{},[26,1250,1252],{"className":112,"code":1251,"filename":114,"language":115,"meta":32,"style":32},"from nolag import NoLagApi, AppCreate, RoomCreate, ActorCreate\n\nasync def main():\n    # Create API client with project-scoped API key\n    async with NoLagApi(\"nlg_live_xxx.secret\") as api:\n        # List all apps in your project\n        apps = await api.apps.list()\n        print(f\"Found {len(apps.data)} apps\")\n\n        # Create a new app\n        app = await api.apps.create(AppCreate(\n            name=\"my-chat-app\",\n            description=\"A real-time chat application\"\n        ))\n\n        # Create a room in the app\n        room = await api.rooms.create(app.app_id, RoomCreate(\n            name=\"general\",\n            slug=\"general\"\n        ))\n\n        # Create an actor (save the access token!)\n        actor = await api.actors.create(ActorCreate(\n            name=\"web-client\",\n            actor_type=\"device\"\n        ))\n        print(f\"Actor token: {actor.access_token}\")\n",[34,1253,1254,1259,1263,1267,1272,1277,1282,1287,1292,1296,1301,1306,1311,1316,1321,1325,1330,1335,1340,1345,1349,1353,1358,1363,1368,1373,1377],{"__ignoreMap":32},[37,1255,1256],{"class":39,"line":40},[37,1257,1258],{},"from nolag import NoLagApi, AppCreate, RoomCreate, ActorCreate\n",[37,1260,1261],{"class":39,"line":47},[37,1262,65],{"emptyLinePlaceholder":64},[37,1264,1265],{"class":39,"line":61},[37,1266,136],{},[37,1268,1269],{"class":39,"line":68},[37,1270,1271],{},"    # Create API client with project-scoped API key\n",[37,1273,1274],{"class":39,"line":74},[37,1275,1276],{},"    async with NoLagApi(\"nlg_live_xxx.secret\") as api:\n",[37,1278,1279],{"class":39,"line":85},[37,1280,1281],{},"        # List all apps in your project\n",[37,1283,1284],{"class":39,"line":90},[37,1285,1286],{},"        apps = await api.apps.list()\n",[37,1288,1289],{"class":39,"line":96},[37,1290,1291],{},"        print(f\"Found {len(apps.data)} apps\")\n",[37,1293,1294],{"class":39,"line":158},[37,1295,65],{"emptyLinePlaceholder":64},[37,1297,1298],{"class":39,"line":164},[37,1299,1300],{},"        # Create a new app\n",[37,1302,1303],{"class":39,"line":169},[37,1304,1305],{},"        app = await api.apps.create(AppCreate(\n",[37,1307,1308],{"class":39,"line":175},[37,1309,1310],{},"            name=\"my-chat-app\",\n",[37,1312,1313],{"class":39,"line":181},[37,1314,1315],{},"            description=\"A real-time chat application\"\n",[37,1317,1318],{"class":39,"line":186},[37,1319,1320],{},"        ))\n",[37,1322,1323],{"class":39,"line":192},[37,1324,65],{"emptyLinePlaceholder":64},[37,1326,1327],{"class":39,"line":198},[37,1328,1329],{},"        # Create a room in the app\n",[37,1331,1332],{"class":39,"line":204},[37,1333,1334],{},"        room = await api.rooms.create(app.app_id, RoomCreate(\n",[37,1336,1337],{"class":39,"line":209},[37,1338,1339],{},"            name=\"general\",\n",[37,1341,1342],{"class":39,"line":215},[37,1343,1344],{},"            slug=\"general\"\n",[37,1346,1347],{"class":39,"line":220},[37,1348,1320],{},[37,1350,1351],{"class":39,"line":226},[37,1352,65],{"emptyLinePlaceholder":64},[37,1354,1355],{"class":39,"line":232},[37,1356,1357],{},"        # Create an actor (save the access token!)\n",[37,1359,1360],{"class":39,"line":237},[37,1361,1362],{},"        actor = await api.actors.create(ActorCreate(\n",[37,1364,1365],{"class":39,"line":243},[37,1366,1367],{},"            name=\"web-client\",\n",[37,1369,1370],{"class":39,"line":249},[37,1371,1372],{},"            actor_type=\"device\"\n",[37,1374,1375],{"class":39,"line":254},[37,1376,1320],{},[37,1378,1379],{"class":39,"line":260},[37,1380,1381],{},"        print(f\"Actor token: {actor.access_token}\")\n",[18,1383,1385],{"id":1384},"load-balancing","Load Balancing",[14,1387,1388],{},"Distribute messages across multiple subscribers:",[23,1390,1391],{},[26,1392,1394],{"className":112,"code":1393,"filename":114,"language":115,"meta":32,"style":32},"from nolag import NoLag, NoLagOptions, SubscribeOptions\n\n# Option 1: Enable load balancing globally via NoLagOptions\nclient = NoLag(\"your-actor-token\", NoLagOptions(\n    load_balance=True,\n    load_balance_group=\"task-workers\"\n))\n\n# Option 2: Enable per-subscription\nawait client.subscribe(\n    \"tasks\",\n    SubscribeOptions(\n        load_balance=True,\n        load_balance_group=\"task-workers\"\n    )\n)\nclient.on(\"tasks\", lambda data, meta: print(f\"Processing: {data}\"))\n",[34,1395,1396,1401,1405,1410,1415,1419,1424,1428,1432,1437,1442,1447,1452,1457,1462,1467,1471],{"__ignoreMap":32},[37,1397,1398],{"class":39,"line":40},[37,1399,1400],{},"from nolag import NoLag, NoLagOptions, SubscribeOptions\n",[37,1402,1403],{"class":39,"line":47},[37,1404,65],{"emptyLinePlaceholder":64},[37,1406,1407],{"class":39,"line":61},[37,1408,1409],{},"# Option 1: Enable load balancing globally via NoLagOptions\n",[37,1411,1412],{"class":39,"line":68},[37,1413,1414],{},"client = NoLag(\"your-actor-token\", NoLagOptions(\n",[37,1416,1417],{"class":39,"line":74},[37,1418,542],{},[37,1420,1421],{"class":39,"line":85},[37,1422,1423],{},"    load_balance_group=\"task-workers\"\n",[37,1425,1426],{"class":39,"line":90},[37,1427,699],{},[37,1429,1430],{"class":39,"line":96},[37,1431,65],{"emptyLinePlaceholder":64},[37,1433,1434],{"class":39,"line":158},[37,1435,1436],{},"# Option 2: Enable per-subscription\n",[37,1438,1439],{"class":39,"line":164},[37,1440,1441],{},"await client.subscribe(\n",[37,1443,1444],{"class":39,"line":169},[37,1445,1446],{},"    \"tasks\",\n",[37,1448,1449],{"class":39,"line":175},[37,1450,1451],{},"    SubscribeOptions(\n",[37,1453,1454],{"class":39,"line":181},[37,1455,1456],{},"        load_balance=True,\n",[37,1458,1459],{"class":39,"line":186},[37,1460,1461],{},"        load_balance_group=\"task-workers\"\n",[37,1463,1464],{"class":39,"line":192},[37,1465,1466],{},"    )\n",[37,1468,1469],{"class":39,"line":198},[37,1470,354],{},[37,1472,1473],{"class":39,"line":204},[37,1474,1475],{},"client.on(\"tasks\", lambda data, meta: print(f\"Processing: {data}\"))\n",[18,1477,1479],{"id":1478},"type-definitions","Type Definitions",[23,1481,1482],{},[26,1483,1485],{"className":112,"code":1484,"filename":114,"language":115,"meta":32,"style":32},"from nolag import (\n    # WebSocket Client\n    NoLag,              # Main client class\n    NoLagOptions,       # Connection options\n    SubscribeOptions,   # Subscription options\n    EmitOptions,        # Publish options\n    ConnectionStatus,   # Connection status enum\n    ActorType,          # Actor type enum\n    QoS,                # QoS level enum\n    MessageMeta,        # Message metadata\n    ActorPresence,      # Presence info\n\n    # REST API Client\n    NoLagApi,           # REST API client\n    NoLagApiError,      # API error class\n    App, AppCreate, AppUpdate,\n    Room, RoomCreate, RoomUpdate,\n    Actor, ActorWithToken, ActorCreate, ActorUpdate,\n)\n",[34,1486,1487,1492,1497,1502,1507,1512,1517,1522,1527,1532,1537,1542,1546,1551,1556,1561,1566,1571,1576],{"__ignoreMap":32},[37,1488,1489],{"class":39,"line":40},[37,1490,1491],{},"from nolag import (\n",[37,1493,1494],{"class":39,"line":47},[37,1495,1496],{},"    # WebSocket Client\n",[37,1498,1499],{"class":39,"line":61},[37,1500,1501],{},"    NoLag,              # Main client class\n",[37,1503,1504],{"class":39,"line":68},[37,1505,1506],{},"    NoLagOptions,       # Connection options\n",[37,1508,1509],{"class":39,"line":74},[37,1510,1511],{},"    SubscribeOptions,   # Subscription options\n",[37,1513,1514],{"class":39,"line":85},[37,1515,1516],{},"    EmitOptions,        # Publish options\n",[37,1518,1519],{"class":39,"line":90},[37,1520,1521],{},"    ConnectionStatus,   # Connection status enum\n",[37,1523,1524],{"class":39,"line":96},[37,1525,1526],{},"    ActorType,          # Actor type enum\n",[37,1528,1529],{"class":39,"line":158},[37,1530,1531],{},"    QoS,                # QoS level enum\n",[37,1533,1534],{"class":39,"line":164},[37,1535,1536],{},"    MessageMeta,        # Message metadata\n",[37,1538,1539],{"class":39,"line":169},[37,1540,1541],{},"    ActorPresence,      # Presence info\n",[37,1543,1544],{"class":39,"line":175},[37,1545,65],{"emptyLinePlaceholder":64},[37,1547,1548],{"class":39,"line":181},[37,1549,1550],{},"    # REST API Client\n",[37,1552,1553],{"class":39,"line":186},[37,1554,1555],{},"    NoLagApi,           # REST API client\n",[37,1557,1558],{"class":39,"line":192},[37,1559,1560],{},"    NoLagApiError,      # API error class\n",[37,1562,1563],{"class":39,"line":198},[37,1564,1565],{},"    App, AppCreate, AppUpdate,\n",[37,1567,1568],{"class":39,"line":204},[37,1569,1570],{},"    Room, RoomCreate, RoomUpdate,\n",[37,1572,1573],{"class":39,"line":209},[37,1574,1575],{},"    Actor, ActorWithToken, ActorCreate, ActorUpdate,\n",[37,1577,1578],{"class":39,"line":215},[37,1579,354],{},[18,1581,1583],{"id":1582},"requirements","Requirements",[1585,1586,1587,1591,1594,1597],"ul",{},[1588,1589,1590],"li",{},"Python 3.10+",[1588,1592,1593],{},"websockets >= 12.0",[1588,1595,1596],{},"msgpack >= 1.0.0",[1588,1598,1599],{},"aiohttp >= 3.9.0",[18,1601,1603],{"id":1602},"next-steps","Next Steps",[1585,1605,1606,1617,1623,1629],{},[1588,1607,1608,1613,1614],{},[1609,1610,1612],"a",{"href":1611},"/docs/agents/getting-started","AI Agents SDK"," - build multi-agent workflows with ",[34,1615,1616],{},"nolag-agents",[1588,1618,1619],{},[1609,1620,1622],{"href":1621},"/docs/concepts/topics","Learn about Topics",[1588,1624,1625],{},[1609,1626,1628],{"href":1627},"/docs/concepts/presence","Presence Tracking",[1588,1630,1631],{},[1609,1632,1634],{"href":1633},"/docs/api-reference","REST API Reference",[1636,1637,1638],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":32,"searchDepth":47,"depth":47,"links":1640},[1641,1642,1643,1644,1645,1646,1647,1648,1649,1650,1651,1652,1653,1654,1655,1656,1657],{"id":20,"depth":47,"text":21},{"id":106,"depth":47,"text":107},{"id":277,"depth":47,"text":278},{"id":366,"depth":47,"text":367},{"id":476,"depth":47,"text":477},{"id":583,"depth":47,"text":584},{"id":655,"depth":47,"text":656},{"id":782,"depth":47,"text":783},{"id":846,"depth":47,"text":847},{"id":920,"depth":47,"text":921},{"id":1065,"depth":47,"text":1066},{"id":1182,"depth":47,"text":1183},{"id":1242,"depth":47,"text":1243},{"id":1384,"depth":47,"text":1385},{"id":1478,"depth":47,"text":1479},{"id":1582,"depth":47,"text":1583},{"id":1602,"depth":47,"text":1603},"Complete reference for the NoLag Python SDK. Connect, subscribe, publish, and manage real-time messaging with async/await support.","md",{},"/docs/sdks/python",{"title":5,"description":1658},"docs/sdks/python","kSeqjeUADnjoDrDRvDCAh-ZC1ap3bnwx9zYfye--MKI",1788160344699]