opengradient 0.1.8__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.
opengradient/__init__.py CHANGED
@@ -2,7 +2,7 @@ from .client import Client
2
2
  from .exceptions import OpenGradientError, FileNotFoundError, UploadError, InferenceError, ResultRetrievalError
3
3
  from .types import ModelInput, InferenceMode, Number, NumberTensor, StringTensor, ModelOutput
4
4
 
5
- __version__ = "0.1.8"
5
+ __version__ = "0.2.0"
6
6
 
7
7
  _client = None
8
8
 
opengradient/cli.py ADDED
@@ -0,0 +1,184 @@
1
+ import click
2
+ import os
3
+ import opengradient
4
+ import json
5
+ import ast
6
+ from pathlib import Path
7
+ from .client import Client
8
+ from opengradient.types import InferenceMode, ModelInput
9
+
10
+ # Environment variable names
11
+ API_KEY_ENV = 'OPENGRADIENT_API_KEY'
12
+ RPC_URL_ENV = 'OPENGRADIENT_RPC_URL'
13
+ CONTRACT_ADDRESS_ENV = 'OPENGRADIENT_CONTRACT_ADDRESS'
14
+ EMAIL_ENV = 'OPENGRADIENT_EMAIL'
15
+ PASSWORD_ENV = 'OPENGRADIENT_PASSWORD'
16
+
17
+ # Convert string to dictionary click parameter typing
18
+ class DictParamType(click.ParamType):
19
+ name = "dictionary"
20
+
21
+ def convert(self, value, param, ctx):
22
+ if isinstance(value, dict):
23
+ return value
24
+ try:
25
+ # First, try to parse as JSON
26
+ return json.loads(value)
27
+ except json.JSONDecodeError:
28
+ # If JSON parsing fails, try to evaluate as a Python literal
29
+ try:
30
+ # ast.literal_eval is safer than eval as it only parses Python literals
31
+ result = ast.literal_eval(value)
32
+ if not isinstance(result, dict):
33
+ self.fail(f"'{value}' is not a valid dictionary", param, ctx)
34
+ return result
35
+ except (ValueError, SyntaxError):
36
+ self.fail(f"'{value}' is not a valid dictionary", param, ctx)
37
+
38
+ Dict = DictParamType()
39
+
40
+ # Support inference modes
41
+ InferenceModes = {
42
+ "VANILLA": opengradient.InferenceMode.VANILLA,
43
+ "ZKML": opengradient.InferenceMode.PRIVATE,
44
+ "TEE": opengradient.InferenceMode.VERIFIED,
45
+ }
46
+
47
+ # TODO (Kyle): Once we're farther into development, we should remove the defaults for these options
48
+ @click.group()
49
+ @click.option('--api_key',
50
+ envvar=API_KEY_ENV,
51
+ help='Your OpenGradient private key',
52
+ default="cd09980ef6e280afc3900d2d6801f9e9c5d858a5deaeeab74a65643f5ff1a4c1")
53
+ @click.option('--rpc_url',
54
+ envvar=RPC_URL_ENV,
55
+ help='OpenGradient RPC URL address',
56
+ default="http://18.218.115.248:8545")
57
+ @click.option('--contract_address',
58
+ envvar=CONTRACT_ADDRESS_ENV,
59
+ help='OpenGradient contract address',
60
+ default="0x350E0A430b2B1563481833a99523Cfd17a530e4e")
61
+ @click.option('--email',
62
+ envvar=EMAIL_ENV,
63
+ help='Your OpenGradient hub email address -- not required for inference',
64
+ default="test@test.com")
65
+ @click.option('--password',
66
+ envvar=PASSWORD_ENV,
67
+ help='Your OpenGradient hub password -- not required for inference',
68
+ default="Test-123")
69
+ @click.pass_context
70
+ def cli(ctx, api_key, rpc_url, contract_address, email, password):
71
+ """CLI for OpenGradient SDK"""
72
+ if not api_key:
73
+ click.echo("Please provide an API key via flag or setting environment variable OPENGRADIENT_API_KEY")
74
+ if not rpc_url:
75
+ click.echo("Please provide a RPC URL via flag or setting environment variable OPENGRADIENT_RPC_URL")
76
+ if not contract_address:
77
+ click.echo("Please provide a contract address via flag or setting environment variable OPENGRADIENT_CONTRACT_ADDRESS")
78
+ if not api_key or not rpc_url or not contract_address:
79
+ ctx.exit(1)
80
+ return
81
+
82
+ try:
83
+ ctx.obj = Client(private_key=api_key,
84
+ rpc_url=rpc_url,
85
+ contract_address=contract_address,
86
+ email=email,
87
+ password=password)
88
+ except Exception as e:
89
+ click.echo(f"Failed to create OpenGradient client: {str(e)}")
90
+
91
+ @cli.command()
92
+ @click.pass_obj
93
+ def client_settings(client):
94
+ """Display OpenGradient client settings"""
95
+ click.echo("Settings for OpenGradient client:")
96
+ click.echo(f"\tAPI key ({API_KEY_ENV}): {client.private_key}")
97
+ click.echo(f"\tRPC URL ({RPC_URL_ENV}): {client.rpc_url}")
98
+ click.echo(f"\tContract address ({CONTRACT_ADDRESS_ENV}): {client.contract_address}")
99
+ if client.user:
100
+ click.echo(f"\tEmail ({EMAIL_ENV}): {client.user["email"]}")
101
+ else:
102
+ click.echo(f"\tEmail: not set")
103
+
104
+ @cli.command()
105
+ @click.argument('model_path', type=Path)
106
+ @click.argument('model_id', type=str)
107
+ @click.argument('version_id', type=str)
108
+ @click.pass_obj
109
+ def upload(client, model_path, model_id, version_id):
110
+ """Upload a model"""
111
+ try:
112
+ result = client.upload(model_path, model_id, version_id)
113
+ click.echo(f"Model uploaded successfully: {result}")
114
+ except Exception as e:
115
+ click.echo(f"Error uploading model: {str(e)}")
116
+
117
+ @cli.command()
118
+ @click.argument('model_name', type=str)
119
+ @click.argument('model_desc', type=str)
120
+ @click.pass_obj
121
+ def create_model(client, model_name, model_desc):
122
+ """Create a new model"""
123
+ try:
124
+ result = client.create_model(model_name, model_desc)
125
+ click.echo(f"Model created successfully: {result}")
126
+ except Exception as e:
127
+ click.echo(f"Error creating model: {str(e)}")
128
+
129
+ @cli.command()
130
+ @click.argument('model_id', type=str)
131
+ @click.option('--notes', type=str, default=None, help='Version notes')
132
+ @click.option('--is-major', default=False, is_flag=True, help='Is this a major version')
133
+ @click.pass_obj
134
+ def create_version(client, model_id, notes, is_major):
135
+ """Create a new version of a model"""
136
+ try:
137
+ result = client.create_version(model_id, notes, is_major)
138
+ click.echo(f"Version created successfully: {result}")
139
+ except Exception as e:
140
+ click.echo(f"Error creating version: {str(e)}")
141
+
142
+ @cli.command()
143
+ @click.argument('model_id', type=str)
144
+ @click.argument('inference_mode', type=click.Choice(InferenceModes.keys()), default="VANILLA")
145
+ @click.argument('input_data', type=Dict, required=False)
146
+ @click.option('--input_file',
147
+ type=click.Path(exists=True, file_okay=True, dir_okay=False, readable=True, path_type=Path),
148
+ help="Optional file input for model inference -- must be JSON")
149
+ @click.pass_context
150
+ def infer(ctx, model_id, inference_mode, input_data, input_file):
151
+ """Run inference on a model"""
152
+ client = ctx.obj
153
+ try:
154
+ if not input_data and not input_file:
155
+ click.echo("Must specify either input_data or input_file")
156
+ ctx.exit(1)
157
+ return
158
+
159
+ if input_data and input_file:
160
+ click.echo("Cannot have both input_data and input_file")
161
+ ctx.exit(1)
162
+ return
163
+
164
+ if input_data:
165
+ model_input = input_data
166
+
167
+ if input_file:
168
+ with input_file.open('r') as file:
169
+ model_input = json.load(file)
170
+
171
+ # Parse input data from string to dict
172
+ click.echo(f"Running {inference_mode} inference for {model_id}...")
173
+ tx_hash, model_output = client.infer(model_cid=model_id, inference_mode=InferenceModes[inference_mode], model_input=model_input)
174
+ click.secho("Success!", fg="green")
175
+ click.echo(f"\nTransaction Hash: \n{tx_hash}")
176
+ click.echo(f"\nInference result: \n{model_output}")
177
+ except json.JSONDecodeError as e:
178
+ click.echo(f"Error decoding JSON: {e}", err=True)
179
+ click.echo(f"Error occurred on line {e.lineno}, column {e.colno}", err=True)
180
+ except Exception as e:
181
+ click.echo(f"Error running inference: {str(e)}")
182
+
183
+ if __name__ == '__main__':
184
+ cli()
opengradient/client.py CHANGED
@@ -32,7 +32,7 @@ class Client:
32
32
  rpc_url (str): The RPC URL for the Ethereum node.
33
33
  contract_address (str): The contract address for the smart contract.
34
34
  email (str, optional): Email for authentication. Defaults to "test@test.com".
35
- password (str, optional): Password for authentication. Defaults to "Test123".
35
+ password (str, optional): Password for authentication. Defaults to "Test-123".
36
36
  """
37
37
  self.private_key = private_key
38
38
  self.rpc_url = rpc_url
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: opengradient
3
- Version: 0.1.8
3
+ Version: 0.2.0
4
4
  Summary: A Python SDK for OpenGradient inference services
5
5
  Author-email: OpenGradient <oliver@opengradient.ai>
6
6
  License: MIT License
@@ -45,6 +45,7 @@ Requires-Dist: web3
45
45
  Requires-Dist: pyarrow
46
46
  Requires-Dist: firebase-rest-api
47
47
  Requires-Dist: fastparquet
48
+ Requires-Dist: pathlib
48
49
 
49
50
  # OpenGradient Python SDK
50
51
 
@@ -0,0 +1,13 @@
1
+ opengradient/__init__.py,sha256=Kukk6uFmngLgIaYDmdoLjZaNO3ue51-bPIqkD62rNf4,1653
2
+ opengradient/cli.py,sha256=pj1iU2AdL1R4MtQHehdQMacAXWw5pP5vJRF6CusP7jg,7243
3
+ opengradient/client.py,sha256=UUIryYtXNi1VAqi7WAZZiF6mhc4i1ueeL6cnKMMFYpk,18020
4
+ opengradient/exceptions.py,sha256=v4VmUGTvvtjhCZAhR24Ga42z3q-DzR1Y5zSqP_yn2Xk,3366
5
+ opengradient/types.py,sha256=NTWQ0HvglQA7d8y6OQDkymToSdCq4NnrVtwQwm_NMMU,1857
6
+ opengradient/utils.py,sha256=95i5RVn-32MRsn00M21io8QHLtmEAoRbgueMhDh0TVk,5079
7
+ opengradient/abi/inference.abi,sha256=HH2SmCJ_D4O0I-CFsln0vFHd2PU-A-fxgCnUtHg0ZQg,2373
8
+ opengradient-0.2.0.dist-info/LICENSE,sha256=xEcvQ3AxZOtDkrqkys2Mm6Y9diEnaSeQRKvxi-JGnNA,1069
9
+ opengradient-0.2.0.dist-info/METADATA,sha256=u6_Ku-gTu_PEmexIVEGBTgKFCfFHxfbSBTyB5eIK78M,3000
10
+ opengradient-0.2.0.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
11
+ opengradient-0.2.0.dist-info/entry_points.txt,sha256=yUKTaJx8RXnybkob0J62wVBiCp_1agVbgw9uzsmaeJc,54
12
+ opengradient-0.2.0.dist-info/top_level.txt,sha256=oC1zimVLa2Yi1LQz8c7x-0IQm92milb5ax8gHBHwDqU,13
13
+ opengradient-0.2.0.dist-info/RECORD,,
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ opengradient = opengradient.cli:cli
@@ -1,11 +0,0 @@
1
- opengradient/__init__.py,sha256=L7fIQzQMFI-NajLWqcTyYwvXmoQhNBn3Zv4vUl-4-zY,1653
2
- opengradient/client.py,sha256=HenTm4UUi0Xf1YJpEm3QXGwPnf6ZUzzwjWwZYtxbQ28,18019
3
- opengradient/exceptions.py,sha256=v4VmUGTvvtjhCZAhR24Ga42z3q-DzR1Y5zSqP_yn2Xk,3366
4
- opengradient/types.py,sha256=NTWQ0HvglQA7d8y6OQDkymToSdCq4NnrVtwQwm_NMMU,1857
5
- opengradient/utils.py,sha256=95i5RVn-32MRsn00M21io8QHLtmEAoRbgueMhDh0TVk,5079
6
- opengradient/abi/inference.abi,sha256=HH2SmCJ_D4O0I-CFsln0vFHd2PU-A-fxgCnUtHg0ZQg,2373
7
- opengradient-0.1.8.dist-info/LICENSE,sha256=xEcvQ3AxZOtDkrqkys2Mm6Y9diEnaSeQRKvxi-JGnNA,1069
8
- opengradient-0.1.8.dist-info/METADATA,sha256=7FoFCwvqHyfOsCwu9BZKtfMrFsxwpuhxsurl18SOw6Y,2977
9
- opengradient-0.1.8.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
10
- opengradient-0.1.8.dist-info/top_level.txt,sha256=oC1zimVLa2Yi1LQz8c7x-0IQm92milb5ax8gHBHwDqU,13
11
- opengradient-0.1.8.dist-info/RECORD,,