sf-queue-sdk 0.3.1b233__tar.gz → 0.3.1b255__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 (30) hide show
  1. sf_queue_sdk-0.3.1b233/README.md → sf_queue_sdk-0.3.1b255/PKG-INFO +70 -3
  2. sf_queue_sdk-0.3.1b233/PKG-INFO → sf_queue_sdk-0.3.1b255/README.md +62 -11
  3. {sf_queue_sdk-0.3.1b233 → sf_queue_sdk-0.3.1b255}/pyproject.toml +1 -1
  4. {sf_queue_sdk-0.3.1b233 → sf_queue_sdk-0.3.1b255}/queue_sdk/__init__.py +3 -1
  5. {sf_queue_sdk-0.3.1b233 → sf_queue_sdk-0.3.1b255}/queue_sdk/client.py +2 -0
  6. sf_queue_sdk-0.3.1b255/queue_sdk/queues/document_notes_queue.py +95 -0
  7. {sf_queue_sdk-0.3.1b233 → sf_queue_sdk-0.3.1b255}/queue_sdk/queues/document_upload_queue.py +5 -0
  8. {sf_queue_sdk-0.3.1b233 → sf_queue_sdk-0.3.1b255}/queue_sdk/types.py +16 -1
  9. {sf_queue_sdk-0.3.1b233 → sf_queue_sdk-0.3.1b255}/.gitignore +0 -0
  10. {sf_queue_sdk-0.3.1b233 → sf_queue_sdk-0.3.1b255}/queue_sdk/generated/__init__.py +0 -0
  11. {sf_queue_sdk-0.3.1b233 → sf_queue_sdk-0.3.1b255}/queue_sdk/generated/queue/email/v1/email_pb2.py +0 -0
  12. {sf_queue_sdk-0.3.1b233 → sf_queue_sdk-0.3.1b255}/queue_sdk/generated/queue/email/v1/email_pb2.pyi +0 -0
  13. {sf_queue_sdk-0.3.1b233 → sf_queue_sdk-0.3.1b255}/queue_sdk/generated/queue/prompt_ingest/v1/prompt_ingest_pb2.py +0 -0
  14. {sf_queue_sdk-0.3.1b233 → sf_queue_sdk-0.3.1b255}/queue_sdk/generated/queue/prompt_ingest/v1/prompt_ingest_pb2.pyi +0 -0
  15. {sf_queue_sdk-0.3.1b233 → sf_queue_sdk-0.3.1b255}/queue_sdk/generated/queue/tool_assignment/v1/tool_assignment_pb2.py +0 -0
  16. {sf_queue_sdk-0.3.1b233 → sf_queue_sdk-0.3.1b255}/queue_sdk/generated/queue/tool_assignment/v1/tool_assignment_pb2.pyi +0 -0
  17. {sf_queue_sdk-0.3.1b233 → sf_queue_sdk-0.3.1b255}/queue_sdk/generated/queue/topic_assignment/v1/topic_assignment_pb2.py +0 -0
  18. {sf_queue_sdk-0.3.1b233 → sf_queue_sdk-0.3.1b255}/queue_sdk/generated/queue/topic_assignment/v1/topic_assignment_pb2.pyi +0 -0
  19. {sf_queue_sdk-0.3.1b233 → sf_queue_sdk-0.3.1b255}/queue_sdk/query.py +0 -0
  20. {sf_queue_sdk-0.3.1b233 → sf_queue_sdk-0.3.1b255}/queue_sdk/queues/__init__.py +0 -0
  21. {sf_queue_sdk-0.3.1b233 → sf_queue_sdk-0.3.1b255}/queue_sdk/queues/base_queue.py +0 -0
  22. {sf_queue_sdk-0.3.1b233 → sf_queue_sdk-0.3.1b255}/queue_sdk/queues/document_persist_queue.py +0 -0
  23. {sf_queue_sdk-0.3.1b233 → sf_queue_sdk-0.3.1b255}/queue_sdk/queues/email_queue.py +0 -0
  24. {sf_queue_sdk-0.3.1b233 → sf_queue_sdk-0.3.1b255}/queue_sdk/queues/pdf_to_image_queue.py +0 -0
  25. {sf_queue_sdk-0.3.1b233 → sf_queue_sdk-0.3.1b255}/queue_sdk/queues/prompt_ingest_queue.py +0 -0
  26. {sf_queue_sdk-0.3.1b233 → sf_queue_sdk-0.3.1b255}/queue_sdk/queues/recommendation_queue.py +0 -0
  27. {sf_queue_sdk-0.3.1b233 → sf_queue_sdk-0.3.1b255}/queue_sdk/queues/tool_assignment_queue.py +0 -0
  28. {sf_queue_sdk-0.3.1b233 → sf_queue_sdk-0.3.1b255}/queue_sdk/queues/topic_assignment_queue.py +0 -0
  29. {sf_queue_sdk-0.3.1b233 → sf_queue_sdk-0.3.1b255}/queue_sdk/redis_client.py +0 -0
  30. {sf_queue_sdk-0.3.1b233 → sf_queue_sdk-0.3.1b255}/queue_sdk/sanitize.py +0 -0
@@ -1,3 +1,11 @@
1
+ Metadata-Version: 2.4
2
+ Name: sf-queue-sdk
3
+ Version: 0.3.1b255
4
+ Summary: Python SDK for sf-queue - Redis-based queue system
5
+ Requires-Python: >=3.11
6
+ Requires-Dist: redis>=5.0.0
7
+ Description-Content-Type: text/markdown
8
+
1
9
  # sf-queue-sdk
2
10
 
3
11
  Python SDK for sf-queue. Enqueues emails via Redis Streams with optional blocking confirmation from the Go consumer service.
@@ -607,6 +615,7 @@ result = client.document_upload.send(
607
615
  | `folder_id` | `Optional[str]` | No | Folder for organization |
608
616
  | `upload_batch_id` | `Optional[str]` | No | Batch ID when multiple files uploaded together |
609
617
  | `youtube_title` | `Optional[str]` | No | Title override for YouTube video transcripts |
618
+ | `skip_material_creation` | `Optional[bool]` | No | Skip folder and material creation when the material already exists (e.g. live lectures) |
610
619
 
611
620
  ### Response Type
612
621
 
@@ -662,11 +671,69 @@ print(f"Pipeline: {status.pipeline_type}") # e.g. "pdf", "youtube",
662
671
 
663
672
  Status data is stored in Redis with a 1-hour TTL, reset on every update. If `get_status()` is called with an unknown request ID or after the TTL expires, it returns `status="unknown"`.
664
673
 
665
- ## Document Persist (Deferred Note Generation)
674
+ ## Document Notes (Note Generation)
675
+
676
+ Enqueue note generation jobs after clustering completes. In the three-queue architecture, Queue 1 (document-upload) handles extraction and clustering, Queue 2 (document-notes) generates notes and persists materials, and Queue 3 (document-persist) links materials to topics after user approval.
677
+
678
+ Queue 1 automatically enqueues to document-notes after clustering. The notes queue generates notes, persists materials, and sends the callback that closes the upload modal.
679
+
680
+ ### Fire and forget
681
+
682
+ ```python
683
+ result = client.document_notes.send(
684
+ uploaded_file_id="file_abc123",
685
+ study_set_id="set_xyz",
686
+ user_id="user_123",
687
+ stash_key="clustering-stash/file_abc123/1720000000.json",
688
+ is_deferred=True,
689
+ callback_url="https://api.example.com/completeCluster",
690
+ callback_api_key="secret",
691
+ )
692
+
693
+ print("Enqueued:", result.message_id)
694
+ ```
695
+
696
+ ### With notes disabled
697
+
698
+ ```python
699
+ result = client.document_notes.send(
700
+ uploaded_file_id="file_abc123",
701
+ study_set_id="set_xyz",
702
+ user_id="user_123",
703
+ stash_key="clustering-stash/file_abc123/1720000000.json",
704
+ is_deferred=False,
705
+ generate_notes=False,
706
+ folder_id="folder_abc",
707
+ callback_url="https://api.example.com/completeCluster",
708
+ callback_api_key="secret",
709
+ )
710
+ ```
711
+
712
+ ### Document Notes Fields
713
+
714
+ | Field | Type | Required | Description |
715
+ |-------|------|----------|-------------|
716
+ | `uploaded_file_id` | `str` | Yes | ID of the uploaded file record |
717
+ | `study_set_id` | `str` | Yes | Study set to persist materials into |
718
+ | `user_id` | `str` | Yes | User who uploaded the document |
719
+ | `stash_key` | `str` | Yes | GCS key of the clustering stash JSON |
720
+ | `is_deferred` | `bool` | No | Whether the study set has existing topics requiring approval (default: `False`) |
721
+ | `generate_notes` | `bool` | No | Whether to generate notes (default: `True`). Set to `False` for noNotes materials |
722
+ | `callback_url` | `Optional[str]` | No | URL to POST results to after completion |
723
+ | `callback_api_key` | `Optional[str]` | No | Auth key for the callback |
724
+ | `folder_id` | `Optional[str]` | No | Pre-created folder ID for the materials |
725
+
726
+ ### Response Types
727
+
728
+ | Method | Return Type | Fields |
729
+ |--------|-------------|--------|
730
+ | `send()` | `SendResult` | `message_id` |
731
+
732
+ ## Document Persist (Topic Linking)
666
733
 
667
- Enqueue deferred note generation + material persistence jobs. Used in the two-queue architecture where Queue 1 (document-upload) handles extraction and clustering, and Queue 2 (document-persist) handles note generation and persistence after user approval.
734
+ Enqueue topic-linking jobs after user approval. In the three-queue architecture, Queue 3 (document-persist) loads the material map from the stash sidecar and links pre-generated materials to approved topics.
668
735
 
669
- For new study sets (no existing study path), Queue 1 auto-forwards to document-persist. For existing study sets, the clustering output is stashed and presented as pending changes for user review. After approval, the approve route enqueues to document-persist.
736
+ For new study sets (no existing study path), Queue 2 handles everything. For existing study sets, the approve route enqueues to document-persist after the user reviews pending changes.
670
737
 
671
738
  ### Fire and forget
672
739
 
@@ -1,11 +1,3 @@
1
- Metadata-Version: 2.4
2
- Name: sf-queue-sdk
3
- Version: 0.3.1b233
4
- Summary: Python SDK for sf-queue - Redis-based queue system
5
- Requires-Python: >=3.11
6
- Requires-Dist: redis>=5.0.0
7
- Description-Content-Type: text/markdown
8
-
9
1
  # sf-queue-sdk
10
2
 
11
3
  Python SDK for sf-queue. Enqueues emails via Redis Streams with optional blocking confirmation from the Go consumer service.
@@ -615,6 +607,7 @@ result = client.document_upload.send(
615
607
  | `folder_id` | `Optional[str]` | No | Folder for organization |
616
608
  | `upload_batch_id` | `Optional[str]` | No | Batch ID when multiple files uploaded together |
617
609
  | `youtube_title` | `Optional[str]` | No | Title override for YouTube video transcripts |
610
+ | `skip_material_creation` | `Optional[bool]` | No | Skip folder and material creation when the material already exists (e.g. live lectures) |
618
611
 
619
612
  ### Response Type
620
613
 
@@ -670,11 +663,69 @@ print(f"Pipeline: {status.pipeline_type}") # e.g. "pdf", "youtube",
670
663
 
671
664
  Status data is stored in Redis with a 1-hour TTL, reset on every update. If `get_status()` is called with an unknown request ID or after the TTL expires, it returns `status="unknown"`.
672
665
 
673
- ## Document Persist (Deferred Note Generation)
666
+ ## Document Notes (Note Generation)
667
+
668
+ Enqueue note generation jobs after clustering completes. In the three-queue architecture, Queue 1 (document-upload) handles extraction and clustering, Queue 2 (document-notes) generates notes and persists materials, and Queue 3 (document-persist) links materials to topics after user approval.
669
+
670
+ Queue 1 automatically enqueues to document-notes after clustering. The notes queue generates notes, persists materials, and sends the callback that closes the upload modal.
671
+
672
+ ### Fire and forget
673
+
674
+ ```python
675
+ result = client.document_notes.send(
676
+ uploaded_file_id="file_abc123",
677
+ study_set_id="set_xyz",
678
+ user_id="user_123",
679
+ stash_key="clustering-stash/file_abc123/1720000000.json",
680
+ is_deferred=True,
681
+ callback_url="https://api.example.com/completeCluster",
682
+ callback_api_key="secret",
683
+ )
684
+
685
+ print("Enqueued:", result.message_id)
686
+ ```
687
+
688
+ ### With notes disabled
689
+
690
+ ```python
691
+ result = client.document_notes.send(
692
+ uploaded_file_id="file_abc123",
693
+ study_set_id="set_xyz",
694
+ user_id="user_123",
695
+ stash_key="clustering-stash/file_abc123/1720000000.json",
696
+ is_deferred=False,
697
+ generate_notes=False,
698
+ folder_id="folder_abc",
699
+ callback_url="https://api.example.com/completeCluster",
700
+ callback_api_key="secret",
701
+ )
702
+ ```
703
+
704
+ ### Document Notes Fields
705
+
706
+ | Field | Type | Required | Description |
707
+ |-------|------|----------|-------------|
708
+ | `uploaded_file_id` | `str` | Yes | ID of the uploaded file record |
709
+ | `study_set_id` | `str` | Yes | Study set to persist materials into |
710
+ | `user_id` | `str` | Yes | User who uploaded the document |
711
+ | `stash_key` | `str` | Yes | GCS key of the clustering stash JSON |
712
+ | `is_deferred` | `bool` | No | Whether the study set has existing topics requiring approval (default: `False`) |
713
+ | `generate_notes` | `bool` | No | Whether to generate notes (default: `True`). Set to `False` for noNotes materials |
714
+ | `callback_url` | `Optional[str]` | No | URL to POST results to after completion |
715
+ | `callback_api_key` | `Optional[str]` | No | Auth key for the callback |
716
+ | `folder_id` | `Optional[str]` | No | Pre-created folder ID for the materials |
717
+
718
+ ### Response Types
719
+
720
+ | Method | Return Type | Fields |
721
+ |--------|-------------|--------|
722
+ | `send()` | `SendResult` | `message_id` |
723
+
724
+ ## Document Persist (Topic Linking)
674
725
 
675
- Enqueue deferred note generation + material persistence jobs. Used in the two-queue architecture where Queue 1 (document-upload) handles extraction and clustering, and Queue 2 (document-persist) handles note generation and persistence after user approval.
726
+ Enqueue topic-linking jobs after user approval. In the three-queue architecture, Queue 3 (document-persist) loads the material map from the stash sidecar and links pre-generated materials to approved topics.
676
727
 
677
- For new study sets (no existing study path), Queue 1 auto-forwards to document-persist. For existing study sets, the clustering output is stashed and presented as pending changes for user review. After approval, the approve route enqueues to document-persist.
728
+ For new study sets (no existing study path), Queue 2 handles everything. For existing study sets, the approve route enqueues to document-persist after the user reviews pending changes.
678
729
 
679
730
  ### Fire and forget
680
731
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sf-queue-sdk"
3
- version = "0.3.1b233"
3
+ version = "0.3.1b255"
4
4
  description = "Python SDK for sf-queue - Redis-based queue system"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -1,6 +1,6 @@
1
1
  """sf-queue Python SDK - Redis-based queue system."""
2
2
 
3
- __version__ = "0.3.1b233"
3
+ __version__ = "0.3.1b255"
4
4
 
5
5
  from queue_sdk.client import QueueClient
6
6
  from queue_sdk.query import QueryClient
@@ -13,6 +13,7 @@ from queue_sdk.types import (
13
13
  BatchTopicAssignmentData,
14
14
  ConvertData,
15
15
  ConvertResponse,
16
+ DocumentNotesData,
16
17
  DocumentPersistData,
17
18
  DocumentPersistResponse,
18
19
  DocumentUploadData,
@@ -54,6 +55,7 @@ __all__ = [
54
55
  "BatchToolAssignmentData",
55
56
  "ConvertData",
56
57
  "ConvertResponse",
58
+ "DocumentNotesData",
57
59
  "DocumentPersistData",
58
60
  "DocumentPersistResponse",
59
61
  "DocumentUploadData",
@@ -1,6 +1,7 @@
1
1
  """QueueClient - main entry point for the Python SDK."""
2
2
 
3
3
  from queue_sdk.query import QueryClient
4
+ from queue_sdk.queues.document_notes_queue import DocumentNotesQueue
4
5
  from queue_sdk.queues.document_persist_queue import DocumentPersistQueue
5
6
  from queue_sdk.queues.document_upload_queue import DocumentUploadQueue
6
7
  from queue_sdk.queues.email_queue import EmailQueue
@@ -72,6 +73,7 @@ class QueueClient:
72
73
  self.pdf_to_image = PdfToImageQueue(self._redis, self._environment)
73
74
  self.recommendations = RecommendationQueue(self._redis, self._environment)
74
75
  self.document_upload = DocumentUploadQueue(self._redis, self._environment)
76
+ self.document_notes = DocumentNotesQueue(self._redis, self._environment)
75
77
  self.document_persist = DocumentPersistQueue(self._redis, self._environment)
76
78
  self.prompt_ingest = PromptIngestQueue(self._redis, self._environment)
77
79
  self.query = QueryClient(self._redis)
@@ -0,0 +1,95 @@
1
+ """Document Notes queue for note generation after clustering."""
2
+
3
+ from typing import Any, Optional
4
+
5
+ import redis as redis_lib
6
+
7
+ from queue_sdk.queues.base_queue import BaseQueue
8
+ from queue_sdk.types import SendResult
9
+
10
+
11
+ class DocumentNotesQueue(BaseQueue):
12
+ """Typed methods for enqueueing note generation jobs.
13
+
14
+ Queue 1 (cluster) enqueues these automatically after clustering
15
+ completes. The notes queue generates notes, persists materials,
16
+ and sends the callback to the frontend.
17
+ """
18
+
19
+ def __init__(self, redis_client: redis_lib.Redis, environment: str):
20
+ super().__init__(redis_client, environment, "document-notes")
21
+
22
+ def send(
23
+ self,
24
+ uploaded_file_id: str,
25
+ study_set_id: str,
26
+ user_id: str,
27
+ stash_key: str,
28
+ is_deferred: bool = False,
29
+ generate_notes: bool = True,
30
+ callback_url: Optional[str] = None,
31
+ callback_api_key: Optional[str] = None,
32
+ folder_id: Optional[str] = None,
33
+ ) -> SendResult:
34
+ """Enqueue a note generation request."""
35
+ self._validate(uploaded_file_id, study_set_id, user_id, stash_key)
36
+ payload = self._build_payload(
37
+ uploaded_file_id=uploaded_file_id,
38
+ study_set_id=study_set_id,
39
+ user_id=user_id,
40
+ stash_key=stash_key,
41
+ is_deferred=is_deferred,
42
+ generate_notes=generate_notes,
43
+ callback_url=callback_url,
44
+ callback_api_key=callback_api_key,
45
+ folder_id=folder_id,
46
+ )
47
+ message_id = self._enqueue(payload)
48
+
49
+ return SendResult(message_id=message_id)
50
+
51
+ @staticmethod
52
+ def _build_payload(
53
+ uploaded_file_id: str,
54
+ study_set_id: str,
55
+ user_id: str,
56
+ stash_key: str,
57
+ is_deferred: bool,
58
+ generate_notes: bool,
59
+ callback_url: Optional[str],
60
+ callback_api_key: Optional[str],
61
+ folder_id: Optional[str],
62
+ ) -> dict[str, Any]:
63
+ payload: dict[str, Any] = {
64
+ "uploadedFileId": uploaded_file_id,
65
+ "studySetId": study_set_id,
66
+ "userId": user_id,
67
+ "stashKey": stash_key,
68
+ "isDeferred": is_deferred,
69
+ "generateNotes": generate_notes,
70
+ }
71
+
72
+ if callback_url is not None:
73
+ payload["callbackUrl"] = callback_url
74
+ if callback_api_key is not None:
75
+ payload["callbackApiKey"] = callback_api_key
76
+ if folder_id is not None:
77
+ payload["folderId"] = folder_id
78
+
79
+ return payload
80
+
81
+ @staticmethod
82
+ def _validate(
83
+ uploaded_file_id: str,
84
+ study_set_id: str,
85
+ user_id: str,
86
+ stash_key: str,
87
+ ) -> None:
88
+ if not uploaded_file_id:
89
+ raise ValueError("uploaded_file_id is required")
90
+ if not study_set_id:
91
+ raise ValueError("study_set_id is required")
92
+ if not user_id:
93
+ raise ValueError("user_id is required")
94
+ if not stash_key:
95
+ raise ValueError("stash_key is required")
@@ -50,6 +50,7 @@ class DocumentUploadQueue(BaseQueue):
50
50
  callback_url: Optional[str] = None,
51
51
  callback_api_key: Optional[str] = None,
52
52
  study_plan_hook: Optional[bool] = None,
53
+ skip_material_creation: Optional[bool] = None,
53
54
  ) -> SendResult:
54
55
  """Enqueue a document upload processing request (fire and forget)."""
55
56
  self._validate(uploaded_file_id, study_set_id, user_id, pdf_s3_key, filename)
@@ -84,6 +85,7 @@ class DocumentUploadQueue(BaseQueue):
84
85
  callback_url=callback_url,
85
86
  callback_api_key=callback_api_key,
86
87
  study_plan_hook=study_plan_hook,
88
+ skip_material_creation=skip_material_creation,
87
89
  )
88
90
  message_id = self._enqueue(payload)
89
91
  self._set_initial_status(message_id)
@@ -168,6 +170,7 @@ class DocumentUploadQueue(BaseQueue):
168
170
  callback_url: Optional[str],
169
171
  callback_api_key: Optional[str],
170
172
  study_plan_hook: Optional[bool],
173
+ skip_material_creation: Optional[bool],
171
174
  ) -> dict[str, Any]:
172
175
  """Build the document upload payload (snake_case -> camelCase)."""
173
176
  payload: dict[str, Any] = {
@@ -217,6 +220,8 @@ class DocumentUploadQueue(BaseQueue):
217
220
  payload["callbackApiKey"] = callback_api_key
218
221
  if study_plan_hook is not None:
219
222
  payload["studyPlanHook"] = study_plan_hook
223
+ if skip_material_creation is not None:
224
+ payload["skipMaterialCreation"] = skip_material_creation
220
225
 
221
226
  return payload
222
227
 
@@ -268,9 +268,24 @@ class PromptIngestResponse:
268
268
  processed_at: Optional[str] = None
269
269
 
270
270
 
271
+ @dataclass
272
+ class DocumentNotesData:
273
+ """Data for a note generation request after clustering."""
274
+
275
+ uploaded_file_id: str
276
+ study_set_id: str
277
+ user_id: str
278
+ stash_key: str
279
+ is_deferred: bool = False
280
+ generate_notes: bool = True
281
+ callback_url: Optional[str] = None
282
+ callback_api_key: Optional[str] = None
283
+ folder_id: Optional[str] = None
284
+
285
+
271
286
  @dataclass
272
287
  class DocumentPersistData:
273
- """Data for a deferred note generation + persistence request."""
288
+ """Data for a topic-linking request after approval."""
274
289
 
275
290
  uploaded_file_id: str
276
291
  study_set_id: str