flowgraphapp 0.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- flowgraph/__init__.py +8 -0
- flowgraph/_static/_headers +21 -0
- flowgraph/_static/assets/JsonCodeEditor-CBMWkoPU.js +12 -0
- flowgraph/_static/assets/index-BE9FlCos.css +2 -0
- flowgraph/_static/assets/index-SiLO3vOy.js +157 -0
- flowgraph/_static/assets/pdf-B_9Q7Dif.js +11 -0
- flowgraph/_static/assets/pdf.worker.min-0p99Cwul.js +1 -0
- flowgraph/_static/assets/pdf.worker.min-yatZIOMy.mjs +21 -0
- flowgraph/_static/favicon.svg +1 -0
- flowgraph/_static/icons.svg +24 -0
- flowgraph/_static/index.html +15 -0
- flowgraph/ai_proxy.py +146 -0
- flowgraph/cli.py +201 -0
- flowgraph/config.py +125 -0
- flowgraph/keys.py +133 -0
- flowgraph/providers.py +89 -0
- flowgraph/runtime_config.py +27 -0
- flowgraph/security.py +291 -0
- flowgraph/server.py +96 -0
- flowgraph/update_check.py +118 -0
- flowgraphapp-0.1.1.dist-info/METADATA +108 -0
- flowgraphapp-0.1.1.dist-info/RECORD +25 -0
- flowgraphapp-0.1.1.dist-info/WHEEL +4 -0
- flowgraphapp-0.1.1.dist-info/entry_points.txt +2 -0
- flowgraphapp-0.1.1.dist-info/licenses/LICENSE +18 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"""Courtesy update check — modelled on pip's self_outdated_check.
|
|
2
|
+
|
|
3
|
+
- Queries https://pypi.org/pypi/flowgraphapp/json (no telemetry, decoupled from any
|
|
4
|
+
analytics) at most once per TTL, caching the result in a per-user statefile.
|
|
5
|
+
- Fully non-blocking (background daemon thread) and crash-proof (all exceptions
|
|
6
|
+
swallowed) — never delays startup, never errors when offline.
|
|
7
|
+
- Opt-out via FLOWGRAPH_NO_UPDATE_CHECK=1, the --no-update-check flag, or config.
|
|
8
|
+
- Never auto-installs. Prints a calm one-line notice with the upgrade command,
|
|
9
|
+
pipx-aware. (Silent auto-update is a supply-chain risk — see docs/18 §updates.)
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import json
|
|
15
|
+
import os
|
|
16
|
+
import sys
|
|
17
|
+
import threading
|
|
18
|
+
import time
|
|
19
|
+
from typing import Callable, Optional
|
|
20
|
+
|
|
21
|
+
from . import __version__
|
|
22
|
+
from .config import cache_dir
|
|
23
|
+
|
|
24
|
+
DIST_NAME = "flowgraphapp"
|
|
25
|
+
PYPI_JSON_URL = f"https://pypi.org/pypi/{DIST_NAME}/json"
|
|
26
|
+
TTL_SECONDS = 24 * 3600
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def opted_out() -> bool:
|
|
30
|
+
return os.environ.get("FLOWGRAPH_NO_UPDATE_CHECK", "").lower() in ("1", "true", "yes", "on")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def installed_version() -> str:
|
|
34
|
+
try:
|
|
35
|
+
from importlib.metadata import version
|
|
36
|
+
return version(DIST_NAME)
|
|
37
|
+
except Exception:
|
|
38
|
+
return __version__
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _state_file():
|
|
42
|
+
return cache_dir() / "update-check.json"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _read_cache() -> Optional[dict]:
|
|
46
|
+
try:
|
|
47
|
+
return json.loads(_state_file().read_text(encoding="utf-8"))
|
|
48
|
+
except Exception:
|
|
49
|
+
return None
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _write_cache(latest: str) -> None:
|
|
53
|
+
try:
|
|
54
|
+
_state_file().write_text(
|
|
55
|
+
json.dumps({"last_check": time.time(), "latest": latest}), encoding="utf-8"
|
|
56
|
+
)
|
|
57
|
+
except Exception:
|
|
58
|
+
pass
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _is_newer(latest: str, current: str) -> bool:
|
|
62
|
+
try:
|
|
63
|
+
from packaging.version import Version
|
|
64
|
+
return Version(latest) > Version(current)
|
|
65
|
+
except Exception:
|
|
66
|
+
# Conservative fallback: only flag on a clean numeric-tuple comparison.
|
|
67
|
+
def parts(v):
|
|
68
|
+
return tuple(int(x) for x in v.split(".") if x.isdigit())
|
|
69
|
+
try:
|
|
70
|
+
return parts(latest) > parts(current)
|
|
71
|
+
except Exception:
|
|
72
|
+
return False
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _fetch_latest(timeout: float = 2.5) -> Optional[str]:
|
|
76
|
+
try:
|
|
77
|
+
import httpx
|
|
78
|
+
r = httpx.get(PYPI_JSON_URL, timeout=timeout, headers={"accept": "application/json"})
|
|
79
|
+
if r.status_code == 200:
|
|
80
|
+
return r.json()["info"]["version"]
|
|
81
|
+
except Exception:
|
|
82
|
+
return None
|
|
83
|
+
return None
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def _upgrade_command() -> str:
|
|
87
|
+
# pipx installs live in a dedicated venv; plain `pip install` inside it can break it.
|
|
88
|
+
if "PIPX_HOME" in os.environ or os.sep + "pipx" + os.sep in (sys.prefix or ""):
|
|
89
|
+
return f"pipx upgrade {DIST_NAME}"
|
|
90
|
+
return f"pip install -U {DIST_NAME}"
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _run(emit: Callable[[str], None]) -> None:
|
|
94
|
+
try:
|
|
95
|
+
current = installed_version()
|
|
96
|
+
cache = _read_cache()
|
|
97
|
+
latest = None
|
|
98
|
+
if cache and (time.time() - cache.get("last_check", 0)) < TTL_SECONDS:
|
|
99
|
+
latest = cache.get("latest")
|
|
100
|
+
else:
|
|
101
|
+
latest = _fetch_latest()
|
|
102
|
+
if latest:
|
|
103
|
+
_write_cache(latest)
|
|
104
|
+
if latest and _is_newer(latest, current):
|
|
105
|
+
emit(
|
|
106
|
+
f"A new version of FlowGraph is available: {current} -> {latest}. "
|
|
107
|
+
f"Upgrade with: {_upgrade_command()}"
|
|
108
|
+
)
|
|
109
|
+
except Exception:
|
|
110
|
+
pass # never let the courtesy check surface an error
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def check_in_background(emit: Optional[Callable[[str], None]] = None) -> None:
|
|
114
|
+
"""Spawn a daemon thread to check + emit. No-op if opted out."""
|
|
115
|
+
if opted_out():
|
|
116
|
+
return
|
|
117
|
+
out = emit or (lambda msg: print(f"[flowgraph] {msg}", file=sys.stderr))
|
|
118
|
+
threading.Thread(target=_run, args=(out,), daemon=True).start()
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: flowgraphapp
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: FlowGraph — local-first knowledge-graph canvas + AI planner, run securely on your own machine.
|
|
5
|
+
Project-URL: Homepage, https://flow-graph.com
|
|
6
|
+
Author: Naveen
|
|
7
|
+
License: FlowGraph — Proprietary License
|
|
8
|
+
Copyright (c) 2026 Naveen. All rights reserved.
|
|
9
|
+
|
|
10
|
+
This software and its source code (the "Software") are the confidential and
|
|
11
|
+
proprietary property of the copyright holder. No license, right, or permission
|
|
12
|
+
is granted to any person to use, copy, modify, merge, publish, distribute,
|
|
13
|
+
sublicense, sell, or create derivative works of the Software, in whole or in
|
|
14
|
+
part, without the prior written consent of the copyright holder.
|
|
15
|
+
|
|
16
|
+
Unauthorized copying, distribution, or use of the Software, via any medium, is
|
|
17
|
+
strictly prohibited.
|
|
18
|
+
|
|
19
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
20
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
21
|
+
FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
22
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER
|
|
23
|
+
IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN
|
|
24
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Keywords: ai,canvas,graph,knowledge-graph,local-first,planner
|
|
27
|
+
Classifier: Environment :: Web Environment
|
|
28
|
+
Classifier: Framework :: FastAPI
|
|
29
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
30
|
+
Classifier: License :: Other/Proprietary License
|
|
31
|
+
Classifier: Operating System :: OS Independent
|
|
32
|
+
Classifier: Programming Language :: Python :: 3
|
|
33
|
+
Classifier: Topic :: Office/Business
|
|
34
|
+
Requires-Python: >=3.9
|
|
35
|
+
Requires-Dist: fastapi>=0.115
|
|
36
|
+
Requires-Dist: httpx>=0.27
|
|
37
|
+
Requires-Dist: keyring>=25.0
|
|
38
|
+
Requires-Dist: packaging>=23.0
|
|
39
|
+
Requires-Dist: platformdirs>=4.2
|
|
40
|
+
Requires-Dist: typer>=0.12
|
|
41
|
+
Requires-Dist: uvicorn[standard]>=0.30
|
|
42
|
+
Provides-Extra: dev
|
|
43
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
44
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
45
|
+
Provides-Extra: local-embeddings
|
|
46
|
+
Description-Content-Type: text/markdown
|
|
47
|
+
|
|
48
|
+
# FlowGraph — local server (`flowgraphapp`)
|
|
49
|
+
|
|
50
|
+
Run FlowGraph — the local-first knowledge-graph canvas + AI planner — on your own
|
|
51
|
+
machine. Same app as [flow-graph.com](https://flow-graph.com), served from a hardened
|
|
52
|
+
localhost server; your data stays in your browser, and (optionally) your AI key stays
|
|
53
|
+
in your OS keychain instead of the browser.
|
|
54
|
+
|
|
55
|
+
## Install
|
|
56
|
+
|
|
57
|
+
**From PyPI** (once published):
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pip install flowgraphapp # or, isolated: pipx install flowgraphapp
|
|
61
|
+
flowgraph # serves http://127.0.0.1:8765 and opens your browser
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**From source** (works today, before the PyPI release):
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# 1. build the frontend once
|
|
68
|
+
cd app && npm run build && cd ..
|
|
69
|
+
# 2. install the local server (use a venv or pipx to keep it isolated)
|
|
70
|
+
cd server && pip install .
|
|
71
|
+
# 3. run it
|
|
72
|
+
flowgraph
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Stop with `Ctrl-C`. Options: `flowgraph --port 0` (auto-pick a free port),
|
|
76
|
+
`--no-open` (don't open the browser), `flowgraph --help`.
|
|
77
|
+
|
|
78
|
+
## Why local
|
|
79
|
+
|
|
80
|
+
- **Offline / air-gapped** — no Cloudflare, no network required for the app itself.
|
|
81
|
+
- **Privacy / data locality** — your graph lives in the browser's IndexedDB on this machine.
|
|
82
|
+
- **On-device models** — point at Ollama / LM Studio for zero-key, zero-cost AI.
|
|
83
|
+
- **No size ceiling** — not bound by hosting per-file limits as the app grows.
|
|
84
|
+
|
|
85
|
+
## AI
|
|
86
|
+
|
|
87
|
+
Local-model-first: if a local runtime (Ollama `:11434`, LM Studio `:1234`) is reachable,
|
|
88
|
+
it's used with **no key**. Otherwise bring your own provider key — stored in the OS
|
|
89
|
+
keychain, used server-side, **never sent to the browser**:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
flowgraph keys set anthropic # or openrouter / openai / google / deepseek
|
|
93
|
+
flowgraph keys list # shows source, never the key
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Security (safe by default)
|
|
97
|
+
|
|
98
|
+
Binds **loopback only** (`127.0.0.1`); a per-session token is required (delivered via the
|
|
99
|
+
terminal + a `0600` file; the auto-opened URL carries a one-time ticket, never the token).
|
|
100
|
+
Host-header allow-listing blocks DNS-rebinding from websites you visit; Origin checks,
|
|
101
|
+
strict CSP, and security headers apply to every route. Exposing beyond loopback
|
|
102
|
+
(`--allow-lan`) requires TLS. See `docs/18-local-server.md` for the full threat model.
|
|
103
|
+
|
|
104
|
+
## Updates
|
|
105
|
+
|
|
106
|
+
`pip install -U flowgraphapp` (or `flowgraph upgrade`) updates the app and server together;
|
|
107
|
+
your data is untouched. A calm one-line "update available" notice appears at startup —
|
|
108
|
+
disable with `FLOWGRAPH_NO_UPDATE_CHECK=1`.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
flowgraph/__init__.py,sha256=Uhhd9AenUsWYKcisXTq-37rr0foMdM2UTbb5QlPxcsw,309
|
|
2
|
+
flowgraph/ai_proxy.py,sha256=1ilSEhSZM9k_aolvoszk7UbfTKroRKtxASsnNIb43d8,5718
|
|
3
|
+
flowgraph/cli.py,sha256=vMQhhBqWlzzQcrW6W7kOIf9yIR8T25syIn-_n4tRrhk,7247
|
|
4
|
+
flowgraph/config.py,sha256=jNPbD9035vplcjxgnolSimz9lvW7Xs5E_On3DUG8LSw,4103
|
|
5
|
+
flowgraph/keys.py,sha256=YzRN50vLrrGRDa4g5R8LKJXLn5-_O6gf3llREpfRxXc,3531
|
|
6
|
+
flowgraph/providers.py,sha256=3gy0zZ1Trdty2Zf8Nohy0sretvE8DcWvFCJI02xQwoE,2854
|
|
7
|
+
flowgraph/runtime_config.py,sha256=KHqCgKzXMEFIYubyEI2pOb6BhZCV88IGgmdYxM1PNcA,1125
|
|
8
|
+
flowgraph/security.py,sha256=lcqKRysA5NoFHVg7gS2mbGrGM8XL15RReMHQYglyjZ0,11187
|
|
9
|
+
flowgraph/server.py,sha256=qx457Egvvcix7h6vocsxZCeGubwtLeLfr3ybXJIAb-c,4169
|
|
10
|
+
flowgraph/update_check.py,sha256=3wgVTHIwt6WMAQnQLxeh5NfVtBXakyZCAX5-PpFlETE,3762
|
|
11
|
+
flowgraph/_static/_headers,sha256=cmOyww5lRS1Z8w2O6wiZjrpyxp33tc2CdqsibZb4hPs,928
|
|
12
|
+
flowgraph/_static/favicon.svg,sha256=YbyaFh3lgkgojmkFQl1xgPBiTChlAHuX12P9rBIEOmY,9522
|
|
13
|
+
flowgraph/_static/icons.svg,sha256=tF-lBhlc_N70BrqfDHezbdwafCJAQJJuxwq8L96nuTo,5031
|
|
14
|
+
flowgraph/_static/index.html,sha256=kMrXQIA0FoEPmfZgZiaVFhXolAuDWRe0xzLYDhIp0Og,588
|
|
15
|
+
flowgraph/_static/assets/JsonCodeEditor-CBMWkoPU.js,sha256=4DaslSm9-DGkLjwkW8nBx0KTE0gy1MliYTQCLlSdR7M,425248
|
|
16
|
+
flowgraph/_static/assets/index-BE9FlCos.css,sha256=TGkndYbWTDsGCUT7slQAGKijdPm82ToRAwckK-K2710,101924
|
|
17
|
+
flowgraph/_static/assets/index-SiLO3vOy.js,sha256=RAJlyg65El-9_Zzctnf8nQv4IOGW1g3Gnz0VDEhXRAU,2466100
|
|
18
|
+
flowgraph/_static/assets/pdf-B_9Q7Dif.js,sha256=cQc6BUyoLXNJSXYcWQx5dyUR55AMx-8v4g1eLciX1JY,330039
|
|
19
|
+
flowgraph/_static/assets/pdf.worker.min-0p99Cwul.js,sha256=T6e89-gp6ttTvgPHTEVUTIBt6muWufonUckbrRlqZDg,90
|
|
20
|
+
flowgraph/_static/assets/pdf.worker.min-yatZIOMy.mjs,sha256=G6oYRMicgKWyeXyRbnWrKSVL5G2OnLU8tjZNeq2EvjY,1375838
|
|
21
|
+
flowgraphapp-0.1.1.dist-info/METADATA,sha256=h1Kbc6BWahctVocp8vEIeMEuk3UdkMmn5Ej5a4X5OmA,4619
|
|
22
|
+
flowgraphapp-0.1.1.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
|
|
23
|
+
flowgraphapp-0.1.1.dist-info/entry_points.txt,sha256=Q5JhUIRD3j94Lg8tJFPeN6Rhn0roW3GzKF761hseDlU,49
|
|
24
|
+
flowgraphapp-0.1.1.dist-info/licenses/LICENSE,sha256=JdzzOu6vvblaVZfl3KYyd6Qvbfm39m8EjV3xSL2J8Hw,1022
|
|
25
|
+
flowgraphapp-0.1.1.dist-info/RECORD,,
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
FlowGraph — Proprietary License
|
|
2
|
+
Copyright (c) 2026 Naveen. All rights reserved.
|
|
3
|
+
|
|
4
|
+
This software and its source code (the "Software") are the confidential and
|
|
5
|
+
proprietary property of the copyright holder. No license, right, or permission
|
|
6
|
+
is granted to any person to use, copy, modify, merge, publish, distribute,
|
|
7
|
+
sublicense, sell, or create derivative works of the Software, in whole or in
|
|
8
|
+
part, without the prior written consent of the copyright holder.
|
|
9
|
+
|
|
10
|
+
Unauthorized copying, distribution, or use of the Software, via any medium, is
|
|
11
|
+
strictly prohibited.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
15
|
+
FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
16
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER
|
|
17
|
+
IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN
|
|
18
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|