haystack-ml-stack 0.3.3__tar.gz → 0.3.4__tar.gz

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.
Files changed (24) hide show
  1. {haystack_ml_stack-0.3.3 → haystack_ml_stack-0.3.4}/PKG-INFO +1 -1
  2. {haystack_ml_stack-0.3.3 → haystack_ml_stack-0.3.4}/pyproject.toml +1 -1
  3. {haystack_ml_stack-0.3.3 → haystack_ml_stack-0.3.4}/src/haystack_ml_stack/__init__.py +1 -1
  4. {haystack_ml_stack-0.3.3 → haystack_ml_stack-0.3.4}/src/haystack_ml_stack/app.py +16 -1
  5. {haystack_ml_stack-0.3.3 → haystack_ml_stack-0.3.4}/src/haystack_ml_stack/utils.py +1 -1
  6. {haystack_ml_stack-0.3.3 → haystack_ml_stack-0.3.4}/src/haystack_ml_stack.egg-info/PKG-INFO +1 -1
  7. {haystack_ml_stack-0.3.3 → haystack_ml_stack-0.3.4}/tests/test_utils.py +75 -0
  8. {haystack_ml_stack-0.3.3 → haystack_ml_stack-0.3.4}/README.md +0 -0
  9. {haystack_ml_stack-0.3.3 → haystack_ml_stack-0.3.4}/setup.cfg +0 -0
  10. {haystack_ml_stack-0.3.3 → haystack_ml_stack-0.3.4}/src/haystack_ml_stack/_serializers.py +0 -0
  11. {haystack_ml_stack-0.3.3 → haystack_ml_stack-0.3.4}/src/haystack_ml_stack/cache.py +0 -0
  12. {haystack_ml_stack-0.3.3 → haystack_ml_stack-0.3.4}/src/haystack_ml_stack/dynamo.py +0 -0
  13. {haystack_ml_stack-0.3.3 → haystack_ml_stack-0.3.4}/src/haystack_ml_stack/exceptions.py +0 -0
  14. {haystack_ml_stack-0.3.3 → haystack_ml_stack-0.3.4}/src/haystack_ml_stack/generated/__init__.py +0 -0
  15. {haystack_ml_stack-0.3.3 → haystack_ml_stack-0.3.4}/src/haystack_ml_stack/generated/v1/__init__.py +0 -0
  16. {haystack_ml_stack-0.3.3 → haystack_ml_stack-0.3.4}/src/haystack_ml_stack/generated/v1/features_pb2.py +0 -0
  17. {haystack_ml_stack-0.3.3 → haystack_ml_stack-0.3.4}/src/haystack_ml_stack/generated/v1/features_pb2.pyi +0 -0
  18. {haystack_ml_stack-0.3.3 → haystack_ml_stack-0.3.4}/src/haystack_ml_stack/model_store.py +0 -0
  19. {haystack_ml_stack-0.3.3 → haystack_ml_stack-0.3.4}/src/haystack_ml_stack/settings.py +0 -0
  20. {haystack_ml_stack-0.3.3 → haystack_ml_stack-0.3.4}/src/haystack_ml_stack.egg-info/SOURCES.txt +0 -0
  21. {haystack_ml_stack-0.3.3 → haystack_ml_stack-0.3.4}/src/haystack_ml_stack.egg-info/dependency_links.txt +0 -0
  22. {haystack_ml_stack-0.3.3 → haystack_ml_stack-0.3.4}/src/haystack_ml_stack.egg-info/requires.txt +0 -0
  23. {haystack_ml_stack-0.3.3 → haystack_ml_stack-0.3.4}/src/haystack_ml_stack.egg-info/top_level.txt +0 -0
  24. {haystack_ml_stack-0.3.3 → haystack_ml_stack-0.3.4}/tests/test_serializers.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: haystack-ml-stack
3
- Version: 0.3.3
3
+ Version: 0.3.4
4
4
  Summary: Functions related to Haystack ML
5
5
  Author-email: Oscar Vega <oscar@haystack.tv>
6
6
  License: MIT
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
 
6
6
  [project]
7
7
  name = "haystack-ml-stack"
8
- version = "0.3.3"
8
+ version = "0.3.4"
9
9
  description = "Functions related to Haystack ML"
10
10
  readme = "README.md"
11
11
  authors = [{ name = "Oscar Vega", email = "oscar@haystack.tv" }]
@@ -11,4 +11,4 @@ from ._serializers import SerializerRegistry, FeatureRegistryId
11
11
 
12
12
  __all__ = [*__all__, "SerializerRegistry", "FeatureRegistryId"]
13
13
 
14
- __version__ = "0.3.3"
14
+ __version__ = "0.3.4"
@@ -7,6 +7,7 @@ from typing import Any, Dict, List, Optional
7
7
  import time
8
8
  from contextlib import asynccontextmanager, AsyncExitStack
9
9
  import traceback
10
+ import json
10
11
 
11
12
  import aiobotocore.session
12
13
  from aiobotocore.config import AioConfig
@@ -161,6 +162,7 @@ def create_app(
161
162
  "user_cache_size": len(user_features_cache),
162
163
  "model_name": state.get("model_name"),
163
164
  "stream_features": state.get("stream_features", []),
165
+ "user_features": state.get("user_features", []),
164
166
  }
165
167
 
166
168
  @app.post("/score", status_code=HTTPStatus.OK)
@@ -173,10 +175,23 @@ def create_app(
173
175
 
174
176
  try:
175
177
  data = await request.json()
176
- except Exception as e:
178
+ except json.JSONDecodeError as e:
179
+ body = await request.body()
180
+ logger.error(
181
+ "Received malformed json. Raw body: %s\n%s",
182
+ body.decode(errors="replace"),
183
+ traceback.format_exc(),
184
+ )
177
185
  raise HTTPException(
178
186
  status_code=HTTPStatus.BAD_REQUEST, detail="Invalid JSON payload"
179
187
  ) from e
188
+ except Exception as e:
189
+ logger.error(
190
+ "Unexpected exception when parsing request.\n %s", traceback.format_exc()
191
+ )
192
+ raise HTTPException(
193
+ status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail="Unknown exception"
194
+ ) from e
180
195
  query_params = {}
181
196
  for k in request.query_params.keys():
182
197
  values = request.query_params.getlist(k)
@@ -336,7 +336,7 @@ def user_pwatched_cleanup(
336
336
  "launch_first_in_session",
337
337
  ]
338
338
  _validate_pwatched_entry_context(entry_contexts)
339
- counts_obj = user.get("PWATCHED#6M", UserPWatched())
339
+ counts_obj = user.get("PWATCHED#6M", UserPWatched()).data
340
340
  out = _cleanup_entry_context_counts(
341
341
  counts_obj=counts_obj,
342
342
  entry_contexts=entry_contexts,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: haystack-ml-stack
3
- Version: 0.3.3
3
+ Version: 0.3.4
4
4
  Summary: Functions related to Haystack ML
5
5
  Author-email: Oscar Vega <oscar@haystack.tv>
6
6
  License: MIT
@@ -560,3 +560,78 @@ def test_stream_similarity_top_category_functions():
560
560
  assert all(
561
561
  actual_key == expected_key for actual_key, expected_key in zip(actual, expected)
562
562
  )
563
+
564
+
565
+ def test_user_pwatched_cleanup():
566
+ user_pwatched_data = {
567
+ "version": 1,
568
+ "data": {
569
+ "sel_thumb": {"attempts": 1, "watched": 1},
570
+ "ch_swtch": {"attempts": 2, "watched": 0},
571
+ },
572
+ }
573
+ user_pwatched_msg = features_pb2_v1.UserPWatched()
574
+ ProtoParseDict(js_dict=user_pwatched_data, message=user_pwatched_msg)
575
+ user = {"PWATCHED#6M": user_pwatched_msg}
576
+ out = {}
577
+ utils.user_pwatched_cleanup(
578
+ user=user, entry_contexts=["autoplay", "sel_thumb", "ch_swtch"], out=out
579
+ )
580
+ expected = pd.Series(
581
+ {
582
+ "USER_AUTOPLAY_6M_TOTAL_ATTEMPTS": 0,
583
+ "USER_AUTOPLAY_6M_TOTAL_WATCHED": 0,
584
+ "USER_SEL_THUMB_6M_TOTAL_ATTEMPTS": 1,
585
+ "USER_SEL_THUMB_6M_TOTAL_WATCHED": 1,
586
+ "USER_CH_SWTCH_6M_TOTAL_ATTEMPTS": 2,
587
+ "USER_CH_SWTCH_6M_TOTAL_WATCHED": 0,
588
+ }
589
+ )
590
+ actual = pd.Series(out).loc[expected.index]
591
+ assert (expected == actual).all()
592
+
593
+
594
+ def test_user_pselect_cleanup():
595
+ user_pselect_data = {
596
+ "version": 1,
597
+ "data": {
598
+ "all_browsed": {
599
+ "first_pos": {
600
+ "total_selects": 0,
601
+ "total_selects_and_watched": 0,
602
+ "total_browsed": 1,
603
+ },
604
+ "rest_pos": {
605
+ "total_selects": 2,
606
+ "total_selects_and_watched": 2,
607
+ "total_browsed": 1,
608
+ },
609
+ },
610
+ "up_to_4_browsed": {
611
+ "first_pos": {
612
+ "total_selects": 0,
613
+ "total_selects_and_watched": 0,
614
+ "total_browsed": 1,
615
+ },
616
+ "rest_pos": {
617
+ "total_selects": 2,
618
+ "total_selects_and_watched": 2,
619
+ "total_browsed": 0,
620
+ },
621
+ },
622
+ },
623
+ }
624
+ user_pselect_msg = features_pb2_v1.UserPSelect()
625
+ ProtoParseDict(js_dict=user_pselect_data, message=user_pselect_msg)
626
+ user = {"PSELECT#6M": user_pselect_msg}
627
+ out = {}
628
+ utils.user_pselect_cleanup(user=user, position_debiasing="up_to_4_browsed", out=out)
629
+ expected = pd.Series(
630
+ {
631
+ "USER_6M_TOTAL_BROWSED_UP_TO_4_BROWSED": 1,
632
+ "USER_6M_TOTAL_SELECTS_UP_TO_4_BROWSED": 2,
633
+ "USER_6M_TOTAL_SELECTS_AND_WATCHED_UP_TO_4_BROWSED": 2,
634
+ }
635
+ )
636
+ actual = pd.Series(out).loc[expected.index]
637
+ assert (actual == expected).all()