datamaker-py 0.7.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.
- datamaker/__init__.py +2 -0
- datamaker/core.py +11 -0
- datamaker/error.py +2 -0
- datamaker/main.py +886 -0
- datamaker/routes/__init__.py +37 -0
- datamaker/routes/api_keys.py +50 -0
- datamaker/routes/base.py +40 -0
- datamaker/routes/connections.py +87 -0
- datamaker/routes/custom_types.py +100 -0
- datamaker/routes/export_and_validation.py +25 -0
- datamaker/routes/folders_and_utils.py +80 -0
- datamaker/routes/generation.py +14 -0
- datamaker/routes/projects.py +35 -0
- datamaker/routes/scenario_files.py +453 -0
- datamaker/routes/sets.py +177 -0
- datamaker/routes/teams.py +62 -0
- datamaker/routes/templates.py +69 -0
- datamaker/routes/users.py +43 -0
- datamaker/template.py +162 -0
- datamaker_py-0.7.0.dist-info/METADATA +79 -0
- datamaker_py-0.7.0.dist-info/RECORD +24 -0
- datamaker_py-0.7.0.dist-info/WHEEL +5 -0
- datamaker_py-0.7.0.dist-info/licenses/LICENSE +21 -0
- datamaker_py-0.7.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
from .base import BaseClient
|
|
2
|
+
from ..error import DataMakerError
|
|
3
|
+
from typing import Dict, List
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TemplatesClient(BaseClient):
|
|
7
|
+
"""Client for template operations."""
|
|
8
|
+
|
|
9
|
+
def get_templates(self) -> List[Dict]:
|
|
10
|
+
"""Fetch all templates from the API."""
|
|
11
|
+
response = self._make_request("GET", "/templates")
|
|
12
|
+
return response.json()
|
|
13
|
+
|
|
14
|
+
def create_template(
|
|
15
|
+
self, template_data: Dict, project_id: str, team_id: str
|
|
16
|
+
) -> Dict:
|
|
17
|
+
"""Create a new template."""
|
|
18
|
+
# Ensure required fields are present
|
|
19
|
+
template_data["projectId"] = project_id
|
|
20
|
+
template_data["teamId"] = team_id
|
|
21
|
+
|
|
22
|
+
# Ensure all fields have the 'active' property set to True by default
|
|
23
|
+
if "fields" in template_data:
|
|
24
|
+
for field in template_data["fields"]:
|
|
25
|
+
if "active" not in field:
|
|
26
|
+
field["active"] = True
|
|
27
|
+
|
|
28
|
+
response = self._make_request("POST", "/templates", json=template_data)
|
|
29
|
+
return response.json()
|
|
30
|
+
|
|
31
|
+
def get_template(self, template_id: str) -> Dict:
|
|
32
|
+
"""Get a specific template by ID."""
|
|
33
|
+
response = self._make_request("GET", f"/templates/{template_id}")
|
|
34
|
+
return response.json()
|
|
35
|
+
|
|
36
|
+
def update_template(self, template_id: str, template_data: Dict) -> Dict:
|
|
37
|
+
"""Update a template."""
|
|
38
|
+
response = self._make_request(
|
|
39
|
+
"PUT", f"/templates/{template_id}", json=template_data
|
|
40
|
+
)
|
|
41
|
+
return response.json()
|
|
42
|
+
|
|
43
|
+
def delete_template(self, template_id: str) -> Dict:
|
|
44
|
+
"""Delete a template."""
|
|
45
|
+
response = self._make_request("DELETE", f"/templates/{template_id}")
|
|
46
|
+
return response.json()
|
|
47
|
+
|
|
48
|
+
def get_template_by_id(self, template_id: str) -> Dict:
|
|
49
|
+
"""Get a specific template by ID (legacy method for backward compatibility)."""
|
|
50
|
+
try:
|
|
51
|
+
# Try direct API call first (more efficient)
|
|
52
|
+
return self.get_template(template_id)
|
|
53
|
+
except:
|
|
54
|
+
# Fallback to searching through all templates (legacy behavior)
|
|
55
|
+
templates = self.get_templates()
|
|
56
|
+
|
|
57
|
+
if not templates:
|
|
58
|
+
raise DataMakerError("No templates found in your account.")
|
|
59
|
+
|
|
60
|
+
template = next(
|
|
61
|
+
(temp for temp in templates if temp["id"] == template_id), None
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
if not template:
|
|
65
|
+
raise DataMakerError(
|
|
66
|
+
"You must provide ID of a template from your account."
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
return template
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from .base import BaseClient
|
|
2
|
+
from typing import Optional, Dict, List
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class UsersClient(BaseClient):
|
|
6
|
+
"""Client for user management operations."""
|
|
7
|
+
|
|
8
|
+
def get_users(self) -> List[Dict]:
|
|
9
|
+
"""Get all users."""
|
|
10
|
+
response = self._make_request("GET", "/users")
|
|
11
|
+
return response.json()
|
|
12
|
+
|
|
13
|
+
def create_user(self, user_data: Dict, user_id: str) -> Dict:
|
|
14
|
+
"""Create a new user."""
|
|
15
|
+
# Ensure required id is present
|
|
16
|
+
user_data["id"] = user_id
|
|
17
|
+
response = self._make_request("POST", "/users", json=user_data)
|
|
18
|
+
return response.json()
|
|
19
|
+
|
|
20
|
+
def get_current_user(self) -> Dict:
|
|
21
|
+
"""Get current user information."""
|
|
22
|
+
response = self._make_request("GET", "/users/me")
|
|
23
|
+
return response.json()
|
|
24
|
+
|
|
25
|
+
def provision_user(self, user_data: Dict) -> Dict:
|
|
26
|
+
"""Provision a new user."""
|
|
27
|
+
response = self._make_request("POST", "/users/provision", json=user_data)
|
|
28
|
+
return response.json()
|
|
29
|
+
|
|
30
|
+
def update_user(self, user_id: str, user_data: Dict) -> Dict:
|
|
31
|
+
"""Update a user."""
|
|
32
|
+
response = self._make_request("PUT", f"/users/{user_id}", json=user_data)
|
|
33
|
+
return response.json()
|
|
34
|
+
|
|
35
|
+
def patch_user(self, user_id: str, user_data: Dict) -> Dict:
|
|
36
|
+
"""Partially update a user."""
|
|
37
|
+
response = self._make_request("PATCH", f"/users/{user_id}", json=user_data)
|
|
38
|
+
return response.json()
|
|
39
|
+
|
|
40
|
+
def delete_user(self, user_id: str) -> Dict:
|
|
41
|
+
"""Delete a user."""
|
|
42
|
+
response = self._make_request("DELETE", f"/users/{user_id}")
|
|
43
|
+
return response.json()
|
datamaker/template.py
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
from typing import Optional, Dict, List, Union
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class WordsField:
|
|
5
|
+
def __init__(self, name: str, options: Optional[Dict[str, int]] = None):
|
|
6
|
+
self.name = name
|
|
7
|
+
self.type = "Words"
|
|
8
|
+
self.options = options
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class UUIDField:
|
|
12
|
+
def __init__(self, name: str, options: Optional[Dict[str, bool]] = None):
|
|
13
|
+
self.name = name
|
|
14
|
+
self.type = "UUID"
|
|
15
|
+
self.options = options
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class NumberField:
|
|
19
|
+
def __init__(
|
|
20
|
+
self, name: str, options: Optional[Dict[str, Union[int, bool]]] = None
|
|
21
|
+
):
|
|
22
|
+
self.name = name
|
|
23
|
+
self.type = "Number"
|
|
24
|
+
self.options = options
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class FloatField:
|
|
28
|
+
def __init__(
|
|
29
|
+
self, name: str, options: Optional[Dict[str, Union[int, float]]] = None
|
|
30
|
+
):
|
|
31
|
+
self.name = name
|
|
32
|
+
self.type = "Float"
|
|
33
|
+
self.options = options
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class BooleanField:
|
|
37
|
+
def __init__(self, name: str, options: Optional[Dict[str, bool]] = None):
|
|
38
|
+
self.name = name
|
|
39
|
+
self.type = "Boolean"
|
|
40
|
+
self.options = options
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class AIField:
|
|
44
|
+
def __init__(self, name: str, prompt: str):
|
|
45
|
+
self.name = name
|
|
46
|
+
self.type = "AI"
|
|
47
|
+
self.options = {"prompt": prompt}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class CustomField:
|
|
51
|
+
def __init__(self, name: str, values: List[str]):
|
|
52
|
+
self.name = name
|
|
53
|
+
self.type = "Custom"
|
|
54
|
+
self.options = {"values": values}
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
# Similar classes would follow for each field type defined in the TypeScript code
|
|
58
|
+
|
|
59
|
+
DataMakerField = Union[
|
|
60
|
+
WordsField,
|
|
61
|
+
UUIDField,
|
|
62
|
+
NumberField,
|
|
63
|
+
FloatField,
|
|
64
|
+
BooleanField,
|
|
65
|
+
AIField,
|
|
66
|
+
CustomField, # Add other field classes here
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class Template:
|
|
71
|
+
def __init__(
|
|
72
|
+
self,
|
|
73
|
+
fields: List[DataMakerField],
|
|
74
|
+
name: Optional[str] = None,
|
|
75
|
+
quantity: Optional[int] = None,
|
|
76
|
+
):
|
|
77
|
+
self.name = name
|
|
78
|
+
self.fields = fields
|
|
79
|
+
self.quantity = quantity
|
|
80
|
+
|
|
81
|
+
def to_dict(self):
|
|
82
|
+
return {
|
|
83
|
+
"name": self.name,
|
|
84
|
+
"fields": [
|
|
85
|
+
field.__dict__ if hasattr(field, "__dict__") else field
|
|
86
|
+
for field in self.fields
|
|
87
|
+
],
|
|
88
|
+
"quantity": self.quantity,
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class AccountTemplate:
|
|
93
|
+
def __init__(
|
|
94
|
+
self,
|
|
95
|
+
id: str,
|
|
96
|
+
name: str,
|
|
97
|
+
fields: List[DataMakerField],
|
|
98
|
+
created_at: str,
|
|
99
|
+
created_by: str,
|
|
100
|
+
template_folder_id: Optional[None] = None,
|
|
101
|
+
team_id: str = "",
|
|
102
|
+
seed: Optional[None] = None,
|
|
103
|
+
):
|
|
104
|
+
self.id = id
|
|
105
|
+
self.name = name
|
|
106
|
+
self.fields = fields
|
|
107
|
+
self.created_at = created_at
|
|
108
|
+
self.created_by = created_by
|
|
109
|
+
self.template_folder_id = template_folder_id
|
|
110
|
+
self.team_id = team_id
|
|
111
|
+
self.seed = seed
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class Endpoint:
|
|
115
|
+
def __init__(
|
|
116
|
+
self,
|
|
117
|
+
id: str,
|
|
118
|
+
name: str,
|
|
119
|
+
method: str,
|
|
120
|
+
url: str,
|
|
121
|
+
headers: Optional[Dict] = None,
|
|
122
|
+
query_params: Optional[Dict] = None,
|
|
123
|
+
created_at: str = "",
|
|
124
|
+
created_by: str = "",
|
|
125
|
+
team_id: Optional[str] = None,
|
|
126
|
+
endpoint_folder_id: Optional[Union[str, None]] = None,
|
|
127
|
+
):
|
|
128
|
+
self.id = id
|
|
129
|
+
self.name = name
|
|
130
|
+
self.method = method
|
|
131
|
+
self.url = url
|
|
132
|
+
self.headers = headers
|
|
133
|
+
self.query_params = query_params
|
|
134
|
+
self.created_at = created_at
|
|
135
|
+
self.created_by = created_by
|
|
136
|
+
self.team_id = team_id
|
|
137
|
+
self.endpoint_folder_id = endpoint_folder_id
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class Headers:
|
|
141
|
+
def __init__(
|
|
142
|
+
self, authorization: Optional[str], content_type: str, credentials: str
|
|
143
|
+
):
|
|
144
|
+
self.Authorization = authorization
|
|
145
|
+
self.Content_type = content_type
|
|
146
|
+
self.Credentials = credentials
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
Data = Dict[str, Union[str, int]]
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
class CustomEndpoint:
|
|
153
|
+
def __init__(self, url: str, method: str, headers: Optional[Dict] = None):
|
|
154
|
+
self.url = url
|
|
155
|
+
self.method = method
|
|
156
|
+
self.headers = headers
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class DBQuery:
|
|
160
|
+
def __init__(self, connection_id: str, query: str):
|
|
161
|
+
self.connection_id = connection_id
|
|
162
|
+
self.query = query
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: datamaker-py
|
|
3
|
+
Version: 0.7.0
|
|
4
|
+
Summary: The official Python library for the Automators DataMaker API.
|
|
5
|
+
Requires-Python: >=3.11
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Dist: python-dotenv>=1.0.1
|
|
9
|
+
Requires-Dist: requests>=2.32.3
|
|
10
|
+
Dynamic: license-file
|
|
11
|
+
|
|
12
|
+
# DataMaker
|
|
13
|
+
|
|
14
|
+
[](https://opensource.org/licenses/MIT)
|
|
15
|
+
[](https://github.com/astral-sh/uv)
|
|
16
|
+
[](https://github.com/charliermarsh/ruff)
|
|
17
|
+
|
|
18
|
+
The official Python library for the Automators DataMaker API.
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
You can install the package using pip:
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
pip install datamaker-py
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Quick start
|
|
29
|
+
|
|
30
|
+
Basic example:
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
from datamaker import DataMaker, Template
|
|
34
|
+
|
|
35
|
+
# Create an instance of DataMaker
|
|
36
|
+
datamaker = DataMaker()
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def main():
|
|
40
|
+
# Define the template
|
|
41
|
+
template = Template(
|
|
42
|
+
name="basic template",
|
|
43
|
+
quantity=2,
|
|
44
|
+
fields=[
|
|
45
|
+
{"name": "first_name", "type": "First Name"},
|
|
46
|
+
{"name": "last_name", "type": "Last Name"},
|
|
47
|
+
{
|
|
48
|
+
"name": "email",
|
|
49
|
+
"type": "Derived",
|
|
50
|
+
"options": {"value": "{{first_name}}.{{last_name}}@automators.com"},
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
# Generate data using the template
|
|
56
|
+
result = datamaker.generate(template)
|
|
57
|
+
print(result)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
if __name__ == "__main__":
|
|
61
|
+
main()
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Autocomplete Types
|
|
66
|
+
|
|
67
|
+
This SDK automatically generates TypeScript autocomplete definitions for use in the [datamaker application](https://github.com/automators/datamaker).
|
|
68
|
+
|
|
69
|
+
The artifact is generated automatically on every push to the `main` branch and can be fetched from:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
https://raw.githubusercontent.com/automators/datamaker-py/main/artifacts/autocomplete-types.ts
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
See [`artifacts/README.md`](artifacts/README.md) for more details.
|
|
76
|
+
|
|
77
|
+
## Development & Contibutions
|
|
78
|
+
|
|
79
|
+
See the [contributing.md](/CONTRIBUTING.md) guide for details on how to contribute to this project.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
datamaker/__init__.py,sha256=B1tXOTZGJzrXaK96J1Wl2BbZSOocAwb6Sd2e_4dF3Bg,75
|
|
2
|
+
datamaker/core.py,sha256=nuXORr4CM4q3evkeQqH79A9FjVPXHEEBcs9E1xpCpKs,397
|
|
3
|
+
datamaker/error.py,sha256=dM8WkfFH5I_2gLS6pMtheSW8AQ2XPByF9tiXU8FIHus,42
|
|
4
|
+
datamaker/main.py,sha256=UdxPYSY-Z3e-F2nVzyqmsrSpgYYq4TuMDK2XtiF8Kak,31352
|
|
5
|
+
datamaker/template.py,sha256=-aeOKErtcgOq8zYzwg2802ErfqSahQ22ZvSiTMpmuns,4005
|
|
6
|
+
datamaker/routes/__init__.py,sha256=9DDq_O0ZmQfNgFMG0jN_2QupmoN78XqnBDU6igkXkzA,1129
|
|
7
|
+
datamaker/routes/api_keys.py,sha256=RmmK4_ZyNRolfzviW8SWokNSd1osnCVc1gQKV5-yQfw,1404
|
|
8
|
+
datamaker/routes/base.py,sha256=0CNj3q_W5be8DVlXDZiUCLjtBPK8lzAIdJdquv7nsec,1438
|
|
9
|
+
datamaker/routes/connections.py,sha256=6uoSCN-Pz74EV33DoEfETO2zOFLrw96XHDpR1setfl4,2926
|
|
10
|
+
datamaker/routes/custom_types.py,sha256=r5IkJdPiQ-EvsISHcyrm0uYakCOGrALl6hgeiDMQVCE,3928
|
|
11
|
+
datamaker/routes/export_and_validation.py,sha256=rqv-H7XEFcYg0HBD0H8pu9B_JmWbaLe0qNEsAPyVV1w,807
|
|
12
|
+
datamaker/routes/folders_and_utils.py,sha256=LUezjta6N4lWgDnM7JJGAfqeo-xVFdMzAB99kYSw19w,2906
|
|
13
|
+
datamaker/routes/generation.py,sha256=TNraoMdX8NFpD2I1R-I_BNOU1agxNfdIQIAlP8tanqY,406
|
|
14
|
+
datamaker/routes/projects.py,sha256=MzkWll4GOzwNumoi5NuSQVkNV8GBYz_7SjU5rl0Z-io,1270
|
|
15
|
+
datamaker/routes/scenario_files.py,sha256=gM5zkGO-rFVrrtJjDhWZmV-Eagmm8Z_DM6TD_bU5sGM,17494
|
|
16
|
+
datamaker/routes/sets.py,sha256=eleaL6p9IuoxLr71BYHj81obmjDSi6vcAIiCMcGF3H4,6100
|
|
17
|
+
datamaker/routes/teams.py,sha256=NMZOakveoaCf1rRLHbDUowRfn8nRFBeyKAS3PkNAQcc,2235
|
|
18
|
+
datamaker/routes/templates.py,sha256=Xhp6CmYf8j0xVW1-OjqsJ_n00bR0i9KDVxRXFhcme8o,2487
|
|
19
|
+
datamaker/routes/users.py,sha256=jCQUyFpfhJorYciYpVZiTUIXF4YFlIs0d1VE0VwnpU0,1570
|
|
20
|
+
datamaker_py-0.7.0.dist-info/licenses/LICENSE,sha256=ulaO3UjPXJc6FMQJ_BvZaGps8NI0bw368TEqkswlayA,1067
|
|
21
|
+
datamaker_py-0.7.0.dist-info/METADATA,sha256=HwDuoOrV29O9qRL1XclwexMhx8c4bJI81BIN1ujocU0,2211
|
|
22
|
+
datamaker_py-0.7.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
23
|
+
datamaker_py-0.7.0.dist-info/top_level.txt,sha256=XQUROqf8JRZ7xLJLziM8GWUf6HbRJIKhVSLNxTqoqQk,10
|
|
24
|
+
datamaker_py-0.7.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Automators
|
|
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.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
datamaker
|