docs: add supported platforms and Windows installation guide (#700)
* docs: add supported platforms section and Windows installation guide Adds a platform compatibility table (Linux, macOS, Windows) and a dedicated Windows setup section with step-by-step instructions for installing PostgreSQL + pgvector and running Hindsight natively. Follows up on #699 which added Windows native support. Also fixes a ty type-check error in metrics.py for the conditional resource module import. * chore: sync generated clients and lock file after #699 Regenerate client SDKs to pick up ValidationError model changes and update uv.lock with platform-specific uvloop/winloop deps. * docs: update Windows section — pg0 now supports Windows pg0 v0.12.0 added Windows support, so embedded DB works everywhere. Restructure Windows section to show simple install-and-run first, with external PostgreSQL as an optional alternative. * chore: sync generated docs skill and openapi references
This commit is contained in:
parent
939cb40a73
commit
349c112c61
8 changed files with 219 additions and 6 deletions
|
|
@ -213,10 +213,12 @@ def main():
|
|||
use_import_string = args.workers > 1 or args.reload
|
||||
# Check for uvloop/winloop availability
|
||||
import sys
|
||||
|
||||
loop_impl = "asyncio"
|
||||
if sys.platform == "win32":
|
||||
try:
|
||||
import winloop
|
||||
|
||||
winloop.install() # Patches asyncio globally — uvicorn uses "asyncio" but gets winloop
|
||||
loop_impl = "asyncio" # Tell uvicorn "asyncio" — it's now winloop underneath
|
||||
print("winloop installed as asyncio event loop policy (Windows uvloop port)")
|
||||
|
|
@ -225,6 +227,7 @@ def main():
|
|||
else:
|
||||
try:
|
||||
import uvloop # noqa: F401
|
||||
|
||||
loop_impl = "uvloop"
|
||||
print("uvloop available, will use for event loop")
|
||||
except ImportError:
|
||||
|
|
|
|||
|
|
@ -13,10 +13,12 @@ This module provides metrics for:
|
|||
|
||||
import logging
|
||||
import os
|
||||
import types
|
||||
|
||||
try:
|
||||
import resource
|
||||
except ImportError:
|
||||
resource = None # Windows doesn't have resource module
|
||||
resource: types.ModuleType | None = None # Windows doesn't have resource module
|
||||
import threading
|
||||
import time
|
||||
from contextlib import contextmanager
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import re # noqa: F401
|
|||
import json
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, StrictStr
|
||||
from typing import Any, ClassVar, Dict, List
|
||||
from typing import Any, ClassVar, Dict, List, Optional
|
||||
from hindsight_client_api.models.validation_error_loc_inner import ValidationErrorLocInner
|
||||
from typing import Optional, Set
|
||||
from typing_extensions import Self
|
||||
|
|
@ -30,7 +30,10 @@ class ValidationError(BaseModel):
|
|||
loc: List[ValidationErrorLocInner]
|
||||
msg: StrictStr
|
||||
type: StrictStr
|
||||
__properties: ClassVar[List[str]] = ["loc", "msg", "type"]
|
||||
input: Optional[Any] = None
|
||||
ctx: Optional[Dict[str, Any]] = None
|
||||
url: Optional[StrictStr] = None
|
||||
__properties: ClassVar[List[str]] = ["loc", "msg", "type", "input", "ctx", "url"]
|
||||
|
||||
model_config = ConfigDict(
|
||||
populate_by_name=True,
|
||||
|
|
@ -78,6 +81,11 @@ class ValidationError(BaseModel):
|
|||
if _item_loc:
|
||||
_items.append(_item_loc.to_dict())
|
||||
_dict['loc'] = _items
|
||||
# set to None if input (nullable) is None
|
||||
# and model_fields_set contains the field
|
||||
if self.input is None and "input" in self.model_fields_set:
|
||||
_dict['input'] = None
|
||||
|
||||
return _dict
|
||||
|
||||
@classmethod
|
||||
|
|
@ -92,7 +100,10 @@ class ValidationError(BaseModel):
|
|||
_obj = cls.model_validate({
|
||||
"loc": [ValidationErrorLocInner.from_dict(_item) for _item in obj["loc"]] if obj.get("loc") is not None else None,
|
||||
"msg": obj.get("msg"),
|
||||
"type": obj.get("type")
|
||||
"type": obj.get("type"),
|
||||
"input": obj.get("input"),
|
||||
"ctx": obj.get("ctx"),
|
||||
"url": obj.get("url")
|
||||
})
|
||||
return _obj
|
||||
|
||||
|
|
|
|||
|
|
@ -2343,6 +2343,20 @@ export type ValidationError = {
|
|||
* Error Type
|
||||
*/
|
||||
type: string;
|
||||
/**
|
||||
* Input
|
||||
*/
|
||||
input?: unknown;
|
||||
/**
|
||||
* Context
|
||||
*/
|
||||
ctx?: {
|
||||
[key: string]: unknown;
|
||||
};
|
||||
/**
|
||||
* URL
|
||||
*/
|
||||
url?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -6,6 +6,20 @@ Hindsight can be deployed in several ways depending on your infrastructure and r
|
|||
**[Hindsight Cloud](https://ui.hindsight.vectorize.io/signup)** is a fully managed service that handles all infrastructure, scaling, and maintenance — [sign up here](https://ui.hindsight.vectorize.io/signup).
|
||||
:::
|
||||
|
||||
## Supported Platforms
|
||||
|
||||
Hindsight runs on **Linux**, **macOS**, and **Windows**:
|
||||
|
||||
| Platform | Docker | Bare Metal (pip) | Embedded DB (pg0) | Notes |
|
||||
|----------|--------|------------------|--------------------|-------|
|
||||
| **Linux** (x86_64, ARM64) | ✅ | ✅ | ✅ | Fully supported, recommended for production |
|
||||
| **macOS** (Apple Silicon, Intel) | ✅ | ✅ | ✅ | Fully supported |
|
||||
| **Windows** (x86_64) | ✅ | ✅ | ✅ | Fully supported — see [Windows setup](#windows) for external PostgreSQL option |
|
||||
|
||||
All platforms support the embedded database (pg0) for development. On Windows, you can also use an external PostgreSQL installation — see the [Windows](#windows) section for a step-by-step guide.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### PostgreSQL
|
||||
|
|
@ -207,6 +221,65 @@ PORT=80 HINDSIGHT_CP_DATAPLANE_API_URL=https://api.hindsight.io npx @vectorize-i
|
|||
|
||||
---
|
||||
|
||||
## Windows
|
||||
|
||||
**Best for**: Running Hindsight natively on Windows without Docker
|
||||
|
||||
Hindsight works on Windows with the embedded database (pg0) out of the box — just install and run:
|
||||
|
||||
```powershell
|
||||
pip install hindsight-api
|
||||
|
||||
set HINDSIGHT_API_LLM_PROVIDER=openai
|
||||
set HINDSIGHT_API_LLM_API_KEY=sk-xxx
|
||||
set HINDSIGHT_API_LLM_MODEL=gpt-4o-mini
|
||||
|
||||
hindsight-api
|
||||
```
|
||||
|
||||
### Using External PostgreSQL (optional)
|
||||
|
||||
If you prefer to use your own PostgreSQL instance instead of the embedded database:
|
||||
|
||||
```powershell
|
||||
# Install PostgreSQL
|
||||
winget install PostgreSQL.PostgreSQL.17
|
||||
|
||||
# Build pgvector (requires Visual Studio Build Tools)
|
||||
git clone https://github.com/pgvector/pgvector.git
|
||||
cd pgvector
|
||||
|
||||
# Open "x64 Native Tools Command Prompt for VS" and run:
|
||||
set PGROOT=C:\Program Files\PostgreSQL\17
|
||||
nmake /F Makefile.win
|
||||
nmake /F Makefile.win install
|
||||
|
||||
# Create the database and enable the vector extension
|
||||
psql -U postgres -c "CREATE DATABASE hindsight;"
|
||||
psql -U postgres -d hindsight -c "CREATE EXTENSION vector;"
|
||||
```
|
||||
|
||||
Then run Hindsight pointing to your database:
|
||||
|
||||
```powershell
|
||||
pip install hindsight-api
|
||||
|
||||
set HINDSIGHT_API_DATABASE_URL=postgresql://postgres@localhost:5432/hindsight
|
||||
set HINDSIGHT_API_LLM_PROVIDER=openai
|
||||
set HINDSIGHT_API_LLM_API_KEY=sk-xxx
|
||||
set HINDSIGHT_API_LLM_MODEL=gpt-4o-mini
|
||||
|
||||
hindsight-api
|
||||
```
|
||||
|
||||
- **API Server**: http://localhost:8888
|
||||
|
||||
:::tip
|
||||
You can also use the slim package (`pip install hindsight-api-slim`) if you configure external providers for embeddings and reranking. See [Configuration](./configuration#embeddings) for details.
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## Embedded in a Python Application
|
||||
|
||||
**Best for**: Using Hindsight programmatically from Python without running a separate server process.
|
||||
|
|
|
|||
|
|
@ -6,6 +6,20 @@ Hindsight can be deployed in several ways depending on your infrastructure and r
|
|||
**[Hindsight Cloud](https://ui.hindsight.vectorize.io/signup)** is a fully managed service that handles all infrastructure, scaling, and maintenance — [sign up here](https://ui.hindsight.vectorize.io/signup).
|
||||
:::
|
||||
|
||||
## Supported Platforms
|
||||
|
||||
Hindsight runs on **Linux**, **macOS**, and **Windows**:
|
||||
|
||||
| Platform | Docker | Bare Metal (pip) | Embedded DB (pg0) | Notes |
|
||||
|----------|--------|------------------|--------------------|-------|
|
||||
| **Linux** (x86_64, ARM64) | ✅ | ✅ | ✅ | Fully supported, recommended for production |
|
||||
| **macOS** (Apple Silicon, Intel) | ✅ | ✅ | ✅ | Fully supported |
|
||||
| **Windows** (x86_64) | ✅ | ✅ | ✅ | Fully supported — see [Windows setup](#windows) for external PostgreSQL option |
|
||||
|
||||
All platforms support the embedded database (pg0) for development. On Windows, you can also use an external PostgreSQL installation — see the [Windows](#windows) section for a step-by-step guide.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### PostgreSQL
|
||||
|
|
@ -207,6 +221,65 @@ PORT=80 HINDSIGHT_CP_DATAPLANE_API_URL=https://api.hindsight.io npx @vectorize-i
|
|||
|
||||
---
|
||||
|
||||
## Windows
|
||||
|
||||
**Best for**: Running Hindsight natively on Windows without Docker
|
||||
|
||||
Hindsight works on Windows with the embedded database (pg0) out of the box — just install and run:
|
||||
|
||||
```powershell
|
||||
pip install hindsight-api
|
||||
|
||||
set HINDSIGHT_API_LLM_PROVIDER=openai
|
||||
set HINDSIGHT_API_LLM_API_KEY=sk-xxx
|
||||
set HINDSIGHT_API_LLM_MODEL=gpt-4o-mini
|
||||
|
||||
hindsight-api
|
||||
```
|
||||
|
||||
### Using External PostgreSQL (optional)
|
||||
|
||||
If you prefer to use your own PostgreSQL instance instead of the embedded database:
|
||||
|
||||
```powershell
|
||||
# Install PostgreSQL
|
||||
winget install PostgreSQL.PostgreSQL.17
|
||||
|
||||
# Build pgvector (requires Visual Studio Build Tools)
|
||||
git clone https://github.com/pgvector/pgvector.git
|
||||
cd pgvector
|
||||
|
||||
# Open "x64 Native Tools Command Prompt for VS" and run:
|
||||
set PGROOT=C:\Program Files\PostgreSQL\17
|
||||
nmake /F Makefile.win
|
||||
nmake /F Makefile.win install
|
||||
|
||||
# Create the database and enable the vector extension
|
||||
psql -U postgres -c "CREATE DATABASE hindsight;"
|
||||
psql -U postgres -d hindsight -c "CREATE EXTENSION vector;"
|
||||
```
|
||||
|
||||
Then run Hindsight pointing to your database:
|
||||
|
||||
```powershell
|
||||
pip install hindsight-api
|
||||
|
||||
set HINDSIGHT_API_DATABASE_URL=postgresql://postgres@localhost:5432/hindsight
|
||||
set HINDSIGHT_API_LLM_PROVIDER=openai
|
||||
set HINDSIGHT_API_LLM_API_KEY=sk-xxx
|
||||
set HINDSIGHT_API_LLM_MODEL=gpt-4o-mini
|
||||
|
||||
hindsight-api
|
||||
```
|
||||
|
||||
- **API Server**: http://localhost:8888
|
||||
|
||||
:::tip
|
||||
You can also use the slim package (`pip install hindsight-api-slim`) if you configure external providers for embeddings and reranking. See [Configuration](./configuration#embeddings) for details.
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## Embedded in a Python Application
|
||||
|
||||
**Best for**: Using Hindsight programmatically from Python without running a separate server process.
|
||||
|
|
|
|||
|
|
@ -8265,6 +8265,17 @@
|
|||
"type": {
|
||||
"type": "string",
|
||||
"title": "Error Type"
|
||||
},
|
||||
"input": {
|
||||
"title": "Input"
|
||||
},
|
||||
"ctx": {
|
||||
"title": "Context",
|
||||
"type": "object"
|
||||
},
|
||||
"url": {
|
||||
"title": "URL",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
|
|
|
|||
30
uv.lock
30
uv.lock
|
|
@ -450,6 +450,7 @@ dependencies = [
|
|||
{ name = "jmespath" },
|
||||
{ name = "s3transfer" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/74/ec/636ab2aa7ad9e6bf6e297240ac2d44dba63cc6611e2d5038db318436d449/boto3-1.42.74.tar.gz", hash = "sha256:dbacd808cf2a3dadbf35f3dbd8de97b94dc9f78b1ebd439f38f552e0f9753577", size = 112739 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ad/16/a264b4da2af99f4a12609b93fea941cce5ec41da14b33ed3fef77a910f0c/boto3-1.42.74-py3-none-any.whl", hash = "sha256:4bf89c044d618fe4435af854ab820f09dd43569c0df15d7beb0398f50b9aa970", size = 140557 },
|
||||
]
|
||||
|
|
@ -1577,7 +1578,8 @@ dependencies = [
|
|||
{ name = "typer" },
|
||||
{ name = "urllib3" },
|
||||
{ name = "uvicorn" },
|
||||
{ name = "uvloop" },
|
||||
{ name = "uvloop", marker = "sys_platform != 'win32'" },
|
||||
{ name = "winloop", marker = "sys_platform == 'win32'" },
|
||||
{ name = "wsproto" },
|
||||
]
|
||||
|
||||
|
|
@ -1696,7 +1698,8 @@ requires-dist = [
|
|||
{ name = "typer", specifier = ">=0.9.0" },
|
||||
{ name = "urllib3", specifier = ">=2.6.3" },
|
||||
{ name = "uvicorn", specifier = ">=0.38.0" },
|
||||
{ name = "uvloop", specifier = ">=0.22.1" },
|
||||
{ name = "uvloop", marker = "sys_platform != 'win32'", specifier = ">=0.22.1" },
|
||||
{ name = "winloop", marker = "sys_platform == 'win32'", specifier = ">=0.1.0" },
|
||||
{ name = "wsproto", specifier = ">=1.0.0" },
|
||||
]
|
||||
provides-extras = ["local-ml", "embedded-db", "all", "test"]
|
||||
|
|
@ -5740,6 +5743,29 @@ wheels = [
|
|||
{ url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winloop"
|
||||
version = "0.6.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/0e/b9/a7c42bd95a18fc13b63002a028de0f2c3e76efbed20c6afd630c608e89b7/winloop-0.6.0.tar.gz", hash = "sha256:3fa5507c152373a508891468cc02acb0ecf96abfc08d6c296042973be3f40267", size = 2562929 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/56/aa/284717ae7fa5de7fd14b840f8f250dbad8660af6c160381984653453258b/winloop-0.6.0-cp311-cp311-win32.whl", hash = "sha256:16266bd17b819900dbde5918639b97a2a31b5d72867703eeeaedeadbe77c653d", size = 529152 },
|
||||
{ url = "https://files.pythonhosted.org/packages/87/82/301bdf57d339a3ba919941ea34baeb67bdb3decd2bed79d47305f4360a32/winloop-0.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:f21a54ef2e7a5be0751ebcbec8e48be5a40ab4b1b45d67feff8a9973db3cea2a", size = 651258 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f8/13/7ec04542984b379f06d7dd68b35e3e94f86d7f541e40fa0e60f2130a0313/winloop-0.6.0-cp311-cp311-win_arm64.whl", hash = "sha256:45d74b9d5cc72f4ad32e4df45bd1e494d9365345112ae235d3207f0ae3af07c5", size = 534325 },
|
||||
{ url = "https://files.pythonhosted.org/packages/22/c5/580a1d888df994e0b719b1f539947cd734b4d4965f03b89d4e314d06e4d1/winloop-0.6.0-cp312-cp312-win32.whl", hash = "sha256:bd254fd5cea884bed1bf5c76bc315b66ef68ba1638347ca2ba252a85ead5a91b", size = 536047 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a9/ed/c12383edfe619711437adbb7972a5b9199ccd99838ffe53dc592e803cb7a/winloop-0.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:d240ae761a079a0c80bf1997a240c6358189eccbc9d3742a43929290f8e29668", size = 648816 },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/1e/ba40e1539c9f8ad1017b63881d40f84e6e14237756323d6ab2d59f2ef628/winloop-0.6.0-cp312-cp312-win_arm64.whl", hash = "sha256:41d2e77e74dec70a7a48f72e5fd48f78f4c64cc1ea5d754bd6a88652c72b06aa", size = 533147 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a0/60/9f026102aa3af68acd76f4ca29e7c720e29ac429593e6b32a90e6144fe24/winloop-0.6.0-cp313-cp313-win32.whl", hash = "sha256:8ab3d7a77c195d18241b87425d97f422e2d2f0cf7724cb43280d4cf3c799789f", size = 535896 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ab/21/5d296171f7b3944d004449f622b3d7fc679f5ebf5917d895de51f2d40cec/winloop-0.6.0-cp313-cp313-win_amd64.whl", hash = "sha256:1b92ce03f762117931c18aa281c5c089c88069d9e01edbd2e5039d4926238b7a", size = 648424 },
|
||||
{ url = "https://files.pythonhosted.org/packages/10/ab/6544b5c30f26d8665bf53be731bb4ba2e54107a991aab33e502d02d17e4f/winloop-0.6.0-cp313-cp313-win_arm64.whl", hash = "sha256:4b03a749f42291e581fca6c3a8eeafe6c2125ca3bff166eb1f78370b2caa5d79", size = 532346 },
|
||||
{ url = "https://files.pythonhosted.org/packages/10/55/50467648f6d79dc4641c105134981a2f0f012628c0ac0ef3118fe4220cf4/winloop-0.6.0-cp314-cp314-win32.whl", hash = "sha256:9539da7d2bdb82176e0d89a96f5c0c40f05cabfaee240eb6bc4a160642fb5c18", size = 542595 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6f/39/1d12dd2127b9bad40e925b4eae1aedd292f4ece37628c09afab0e9ae2e38/winloop-0.6.0-cp314-cp314-win_amd64.whl", hash = "sha256:7e9a8b992b207330158f7866e72111d8cee293d0d7b68faee6df4dec6c3922b9", size = 659338 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a5/4a/0e24a2a7fbf1a92b02c8b2872683ab504fb987881a811cff9a6cdc175db0/winloop-0.6.0-cp314-cp314-win_arm64.whl", hash = "sha256:08df8649fdfe25a48f96fe0d9d1f92b2ce27a2cd9c5bc761284de3626fb77575", size = 550915 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e6/27/556353390e8ee4fb75f4bb46b8e711b3d6bc091ecc07a9ddabe0bfef6e59/winloop-0.6.0-cp314-cp314t-win32.whl", hash = "sha256:3cf4bed145e8baa5bca865849e4d8b0745bb02da00afb52070d69436906f3794", size = 649712 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/4e/a930cb590bdc7fe9e02e9c5ad5b0a15c9fb3a25cf007a96e6116534fdcbc/winloop-0.6.0-cp314-cp314t-win_amd64.whl", hash = "sha256:f7d0bf2a83a87a8160c03fe65b3348f59b76f617d3771fbaee44923d5aa2b536", size = 808605 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e3/03/37f308e32395342b3d9409fff5dddb62f4a80089bbc869261ac54bcddc3d/winloop-0.6.0-cp314-cp314t-win_arm64.whl", hash = "sha256:8035b4ad56fa4c49c7aa09f458eb1a53bf61e98cd97c3b6e381ffb1e8f007d83", size = 580005 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wrapt"
|
||||
version = "1.17.3"
|
||||
|
|
|
|||
Loading…
Reference in a new issue