langgraph-runtime-inmem 0.19.0__py3-none-any.whl → 0.19.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.
@@ -9,7 +9,7 @@ from langgraph_runtime_inmem import (
9
9
  store,
10
10
  )
11
11
 
12
- __version__ = "0.19.0"
12
+ __version__ = "0.19.1"
13
13
  __all__ = [
14
14
  "ops",
15
15
  "database",
@@ -2939,19 +2939,154 @@ def _delete_checkpoints_for_thread(
2939
2939
  )
2940
2940
 
2941
2941
 
2942
- def _check_filter_match(metadata: dict, filters: Auth.types.FilterType | None) -> bool:
2942
+ def _validate_filter_structure(
2943
+ filters: Auth.types.FilterType | None,
2944
+ nesting_level: int = 0,
2945
+ ) -> None:
2946
+ """Validate the structure of filter conditions without checking matches.
2947
+
2948
+ Args:
2949
+ filters: The filter conditions to validate
2950
+ nesting_level: Current depth of nested operators (max 2)
2951
+
2952
+ Raises:
2953
+ HTTPException: If the filter structure is invalid
2954
+ """
2955
+ if nesting_level > 2:
2956
+ raise HTTPException(
2957
+ status_code=500,
2958
+ detail="Your auth handler returned a filter with too many nested operators. The maximum depth for nested operators is 2. Please simplify your filter.",
2959
+ )
2960
+
2961
+ if not filters:
2962
+ return
2963
+
2964
+ # Handle $or operator
2965
+ if "$or" in filters:
2966
+ or_groups = filters["$or"]
2967
+ if not isinstance(or_groups, list) or not len(or_groups) >= 2:
2968
+ raise HTTPException(
2969
+ status_code=500,
2970
+ detail="Your auth handler returned a filter with an invalid $or operator. The $or operator must be a list of at least 2 filter objects. Check the filter returned by your auth handler.",
2971
+ )
2972
+
2973
+ # Recursively validate all groups
2974
+ for group in or_groups:
2975
+ _validate_filter_structure(group, nesting_level=nesting_level + 1)
2976
+
2977
+ # Validate remaining filters (implicit AND with the $or)
2978
+ remaining_filters = {k: v for k, v in filters.items() if k != "$or"}
2979
+ if remaining_filters:
2980
+ _validate_filter_structure(
2981
+ remaining_filters, nesting_level=nesting_level + 1
2982
+ )
2983
+
2984
+ # Handle $and operator
2985
+ if "$and" in filters:
2986
+ and_groups = filters["$and"]
2987
+ if not isinstance(and_groups, list) or not len(and_groups) >= 2:
2988
+ raise HTTPException(
2989
+ status_code=500,
2990
+ detail="Your auth handler returned a filter with an invalid $and operator. The $and operator must be a list of at least 2 filter objects. Check the filter returned by your auth handler.",
2991
+ )
2992
+
2993
+ # Recursively validate all groups
2994
+ for group in and_groups:
2995
+ _validate_filter_structure(group, nesting_level=nesting_level + 1)
2996
+
2997
+ # Validate remaining filters (implicit AND with the $and)
2998
+ remaining_filters = {k: v for k, v in filters.items() if k != "$and"}
2999
+ if remaining_filters:
3000
+ _validate_filter_structure(
3001
+ remaining_filters, nesting_level=nesting_level + 1
3002
+ )
3003
+
3004
+
3005
+ def _check_filter_match(
3006
+ metadata: dict,
3007
+ filters: Auth.types.FilterType | None,
3008
+ nesting_level: int = 0,
3009
+ ) -> bool:
2943
3010
  """Check if metadata matches the filter conditions.
2944
3011
 
2945
3012
  Args:
2946
3013
  metadata: The metadata to check
2947
3014
  filters: The filter conditions to apply
3015
+ nesting_level: Current depth of nested operators (max 2)
2948
3016
 
2949
3017
  Returns:
2950
3018
  True if the metadata matches all filter conditions, False otherwise
2951
3019
  """
3020
+ if nesting_level > 2:
3021
+ raise HTTPException(
3022
+ status_code=500,
3023
+ detail="Your auth handler returned a filter with too many nested operators. The maximum depth for nested operators is 2. Please simplify your filter.",
3024
+ )
3025
+
2952
3026
  if not filters:
2953
3027
  return True
2954
3028
 
3029
+ # Handle $or operator
3030
+ if "$or" in filters:
3031
+ or_groups = filters["$or"]
3032
+ if not isinstance(or_groups, list) or not len(or_groups) >= 2:
3033
+ raise HTTPException(
3034
+ status_code=500,
3035
+ detail="Your auth handler returned a filter with an invalid $or operator. The $or operator must be a list of at least 2 filter objects. Check the filter returned by your auth handler.",
3036
+ )
3037
+
3038
+ # Validate all groups first to ensure nesting limits are respected
3039
+ # (even if we short-circuit during matching)
3040
+ for group in or_groups:
3041
+ _validate_filter_structure(group, nesting_level=nesting_level + 1)
3042
+
3043
+ # At least one group must match
3044
+ or_match = False
3045
+ for group in or_groups:
3046
+ if _check_filter_match(metadata, group, nesting_level=nesting_level + 1):
3047
+ or_match = True
3048
+ break
3049
+
3050
+ if not or_match:
3051
+ return False
3052
+
3053
+ # Check remaining filters (implicit AND with the $or)
3054
+ remaining_filters = {k: v for k, v in filters.items() if k != "$or"}
3055
+ if remaining_filters:
3056
+ return _check_filter_match(
3057
+ metadata, remaining_filters, nesting_level=nesting_level + 1
3058
+ )
3059
+ return True
3060
+
3061
+ # Handle $and operator
3062
+ if "$and" in filters:
3063
+ and_groups = filters["$and"]
3064
+ if not isinstance(and_groups, list) or not len(and_groups) >= 2:
3065
+ raise HTTPException(
3066
+ status_code=500,
3067
+ detail="Your auth handler returned a filter with an invalid $and operator. The $and operator must be a list of at least 2 filter objects. Check the filter returned by your auth handler.",
3068
+ )
3069
+
3070
+ # Validate all groups first to ensure nesting limits are respected
3071
+ for group in and_groups:
3072
+ _validate_filter_structure(group, nesting_level=nesting_level + 1)
3073
+
3074
+ # All groups must match
3075
+ for group in and_groups:
3076
+ if not _check_filter_match(
3077
+ metadata, group, nesting_level=nesting_level + 1
3078
+ ):
3079
+ return False
3080
+
3081
+ # Check remaining filters (implicit AND with the $and)
3082
+ remaining_filters = {k: v for k, v in filters.items() if k != "$and"}
3083
+ if remaining_filters:
3084
+ return _check_filter_match(
3085
+ metadata, remaining_filters, nesting_level=nesting_level + 1
3086
+ )
3087
+ return True
3088
+
3089
+ # Regular filter logic (implicit AND)
2955
3090
  for key, value in filters.items():
2956
3091
  if isinstance(value, dict):
2957
3092
  op = next(iter(value))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langgraph-runtime-inmem
3
- Version: 0.19.0
3
+ Version: 0.19.1
4
4
  Summary: Inmem implementation for the LangGraph API server.
5
5
  Author-email: Will Fu-Hinthorn <will@langchain.dev>
6
6
  License: Elastic-2.0
@@ -1,13 +1,13 @@
1
- langgraph_runtime_inmem/__init__.py,sha256=0BIs1nkaj3_LrNv5Rn9zRPO-KeI1bc0YYx5ZxleIq8c,311
1
+ langgraph_runtime_inmem/__init__.py,sha256=5pyvRaivaIwrST-IiIzvk4R9yyuIp3H5eYCp5sli7Qg,311
2
2
  langgraph_runtime_inmem/checkpoint.py,sha256=nc1G8DqVdIu-ibjKTqXfbPfMbAsKjPObKqegrSzo6Po,4432
3
3
  langgraph_runtime_inmem/database.py,sha256=g2XYa5KN-T8MbDeFH9sfUApDG62Wp4BACumVnDtxYhI,6403
4
4
  langgraph_runtime_inmem/inmem_stream.py,sha256=PFLWbsxU8RqbT5mYJgNk6v5q6TWJRIY1hkZWhJF8nkI,9094
5
5
  langgraph_runtime_inmem/lifespan.py,sha256=fCoYcN_h0cxmj6-muC-f0csPdSpyepZuGRD1yBrq4XM,4755
6
6
  langgraph_runtime_inmem/metrics.py,sha256=_YiSkLnhQvHpMktk38SZo0abyL-5GihfVAtBo0-lFIc,403
7
- langgraph_runtime_inmem/ops.py,sha256=lDR4b-N4pALnMPPc61lpACce1Up-u5U9R5sO0hPTIAw,109276
7
+ langgraph_runtime_inmem/ops.py,sha256=E6dja8tp9rnNj0Qw0qPLrlizMx9wa9fTFB-K-gnK1QI,114625
8
8
  langgraph_runtime_inmem/queue.py,sha256=17HBZrYaxJg_k4NoabToYD_J6cqVzyHpWIz3VzGg_14,9363
9
9
  langgraph_runtime_inmem/retry.py,sha256=XmldOP4e_H5s264CagJRVnQMDFcEJR_dldVR1Hm5XvM,763
10
10
  langgraph_runtime_inmem/store.py,sha256=rTfL1JJvd-j4xjTrL8qDcynaWF6gUJ9-GDVwH0NBD_I,3506
11
- langgraph_runtime_inmem-0.19.0.dist-info/METADATA,sha256=opTbJKPl-tNZseiVB7djNcdOCfoyPCesrjz3QFoB4Hs,570
12
- langgraph_runtime_inmem-0.19.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
13
- langgraph_runtime_inmem-0.19.0.dist-info/RECORD,,
11
+ langgraph_runtime_inmem-0.19.1.dist-info/METADATA,sha256=zSasD-8sdF518e-qs_sveuEkQ0VQPbDVd9e13ziyYj4,570
12
+ langgraph_runtime_inmem-0.19.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
13
+ langgraph_runtime_inmem-0.19.1.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.27.0
2
+ Generator: hatchling 1.28.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any