# TYTX API Reference Complete API reference for Python and JavaScript implementations. --- ## Python API ### Core Functions #### `to_tytx(value, transport=None)` Encode a Python value to TYTX format. ```python from genro_tytx import to_tytx from decimal import Decimal from datetime import date # Dict with typed values → JSON string with ::JS suffix to_tytx({"price": Decimal("100.50")}) # '{"price": "100.50::N"}::JS' # Scalar typed value → JSON string to_tytx(date(2025, 1, 15)) # '"2025-01-15::D"' # Plain dict (no typed values) → plain JSON to_tytx({"name": "test", "count": 42}) # '{"name": "test", "count": 42}' ``` **Parameters:** | Parameter | Type | Default | Description | |-------------|--------------|------------|-----------------------------------------------------------------| | `value` | Any | required | Value to encode | | `transport` | str \| None | `None` | Transport format: `None`/`"json"`, `"xml"`, `"msgpack"` | | `raw` | bool | `False` | If `True`, output raw format without TYTX type suffixes | | `qs` | bool | `False` | If `True`, output as query string format (flat dict or list) | **Returns:** `str` for JSON/XML/QS, `bytes` for MessagePack **Query String Example:** ```python from genro_tytx import to_tytx from datetime import date # Flat dict → QS format to_tytx({"alfa": 33, "date": date(2025, 1, 15)}, qs=True) # 'alfa=33::L&date=2025-01-15::D::QS' # List → QS format to_tytx(["alfa", "beta", "gamma"], qs=True) # 'alfa&beta&gamma::QS' ``` --- #### `from_tytx(data, transport=None)` Decode TYTX data to Python values. ```python from genro_tytx import from_tytx # JSON with typed values from_tytx('{"price": "100.50::N"}::JS') # {"price": Decimal("100.50")} # Scalar typed value from_tytx('"2025-01-15::D"') # date(2025, 1, 15) # Plain JSON from_tytx('{"name": "test"}') # {"name": "test"} ``` **Parameters:** | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `data` | str \| bytes | required | Data to decode | | `transport` | str \| None | `None` | Transport format (auto-detected if `None`) | **Returns:** Decoded Python value with hydrated types --- ### HTTP Functions #### `asgi_data(scope, receive)` (async) Decode TYTX data from an ASGI request. ```python from fastapi import FastAPI, Request from genro_tytx import asgi_data app = FastAPI() @app.post("/api/order") async def create_order(request: Request): data = await asgi_data(request.scope, request.receive) body = data["body"] # Request body (dict) query = data["query"] # Query parameters (dict) headers = data["headers"] # HTTP headers (dict) cookies = data["cookies"] # Cookies (dict) ``` **Parameters:** | Parameter | Type | Description | |-----------|------|-------------| | `scope` | dict | ASGI scope dict | | `receive` | Callable | ASGI receive callable | **Returns:** `dict` with keys `query`, `headers`, `cookies`, `body` --- #### `wsgi_data(environ)` Decode TYTX data from a WSGI request. ```python from flask import Flask, request from genro_tytx import wsgi_data app = Flask(__name__) @app.route("/api/order", methods=["POST"]) def create_order(): data = wsgi_data(request.environ) body = data["body"] query = data["query"] ``` **Parameters:** | Parameter | Type | Description | |-----------|------|-------------| | `environ` | dict | WSGI environ dict | **Returns:** `dict` with keys `query`, `headers`, `cookies`, `body` --- ### XML Functions #### `to_xml(value)` Encode a dict to XML with TYTX type suffixes. ```python from genro_tytx import to_xml from decimal import Decimal data = { "order": { "attrs": {"id": 123}, "value": { "total": {"attrs": {}, "value": Decimal("100.50")} } } } to_xml(data) # '100.50::N' ``` **Input Structure:** ```python { "tag_name": { "attrs": {"attr1": value1, ...}, # Attributes "value": ... # Scalar, dict of children, list, or None } } ``` --- #### `from_xml(data)` Decode XML with TYTX type suffixes. ```python from genro_tytx import from_xml from_xml('100.50::N') # { # "order": { # "attrs": {"id": 123}, # "value": {"total": {"attrs": {}, "value": Decimal("100.50")}} # } # } ``` --- ### MessagePack Functions #### `to_msgpack(value)` Encode a value to MessagePack binary format. ```python from genro_tytx import to_msgpack from decimal import Decimal packed = to_msgpack({"price": Decimal("100.50")}) # bytes ``` > Requires `pip install genro-tytx[msgpack]` --- #### `from_msgpack(data)` Decode MessagePack binary data. ```python from genro_tytx import from_msgpack unpacked = from_msgpack(packed) # {"price": Decimal("100.50")} ``` --- ## JavaScript API ### Core Functions #### `toTytx(value, transport='json')` Encode a JavaScript value to TYTX format. ```javascript import { toTytx } from 'genro-tytx'; import Big from 'big.js'; // Object with typed values toTytx({ price: new Big('100.50') }); // '{"price":"100.50::N"}::JS' // Scalar typed value toTytx(new Date(Date.UTC(2025, 0, 15))); // '"2025-01-15::D"' ``` **Parameters:** | Parameter | Type | Default | Description | |---------------|---------|------------|----------------------------------------------------------| | `value` | any | required | Value to encode | | `transport` | string | `null` | Transport: `null`/`'json'`, `'xml'`, `'msgpack'` | | `options.raw` | boolean | `false` | If `true`, output raw format without TYTX type suffixes | | `options.qs` | boolean | `false` | If `true`, output as query string format | **Returns:** `string` for JSON/XML/QS, `Uint8Array` for MessagePack **Query String Example:** ```javascript import { toTytx } from 'genro-tytx'; // Flat object → QS format toTytx({alfa: 33, date: new Date(Date.UTC(2025, 0, 15))}, null, {qs: true}); // 'alfa=33::L&date=2025-01-15::D::QS' // Array → QS format toTytx(['alfa', 'beta', 'gamma'], null, {qs: true}); // 'alfa&beta&gamma::QS' ``` --- #### `fromTytx(data, transport='json')` Decode TYTX data to JavaScript values. ```javascript import { fromTytx } from 'genro-tytx'; // JSON with typed values fromTytx('{"price":"100.50::N"}::JS'); // { price: Decimal("100.50") } // Scalar typed value fromTytx('"2025-01-15::D"'); // Date object ``` --- ### HTTP Functions #### `fetchTytx(url, options)` Fetch wrapper with automatic TYTX encoding/decoding. ```javascript import { fetchTytx } from 'genro-tytx'; import Big from 'big.js'; const result = await fetchTytx('/api/order', { method: 'POST', body: { price: new Big('100.50'), date: new Date(Date.UTC(2025, 0, 15)), }, headers: { 'Authorization': 'Bearer token', }, }); // result is already decoded console.log(result.total.toFixed(2)); ``` **Options:** | Option | Type | Default | Description | |--------|------|---------|-------------| | `body` | any | - | Request body (will be encoded) | | `transport` | string | `'json'` | Transport format | | `method` | string | `'GET'` or `'POST'` | HTTP method (auto-detected if body present) | | `headers` | object | `{}` | Additional headers | **Returns:** `Promise` - Decoded response body --- #### `getTransport(contentType)` Detect transport format from Content-Type header. ```javascript import { getTransport } from 'genro-tytx'; getTransport('application/json'); // 'json' getTransport('application/vnd.tytx+json'); // 'json' getTransport('application/xml'); // 'xml' getTransport('application/msgpack'); // 'msgpack' ``` --- ## Type Suffixes | Suffix | Type | Python | JavaScript | Example | |--------|------|--------|------------|---------| | `N` | Decimal | `Decimal` | `Decimal` (big.js) | `"99.99::N"` | | `D` | Date | `date` | `Date` (midnight UTC) | `"2025-01-15::D"` | | `DHZ` | DateTime | `datetime` | `Date` | `"2025-01-15T10:30:00.000Z::DHZ"` | | `H` | Time | `time` | `Date` (epoch) | `"10:30:00.000::H"` | | `L` | Integer | `int` | `number` | `"42::L"` | | `R` | Float | `float` | `number` | `"3.14::R"` | | `B` | Boolean | `bool` | `boolean` | `"true::B"` | | `T` | Text | `str` | `string` | `"hello::T"` | | `JS` | JSON Structure | `dict`/`list` | `object`/`array` | `{"a":1}::JS` | | `QS` | Query String | `dict`/`list` | `object`/`array` | `a=1::L&b=2::L::QS` | **Notes:** - `L`, `R`, `B`, `T` are mainly used for XML (where all values are strings) - In JSON, native types pass through unchanged - `DH` is deprecated, use `DHZ` instead (still accepted on decode) - `QS` is used for URL query string encoding via `to_tytx(..., qs=True)` --- ## Constants ### JavaScript: `CONTENT_TYPES` ```javascript import { CONTENT_TYPES } from 'genro-tytx'; CONTENT_TYPES.json; // 'application/json' CONTENT_TYPES.xml; // 'application/xml' CONTENT_TYPES.msgpack; // 'application/msgpack' ``` --- ## Framework Examples ### FastAPI ```python from fastapi import FastAPI, Request, Response from genro_tytx import asgi_data, to_tytx from decimal import Decimal app = FastAPI() @app.post("/api/order") async def create_order(request: Request): data = await asgi_data(request.scope, request.receive) body = data["body"] result = {"total": body["price"] * body["quantity"]} return Response( content=to_tytx(result), media_type="application/vnd.tytx+json" ) ``` ### Flask ```python from flask import Flask, request from genro_tytx import wsgi_data, to_tytx app = Flask(__name__) @app.route("/api/order", methods=["POST"]) def create_order(): data = wsgi_data(request.environ) body = data["body"] result = {"total": body["price"] * body["quantity"]} response = app.response_class( response=to_tytx(result), mimetype="application/vnd.tytx+json" ) return response ``` ### Starlette ```python from starlette.applications import Starlette from starlette.responses import Response from starlette.routing import Route from genro_tytx import asgi_data, to_tytx async def create_order(request): data = await asgi_data(request.scope, request.receive) result = {"total": data["body"]["price"]} return Response( content=to_tytx(result), media_type="application/vnd.tytx+json" ) app = Starlette(routes=[Route("/api/order", create_order, methods=["POST"])]) ``` --- ## Wire Format Examples ### Query String ``` # Native values (no encoding) ?name=John&limit=10 # Typed values ?date=2025-01-15::D&price=100.50::N&active=true::B ``` ### Body (JSON) ```text {"price":"100.50::N","date":"2025-01-15::D","active":true}::JS ``` ### Response ``` HTTP/1.1 200 OK Content-Type: application/vnd.tytx+json {"total":"122.61::N","created_at":"2025-01-15T10:30:00.000Z::DHZ"}::JS ```