Language Server Protocol implementation in sans-io pattern. Which is highly inspired by Sans-IO pattern. And some relatived projects:
So it can be integreted with trio, asyncio, or some other frameworks easily.
Python >= 3.6
- Pure python implementation
- Don't relatived to other site-packages
- Can (should) easily integreted with high level framework like trio, asyncio
There are two ways to install lsp
- Install via pip (recommended)
pip install lsp
- Install via setup.py
python setup.py install
import socket
from lsp import Connection, NEED_DATA, DataReceived, MessageEnd
sock = socket.socket()
sock.connect(("localhost", 10001))
conn = Connection("client")
answer = input("Send request?(y/n)")
while answer == "y":
# use connection send_json method to convert json object to bytes
request_data = conn.send_json({"method": "didOpen"})
# then we can send data to server
sock.sendall(request_data)
while True:
# and then we can get next_event of connection, it can indicate
# that what should we do.
event = conn.next_event()
# we need to receive data from server
if event is NEED_DATA:
try:
data = sock.recv(1024)
except ConnectionResetError:
print('The server connection is closed, So I will leave:)')
conn.close()
sock.close()
exit(0)
else:
print("return from sock.recv")
conn.receive(data)
# we have receive data from server
elif isinstance(event, DataReceived):
print("Receive event, content:")
print(event)
elif isinstance(event, MessageEnd):
print("Server sending data complete.")
break
# then we can call get_received_data() to extract out what we get
header, response_body = conn.get_received_data()
print("Response header from server:")
print(header)
print("Response body from server:")
print(response_body)
answer = input("Send request?(y/n)")
conn.go_next_circle()
import socket
from lsp import Connection, NEED_DATA, RequestReceived, DataReceived, MessageEnd
sock = socket.socket()
sock.bind(("0.0.0.0", 10001))
sock.listen(1)
client_sock, addr = sock.accept()
print(f"get connection from {client_sock}")
conn = Connection("server")
try:
while True:
while True:
# call next event to indicate what server socket should do.
event = conn.next_event()
# no data coming yet, so the return value is NEED_DATA
if event is NEED_DATA:
data = client_sock.recv(1024)
if data == b"":
print("Client connection is closed, I will exit.")
exit(0)
conn.receive(data)
# Request header is coming :)
elif isinstance(event, RequestReceived):
print("Receive request header")
print(event.to_data())
# Request data is coming :)
elif isinstance(event, DataReceived):
print("Receive request data")
print(event.to_data())
# client has send data completely.
elif isinstance(event, MessageEnd):
print("Data receive complete:)")
break
# so we can call con.get_received_data to fetch what client send.
received_data = conn.get_received_data()
print(f"Receiving data: {received_data}")
# send response back to client.
print(f"Sending response to client")
data = conn.send_json({"Content": "I am received:)"})
client_sock.sendall(data)
print(f"For now, go to next circle")
# then we need to call go_next_circle, to get another request from client.
conn.go_next_circle()
finally:
sock.close()
For more usage example, please check out files in examples/servers folder.
- Want to send json data? You can try
conn.send_json
. - Want to know what we should do next? You can try
conn.next_event
. - After receive data, please don't forget to call
conn.receive(data)
. Which will save data into inner buffer, and it can driveconn.next_event
method returns other events. - When Receive
MessageEnd
event, we can just callconn.get_received_data
to fetch for incoming data.
Client side will get the following values from next_events:
- NEED_DATA - which indicate that we need to receive data from server.
- ResponseReceived - Client have receive response header.
- DataReceived - Client have receive resposne body.
- MessageEnd - Receive data from server complete.
Server side will get the following values from next_events:
- NEED_DATA - which indicate that we need to receive data from client.
- RequestReceived - Client have send request header, and we receive it.
- DataReceived - Server have receive response body from client.
- MessageEnd - Client sending request complete.