neurocli-sdk 0.2.1__tar.gz

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.
@@ -0,0 +1,61 @@
1
+ Metadata-Version: 2.4
2
+ Name: neurocli-sdk
3
+ Version: 0.2.1
4
+ Summary: The official Python SDK for the NeuroCLI API
5
+ Home-page: https://www.neurocli.in
6
+ Author: NeuroCLI
7
+ Author-email: NeuroCLI <info@neurocli.in>
8
+ License: MIT
9
+ Project-URL: Homepage, https://www.neurocli.in
10
+ Project-URL: Documentation, https://www.neurocli.in/docs
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Intended Audience :: Developers
15
+ Requires-Python: >=3.7
16
+ Description-Content-Type: text/markdown
17
+ Requires-Dist: httpx>=0.24.0
18
+ Requires-Dist: tenacity>=8.0.0
19
+ Requires-Dist: pydantic>=2.0.0
20
+ Dynamic: author
21
+ Dynamic: home-page
22
+ Dynamic: requires-python
23
+
24
+ # NeuroCLI Python SDK
25
+
26
+ The official Python library for the NeuroCLI API.
27
+
28
+ ## Installation
29
+
30
+ You can install this SDK locally:
31
+ ```bash
32
+ pip install -e .
33
+ ```
34
+
35
+ ## Usage
36
+
37
+ The SDK mimics the standard OpenAI Python client interface, making it extremely easy to drop into existing AI applications.
38
+
39
+ ### Basic Chat Completion
40
+
41
+ ```python
42
+ import neurocli
43
+
44
+ # Initialize the client
45
+ client = neurocli.NeuroCLI(
46
+ api_key="ncli_YOUR_SECRET_KEY",
47
+ # During local testing, point this to your local server:
48
+ # base_url="http://127.0.0.1:8000/api/ai"
49
+ )
50
+
51
+ # Generate a response
52
+ response = client.chat.completions.create(
53
+ model="meta/llama-3.1-8b-instruct",
54
+ messages=[
55
+ {"role": "user", "content": "Explain quantum computing in simple terms."}
56
+ ],
57
+ temperature=0.7
58
+ )
59
+
60
+ print(response.choices[0].message.content)
61
+ ```
@@ -0,0 +1,38 @@
1
+ # NeuroCLI Python SDK
2
+
3
+ The official Python library for the NeuroCLI API.
4
+
5
+ ## Installation
6
+
7
+ You can install this SDK locally:
8
+ ```bash
9
+ pip install -e .
10
+ ```
11
+
12
+ ## Usage
13
+
14
+ The SDK mimics the standard OpenAI Python client interface, making it extremely easy to drop into existing AI applications.
15
+
16
+ ### Basic Chat Completion
17
+
18
+ ```python
19
+ import neurocli
20
+
21
+ # Initialize the client
22
+ client = neurocli.NeuroCLI(
23
+ api_key="ncli_YOUR_SECRET_KEY",
24
+ # During local testing, point this to your local server:
25
+ # base_url="http://127.0.0.1:8000/api/ai"
26
+ )
27
+
28
+ # Generate a response
29
+ response = client.chat.completions.create(
30
+ model="meta/llama-3.1-8b-instruct",
31
+ messages=[
32
+ {"role": "user", "content": "Explain quantum computing in simple terms."}
33
+ ],
34
+ temperature=0.7
35
+ )
36
+
37
+ print(response.choices[0].message.content)
38
+ ```
@@ -0,0 +1,3 @@
1
+ from .client import NeuroCLI, AsyncNeuroCLI, wrap_function
2
+
3
+ __all__ = ["NeuroCLI", "AsyncNeuroCLI", "wrap_function"]
@@ -0,0 +1,234 @@
1
+ import json
2
+ import inspect
3
+ from typing import List, Dict, Optional, Any, Callable, Union, Iterator, AsyncIterator
4
+ import httpx
5
+ from pydantic import BaseModel, Field
6
+ from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type
7
+
8
+ # --- Types ---
9
+ class Message(BaseModel):
10
+ role: str
11
+ content: str
12
+
13
+ class Choice(BaseModel):
14
+ message: Message
15
+ finish_reason: Optional[str] = None
16
+
17
+ class ChatCompletionResponse(BaseModel):
18
+ id: Optional[str] = None
19
+ choices: List[Choice]
20
+
21
+ # Streaming chunk model
22
+ class ChoiceDelta(BaseModel):
23
+ content: Optional[str] = None
24
+
25
+ class ChunkChoice(BaseModel):
26
+ delta: ChoiceDelta
27
+ finish_reason: Optional[str] = None
28
+
29
+ class ChatCompletionChunk(BaseModel):
30
+ id: Optional[str] = None
31
+ choices: List[ChunkChoice]
32
+
33
+ # --- Error Handling ---
34
+ class NeuroCLIError(Exception):
35
+ pass
36
+
37
+ class RateLimitError(NeuroCLIError):
38
+ pass
39
+
40
+ class APIError(NeuroCLIError):
41
+ pass
42
+
43
+ # Retry decorator for rate limits (429) or temporary server errors (502, 503, 504)
44
+ def create_retry_decorator():
45
+ return retry(
46
+ stop=stop_after_attempt(3),
47
+ wait=wait_exponential(multiplier=1, min=2, max=10),
48
+ retry=retry_if_exception_type((RateLimitError, httpx.ReadTimeout, httpx.ConnectError)),
49
+ reraise=True
50
+ )
51
+
52
+ # --- Function Calling Wrapper ---
53
+ def wrap_function(func: Callable) -> Dict[str, Any]:
54
+ """
55
+ Automatically converts a Python function with docstrings and type hints
56
+ into an OpenAI/Nvidia NIM compatible JSON Schema for function calling.
57
+ """
58
+ sig = inspect.signature(func)
59
+ doc = inspect.getdoc(func) or ""
60
+
61
+ properties = {}
62
+ required = []
63
+
64
+ for name, param in sig.parameters.items():
65
+ param_type = "string"
66
+ if param.annotation == int:
67
+ param_type = "integer"
68
+ elif param.annotation == float:
69
+ param_type = "number"
70
+ elif param.annotation == bool:
71
+ param_type = "boolean"
72
+
73
+ properties[name] = {"type": param_type}
74
+
75
+ if param.default == inspect.Parameter.empty:
76
+ required.append(name)
77
+
78
+ return {
79
+ "type": "function",
80
+ "function": {
81
+ "name": func.__name__,
82
+ "description": doc,
83
+ "parameters": {
84
+ "type": "object",
85
+ "properties": properties,
86
+ "required": required
87
+ }
88
+ }
89
+ }
90
+
91
+
92
+ # --- Core Logic ---
93
+
94
+ def _handle_response(response: httpx.Response) -> ChatCompletionResponse:
95
+ if not response.is_success:
96
+ if response.status_code == 429:
97
+ raise RateLimitError("Rate Limit Exceeded. Retrying automatically...")
98
+ try:
99
+ error_data = response.json()
100
+ error_msg = error_data.get('message') or error_data.get('error') or response.text
101
+ except Exception:
102
+ error_msg = response.text
103
+ raise APIError(f"NeuroCLI API Error ({response.status_code}): {error_msg}")
104
+
105
+ data = response.json()
106
+ return ChatCompletionResponse(**data)
107
+
108
+ def _stream_iterator(response: httpx.Response) -> Iterator[ChatCompletionChunk]:
109
+ if not response.is_success:
110
+ if response.status_code == 429:
111
+ raise RateLimitError("Rate Limit Exceeded. Retrying automatically...")
112
+ raise APIError(f"NeuroCLI API Error ({response.status_code})")
113
+
114
+ for line in response.iter_lines():
115
+ if line.startswith("data: ") and line != "data: [DONE]":
116
+ data = json.loads(line[6:])
117
+ yield ChatCompletionChunk(**data)
118
+
119
+ async def _astream_iterator(response: httpx.Response) -> AsyncIterator[ChatCompletionChunk]:
120
+ if not response.is_success:
121
+ if response.status_code == 429:
122
+ raise RateLimitError("Rate Limit Exceeded. Retrying automatically...")
123
+ raise APIError(f"NeuroCLI API Error ({response.status_code})")
124
+
125
+ async for line in response.aiter_lines():
126
+ if line.startswith("data: ") and line != "data: [DONE]":
127
+ data = json.loads(line[6:])
128
+ yield ChatCompletionChunk(**data)
129
+
130
+
131
+ # --- Sync Client ---
132
+ class ChatCompletions:
133
+ def __init__(self, client):
134
+ self._client = client
135
+
136
+ @create_retry_decorator()
137
+ def create(
138
+ self,
139
+ model: str,
140
+ messages: List[Dict[str, str]],
141
+ temperature: Optional[float] = None,
142
+ max_tokens: Optional[int] = None,
143
+ stream: bool = False,
144
+ tools: Optional[List[Dict[str, Any]]] = None,
145
+ **kwargs
146
+ ) -> Union[ChatCompletionResponse, Iterator[ChatCompletionChunk]]:
147
+
148
+ payload = {"model": model, "messages": messages}
149
+ if temperature is not None: payload["temperature"] = temperature
150
+ if max_tokens is not None: payload["max_tokens"] = max_tokens
151
+ if tools is not None: payload["tools"] = tools
152
+ if stream: payload["stream"] = True
153
+ payload.update(kwargs)
154
+
155
+ headers = {
156
+ "Content-Type": "application/json",
157
+ "Authorization": f"Bearer {self._client.api_key}"
158
+ }
159
+
160
+ if stream:
161
+ request = self._client._http.build_request(
162
+ "POST", f"{self._client.base_url}/chat/completions", json=payload, headers=headers
163
+ )
164
+ response = self._client._http.send(request, stream=True)
165
+ return _stream_iterator(response)
166
+ else:
167
+ response = self._client._http.post(
168
+ f"{self._client.base_url}/chat/completions", json=payload, headers=headers
169
+ )
170
+ return _handle_response(response)
171
+
172
+ class Chat:
173
+ def __init__(self, client):
174
+ self.completions = ChatCompletions(client)
175
+
176
+ class NeuroCLI:
177
+ def __init__(self, api_key: str, base_url: str = "https://www.neurocli.in/v1"):
178
+ self.api_key = api_key
179
+ self.base_url = base_url.rstrip("/")
180
+ self._http = httpx.Client(timeout=60.0)
181
+ self.chat = Chat(self)
182
+
183
+
184
+ # --- Async Client ---
185
+ class AsyncChatCompletions:
186
+ def __init__(self, client):
187
+ self._client = client
188
+
189
+ @create_retry_decorator()
190
+ async def create(
191
+ self,
192
+ model: str,
193
+ messages: List[Dict[str, str]],
194
+ temperature: Optional[float] = None,
195
+ max_tokens: Optional[int] = None,
196
+ stream: bool = False,
197
+ tools: Optional[List[Dict[str, Any]]] = None,
198
+ **kwargs
199
+ ) -> Union[ChatCompletionResponse, AsyncIterator[ChatCompletionChunk]]:
200
+
201
+ payload = {"model": model, "messages": messages}
202
+ if temperature is not None: payload["temperature"] = temperature
203
+ if max_tokens is not None: payload["max_tokens"] = max_tokens
204
+ if tools is not None: payload["tools"] = tools
205
+ if stream: payload["stream"] = True
206
+ payload.update(kwargs)
207
+
208
+ headers = {
209
+ "Content-Type": "application/json",
210
+ "Authorization": f"Bearer {self._client.api_key}"
211
+ }
212
+
213
+ if stream:
214
+ request = self._client._http.build_request(
215
+ "POST", f"{self._client.base_url}/chat/completions", json=payload, headers=headers
216
+ )
217
+ response = await self._client._http.send(request, stream=True)
218
+ return _astream_iterator(response)
219
+ else:
220
+ response = await self._client._http.post(
221
+ f"{self._client.base_url}/chat/completions", json=payload, headers=headers
222
+ )
223
+ return _handle_response(response)
224
+
225
+ class AsyncChat:
226
+ def __init__(self, client):
227
+ self.completions = AsyncChatCompletions(client)
228
+
229
+ class AsyncNeuroCLI:
230
+ def __init__(self, api_key: str, base_url: str = "https://www.neurocli.in/v1"):
231
+ self.api_key = api_key
232
+ self.base_url = base_url.rstrip("/")
233
+ self._http = httpx.AsyncClient(timeout=60.0)
234
+ self.chat = AsyncChat(self)
@@ -0,0 +1,61 @@
1
+ Metadata-Version: 2.4
2
+ Name: neurocli-sdk
3
+ Version: 0.2.1
4
+ Summary: The official Python SDK for the NeuroCLI API
5
+ Home-page: https://www.neurocli.in
6
+ Author: NeuroCLI
7
+ Author-email: NeuroCLI <info@neurocli.in>
8
+ License: MIT
9
+ Project-URL: Homepage, https://www.neurocli.in
10
+ Project-URL: Documentation, https://www.neurocli.in/docs
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Intended Audience :: Developers
15
+ Requires-Python: >=3.7
16
+ Description-Content-Type: text/markdown
17
+ Requires-Dist: httpx>=0.24.0
18
+ Requires-Dist: tenacity>=8.0.0
19
+ Requires-Dist: pydantic>=2.0.0
20
+ Dynamic: author
21
+ Dynamic: home-page
22
+ Dynamic: requires-python
23
+
24
+ # NeuroCLI Python SDK
25
+
26
+ The official Python library for the NeuroCLI API.
27
+
28
+ ## Installation
29
+
30
+ You can install this SDK locally:
31
+ ```bash
32
+ pip install -e .
33
+ ```
34
+
35
+ ## Usage
36
+
37
+ The SDK mimics the standard OpenAI Python client interface, making it extremely easy to drop into existing AI applications.
38
+
39
+ ### Basic Chat Completion
40
+
41
+ ```python
42
+ import neurocli
43
+
44
+ # Initialize the client
45
+ client = neurocli.NeuroCLI(
46
+ api_key="ncli_YOUR_SECRET_KEY",
47
+ # During local testing, point this to your local server:
48
+ # base_url="http://127.0.0.1:8000/api/ai"
49
+ )
50
+
51
+ # Generate a response
52
+ response = client.chat.completions.create(
53
+ model="meta/llama-3.1-8b-instruct",
54
+ messages=[
55
+ {"role": "user", "content": "Explain quantum computing in simple terms."}
56
+ ],
57
+ temperature=0.7
58
+ )
59
+
60
+ print(response.choices[0].message.content)
61
+ ```
@@ -0,0 +1,10 @@
1
+ README.md
2
+ pyproject.toml
3
+ setup.py
4
+ neurocli/__init__.py
5
+ neurocli/client.py
6
+ neurocli_sdk.egg-info/PKG-INFO
7
+ neurocli_sdk.egg-info/SOURCES.txt
8
+ neurocli_sdk.egg-info/dependency_links.txt
9
+ neurocli_sdk.egg-info/requires.txt
10
+ neurocli_sdk.egg-info/top_level.txt
@@ -0,0 +1,3 @@
1
+ httpx>=0.24.0
2
+ tenacity>=8.0.0
3
+ pydantic>=2.0.0
@@ -0,0 +1 @@
1
+ neurocli
@@ -0,0 +1,29 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "neurocli-sdk"
7
+ version = "0.2.1"
8
+ description = "The official Python SDK for the NeuroCLI API"
9
+ readme = "README.md"
10
+ requires-python = ">=3.7"
11
+ license = { text = "MIT" }
12
+ authors = [
13
+ { name="NeuroCLI", email="info@neurocli.in" },
14
+ ]
15
+ classifiers = [
16
+ "Programming Language :: Python :: 3",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Operating System :: OS Independent",
19
+ "Intended Audience :: Developers",
20
+ ]
21
+ dependencies = [
22
+ "httpx>=0.24.0",
23
+ "tenacity>=8.0.0",
24
+ "pydantic>=2.0.0",
25
+ ]
26
+
27
+ [project.urls]
28
+ "Homepage" = "https://www.neurocli.in"
29
+ "Documentation" = "https://www.neurocli.in/docs"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,28 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ with open("README.md", "r", encoding="utf-8") as fh:
4
+ long_description = fh.read()
5
+
6
+ setup(
7
+ name="neurocli-sdk",
8
+ version="0.2.1",
9
+ description="The official Python SDK for the NeuroCLI API.",
10
+ long_description=long_description,
11
+ long_description_content_type="text/markdown",
12
+ author="NeuroCLI",
13
+ author_email="info@neurocli.in",
14
+ url="https://www.neurocli.in",
15
+ packages=find_packages(),
16
+ install_requires=[
17
+ "httpx>=0.24.0",
18
+ "tenacity>=8.0.0",
19
+ "pydantic>=2.0.0"
20
+ ],
21
+ classifiers=[
22
+ "Programming Language :: Python :: 3",
23
+ "License :: OSI Approved :: MIT License",
24
+ "Operating System :: OS Independent",
25
+ "Intended Audience :: Developers",
26
+ ],
27
+ python_requires=">=3.7",
28
+ )