Coverage for src/local_deep_research/settings/env_definitions/server.py: 100%

3 statements  

« prev     ^ index     » next       coverage.py v7.16.2, created at 2026-10-22 21:20 +0000

1""" 

2Server runtime environment settings. 

3 

4These settings control server-level parameters that require a restart 

5to take effect. They are not editable via the UI. 

6""" 

7 

8from ..env_settings import BooleanSetting, IntegerSetting 

9 

10TRUSTED_PROXY_COUNT = IntegerSetting( 

11 key="server.trusted_proxy_count", 

12 description=( 

13 "Number of X-Forwarded-For entries your trusted reverse proxies " 

14 "append -- one per appending hop for an ordinary proxy, so CDN -> " 

15 "nginx is 2. Used by the rate limiter only while " 

16 "TRUST_PROXY_HEADERS is NOT set: it then reads the N-th entry from " 

17 "the right, provided the direct peer is private/loopback or, once " 

18 "a restricted LDR_SERVER_FORWARDED_ALLOW_IPS is set, listed there " 

19 "(otherwise it keys on the direct peer). N must be exact: too " 

20 "small keys every client on a proxy's address, too large reads an " 

21 "entry the client wrote itself (or, when the header is shorter " 

22 "than N, keys on the direct peer). Zero (default) disables hop " 

23 "counting and keeps the single-proxy behaviour (the right-most " 

24 "entry). With TRUST_PROXY_HEADERS=true this value has no effect -- " 

25 "list every hop in LDR_SERVER_FORWARDED_ALLOW_IPS instead -- and " 

26 "setting it while that allow-list still trusts every peer (the " 

27 'default "*") makes LDR refuse to start. For N >= 2, every ' 

28 "intermediate hop must be unreachable directly by clients, or a " 

29 "client connecting to an inner hop chooses the entry read. Does not " 

30 "affect X-Forwarded-Proto/scheme detection. See 'Proxy chains' in " 

31 "docs/deployment/reverse-proxy.md. Accepted values are ASCII " 

32 "decimal integers from 0 to 16 (surrounding whitespace is ignored " 

33 "and -0 reads as 0); an empty or whitespace-only value counts as " 

34 "unset, and any other invalid value prevents startup." 

35 ), 

36 min_value=0, 

37 # A real deployment has one or two hops in front of LDR; a CDN plus a 

38 # tunnel plus an ingress is three or four. 16 sits far above anything 

39 # operationally sensible while still turning a fat-fingered value (a 

40 # pasted port number, a year) into a startup failure that names the 

41 # variable -- instead of a hop count no X-Forwarded-For chain can 

42 # satisfy, which would silently collapse every client behind the proxy 

43 # into the direct peer's single rate-limit bucket. 

44 max_value=16, 

45 default=0, 

46 raise_on_validation_error=True, 

47 # Reject "1_0" (int() reads that as 10), "+3", and non-ASCII decimal 

48 # digits such as "٣": a trust-boundary count must mean what it 

49 # looks like. 

50 strict_digits=True, 

51) 

52 

53 

54SERVER_SETTINGS = [ 

55 IntegerSetting( 

56 key="server.max_concurrent_research", 

57 description="Server-wide maximum concurrent research operations. Requires restart.", 

58 min_value=1, 

59 max_value=1000, 

60 default=10, 

61 deprecated_env_var="LDR_MAX_GLOBAL_CONCURRENT", 

62 ), 

63 IntegerSetting( 

64 key="web.threadpool_max_threads", 

65 description=( 

66 "Maximum AnyIO worker threads serving synchronous route " 

67 "handlers. Leave unset to use AnyIO's default of 40. Every " 

68 "plain `def` route occupies one worker for its whole duration, " 

69 "and the pool is shared with async dependency solving and " 

70 "response validation, so exhausting it slows async routes too. " 

71 "Raise it if concurrent requests queue behind each other under " 

72 "load; each extra thread costs context switching and contends " 

73 "for the same per-user database pool. Requires restart." 

74 ), 

75 min_value=1, 

76 max_value=1000, 

77 default=None, 

78 ), 

79 BooleanSetting( 

80 key="vite.dev_mode", 

81 description=( 

82 "When true, templates link to the Vite dev server at " 

83 "http://localhost:5173 for HMR instead of the built manifest " 

84 "under static/dist. Set to true when running `npm run dev` " 

85 "alongside the Python server." 

86 ), 

87 default=False, 

88 ), 

89 TRUSTED_PROXY_COUNT, 

90]