schemez 0.1.1__py3-none-any.whl → 0.2.1__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.
- schemez/__init__.py +18 -2
- schemez/helpers.py +136 -0
- schemez/schema.py +145 -1
- schemez/schemadef/__init__.py +0 -0
- schemez/schemadef/schemadef.py +120 -0
- {schemez-0.1.1.dist-info → schemez-0.2.1.dist-info}/METADATA +6 -1
- schemez-0.2.1.dist-info/RECORD +13 -0
- schemez-0.1.1.dist-info/RECORD +0 -11
- {schemez-0.1.1.dist-info → schemez-0.2.1.dist-info}/WHEEL +0 -0
- {schemez-0.1.1.dist-info → schemez-0.2.1.dist-info}/licenses/LICENSE +0 -0
schemez/__init__.py
CHANGED
@@ -1,7 +1,23 @@
|
|
1
|
-
__version__ = "0.
|
1
|
+
__version__ = "0.2.1"
|
2
2
|
|
3
3
|
|
4
4
|
from schemez.schema import Schema
|
5
5
|
from schemez.code import PythonCode, JSONCode, TOMLCode, YAMLCode
|
6
|
+
from schemez.schemadef.schemadef import (
|
7
|
+
SchemaDef,
|
8
|
+
SchemaField,
|
9
|
+
ImportedSchemaDef,
|
10
|
+
InlineSchemaDef,
|
11
|
+
)
|
6
12
|
|
7
|
-
__all__ = [
|
13
|
+
__all__ = [
|
14
|
+
"ImportedSchemaDef",
|
15
|
+
"InlineSchemaDef",
|
16
|
+
"JSONCode",
|
17
|
+
"PythonCode",
|
18
|
+
"Schema",
|
19
|
+
"SchemaDef",
|
20
|
+
"SchemaField",
|
21
|
+
"TOMLCode",
|
22
|
+
"YAMLCode",
|
23
|
+
]
|
schemez/helpers.py
CHANGED
@@ -2,7 +2,9 @@
|
|
2
2
|
|
3
3
|
from __future__ import annotations
|
4
4
|
|
5
|
+
import importlib
|
5
6
|
import os
|
7
|
+
from typing import TYPE_CHECKING, Any
|
6
8
|
|
7
9
|
from pydantic import BaseModel
|
8
10
|
|
@@ -10,6 +12,86 @@ from pydantic import BaseModel
|
|
10
12
|
StrPath = str | os.PathLike[str]
|
11
13
|
|
12
14
|
|
15
|
+
if TYPE_CHECKING:
|
16
|
+
from collections.abc import Callable
|
17
|
+
|
18
|
+
|
19
|
+
def import_callable(path: str) -> Callable[..., Any]:
|
20
|
+
"""Import a callable from a dotted path.
|
21
|
+
|
22
|
+
Supports both dot and colon notation:
|
23
|
+
- Dot notation: module.submodule.Class.method
|
24
|
+
- Colon notation: module.submodule:Class.method
|
25
|
+
|
26
|
+
Args:
|
27
|
+
path: Import path using dots and/or colon
|
28
|
+
|
29
|
+
Raises:
|
30
|
+
ValueError: If path cannot be imported or result isn't callable
|
31
|
+
"""
|
32
|
+
if not path:
|
33
|
+
msg = "Import path cannot be empty"
|
34
|
+
raise ValueError(msg)
|
35
|
+
|
36
|
+
# Normalize path - replace colon with dot if present
|
37
|
+
normalized_path = path.replace(":", ".")
|
38
|
+
parts = normalized_path.split(".")
|
39
|
+
|
40
|
+
# Try importing progressively smaller module paths
|
41
|
+
for i in range(len(parts), 0, -1):
|
42
|
+
try:
|
43
|
+
# Try current module path
|
44
|
+
module_path = ".".join(parts[:i])
|
45
|
+
module = importlib.import_module(module_path)
|
46
|
+
|
47
|
+
# Walk remaining parts as attributes
|
48
|
+
obj = module
|
49
|
+
for part in parts[i:]:
|
50
|
+
obj = getattr(obj, part)
|
51
|
+
|
52
|
+
# Check if we got a callable
|
53
|
+
if callable(obj):
|
54
|
+
return obj
|
55
|
+
|
56
|
+
msg = f"Found object at {path} but it isn't callable"
|
57
|
+
raise ValueError(msg)
|
58
|
+
|
59
|
+
except ImportError:
|
60
|
+
# Try next shorter path
|
61
|
+
continue
|
62
|
+
except AttributeError:
|
63
|
+
# Attribute not found - try next shorter path
|
64
|
+
continue
|
65
|
+
|
66
|
+
# If we get here, no import combination worked
|
67
|
+
msg = f"Could not import callable from path: {path}"
|
68
|
+
raise ValueError(msg)
|
69
|
+
|
70
|
+
|
71
|
+
def import_class(path: str) -> type:
|
72
|
+
"""Import a class from a dotted path.
|
73
|
+
|
74
|
+
Args:
|
75
|
+
path: Dot-separated path to the class
|
76
|
+
|
77
|
+
Returns:
|
78
|
+
The imported class
|
79
|
+
|
80
|
+
Raises:
|
81
|
+
ValueError: If path is invalid or doesn't point to a class
|
82
|
+
"""
|
83
|
+
try:
|
84
|
+
obj = import_callable(path)
|
85
|
+
if not isinstance(obj, type):
|
86
|
+
msg = f"{path} is not a class"
|
87
|
+
raise TypeError(msg) # noqa: TRY301
|
88
|
+
except Exception as exc:
|
89
|
+
msg = f"Failed to import class from {path}"
|
90
|
+
raise ValueError(msg) from exc
|
91
|
+
else:
|
92
|
+
return obj
|
93
|
+
|
94
|
+
|
13
95
|
def merge_models[T: BaseModel](base: T, overlay: T) -> T:
|
14
96
|
"""Deep merge two Pydantic models."""
|
15
97
|
if not isinstance(overlay, type(base)):
|
@@ -33,3 +115,57 @@ def merge_models[T: BaseModel](base: T, overlay: T) -> T:
|
|
33
115
|
merged_data[field_name] = field_value
|
34
116
|
|
35
117
|
return base.__class__.model_validate(merged_data)
|
118
|
+
|
119
|
+
|
120
|
+
def resolve_type_string(type_string: str, safe: bool = True) -> type:
|
121
|
+
"""Convert a string representation to an actual Python type.
|
122
|
+
|
123
|
+
Args:
|
124
|
+
type_string: String representation of a type (e.g. "list[str]", "int")
|
125
|
+
safe: If True, uses a limited set of allowed types. If False, allows any valid
|
126
|
+
Python type expression but has potential security implications
|
127
|
+
if input is untrusted
|
128
|
+
|
129
|
+
Returns:
|
130
|
+
The corresponding Python type
|
131
|
+
|
132
|
+
Raises:
|
133
|
+
ValueError: If the type string cannot be resolved
|
134
|
+
"""
|
135
|
+
if safe:
|
136
|
+
# Create a safe context with just the allowed types
|
137
|
+
type_context = {
|
138
|
+
"str": str,
|
139
|
+
"int": int,
|
140
|
+
"float": float,
|
141
|
+
"bool": bool,
|
142
|
+
"list": list,
|
143
|
+
"dict": dict,
|
144
|
+
"set": set,
|
145
|
+
"tuple": tuple,
|
146
|
+
"Any": Any,
|
147
|
+
# Add other safe types as needed
|
148
|
+
}
|
149
|
+
|
150
|
+
try:
|
151
|
+
return eval(type_string, {"__builtins__": {}}, type_context)
|
152
|
+
except Exception as e:
|
153
|
+
msg = f"Failed to resolve type {type_string} in safe mode"
|
154
|
+
raise ValueError(msg) from e
|
155
|
+
else: # unsafe mode
|
156
|
+
# Import common typing modules to make them available
|
157
|
+
import collections.abc
|
158
|
+
import typing
|
159
|
+
|
160
|
+
# Create a context with full typing module available
|
161
|
+
type_context = {
|
162
|
+
**vars(typing),
|
163
|
+
**vars(collections.abc),
|
164
|
+
**{t.__name__: t for t in __builtins__.values() if isinstance(t, type)}, # type: ignore
|
165
|
+
}
|
166
|
+
|
167
|
+
try:
|
168
|
+
return eval(type_string, {"__builtins__": {}}, type_context)
|
169
|
+
except Exception as e:
|
170
|
+
msg = f"Failed to resolve type {type_string} in unsafe mode"
|
171
|
+
raise ValueError(msg) from e
|
schemez/schema.py
CHANGED
@@ -3,8 +3,9 @@
|
|
3
3
|
from __future__ import annotations
|
4
4
|
|
5
5
|
import os
|
6
|
-
from typing import TYPE_CHECKING, Any, Self
|
6
|
+
from typing import TYPE_CHECKING, Any, Literal, Self
|
7
7
|
|
8
|
+
import anyenv
|
8
9
|
from pydantic import BaseModel, ConfigDict
|
9
10
|
import upath
|
10
11
|
|
@@ -12,8 +13,15 @@ import upath
|
|
12
13
|
if TYPE_CHECKING:
|
13
14
|
from collections.abc import Callable
|
14
15
|
|
16
|
+
from llmling_agent.agent.agent import AgentType
|
17
|
+
from llmling_agent.models.content import BaseContent
|
18
|
+
|
15
19
|
|
16
20
|
StrPath = str | os.PathLike[str]
|
21
|
+
SourceType = Literal["pdf", "image"]
|
22
|
+
|
23
|
+
DEFAULT_SYSTEM_PROMPT = "You are a schema extractor for {name} BaseModels."
|
24
|
+
DEFAULT_USER_PROMPT = "Extract information from this document:"
|
17
25
|
|
18
26
|
|
19
27
|
class Schema(BaseModel):
|
@@ -58,6 +66,142 @@ class Schema(BaseModel):
|
|
58
66
|
|
59
67
|
return get_function_model(func, name=name)
|
60
68
|
|
69
|
+
@classmethod
|
70
|
+
def from_vision_llm_sync(
|
71
|
+
cls,
|
72
|
+
file_content: bytes,
|
73
|
+
source_type: SourceType = "pdf",
|
74
|
+
model: str = "google-gla:gemini-2.0-flash",
|
75
|
+
system_prompt: str = DEFAULT_SYSTEM_PROMPT,
|
76
|
+
user_prompt: str = DEFAULT_USER_PROMPT,
|
77
|
+
provider: AgentType = "pydantic_ai",
|
78
|
+
) -> Self:
|
79
|
+
"""Create a schema model from a document using AI.
|
80
|
+
|
81
|
+
Args:
|
82
|
+
file_content: The document content to create a schema from
|
83
|
+
source_type: The type of the document
|
84
|
+
model: The AI model to use for schema extraction
|
85
|
+
system_prompt: The system prompt to use for schema extraction
|
86
|
+
user_prompt: The user prompt to use for schema extraction
|
87
|
+
provider: The provider to use for schema extraction
|
88
|
+
|
89
|
+
Returns:
|
90
|
+
A new schema model class based on the document
|
91
|
+
"""
|
92
|
+
from llmling_agent import Agent, ImageBase64Content, PDFBase64Content
|
93
|
+
|
94
|
+
if source_type == "pdf":
|
95
|
+
content: BaseContent = PDFBase64Content.from_bytes(file_content)
|
96
|
+
else:
|
97
|
+
content = ImageBase64Content.from_bytes(file_content)
|
98
|
+
agent = Agent[None]( # type:ignore[var-annotated]
|
99
|
+
model=model,
|
100
|
+
system_prompt=system_prompt.format(name=cls.__name__),
|
101
|
+
provider=provider,
|
102
|
+
).to_structured(cls)
|
103
|
+
chat_message = anyenv.run_sync(agent.run(user_prompt, content))
|
104
|
+
return chat_message.content
|
105
|
+
|
106
|
+
@classmethod
|
107
|
+
async def from_vision_llm(
|
108
|
+
cls,
|
109
|
+
file_content: bytes,
|
110
|
+
source_type: SourceType = "pdf",
|
111
|
+
model: str = "google-gla:gemini-2.0-flash",
|
112
|
+
system_prompt: str = DEFAULT_SYSTEM_PROMPT,
|
113
|
+
user_prompt: str = DEFAULT_USER_PROMPT,
|
114
|
+
provider: AgentType = "pydantic_ai",
|
115
|
+
) -> Self:
|
116
|
+
"""Create a schema model from a document using AI.
|
117
|
+
|
118
|
+
Args:
|
119
|
+
file_content: The document content to create a schema from
|
120
|
+
source_type: The type of the document
|
121
|
+
model: The AI model to use for schema extraction
|
122
|
+
system_prompt: The system prompt to use for schema extraction
|
123
|
+
user_prompt: The user prompt to use for schema extraction
|
124
|
+
provider: The provider to use for schema extraction
|
125
|
+
|
126
|
+
Returns:
|
127
|
+
A new schema model class based on the document
|
128
|
+
"""
|
129
|
+
from llmling_agent import Agent, ImageBase64Content, PDFBase64Content
|
130
|
+
|
131
|
+
if source_type == "pdf":
|
132
|
+
content: BaseContent = PDFBase64Content.from_bytes(file_content)
|
133
|
+
else:
|
134
|
+
content = ImageBase64Content.from_bytes(file_content)
|
135
|
+
agent = Agent[None]( # type:ignore[var-annotated]
|
136
|
+
model=model,
|
137
|
+
system_prompt=system_prompt.format(name=cls.__name__),
|
138
|
+
provider=provider,
|
139
|
+
).to_structured(cls)
|
140
|
+
chat_message = await agent.run(user_prompt, content)
|
141
|
+
return chat_message.content
|
142
|
+
|
143
|
+
@classmethod
|
144
|
+
def from_llm_sync(
|
145
|
+
cls,
|
146
|
+
text: str,
|
147
|
+
model: str = "google-gla:gemini-2.0-flash",
|
148
|
+
system_prompt: str = DEFAULT_SYSTEM_PROMPT,
|
149
|
+
user_prompt: str = DEFAULT_USER_PROMPT,
|
150
|
+
provider: AgentType = "pydantic_ai",
|
151
|
+
) -> Self:
|
152
|
+
"""Create a schema model from a text snippet using AI.
|
153
|
+
|
154
|
+
Args:
|
155
|
+
text: The text to create a schema from
|
156
|
+
model: The AI model to use for schema extraction
|
157
|
+
system_prompt: The system prompt to use for schema extraction
|
158
|
+
user_prompt: The user prompt to use for schema extraction
|
159
|
+
provider: The provider to use for schema extraction
|
160
|
+
|
161
|
+
Returns:
|
162
|
+
A new schema model class based on the document
|
163
|
+
"""
|
164
|
+
from llmling_agent import Agent
|
165
|
+
|
166
|
+
agent = Agent[None]( # type:ignore[var-annotated]
|
167
|
+
model=model,
|
168
|
+
system_prompt=system_prompt.format(name=cls.__name__),
|
169
|
+
provider=provider,
|
170
|
+
).to_structured(cls)
|
171
|
+
chat_message = anyenv.run_sync(agent.run(user_prompt, text))
|
172
|
+
return chat_message.content
|
173
|
+
|
174
|
+
@classmethod
|
175
|
+
async def from_llm(
|
176
|
+
cls,
|
177
|
+
text: str,
|
178
|
+
model: str = "google-gla:gemini-2.0-flash",
|
179
|
+
system_prompt: str = DEFAULT_SYSTEM_PROMPT,
|
180
|
+
user_prompt: str = DEFAULT_USER_PROMPT,
|
181
|
+
provider: AgentType = "pydantic_ai",
|
182
|
+
) -> Self:
|
183
|
+
"""Create a schema model from a text snippet using AI.
|
184
|
+
|
185
|
+
Args:
|
186
|
+
text: The text to create a schema from
|
187
|
+
model: The AI model to use for schema extraction
|
188
|
+
system_prompt: The system prompt to use for schema extraction
|
189
|
+
user_prompt: The user prompt to use for schema extraction
|
190
|
+
provider: The provider to use for schema extraction
|
191
|
+
|
192
|
+
Returns:
|
193
|
+
A new schema model class based on the document
|
194
|
+
"""
|
195
|
+
from llmling_agent import Agent
|
196
|
+
|
197
|
+
agent = Agent[None]( # type:ignore[var-annotated]
|
198
|
+
model=model,
|
199
|
+
system_prompt=system_prompt.format(name=cls.__name__),
|
200
|
+
provider=provider,
|
201
|
+
).to_structured(cls)
|
202
|
+
chat_message = await agent.run(user_prompt, text)
|
203
|
+
return chat_message.content
|
204
|
+
|
61
205
|
@classmethod
|
62
206
|
def for_class_ctor(cls, target_cls: type) -> type[Schema]:
|
63
207
|
"""Create a schema model from a class constructor.
|
File without changes
|
@@ -0,0 +1,120 @@
|
|
1
|
+
"""Models for schema fields and definitions."""
|
2
|
+
|
3
|
+
from __future__ import annotations
|
4
|
+
|
5
|
+
from typing import Annotated, Any, Literal
|
6
|
+
|
7
|
+
from pydantic import BaseModel, Field, create_model
|
8
|
+
|
9
|
+
from schemez import Schema, helpers
|
10
|
+
|
11
|
+
|
12
|
+
class SchemaField(Schema):
|
13
|
+
"""Field definition for inline response types.
|
14
|
+
|
15
|
+
Defines a single field in an inline response definition, including:
|
16
|
+
- Data type specification
|
17
|
+
- Optional description
|
18
|
+
- Validation constraints
|
19
|
+
|
20
|
+
Used by InlineSchemaDef to structure response fields.
|
21
|
+
"""
|
22
|
+
|
23
|
+
type: str
|
24
|
+
"""Data type of the response field"""
|
25
|
+
|
26
|
+
description: str | None = None
|
27
|
+
"""Optional description of what this field represents"""
|
28
|
+
|
29
|
+
constraints: dict[str, Any] = Field(default_factory=dict)
|
30
|
+
"""Optional validation constraints for the field"""
|
31
|
+
|
32
|
+
|
33
|
+
class BaseSchemaDef(Schema):
|
34
|
+
"""Base class for response definitions."""
|
35
|
+
|
36
|
+
type: str = Field(init=False)
|
37
|
+
|
38
|
+
description: str | None = None
|
39
|
+
"""A description for this response definition."""
|
40
|
+
|
41
|
+
|
42
|
+
class InlineSchemaDef(BaseSchemaDef):
|
43
|
+
"""Inline definition of schema.
|
44
|
+
|
45
|
+
Allows defining response types directly in the configuration using:
|
46
|
+
- Field definitions with types and descriptions
|
47
|
+
- Optional validation constraints
|
48
|
+
- Custom field descriptions
|
49
|
+
|
50
|
+
Example:
|
51
|
+
schemas:
|
52
|
+
BasicResult:
|
53
|
+
type: inline
|
54
|
+
fields:
|
55
|
+
success: {type: bool, description: "Operation success"}
|
56
|
+
message: {type: str, description: "Result details"}
|
57
|
+
"""
|
58
|
+
|
59
|
+
type: Literal["inline"] = Field("inline", init=False)
|
60
|
+
"""Inline response definition."""
|
61
|
+
|
62
|
+
fields: dict[str, SchemaField]
|
63
|
+
"""A dictionary containing all fields."""
|
64
|
+
|
65
|
+
def get_schema(self) -> type[Schema]: # type: ignore
|
66
|
+
"""Create Pydantic model from inline definition."""
|
67
|
+
fields = {}
|
68
|
+
for name, field in self.fields.items():
|
69
|
+
python_type = helpers.resolve_type_string(field.type)
|
70
|
+
if not python_type:
|
71
|
+
msg = f"Unsupported field type: {field.type}"
|
72
|
+
raise ValueError(msg)
|
73
|
+
|
74
|
+
field_info = Field(description=field.description, **(field.constraints))
|
75
|
+
fields[name] = (python_type, field_info)
|
76
|
+
|
77
|
+
cls_name = self.description or "ResponseType"
|
78
|
+
return create_model(cls_name, **fields, __base__=Schema, __doc__=self.description) # type: ignore[call-overload]
|
79
|
+
|
80
|
+
|
81
|
+
class ImportedSchemaDef(BaseSchemaDef):
|
82
|
+
"""Response definition that imports an existing Pydantic model.
|
83
|
+
|
84
|
+
Allows using externally defined Pydantic models as response types.
|
85
|
+
Benefits:
|
86
|
+
- Reuse existing model definitions
|
87
|
+
- Full Python type support
|
88
|
+
- Complex validation logic
|
89
|
+
- IDE support for imported types
|
90
|
+
|
91
|
+
Example:
|
92
|
+
responses:
|
93
|
+
AnalysisResult:
|
94
|
+
type: import
|
95
|
+
import_path: myapp.models.AnalysisResult
|
96
|
+
"""
|
97
|
+
|
98
|
+
type: Literal["import"] = Field("import", init=False)
|
99
|
+
"""Import-path based response definition."""
|
100
|
+
|
101
|
+
import_path: str
|
102
|
+
"""The path to the pydantic model to use as the response type."""
|
103
|
+
|
104
|
+
# mypy is confused about "type"
|
105
|
+
# TODO: convert BaseModel to Schema?
|
106
|
+
def get_schema(self) -> type[BaseModel]: # type: ignore
|
107
|
+
"""Import and return the model class."""
|
108
|
+
try:
|
109
|
+
model_class = helpers.import_class(self.import_path)
|
110
|
+
if not issubclass(model_class, BaseModel):
|
111
|
+
msg = f"{self.import_path} must be a Pydantic model"
|
112
|
+
raise TypeError(msg) # noqa: TRY301
|
113
|
+
except Exception as e:
|
114
|
+
msg = f"Failed to import response type {self.import_path}"
|
115
|
+
raise ValueError(msg) from e
|
116
|
+
else:
|
117
|
+
return model_class
|
118
|
+
|
119
|
+
|
120
|
+
SchemaDef = Annotated[InlineSchemaDef | ImportedSchemaDef, Field(discriminator="type")]
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: schemez
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.2.1
|
4
4
|
Summary: Pydantic shim for config stuff
|
5
5
|
Project-URL: Documentation, https://phil65.github.io/schemez/
|
6
6
|
Project-URL: Source, https://github.com/phil65/schemez
|
@@ -49,6 +49,11 @@ Requires-Python: >=3.12
|
|
49
49
|
Requires-Dist: griffe>=1.7.3
|
50
50
|
Requires-Dist: pydantic
|
51
51
|
Requires-Dist: universal-pathlib>=0.2.6
|
52
|
+
Provides-Extra: ai
|
53
|
+
Requires-Dist: anyenv>=0.4.14; extra == 'ai'
|
54
|
+
Requires-Dist: llmling-agent; extra == 'ai'
|
55
|
+
Provides-Extra: yaml
|
56
|
+
Requires-Dist: yamling; extra == 'yaml'
|
52
57
|
Description-Content-Type: text/markdown
|
53
58
|
|
54
59
|
# Schemez
|
@@ -0,0 +1,13 @@
|
|
1
|
+
schemez/__init__.py,sha256=gniCM7yfehxd93fGd154YFF-4suRuZtRbQwJVg-63cU,423
|
2
|
+
schemez/code.py,sha256=usZLov9i5KpK1W2VJxngUzeetgrINtodiooG_AxN-y4,2072
|
3
|
+
schemez/convert.py,sha256=b6Sz11lq0HvpXfMREOqnnw8rcVg2XzTKhjjPNc4YIoE,4403
|
4
|
+
schemez/docstrings.py,sha256=kmd660wcomXzKac0SSNYxPRNbVCUovrpmE9jwnVRS6c,4115
|
5
|
+
schemez/helpers.py,sha256=Ee3wvFbt65ljhWDFdb6ACVUJK4KLjJFVzl4Le75pOBQ,5159
|
6
|
+
schemez/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
|
+
schemez/schema.py,sha256=8nwLYW6J-RIMbKjt0BZK3zlktZZzBYXabGFlaQsecCQ,8538
|
8
|
+
schemez/schemadef/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
9
|
+
schemez/schemadef/schemadef.py,sha256=TLfcmCxPLZEvScxuIMlss0QDRWtQNhxLQ8z2i0Linoc,3794
|
10
|
+
schemez-0.2.1.dist-info/METADATA,sha256=sd3YrOY6JfwDjhkO9sidYWd8BhqhQDLxW0pmxrwG3_4,5891
|
11
|
+
schemez-0.2.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
12
|
+
schemez-0.2.1.dist-info/licenses/LICENSE,sha256=AteGCH9r177TxxrOFEiOARrastASsf7yW6MQxlAHdwA,1078
|
13
|
+
schemez-0.2.1.dist-info/RECORD,,
|
schemez-0.1.1.dist-info/RECORD
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
schemez/__init__.py,sha256=5rZvW7U4pMKyiONvY8rok5fVr6Bw8hjN8Kz8xnfmzoI,196
|
2
|
-
schemez/code.py,sha256=usZLov9i5KpK1W2VJxngUzeetgrINtodiooG_AxN-y4,2072
|
3
|
-
schemez/convert.py,sha256=b6Sz11lq0HvpXfMREOqnnw8rcVg2XzTKhjjPNc4YIoE,4403
|
4
|
-
schemez/docstrings.py,sha256=kmd660wcomXzKac0SSNYxPRNbVCUovrpmE9jwnVRS6c,4115
|
5
|
-
schemez/helpers.py,sha256=_leGedEf5AoeQOV0eyrJpDnvDOPB5XV3pd5YNANASeI,1081
|
6
|
-
schemez/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
|
-
schemez/schema.py,sha256=qlkNigpDQJIopjSjfS4yp8vXReCr2o2eWBEDjIN7YjM,3021
|
8
|
-
schemez-0.1.1.dist-info/METADATA,sha256=I4hRIS0_WvWnmdr9Fs1-1jhvnScc27WKua0fXwJGU8w,5722
|
9
|
-
schemez-0.1.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
10
|
-
schemez-0.1.1.dist-info/licenses/LICENSE,sha256=AteGCH9r177TxxrOFEiOARrastASsf7yW6MQxlAHdwA,1078
|
11
|
-
schemez-0.1.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|