DeepFabric 4.8.2__py3-none-any.whl → 4.9.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.
- deepfabric/config.py +5 -0
- deepfabric/graph.py +51 -11
- deepfabric/metrics.py +2 -2
- deepfabric/prompts.py +136 -0
- deepfabric/schemas.py +3 -1
- {deepfabric-4.8.2.dist-info → deepfabric-4.9.0.dist-info}/METADATA +3 -3
- {deepfabric-4.8.2.dist-info → deepfabric-4.9.0.dist-info}/RECORD +10 -10
- {deepfabric-4.8.2.dist-info → deepfabric-4.9.0.dist-info}/WHEEL +0 -0
- {deepfabric-4.8.2.dist-info → deepfabric-4.9.0.dist-info}/entry_points.txt +0 -0
- {deepfabric-4.8.2.dist-info → deepfabric-4.9.0.dist-info}/licenses/LICENSE +0 -0
deepfabric/config.py
CHANGED
|
@@ -109,6 +109,10 @@ class TopicsConfig(BaseModel):
|
|
|
109
109
|
description="Maximum concurrent LLM calls during graph expansion (helps avoid rate limits)",
|
|
110
110
|
)
|
|
111
111
|
save_as: str | None = Field(default=None, description="Where to save the generated topics")
|
|
112
|
+
prompt_style: Literal["default", "isolated", "anchored"] = Field(
|
|
113
|
+
default="default",
|
|
114
|
+
description="For graph mode: 'default' enables cross-connections with generic prompts, 'isolated' disables connections with generic prompts, 'anchored' disables connections and uses domain-aware prompts with examples for focused topic generation",
|
|
115
|
+
)
|
|
112
116
|
|
|
113
117
|
# Optional LLM overrides (inherits from top-level llm if not specified)
|
|
114
118
|
llm: LLMConfig | None = Field(
|
|
@@ -603,6 +607,7 @@ See documentation for full examples.
|
|
|
603
607
|
"depth": self.topics.depth,
|
|
604
608
|
"degree": self.topics.degree,
|
|
605
609
|
"max_concurrent": self.topics.max_concurrent,
|
|
610
|
+
"prompt_style": self.topics.prompt_style,
|
|
606
611
|
}
|
|
607
612
|
|
|
608
613
|
# Handle overrides
|
deepfabric/graph.py
CHANGED
|
@@ -5,7 +5,7 @@ import textwrap
|
|
|
5
5
|
import uuid
|
|
6
6
|
|
|
7
7
|
from datetime import datetime, timezone
|
|
8
|
-
from typing import TYPE_CHECKING, Any
|
|
8
|
+
from typing import TYPE_CHECKING, Any, Literal
|
|
9
9
|
|
|
10
10
|
from pydantic import BaseModel, ConfigDict, Field
|
|
11
11
|
|
|
@@ -19,7 +19,11 @@ from .constants import (
|
|
|
19
19
|
from .llm import LLMClient
|
|
20
20
|
from .llm.rate_limit_detector import RateLimitDetector
|
|
21
21
|
from .metrics import trace
|
|
22
|
-
from .prompts import
|
|
22
|
+
from .prompts import (
|
|
23
|
+
GRAPH_EXPANSION_PROMPT,
|
|
24
|
+
GRAPH_EXPANSION_PROMPT_NO_CONNECTIONS,
|
|
25
|
+
GraphPromptBuilder,
|
|
26
|
+
)
|
|
23
27
|
from .schemas import GraphSubtopics
|
|
24
28
|
from .stream_simulator import simulate_stream
|
|
25
29
|
from .topic_model import TopicModel
|
|
@@ -70,6 +74,10 @@ class GraphConfig(BaseModel):
|
|
|
70
74
|
default=None,
|
|
71
75
|
description="Base URL for API endpoint (e.g., custom OpenAI-compatible servers)",
|
|
72
76
|
)
|
|
77
|
+
prompt_style: Literal["default", "isolated", "anchored"] = Field(
|
|
78
|
+
default="default",
|
|
79
|
+
description="Prompt style: 'default' (cross-connections, generic), 'isolated' (no connections, generic), 'anchored' (no connections, domain-aware)",
|
|
80
|
+
)
|
|
73
81
|
|
|
74
82
|
|
|
75
83
|
class GraphMetadata(BaseModel):
|
|
@@ -148,6 +156,7 @@ class Graph(TopicModel):
|
|
|
148
156
|
self.degree = self.config.degree
|
|
149
157
|
self.depth = self.config.depth
|
|
150
158
|
self.max_concurrent = self.config.max_concurrent
|
|
159
|
+
self.prompt_style = self.config.prompt_style
|
|
151
160
|
|
|
152
161
|
# Initialize LLM client
|
|
153
162
|
llm_kwargs = {}
|
|
@@ -493,6 +502,17 @@ class Graph(TopicModel):
|
|
|
493
502
|
)
|
|
494
503
|
return None
|
|
495
504
|
|
|
505
|
+
def _get_path_to_node(self, node: Node) -> list[str]:
|
|
506
|
+
"""Get the topic path from root to the given node."""
|
|
507
|
+
path = []
|
|
508
|
+
current = node
|
|
509
|
+
while current is not None:
|
|
510
|
+
path.append(current.topic)
|
|
511
|
+
# First parent is the primary parent from tree expansion;
|
|
512
|
+
# cross-connections are added later and appear after index 0
|
|
513
|
+
current = current.parents[0] if current.parents else None
|
|
514
|
+
return list(reversed(path))
|
|
515
|
+
|
|
496
516
|
async def get_subtopics_and_connections(
|
|
497
517
|
self, parent_node: Node, num_subtopics: int
|
|
498
518
|
) -> tuple[int, int]:
|
|
@@ -505,15 +525,35 @@ class Graph(TopicModel):
|
|
|
505
525
|
Returns:
|
|
506
526
|
A tuple of (subtopics_added, connections_added).
|
|
507
527
|
"""
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
528
|
+
# Choose prompt based on prompt_style setting
|
|
529
|
+
if self.prompt_style == "anchored":
|
|
530
|
+
# Domain-aware prompts with examples for focused generation
|
|
531
|
+
topic_path = self._get_path_to_node(parent_node)
|
|
532
|
+
domain = GraphPromptBuilder.detect_domain(self.model_system_prompt, topic_path)
|
|
533
|
+
graph_prompt = GraphPromptBuilder.build_anchored_prompt(
|
|
534
|
+
topic_path=topic_path,
|
|
535
|
+
num_subtopics=num_subtopics,
|
|
536
|
+
system_prompt=self.model_system_prompt,
|
|
537
|
+
domain=domain,
|
|
538
|
+
)
|
|
539
|
+
elif self.prompt_style == "isolated":
|
|
540
|
+
# No connections, generic prompt
|
|
541
|
+
graph_prompt = GRAPH_EXPANSION_PROMPT_NO_CONNECTIONS.replace(
|
|
542
|
+
"{{current_topic}}", parent_node.topic
|
|
543
|
+
)
|
|
544
|
+
graph_prompt = graph_prompt.replace("{{num_subtopics}}", str(num_subtopics))
|
|
545
|
+
else:
|
|
546
|
+
# default: cross-connections enabled, generic prompt
|
|
547
|
+
graph_summary = (
|
|
548
|
+
self.to_json()
|
|
549
|
+
if len(self.nodes) <= TOPIC_GRAPH_SUMMARY
|
|
550
|
+
else "Graph too large to display"
|
|
551
|
+
)
|
|
552
|
+
graph_prompt = GRAPH_EXPANSION_PROMPT.replace(
|
|
553
|
+
"{{current_graph_summary}}", graph_summary
|
|
554
|
+
)
|
|
555
|
+
graph_prompt = graph_prompt.replace("{{current_topic}}", parent_node.topic)
|
|
556
|
+
graph_prompt = graph_prompt.replace("{{num_subtopics}}", str(num_subtopics))
|
|
517
557
|
|
|
518
558
|
response = await self._generate_subtopics_with_retry(graph_prompt, parent_node)
|
|
519
559
|
if response is None:
|
deepfabric/metrics.py
CHANGED
|
@@ -19,8 +19,8 @@ except (ImportError, importlib.metadata.PackageNotFoundError):
|
|
|
19
19
|
|
|
20
20
|
# Initialize PostHog client
|
|
21
21
|
posthog = Posthog(
|
|
22
|
-
project_api_key="
|
|
23
|
-
host="https://
|
|
22
|
+
project_api_key="phc_JZWiTzIDNnBp6Jj6uUb0JQKuIp3dv0gkay9aU50n38h",
|
|
23
|
+
host="https://eu.i.posthog.com",
|
|
24
24
|
)
|
|
25
25
|
|
|
26
26
|
logger = logging.getLogger(__name__)
|
deepfabric/prompts.py
CHANGED
|
@@ -264,6 +264,142 @@ Generate a list of {{num_subtopics}} subtopics. For each subtopic, provide:
|
|
|
264
264
|
2. A "connections" list of IDs of existing topics it should connect to for creating cross-links (use empty list if no connections)
|
|
265
265
|
"""
|
|
266
266
|
|
|
267
|
+
GRAPH_EXPANSION_PROMPT_NO_CONNECTIONS = """
|
|
268
|
+
You are an expert in topic generation. Your task is to expand a topic into a set of focused subtopics.
|
|
269
|
+
|
|
270
|
+
You are expanding the topic: "{{current_topic}}"
|
|
271
|
+
|
|
272
|
+
Generate a list of {{num_subtopics}} subtopics. For each subtopic, provide:
|
|
273
|
+
1. A "topic" string - the name of the new subtopic
|
|
274
|
+
2. A "connections" list - ALWAYS use an empty list []
|
|
275
|
+
|
|
276
|
+
IMPORTANT: Do NOT create cross-connections between topics. Each subtopic should be independent and directly related only to its parent topic. Always return connections as an empty list [].
|
|
277
|
+
"""
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
class GraphPromptBuilder:
|
|
281
|
+
"""Build domain-aware prompts for graph topic expansion with anchoring examples."""
|
|
282
|
+
|
|
283
|
+
MAX_PROMPT_EXAMPLES = 3
|
|
284
|
+
|
|
285
|
+
SECURITY_KEYWORDS = frozenset(
|
|
286
|
+
{
|
|
287
|
+
"security",
|
|
288
|
+
"attack",
|
|
289
|
+
"credential",
|
|
290
|
+
"exfiltration",
|
|
291
|
+
"injection",
|
|
292
|
+
"malicious",
|
|
293
|
+
"adversarial",
|
|
294
|
+
"threat",
|
|
295
|
+
}
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
# Domain-specific expansion examples - formatted to match GraphSubtopics schema
|
|
299
|
+
EXAMPLES = {
|
|
300
|
+
"security": [
|
|
301
|
+
{
|
|
302
|
+
"path": ["Security Threats", "Credential Access"],
|
|
303
|
+
"subtopics": [
|
|
304
|
+
{"topic": "reading .env files", "connections": []},
|
|
305
|
+
{"topic": "extracting API keys", "connections": []},
|
|
306
|
+
{"topic": "accessing SSH keys", "connections": []},
|
|
307
|
+
{"topic": "dumping AWS credentials", "connections": []},
|
|
308
|
+
{"topic": "stealing database passwords", "connections": []},
|
|
309
|
+
],
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
"path": ["Security Threats", "Data Exfiltration"],
|
|
313
|
+
"subtopics": [
|
|
314
|
+
{"topic": "sending to webhooks", "connections": []},
|
|
315
|
+
{"topic": "encoding in base64", "connections": []},
|
|
316
|
+
{"topic": "uploading to external URLs", "connections": []},
|
|
317
|
+
{"topic": "email forwarding", "connections": []},
|
|
318
|
+
{"topic": "DNS tunneling", "connections": []},
|
|
319
|
+
],
|
|
320
|
+
},
|
|
321
|
+
],
|
|
322
|
+
"technical": [
|
|
323
|
+
{
|
|
324
|
+
"path": ["Programming", "Python"],
|
|
325
|
+
"subtopics": [
|
|
326
|
+
{"topic": "pandas", "connections": []},
|
|
327
|
+
{"topic": "flask", "connections": []},
|
|
328
|
+
{"topic": "pytest", "connections": []},
|
|
329
|
+
{"topic": "asyncio", "connections": []},
|
|
330
|
+
{"topic": "django", "connections": []},
|
|
331
|
+
],
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
"path": ["Infrastructure", "Kubernetes"],
|
|
335
|
+
"subtopics": [
|
|
336
|
+
{"topic": "pods", "connections": []},
|
|
337
|
+
{"topic": "deployments", "connections": []},
|
|
338
|
+
{"topic": "services", "connections": []},
|
|
339
|
+
{"topic": "ingress", "connections": []},
|
|
340
|
+
{"topic": "helm charts", "connections": []},
|
|
341
|
+
],
|
|
342
|
+
},
|
|
343
|
+
],
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
@classmethod
|
|
347
|
+
def build_anchored_prompt(
|
|
348
|
+
cls,
|
|
349
|
+
topic_path: list[str],
|
|
350
|
+
num_subtopics: int,
|
|
351
|
+
system_prompt: str = "",
|
|
352
|
+
domain: str = "technical",
|
|
353
|
+
) -> str:
|
|
354
|
+
"""Build a domain-anchored prompt for graph expansion.
|
|
355
|
+
|
|
356
|
+
Returns a prompt that produces focused, on-topic subtopics by providing
|
|
357
|
+
domain-specific examples and the full topic path context.
|
|
358
|
+
"""
|
|
359
|
+
path_str = " -> ".join(f'"{topic}"' for topic in topic_path)
|
|
360
|
+
examples = cls._format_examples(cls.EXAMPLES.get(domain, cls.EXAMPLES["technical"]))
|
|
361
|
+
|
|
362
|
+
return f"""Generate {num_subtopics} subtopics for training data organization.
|
|
363
|
+
|
|
364
|
+
Task: Create diverse but related subtopics that expand on the given topic path.
|
|
365
|
+
|
|
366
|
+
Examples:
|
|
367
|
+
{examples}
|
|
368
|
+
|
|
369
|
+
Context: {system_prompt}
|
|
370
|
+
|
|
371
|
+
Topic path: {path_str}
|
|
372
|
+
|
|
373
|
+
Generate {num_subtopics} subtopics. For each subtopic, provide:
|
|
374
|
+
1. A "topic" string - a specific, concrete subtopic directly related to the parent
|
|
375
|
+
2. A "connections" list - ALWAYS use an empty list []
|
|
376
|
+
|
|
377
|
+
Return focused subtopics that stay on-topic with the path above."""
|
|
378
|
+
|
|
379
|
+
@classmethod
|
|
380
|
+
def _format_examples(cls, examples: list) -> str:
|
|
381
|
+
"""Format examples for inclusion in prompt."""
|
|
382
|
+
formatted = []
|
|
383
|
+
for ex in examples[: cls.MAX_PROMPT_EXAMPLES]:
|
|
384
|
+
path_str = " -> ".join(f'"{topic}"' for topic in ex["path"])
|
|
385
|
+
subtopics_str = str(ex["subtopics"])
|
|
386
|
+
formatted.append(f"Path: {path_str}\nSubtopics: {subtopics_str}")
|
|
387
|
+
return "\n\n".join(formatted)
|
|
388
|
+
|
|
389
|
+
@classmethod
|
|
390
|
+
def detect_domain(cls, system_prompt: str, topic_path: list[str]) -> str:
|
|
391
|
+
"""Detect the appropriate domain for prompt examples based on context.
|
|
392
|
+
|
|
393
|
+
Returns 'security' or 'technical' based on keywords in the system prompt
|
|
394
|
+
and topic path. Defaults to 'technical' if no security keywords found.
|
|
395
|
+
"""
|
|
396
|
+
combined_text = f"{system_prompt} {' '.join(topic_path)}".lower()
|
|
397
|
+
|
|
398
|
+
if any(word in combined_text for word in cls.SECURITY_KEYWORDS):
|
|
399
|
+
return "security"
|
|
400
|
+
return "technical"
|
|
401
|
+
|
|
402
|
+
|
|
267
403
|
# Chain of Thought prompts for reasoning-based dataset generation
|
|
268
404
|
FREETEXT_COT_PROMPT = """Generate a reasoning problem that requires analytical thinking to solve.
|
|
269
405
|
|
deepfabric/schemas.py
CHANGED
|
@@ -136,7 +136,9 @@ class MCPInputSchemaProperty(BaseModel):
|
|
|
136
136
|
|
|
137
137
|
model_config = {"extra": "allow"}
|
|
138
138
|
|
|
139
|
-
type: str | list[str] = Field(
|
|
139
|
+
type: str | list[str] = Field(
|
|
140
|
+
default="string", description="JSON Schema type (string or array for nullable)"
|
|
141
|
+
)
|
|
140
142
|
description: str = Field(default="", description="Property description")
|
|
141
143
|
default: Any | None = Field(default=None, description="Default value")
|
|
142
144
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: DeepFabric
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.9.0
|
|
4
4
|
Summary: Curate High Quality Datasets, Train, Evaluate and Ship
|
|
5
5
|
Author-email: DeepFabric Team <oss@alwaysfurther.ai>
|
|
6
6
|
License-File: LICENSE
|
|
@@ -11,7 +11,7 @@ Requires-Dist: componentize-py>=0.19.3
|
|
|
11
11
|
Requires-Dist: datasets<5.0,>=3.0
|
|
12
12
|
Requires-Dist: google-api-core>=2.0.0
|
|
13
13
|
Requires-Dist: google-genai>=1.56.0
|
|
14
|
-
Requires-Dist: huggingface-hub
|
|
14
|
+
Requires-Dist: huggingface-hub>=1.3.1
|
|
15
15
|
Requires-Dist: kagglehub>=0.3.0
|
|
16
16
|
Requires-Dist: mermaid-py>=0.8.0
|
|
17
17
|
Requires-Dist: ollama>=0.6.1
|
|
@@ -25,7 +25,7 @@ Requires-Dist: pyyaml>=6.0.1
|
|
|
25
25
|
Requires-Dist: rich>=13.0.0
|
|
26
26
|
Requires-Dist: sentencepiece>=0.1.99
|
|
27
27
|
Requires-Dist: spin-sdk>=3.4.1
|
|
28
|
-
Requires-Dist: transformers
|
|
28
|
+
Requires-Dist: transformers==5.0.0rc2
|
|
29
29
|
Provides-Extra: dev
|
|
30
30
|
Requires-Dist: bandit>=1.7.10; extra == 'dev'
|
|
31
31
|
Requires-Dist: mermaid-py>=0.2.0; extra == 'dev'
|
|
@@ -5,7 +5,7 @@ deepfabric/builders.py,sha256=XKlKsAhsed2_M_uHft-VB-n8T1ZhAbIo_7XXc2mE3Ug,11503
|
|
|
5
5
|
deepfabric/builders_agent.py,sha256=7xaXVNzmW_vBDkxJNKR_9HveljrdljwDAFx3iu-L_-M,48468
|
|
6
6
|
deepfabric/cli.py,sha256=gf7HoXlLn-8SZHHmpNWI7dwXvv_VCzu7wCQraOJkKsc,51236
|
|
7
7
|
deepfabric/cloud_upload.py,sha256=WYaISQY1XxorNdL7_F_FYwQUPHGJr2Bb_bohAa5xpbY,27801
|
|
8
|
-
deepfabric/config.py,sha256=
|
|
8
|
+
deepfabric/config.py,sha256=5M8BhvWXGmC0rcvSlY3TKwGI8TIrYHL6xjQ95ITGs8o,34780
|
|
9
9
|
deepfabric/config_manager.py,sha256=CIOJV121tBpH_V_ljwTenvyFO31yoohPSjW0yrHCD-w,9041
|
|
10
10
|
deepfabric/constants.py,sha256=MwADziDmnt0zi9t9gG65EM7AJvIQP0FSsXgGj7Yqxm8,2578
|
|
11
11
|
deepfabric/dataset.py,sha256=bZfx35A-dt0kMflgskU9Ge-NLVesq8xNKHsrxTnNn6Q,9740
|
|
@@ -14,14 +14,14 @@ deepfabric/error_codes.py,sha256=HGGWsahUTI8UG996C74X-XgNuaPX8RHo4gOidlaJql4,176
|
|
|
14
14
|
deepfabric/exceptions.py,sha256=pEg4YFQaDEWtBoJaSkxsJJoBBp2-6EE3M7m5H7R6i_8,1586
|
|
15
15
|
deepfabric/factory.py,sha256=OCqo3w-eiYNWvK_I_egDZuWj192kf18yD3SPj8rrPxU,753
|
|
16
16
|
deepfabric/generator.py,sha256=wdGxuKQOMGY8oEpa-YvXX2ceCnzRApDgzweLHgwtjlw,44226
|
|
17
|
-
deepfabric/graph.py,sha256=
|
|
17
|
+
deepfabric/graph.py,sha256=JQ68GXnLymtR7ESfeZgdMh3YrReSPX5wEWEqXlkIR4Q,24175
|
|
18
18
|
deepfabric/hf_hub.py,sha256=hw2CWqZ3CzyAzMo552VPZKVWtuv-j0TQ2_gV5K0AUto,7670
|
|
19
19
|
deepfabric/kaggle_hub.py,sha256=CXVO1Lv3IRhdO0bp9_IQr6nUs-v5jOWi5k4EwPkbJmw,7927
|
|
20
20
|
deepfabric/loader.py,sha256=YNTGZZE-POjR0BIlx6WCT4bIzf0T4lW_fQl7ev9UFqE,18584
|
|
21
|
-
deepfabric/metrics.py,sha256=
|
|
21
|
+
deepfabric/metrics.py,sha256=txqmXDM_r6cWPjdnnEjoA5xJkCHxFrjKWTpihE_jimA,6129
|
|
22
22
|
deepfabric/progress.py,sha256=3XQQrf2pUZlyd-8eRcNATH1v0Oi8JMedVHGbhPcca-8,9354
|
|
23
|
-
deepfabric/prompts.py,sha256=
|
|
24
|
-
deepfabric/schemas.py,sha256=
|
|
23
|
+
deepfabric/prompts.py,sha256=C-zonGrzyE752oWY2zOr4ufmvVaxsxFx4E2wLuSNluI,15447
|
|
24
|
+
deepfabric/schemas.py,sha256=N1cTvXuAyV8r8YS5DSAcFgpfxF0AqVGJbbOpeT5H72g,37881
|
|
25
25
|
deepfabric/stream_simulator.py,sha256=GzvAxWxHVsuTwgXlqwXNfrTUDn6sND2kJOoQuYg88FA,3028
|
|
26
26
|
deepfabric/topic_manager.py,sha256=6YxMO6dQHaGyxghsI8iNJGP1miaekBe5Mh1WdYeLqdI,11164
|
|
27
27
|
deepfabric/topic_model.py,sha256=i_wYpw2kUl8NLodOSaqNu-C4_d6caYT1kPe_vkKjoyw,707
|
|
@@ -69,8 +69,8 @@ deepfabric/training/api_key_prompt.py,sha256=pSIMX3eDGyV9x_r7MHE4TyIsIB2SqYb8gKC
|
|
|
69
69
|
deepfabric/training/callback.py,sha256=5zdifbHA2PWILHl2cVFyO65aW7cGAQhcvDqm3s8_I0Q,13221
|
|
70
70
|
deepfabric/training/dataset_utils.py,sha256=klx8DoawEwuMigBDP-RpMAfe7FvYxRbhj599MErxBr4,7313
|
|
71
71
|
deepfabric/training/metrics_sender.py,sha256=ZCyvMv5hRu8XJnQYVGXJ9wh7HEMJ0l3Ktyi8_etOpZs,10833
|
|
72
|
-
deepfabric-4.
|
|
73
|
-
deepfabric-4.
|
|
74
|
-
deepfabric-4.
|
|
75
|
-
deepfabric-4.
|
|
76
|
-
deepfabric-4.
|
|
72
|
+
deepfabric-4.9.0.dist-info/METADATA,sha256=exOMACgFoZPhQ0xpu-x5iyo4J5-1EBiEHtu3aQ7pozI,20537
|
|
73
|
+
deepfabric-4.9.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
74
|
+
deepfabric-4.9.0.dist-info/entry_points.txt,sha256=zatevils13hfs8x29_vmUyivQ6rTtq7hE2RBusZw1Fo,50
|
|
75
|
+
deepfabric-4.9.0.dist-info/licenses/LICENSE,sha256=-qRt8wmrhQ9aMf7KhmZXc2vrTETYZF-6_T1KCeUhvHY,11340
|
|
76
|
+
deepfabric-4.9.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|