Metadata-Version: 2.4
Name: lynkio
Version: 1.2.9
Summary: Lynkio – Python only Realtime Server Framework: HTTP + WebSockets + Database in one engine. No dependencies.
Home-page: https://raw.githubusercontent.com/all-about-coding4/lynkio/main
Author: Alex Austin
Author-email: Alex Austin <alexaustinndubuisi@gmail.com>
License: MIT
Project-URL: Bug Reports, https://github.com/all-about-coding4/lynkio/issues
Project-URL: Source, https://raw.githubusercontent.com/all-about-coding4/lynkio/main
Project-URL: Documentation, https://raw.githubusercontent.com/all-about-coding4/lynkio/main/readme.md
Keywords: database,json,offline,lightweight,local-storage,ai,huggingface,cloud,aws,gdrive,dropbox,encryption,real-time,event-engine,http,websocket,asyncio,routing,middleware,pubsub,server,distributed-system
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.13
Classifier: Operating System :: OS Independent
Classifier: Topic :: Database
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.7
Description-Content-Type: text/markdown
Provides-Extra: huggingface
Requires-Dist: huggingface_hub~=0.16; extra == "huggingface"
Provides-Extra: aws
Requires-Dist: boto3~=1.26; extra == "aws"
Provides-Extra: gdrive
Requires-Dist: google-api-python-client~=2.70; extra == "gdrive"
Requires-Dist: google-auth-oauthlib~=1.0; extra == "gdrive"
Requires-Dist: google-auth-httplib2~=0.1; extra == "gdrive"
Provides-Extra: dropbox
Requires-Dist: dropbox~=11.36; extra == "dropbox"
Provides-Extra: encryption
Requires-Dist: cryptography~=39.0; extra == "encryption"
Provides-Extra: full
Requires-Dist: huggingface_hub~=0.16; extra == "full"
Requires-Dist: boto3~=1.26; extra == "full"
Requires-Dist: google-api-python-client~=2.70; extra == "full"
Requires-Dist: google-auth-oauthlib~=1.0; extra == "full"
Requires-Dist: google-auth-httplib2~=0.1; extra == "full"
Requires-Dist: dropbox~=11.36; extra == "full"
Requires-Dist: cryptography~=39.0; extra == "full"
Provides-Extra: dev
Requires-Dist: pytest~=7.0; extra == "dev"
Requires-Dist: pytest-cov~=4.0; extra == "dev"
Requires-Dist: black~=22.0; extra == "dev"
Requires-Dist: mypy~=0.990; extra == "dev"
Requires-Dist: flake8~=5.0; extra == "dev"
Dynamic: author
Dynamic: home-page
Dynamic: requires-python

## Lynkio – Pure‑Python Real‑Time Event Engine

Lynkio is a lightweight, high‑performance framework for building real‑time web applications with native HTTP routing, WebSockets (RFC6455), UDP datagram handling, and an AUTO mode that serves TCP (HTTP/WS) and UDP concurrently on the same port.
It runs on Python 3.10+ and has no external dependencies – only the standard library. Optional integration with soketDB provides automatic logging and distributed database queries, multipler listeners(port), javascript interceptor server.

## [Visit Lynkio Website](https://all-about-coding4.github.io/lynkio/)
---

## ✨ Features

```text
Category Capabilities
HTTP Path parameters (/user/<id>), method shortcuts (GET, POST, PUT, DELETE, PATCH), route groups, middleware, file streaming, redirects, JSON responses, template rendering, static serving
WebSocket Event‑driven messaging, fragmentation, binary frames, named binary events, automatic heartbeat (ping/pong), per‑client session storage
UDP + AUTO UDP datagram routing (JSON messages), same port for HTTP/WS + UDP, token‑based rate limiting
Rooms & Pub/Sub Join/leave rooms, batch emission, emit_to_room, get_room_clients
Background @app.task (startup coroutines), @app.schedule(interval) (cron‑like periodic tasks)
Database Built‑in soketDB integration: automatic logging of HTTP, WebSocket, runtime events. Distributed query API across any registered database
Middleware WebSocket and HTTP middleware chains; group‑level middleware
CORS One‑line CORS enable with allowed origins & credentials
Plugin system Extend Lynkio via app.use(plugin)
Client libraries Built‑in JavaScript client (served at /lynkio/client.js) + full async Python client
Pure Python Zero extra dependencies – only asyncio and the standard library
```
---

## 📦 Installation

```bash
pip install lynkio
```

If you need cloud backups for soketDB (Hugging Face, AWS S3, Google Drive, Dropbox), install with extras:

```bash
pip install lynkio[huggingface]   # or [aws], [gdrive], [dropbox], or [all]
```

---

## 🚀 Quick Start (HTTP + WebSocket + UDP)

```python
from lynkio import Lynk

app = Lynk(host="0.0.0.0", port=8765, protocol="AUTO", debug=True)

@app.get("/")
async def home(req):
    return "<h1>Hello Lynkio</h1>", "text/html"

@app.on("ping")
async def pong(client, data):
    await client.send("pong")

@app.udp("/sensor")
async def sensor(req):
    data = await req.json()
    print(f"UDP datagram: {data}")
    return {"status": "ok"}

if __name__ == "__main__":
    app.run()
```

Run with: python server.py
Now you have a single server accepting HTTP, WebSocket connections, and UDP datagrams on port 8765.

---

## 📡 HTTP Routing – Deep Dive

Path parameters and methods

```python
@app.get("/users/<user_id>")
async def get_user(req, user_id):
    return {"user_id": user_id}

@app.post("/items")
async def create_item(req):
    data = await req.json()
    return json_response({"id": 123, ...}, status=201)

@app.route("/posts/<post_id>", methods=["PUT", "DELETE"])
async def modify_post(req, post_id):
    if req.method == "PUT":
        ...
    elif req.method == "DELETE":
        ...
```

## Response helpers

```python
from lynkio import json_response, redirect, send_file, abort

@app.get("/old")
async def old_route(req):
    return redirect("/new", status=302)

@app.get("/report")
async def report(req):
    return send_file("docs/summary.pdf", as_attachment=True, cache_control="max-age=3600")

@app.get("/secret")
async def secret(req):
    if not req.headers.get("Authorization"):
        abort(403, "Forbidden")
    return "ok"
```

## Route groups & middleware

```python
api = app.group("/api/v1")

@api.get("/status")
async def api_status(req):
    return {"status": "running"}
```

## Static files & templates

```python
app.static("/static", "public")          # serve ./public

from lynkio import render_template
@app.get("/welcome")
async def welcome(req):
    return render_template("index.html", {"name": "Lynkio"}, template_dir="templates")
```

---

## 🔌 WebSocket Events & Real‑time Messaging

Event handlers

```python
@app.on("echo")
async def echo(client, data):
    await client.send(data)                     # send JSON back

@app.on("set_name")
async def set_name(client, data):
    client.session["name"] = data["name"]       # per‑client session
```

## Rooms (Pub/Sub)

```python
@app.on("join")
async def join_room(client, data):
    room = data["room"]
    app.join_room(client.id, room)
    await app.emit_to_room(room, "system", f"{client.id} joined")

@app.on("message")
async def chat_msg(client, data):
    room = client.session.get("room")
    if room:
        await app.emit_to_room(room, "chat", {
            "from": client.id,
            "text": data["text"]
        })
```

## Binary events (live streaming)

```python
# Send a named binary event to a client
await app.send_binary_event(client_id, "video_frame", frame_bytes)

# Receive named binary events
@app.on_binary_event("audio")
async def handle_audio(client, payload: bytes):
    print(f"Received audio chunk: {len(payload)} bytes")
    await app.send_binary_event(client.id, "audio_ack", b"OK")
```

## WebSocket middleware

```python
@app.middleware
async def auth_mw(client, event, data):
    if event == "admin" and not client.session.get("auth"):
        raise StopProcessing        # reject event
    return data                     # optionally mutate data
```

---

## 📡 UDP & AUTO Mode

Lynkio can run a UDP datagram server on the same port as HTTP/WebSocket (AUTO mode) or standalone.

Registering UDP routes

```python
@app.udp("/log")
async def udp_log(req):
    payload = await req.json()
    # payload = {"path": "/log", "data": {...}, "client_id": optional}
    print(payload)
    return {"status": "logged"}
```

Sending UDP datagrams from Python

```python
import socket, json
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
msg = json.dumps({"path": "/log", "data": {"temp": 22.5}, "client_id": "sensor1"})
sock.sendto(msg.encode(), ("127.0.0.1", 8765))
```

Rate limiting for UDP is based on client_id (or IP:port if not provided). Set rate_limit in Lynk().

---

## 🧠 Background Tasks & Scheduler

One‑time background task (starts with server)

```python
@app.task
async def cache_warmer():
    while app._running:
        await asyncio.sleep(60)
        # refresh cache
```

## Periodic scheduled tasks

```python
@app.schedule(interval=10.0)   # seconds
async def broadcast_time():
    await app.emit("server_time", {"now": time.time()})
```

Scheduled tasks run in the background and are automatically cancelled during graceful shutdown.

---

## 🗄️ Database & Automatic Logging (soketDB)

Lynkio ships with soketDB – a file‑based database with backup, caching, and async support. Enable it to automatically log HTTP requests, WebSocket messages, and runtime events.

Enable database logging

```python
app = Lynk(enable_database=True)
db = app.create_database(
    name="myapp_logs",
    create_log_table=True,   # creates http_logs, wss_logs, runtime_logs
    auto_sync_log=True       # auto‑insert every request/event
)
```

## Log tables

· http_logs – method, path, status, client_ip, user_agent, response_time, request_id
· wss_logs – direction, event, data size, opcode, client_id
· runtime_logs – level, message, source

## Manual logging

```python
await app.add_log("runtime", level="INFO", message="Custom event", source="auth")
```

## Distributed queries across any registered database

```python
# Inside any async handler
rows = await app.query_database(
    "myapp_logs",
    "SELECT method, path FROM http_logs WHERE status_code = $1",
    (200,)
)
for row in rows:
    print(row)
```

---

## 🔧 Middleware, CORS & Plugin System

HTTP middleware

```python
async def my_http_middleware(req):
    print(f"{req.method} {req.path}")
    # return None to continue, or return bytes to short‑circuit
    return None

app._http_middleware.append(my_http_middleware)
```

## CORS (one line)

```python
app.enable_cors(allowed_origins=["https://example.com"], allow_credentials=True)
```

## Plugin system

```python
def metrics_plugin(app):
    @app.get("/metrics")
    async def metrics(req):
        return {"active_clients": len(app._clients)}

app.use(metrics_plugin)
```

---

## 🌐 Clients

Built‑in JavaScript client

Set serve_client=True in Lynk() – the client is served at /lynkio/client.js:

```html
<script src="/lynkio/client.js"></script>
<script>
  const client = new LynkClient("ws://localhost:8765");
  client.on("chat", msg => console.log(msg));
  client.connect().then(() => {
    client.joinRoom("general");
    client.emit("chat", { room: "general", text: "hi" });
    client.sendBinaryEvent("image", new Uint8Array([1,2,3]));
  });
</script>
```

## Multiple port listeners

```python

#!/usr/bin/env python3
"""
Lynkio Test Server with Listeners
- Public:  HTTP + WebSocket on port 8080
- Admin:   HTTP only on port 8081 (with API key)
- Internal: UDP on port 9091 (telemetry)
Serves JavaScript client at /lynkio/client.js
"""

import asyncio
import time
import json
from lynkio import Lynk, Listener, json_response

# ----------------------------------------------------------------------
# Listeners (no SSL)
# ----------------------------------------------------------------------
listeners = [
    Listener("public", port=8080, protocol="TCP", max_connections=1000),
    Listener("admin", port=8081, protocol="TCP", max_connections=10),
    Listener("internal", port=9091, protocol="UDP", rate_limit=100),
]

app = Lynk(
    listeners=listeners,
    debug=True,
    serve_client=True,          # Serves /lynkio/client.js
)

# ----------------------------------------------------------------------
# Middleware
# ----------------------------------------------------------------------
@app.http_middleware(listener=None)
async def log_request(req):
    print(f"[{req.listener}] {req.method} {req.path}")
    return None

ADMIN_KEY = "admin123"

@app.http_middleware(listener="admin")
async def admin_auth(req):
    if req.headers.get("X-API-Key") != ADMIN_KEY:
        from lynkio import http_response
        return http_response(401, "text/plain", "Unauthorized")
    return None

# ----------------------------------------------------------------------
# Public routes
# ----------------------------------------------------------------------
@app.get("/", listener="public")
async def index(req):
    return HTML_PAGE, "text/html"

@app.get("/health", listener="public")
async def health(req):
    return {"status": "ok", "timestamp": time.time(), "listener": req.listener}

@app.get("/api/data", listener="public")
async def api_data(req):
    return {"data": [1, 2, 3], "listener": req.listener}

@app.post("/echo", listener="public")
async def echo(req):
    body = await req.json()
    return json_response(body)

# ----------------------------------------------------------------------
# Admin routes
# ----------------------------------------------------------------------
@app.get("/admin/stats", listener="admin")
async def admin_stats(req):
    return {
        "connections": app.connection_count(),
        "rooms": len(app._rooms),
        "listener": req.listener
    }

# ----------------------------------------------------------------------
# WebSocket events
# ----------------------------------------------------------------------
@app.on("join")
async def ws_join(client, data):
    room = data.get("room", "lobby")
    app.join_room(client.id, room)
    await app.emit_to_room(room, "system", f"Client joined", exclude=client.id)
    await client.send(json.dumps({"event": "connected", "data": {"room": room}}))

@app.on("chat")
async def ws_chat(client, data):
    room = data.get("room")
    text = data.get("text")
    if room and text and app.is_client_in_room(client.id, room):
        await app.emit_to_room(room, "chat", {
            "from": client.id,
            "text": text,
            "timestamp": time.time()
        }, exclude=client.id)

@app.on_binary_event("binary_ping")
async def ws_binary_ping(client, payload):
    print(f"Binary ping from {client.id}: {len(payload)} bytes")
    await client.send_binary_event("binary_echo", payload[:100] + b"...")

# ----------------------------------------------------------------------
# UDP endpoint
# ----------------------------------------------------------------------
@app.udp("/telemetry", listener="internal")
async def udp_telemetry(req):
    payload = await req.json()
    print(f"UDP telemetry: {payload}")
    return {"status": "ok", "received": payload}

# ----------------------------------------------------------------------
# Background task
# ----------------------------------------------------------------------
@app.task
async def stats_printer():
    while app._running:
        await asyncio.sleep(30)
        print(f"Stats: {app.connection_count()} connections, {len(app._rooms)} rooms")

# ----------------------------------------------------------------------
# HTML page
# ----------------------------------------------------------------------
HTML_PAGE = """
<!DOCTYPE html>
<html>
<head>
    <title>Lynkio Test</title>
    <style>
        body { font-family: Arial; margin: 40px; max-width: 800px; }
        .status { padding: 10px; margin: 10px 0; border-radius: 4px; font-weight: bold; }
        .connected { background: #d4edda; color: #155724; }
        .disconnected { background: #f8d7da; color: #721c24; }
        button { padding: 8px 16px; margin: 5px; cursor: pointer; background: #007bff; color: white; border: none; border-radius: 4px; }
        button:hover { background: #0056b3; }
        button.danger { background: #dc3545; }
        button.danger:hover { background: #c82333; }
        input { padding: 8px; margin: 5px; border: 1px solid #ccc; border-radius: 4px; }
        #messages { border: 1px solid #ddd; padding: 10px; height: 250px; overflow-y: scroll; margin: 10px 0; background: #fafafa; border-radius: 4px; }
        .msg { padding: 4px 8px; margin: 2px 0; border-radius: 4px; }
        .msg-system { background: #fff3cd; color: #856404; }
        .msg-chat { background: #d1ecf1; color: #0c5460; }
        .msg-you { background: #d4edda; color: #155724; }
        .msg-binary { background: #e2e3e5; color: #383d41; }
    </style>
</head>
<body>
    <h1>🚀 Lynkio Test (Listeners)</h1>
    <p>Public: port 8080 (HTTP/WS) | Admin: port 8081 | UDP: port 9091</p>
    <div id="status" class="status disconnected">🔴 Disconnected</div>
    
    <div>
        <button onclick="connect()">🔗 Connect</button>
        <button class="danger" onclick="disconnect()">🔌 Disconnect</button>
        <button onclick="joinRoom()">📥 Join Room</button>
        <button onclick="sendMessage()">💬 Send</button>
        <button onclick="sendBinary()">📦 Binary</button>
    </div>
    
    <div>
        <input id="roomInput" placeholder="Room name" value="lobby">
        <input id="messageInput" placeholder="Message" value="Hello!">
    </div>
    
    <h3>📨 Messages</h3>
    <div id="messages">
        <div class="msg msg-system">Ready. Click "Connect".</div>
    </div>
    
    <script src="/lynkio/client.js"></script>
    <script>
        let client = null;
        let room = 'lobby';
        
        function log(msg, type = '') {
            const div = document.getElementById('messages');
            const p = document.createElement('div');
            p.className = 'msg ' + type;
            p.textContent = '[' + new Date().toLocaleTimeString() + '] ' + msg;
            div.appendChild(p);
            div.scrollTop = div.scrollHeight;
        }
        
        async function connect() {
            try {
                if (client) { log('Already connected', 'msg-system'); return; }
                client = new LynkClient('ws://localhost:8080');
                
                client.on('connected', (d) => log('✅ Connected: ' + JSON.stringify(d), 'msg-system'));
                client.on('chat', (d) => log('💬 ' + d.from + ': ' + d.text, 'msg-chat'));
                client.on('system', (d) => log('📢 ' + d, 'msg-system'));
                client.onBinary('binary_echo', (payload) => {
                    log('📦 Binary echo: ' + payload.byteLength + ' bytes', 'msg-binary');
                });
                
                await client.connect();
                document.getElementById('status').className = 'status connected';
                document.getElementById('status').textContent = '🟢 Connected';
                log('Connected to server!', 'msg-system');
            } catch (err) {
                log('❌ Connection failed: ' + err.message, 'msg-system');
                client = null;
            }
        }
        
        function disconnect() {
            if (client) {
                client.close();
                client = null;
                document.getElementById('status').className = 'status disconnected';
                document.getElementById('status').textContent = '🔴 Disconnected';
                log('Disconnected', 'msg-system');
            }
        }
        
        function joinRoom() {
            if (!client) { log('⚠️ Connect first!'); return; }
            room = document.getElementById('roomInput').value || 'lobby';
            client.joinRoom(room);
            log('Joined room: ' + room, 'msg-system');
        }
        
        function sendMessage() {
            if (!client) { log('⚠️ Connect first!'); return; }
            const msg = document.getElementById('messageInput').value || 'Hello!';
            client.emit('chat', { room: room, text: msg });
            log('You: ' + msg, 'msg-you');
        }
        
        function sendBinary() {
            if (!client) { log('⚠️ Connect first!'); return; }
            const data = new Uint8Array(1024);
            for (let i = 0; i < data.length; i++) data[i] = i % 256;
            client.sendBinaryEvent('binary_ping', data);
            log('Sent binary ping: 1KB', 'msg-binary');
        }
        
        window.onload = function() {
            log('🚀 Page loaded. Click Connect.');
        };
    </script>
</body>
</html>
"""

# ----------------------------------------------------------------------
# Run
# ----------------------------------------------------------------------
if __name__ == "__main__":
    print("=" * 50)
    print("🚀 Lynkio Test Server with Listeners")
    print("=" * 50)
    print("🌐 Public  (HTTP/WS): http://localhost:8080")
    print("🔒 Admin   (HTTP):   http://localhost:8081 (X-API-Key: admin123)")
    print("📡 UDP     (port):   localhost:9091 (path: /telemetry)")
    print("📦 JS Client served at /lynkio/client.js")
    print("=" * 50)
    app.run()
```

## Full Python client

```python
from lynkio import LynkClient

async def demo():
    client = LynkClient("localhost", 8765)
    await client.ws.connect()
    client.on("greeting", lambda d: print(d))
    await client.ws.emit("ping", "hello")

    # HTTP client
    status, headers, body = await client.http.get("/api/status")
    print(status, body)

    # UDP client
    resp = await client.udp.send(b'{"path":"/ping"}')
    print(resp)

asyncio.run(demo())
```

## Javascript server/interceptor

```python
from lynkio import Lynk, render_template

app = Lynk(
    port= 9090,
    serve_client = True,
    debug = True,
    protocol= "AUTO",
)

@app.get("/")
async def test(reg):
    return render_template("test.html")

if __name__ == "__main__":
    print("server running")
    app.run()

#templates/test.html
```
```html
<button id="btn" style="width: 80px; height: 100px;">Click Me</button>
<div id="output">fetch output</div>
<script src="/lynkio/client.js"></script>

<script>
    const client = new LynkClient("ws://localhost:9090");

    console.log(client);

    if (client) {

        client.connect();

        const server = client.server();
        console.log(server.object);

        server.get("/happy", {}, async (req) => {

            console.log("server running");

            return new Response(
                JSON.stringify({
                    hello: "hello testing server"
                }),
                {
                    status: 200,
                    headers: {
                        "Content-Type": "application/json"
                    }
                }
            );
        });


        document.getElementById("btn").addEventListener("click", async () => {

                console.log("clicked");

                //window.location.href = "/happy";
                const res = await fetch("/happy");

                if(res.ok){
                    const data = await res.json();

                    document.getElementById("output").textContent = data.hello;

                    console.log(data);
                }



        });

    } else {

        console.log("lynkio");

    }
</script>
```
## Server can be created/design for multiple listeners/port you just have to make it fit your idea.

---

## 🧩 Complete Chat Server Example

```python
import asyncio, time, os
from lynkio import Lynk, render_template

app = Lynk(host="0.0.0.0", port=8765, protocol="AUTO", debug=True,
           enable_database=True)
app.create_database("chat_logs", create_log_table=True, auto_sync_log=True)
app.enable_cors()

@app.get("/")
async def index(req):
    return render_template("chat.html", {"title": "Lynk Chat"})

app.static("/static", "static")

@app.on("join")
async def join(client, data):
    room = data.get("room", "lobby")
    name = data.get("name", "Anonymous")
    client.session["name"] = name
    client.session["room"] = room
    app.join_room(client.id, room)
    await app.emit_to_room(room, "system", f"{name} joined")

@app.on("message")
async def message(client, data):
    room = client.session.get("room")
    if room:
        await app.emit_to_room(room, "chat", {
            "from": client.session.get("name"),
            "text": data["text"]
        })

@app.task
async def stats_printer():
    while app._running:
        await asyncio.sleep(10)
        print(f"Clients: {len(app._clients)}")

if __name__ == "__main__":
    os.makedirs("templates", exist_ok=True)
    app.run()
```

---


## 📖 API Reference (Summary)

```text
## Lynk(**options)

Parameter Default Description
host "0.0.0.0" Bind address
port 8765 Port
protocol "TCP" "TCP", "UDP", or "AUTO"
max_payload_size 256*1024 Max WebSocket frame / UDP datagram
max_message_size 1024*1024 Max fragmented WebSocket message
max_body_size 1024*1024 Max HTTP body
rate_limit None Messages/sec per client/UDP token
enable_database False Enable soketDB logging
serve_client False Serve built‑in JS client

## Core methods

· HTTP: @app.get, .post, .put, .delete, .patch, .route, .static, .group
· WebSocket: @app.on(event), @app.on_binary, @app.on_binary_event(name), @app.middleware
· UDP: @app.udp(path)
· Rooms: join_room(), leave_room(), emit_to_room(), get_room_clients()
· Broadcast: emit(event, data, client_id=None)
· Background: @app.task, @app.schedule(interval)
· Database: create_database(), query_database(), add_log()
· Misc: enable_cors(), use(plugin), fetch(url, ...)

## Request object

· req.method, req.path, req.headers, req.body, req.client_ip
· await req.json(), await req.form(), req.query_params, req.cookies

## Response helpers
· json_response(data, status), redirect(location, status), abort(code, message)
· send_file(filepath, as_attachment=False, cache_control=None, ...)
· render_template(template_name, context, template_dir)

## Javascript client
. HTTP/INTERCEPTOR/SERVER: .get, .post, .delete, .put, .route
. WebSocket: .connect, .on, .emit, .onBinary, .onBinaryEvent, .sendBinary, .sendBinaryEvent, .joinRoom, .leaveRoom, .close
. Session: .setSession,
. UDP: .sendUdp, 
.Background: .createTask, .scheduleTask, .clearTask, 
. Database: .createDataset,
. Server: .server, eg(.server.get())
---
```

## 🖥️ CLI Usage

```bash
python -m lynkio myapp:app --host 0.0.0.0 --port 8765 --protocol AUTO --debug
```

The format is module:app where app is your Lynk instance.

---

## 🤝 Contributing

```text
1. Fork the repository
2. Create a feature branch (git checkout -b feature/amazing)
3. Commit your changes
4. Push to the branch
5. Open a Pull Request

---
```

## Lynkio Versions

```python
pip install lynkio==1.2.9

Avaible Versions

 v1.1.4 (bugs)
 
 v1.1.5
 
 v1.1.6 (stable)
 
 v1.1.7
 
 v1.1.8
 
 v1.1.9
 
 v1.2.0
 
 v1.2.1
 
 v1.2.3
 
 v1.2.4
 
 v1.2.5
 
 v1.2.6
 
 v1.2.7 

 v1.2.8

 v1.2.9 (new)

```

## 📄 License

MIT License – see LICENSE for details.

---

## 👤 Built by Alex Austin

Lynkio is a modern, dependency‑free real‑time framework for Python developers who value simplicity and performance.
