line-protocol-parser 2.0.0


pip install line-protocol-parser

  Latest version

Released: Mar 25, 2026

Project Links

Meta
Author: Daniel Andersson
Requires Python: >=3.10

Classifiers

Development Status
  • 5 - Production/Stable

Environment
  • Console

Intended Audience
  • Developers
  • Education
  • Science/Research

Topic
  • Software Development :: Version Control :: Git

Natural Language
  • English

Operating System
  • POSIX :: Linux
  • MacOS
  • Microsoft :: Windows :: Windows 10

Programming Language
  • C
  • Python :: 3.10
  • Python :: 3.11
  • Python :: 3.12
  • Python :: 3.13
  • Python :: 3.14
  • Python :: Implementation :: CPython

Parse InfluxDB line protocol strings into Python dictionaries.

Example:

>>> from line_protocol_parser import parse_line
>>> data = parse_line('myMeas,someTag=ABC field1=3.14,field2="Hello, World!" 123')
>>> print(data)
{'measurement': 'myMeas',
'fields': {'field1': 3.14, 'field2': 'Hello, World!'},
'tags': {'someTag': 'ABC'},
'time': 123}

The InfluxDB line protocol is a text based format for writing points to InfluxDB. This project can read this format and convert line strings to Python dicitonaries.

The line protocol has the following format:

<measurement>[,<tag_key>=<tag_value>[,<tag_key>=<tag_value>]] <field_key>=<field_value>[,<field_key>=<field_value>] [<timestamp>]

and is documented here: InfluxDB line protocol.

This parser is aligned with archived InfluxDB v1.2 single-line parser semantics for standard text inputs. When an input point omits the timestamp, parse_line() returns None for time so omission remains distinct from an explicit 0 timestamp. Leading # comment lines, including lines with leading whitespace before #, are treated as valid input and parse_line() returns None for those lines as well. The parser also accepts the same top-level whitespace skipping before measurements, fields, and timestamps that the archived v1.2 parser tolerated, along with trailing spaces after the optional timestamp. The combined measurement/tag key is limited to 65535 bytes, matching the archived parser limit. Unsigned 123u field values are retained as a package extension even though they are not documented in the archived v1.2 reference.

The line_protocol_parser module only contains the parse_line function and the LineFormatError exception which is raised on failure.

Installation

Python 3.10 or newer is required.

From PyPI:

$ python3 -m pip install line-protocol-parser

or from source (make sure you have python3 -m pip install wheel setuptools first):

$ git clone https://github.com/Penlect/line-protocol-parser.git
$ cd line-protocol-parser
$ python3 setup.py bdist_wheel
$ python3 -m pip install ./dist/line-protocol-parser-*.whl

or from generated Debian package:

# Install build dependencies
$ sudo apt install python3-all python3-all-dev python3-setuptools dh-python
$ git clone https://github.com/Penlect/line-protocol-parser.git
$ cd line-protocol-parser
$ make deb
$ sudo apt install ./python3-line-protocol-parser_*.deb

Use Case 1: Read points from a file

Suppose you have a text file with influxDB measurement points, “my_influxDB_points.txt”:

# generated by sensor gateway
myMeasurement,someTag=A temperature=37.0 1570977942581909918
myMeasurement,someTag=A temperature=37.3 1570977942581910000
myMeasurement,someTag=A temperature=36.9 1570977942581912345
myMeasurement,someTag=A temperature=37.1 1570977942581923399
...

Then you can load each line into a dicitonary to be printed like this:

>>> from line_protocol_parser import parse_line
>>> with open('my_influxDB_points.txt', 'r') as f_obj:
...     for line in f_obj:
...         point = parse_line(line)
...         if point is not None:
...             print(point)

Use Case 2: InfluxDB subscriptions

InfluxDB subscriptions are documented here: InfluxDB Subscriptions.

InfluxDB subscriptions are local or remote endpoints to which all data written to InfluxDB is copied. Endpoint able to accept UDP, HTTP, or HTTPS connections can subscribe to InfluxDB and receive a copy of all data as it is written.

In this example we will do the following:

  1. Setup and run a InfluxDB container.

  2. Create a subscription.

  3. Create a Python server and register it as an endpoint.

  4. Use line_protocol_parser to read and print incoming data.

Step 1. Run the following commands to run a InfluxDB container and attach to the influx client.

$ docker run -d --network="host" --name inf influxdb
$ docker exec -it inf influx

Step 2. Create subscription. Run these commands in the influx client prompt.

> CREATE DATABASE mydb
> USE mydb
> CREATE SUBSCRIPTION "mysub" ON "mydb"."autogen" DESTINATIONS ALL 'http://localhost:9090'

Since we used –network=”host” we can use localhost from inside the container.

Step 3 & 4. Python server to receive InfluxDB data.

Create a python file server.py with the following content:

from pprint import pprint
from http.server import HTTPServer, BaseHTTPRequestHandler
from line_protocol_parser import parse_line

class PostHandler(BaseHTTPRequestHandler):

    def do_POST(self):
        content_length = int(self.headers['Content-Length'])
        post_data = self.rfile.read(content_length)
        point = parse_line(post_data)
        if point is not None:
            pprint(point)
        self.send_response(200)
        self.end_headers()

if __name__ == '__main__':
    server = HTTPServer(('localhost', 9090), PostHandler)
    print('Starting server, use <Ctrl-C> to stop')
    server.serve_forever()

Start the server:

$ python3 server.py
Starting server, use <Ctrl-C> to stop

Next, go back to your influx client and insert a data point:

> INSERT oven,room=kitchen temperature=225.0 1234567890

Head back to your Python server and watch the output:

$ python3 server.py
Starting server, use <Ctrl-C> to stop
{'fields': {'temperature': 225.0},
 'measurement': 'oven',
 'tags': {'room': 'kitchen'},
 'time': 1234567890}
172.17.0.2 - - [14/Oct/2019 21:02:57] "POST /write?consistency=&db=mydb&precision=ns&rp=autogen HTTP/1.1" 200 -

Pure C usage

If you are not interested in the Python wrapper you may find the pure-c files useful:

  • include/line_protocol_parser.h

  • src/line_protocol_parser.c

The C API keeps the original point-or-error contract. If you want to skip leading # comment lines in C code, filter those lines before calling LP_parse_line(). The C API accepts NUL-terminated strings only, while the Python wrapper rejects embedded NUL bytes instead of silently truncating input.

Example:

int main()
{
    const char *line = "measurement,tag=value field=\"Hello, world!\" 1570283407262541159";
    struct LP_Point *point;
    int status = 0;
    point = LP_parse_line(line, &status);
    if (point == NULL) {
        LP_DEBUG_PRINT("ERROR STATUS: %d\n", status);
    }
    // < Do something useful with point here >
    LP_free_point(point);
    return status;
}

Please see the comments in the source and header file for more information.

Examples from the Test Cases

The test cases are a good source of examples. Please see: tests/test_parse_line.py.

Changelog

The changelog is maintained in the debian directory, please check there: changelog.

Wheel compatibility matrix

Platform CPython 3.10 CPython 3.11 CPython 3.12 CPython 3.13 CPython 3.14
macosx_10_13_x86_64
macosx_10_15_x86_64
macosx_10_9_x86_64
macosx_11_0_arm64
manylinux2014_aarch64
manylinux2014_x86_64
manylinux_2_17_aarch64
manylinux_2_17_x86_64
manylinux_2_28_aarch64
manylinux_2_28_x86_64
musllinux_1_2_aarch64
musllinux_1_2_x86_64
win32
win_amd64

Files in release

line_protocol_parser-2.0.0-cp310-cp310-macosx_10_9_x86_64.whl (13.3KiB)
line_protocol_parser-2.0.0-cp310-cp310-macosx_11_0_arm64.whl (13.3KiB)
line_protocol_parser-2.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (34.3KiB)
line_protocol_parser-2.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (33.5KiB)
line_protocol_parser-2.0.0-cp310-cp310-musllinux_1_2_aarch64.whl (33.2KiB)
line_protocol_parser-2.0.0-cp310-cp310-musllinux_1_2_x86_64.whl (32.8KiB)
line_protocol_parser-2.0.0-cp310-cp310-win32.whl (15.1KiB)
line_protocol_parser-2.0.0-cp310-cp310-win_amd64.whl (15.2KiB)
line_protocol_parser-2.0.0-cp311-cp311-macosx_10_9_x86_64.whl (13.3KiB)
line_protocol_parser-2.0.0-cp311-cp311-macosx_11_0_arm64.whl (13.3KiB)
line_protocol_parser-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (34.1KiB)
line_protocol_parser-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (33.4KiB)
line_protocol_parser-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl (33.1KiB)
line_protocol_parser-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl (32.7KiB)
line_protocol_parser-2.0.0-cp311-cp311-win32.whl (15.1KiB)
line_protocol_parser-2.0.0-cp311-cp311-win_amd64.whl (15.2KiB)
line_protocol_parser-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl (13.3KiB)
line_protocol_parser-2.0.0-cp312-cp312-macosx_11_0_arm64.whl (13.3KiB)
line_protocol_parser-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (35.5KiB)
line_protocol_parser-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (34.6KiB)
line_protocol_parser-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl (34.3KiB)
line_protocol_parser-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl (33.8KiB)
line_protocol_parser-2.0.0-cp312-cp312-win32.whl (15.2KiB)
line_protocol_parser-2.0.0-cp312-cp312-win_amd64.whl (15.3KiB)
line_protocol_parser-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl (13.3KiB)
line_protocol_parser-2.0.0-cp313-cp313-macosx_11_0_arm64.whl (13.3KiB)
line_protocol_parser-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (35.6KiB)
line_protocol_parser-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (34.6KiB)
line_protocol_parser-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl (34.3KiB)
line_protocol_parser-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl (33.9KiB)
line_protocol_parser-2.0.0-cp313-cp313-win32.whl (15.1KiB)
line_protocol_parser-2.0.0-cp313-cp313-win_amd64.whl (15.3KiB)
line_protocol_parser-2.0.0-cp314-cp314-macosx_10_15_x86_64.whl (13.4KiB)
line_protocol_parser-2.0.0-cp314-cp314-macosx_11_0_arm64.whl (13.4KiB)
line_protocol_parser-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (35.6KiB)
line_protocol_parser-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (34.6KiB)
line_protocol_parser-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl (34.3KiB)
line_protocol_parser-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl (33.8KiB)
line_protocol_parser-2.0.0-cp314-cp314-win32.whl (15.5KiB)
line_protocol_parser-2.0.0-cp314-cp314-win_amd64.whl (15.6KiB)
line_protocol_parser-2.0.0.tar.gz (16.4KiB)
No dependencies