Skip to main content

Sans-IO pattern, language server protocol implementation

Project description

Language Server Protocol implementation in sans-io pattern. Which is highly inspired by [[https://sans-io.readthedocs.io/how-to-sans-io.html][Sans-IO pattern]]. And some relatived projects: [[https://github.com/python-hyper/hyper-h2][hyper-h2]], [[https://github.com/python-hyper/h11][h11]]

So the actual language server can build on this, it can be integreted with trio, asyncio, or some other frameworks.

* Required python version
Python >= 3.6

* How to install it
There are two ways to install lsp:
- install via pip (recommended)
#+BEGIN_SRC shell
pip install lsp
#+END_SRC
- install via setup.py
#+BEGIN_SRC shell
python setup.py install
#+END_SRC
* Basic Usage example
** For client
#+BEGIN_SRC python
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()

#+END_SRC

For more usage example, please check out files in *examples/clients* folder.
** For server
#+BEGIN_SRC python
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()

#+END_SRC

For more usage example, please check out files in *examples/servers* folder.


* Main API
1. Want to send json data? You can try =conn.send_json=.
2. Want to know what we should do next? You can try =conn.next_event=.
3. After receive data, please don't forget to call =conn.receive(data)=. Which will save data into inner buffer, and it can drive =conn.next_event= method returns other events.

* Main events we will get from next_event
** Client
Client side will get the following values from next_events:
1. NEED_DATA - which indicate that we need to receive data from server.
2. ResponseReceived - Client have receive response header.
3. DataReceived - Client have receive resposne body.
4. MessageEnd - Receive data from server complete.

** Server
Server side will get the following values from next_events:
1. NEED_DATA - which indicate that we need to receive data from client.
2. RequestReceived - Client have send request header, and we receive it.
3. DataReceived - Server have receive response body from client.
4. MessageEnd - Client sending request complete.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lsp-0.1.0.tar.gz (11.7 kB view details)

Uploaded Source

Built Distribution

lsp-0.1.0-py3.7.egg (26.2 kB view details)

Uploaded Source

File details

Details for the file lsp-0.1.0.tar.gz.

File metadata

  • Download URL: lsp-0.1.0.tar.gz
  • Upload date:
  • Size: 11.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/40.6.3 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/3.7.0rc1

File hashes

Hashes for lsp-0.1.0.tar.gz
Algorithm Hash digest
SHA256 06d49b283d0fcdd848d44c0839cd935a839add4920bd74e270d8761131ae3f1e
MD5 6bfb1ed3051ccc60b758e89f245457e3
BLAKE2b-256 0fbce11e6033055977cedf86b2cf0156da604afe29617933d4b33d7ddcd71fae

See more details on using hashes here.

File details

Details for the file lsp-0.1.0-py3.7.egg.

File metadata

  • Download URL: lsp-0.1.0-py3.7.egg
  • Upload date:
  • Size: 26.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/40.6.3 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/3.7.0rc1

File hashes

Hashes for lsp-0.1.0-py3.7.egg
Algorithm Hash digest
SHA256 191f4306e283a058c46322fabf83e720eb4b3dff35cc28599ea6e0a3a2440640
MD5 27f49214993312573af4b671a428433e
BLAKE2b-256 eda8796871383980c3c4d60388f456e7175d7a1dd8929575d0cda04d6db52b24

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page