Metadata-Version: 2.5
Name: kymoscope
Version: 0.6.1
Summary: Stream live, end-to-end encrypted telemetry to Kymoscope
Project-URL: Homepage, https://kymoscope.com
Project-URL: Documentation, https://kymoscope.com/docs/live
License: # Kymoscope SDK License Agreement
        
        Copyright © 2026 Kymoscope. All rights reserved.
        
        This is proprietary software. It is licensed, not sold. By installing, copying
        or using the Kymoscope SDK (the "Software") you agree to these terms. If you do not
        agree, do not use the Software.
        
        > Template notice for the owner: this agreement was drafted as a starting point.
        > Have it reviewed by a lawyer for your jurisdiction and fill in the legal
        > entity, governing law and contact details before relying on it.
        
        ## 1. Licenses
        
        **1.1 Evaluation.** You may use the Software without a license key to evaluate
        it and to develop your integration. Unlicensed use displays a "Powered by
        Kymoscope" attribution in the workspace.
        
        **1.2 Production.** Using the Software in a product, service or internal tool
        made available to anyone other than your own developers ("Production Use")
        requires a valid license key issued by Kymoscope for each domain the Software is
        served from, under an order or agreement with Kymoscope.
        
        **1.3 Scope.** A license key is personal to the licensee named in it, for the
        domains listed in it and until its expiry date.
        
        ## 2. Restrictions
        
        You must not, and must not allow others to:
        
        1. make the Software available in Production Use without a valid license key
           for that domain;
        2. remove, hide, obscure or alter the attribution shown by unlicensed use, or
           the copyright notices in the Software;
        3. circumvent, disable or modify the license check, or create, alter or share
           license keys;
        4. copy, sell, sublicense, distribute or publish the Software, or offer it as a
           standalone component library or SDK, except as embedded in your own product
           as permitted above;
        5. reverse engineer, decompile or disassemble the Software, except to the
           extent applicable law expressly permits it despite this restriction;
        6. use the Software to build a competing embeddable analytics or charting
           product.
        
        ## 3. Kymoscope services
        
        Live-stream relaying, watch tickets and other hosted services are provided
        under your Kymoscope account terms and may be rate limited or suspended for abuse.
        
        ## 4. Ownership
        
        Kymoscope and its licensors own all rights in the Software. No rights are granted
        except those expressly stated here.
        
        ## 5. Termination
        
        This license ends automatically if you breach it. On termination you must stop
        using the Software and delete all copies.
        
        ## 6. No warranty and limitation of liability
        
        The Software is provided "as is", without warranties of any kind. To the
        maximum extent permitted by law, Kymoscope is not liable for any indirect,
        incidental or consequential damages, and its total liability is limited to the
        fees you paid for the Software in the twelve months before the claim.
        
        ## 7. Contact
        
        For license keys and commercial terms, contact Kymoscope.
License-File: LICENSE.md
Requires-Python: >=3.9
Requires-Dist: cryptography>=41
Requires-Dist: requests>=2.28
Requires-Dist: websocket-client>=1.6
Provides-Extra: test
Requires-Dist: pytest>=7; extra == 'test'
Provides-Extra: viewer
Requires-Dist: msgpack>=1.0; extra == 'viewer'
Description-Content-Type: text/markdown

# kymoscope

Stream live, end-to-end encrypted telemetry to [Kymoscope](https://kymoscope.com) from Python.

Requires Python 3.9 or later.

```bash
pip install kymoscope
```

## Example

```python
import math, time
from kymoscope import LiveStream

API_KEY = "kymoscope_..."   # Account -> API & real-time streaming, or a project's API key
# state_path keeps this sender's identity, so a restart needs no new approval
with LiveStream(API_KEY, "Rig A", state_path="kymoscope-state.json") as stream:
    print("stream id:", stream.stream_id)
    while True:
        t = time.time()           # absolute (Unix seconds)
        stream.send([{"t": t, "signals": [
            {"name": "speed", "unit": "m/s", "value": 50 + 10 * math.sin(t)},
        ]}])
        time.sleep(1 / 60)
```

In an end-to-end encrypted project, the first run waits until a project member's browser
approves the sender; after that it publishes on its own.
`LiveStream.project_key` gives a collector the current project key so it can seal keys of its own (day history);
never log or persist it.

## Keep every sample when the connection drops

```python
with LiveStream(API_KEY, "Rig A", state_path="kymoscope-state.json",
                buffer_path="kymoscope-buffer", buffer_max_mb=2048) as stream:
    ...
```

With `buffer_path` (a folder), the stream always sends, also with nobody watching, so a cloud
recording keeps everything. While the relay is unreachable it keeps the encrypted messages on disk, then sends
them in order when the relay is back, with the bandwidth live data leaves spare. Viewers see that data in the
recording, not in the live view. A crash can send a few messages twice.
`buffer_max_mb` caps the disk used; when it is full, new samples are dropped and counted in `stream.buffer_dropped`.
`buffer_min_free_mb` (default 0, off) also stops buffering when the disk has less free space than that.
Since 0.3.0 the stream sends the compact format by default (4–8× less data); `block_format=False` sends the
classic format for viewers on SDK versions before 0.2.0 or self-hosted relays before 0.2.0 (`buffer_path` always
uses the compact one). With `buffer_path`, send absolute times (`time.time()`), so data sent after a restart lands
in the right place in the recording.

## Cameras

A camera is a channel of a stream: whoever opens the stream sees its cameras. It needs
[ffmpeg](https://ffmpeg.org) on PATH.

```python
with LiveStream(API_KEY, "Rig A", state_path="kymoscope-state.json") as stream:
    stream.add_camera("Front", "video=Integrated Camera", input_format="dshow")   # a webcam on Windows
    stream.add_camera("Bay", "/dev/video0", input_format="v4l2", size="1280x720") # a webcam on Linux
    stream.add_camera("Door", "rtsp://user:pass@10.0.0.7/stream1", copy=True)     # an H.264 IP camera, as is
    stream.add_camera("Test", "testsrc=size=1280x720:rate=30", input_format="lavfi")  # a test pattern
    while True:
        stream.send(...)    # keep sending (or call stream.tick()): the cameras heartbeat with the stream
```

ffmpeg re-encodes to H.264 (`fps` 30, `kbps` 2000 by default, a keyframe every 2 s) unless `copy=True`.
Video goes out only while someone watches the camera; a new viewer starts at the next keyframe.
Use the same API key for the cameras as for their stream; in an encrypted project they need no extra approval.

`low=True` also publishes a 360p copy (640x360 for 16:9, 15 fps, 400 kbit/s, a keyframe every 2 s) as the camera's
low layer. Viewers play it in small panels and camera walls, and switch to full quality when a camera is enlarged;
it also suits viewers on slow links. It goes out only while someone watches it, isn't recorded, and doesn't count
as a camera of your plan.

```python
stream.add_camera("Bay", "/dev/video0", input_format="v4l2", low=True)
stream.add_camera("Door", "rtsp://user:pass@10.0.0.7/stream1", copy=True, low=True)
```

One ffmpeg writes both layers. With `copy=True` the full layer is still forwarded as is; only the low layer is decoded
and encoded, which costs the CPU of one 360p libx264 encode (plus decoding the camera's stream). On Windows a
second ffmpeg encodes the low layer and opens the input again: fine for an IP camera or a file, but a webcam
(`dshow`) can't be opened twice, so `low=True` with `input_format="dshow"` raises an error; run that sender on
Linux or macOS, or use an IP camera.

Credentials in a camera URL (`rtsp://user:pass@host/...`) are passed to ffmpeg on its command line, so other users
of the same machine can read them in the process list. Kymoscope hides them (`rtsp://***@host`) in everything it
prints, ffmpeg's own error lines included. Give the sender a camera account that can only view the stream, and run
it on a machine (or under an account) nobody else uses.

The headless viewer (`kymoscope.viewer`) needs msgpack: `pip install 'kymoscope[viewer]'`.

Full documentation: https://kymoscope.com/docs/live
