0
# pygls
1
2
A pythonic generic language server framework that implements the Language Server Protocol (LSP) for building custom language servers in Python. pygls provides comprehensive server lifecycle management, LSP feature decorators, workspace document management, async/await support, WebSocket capabilities for browser-based editors, and built-in progress reporting.
3
4
## Package Information
5
6
- **Package Name**: pygls
7
- **Language**: Python
8
- **Installation**: `pip install pygls`
9
- **Optional WebSocket Support**: `pip install pygls[ws]`
10
11
## Core Imports
12
13
```python
14
from pygls.server import LanguageServer
15
```
16
17
For protocol customization:
18
19
```python
20
from pygls.protocol import LanguageServerProtocol
21
from pygls.server import LanguageServer, Server
22
```
23
24
For client development:
25
26
```python
27
from pygls.client import JsonRPCClient
28
```
29
30
For workspace management:
31
32
```python
33
from pygls.workspace import Workspace, TextDocument, PositionCodec
34
```
35
36
For URI utilities:
37
38
```python
39
from pygls.uris import from_fs_path, to_fs_path, uri_scheme
40
```
41
42
For exception handling:
43
44
```python
45
from pygls.exceptions import PyglsError, JsonRpcException, FeatureAlreadyRegisteredError
46
```
47
48
## Basic Usage
49
50
```python
51
from pygls.server import LanguageServer
52
from lsprotocol.types import (
53
TEXT_DOCUMENT_COMPLETION,
54
CompletionItem,
55
CompletionList,
56
CompletionParams,
57
)
58
59
# Create a language server instance
60
server = LanguageServer("my-language-server", "v1.0.0")
61
62
# Register a completion feature
63
@server.feature(TEXT_DOCUMENT_COMPLETION)
64
def completions(params: CompletionParams):
65
document = server.workspace.get_document(params.text_document.uri)
66
current_line = document.lines[params.position.line].strip()
67
68
items = []
69
if current_line.endswith("hello."):
70
items = [
71
CompletionItem(label="world"),
72
CompletionItem(label="friend"),
73
]
74
75
return CompletionList(is_incomplete=False, items=items)
76
77
# Register a custom command
78
@server.command("myCustomCommand")
79
def my_command(params):
80
return {"result": "Command executed successfully"}
81
82
# Start the server
83
if __name__ == "__main__":
84
server.start_io() # Use stdio transport
85
```
86
87
## Architecture
88
89
pygls follows a layered architecture designed for maximum flexibility and LSP compliance:
90
91
- **Server Layer**: `LanguageServer` and `Server` classes handle server lifecycle, transport management, and feature registration
92
- **Protocol Layer**: `LanguageServerProtocol` and `JsonRPCProtocol` implement LSP message handling and JSON-RPC communication
93
- **Workspace Layer**: `Workspace`, `TextDocument`, and `PositionCodec` manage document synchronization and text operations
94
- **Feature Layer**: Decorators (`@server.feature`, `@server.command`, `@server.thread`) enable declarative feature registration
95
- **Transport Layer**: Adapters for stdio, TCP, and WebSocket connections support various editor integrations
96
97
This design enables custom language servers to integrate seamlessly with VSCode, Vim, Emacs, and other LSP-compatible editors while providing Python-native patterns for rapid development.
98
99
## Capabilities
100
101
### Server Creation and Management
102
103
Core functionality for creating, configuring, and running language servers with support for multiple transport methods and server lifecycle management.
104
105
```python { .api }
106
class LanguageServer(Server):
107
def __init__(
108
self,
109
name: str,
110
version: str,
111
protocol_cls: Type[LanguageServerProtocol] = None,
112
max_workers: int = 2,
113
text_document_sync_kind: TextDocumentSyncKind = TextDocumentSyncKind.Incremental
114
): ...
115
116
def start_io(self) -> None: ...
117
def start_tcp(self, host: str, port: int) -> None: ...
118
def start_ws(self, host: str, port: int) -> None: ...
119
```
120
121
[Server Management](./server-management.md)
122
123
### Feature Registration and Decorators
124
125
Decorator-based system for registering LSP features, custom commands, and thread execution patterns with automatic capability registration.
126
127
```python { .api }
128
def feature(
129
self,
130
method_name: str,
131
options: Any = None
132
) -> Callable[[F], F]: ...
133
134
def command(self, command_name: str) -> Callable[[F], F]: ...
135
136
def thread(self) -> Callable[[F], F]: ...
137
```
138
139
[Feature Registration](./feature-registration.md)
140
141
### Protocol and Message Handling
142
143
Low-level protocol handling for JSON-RPC communication, LSP message processing, and custom protocol extensions.
144
145
```python { .api }
146
class LanguageServerProtocol(JsonRPCProtocol):
147
def send_request(self, method: str, params: Any = None) -> Future: ...
148
def send_notification(self, method: str, params: Any = None) -> None: ...
149
def lsp_initialize(self, params: InitializeParams) -> InitializeResult: ...
150
```
151
152
[Protocol Handling](./protocol-handling.md)
153
154
### Workspace and Document Management
155
156
Comprehensive document synchronization, workspace operations, and text manipulation with position encoding support.
157
158
```python { .api }
159
class Workspace:
160
def get_document(self, doc_uri: str) -> TextDocument: ...
161
def put_document(self, doc_uri: str, source: str, version: int = None) -> TextDocument: ...
162
def remove_document(self, doc_uri: str) -> None: ...
163
def apply_edit(self, edit: WorkspaceEdit) -> None: ...
164
165
class TextDocument:
166
def apply_change(self, change: TextDocumentContentChangeEvent) -> None: ...
167
def offset_at_position(self, position: Position) -> int: ...
168
def word_at_position(self, position: Position) -> str: ...
169
```
170
171
[Workspace Management](./workspace-management.md)
172
173
### Client Operations
174
175
Client-side functionality for connecting to language servers and handling server responses.
176
177
```python { .api }
178
class JsonRPCClient:
179
def __init__(
180
self,
181
protocol_cls: Type[JsonRPCProtocol] = None,
182
converter_factory: Callable[[], Converter] = None
183
): ...
184
185
def start_io(self, stdin: TextIO, stdout: TextIO) -> None: ...
186
def start_tcp(self, host: str, port: int) -> None: ...
187
def start_ws(self, host: str, port: int) -> None: ...
188
```
189
190
[Client Operations](./client-operations.md)
191
192
### Progress Reporting
193
194
Built-in progress reporting system for long-running operations with client-side progress bar integration.
195
196
```python { .api }
197
class Progress:
198
def create_task(
199
self,
200
token: ProgressToken,
201
title: str,
202
cancellable: bool = True,
203
message: str = None,
204
percentage: int = None
205
) -> Future: ...
206
207
def update(
208
self,
209
token: ProgressToken,
210
message: str = None,
211
percentage: int = None
212
) -> None: ...
213
214
def end(self, token: ProgressToken, message: str = None) -> None: ...
215
```
216
217
[Progress Reporting](./progress-reporting.md)
218
219
### Utilities and Helpers
220
221
URI handling, position encoding, exception management, and other utility functions for language server development.
222
223
```python { .api }
224
# URI Utilities
225
def from_fs_path(path: str) -> str: ...
226
def to_fs_path(uri: str) -> str: ...
227
228
# Position Encoding
229
class PositionCodec:
230
def position_from_client_units(self, lines: List[str], position: Position) -> Position: ...
231
def position_to_client_units(self, lines: List[str], position: Position) -> Position: ...
232
```
233
234
[Utilities](./utilities.md)
235
236
### URI Utilities
237
238
Cross-platform URI handling and path conversion utilities for working with Language Server Protocol URIs and filesystem paths across different platforms.
239
240
```python { .api }
241
def from_fs_path(path: str) -> Optional[str]: ...
242
def to_fs_path(uri: str) -> Optional[str]: ...
243
def uri_scheme(uri: str) -> Optional[str]: ...
244
def uri_with(uri: str, **components) -> str: ...
245
```
246
247
[URI Utilities](./uri-utilities.md)
248
249
### Exception Handling
250
251
Exception classes for pygls error handling, JSON-RPC protocol errors, and language server specific exceptions with proper error codes and messages.
252
253
```python { .api }
254
class PyglsError(Exception): ...
255
class JsonRpcException(Exception): ...
256
class JsonRpcParseError(JsonRpcException): ...
257
class JsonRpcInvalidRequest(JsonRpcException): ...
258
class JsonRpcMethodNotFound(JsonRpcException): ...
259
class FeatureAlreadyRegisteredError(PyglsError): ...
260
class CommandAlreadyRegisteredError(PyglsError): ...
261
```
262
263
[Exception Handling](./exception-handling.md)