Metadata-Version: 2.4
Name: flowdoc-format
Version: 1.1.4
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Rust
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Text Processing :: Markup
Requires-Dist: msgpack>=1.0
Summary: Fast multilanguage serialization format (Python binding via PyO3)
Keywords: serialization,parser,flowdoc,pyo3,rust
Author-email: Pornchai Nimnoi <jomy.nn@gmail.com>
License-Expression: MIT
Requires-Python: >=3.8
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Homepage, https://github.com/sendwavehub/flowdoc-bindings
Project-URL: Issues, https://github.com/sendwavehub/flowdoc-bindings/issues
Project-URL: Repository, https://github.com/sendwavehub/flowdoc-bindings

# flowdoc

Python binding (via [PyO3](https://pyo3.rs)) for [FlowDoc](https://github.com/sendwavehub/flowdoc-bindings) — a fast serialization format: indent-delimited `key: value` records, parsed by a shared Rust core.

```python
import flowdoc

records = flowdoc.parse_flow("""
Record
  id: 1
  name: Test
""")
# [{"id": "1", "name": "Test"}]
```

## `.flowc` (compact FlowDoc)

`.flowc` is a denser text sibling of `.flow` — no `Record` header, no
indentation, `key:value` (no space), blank line between records. Same
`list[dict[str, str]]` data model, just terser syntax; see
`docs/FORMAT_FLOWC.md` for the full spec.

```python
import flowdoc

records = flowdoc.parse_flow_compact("id:1\nname:Test\n\nid:2\nname:Test2\n")
# [{"id": "1", "name": "Test"}, {"id": "2", "name": "Test2"}]

text = flowdoc.write_flow_compact(records)
# "id:1\nname:Test\n\nid:2\nname:Test2\n\n" (field order not guaranteed)
```

## Licensing (soft gate)

`parse_flow`/`parse_flow_via_hashmap` work identically whether or not a
license key is configured — there is no Pro-exclusive capability gated by
this yet. If `FLOWDOC_LICENSE_KEY` is set, this package validates it once
per process, in a background thread, against `FLOWDOC_LICENSE_SERVER +
/api/licenses/validate` (no default server — validation is skipped
entirely if this isn't set too), and logs a warning on an invalid key or
an unreachable server. Query the result yourself with:

```python
import flowdoc

status = flowdoc.license_status()
# {"checked": True, "valid": True | False | None, "error": str | None}
```

`valid` is `None` when there was nothing to check (no key configured) or
nothing could be checked (no server configured, or unreachable) — see
`python/flowdoc/__init__.py` for the full behavior.

In production, set `FLOWDOC_LICENSE_SERVER=https://license-admin.sendwavehub.tech/api`
(the trailing `/api` is required — see `RELEASING.md`'s "Production
license server" section for why). There is no default; validation is
skipped entirely without it.

### Activation

`activate_license(activated_by, activation_ip=None, metadata=None)` is a
separate, explicit call — unlike `license_status()`, it never runs
automatically, since it's a mutating call (it flips the license to
"Activated" server-side, unlike `/validate`'s read-only check). Call it
once, e.g. on first run/install:

```python
import flowdoc

result = flowdoc.activate_license("install-script")
# {"success": True, "error": None, "message": ..., "tier": ..., "seats": ...,
#  "expiresAt": ..., "customerId": ..., "signedLicenseArtifact": ...}
# or, on failure: {"success": False, "error": str, ...other fields None}
```

Posts to `FLOWDOC_LICENSE_SERVER + /licenses/<FLOWDOC_LICENSE_KEY>/activate`
(a single `/api/` segment, since `FLOWDOC_LICENSE_SERVER` is expected to
already carry one — see `/validate`'s doubled `/api/api/` above). Cache
`signedLicenseArtifact` yourself if you need it later; this function
doesn't persist anything.

See the [FlowDoc project](https://github.com/sendwavehub/flowdoc-bindings) for the format overview, benchmark numbers, and links to every other language binding (Rust, Go, Node.js, C#, PHP, C++).

