sdg-hub 0.1.4__py3-none-any.whl → 0.2.0__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 (139) hide show
  1. sdg_hub/__init__.py +28 -1
  2. sdg_hub/_version.py +2 -2
  3. sdg_hub/core/__init__.py +22 -0
  4. sdg_hub/core/blocks/__init__.py +58 -0
  5. sdg_hub/core/blocks/base.py +313 -0
  6. sdg_hub/core/blocks/deprecated_blocks/__init__.py +29 -0
  7. sdg_hub/core/blocks/deprecated_blocks/combine_columns.py +93 -0
  8. sdg_hub/core/blocks/deprecated_blocks/duplicate_columns.py +88 -0
  9. sdg_hub/core/blocks/deprecated_blocks/filter_by_value.py +103 -0
  10. sdg_hub/core/blocks/deprecated_blocks/flatten_columns.py +94 -0
  11. sdg_hub/core/blocks/deprecated_blocks/llmblock.py +479 -0
  12. sdg_hub/core/blocks/deprecated_blocks/rename_columns.py +88 -0
  13. sdg_hub/core/blocks/deprecated_blocks/sample_populator.py +58 -0
  14. sdg_hub/core/blocks/deprecated_blocks/selector.py +97 -0
  15. sdg_hub/core/blocks/deprecated_blocks/set_to_majority_value.py +88 -0
  16. sdg_hub/core/blocks/evaluation/__init__.py +9 -0
  17. sdg_hub/core/blocks/evaluation/evaluate_faithfulness_block.py +564 -0
  18. sdg_hub/core/blocks/evaluation/evaluate_relevancy_block.py +564 -0
  19. sdg_hub/core/blocks/evaluation/verify_question_block.py +564 -0
  20. sdg_hub/core/blocks/filtering/__init__.py +12 -0
  21. sdg_hub/core/blocks/filtering/column_value_filter.py +188 -0
  22. sdg_hub/core/blocks/llm/__init__.py +25 -0
  23. sdg_hub/core/blocks/llm/client_manager.py +398 -0
  24. sdg_hub/core/blocks/llm/config.py +336 -0
  25. sdg_hub/core/blocks/llm/error_handler.py +368 -0
  26. sdg_hub/core/blocks/llm/llm_chat_block.py +542 -0
  27. sdg_hub/core/blocks/llm/prompt_builder_block.py +368 -0
  28. sdg_hub/core/blocks/llm/text_parser_block.py +310 -0
  29. sdg_hub/core/blocks/registry.py +331 -0
  30. sdg_hub/core/blocks/transform/__init__.py +23 -0
  31. sdg_hub/core/blocks/transform/duplicate_columns.py +88 -0
  32. sdg_hub/core/blocks/transform/index_based_mapper.py +225 -0
  33. sdg_hub/core/blocks/transform/melt_columns.py +126 -0
  34. sdg_hub/core/blocks/transform/rename_columns.py +69 -0
  35. sdg_hub/core/blocks/transform/text_concat.py +102 -0
  36. sdg_hub/core/blocks/transform/uniform_col_val_setter.py +101 -0
  37. sdg_hub/core/flow/__init__.py +20 -0
  38. sdg_hub/core/flow/base.py +980 -0
  39. sdg_hub/core/flow/metadata.py +344 -0
  40. sdg_hub/core/flow/migration.py +187 -0
  41. sdg_hub/core/flow/registry.py +330 -0
  42. sdg_hub/core/flow/validation.py +265 -0
  43. sdg_hub/{utils → core/utils}/__init__.py +6 -4
  44. sdg_hub/{utils → core/utils}/datautils.py +1 -3
  45. sdg_hub/core/utils/error_handling.py +208 -0
  46. sdg_hub/{utils → core/utils}/path_resolution.py +2 -2
  47. sdg_hub/flows/qa_generation/document_grounded_qa/multi_summary_qa/instructlab/atomic_facts.yaml +40 -0
  48. sdg_hub/flows/qa_generation/document_grounded_qa/multi_summary_qa/instructlab/detailed_summary.yaml +13 -0
  49. sdg_hub/flows/qa_generation/document_grounded_qa/multi_summary_qa/instructlab/evaluate_faithfulness.yaml +64 -0
  50. sdg_hub/flows/qa_generation/document_grounded_qa/multi_summary_qa/instructlab/evaluate_question.yaml +29 -0
  51. sdg_hub/flows/qa_generation/document_grounded_qa/multi_summary_qa/instructlab/evaluate_relevancy.yaml +81 -0
  52. sdg_hub/flows/qa_generation/document_grounded_qa/multi_summary_qa/instructlab/extractive_summary.yaml +13 -0
  53. sdg_hub/flows/qa_generation/document_grounded_qa/multi_summary_qa/instructlab/flow.yaml +191 -0
  54. sdg_hub/flows/qa_generation/document_grounded_qa/multi_summary_qa/instructlab/generate_questions_responses.yaml +54 -0
  55. sdg_hub-0.2.0.dist-info/METADATA +218 -0
  56. sdg_hub-0.2.0.dist-info/RECORD +63 -0
  57. sdg_hub/blocks/__init__.py +0 -42
  58. sdg_hub/blocks/block.py +0 -96
  59. sdg_hub/blocks/llmblock.py +0 -375
  60. sdg_hub/blocks/openaichatblock.py +0 -556
  61. sdg_hub/blocks/utilblocks.py +0 -597
  62. sdg_hub/checkpointer.py +0 -139
  63. sdg_hub/configs/annotations/cot_reflection.yaml +0 -34
  64. sdg_hub/configs/annotations/detailed_annotations.yaml +0 -28
  65. sdg_hub/configs/annotations/detailed_description.yaml +0 -10
  66. sdg_hub/configs/annotations/detailed_description_icl.yaml +0 -32
  67. sdg_hub/configs/annotations/simple_annotations.yaml +0 -9
  68. sdg_hub/configs/knowledge/__init__.py +0 -0
  69. sdg_hub/configs/knowledge/atomic_facts.yaml +0 -46
  70. sdg_hub/configs/knowledge/auxilary_instructions.yaml +0 -35
  71. sdg_hub/configs/knowledge/detailed_summary.yaml +0 -18
  72. sdg_hub/configs/knowledge/evaluate_faithfulness.yaml +0 -68
  73. sdg_hub/configs/knowledge/evaluate_question.yaml +0 -38
  74. sdg_hub/configs/knowledge/evaluate_relevancy.yaml +0 -84
  75. sdg_hub/configs/knowledge/extractive_summary.yaml +0 -18
  76. sdg_hub/configs/knowledge/generate_code_questions_responses.yaml +0 -39
  77. sdg_hub/configs/knowledge/generate_questions.yaml +0 -82
  78. sdg_hub/configs/knowledge/generate_questions_responses.yaml +0 -56
  79. sdg_hub/configs/knowledge/generate_responses.yaml +0 -86
  80. sdg_hub/configs/knowledge/mcq_generation.yaml +0 -83
  81. sdg_hub/configs/knowledge/router.yaml +0 -12
  82. sdg_hub/configs/knowledge/simple_generate_qa.yaml +0 -34
  83. sdg_hub/configs/reasoning/__init__.py +0 -0
  84. sdg_hub/configs/reasoning/dynamic_cot.yaml +0 -40
  85. sdg_hub/configs/skills/__init__.py +0 -0
  86. sdg_hub/configs/skills/analyzer.yaml +0 -48
  87. sdg_hub/configs/skills/annotation.yaml +0 -36
  88. sdg_hub/configs/skills/contexts.yaml +0 -28
  89. sdg_hub/configs/skills/critic.yaml +0 -60
  90. sdg_hub/configs/skills/evaluate_freeform_pair.yaml +0 -111
  91. sdg_hub/configs/skills/evaluate_freeform_questions.yaml +0 -78
  92. sdg_hub/configs/skills/evaluate_grounded_pair.yaml +0 -119
  93. sdg_hub/configs/skills/evaluate_grounded_questions.yaml +0 -51
  94. sdg_hub/configs/skills/freeform_questions.yaml +0 -34
  95. sdg_hub/configs/skills/freeform_responses.yaml +0 -39
  96. sdg_hub/configs/skills/grounded_questions.yaml +0 -38
  97. sdg_hub/configs/skills/grounded_responses.yaml +0 -59
  98. sdg_hub/configs/skills/icl_examples/STEM.yaml +0 -56
  99. sdg_hub/configs/skills/icl_examples/__init__.py +0 -0
  100. sdg_hub/configs/skills/icl_examples/coding.yaml +0 -97
  101. sdg_hub/configs/skills/icl_examples/extraction.yaml +0 -36
  102. sdg_hub/configs/skills/icl_examples/humanities.yaml +0 -71
  103. sdg_hub/configs/skills/icl_examples/math.yaml +0 -85
  104. sdg_hub/configs/skills/icl_examples/reasoning.yaml +0 -30
  105. sdg_hub/configs/skills/icl_examples/roleplay.yaml +0 -45
  106. sdg_hub/configs/skills/icl_examples/writing.yaml +0 -80
  107. sdg_hub/configs/skills/judge.yaml +0 -53
  108. sdg_hub/configs/skills/planner.yaml +0 -67
  109. sdg_hub/configs/skills/respond.yaml +0 -8
  110. sdg_hub/configs/skills/revised_responder.yaml +0 -78
  111. sdg_hub/configs/skills/router.yaml +0 -59
  112. sdg_hub/configs/skills/simple_generate_qa_freeform.yaml +0 -27
  113. sdg_hub/configs/skills/simple_generate_qa_grounded.yaml +0 -31
  114. sdg_hub/flow.py +0 -477
  115. sdg_hub/flow_runner.py +0 -450
  116. sdg_hub/flows/generation/knowledge/mmlu_bench.yaml +0 -13
  117. sdg_hub/flows/generation/knowledge/simple_knowledge.yaml +0 -12
  118. sdg_hub/flows/generation/knowledge/synth_knowledge.yaml +0 -89
  119. sdg_hub/flows/generation/knowledge/synth_knowledge1.5.yaml +0 -136
  120. sdg_hub/flows/generation/skills/improve_responses.yaml +0 -103
  121. sdg_hub/flows/generation/skills/simple_freeform_skill.yaml +0 -12
  122. sdg_hub/flows/generation/skills/simple_grounded_skill.yaml +0 -12
  123. sdg_hub/flows/generation/skills/synth_grounded_skills.yaml +0 -80
  124. sdg_hub/flows/generation/skills/synth_skills.yaml +0 -59
  125. sdg_hub/pipeline.py +0 -121
  126. sdg_hub/prompts.py +0 -80
  127. sdg_hub/registry.py +0 -122
  128. sdg_hub/sdg.py +0 -206
  129. sdg_hub/utils/config_validation.py +0 -91
  130. sdg_hub/utils/error_handling.py +0 -94
  131. sdg_hub/utils/validation_result.py +0 -10
  132. sdg_hub-0.1.4.dist-info/METADATA +0 -190
  133. sdg_hub-0.1.4.dist-info/RECORD +0 -89
  134. sdg_hub/{logger_config.py → core/utils/logger_config.py} +1 -1
  135. /sdg_hub/{configs/__init__.py → flows/qa_generation/document_grounded_qa/multi_summary_qa/instructlab/README.md} +0 -0
  136. /sdg_hub/{configs/annotations → flows/qa_generation/document_grounded_qa/multi_summary_qa/instructlab}/__init__.py +0 -0
  137. {sdg_hub-0.1.4.dist-info → sdg_hub-0.2.0.dist-info}/WHEEL +0 -0
  138. {sdg_hub-0.1.4.dist-info → sdg_hub-0.2.0.dist-info}/licenses/LICENSE +0 -0
  139. {sdg_hub-0.1.4.dist-info → sdg_hub-0.2.0.dist-info}/top_level.txt +0 -0
sdg_hub/sdg.py DELETED
@@ -1,206 +0,0 @@
1
- # SPDX-License-Identifier: Apache-2.0
2
-
3
- """Synthetic Data Generator (SDG) module for managing data generation flows."""
4
-
5
- # Standard
6
- from concurrent.futures import ThreadPoolExecutor, as_completed
7
- from typing import List, Optional, Tuple
8
- import traceback
9
-
10
- # Third Party
11
- from datasets import Dataset
12
- from tqdm import tqdm
13
-
14
- # Local
15
- from .checkpointer import Checkpointer
16
- from .flow import Flow
17
- from .logger_config import setup_logger
18
- from .utils.datautils import safe_concatenate_datasets
19
-
20
- logger = setup_logger(__name__)
21
-
22
-
23
- class SDG:
24
- """Synthetic Data Generator class.
25
-
26
- This class manages the generation of synthetic data using one or more
27
- data generation flows.
28
-
29
- Parameters
30
- ----------
31
- flows : List[Flow]
32
- List of flows to execute.
33
- num_workers : int, optional
34
- Number of worker threads to use, by default 1
35
- batch_size : Optional[int], optional
36
- Size of batches to process, by default None
37
- save_freq : Optional[int], optional
38
- Frequency of checkpoint saves, by default None
39
-
40
- Attributes
41
- ----------
42
- flows : List[Flow]
43
- List of flows to execute.
44
- num_workers : int
45
- Number of worker threads to use.
46
- batch_size : Optional[int]
47
- Size of batches to process.
48
- save_freq : Optional[int]
49
- Frequency of checkpoint saves.
50
- """
51
-
52
- def __init__(
53
- self,
54
- flows: List[Flow],
55
- num_workers: int = 1,
56
- batch_size: Optional[int] = None,
57
- save_freq: Optional[int] = None,
58
- ) -> None:
59
- self.flows = flows
60
- self.num_workers = num_workers
61
- self.batch_size = batch_size
62
- self.save_freq = save_freq
63
-
64
- def _split_dataset(
65
- self, dataset: Dataset, batch_size: int
66
- ) -> List[Tuple[int, int]]:
67
- """Split the dataset into smaller batches.
68
-
69
- Parameters
70
- ----------
71
- dataset : Dataset
72
- The dataset to split.
73
- batch_size : int
74
- Size of each batch.
75
-
76
- Returns
77
- -------
78
- List[Tuple[int, int]]
79
- List of (start, end) indices for each batch.
80
- """
81
- total_size = len(dataset)
82
- num_batches = (total_size + batch_size - 1) // batch_size
83
-
84
- batches = [
85
- (i * batch_size, min((i + 1) * batch_size, total_size))
86
- for i in tqdm(range(num_batches))
87
- ]
88
-
89
- return batches
90
-
91
- @staticmethod
92
- def _generate_data(
93
- flows: List[Flow],
94
- input_split: Tuple[int, int],
95
- ds: Dataset,
96
- i: Optional[int] = None,
97
- ) -> Optional[Dataset]:
98
- """Generate data for a single split using the provided flows.
99
-
100
- Parameters
101
- ----------
102
- flows : List[Flow]
103
- List of flows to execute.
104
- input_split : Tuple[int, int]
105
- (start, end) indices for the current split.
106
- ds : Dataset
107
- The full input dataset.
108
- i : Optional[int], optional
109
- Split index for logging, by default None
110
-
111
- Returns
112
- -------
113
- Optional[Dataset]
114
- Generated dataset for the split, or None if generation failed.
115
- """
116
- logger.info(f"Processing split {i}")
117
- input_split = ds.select(range(input_split[0], input_split[1]))
118
- try:
119
- for flow in flows:
120
- input_split = flow.generate(input_split)
121
- return input_split
122
- except Exception as e:
123
- logger.error(f"Error processing split {i}: {e}")
124
- traceback.print_exc()
125
- return None
126
-
127
- def generate(
128
- self, dataset: Dataset, checkpoint_dir: Optional[str] = None
129
- ) -> Dataset:
130
- """Generate synthetic data using the configured flows.
131
-
132
- Parameters
133
- ----------
134
- dataset : Dataset
135
- The input dataset to process.
136
- checkpoint_dir : Optional[str], optional
137
- Directory to save checkpoints, by default None
138
-
139
- Returns
140
- -------
141
- Dataset
142
- The generated dataset.
143
-
144
- Notes
145
- -----
146
- If checkpoint_dir is provided, the generation process can be resumed
147
- from the last checkpoint in case of interruption.
148
- """
149
- # Initialize checkpointer
150
- checkpointer = Checkpointer(checkpoint_dir, self.save_freq)
151
-
152
- # Load existing checkpoints and determine missing data
153
- seed_data, pre_generated_data = checkpointer.load_existing_data(dataset)
154
-
155
- # If all data has been generated, return the pre-generated data
156
- if seed_data.num_rows == 0 and pre_generated_data is not None:
157
- return pre_generated_data
158
-
159
- if not self.batch_size:
160
- # If batch size is not provided, generate the dataset in a single pass
161
- generated_dataset = seed_data
162
- # generated_data is initialized with seed_data, and it gets updated with each flow
163
- for flow in self.flows:
164
- generated_dataset = flow.generate(generated_dataset)
165
- return generated_dataset
166
-
167
- logger.info("Splitting the dataset into smaller batches")
168
- input_splits = self._split_dataset(seed_data, self.batch_size)
169
- logger.info(
170
- f"Generating dataset with {len(input_splits)} splits, "
171
- f"batch size {self.batch_size}, and {self.num_workers} workers"
172
- )
173
-
174
- generated_data = [pre_generated_data] if pre_generated_data else []
175
- last_saved_split_index = 0 # To track the last saved split
176
-
177
- with ThreadPoolExecutor(max_workers=self.num_workers) as executor:
178
- futures = [
179
- executor.submit(
180
- self._generate_data, self.flows, input_split, seed_data, i
181
- )
182
- for i, input_split in enumerate(input_splits)
183
- ]
184
-
185
- for i, future in enumerate(tqdm(as_completed(futures), total=len(futures))):
186
- generated_data_split = future.result() # Ensure each future completes
187
-
188
- if generated_data_split:
189
- generated_data.append(generated_data_split)
190
- logger.info(f"Finished future processing split {i} \n\n")
191
-
192
- # Use checkpointer to handle intermediate saves
193
- if checkpointer.should_save_checkpoint(i):
194
- # Save only the new splits since the last checkpoint
195
- new_splits = generated_data[last_saved_split_index : i + 1]
196
- checkpoint_dataset = safe_concatenate_datasets(new_splits)
197
- # check if checkpoint_dataset is not None
198
- if checkpoint_dataset:
199
- checkpointer.save_intermediate_checkpoint(
200
- checkpoint_dataset
201
- )
202
- last_saved_split_index = i + 1
203
-
204
- generated_dataset = safe_concatenate_datasets(generated_data)
205
-
206
- return generated_dataset
@@ -1,91 +0,0 @@
1
- # SPDX-License-Identifier: Apache-2.0
2
- """Configuration validation utilities for SDG Hub.
3
-
4
- This module provides functions to validate configuration files used by blocks,
5
- ensuring they meet the required schema and contain all necessary fields.
6
- """
7
-
8
- # Standard
9
- from typing import Any, Dict, List
10
-
11
- # Local
12
- from ..logger_config import setup_logger
13
-
14
- logger = setup_logger(__name__)
15
-
16
-
17
- def validate_prompt_config_schema(
18
- config: Dict[str, Any], config_path: str
19
- ) -> tuple[bool, List[str]]:
20
- """Validate that a prompt configuration file has the required schema fields.
21
-
22
- For prompt template configs, 'system' and 'generation' are required fields.
23
- Other fields like 'introduction', 'principles', 'examples', 'start_tags', 'end_tags' are optional.
24
-
25
- Parameters
26
- ----------
27
- config : Dict[str, Any]
28
- The loaded configuration dictionary.
29
- config_path : str
30
- The path to the configuration file (for error reporting).
31
-
32
- Returns
33
- -------
34
- tuple[bool, List[str]]
35
- A tuple containing:
36
- - bool: True if schema is valid, False otherwise
37
- - List[str]: List of validation error messages (empty if valid)
38
- """
39
- required_fields = ["system", "generation"]
40
- errors = []
41
-
42
- # Ensure config is a dictionary
43
- if not isinstance(config, dict):
44
- errors.append(f"Configuration must be a dictionary, got {type(config).__name__}")
45
- return False, errors
46
-
47
- # Check for missing required fields
48
- missing_fields = [field for field in required_fields if field not in config]
49
- if missing_fields:
50
- errors.append(f"Missing required fields: {missing_fields}")
51
-
52
- # Check for empty or null required fields and validate they are strings
53
- for field in required_fields:
54
- if field in config:
55
- value = config[field]
56
- if value is None:
57
- errors.append(f"Required field '{field}' is null")
58
- elif not isinstance(value, str):
59
- errors.append(f"Required field '{field}' must be a string, got {type(value).__name__}")
60
- elif not value.strip():
61
- errors.append(f"Required field '{field}' is empty")
62
-
63
- # Check optional string fields are strings when present
64
- string_fields = ["introduction", "principles", "examples"]
65
- for field in string_fields:
66
- if field in config:
67
- value = config[field]
68
- if value is not None and not isinstance(value, str):
69
- errors.append(f"Field '{field}' must be a string, got {type(value).__name__}")
70
-
71
- # Check start_tags and end_tags are lists of strings when present
72
- tag_fields = ["start_tags", "end_tags"]
73
- for field in tag_fields:
74
- if field in config:
75
- value = config[field]
76
- if value is not None:
77
- if not isinstance(value, list):
78
- errors.append(f"Field '{field}' must be a list, got {type(value).__name__}")
79
- else:
80
- for i, tag in enumerate(value):
81
- if not isinstance(tag, str):
82
- errors.append(f"Field '{field}[{i}]' must be a string, got {type(tag).__name__}")
83
-
84
- # Log validation results
85
- if errors:
86
- for error in errors:
87
- logger.error(f"Config validation failed for {config_path}: {error}")
88
- return False, errors
89
-
90
- logger.debug(f"Config validation passed for {config_path}")
91
- return True, []
@@ -1,94 +0,0 @@
1
- """Custom exception classes for SDG Hub error handling."""
2
-
3
-
4
- class SDGHubError(Exception):
5
- """Base exception class for all SDG Hub errors."""
6
-
7
- def __init__(self, message: str, details: str = None):
8
- """Initialize SDGHubError.
9
-
10
- Parameters
11
- ----------
12
- message : str
13
- The main error message.
14
- details : str, optional
15
- Additional details about the error.
16
- """
17
- self.message = message
18
- self.details = details
19
- full_message = message
20
- if details:
21
- full_message = f"{message}\nDetails: {details}"
22
- super().__init__(full_message)
23
-
24
-
25
- class FlowRunnerError(SDGHubError):
26
- """Base exception class for flow runner errors."""
27
-
28
- pass
29
-
30
-
31
- class DatasetLoadError(FlowRunnerError):
32
- """Raised when dataset loading fails."""
33
-
34
- pass
35
-
36
-
37
- class FlowConfigurationError(FlowRunnerError):
38
- """Raised when flow configuration is invalid."""
39
-
40
- pass
41
-
42
-
43
- class APIConnectionError(FlowRunnerError):
44
- """Raised when API connection fails."""
45
-
46
- pass
47
-
48
-
49
- class DataGenerationError(FlowRunnerError):
50
- """Raised when data generation fails."""
51
-
52
- pass
53
-
54
-
55
- class DataSaveError(FlowRunnerError):
56
- """Raised when saving generated data fails."""
57
-
58
- pass
59
-
60
-
61
- class BlockError(SDGHubError):
62
- """Base exception class for block-related errors."""
63
-
64
- pass
65
-
66
-
67
- class BlockConfigurationError(BlockError):
68
- """Raised when block configuration is invalid."""
69
-
70
- pass
71
-
72
-
73
- class BlockExecutionError(BlockError):
74
- """Raised when block execution fails."""
75
-
76
- pass
77
-
78
-
79
- class FlowError(SDGHubError):
80
- """Base exception class for flow-related errors."""
81
-
82
- pass
83
-
84
-
85
- class FlowValidationError(FlowError):
86
- """Raised when flow validation fails."""
87
-
88
- pass
89
-
90
-
91
- class FlowExecutionError(FlowError):
92
- """Raised when flow execution fails."""
93
-
94
- pass
@@ -1,10 +0,0 @@
1
- from typing import List
2
-
3
-
4
- class ValidationResult:
5
- def __init__(self, valid: bool, errors: List[str]):
6
- self.valid = valid
7
- self.errors = errors
8
-
9
- def __repr__(self):
10
- return f"ValidationResult(valid={self.valid}, errors={self.errors})"
@@ -1,190 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: sdg_hub
3
- Version: 0.1.4
4
- Summary: Synthetic Data Generation
5
- Author-email: Red Hat AI Innovation <abhandwa@redhat.com>
6
- License: Apache-2.0
7
- Project-URL: homepage, https://ai-innovation.team/
8
- Project-URL: source, https://github.com/Red-Hat-AI-Innovation-Team/sdg_hub
9
- Project-URL: issues, https://github.com/Red-Hat-AI-Innovation-Team/sdg_hub/issues
10
- Classifier: Development Status :: 3 - Alpha
11
- Classifier: Environment :: Console
12
- Classifier: License :: OSI Approved :: Apache Software License
13
- Classifier: License :: OSI Approved :: MIT License
14
- Classifier: Operating System :: MacOS :: MacOS X
15
- Classifier: Operating System :: POSIX :: Linux
16
- Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
17
- Classifier: Programming Language :: Python :: 3
18
- Classifier: Programming Language :: Python :: 3.9
19
- Classifier: Programming Language :: Python :: 3.10
20
- Classifier: Programming Language :: Python :: 3.11
21
- Classifier: Programming Language :: Python :: 3.12
22
- Classifier: Programming Language :: Python :: Implementation :: CPython
23
- Requires-Python: >=3.9
24
- Description-Content-Type: text/markdown
25
- License-File: LICENSE
26
- Requires-Dist: click<9.0.0,>=8.1.7
27
- Requires-Dist: datasets<4.0.0,>=2.18.0
28
- Requires-Dist: httpx<1.0.0,>=0.25.0
29
- Requires-Dist: jinja2
30
- Requires-Dist: openai<2.0.0,>=1.13.3
31
- Requires-Dist: rich
32
- Requires-Dist: tenacity!=8.4.0,>=8.3.0
33
- Requires-Dist: tqdm<5.0.0,>=4.66.2
34
- Provides-Extra: web-interface
35
- Requires-Dist: flask>=3.0.2; extra == "web-interface"
36
- Requires-Dist: pyyaml>=6.0.1; extra == "web-interface"
37
- Requires-Dist: flask-wtf>=1.2.2; extra == "web-interface"
38
- Provides-Extra: vllm
39
- Requires-Dist: vllm>=0.9.1; extra == "vllm"
40
- Requires-Dist: torch>=2.0.0; extra == "vllm"
41
- Requires-Dist: transformers>=4.37.0; extra == "vllm"
42
- Requires-Dist: accelerate>=0.21.0; extra == "vllm"
43
- Requires-Dist: xformers>=0.0.22.post7; extra == "vllm"
44
- Provides-Extra: examples
45
- Requires-Dist: tabulate>=0.9.0; extra == "examples"
46
- Requires-Dist: transformers>=4.37.0; extra == "examples"
47
- Requires-Dist: langchain-text-splitters; extra == "examples"
48
- Requires-Dist: docling>=2.3.0; extra == "examples"
49
- Provides-Extra: dev
50
- Requires-Dist: pre-commit<4.0,>=3.0.4; extra == "dev"
51
- Requires-Dist: pylint<4.0,>=2.16.2; extra == "dev"
52
- Requires-Dist: pylint-pydantic; extra == "dev"
53
- Requires-Dist: pytest; extra == "dev"
54
- Requires-Dist: pytest-asyncio; extra == "dev"
55
- Requires-Dist: pytest-cov; extra == "dev"
56
- Requires-Dist: pytest-html; extra == "dev"
57
- Requires-Dist: tox<5,>=4.4.2; extra == "dev"
58
- Dynamic: license-file
59
-
60
- # SDG Hub: Synthetic Data Generation Toolkit
61
-
62
- [![Build](https://github.com/Red-Hat-AI-Innovation-Team/sdg_hub/actions/workflows/pypi.yaml/badge.svg?branch=main)](https://github.com/Red-Hat-AI-Innovation-Team/sdg_hub/actions/workflows/pypi.yaml)
63
- [![Release](https://img.shields.io/github/v/release/Red-Hat-AI-Innovation-Team/sdg_hub)](https://github.com/Red-Hat-AI-Innovation-Team/sdg_hub/releases)
64
- [![License](https://img.shields.io/github/license/Red-Hat-AI-Innovation-Team/sdg_hub)](https://github.com/Red-Hat-AI-Innovation-Team/sdg_hub/blob/main/LICENSE)
65
- [![Tests](https://github.com/Red-Hat-AI-Innovation-Team/sdg_hub/actions/workflows/test.yml/badge.svg)](https://github.com/Red-Hat-AI-Innovation-Team/sdg_hub/actions/workflows/test.yml)
66
- [![codecov](https://codecov.io/gh/Red-Hat-AI-Innovation-Team/sdg_hub/graph/badge.svg?token=SP75BCXWO2)](https://codecov.io/gh/Red-Hat-AI-Innovation-Team/sdg_hub)
67
-
68
- <html>
69
- <h3 align="center">
70
- A modular, scalable, and efficient solution for creating synthetic data generation flows in a "low-code" manner.
71
- </h3>
72
- <h3 align="center">
73
- <a href="http://ai-innovation.team/sdg_hub">Documentation</a> |
74
- <a href="examples/">Examples</a> |
75
- <a href="https://www.youtube.com/watch?v=aGKCViWjAmA">Video Tutorial</a>
76
- </h3>
77
- </html>
78
-
79
- SDG Hub is designed to simplify data creation for LLMs, allowing users to chain computational units and build powerful flows for generating data and processing tasks. Define complex workflows using nothing but YAML configuration files.
80
-
81
- **📖 Full documentation available at: [https://ai-innovation.team/sdg_hub](https://ai-innovation.team/sdg_hub)**
82
-
83
- ---
84
-
85
- ## ✨ Key Features
86
-
87
- - **Low-Code Flow Creation**: Build sophisticated data generation pipelines using
88
- simple YAML configuration files without writing any code.
89
-
90
- - **Modular Block System**: Compose workflows from reusable, self-contained
91
- blocks that handle LLM calls, data transformations, and filtering.
92
-
93
- - **LLM-Agnostic**: Works with any language model through configurable
94
- prompt templates and generation parameters.
95
-
96
- - **Prompt Engineering Friendly**: Tune LLM behavior by editing declarative YAML prompts.
97
-
98
- ## 🚀 Installation
99
-
100
- ### Stable Release (Recommended)
101
-
102
- ```bash
103
- pip install sdg-hub
104
- ```
105
-
106
- ### Development Version
107
-
108
- ```bash
109
- pip install git+https://github.com/Red-Hat-AI-Innovation-Team/sdg_hub.git
110
- ```
111
-
112
- ## 🏁 Quick Start
113
-
114
- ### Prerequisites
115
-
116
- Before getting started, make sure you have:
117
- - Python 3.8 or higher
118
- - LLM Inference Endpoint exposed through OpenAI API
119
-
120
- ### Simple Example
121
-
122
- Here's the simplest way to get started:
123
-
124
- ```python
125
- from sdg_hub.flow_runner import run_flow
126
-
127
- # Run a basic knowledge generation flow
128
- run_flow(
129
- ds_path="my_data.jsonl",
130
- save_path="output.jsonl",
131
- endpoint="http://0.0.0.0:8000/v1",
132
- flow_path="flows/generation/knowledge/synth_knowledge.yaml"
133
- )
134
- ```
135
-
136
- ### Advanced Configuration
137
- You can invoke any built-in flow using run_flow:
138
- ```python
139
- from sdg_hub.flow_runner import run_flow
140
-
141
- run_flow(
142
- ds_path="path/to/dataset.jsonl",
143
- save_path="path/to/output.jsonl",
144
- endpoint="http://0.0.0.0:8000/v1",
145
- flow_path="path/to/flow.yaml",
146
- checkpoint_dir="path/to/checkpoints",
147
- batch_size=8,
148
- num_workers=32,
149
- save_freq=2,
150
- )
151
- ```
152
-
153
- ### 📂 Available Built-in Flows
154
-
155
- You can start with any of these YAML flows out of the box:
156
-
157
- #### 🔎 **Knowledge Flows**
158
-
159
- | Flow | Description |
160
- |------|-------------|
161
- | `synth_knowledge.yaml` | Produces document-grounded questions and answers for factual memorization |
162
- | `synth_knowledge1.5.yaml` | Improved version that builds intermediate representations for better recall |
163
-
164
- #### 🧠 **Skills Flows**
165
-
166
- | Flow | Description |
167
- |------|-------------|
168
- | `synth_skills.yaml` | Freeform skills QA generation (eg: "Create a new github issue to add type hints") |
169
- | `synth_grounded_skills.yaml` | Domain-specific skill generation (eg: "From the given conversation create a table for feature requests") |
170
- | `improve_responses.yaml` | Uses planning and critique-based refinement to improve generated answers |
171
-
172
- All these can be found here: [flows](src/sdg_hub/flows)
173
-
174
- ## 📺 Video Tutorial
175
-
176
- For a comprehensive walkthrough of sdg_hub:
177
-
178
- [![SDG Hub Tutorial](https://img.youtube.com/vi/aGKCViWjAmA/0.jpg)](https://www.youtube.com/watch?v=aGKCViWjAmA)
179
-
180
- ## 🤝 Contributing
181
-
182
- We welcome contributions from the community! Whether it's bug reports, feature requests, documentation improvements, or code contributions, please check out our [contribution guidelines](CONTRIBUTING.md).
183
-
184
- ## 📄 License
185
-
186
- This project is licensed under the Apache 2.0 License - see the [LICENSE](LICENSE) file for details.
187
-
188
- ---
189
-
190
- Built with ❤️ by the Red Hat AI Innovation Team
@@ -1,89 +0,0 @@
1
- sdg_hub/__init__.py,sha256=5Wa6onDndPvG4iwnjq2jK747t3-7XKdQn2WfHfq1sFc,67
2
- sdg_hub/_version.py,sha256=hcPkC9vIGgfrKK6ft7ysLT7iOCjpFmCBmyKLmXiaZ1g,511
3
- sdg_hub/checkpointer.py,sha256=R0pNKL_q7-BerxmIarY0w1nFYaq7fGnoRRkCVL6Z-Gw,5053
4
- sdg_hub/flow.py,sha256=14WDZfb-VDUBwXsVo9u5oMuWD6aOm-GWtIdT64z4j-0,18050
5
- sdg_hub/flow_runner.py,sha256=rSoXoN2n2vsMmOnsRImeQivsY9zlrDig53O9DBbQzz0,15177
6
- sdg_hub/logger_config.py,sha256=7uHEJVRfym1c4n95DOKHelLXqAus8uHsZYmzLsEjqpo,422
7
- sdg_hub/pipeline.py,sha256=mahktfoCMVnuBnvLNjAVOAoFKNQo-wb0Dz1_xdYhKDM,3852
8
- sdg_hub/prompts.py,sha256=VMuPnABC9f3SgzSBFLprPbn1o2P4XttnKFwen_IYqR4,19273
9
- sdg_hub/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- sdg_hub/registry.py,sha256=Sc_HNxo4n0pgWMiEDd_sLjxaSXAMZFiHJIhQKqjywwk,3772
11
- sdg_hub/sdg.py,sha256=8SKrSnqyvJAwE2Muf9lXw9ONRcDzqmCtaEzFHCYW4CY,6914
12
- sdg_hub/blocks/__init__.py,sha256=I-kMjIM7E1NrPLyBuUi0yNoXnuw_kTK3A7ybyt3pOxU,936
13
- sdg_hub/blocks/block.py,sha256=zdeyDyYiY0EdD3xS7kZR2hRZCRkbygQ4WONp_zv3X7w,3051
14
- sdg_hub/blocks/llmblock.py,sha256=nWslPFZSCiyL7MXQurOk6Jx29UOsgnVDMI3PTwje7kg,13678
15
- sdg_hub/blocks/openaichatblock.py,sha256=BWsWFEozWptwe1MMaz-_ZmgQPsNbCRun6ZlaKD3ICxQ,20016
16
- sdg_hub/blocks/utilblocks.py,sha256=U2PQk26cwHOgofk5IenHjrao08gbqPFOBNRy5QJ-EEY,18290
17
- sdg_hub/configs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
- sdg_hub/configs/annotations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
- sdg_hub/configs/annotations/cot_reflection.yaml,sha256=60EdsTe1y7GoUIAWYSGfMa3EKI3oLZKCvDuKU7wHgQU,1737
20
- sdg_hub/configs/annotations/detailed_annotations.yaml,sha256=in21xmlhxDJGEaWh1IgINh33tEyW9AuyG3k4pWBuKSM,1520
21
- sdg_hub/configs/annotations/detailed_description.yaml,sha256=FsGbQMBxf1MAOi0nhrQ4icxcwYMlRura_ji9Pmeh1AA,192
22
- sdg_hub/configs/annotations/detailed_description_icl.yaml,sha256=NDdwo5EShnYZjm1Fn80sZTAwfnwpPigixP2hvJ8--cU,679
23
- sdg_hub/configs/annotations/simple_annotations.yaml,sha256=d80d0mK7Xz0MMCCSW3sYw3ztt5HASV5miu0krSAbjnA,234
24
- sdg_hub/configs/knowledge/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
- sdg_hub/configs/knowledge/atomic_facts.yaml,sha256=bIfQr0q0FyReO94v_lpLO56FikARCvFmZza-ISZTOnA,2453
26
- sdg_hub/configs/knowledge/auxilary_instructions.yaml,sha256=aCgIjvNacdC2ZHThEvhZKvwORK6KqErVvVYQYQrIDLE,2034
27
- sdg_hub/configs/knowledge/detailed_summary.yaml,sha256=_Mc_i9vaLp1OPKexSOURV5gbXEG41p1eELUukOhz8oM,388
28
- sdg_hub/configs/knowledge/evaluate_faithfulness.yaml,sha256=iuvx5vNNm_jzHlmcKF83StaDYezRz2vQn3JUHM-TMdQ,3054
29
- sdg_hub/configs/knowledge/evaluate_question.yaml,sha256=02mikEAJCUEkREBo7KxPY9H6iTUHQN-4cRkn2XMlVQ8,1915
30
- sdg_hub/configs/knowledge/evaluate_relevancy.yaml,sha256=yPyW2BeLV07cvDU8NO6f-Wc32P9iycnpXyLvvTnUy44,3651
31
- sdg_hub/configs/knowledge/extractive_summary.yaml,sha256=TYgJ7WQc7NFkf3GeRsbx6lwfA_xFnEOYGELewSqorp0,399
32
- sdg_hub/configs/knowledge/generate_code_questions_responses.yaml,sha256=cIus2JYMYDvxHFVSU9QVa-1IK5KoChb3rCU2b4b9UmI,908
33
- sdg_hub/configs/knowledge/generate_questions.yaml,sha256=iJtttZrVvlXFraUSrMowqTCLoJOLDbBndcTNMPTO8A4,2788
34
- sdg_hub/configs/knowledge/generate_questions_responses.yaml,sha256=H9nb_5xGP7k6HtC3VboXqpiI5kQ9Xp3vjhXH3YIFesk,2525
35
- sdg_hub/configs/knowledge/generate_responses.yaml,sha256=wwiB7lSB9yEB1XG2SIEIRtHkSlKh3NGJAmDaq2J6-ZY,2483
36
- sdg_hub/configs/knowledge/mcq_generation.yaml,sha256=d4VKegnVIexwCn0e2AJs-0DC6XdLyUBGaCsQVwzICUE,3152
37
- sdg_hub/configs/knowledge/router.yaml,sha256=9m_cX3xl808Vwrcq2PACyX45QFPkrV2nVYIY8x10JBU,119
38
- sdg_hub/configs/knowledge/simple_generate_qa.yaml,sha256=OsuZP9SxQeUhTsHdhUO10mnjJ1u_6xekW5IQucFpRco,1565
39
- sdg_hub/configs/reasoning/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
- sdg_hub/configs/reasoning/dynamic_cot.yaml,sha256=6XY_mFpB_oKFQ7U2CmHTqkJRGVHgOvpNmIDfhksYW6o,2641
41
- sdg_hub/configs/skills/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
- sdg_hub/configs/skills/analyzer.yaml,sha256=QBtyjaU6HBZqzNOmev_W4_scn_hH7Rfxd2xL_LcPLho,2261
43
- sdg_hub/configs/skills/annotation.yaml,sha256=k5nJ357kUr0Uvq7Hkt3Ey22UbgSjgSjIomjHFfjaQnY,916
44
- sdg_hub/configs/skills/contexts.yaml,sha256=MZ2QpuGhTce6kuEsMleaGblljhGG-yhXBuH42htA2P4,1161
45
- sdg_hub/configs/skills/critic.yaml,sha256=Dr7anOKa7Xx1oDonXzsCfXwKIl4hUTArx2Sb_rgpLQI,1808
46
- sdg_hub/configs/skills/evaluate_freeform_pair.yaml,sha256=MOI0-GyKrJ_O4v1mm8A1lIKxXfwcS3dA7GjlpDEuXRU,4055
47
- sdg_hub/configs/skills/evaluate_freeform_questions.yaml,sha256=yDmLd-3A9pN5VLaT4lAcJ_ZvCY43LYlcS1KEdxpBRjU,2559
48
- sdg_hub/configs/skills/evaluate_grounded_pair.yaml,sha256=vMQtsHpNxPOOHnkzqWPp-N1gSfwPqTbfcKmNfhb9WS8,4648
49
- sdg_hub/configs/skills/evaluate_grounded_questions.yaml,sha256=9yr97azFhMdOfYp11BFtDSIhhP4wjQMOxYZnKWKlCPU,3115
50
- sdg_hub/configs/skills/freeform_questions.yaml,sha256=N6R3c1jNiSSw6T-OUJULpLnPHuaSXjvoNjSqTKL6EOY,1500
51
- sdg_hub/configs/skills/freeform_responses.yaml,sha256=4URTMsPpgSDOVj71Gw3lL82QWnUFR37iE72BIMwwv7c,1544
52
- sdg_hub/configs/skills/grounded_questions.yaml,sha256=t6pKjt5Fp_ThZueB7JBrUKuQLQY_At-Y9O67OtrIXMo,1898
53
- sdg_hub/configs/skills/grounded_responses.yaml,sha256=kVOeBp3BjKCFKG2qConXIQVVPI1EgcKJgKn6DFAkl1s,1860
54
- sdg_hub/configs/skills/judge.yaml,sha256=FxnJA_wdmyMyMqGEZDAT8hc2itO845mGDNXgpmV2EUU,3203
55
- sdg_hub/configs/skills/planner.yaml,sha256=yNF6t0EnmwYt1EV9Y3-vkmPcbOQRtvoLr8MITuiUw_A,2086
56
- sdg_hub/configs/skills/respond.yaml,sha256=K1Q5X5_Q1k60hNDbHDjMYBzxbyOIEEHTQcXW6qQ4Ve0,108
57
- sdg_hub/configs/skills/revised_responder.yaml,sha256=rjypOJbhZV9PuOD9YhlYgymxOJV8Zdzzz54x6Fxn2bY,2875
58
- sdg_hub/configs/skills/router.yaml,sha256=7YnFp6H5wYD8W5Qn1Ac4r9dGBSFUDhZSNwmglQ99PgQ,3545
59
- sdg_hub/configs/skills/simple_generate_qa_freeform.yaml,sha256=j8cJtEKSvtA__rE08iU6oz2XnfIgj0HiLVL8-6RhK3c,1431
60
- sdg_hub/configs/skills/simple_generate_qa_grounded.yaml,sha256=tvX9EN5TArFesOOqpdN3hb-IHe7O82a2twQd-gzyCgw,1500
61
- sdg_hub/configs/skills/icl_examples/STEM.yaml,sha256=5dcLC5jXOEeDasBkTunnHYrlddI3HcHYnEAXZcrd0ds,8412
62
- sdg_hub/configs/skills/icl_examples/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
63
- sdg_hub/configs/skills/icl_examples/coding.yaml,sha256=a5m-pUcV9xUb54gQ5U3vsU1RBXzOmsfX0CjTW7U62zo,5240
64
- sdg_hub/configs/skills/icl_examples/extraction.yaml,sha256=P751l6NvFRkINWz-bX5jgnd_if2bl3d_NlhGI7g81xw,4654
65
- sdg_hub/configs/skills/icl_examples/humanities.yaml,sha256=tZyiJ4Q3gG4uuoDXw6g__lX3ySEUaRZW2GhW1ustwaM,11370
66
- sdg_hub/configs/skills/icl_examples/math.yaml,sha256=hNq-QudlXrg9CWLpJdrZ4v3vifGTWhyp2gcfwPdR3_o,6776
67
- sdg_hub/configs/skills/icl_examples/reasoning.yaml,sha256=eesIlH9SO07TVF20gy18MZrcDzLhSmynd_F_lvg0oQg,4335
68
- sdg_hub/configs/skills/icl_examples/roleplay.yaml,sha256=LYEyA7wv7QWQscUNQr0K_lotNoWSfuoAEncx3PCRYIs,6997
69
- sdg_hub/configs/skills/icl_examples/writing.yaml,sha256=El-57IjZ5IvdcmCHyHvX_M2RFFkEos572220be8ecrQ,11335
70
- sdg_hub/flows/generation/knowledge/mmlu_bench.yaml,sha256=U0S2NPkZ_9_8yQGgHJm4el-wVsg_6MllzbFT97cGNrI,343
71
- sdg_hub/flows/generation/knowledge/simple_knowledge.yaml,sha256=_DkBZjS47bH0Lmu0eXVRlesTxeAF8Zlzj1PgR1vruuA,295
72
- sdg_hub/flows/generation/knowledge/synth_knowledge.yaml,sha256=sYBzIFNBGks_o2Nwvov5MSrMadAB3g-niBAaWPbBYO0,2160
73
- sdg_hub/flows/generation/knowledge/synth_knowledge1.5.yaml,sha256=afQu7wePfBEb6nqAahJ6K2dT5jgp25qU6nA5DRR4JV0,3372
74
- sdg_hub/flows/generation/skills/improve_responses.yaml,sha256=wUV0awTmKHNZ62pHiw_yz-IdG0OYgT_dCwlMUlZS3TA,2683
75
- sdg_hub/flows/generation/skills/simple_freeform_skill.yaml,sha256=iVEomFH1E52JA7KLmTIwkS1PnzxUJVPMgbK2O-m80As,309
76
- sdg_hub/flows/generation/skills/simple_grounded_skill.yaml,sha256=LTLxqdgbLIKSJonuIRHhcRSpit1EawwNvytWzXWXe2E,309
77
- sdg_hub/flows/generation/skills/synth_grounded_skills.yaml,sha256=91Dm--agpmbm02hIVnFhEndjppKsQEWXDbckR9GAzKM,2045
78
- sdg_hub/flows/generation/skills/synth_skills.yaml,sha256=9lhQcxXXbN4V9ztPph4fyjUtctll2FYtKY-V4grQdy4,1492
79
- sdg_hub/utils/__init__.py,sha256=Jfs1DAVSYDNn8dfs0Uq2MguSwu77NyhP-KufSJICiBQ,278
80
- sdg_hub/utils/config_validation.py,sha256=g92GxN73Mjr0cXvc5amB_Fn4iV9-iKeWmPz9HwLPmNY,3426
81
- sdg_hub/utils/datautils.py,sha256=0t_SZ_UXBKl8uL6rVp3SUh8YKRbzKlh2oO5gr2cKyEw,389
82
- sdg_hub/utils/error_handling.py,sha256=UvPEmtdpbBL71Zx8DWpIqd8869kEY2dlCH11iDgMfec,1847
83
- sdg_hub/utils/path_resolution.py,sha256=M7hnwoyRQTKgwGC3Ld1_KmKaO_8Lu0PCk6JtQrLp67Q,2006
84
- sdg_hub/utils/validation_result.py,sha256=O3zF6r49LQ9StAf_oWmK2bg-JfTQw6rpbHtHr9lI4ks,264
85
- sdg_hub-0.1.4.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
86
- sdg_hub-0.1.4.dist-info/METADATA,sha256=rXHwcDfzwZDA2gxcO0uNUMwr_oiDjNqMzdQIEkiakwg,7240
87
- sdg_hub-0.1.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
88
- sdg_hub-0.1.4.dist-info/top_level.txt,sha256=TqI7d-HE1n6zkXFkU0nF3A1Ct0P0pBaqI675uFokhx4,8
89
- sdg_hub-0.1.4.dist-info/RECORD,,