LSP for validating htpy syntax rules
Project description
htpy-lsp (python)
A Language Server Protocol (LSP) server for validating htpy coding usage, including Datastar and FastApi integration patterns.
[!TIP] Why this matters? While
htpyis powerful and type-safe, its syntax (brackets for content, parentheses for attributes) can be counter-intuitive for developers coming from React/Jinja. LLMs and AI coding assistants frequently fail to follow these rules, often nesting content in parentheses. This LSP serves as a critical safety net for both humans and AI to ensure correct code generation and execution.
Rules Enforced
- Attributes in Parentheses: Use keyword arguments like
div(class_="foo"). (Note: useclass_, notcls). - Content in Brackets:
div["Hello"] - No Positional Arguments in Parentheses:
- Invalid:
div("Hello")-> Warning (Usediv["Hello"]instead) - Exception 1: Class shorthand
div(".my-class")is allowed. - Exception 2: Datastar helpers
data.on(...),data.attr(...)are allowed as positional arguments.
- Invalid:
- Return Type Consistency:
- If a function is annotated to return
HtpyResponse(or-> HtpyResponse), it should return aHtpyResponse(...)wrapper, not a rawhtpyelement (div[...]).
- If a function is annotated to return
- String Conversion:
- Avoid manual casting of
htpyelements to string. UseHtpyResponse.
- Avoid manual casting of
- Prefer HtpyResponse:
- Warns when
HTMLResponseis used withhtpycontent.
- Warns when
Installation
Global Installation (Recommended)
Using uv to install the tool globally and isolated:
uv tool install htpy-lsp
# Or from local source:
uv tool install .
This creates a global htpy-lsp command.
Editor Configuration
1. OpenCode
OpenCode uses opencode.json in the project root for local LSP settings, or its global config (e.g., ~/.config/opencode/opencode.json on Linux/Mac).
Add the following to your configuration:
{
"lsp": {
"htpy-lsp": {
"command": ["/path/to/htpy-lsp"],
"extensions": [".py"]
}
}
}
[!NOTE] Executable Path Examples:
- Mac/Linux:
/Users/YOUR_USER/.local/bin/htpy-lspor/usr/local/bin/htpy-lsp- Windows:
C:\Users\YOUR_USER\AppData\Roaming\Python\Scripts\htpy-lsp.exe
2. VS Code
Since htpy-lsp is a custom server, you can use the Generic LSP Proxy extension.
Create a .vscode/lsp-proxy.json file in your workspace:
[
{
"languageId": "python",
"command": "/path/to/htpy-lsp",
"fileExtensions": [".py"]
}
]
Usage Examples
Proper Syntax
from htpy import div, span
# ✅ Correct: Attributes in (), content in []
div(class_="container")[
span(".text-bold")["Hello World"]
]
# ✅ Correct: Standalone tags or attributes only
my_div = div
attrs_only = div(id="main")
# ❌ Incorrect: Content in ()
div("Hello") # Use div["Hello"]
# ❌ Incorrect: Syntax not supported by htpy (or invalid Python)
# div[class_="foo"] # Attributes must be in ()
Datastar & Responses
from datastar_py import attribute_generator as data
from starlette.responses import HtpyResponse
from fastapi.responses import HTMLResponse
# ✅ Correct: Datastar in ()
button(data.on("click", "$count += 1"))["+"]
# ✅ Correct: HtpyResponse wrapper
def home() -> HtpyResponse:
return HtpyResponse(div["Hello"])
# ❌ Warning: Manual wrapping
def bad() -> HtpyResponse:
return HTMLResponse(content=str(div["Oops"])) # Suggests HtpyResponse
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file htpy_lsp-0.1.0.tar.gz.
File metadata
- Download URL: htpy_lsp-0.1.0.tar.gz
- Upload date:
- Size: 11.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Alpine Linux","version":"3.23.3","id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fbbc46f217ad42ea2fe91157e1d5c40032ed2ed10ad3f645390899873445dda2
|
|
| MD5 |
6dee668ffeb80be5dc32c7959ad9e7e8
|
|
| BLAKE2b-256 |
03ea48402ac0ee13e848b1bf4fda5c3cae842f82526de9223c5a47b60b39b9ae
|
File details
Details for the file htpy_lsp-0.1.0-py3-none-any.whl.
File metadata
- Download URL: htpy_lsp-0.1.0-py3-none-any.whl
- Upload date:
- Size: 7.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Alpine Linux","version":"3.23.3","id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fd8d51ce25b5c79e26af8ab8198c7eeb952bd5448ee840582000671eb19c675e
|
|
| MD5 |
f630f377af9249eeee8f1d2b8ef73f29
|
|
| BLAKE2b-256 |
42ae3f81073625a04b8654fdde058a8fac2b447b6c4a20ab5972a2cf49fc1161
|