lightningrod-ai 0.1.6__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.
Files changed (123) hide show
  1. lightningrod/__init__.py +66 -0
  2. lightningrod/_display.py +204 -0
  3. lightningrod/_errors.py +67 -0
  4. lightningrod/_generated/__init__.py +8 -0
  5. lightningrod/_generated/api/__init__.py +1 -0
  6. lightningrod/_generated/api/datasets/__init__.py +1 -0
  7. lightningrod/_generated/api/datasets/create_dataset_datasets_post.py +133 -0
  8. lightningrod/_generated/api/datasets/get_dataset_datasets_dataset_id_get.py +168 -0
  9. lightningrod/_generated/api/datasets/get_dataset_samples_datasets_dataset_id_samples_get.py +209 -0
  10. lightningrod/_generated/api/datasets/upload_samples_datasets_dataset_id_samples_post.py +190 -0
  11. lightningrod/_generated/api/file_sets/__init__.py +1 -0
  12. lightningrod/_generated/api/file_sets/add_file_to_set_filesets_file_set_id_files_post.py +190 -0
  13. lightningrod/_generated/api/file_sets/create_file_set_filesets_post.py +174 -0
  14. lightningrod/_generated/api/file_sets/get_file_set_filesets_file_set_id_get.py +168 -0
  15. lightningrod/_generated/api/file_sets/list_file_sets_filesets_get.py +173 -0
  16. lightningrod/_generated/api/file_sets/list_files_in_set_filesets_file_set_id_files_get.py +209 -0
  17. lightningrod/_generated/api/files/__init__.py +1 -0
  18. lightningrod/_generated/api/files/create_file_upload_files_post.py +174 -0
  19. lightningrod/_generated/api/open_ai_compatible/__init__.py +1 -0
  20. lightningrod/_generated/api/open_ai_compatible/chat_completions_openai_chat_completions_post.py +174 -0
  21. lightningrod/_generated/api/organizations/__init__.py +1 -0
  22. lightningrod/_generated/api/organizations/get_balance_organizations_balance_get.py +131 -0
  23. lightningrod/_generated/api/samples/__init__.py +1 -0
  24. lightningrod/_generated/api/samples/validate_sample_samples_validate_post.py +174 -0
  25. lightningrod/_generated/api/transform_jobs/__init__.py +1 -0
  26. lightningrod/_generated/api/transform_jobs/cost_estimation_transform_jobs_cost_estimation_post.py +174 -0
  27. lightningrod/_generated/api/transform_jobs/create_transform_job_transform_jobs_post.py +174 -0
  28. lightningrod/_generated/api/transform_jobs/get_transform_job_metrics_transform_jobs_job_id_metrics_get.py +172 -0
  29. lightningrod/_generated/api/transform_jobs/get_transform_job_transform_jobs_job_id_get.py +168 -0
  30. lightningrod/_generated/client.py +268 -0
  31. lightningrod/_generated/errors.py +16 -0
  32. lightningrod/_generated/models/__init__.py +147 -0
  33. lightningrod/_generated/models/answer_type.py +129 -0
  34. lightningrod/_generated/models/answer_type_enum.py +11 -0
  35. lightningrod/_generated/models/balance_response.py +61 -0
  36. lightningrod/_generated/models/chat_completion_request.py +216 -0
  37. lightningrod/_generated/models/chat_completion_response.py +146 -0
  38. lightningrod/_generated/models/chat_message.py +69 -0
  39. lightningrod/_generated/models/choice.py +97 -0
  40. lightningrod/_generated/models/create_dataset_response.py +61 -0
  41. lightningrod/_generated/models/create_file_set_file_request.py +101 -0
  42. lightningrod/_generated/models/create_file_set_file_request_metadata_type_0.py +46 -0
  43. lightningrod/_generated/models/create_file_set_request.py +83 -0
  44. lightningrod/_generated/models/create_file_upload_request.py +91 -0
  45. lightningrod/_generated/models/create_file_upload_response.py +165 -0
  46. lightningrod/_generated/models/create_file_upload_response_metadata_type_0.py +46 -0
  47. lightningrod/_generated/models/create_transform_job_request.py +312 -0
  48. lightningrod/_generated/models/dataset_metadata.py +69 -0
  49. lightningrod/_generated/models/estimate_cost_request.py +243 -0
  50. lightningrod/_generated/models/estimate_cost_response.py +117 -0
  51. lightningrod/_generated/models/event_usage_summary.py +80 -0
  52. lightningrod/_generated/models/file_set.py +128 -0
  53. lightningrod/_generated/models/file_set_file.py +203 -0
  54. lightningrod/_generated/models/file_set_file_metadata_type_0.py +57 -0
  55. lightningrod/_generated/models/file_set_query_seed_generator.py +136 -0
  56. lightningrod/_generated/models/file_set_seed_generator.py +126 -0
  57. lightningrod/_generated/models/filter_criteria.py +83 -0
  58. lightningrod/_generated/models/forward_looking_question.py +130 -0
  59. lightningrod/_generated/models/forward_looking_question_generator.py +217 -0
  60. lightningrod/_generated/models/gdelt_seed_generator.py +103 -0
  61. lightningrod/_generated/models/http_validation_error.py +79 -0
  62. lightningrod/_generated/models/job_usage.py +185 -0
  63. lightningrod/_generated/models/job_usage_by_step_type_0.py +59 -0
  64. lightningrod/_generated/models/label.py +143 -0
  65. lightningrod/_generated/models/list_file_set_files_response.py +113 -0
  66. lightningrod/_generated/models/list_file_sets_response.py +75 -0
  67. lightningrod/_generated/models/llm_model_usage_summary.py +98 -0
  68. lightningrod/_generated/models/mock_transform_config.py +243 -0
  69. lightningrod/_generated/models/mock_transform_config_metadata_additions.py +46 -0
  70. lightningrod/_generated/models/model_config.py +316 -0
  71. lightningrod/_generated/models/model_source_type.py +16 -0
  72. lightningrod/_generated/models/news_context.py +82 -0
  73. lightningrod/_generated/models/news_context_generator.py +127 -0
  74. lightningrod/_generated/models/news_seed_generator.py +220 -0
  75. lightningrod/_generated/models/paginated_samples_response.py +113 -0
  76. lightningrod/_generated/models/pipeline_metrics_response.py +99 -0
  77. lightningrod/_generated/models/question.py +74 -0
  78. lightningrod/_generated/models/question_and_label_generator.py +217 -0
  79. lightningrod/_generated/models/question_generator.py +217 -0
  80. lightningrod/_generated/models/question_pipeline.py +417 -0
  81. lightningrod/_generated/models/question_renderer.py +123 -0
  82. lightningrod/_generated/models/rag_context.py +82 -0
  83. lightningrod/_generated/models/response_message.py +69 -0
  84. lightningrod/_generated/models/rollout.py +130 -0
  85. lightningrod/_generated/models/rollout_generator.py +139 -0
  86. lightningrod/_generated/models/rollout_parsed_output_type_0.py +46 -0
  87. lightningrod/_generated/models/sample.py +323 -0
  88. lightningrod/_generated/models/sample_meta.py +46 -0
  89. lightningrod/_generated/models/seed.py +135 -0
  90. lightningrod/_generated/models/step_cost_breakdown.py +109 -0
  91. lightningrod/_generated/models/transform_job.py +268 -0
  92. lightningrod/_generated/models/transform_job_status.py +11 -0
  93. lightningrod/_generated/models/transform_step_metrics_response.py +131 -0
  94. lightningrod/_generated/models/transform_type.py +25 -0
  95. lightningrod/_generated/models/upload_samples_request.py +75 -0
  96. lightningrod/_generated/models/upload_samples_response.py +69 -0
  97. lightningrod/_generated/models/usage.py +77 -0
  98. lightningrod/_generated/models/usage_summary.py +102 -0
  99. lightningrod/_generated/models/usage_summary_events.py +59 -0
  100. lightningrod/_generated/models/usage_summary_llm_by_model.py +59 -0
  101. lightningrod/_generated/models/validate_sample_response.py +69 -0
  102. lightningrod/_generated/models/validation_error.py +90 -0
  103. lightningrod/_generated/models/web_search_labeler.py +120 -0
  104. lightningrod/_generated/py.typed +1 -0
  105. lightningrod/_generated/types.py +54 -0
  106. lightningrod/client.py +48 -0
  107. lightningrod/datasets/__init__.py +4 -0
  108. lightningrod/datasets/client.py +174 -0
  109. lightningrod/datasets/dataset.py +255 -0
  110. lightningrod/files/__init__.py +0 -0
  111. lightningrod/files/client.py +58 -0
  112. lightningrod/filesets/__init__.py +0 -0
  113. lightningrod/filesets/client.py +106 -0
  114. lightningrod/organization/__init__.py +0 -0
  115. lightningrod/organization/client.py +17 -0
  116. lightningrod/py.typed +0 -0
  117. lightningrod/transforms/__init__.py +0 -0
  118. lightningrod/transforms/client.py +154 -0
  119. lightningrod_ai-0.1.6.dist-info/METADATA +122 -0
  120. lightningrod_ai-0.1.6.dist-info/RECORD +123 -0
  121. lightningrod_ai-0.1.6.dist-info/WHEEL +5 -0
  122. lightningrod_ai-0.1.6.dist-info/licenses/LICENSE +23 -0
  123. lightningrod_ai-0.1.6.dist-info/top_level.txt +1 -0
@@ -0,0 +1,58 @@
1
+ from pathlib import Path
2
+
3
+ import httpx
4
+
5
+ from lightningrod._generated.models import (
6
+ HTTPValidationError,
7
+ CreateFileUploadRequest,
8
+ CreateFileUploadResponse,
9
+ )
10
+ from lightningrod._generated.api.files import (
11
+ create_file_upload_files_post,
12
+ )
13
+ import mimetypes
14
+ from lightningrod._generated.client import AuthenticatedClient
15
+ from lightningrod._errors import handle_response_error
16
+
17
+ class FilesClient:
18
+ def __init__(self, client: AuthenticatedClient):
19
+ self._client: AuthenticatedClient = client
20
+
21
+ def upload(self, file_path: str | Path) -> CreateFileUploadResponse:
22
+ path = Path(file_path)
23
+ if not path.exists():
24
+ raise FileNotFoundError(f"File not found: {file_path}")
25
+
26
+ file_size: int = path.stat().st_size
27
+ mime_type, _ = mimetypes.guess_type(str(path))
28
+
29
+ request_body = CreateFileUploadRequest(
30
+ filename=path.name,
31
+ size_bytes=file_size,
32
+ mime_type=mime_type
33
+ )
34
+
35
+ response = create_file_upload_files_post.sync_detailed(
36
+ client=self._client,
37
+ body=request_body
38
+ )
39
+
40
+ parsed = handle_response_error(response, "get upload URL")
41
+
42
+ upload_headers: dict[str, str] = {
43
+ "Content-Length": str(file_size)
44
+ }
45
+ if parsed.mime_type:
46
+ upload_headers["Content-Type"] = parsed.mime_type
47
+
48
+ with httpx.Client() as http_client:
49
+ with open(path, "rb") as f:
50
+ upload_response = http_client.put(
51
+ parsed.upload_url,
52
+ content=f,
53
+ headers=upload_headers,
54
+ timeout=1800.0
55
+ )
56
+ upload_response.raise_for_status()
57
+
58
+ return parsed
File without changes
@@ -0,0 +1,106 @@
1
+ from pathlib import Path
2
+ from typing import Any, List, Optional
3
+
4
+ from lightningrod._generated.models import (
5
+ FileSet,
6
+ ListFileSetFilesResponse,
7
+ HTTPValidationError,
8
+ CreateFileSetRequest,
9
+ CreateFileSetFileRequest,
10
+ CreateFileSetFileRequestMetadataType0,
11
+ FileSetFile,
12
+ )
13
+ from lightningrod._generated.api.file_sets import (
14
+ create_file_set_filesets_post,
15
+ get_file_set_filesets_file_set_id_get,
16
+ list_file_sets_filesets_get,
17
+ add_file_to_set_filesets_file_set_id_files_post,
18
+ list_files_in_set_filesets_file_set_id_files_get,
19
+ )
20
+ from lightningrod._generated.client import AuthenticatedClient
21
+ from lightningrod.files.client import FilesClient
22
+ from lightningrod._errors import handle_response_error
23
+
24
+ class FileSetFilesClient:
25
+ def __init__(self, client: AuthenticatedClient, files_client: FilesClient):
26
+ self._client: AuthenticatedClient = client
27
+ self._files_client: FilesClient = files_client
28
+
29
+ def upload(
30
+ self,
31
+ file_set_id: str,
32
+ file_path: str | Path,
33
+ metadata: Optional[dict[str, Any]] = None
34
+ ) -> FileSetFile:
35
+ file = self._files_client.upload(file_path)
36
+ return self.add(file_set_id, file.id, metadata)
37
+
38
+ def add(
39
+ self,
40
+ file_set_id: str,
41
+ file_id: str,
42
+ metadata: Optional[dict[str, Any]] = None
43
+ ) -> FileSetFile:
44
+ request = CreateFileSetFileRequest(
45
+ file_id=file_id,
46
+ metadata=CreateFileSetFileRequestMetadataType0.from_dict(metadata) if metadata else None
47
+ )
48
+
49
+ response = add_file_to_set_filesets_file_set_id_files_post.sync_detailed(
50
+ file_set_id=file_set_id,
51
+ client=self._client,
52
+ body=request
53
+ )
54
+
55
+ return handle_response_error(response, "add file to set")
56
+
57
+ def list(
58
+ self,
59
+ file_set_id: str,
60
+ cursor: Optional[str] = None,
61
+ limit: int = 100
62
+ ) -> ListFileSetFilesResponse:
63
+ response = list_files_in_set_filesets_file_set_id_files_get.sync_detailed(
64
+ file_set_id=file_set_id,
65
+ client=self._client,
66
+ cursor=cursor if cursor else None,
67
+ limit=limit
68
+ )
69
+
70
+ return handle_response_error(response, "list files in set")
71
+
72
+
73
+ class FileSetsClient:
74
+ def __init__(self, client: AuthenticatedClient, files_client: FilesClient):
75
+ self._client = client
76
+ self.files = FileSetFilesClient(client, files_client)
77
+
78
+ def create(
79
+ self,
80
+ name: str,
81
+ description: Optional[str] = None
82
+ ) -> FileSet:
83
+ request = CreateFileSetRequest(name=name)
84
+ if description is not None:
85
+ request.description = description
86
+
87
+ response = create_file_set_filesets_post.sync_detailed(
88
+ client=self._client,
89
+ body=request
90
+ )
91
+
92
+ return handle_response_error(response, "create file set")
93
+
94
+ def get(self, file_set_id: str) -> FileSet:
95
+ response = get_file_set_filesets_file_set_id_get.sync_detailed(
96
+ file_set_id=file_set_id,
97
+ client=self._client
98
+ )
99
+
100
+ return handle_response_error(response, "get file set")
101
+
102
+ def list(self) -> List[FileSet]:
103
+ response = list_file_sets_filesets_get.sync_detailed(client=self._client)
104
+
105
+ parsed = handle_response_error(response, "list file sets")
106
+ return parsed.file_sets
File without changes
@@ -0,0 +1,17 @@
1
+ from lightningrod._generated.api.organizations import get_balance_organizations_balance_get
2
+ from lightningrod._generated.client import AuthenticatedClient
3
+ from lightningrod._generated.models.balance_response import BalanceResponse
4
+ from lightningrod._errors import handle_response_error
5
+
6
+
7
+ class OrganizationsClient:
8
+
9
+ def __init__(self, client: AuthenticatedClient):
10
+ self._client = client
11
+
12
+ def get_balance(self) -> float:
13
+ response = get_balance_organizations_balance_get.sync_detailed(
14
+ client=self._client,
15
+ )
16
+ parsed: BalanceResponse = handle_response_error(response, "get balance")
17
+ return parsed.balance_dollars
lightningrod/py.typed ADDED
File without changes
File without changes
@@ -0,0 +1,154 @@
1
+ from typing import Optional, Union
2
+
3
+ from lightningrod._display import display_error, display_warning, run_live_display
4
+ from lightningrod._generated.models import (
5
+ FileSetQuerySeedGenerator,
6
+ FileSetSeedGenerator,
7
+ ForwardLookingQuestionGenerator,
8
+ GdeltSeedGenerator,
9
+ NewsSeedGenerator,
10
+ QuestionAndLabelGenerator,
11
+ QuestionGenerator,
12
+ QuestionPipeline,
13
+ QuestionRenderer,
14
+ TransformJob,
15
+ TransformJobStatus,
16
+ CreateTransformJobRequest,
17
+ HTTPValidationError,
18
+ WebSearchLabeler,
19
+ EstimateCostRequest,
20
+ EstimateCostResponse,
21
+ )
22
+ from lightningrod._generated.api.datasets import (
23
+ get_dataset_datasets_dataset_id_get,
24
+ )
25
+ from lightningrod._generated.api.transform_jobs import (
26
+ create_transform_job_transform_jobs_post,
27
+ get_transform_job_transform_jobs_job_id_get,
28
+ get_transform_job_metrics_transform_jobs_job_id_metrics_get,
29
+ cost_estimation_transform_jobs_cost_estimation_post,
30
+ )
31
+ from lightningrod._generated.models.pipeline_metrics_response import PipelineMetricsResponse
32
+ from lightningrod.datasets.dataset import Dataset
33
+ from lightningrod._generated.client import AuthenticatedClient
34
+ from lightningrod.datasets.client import DatasetSamplesClient
35
+ from lightningrod._generated.types import Unset
36
+ from lightningrod._errors import handle_response_error
37
+
38
+ TransformConfig = Union[FileSetQuerySeedGenerator, FileSetSeedGenerator, ForwardLookingQuestionGenerator, GdeltSeedGenerator, NewsSeedGenerator, QuestionAndLabelGenerator, QuestionGenerator, QuestionPipeline, QuestionRenderer, WebSearchLabeler]
39
+
40
+ class TransformJobsClient:
41
+ def __init__(self, client: AuthenticatedClient):
42
+ self._client = client
43
+
44
+ def get(self, job_id: str) -> TransformJob:
45
+ response = get_transform_job_transform_jobs_job_id_get.sync_detailed(
46
+ job_id=job_id,
47
+ client=self._client,
48
+ )
49
+ return handle_response_error(response, "get transform job")
50
+
51
+ def get_metrics(self, job_id: str) -> Optional[PipelineMetricsResponse]:
52
+ """Fetch pipeline metrics. Returns None if not yet available (404) or on error."""
53
+ response = get_transform_job_metrics_transform_jobs_job_id_metrics_get.sync_detailed(
54
+ job_id=job_id,
55
+ client=self._client,
56
+ )
57
+ if isinstance(response.parsed, PipelineMetricsResponse):
58
+ return response.parsed
59
+ return None
60
+
61
+
62
+ class TransformsClient:
63
+ def __init__(self, client: AuthenticatedClient, dataset_samples_client: DatasetSamplesClient):
64
+ self._client: AuthenticatedClient = client
65
+ self._dataset_samples_client: DatasetSamplesClient = dataset_samples_client
66
+ self.jobs = TransformJobsClient(client)
67
+
68
+ def run(
69
+ self,
70
+ config: TransformConfig,
71
+ input_dataset: Optional[Union[Dataset, str]] = None,
72
+ max_questions: Optional[int] = None,
73
+ max_cost_dollars: Optional[float] = None
74
+ ) -> Dataset:
75
+ job: TransformJob = self.submit(config, input_dataset, max_questions, max_cost_dollars)
76
+
77
+ # Save the warning message before polling overwrites the job object
78
+ warning_message = job.warning_message if (not isinstance(job.warning_message, Unset) and job.warning_message is not None) else None
79
+
80
+ def poll():
81
+ nonlocal job
82
+ job = self.jobs.get(job.id)
83
+ metrics = self.jobs.get_metrics(job.id)
84
+ return metrics, job, job.status == TransformJobStatus.RUNNING
85
+
86
+ run_live_display(poll, poll_interval=15, warning_message=warning_message)
87
+
88
+ if job.status == TransformJobStatus.FAILED:
89
+ error_msg = job.error_message if (not isinstance(job.error_message, Unset) and job.error_message) else "Unknown error"
90
+ display_error(error_msg, title="Job Failed", job=job)
91
+ raise Exception(f"Transform job {job.id} failed: {error_msg}")
92
+
93
+ if job.status == TransformJobStatus.COMPLETED:
94
+ if job.output_dataset_id is None:
95
+ raise Exception(f"Transform job {job.id} completed but has no output dataset")
96
+
97
+ dataset_response = get_dataset_datasets_dataset_id_get.sync_detailed(
98
+ dataset_id=job.output_dataset_id,
99
+ client=self._client,
100
+ )
101
+ dataset_result = handle_response_error(dataset_response, "get dataset")
102
+
103
+ return Dataset(
104
+ id=dataset_result.id,
105
+ num_rows=dataset_result.num_rows,
106
+ datasets_client=self._dataset_samples_client
107
+ )
108
+
109
+ raise Exception(f"Unexpected job status: {job.status}")
110
+
111
+ def submit(
112
+ self,
113
+ config: TransformConfig,
114
+ input_dataset: Optional[Union[Dataset, str]] = None,
115
+ max_questions: Optional[int] = None,
116
+ max_cost_dollars: Optional[float] = None
117
+ ) -> TransformJob:
118
+ dataset_id: Optional[str] = None
119
+ if isinstance(input_dataset, Dataset):
120
+ dataset_id = input_dataset.id
121
+ elif isinstance(input_dataset, str):
122
+ dataset_id = input_dataset
123
+ request: CreateTransformJobRequest = CreateTransformJobRequest(
124
+ config=config,
125
+ input_dataset_id=dataset_id,
126
+ max_questions=max_questions,
127
+ max_cost_dollars=max_cost_dollars,
128
+ )
129
+
130
+ response = create_transform_job_transform_jobs_post.sync_detailed(
131
+ client=self._client,
132
+ body=request,
133
+ )
134
+
135
+ job: TransformJob = handle_response_error(response, "submit transform job")
136
+
137
+ if not isinstance(job.error_message, Unset) and job.error_message is not None:
138
+ display_error(job.error_message, title="Error", job=job)
139
+ raise Exception(f"Transform job {job.id} error: {job.error_message}")
140
+ if not isinstance(job.warning_message, Unset) and job.warning_message is not None:
141
+ display_warning(job.warning_message)
142
+
143
+ return job
144
+
145
+ def estimate_cost(self, config: TransformConfig, max_questions: Optional[int] = None) -> float:
146
+ response = cost_estimation_transform_jobs_cost_estimation_post.sync_detailed(
147
+ client=self._client,
148
+ body=EstimateCostRequest(
149
+ config=config,
150
+ max_questions=max_questions,
151
+ ),
152
+ )
153
+ parsed: EstimateCostResponse = handle_response_error(response, "estimate cost")
154
+ return parsed.total_cost_dollars
@@ -0,0 +1,122 @@
1
+ Metadata-Version: 2.4
2
+ Name: lightningrod-ai
3
+ Version: 0.1.6
4
+ Summary: Python SDK for Lightning Rod AI-powered forecasting dataset generation
5
+ Author-email: Lightning Rod Labs <support@lightningrod.ai>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2025 Lightning Rod Labs
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+
29
+
30
+ Project-URL: Homepage, https://lightningrod.ai/sdk
31
+ Project-URL: Repository, https://github.com/lightning-rod-labs/lightningrod-python-sdk
32
+ Requires-Python: >=3.10
33
+ Description-Content-Type: text/markdown
34
+ License-File: LICENSE
35
+ Requires-Dist: requests>=2.31.0
36
+ Requires-Dist: pydantic>=2.0.0
37
+ Requires-Dist: httpx>=0.25.0
38
+ Requires-Dist: attrs>=23.1.0
39
+ Requires-Dist: python-dateutil>=2.8.0
40
+ Requires-Dist: pyarrow>=14.0.0
41
+ Requires-Dist: fsspec>=2023.0.0
42
+ Requires-Dist: rich>=13.0.0
43
+ Provides-Extra: dev
44
+ Requires-Dist: openapi-python-client>=0.15.0; extra == "dev"
45
+ Dynamic: license-file
46
+
47
+ <div align="center">
48
+ <!-- Note: only an absolute image URL works on PyPi: https://pypi.org/project/lightningrod-ai -->
49
+ <img src="https://github.com/lightning-rod-labs/lightningrod-python-sdk/blob/main/banner.png?raw=true" alt="Lightning Rod Labs" />
50
+ </div>
51
+
52
+ # Lightning Rod Python SDK [![Beta](https://img.shields.io/badge/beta-0.1.6-orange)](https://pypi.org/project/lightningrod-ai/0.1.6/)
53
+
54
+ The Lightning Rod SDK provides a simple Python API for generating custom forecasting datasets to train your LLMs. Transform news articles, documents, and other real-world data into high-quality training samples automatically.
55
+
56
+ Based on our research: [Future-as-Label: Scalable Supervision from Real-World Outcomes](https://arxiv.org/abs/2601.06336)
57
+
58
+ ## 👋 Quick Start
59
+
60
+ ### 1. Install the SDK
61
+
62
+ ```bash
63
+ pip install lightningrod-ai
64
+ ```
65
+
66
+ ### 2. Get your API key
67
+
68
+ Sign up at [dashboard.lightningrod.ai](https://dashboard.lightningrod.ai/?redirect=/api) to get your API key and **$50 of free credits**.
69
+
70
+ ### 3. Generate your first dataset
71
+
72
+ Generate **1000+ forecasting questions in minutes** - from raw sources to labeled dataset, automatically. ⚡
73
+
74
+ ```python
75
+ from lightningrod import LightningRod, AnswerType, QuestionPipeline, NewsSeedGenerator, ForwardLookingQuestionGenerator, WebSearchLabeler
76
+
77
+ lr = LightningRod(api_key="your-api-key")
78
+
79
+ binary_answer = AnswerType(answer_type=AnswerTypeEnum.BINARY)
80
+
81
+ pipeline = QuestionPipeline(
82
+ seed_generator=NewsSeedGenerator(
83
+ start_date=datetime.now() - timedelta(days=90),
84
+ end_date=datetime.now(),
85
+ search_query=["Trump"],
86
+ ),
87
+ question_generator=ForwardLookingQuestionGenerator(
88
+ instructions="Generate binary forecasting questions about Trump's actions and decisions.",
89
+ examples=[
90
+ "Will Trump impose 25% tariffs on all goods from Canada by February 1, 2025?",
91
+ "Will Pete Hegseth be confirmed as Secretary of Defense by February 15, 2025?",
92
+ ]
93
+ ),
94
+ labeler=WebSearchLabeler(answer_type=binary_answer),
95
+ )
96
+
97
+ dataset = lr.transforms.run(pipeline, max_questions=3000)
98
+ dataset.flattened() # Ready-to-use data for your training pipelines
99
+ ```
100
+
101
+ **We use this to generate the [Future-as-Label training dataset](https://huggingface.co/datasets/LightningRodLabs/future-as-label-paper-training-dataset) for our research paper.**
102
+
103
+ ## ✨ Examples
104
+
105
+ We have some example notebooks to help you get started! If you have trouble using the SDK, please submit an issue on Github.
106
+
107
+ | Example Name | Path | Google Colab Link |
108
+ |--------------|------|-------------------|
109
+ | Quick Start | `notebooks/01_quick_start.ipynb` | [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/lightning-rod-labs/lightningrod-python-sdk/blob/main/notebooks/01_quick_start.ipynb) |
110
+ | News Datasource | `notebooks/02_news_datasource.ipynb` | [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/lightning-rod-labs/lightningrod-python-sdk/blob/main/notebooks/02_news_datasource.ipynb) |
111
+ | Custom Documents | `notebooks/03_custom_documents_datasource.ipynb` | [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/lightning-rod-labs/lightningrod-python-sdk/blob/main/notebooks/03_custom_documents_datasource.ipynb) |
112
+ | Binary Answer Type | `notebooks/04_binary_answer_type.ipynb` | [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/lightning-rod-labs/lightningrod-python-sdk/blob/main/notebooks/04_binary_answer_type.ipynb) |
113
+ | Continuous Answer Type | `notebooks/05_continuous_answer_type.ipynb` | [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/lightning-rod-labs/lightningrod-python-sdk/blob/main/notebooks/05_continuous_answer_type.ipynb) |
114
+ | Multiple Choice Answer Type | `notebooks/06_multiple_choice_answer_type.ipynb` | [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/lightning-rod-labs/lightningrod-python-sdk/blob/main/notebooks/06_multiple_choice_answer_type.ipynb) |
115
+ | Free Response Answer Type | `notebooks/07_free_response_answer_type.ipynb` | [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/lightning-rod-labs/lightningrod-python-sdk/blob/main/notebooks/07_free_response_answer_type.ipynb) |
116
+
117
+
118
+ For complete API reference documentation, see [API.md](API.md). This includes overview of the core system concepts, methods and types.
119
+
120
+ ## License
121
+
122
+ MIT License - see LICENSE file for details
@@ -0,0 +1,123 @@
1
+ lightningrod/__init__.py,sha256=m--GzbDI8R4J7q4ljR0jGoz3wV85mJkeomBJdADu5-I,1594
2
+ lightningrod/_display.py,sha256=zkTv6XvNdOfYoabwczzw9UtgHAlGanFjnu3yMgVoEjY,6862
3
+ lightningrod/_errors.py,sha256=-a0HW-Tf3Q7CGZAWN2JUC39xbpw21JU9jPLbA-Oter0,2584
4
+ lightningrod/client.py,sha256=iBKIY-cpbDHVKgi1_MdWn-rs9xW-pAqZzzlqPNCE9iQ,2002
5
+ lightningrod/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ lightningrod/_generated/__init__.py,sha256=jFzSKbyPsPcdGmeuJ201Z7y-GWvrbNweFZR-IIClIGg,159
7
+ lightningrod/_generated/client.py,sha256=-rT3epMc77Y7QMTy5o1oH5hkGLufY9qFrD1rb7qItFU,12384
8
+ lightningrod/_generated/errors.py,sha256=gO8GBmKqmSNgAg-E5oT-oOyxztvp7V_6XG7OUTT15q0,546
9
+ lightningrod/_generated/py.typed,sha256=8ZJUsxZiuOy1oJeVhsTWQhTG_6pTVHVXk5hJL79ebTk,25
10
+ lightningrod/_generated/types.py,sha256=0We4NPvhIYASRpQ3le41nmJeEAVm42-2VKdzlJ4Ogok,1343
11
+ lightningrod/_generated/api/__init__.py,sha256=zTSiG_ujSjAqWPyc435YXaX9XTlpMjiJWBbV-f-YtdA,45
12
+ lightningrod/_generated/api/datasets/__init__.py,sha256=5vd9uJWAjRqa9xzxzYkLD1yoZ12Ld_bAaNB5WX4fbE8,56
13
+ lightningrod/_generated/api/datasets/create_dataset_datasets_post.py,sha256=nnRAf6aKYhIWn2DSvs_H1FFB2gUX6zNy-3sKnY3SAeo,3364
14
+ lightningrod/_generated/api/datasets/get_dataset_datasets_dataset_id_get.py,sha256=EoxLfcgews7gcEjQNGz_qzf2UrkfklDmirQGGYVXB7k,4292
15
+ lightningrod/_generated/api/datasets/get_dataset_samples_datasets_dataset_id_samples_get.py,sha256=miVF-7zo75c0eiyQtJ2BhSyzp7eeyaVRFmQ4Juvayuw,5715
16
+ lightningrod/_generated/api/datasets/upload_samples_datasets_dataset_id_samples_post.py,sha256=08ahg8D4CIyBFLVxEf_BCofTETTJVdq76AHw4sJvrHI,4928
17
+ lightningrod/_generated/api/file_sets/__init__.py,sha256=5vd9uJWAjRqa9xzxzYkLD1yoZ12Ld_bAaNB5WX4fbE8,56
18
+ lightningrod/_generated/api/file_sets/add_file_to_set_filesets_file_set_id_files_post.py,sha256=wLkItO5IEXscNEcc0Gl1XzHTMyVUMh-4yFIj8pdNTWo,5026
19
+ lightningrod/_generated/api/file_sets/create_file_set_filesets_post.py,sha256=oAC-lwkOswz0Zk8N8RZR2bhgcvGeSlhbGMguXlI0bn8,4348
20
+ lightningrod/_generated/api/file_sets/get_file_set_filesets_file_set_id_get.py,sha256=IZP_d3LUxOBYSbB8OlAQkSeIGbsgdG-hLRG2RZqOwH8,4140
21
+ lightningrod/_generated/api/file_sets/list_file_sets_filesets_get.py,sha256=-Sh-KpZofBZFefa82FSrF2cWoITxHEGqJnkmE3lS0Bg,4934
22
+ lightningrod/_generated/api/file_sets/list_files_in_set_filesets_file_set_id_files_get.py,sha256=VCph7m5-wWMdSgz85I7dCfMTEMO2_RQDTmPaxPEGQgw,5601
23
+ lightningrod/_generated/api/files/__init__.py,sha256=5vd9uJWAjRqa9xzxzYkLD1yoZ12Ld_bAaNB5WX4fbE8,56
24
+ lightningrod/_generated/api/files/create_file_upload_files_post.py,sha256=lxQKnaYYuiklpkB1hY2C7TSHimf408zHkT_7rrE_bHg,4624
25
+ lightningrod/_generated/api/open_ai_compatible/__init__.py,sha256=5vd9uJWAjRqa9xzxzYkLD1yoZ12Ld_bAaNB5WX4fbE8,56
26
+ lightningrod/_generated/api/open_ai_compatible/chat_completions_openai_chat_completions_post.py,sha256=Mr7d5K96artn665JYZaFMHxivZViRNAeJ_HRbdazcaI,4764
27
+ lightningrod/_generated/api/organizations/__init__.py,sha256=5vd9uJWAjRqa9xzxzYkLD1yoZ12Ld_bAaNB5WX4fbE8,56
28
+ lightningrod/_generated/api/organizations/get_balance_organizations_balance_get.py,sha256=mR6U2Vii_1NZzegQ4ZhpcWouBCvUSX6r3OAXrcRLh7g,3379
29
+ lightningrod/_generated/api/samples/__init__.py,sha256=5vd9uJWAjRqa9xzxzYkLD1yoZ12Ld_bAaNB5WX4fbE8,56
30
+ lightningrod/_generated/api/samples/validate_sample_samples_validate_post.py,sha256=hlG30JrHJ0giOqApjN9L8JSaXncAubNxdMM9pv3ekiA,4398
31
+ lightningrod/_generated/api/transform_jobs/__init__.py,sha256=5vd9uJWAjRqa9xzxzYkLD1yoZ12Ld_bAaNB5WX4fbE8,56
32
+ lightningrod/_generated/api/transform_jobs/cost_estimation_transform_jobs_cost_estimation_post.py,sha256=ATOyYOP4h5TzAscwZBvMe6ZJKNavVpvLNr-sHgCn3zg,4591
33
+ lightningrod/_generated/api/transform_jobs/create_transform_job_transform_jobs_post.py,sha256=yW6IyX8iyc0aBjeoN8mW-jgvLjZDCSl5odhsqCBnBSU,4429
34
+ lightningrod/_generated/api/transform_jobs/get_transform_job_metrics_transform_jobs_job_id_metrics_get.py,sha256=EOhi3zHuf31CTtXWOB576MO-iiXSXKoTW5E1utqfOGQ,4529
35
+ lightningrod/_generated/api/transform_jobs/get_transform_job_transform_jobs_job_id_get.py,sha256=UydMUJD_CntufK1a8uJ6a9-JstyMu-j-k9LS_1OxkVQ,4115
36
+ lightningrod/_generated/models/__init__.py,sha256=y_rYQAIZwGc1iZjpTlXaLmqG-Gneli3jrPdiJGarsrw,5623
37
+ lightningrod/_generated/models/answer_type.py,sha256=JEvrzITGDqwf28yl7F6vmVnTRqkMMhmgh_pZ2z7KXQU,4827
38
+ lightningrod/_generated/models/answer_type_enum.py,sha256=_8nR5gK6cPJpj3IX15qVEJ-0kJW2e7YjBvBtUt2BkTA,247
39
+ lightningrod/_generated/models/balance_response.py,sha256=CWD8gZ4JTe6mYZ2mePG747ufgeyisy4BfygS_eLtL5w,1607
40
+ lightningrod/_generated/models/chat_completion_request.py,sha256=WqXeC3ViEk0MJwFmEEu4I0aXsDknNu4I0K8hCp_u7hs,6792
41
+ lightningrod/_generated/models/chat_completion_response.py,sha256=ePzrsB2fYYCESmirTSitsK0Z1eTleW5MmFd_qYasMtM,4380
42
+ lightningrod/_generated/models/chat_message.py,sha256=XaXjfz15uwQwvu9ky5FUoiF4D82JCDEn5XOs2oOT7xs,1733
43
+ lightningrod/_generated/models/choice.py,sha256=9JRch2Vc8Os3ctyF1vvdbIjFZsK_lHS4LJDVFYBtslg,2694
44
+ lightningrod/_generated/models/create_dataset_response.py,sha256=Df5qm7DqpXcXFvMtvcKJXxILNgMSp2jZb1OD6PaZ3ts,1506
45
+ lightningrod/_generated/models/create_file_set_file_request.py,sha256=aVfd9K5zS4PQXOH8xPBsFfv3jIhGv6mTqP_t8SFuowA,3281
46
+ lightningrod/_generated/models/create_file_set_file_request_metadata_type_0.py,sha256=RsNzjzA5qx64Pa1dm72qXZajkm1l9j6GOAHfF2GD03A,1384
47
+ lightningrod/_generated/models/create_file_set_request.py,sha256=72k6SPBOrIh2ovJIYDVYC9DrhZMFZMgqZa6JKj87-N8,2351
48
+ lightningrod/_generated/models/create_file_upload_request.py,sha256=W14oVfEqlhn15nsDM_gwK519j1heKLkM4IqXRG7rBaU,2554
49
+ lightningrod/_generated/models/create_file_upload_response.py,sha256=MaYsEMnWx5oODHZ33aaXJ3uJ00kYqcoXBKDMfAR2R2A,5213
50
+ lightningrod/_generated/models/create_file_upload_response_metadata_type_0.py,sha256=TxSj7AVfWjK5ViTbV-33g6rlvktU8B4C0FoxGz_4GQg,1381
51
+ lightningrod/_generated/models/create_transform_job_request.py,sha256=4MV7A8DlS7Ps0himDhni0D4eck6iHS9G5YDVfPTAXvU,12847
52
+ lightningrod/_generated/models/dataset_metadata.py,sha256=DHg4lBYOTrtkuKK8EyyisPsxiMoLjB_CJdZHDPuw4Tg,1656
53
+ lightningrod/_generated/models/estimate_cost_request.py,sha256=uwM0xXtCkEtclgTlLW8yCF6BiYKPjhm4iXU4uL-SrjE,10020
54
+ lightningrod/_generated/models/estimate_cost_response.py,sha256=bDLckyxuwqjZGXmLugI5UFe7IWc6YCEcwdY8YRt3vp8,3643
55
+ lightningrod/_generated/models/event_usage_summary.py,sha256=xswYrrND-5OlULlsA-j6CSFPSOUwoaipmbse_YYX2QI,2163
56
+ lightningrod/_generated/models/file_set.py,sha256=7wT8r1s7Fm0eU5ny3yueQUaVt9Coo2YNrwidQ8_B0k0,3386
57
+ lightningrod/_generated/models/file_set_file.py,sha256=SiAg6BV3BZ4j-RbD58-nhGBpfAq4P6OpWLtA7uJe7Sk,6412
58
+ lightningrod/_generated/models/file_set_file_metadata_type_0.py,sha256=qFW2BN8N_57xYGa7FiCar550Emw746t61bG39IqLsqY,1827
59
+ lightningrod/_generated/models/file_set_query_seed_generator.py,sha256=ISqMBmCSGkut9-u0dGZlpOloFIJ5nqGsLMfUQqDwLfA,5007
60
+ lightningrod/_generated/models/file_set_seed_generator.py,sha256=oSvEDU3kFf-Nh5-jIbJDCpJ8KnW7jT_KPi1lYsvvl7A,4520
61
+ lightningrod/_generated/models/filter_criteria.py,sha256=L_dHLbjoQ8zsTpoxOwCNilwHKigNyZbdFD1Ga6kFVEc,2376
62
+ lightningrod/_generated/models/forward_looking_question.py,sha256=F-_1fcMMhZw4q69NzXB7Q2H_ocAKUMJ-1FMnOAScYic,4467
63
+ lightningrod/_generated/models/forward_looking_question_generator.py,sha256=WwfyyPQUmPoEUw00E1M38BxWkComyI0S1WFMP5NnA7Q,8457
64
+ lightningrod/_generated/models/gdelt_seed_generator.py,sha256=pt5k3ah2mvtLmFzrMvG8I6zhZGOZL6NxC27XmitWEJc,3609
65
+ lightningrod/_generated/models/http_validation_error.py,sha256=ceDDkSqsvFmTdFwrra6lwo-L-BAHNX8h8bwaKyxPkEk,2317
66
+ lightningrod/_generated/models/job_usage.py,sha256=shYwf_Pqe56nvl8QwpecK56xSjHoeyUxOS4XREntxrw,6514
67
+ lightningrod/_generated/models/job_usage_by_step_type_0.py,sha256=7ydjDhI2Kgk2SuAx1Bnx8i5qLyRlq0SCKCDQaxUyuU8,1762
68
+ lightningrod/_generated/models/label.py,sha256=KcNzAbPSojHEnhrsvFZEEcTpcuhED8n0SVPoX0FNasY,4485
69
+ lightningrod/_generated/models/list_file_set_files_response.py,sha256=i-ThbM4TkBcyiT96rdMxQ0rES6r-5IAAHG8zteomPDs,3094
70
+ lightningrod/_generated/models/list_file_sets_response.py,sha256=ZYoJZfl5eH31cTDo6xKG48h3im0FpzOyBrQvAPYNk7w,2046
71
+ lightningrod/_generated/models/llm_model_usage_summary.py,sha256=XY0jJo_-q3k5yZT95ntDD_kVcIMD-ap8U6HIewd4Szs,2809
72
+ lightningrod/_generated/models/mock_transform_config.py,sha256=Vw6sh0Ry19g-wN47_X9U_p3UuguNsRReua-aT81g_7s,9797
73
+ lightningrod/_generated/models/mock_transform_config_metadata_additions.py,sha256=g-M2Ay7SxXabw3yA2ltKpKt-avGg1zjC40KbTLctvTs,1389
74
+ lightningrod/_generated/models/model_config.py,sha256=1EC6T2DVFps_6I5tIVIb6XPd_53M3imTNmPzoAdPm1w,11828
75
+ lightningrod/_generated/models/model_source_type.py,sha256=lOTOmlimVdGkfFSfnkr1VLgyx9NxAe_R4k7z0vUZtfA,364
76
+ lightningrod/_generated/models/news_context.py,sha256=ShNxfoQn-Rb3n5HtrdoXxAAAYngu9YRaaltBS9Gjx6E,2462
77
+ lightningrod/_generated/models/news_context_generator.py,sha256=O12bLPki-lmmrqROGJk94WhW2mD4E_g07gYUuDXMxOw,4975
78
+ lightningrod/_generated/models/news_seed_generator.py,sha256=sGOjOYugx01Lk8am6AYfbUnSUGKoVXePMoHW5zBttU8,8547
79
+ lightningrod/_generated/models/paginated_samples_response.py,sha256=bXMJPABVpGuqHSLpn56sXFhrb0EeVxmejjx998Kc2SE,3093
80
+ lightningrod/_generated/models/pipeline_metrics_response.py,sha256=qj4v41drh2GOYz-slB1P-GD6XEQzzQjHD56aOgoh15Y,2984
81
+ lightningrod/_generated/models/question.py,sha256=4T93bqF0Cttvkji1XEuqEEenPzgUX9TC7rONH9G6i9Q,2178
82
+ lightningrod/_generated/models/question_and_label_generator.py,sha256=yl_EBSDQmQMBU3NBa2zTOLEelnMrY4SGLJql7kNtVNY,8385
83
+ lightningrod/_generated/models/question_generator.py,sha256=5zv7yowjKw7s34oyJBGVsMyhYL6oUbFp7emExhZpzEw,8269
84
+ lightningrod/_generated/models/question_pipeline.py,sha256=eD8ogjrC43Z9wcq0fgo8UWZPijhVmPN3PvENjlPvK1Y,18625
85
+ lightningrod/_generated/models/question_renderer.py,sha256=x-pE8h2nG2CVHg4ZN55GqgXqN84SK1HetD0VPuJZDjA,4287
86
+ lightningrod/_generated/models/rag_context.py,sha256=iP0jjPR8XndLPXhzJ4lQRlArYAwxLlB56-ypjf1frrg,2440
87
+ lightningrod/_generated/models/response_message.py,sha256=6c3e39BDt5azCDhhZxweuALIEejBeoHsJW8xNzMKYOI,1724
88
+ lightningrod/_generated/models/rollout.py,sha256=pVAy8mXA_no9Mc9SVYWkNxZZiUSX6iFjjq3qpgIHsME,3989
89
+ lightningrod/_generated/models/rollout_generator.py,sha256=lEzmQg-O3O3Jcx2Q_abENDoKaexnoqwBtHGaUvdAj3I,4793
90
+ lightningrod/_generated/models/rollout_parsed_output_type_0.py,sha256=EH9lCGib8M4n2F1G4hMeWEnSc2_ZFwkRj3KHN_HHZx4,1310
91
+ lightningrod/_generated/models/sample.py,sha256=9qrsOq7EuWymGHgjgcJAAgcWHaLIi0fpkqTvq7ZK2c8,11378
92
+ lightningrod/_generated/models/sample_meta.py,sha256=vTv4SitilY86P3Cbj-IdGZDnekw0mbw9VRxAAGhISOA,1231
93
+ lightningrod/_generated/models/seed.py,sha256=DkpzUIvoClbsP3AGZMHWcXrClZYNqOITIe3ONX_cL2o,4188
94
+ lightningrod/_generated/models/step_cost_breakdown.py,sha256=BKa1UMEuhGuE-1JNLh0jiVEabfng_B7b7ylWHznt7l0,3012
95
+ lightningrod/_generated/models/transform_job.py,sha256=j9DZbrjuZNAuLcnKcKgJkF6IZepaH7qi9frqzxMVpFY,8793
96
+ lightningrod/_generated/models/transform_job_status.py,sha256=q31k5DSM9LMl57DFtGeUkiGX0o8SaSEvYv5kU-PWVDE,225
97
+ lightningrod/_generated/models/transform_step_metrics_response.py,sha256=6jbdta-YZ4z-VyHPbvcAakPIqssPG1OnF1UduyLWlWE,3586
98
+ lightningrod/_generated/models/transform_type.py,sha256=1nfCqKee6NIJFs6xdbtL9OLkml1G5v9hjuZLEPiI76s,972
99
+ lightningrod/_generated/models/upload_samples_request.py,sha256=0U5K_sM30H2lHuR2c3-0YZsRMn95ZVUKTSM8EPkC2uE,1990
100
+ lightningrod/_generated/models/upload_samples_response.py,sha256=_8lve7Px9IF8lcjmO3Wrj6e8vWGM0-DEpHQm3aAWRus,1689
101
+ lightningrod/_generated/models/usage.py,sha256=0bxQ2P3Ha943iKC1hF8mUXWCfG1wp3lxVKkPD4SFvmI,2120
102
+ lightningrod/_generated/models/usage_summary.py,sha256=BG20LHPURyjsYIBpO20cglI0D4tl3XKGvaLsV6sauvM,3242
103
+ lightningrod/_generated/models/usage_summary_events.py,sha256=QiExGlPQH6218RWKLAaHUfj66OEVeqXVLjreR7dt9hU,1790
104
+ lightningrod/_generated/models/usage_summary_llm_by_model.py,sha256=F6vvce_Uy87h3GchXldIhHy5NS6szoP_tJBbceiDAj4,1842
105
+ lightningrod/_generated/models/validate_sample_response.py,sha256=_6-MUdSxjfGAoRXs32qz670Ma-RXcMGbbIIwpLSCg5A,1716
106
+ lightningrod/_generated/models/validation_error.py,sha256=n8d_ZobQV26pm0KyDAKvIo93uOBhz2BH59jpJAKwoPY,2180
107
+ lightningrod/_generated/models/web_search_labeler.py,sha256=VdvQWRPyduGTIHZnXinELFrQIUvMZlKu3A2SVuIlrK8,4310
108
+ lightningrod/datasets/__init__.py,sha256=9fFeVHOm5rIkqVmbuPacbECuu8A_NLxsW-jwLrCh-dw,223
109
+ lightningrod/datasets/client.py,sha256=1dmvmKSvjII7l9bCjbG9dlw1BEo2AM0KiSrxxd3X89k,5927
110
+ lightningrod/datasets/dataset.py,sha256=IRgpFoYiosEZ4L2VXxwBZWwkcG-cAZ0ElECfxOBJGgs,10584
111
+ lightningrod/files/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
112
+ lightningrod/files/client.py,sha256=hmvom3csB-EUqlciuBhsDLBPYNSxXr--HzY1nCdrvYI,1809
113
+ lightningrod/filesets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
114
+ lightningrod/filesets/client.py,sha256=ek4sFy2KmsdBETuXK8HbWPaOvOylfkTvcxQ3Z7t1FjA,3458
115
+ lightningrod/organization/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
116
+ lightningrod/organization/client.py,sha256=kWrz0ni1t0gHzEt0p0HaaxhX8zdWXyWHlbkybiQFpBI,670
117
+ lightningrod/transforms/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
118
+ lightningrod/transforms/client.py,sha256=i-evm0gfbIBGcNZ6fIsluhqe5Cl4lRBv15MTkYHGr4c,6447
119
+ lightningrod_ai-0.1.6.dist-info/licenses/LICENSE,sha256=2JERXI_r2IOXiM88NK3c8ca27RT09uWLyixybv46vGk,1077
120
+ lightningrod_ai-0.1.6.dist-info/METADATA,sha256=8WAqVq8Mp_w3H4oH2FpjBZ_fEZGVhN8de1oLjTlSaMw,6794
121
+ lightningrod_ai-0.1.6.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
122
+ lightningrod_ai-0.1.6.dist-info/top_level.txt,sha256=U344S1V_s96PAg6NBzFCgLNKP8bVq9OUnI5sm_DqiTo,13
123
+ lightningrod_ai-0.1.6.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.10.2)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,23 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Lightning Rod Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+
@@ -0,0 +1 @@
1
+ lightningrod