mira-network 0.1.0__tar.gz → 0.1.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,107 @@
1
+ Metadata-Version: 2.1
2
+ Name: mira-network
3
+ Version: 0.1.1
4
+ Summary: Python SDK for Mira Network API
5
+ Author-Email: sarim2000 <sarimbleedblue@gmail.com>
6
+ License: MIT
7
+ Requires-Python: ==3.10.*
8
+ Requires-Dist: httpx>=0.28.1
9
+ Requires-Dist: pydantic>=2.10.4
10
+ Requires-Dist: typing-extensions>=4.8.0
11
+ Requires-Dist: requests>=2.32.3
12
+ Description-Content-Type: text/markdown
13
+
14
+ # Mira SDK
15
+
16
+ A Python SDK for interacting with the Mira Network API. This SDK provides a simple interface to access all Mira API endpoints including model inference, flow management, and credit system.
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ pip install mira-sdk
22
+ ```
23
+
24
+ ## Quick Start
25
+
26
+ ```python
27
+ import asyncio
28
+ from mira_sdk import MiraClient, Message, AiRequest
29
+
30
+ async def main():
31
+ # Initialize client
32
+ client = MiraClient(
33
+ base_url="https://api.mira.example.com",
34
+ api_token="your-api-token"
35
+ )
36
+
37
+ # List available models
38
+ models = await client.list_models()
39
+ print("Available models:", models)
40
+
41
+ # Generate text
42
+ request = AiRequest(
43
+ model="mira/llama3.1",
44
+ messages=[
45
+ Message(role="system", content="You are a helpful assistant."),
46
+ Message(role="user", content="Hello!")
47
+ ],
48
+ model_provider=None
49
+ )
50
+
51
+ response = await client.generate(request)
52
+ print("Response:", response)
53
+
54
+ if __name__ == "__main__":
55
+ asyncio.run(main())
56
+ ```
57
+
58
+ ## Features
59
+
60
+ - Asynchronous API using `httpx`
61
+ - Full type hints support
62
+ - Pydantic models for request/response validation
63
+ - Support for all Mira API endpoints:
64
+ - Model inference
65
+ - Flow management
66
+ - API token management
67
+ - Credit system
68
+
69
+ ## API Reference
70
+
71
+ ### Models
72
+
73
+ - `Message`: Represents a chat message
74
+ - `ModelProvider`: Configuration for custom model providers
75
+ - `AiRequest`: Request for model inference
76
+ - `FlowChatCompletion`: Request for flow-based chat completion
77
+ - `FlowRequest`: Request for creating/updating flows
78
+ - `ApiTokenRequest`: Request for creating API tokens
79
+ - `AddCreditRequest`: Request for adding credits
80
+
81
+ ### Client Methods
82
+
83
+ #### Model Operations
84
+ - `list_models()`: List available models
85
+ - `generate(request: AiRequest)`: Generate text using specified model
86
+
87
+ #### Flow Operations
88
+ - `list_flows()`: List all flows
89
+ - `get_flow(flow_id: str)`: Get flow details
90
+ - `create_flow(request: FlowRequest)`: Create new flow
91
+ - `update_flow(flow_id: str, request: FlowRequest)`: Update flow
92
+ - `delete_flow(flow_id: str)`: Delete flow
93
+ - `generate_with_flow(flow_id: str, request: FlowChatCompletion)`: Generate using flow
94
+
95
+ #### Token Operations
96
+ - `create_api_token(request: ApiTokenRequest)`: Create API token
97
+ - `list_api_tokens()`: List API tokens
98
+ - `delete_api_token(token: str)`: Delete API token
99
+
100
+ #### Credit Operations
101
+ - `get_user_credits()`: Get credit information
102
+ - `add_credit(request: AddCreditRequest)`: Add credits
103
+ - `get_credits_history()`: Get credit history
104
+
105
+ ## License
106
+
107
+ MIT License
@@ -0,0 +1,94 @@
1
+ # Mira SDK
2
+
3
+ A Python SDK for interacting with the Mira Network API. This SDK provides a simple interface to access all Mira API endpoints including model inference, flow management, and credit system.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install mira-sdk
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```python
14
+ import asyncio
15
+ from mira_sdk import MiraClient, Message, AiRequest
16
+
17
+ async def main():
18
+ # Initialize client
19
+ client = MiraClient(
20
+ base_url="https://api.mira.example.com",
21
+ api_token="your-api-token"
22
+ )
23
+
24
+ # List available models
25
+ models = await client.list_models()
26
+ print("Available models:", models)
27
+
28
+ # Generate text
29
+ request = AiRequest(
30
+ model="mira/llama3.1",
31
+ messages=[
32
+ Message(role="system", content="You are a helpful assistant."),
33
+ Message(role="user", content="Hello!")
34
+ ],
35
+ model_provider=None
36
+ )
37
+
38
+ response = await client.generate(request)
39
+ print("Response:", response)
40
+
41
+ if __name__ == "__main__":
42
+ asyncio.run(main())
43
+ ```
44
+
45
+ ## Features
46
+
47
+ - Asynchronous API using `httpx`
48
+ - Full type hints support
49
+ - Pydantic models for request/response validation
50
+ - Support for all Mira API endpoints:
51
+ - Model inference
52
+ - Flow management
53
+ - API token management
54
+ - Credit system
55
+
56
+ ## API Reference
57
+
58
+ ### Models
59
+
60
+ - `Message`: Represents a chat message
61
+ - `ModelProvider`: Configuration for custom model providers
62
+ - `AiRequest`: Request for model inference
63
+ - `FlowChatCompletion`: Request for flow-based chat completion
64
+ - `FlowRequest`: Request for creating/updating flows
65
+ - `ApiTokenRequest`: Request for creating API tokens
66
+ - `AddCreditRequest`: Request for adding credits
67
+
68
+ ### Client Methods
69
+
70
+ #### Model Operations
71
+ - `list_models()`: List available models
72
+ - `generate(request: AiRequest)`: Generate text using specified model
73
+
74
+ #### Flow Operations
75
+ - `list_flows()`: List all flows
76
+ - `get_flow(flow_id: str)`: Get flow details
77
+ - `create_flow(request: FlowRequest)`: Create new flow
78
+ - `update_flow(flow_id: str, request: FlowRequest)`: Update flow
79
+ - `delete_flow(flow_id: str)`: Delete flow
80
+ - `generate_with_flow(flow_id: str, request: FlowChatCompletion)`: Generate using flow
81
+
82
+ #### Token Operations
83
+ - `create_api_token(request: ApiTokenRequest)`: Create API token
84
+ - `list_api_tokens()`: List API tokens
85
+ - `delete_api_token(token: str)`: Delete API token
86
+
87
+ #### Credit Operations
88
+ - `get_user_credits()`: Get credit information
89
+ - `add_credit(request: AddCreditRequest)`: Add credits
90
+ - `get_credits_history()`: Get credit history
91
+
92
+ ## License
93
+
94
+ MIT License
@@ -0,0 +1,34 @@
1
+ [project]
2
+ name = "mira-network"
3
+ version = "0.1.1"
4
+ description = "Python SDK for Mira Network API"
5
+ authors = [
6
+ { name = "sarim2000", email = "sarimbleedblue@gmail.com" },
7
+ ]
8
+ dependencies = [
9
+ "httpx>=0.28.1",
10
+ "pydantic>=2.10.4",
11
+ "typing-extensions>=4.8.0",
12
+ "requests>=2.32.3",
13
+ ]
14
+ requires-python = "==3.10.*"
15
+ readme = "README.md"
16
+
17
+ [project.license]
18
+ text = "MIT"
19
+
20
+ [build-system]
21
+ requires = [
22
+ "pdm-backend",
23
+ ]
24
+ build-backend = "pdm.backend"
25
+
26
+ [tool.pdm]
27
+ distribution = true
28
+
29
+ [dependency-groups]
30
+ test = [
31
+ "pytest>=8.3.4",
32
+ "pytest-asyncio>=0.25.0",
33
+ "pytest-cov>=6.0.0",
34
+ ]
@@ -0,0 +1,21 @@
1
+ from .client import MiraClient
2
+ from .models import (
3
+ Message,
4
+ ModelProvider,
5
+ AiRequest,
6
+ FlowChatCompletion,
7
+ FlowRequest,
8
+ ApiTokenRequest,
9
+ AddCreditRequest,
10
+ )
11
+
12
+ __all__ = [
13
+ "MiraClient",
14
+ "Message",
15
+ "ModelProvider",
16
+ "AiRequest",
17
+ "FlowChatCompletion",
18
+ "FlowRequest",
19
+ "ApiTokenRequest",
20
+ "AddCreditRequest",
21
+ ]
@@ -0,0 +1,180 @@
1
+ from typing import Optional, List, Dict, AsyncGenerator, Union
2
+ import httpx
3
+ from src.mira_sdk.models import (
4
+ Message,
5
+ ModelProvider,
6
+ AiRequest,
7
+ FlowChatCompletion,
8
+ FlowRequest,
9
+ ApiTokenRequest,
10
+ AddCreditRequest,
11
+ )
12
+
13
+
14
+ class MiraClient:
15
+ def __init__(self, base_url: str, api_token: Optional[str] = None):
16
+ """Initialize Mira client.
17
+
18
+ Args:
19
+ base_url: Base URL of the Mira API
20
+ api_token: Optional API token for authentication
21
+ """
22
+ self.base_url = base_url
23
+ self.api_token = api_token
24
+ self._client = httpx.AsyncClient()
25
+
26
+ async def __aenter__(self):
27
+ return self
28
+
29
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
30
+ await self._client.aclose()
31
+
32
+ def _get_headers(self) -> Dict[str, str]:
33
+ headers = {"Content-Type": "application/json"}
34
+ if self.api_token:
35
+ headers["Authorization"] = f"Bearer {self.api_token}"
36
+ return headers
37
+
38
+ async def list_models(self) -> List[str]:
39
+ """List available models."""
40
+ response = await self._client.get(
41
+ f"{self.base_url}/v1/models",
42
+ headers=self._get_headers(),
43
+ )
44
+ response.raise_for_status()
45
+ return response.json()
46
+
47
+ async def generate(
48
+ self, request: AiRequest
49
+ ) -> Union[str, AsyncGenerator[str, None]]:
50
+ """Generate text using the specified model."""
51
+ response = await self._client.post(
52
+ f"{self.base_url}/v1/chat/completions",
53
+ headers=self._get_headers(),
54
+ json=request.model_dump(),
55
+ )
56
+
57
+ response.raise_for_status()
58
+
59
+ if request.stream:
60
+
61
+ async def stream_response():
62
+ async for chunk in response.aiter_text():
63
+ yield chunk
64
+
65
+ return stream_response()
66
+ else:
67
+ return response.json()
68
+
69
+ async def generate_with_flow(
70
+ self, flow_id: str, request: FlowChatCompletion
71
+ ) -> Union[str, AsyncGenerator[str, None]]:
72
+ """Generate text using a specific flow."""
73
+ response = await self._client.post(
74
+ f"{self.base_url}/v1/flows/{flow_id}/chat/completions",
75
+ headers=self._get_headers(),
76
+ json=request.model_dump(),
77
+ )
78
+ response.raise_for_status()
79
+ return response.json()
80
+
81
+ async def list_flows(self) -> List[Dict]:
82
+ """List all flows."""
83
+ response = await self._client.get(
84
+ f"{self.base_url}/flows",
85
+ headers=self._get_headers(),
86
+ )
87
+ response.raise_for_status()
88
+ return response.json()
89
+
90
+ async def get_flow(self, flow_id: str) -> Dict:
91
+ """Get details of a specific flow."""
92
+ response = await self._client.get(
93
+ f"{self.base_url}/flows/{flow_id}",
94
+ headers=self._get_headers(),
95
+ )
96
+ response.raise_for_status()
97
+ return response.json()
98
+
99
+ async def create_flow(self, request: FlowRequest) -> Dict:
100
+ """Create a new flow."""
101
+ response = await self._client.post(
102
+ f"{self.base_url}/flows",
103
+ headers=self._get_headers(),
104
+ json=request.model_dump(),
105
+ )
106
+ response.raise_for_status()
107
+ return response.json()
108
+
109
+ async def update_flow(self, flow_id: str, request: FlowRequest) -> Dict:
110
+ """Update an existing flow."""
111
+ response = await self._client.put(
112
+ f"{self.base_url}/flows/{flow_id}",
113
+ headers=self._get_headers(),
114
+ json=request.model_dump(),
115
+ )
116
+ response.raise_for_status()
117
+ return response.json()
118
+
119
+ async def delete_flow(self, flow_id: str) -> None:
120
+ """Delete a flow."""
121
+ response = await self._client.delete(
122
+ f"{self.base_url}/flows/{flow_id}",
123
+ headers=self._get_headers(),
124
+ )
125
+ response.raise_for_status()
126
+
127
+ async def create_api_token(self, request: ApiTokenRequest) -> Dict:
128
+ """Create a new API token."""
129
+ response = await self._client.post(
130
+ f"{self.base_url}/tokens",
131
+ headers=self._get_headers(),
132
+ json=request.model_dump(),
133
+ )
134
+ response.raise_for_status()
135
+ return response.json()
136
+
137
+ async def list_api_tokens(self) -> List[Dict]:
138
+ """List all API tokens."""
139
+ response = await self._client.get(
140
+ f"{self.base_url}/tokens",
141
+ headers=self._get_headers(),
142
+ )
143
+ response.raise_for_status()
144
+ return response.json()
145
+
146
+ async def delete_api_token(self, token: str) -> None:
147
+ """Delete an API token."""
148
+ response = await self._client.delete(
149
+ f"{self.base_url}/tokens/{token}",
150
+ headers=self._get_headers(),
151
+ )
152
+ response.raise_for_status()
153
+
154
+ async def get_user_credits(self) -> Dict:
155
+ """Get user credits information."""
156
+ response = await self._client.get(
157
+ f"{self.base_url}/credits",
158
+ headers=self._get_headers(),
159
+ )
160
+ response.raise_for_status()
161
+ return response.json()
162
+
163
+ async def add_credit(self, request: AddCreditRequest) -> Dict:
164
+ """Add credits to a user account."""
165
+ response = await self._client.post(
166
+ f"{self.base_url}/credits",
167
+ headers=self._get_headers(),
168
+ json=request.model_dump(),
169
+ )
170
+ response.raise_for_status()
171
+ return response.json()
172
+
173
+ async def get_credits_history(self) -> List[Dict]:
174
+ """Get user credits history."""
175
+ response = await self._client.get(
176
+ f"{self.base_url}/credits/history",
177
+ headers=self._get_headers(),
178
+ )
179
+ response.raise_for_status()
180
+ return response.json()
@@ -0,0 +1,67 @@
1
+ from typing import Optional, List, Dict
2
+ from pydantic import BaseModel, Field, field_validator
3
+
4
+
5
+ class Message(BaseModel):
6
+ role: str
7
+ content: str
8
+
9
+ @field_validator("role")
10
+ @classmethod
11
+ def validate_role(cls, v: str) -> str:
12
+ valid_roles = ["system", "user", "assistant"]
13
+ if v not in valid_roles:
14
+ raise ValueError(f"Invalid role. Must be one of: {valid_roles}")
15
+ return v
16
+
17
+
18
+ class ModelProvider(BaseModel):
19
+ base_url: str
20
+ api_key: str
21
+
22
+
23
+ class AiRequest(BaseModel):
24
+ model: str = Field("mira/llama3.1", title="Model")
25
+ model_provider: Optional[ModelProvider] = Field(None, title="Model Provider (optional)")
26
+ messages: List[Message] = Field([], title="Messages")
27
+ stream: Optional[bool] = Field(False, title="Stream")
28
+
29
+ @field_validator("messages")
30
+ @classmethod
31
+ def validate_messages(cls, v: List[Message]) -> List[Message]:
32
+ if not v:
33
+ raise ValueError("Messages list cannot be empty")
34
+ return v
35
+
36
+
37
+ class FlowChatCompletion(BaseModel):
38
+ variables: Optional[Dict] = Field(None, title="Variables")
39
+
40
+
41
+ class FlowRequest(BaseModel):
42
+ system_prompt: str
43
+ name: str
44
+
45
+
46
+ class ApiTokenRequest(BaseModel):
47
+ description: Optional[str] = None
48
+
49
+
50
+ class AddCreditRequest(BaseModel):
51
+ user_id: str
52
+ amount: float
53
+ description: Optional[str] = None
54
+
55
+ @field_validator("amount")
56
+ @classmethod
57
+ def validate_amount(cls, v: float) -> float:
58
+ if v <= 0:
59
+ raise ValueError("Amount must be greater than 0")
60
+ return v
61
+
62
+ @field_validator("user_id")
63
+ @classmethod
64
+ def validate_user_id(cls, v: str) -> str:
65
+ if not v.strip():
66
+ raise ValueError("User ID cannot be empty")
67
+ return v
@@ -0,0 +1,109 @@
1
+ import pytest
2
+ import httpx
3
+ from src.mira_sdk.client import MiraClient
4
+ from src.mira_sdk.models import (
5
+ Message,
6
+ AiRequest,
7
+ FlowRequest,
8
+ ApiTokenRequest,
9
+ AddCreditRequest,
10
+ )
11
+
12
+
13
+ @pytest.fixture
14
+ def client():
15
+ return MiraClient(
16
+ base_url="https://mira-client-balancer.alts.dev",
17
+ api_token="sk-mira-8ac810228d32ff68fc93266fb9a0ba612724119ffab16dcc"
18
+ )
19
+
20
+
21
+ @pytest.mark.asyncio
22
+ async def test_list_models(client):
23
+ result = await client.list_models()
24
+ assert isinstance(result, list)
25
+ # assert len(result) > 0
26
+
27
+
28
+ @pytest.mark.asyncio
29
+ async def test_generate(client):
30
+ request = AiRequest(
31
+ model="mira/llama3.1",
32
+ messages=[Message(role="user", content="Hi Who are you!")],
33
+ stream=False,
34
+ model_provider=None
35
+ )
36
+
37
+ result = await client.generate(request)
38
+ assert isinstance(result, str)
39
+ assert len(result) > 0
40
+
41
+
42
+ @pytest.mark.asyncio
43
+ async def test_generate_stream(client):
44
+ request = AiRequest(
45
+ model="mira/llama3.1",
46
+ messages=[Message(role="user", content="Hi!")],
47
+ stream=True,
48
+ model_provider=None
49
+ )
50
+
51
+ stream = await client.generate(request)
52
+ chunks = []
53
+ async for chunk in stream:
54
+ chunks.append(chunk)
55
+ assert len(chunks) > 0
56
+
57
+
58
+ @pytest.mark.asyncio
59
+ async def test_list_flows(client):
60
+ result = await client.list_flows()
61
+ assert isinstance(result, list)
62
+
63
+
64
+ @pytest.mark.asyncio
65
+ async def test_create_and_delete_flow(client):
66
+ # Create flow
67
+ request = FlowRequest(
68
+ system_prompt="You are a helpful assistant",
69
+ name="test_flow"
70
+ )
71
+
72
+ flow = await client.create_flow(request)
73
+ assert flow.get("name") == "test_flow"
74
+
75
+ # Delete the created flow
76
+ flow_id = flow.get("id")
77
+ await client.delete_flow(flow_id)
78
+
79
+
80
+ @pytest.mark.asyncio
81
+ async def test_create_api_token(client):
82
+ request = ApiTokenRequest(description="Test token")
83
+ result = await client.create_api_token(request)
84
+ assert "token" in result
85
+
86
+
87
+ @pytest.mark.asyncio
88
+ async def test_get_user_credits(client):
89
+ result = await client.get_user_credits()
90
+ assert "amount" in result
91
+
92
+
93
+ @pytest.mark.asyncio
94
+ async def test_error_handling(client):
95
+ with pytest.raises(httpx.HTTPError):
96
+ # Test with invalid model name to trigger error
97
+ request = AiRequest(
98
+ model="invalid_model",
99
+ messages=[Message(role="user", content="Hi!")],
100
+ stream=False,
101
+ model_provider=None
102
+ )
103
+ await client.generate(request)
104
+
105
+
106
+ @pytest.mark.asyncio
107
+ async def test_client_context_manager():
108
+ async with MiraClient("https://mira-client-balancer.alts.dev") as client:
109
+ assert isinstance(client._client, httpx.AsyncClient)
@@ -0,0 +1,48 @@
1
+ import pytest
2
+ from src.mira_sdk.client import MiraClient
3
+ from src.mira_sdk.models import Message, AiRequest, ModelProvider
4
+
5
+
6
+ @pytest.mark.asyncio
7
+ async def test_real_generate():
8
+ """This test makes a real API call to generate text."""
9
+ client = MiraClient(
10
+ base_url="https://mira-client-balancer.alts.dev",
11
+ api_token="sk-mira-8ac810228d32ff68fc93266fb9a0ba612724119ffab16dcc"
12
+ )
13
+
14
+ request = AiRequest(
15
+ model="mira/llama3.1",
16
+ messages=[Message(role="user", content="Hi Who are you!")],
17
+ stream=False,
18
+ model_provider=None
19
+ )
20
+
21
+ async with client:
22
+ result = await client.generate(request)
23
+ print("Real API Response:", result)
24
+ # assert len(result) > 0
25
+
26
+
27
+ # @pytest.mark.asyncio
28
+ # async def test_real_generate_stream():
29
+ # """This test makes a real API call with streaming enabled."""
30
+ # client = MiraClient(
31
+ # base_url="https://mira-client-balancer.alts.dev",
32
+ # api_token="sk-mira-8ac810228d32ff68fc93266fb9a0ba612724119ffab16dcc"
33
+ # )
34
+
35
+ # request = AiRequest(
36
+ # messages=[Message(role="user", content="Count from 1 to 5")],
37
+ # stream=True
38
+ # )
39
+
40
+ # async with client:
41
+ # stream = await client.generate(request)
42
+ # response = ""
43
+ # async for chunk in stream:
44
+ # print("Chunk:", chunk)
45
+ # response += chunk
46
+ # print("Final Response:", response)
47
+ # assert isinstance(response, str)
48
+ # assert len(response) > 0
@@ -0,0 +1,109 @@
1
+ import pytest
2
+ from src.mira_sdk.models import (
3
+ Message,
4
+ ModelProvider,
5
+ AiRequest,
6
+ FlowChatCompletion,
7
+ FlowRequest,
8
+ ApiTokenRequest,
9
+ AddCreditRequest,
10
+ )
11
+
12
+
13
+ def test_message_model():
14
+ message = Message(role="user", content="Hello!")
15
+ assert message.role == "user"
16
+ assert message.content == "Hello!"
17
+
18
+
19
+ def test_model_provider():
20
+ provider = ModelProvider(base_url="https://mira-client-balancer.alts.dev", api_key="sk-mira-8ac810228d32ff68fc93266fb9a0ba612724119ffab16dcc")
21
+ assert provider.base_url == "https://mira-client-balancer.alts.dev"
22
+ assert provider.api_key == "sk-mira-8ac810228d32ff68fc93266fb9a0ba612724119ffab16dcc"
23
+
24
+
25
+ def test_ai_request():
26
+ messages = [Message(role="user", content="Hello!")]
27
+ provider = ModelProvider(base_url="https://mira-client-balancer.alts.dev", api_key="sk-mira-8ac810228d32ff68fc93266fb9a0ba612724119ffab16dcc")
28
+
29
+ # Test with default values
30
+ request = AiRequest(messages=messages)
31
+ assert request.model == "mira/llama3.1"
32
+ assert request.stream is False
33
+ assert request.model_provider is None
34
+ assert request.messages == messages
35
+
36
+ # Test with custom values
37
+ request = AiRequest(
38
+ model="custom/model",
39
+ messages=messages,
40
+ model_provider=provider,
41
+ stream=True
42
+ )
43
+ assert request.model == "custom/model"
44
+ assert request.stream is True
45
+ assert request.model_provider == provider
46
+ assert request.messages == messages
47
+
48
+
49
+ def test_flow_chat_completion():
50
+ # Test with no variables
51
+ completion = FlowChatCompletion()
52
+ assert completion.variables is None
53
+
54
+ # Test with variables
55
+ variables = {"key": "value"}
56
+ completion = FlowChatCompletion(variables=variables)
57
+ assert completion.variables == variables
58
+
59
+
60
+ def test_flow_request():
61
+ request = FlowRequest(
62
+ system_prompt="You are a helpful assistant",
63
+ name="test-flow"
64
+ )
65
+ assert request.system_prompt == "You are a helpful assistant"
66
+ assert request.name == "test-flow"
67
+
68
+
69
+ def test_api_token_request():
70
+ # Test with no description
71
+ request = ApiTokenRequest()
72
+ assert request.description is None
73
+
74
+ # Test with description
75
+ request = ApiTokenRequest(description="Test token")
76
+ assert request.description == "Test token"
77
+
78
+
79
+ def test_add_credit_request():
80
+ # Test required fields
81
+ request = AddCreditRequest(user_id="user123", amount=100.0)
82
+ assert request.user_id == "user123"
83
+ assert request.amount == 100.0
84
+ assert request.description is None
85
+
86
+ # Test with description
87
+ request = AddCreditRequest(
88
+ user_id="user123",
89
+ amount=100.0,
90
+ description="Test credit"
91
+ )
92
+ assert request.user_id == "user123"
93
+ assert request.amount == 100.0
94
+ assert request.description == "Test credit"
95
+
96
+
97
+ def test_invalid_message():
98
+ with pytest.raises(ValueError):
99
+ Message(role="invalid", content="") # Invalid role
100
+
101
+
102
+ def test_invalid_ai_request():
103
+ with pytest.raises(ValueError):
104
+ AiRequest(messages=[]) # Empty messages list
105
+
106
+
107
+ def test_invalid_add_credit_request():
108
+ with pytest.raises(ValueError):
109
+ AddCreditRequest(user_id="", amount=-100) # Negative amount
@@ -1,10 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: mira-network
3
- Version: 0.1.0
4
- Summary: Default template for PDM package
5
- Author-email: Hamid Raza <contact@hamidraza.com>
6
- License: MIT
7
- Requires-Python: >=3.11
8
- Description-Content-Type: text/markdown
9
-
10
- # mira-network
@@ -1 +0,0 @@
1
- # mira-network
@@ -1,19 +0,0 @@
1
- [project]
2
- name = "mira-network"
3
- version = "0.1.0"
4
- description = "Default template for PDM package"
5
- authors = [
6
- {name = "Hamid Raza", email = "contact@hamidraza.com"},
7
- ]
8
- dependencies = []
9
- requires-python = ">=3.11"
10
- readme = "README.md"
11
- license = {text = "MIT"}
12
-
13
- [build-system]
14
- requires = ["setuptools>=61"]
15
- build-backend = "setuptools.build_meta"
16
-
17
-
18
- [tool.pdm]
19
- distribution = true
@@ -1,4 +0,0 @@
1
- [egg_info]
2
- tag_build =
3
- tag_date = 0
4
-
@@ -1,8 +0,0 @@
1
- class MiraNetwork:
2
- def __init__(self, api_key: str) -> None:
3
- self.api_key = api_key
4
-
5
- def generate(self) -> dict:
6
- # check if the api key is valid
7
- if not self.api_key:
8
- raise ValueError("API key is required")
@@ -1,10 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: mira-network
3
- Version: 0.1.0
4
- Summary: Default template for PDM package
5
- Author-email: Hamid Raza <contact@hamidraza.com>
6
- License: MIT
7
- Requires-Python: >=3.11
8
- Description-Content-Type: text/markdown
9
-
10
- # mira-network
@@ -1,9 +0,0 @@
1
- README.md
2
- pyproject.toml
3
- src/mira_network/__init__.py
4
- src/mira_network/client.py
5
- src/mira_network.egg-info/PKG-INFO
6
- src/mira_network.egg-info/SOURCES.txt
7
- src/mira_network.egg-info/dependency_links.txt
8
- src/mira_network.egg-info/top_level.txt
9
- tests/test_client.py
@@ -1 +0,0 @@
1
- mira_network
@@ -1,26 +0,0 @@
1
- import unittest
2
- from mira_network.client import MiraNetwork
3
-
4
-
5
- class TestMiraNetwork(unittest.TestCase):
6
- def test_init(self):
7
- api_key = "test_api_key"
8
- client = MiraNetwork(api_key)
9
- self.assertEqual(client.api_key, api_key)
10
-
11
- def test_generate_with_valid_api_key(self):
12
- api_key = "test_api_key"
13
- client = MiraNetwork(api_key)
14
- result = client.generate()
15
- self.assertIsInstance(result, dict)
16
-
17
- def test_generate_with_invalid_api_key(self):
18
- client = MiraNetwork("")
19
- with self.assertRaises(ValueError):
20
- client.generate()
21
-
22
-
23
- if __name__ == "__main__":
24
- unittest.main()
25
-
26
- # pypi-AgEIcHlwaS5vcmcCJGUzODI5NjhjLWQ4MTQtNDFhZi1iYjhlLTlmYWYyNDcyZjQ3ZgACKlszLCJjMzJhNWQ1NS1kYjYyLTRiYzEtOWZlMS0xNzEzNGIyZjVjNmQiXQAABiBQXeHWfLbWZOZA8Yw9XyZmDdyy_OonAp3XUeqCJTwBwA