mayia-ai 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.
- mayia_ai-0.1.1/LICENSE +15 -0
- mayia_ai-0.1.1/PKG-INFO +54 -0
- mayia_ai-0.1.1/README.md +38 -0
- mayia_ai-0.1.1/pyproject.toml +27 -0
- mayia_ai-0.1.1/setup.cfg +4 -0
- mayia_ai-0.1.1/src/mayia/__init__.py +4 -0
- mayia_ai-0.1.1/src/mayia/cli.py +45 -0
- mayia_ai-0.1.1/src/mayia/client.py +178 -0
- mayia_ai-0.1.1/src/mayia_ai.egg-info/PKG-INFO +54 -0
- mayia_ai-0.1.1/src/mayia_ai.egg-info/SOURCES.txt +11 -0
- mayia_ai-0.1.1/src/mayia_ai.egg-info/dependency_links.txt +1 -0
- mayia_ai-0.1.1/src/mayia_ai.egg-info/entry_points.txt +2 -0
- mayia_ai-0.1.1/src/mayia_ai.egg-info/top_level.txt +1 -0
mayia_ai-0.1.1/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ORF (Filip O.)
|
|
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.
|
mayia_ai-0.1.1/PKG-INFO
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mayia-ai
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Official Python SDK for the Mayia AI API
|
|
5
|
+
Author: ORF (Filip O.)
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://ai-mayia.web.app
|
|
8
|
+
Project-URL: Documentation, https://ai-mayia.web.app/api-center
|
|
9
|
+
Keywords: mayia,ai,sdk,api,llm
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Requires-Python: >=3.9
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
Dynamic: license-file
|
|
16
|
+
|
|
17
|
+
# Mayia Python SDK
|
|
18
|
+
|
|
19
|
+
Official Python client for the Mayia API.
|
|
20
|
+
|
|
21
|
+
## Install
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pip install mayia-ai
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Quick start
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
from mayia import api
|
|
31
|
+
|
|
32
|
+
client = api(api_key="mayia_sk_...")
|
|
33
|
+
print(client.ask("Explain quantum computing simply."))
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
OpenAI-style chat:
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
from mayia import Mayia
|
|
40
|
+
|
|
41
|
+
client = Mayia(api_key="mayia_sk_...")
|
|
42
|
+
response = client.chat.completions.create(
|
|
43
|
+
model="mayia-1",
|
|
44
|
+
messages=[{"role": "user", "content": "Build a Flask API."}],
|
|
45
|
+
)
|
|
46
|
+
print(response.content)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Environment variables:
|
|
50
|
+
|
|
51
|
+
- `MAYIA_API_KEY`
|
|
52
|
+
- `MAYIA_API_URL` (default: `https://ai-mayia.web.app/api`)
|
|
53
|
+
|
|
54
|
+
> Keep API keys server-side. Never ship a secret Mayia API key in a public website, Roblox LocalScript, downloadable game client, or mobile bundle.
|
mayia_ai-0.1.1/README.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Mayia Python SDK
|
|
2
|
+
|
|
3
|
+
Official Python client for the Mayia API.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install mayia-ai
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick start
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from mayia import api
|
|
15
|
+
|
|
16
|
+
client = api(api_key="mayia_sk_...")
|
|
17
|
+
print(client.ask("Explain quantum computing simply."))
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
OpenAI-style chat:
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
from mayia import Mayia
|
|
24
|
+
|
|
25
|
+
client = Mayia(api_key="mayia_sk_...")
|
|
26
|
+
response = client.chat.completions.create(
|
|
27
|
+
model="mayia-1",
|
|
28
|
+
messages=[{"role": "user", "content": "Build a Flask API."}],
|
|
29
|
+
)
|
|
30
|
+
print(response.content)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Environment variables:
|
|
34
|
+
|
|
35
|
+
- `MAYIA_API_KEY`
|
|
36
|
+
- `MAYIA_API_URL` (default: `https://ai-mayia.web.app/api`)
|
|
37
|
+
|
|
38
|
+
> Keep API keys server-side. Never ship a secret Mayia API key in a public website, Roblox LocalScript, downloadable game client, or mobile bundle.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=69", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "mayia-ai"
|
|
7
|
+
version = "0.1.1"
|
|
8
|
+
description = "Official Python SDK for the Mayia AI API"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = {text = "MIT"}
|
|
12
|
+
authors = [{name = "ORF (Filip O.)"}]
|
|
13
|
+
keywords = ["mayia", "ai", "sdk", "api", "llm"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"Operating System :: OS Independent",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[project.urls]
|
|
20
|
+
Homepage = "https://ai-mayia.web.app"
|
|
21
|
+
Documentation = "https://ai-mayia.web.app/api-center"
|
|
22
|
+
|
|
23
|
+
[project.scripts]
|
|
24
|
+
mayia = "mayia.cli:main"
|
|
25
|
+
|
|
26
|
+
[tool.setuptools.packages.find]
|
|
27
|
+
where = ["src"]
|
mayia_ai-0.1.1/setup.cfg
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import json
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
from .client import Mayia, MayiaError
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def main() -> None:
|
|
11
|
+
parser = argparse.ArgumentParser(prog="mayia", description="Mayia AI CLI")
|
|
12
|
+
parser.add_argument("prompt", nargs="*", help="Prompt to send to Mayia")
|
|
13
|
+
parser.add_argument("--model", default="mayia-1")
|
|
14
|
+
parser.add_argument("--api-key")
|
|
15
|
+
parser.add_argument("--base-url")
|
|
16
|
+
parser.add_argument("--verify", action="store_true")
|
|
17
|
+
parser.add_argument("--models", action="store_true")
|
|
18
|
+
parser.add_argument("--json", action="store_true")
|
|
19
|
+
args = parser.parse_args()
|
|
20
|
+
|
|
21
|
+
kwargs = {"api_key": args.api_key}
|
|
22
|
+
if args.base_url:
|
|
23
|
+
kwargs["base_url"] = args.base_url
|
|
24
|
+
try:
|
|
25
|
+
client = Mayia(**kwargs)
|
|
26
|
+
if args.verify:
|
|
27
|
+
result = client.verify()
|
|
28
|
+
print(json.dumps(result, indent=2) if args.json else result)
|
|
29
|
+
return
|
|
30
|
+
if args.models:
|
|
31
|
+
result = client.models()
|
|
32
|
+
print(json.dumps(result, indent=2) if args.json else result)
|
|
33
|
+
return
|
|
34
|
+
prompt = " ".join(args.prompt).strip()
|
|
35
|
+
if not prompt:
|
|
36
|
+
parser.error("Provide a prompt, --verify, or --models")
|
|
37
|
+
result = client.ask(prompt, model=args.model)
|
|
38
|
+
print(json.dumps(result.raw, indent=2) if args.json else result.content)
|
|
39
|
+
except MayiaError as exc:
|
|
40
|
+
print(f"Mayia error: {exc}", file=sys.stderr)
|
|
41
|
+
raise SystemExit(1)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
if __name__ == "__main__":
|
|
45
|
+
main()
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
import urllib.error
|
|
6
|
+
import urllib.request
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from typing import Any, Dict, Iterable, List, Mapping, Optional
|
|
9
|
+
|
|
10
|
+
DEFAULT_BASE_URL = os.getenv("MAYIA_API_URL", "https://ai-mayia.web.app/api")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class MayiaError(RuntimeError):
|
|
14
|
+
def __init__(self, message: str, *, status: Optional[int] = None, payload: Any = None):
|
|
15
|
+
super().__init__(message)
|
|
16
|
+
self.status = status
|
|
17
|
+
self.payload = payload
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass
|
|
21
|
+
class MayiaResponse:
|
|
22
|
+
id: Optional[str]
|
|
23
|
+
model: Optional[str]
|
|
24
|
+
content: str
|
|
25
|
+
raw: Dict[str, Any]
|
|
26
|
+
|
|
27
|
+
def __str__(self) -> str:
|
|
28
|
+
return self.content
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class _Completions:
|
|
32
|
+
def __init__(self, client: "Mayia") -> None:
|
|
33
|
+
self._client = client
|
|
34
|
+
|
|
35
|
+
def create(
|
|
36
|
+
self,
|
|
37
|
+
*,
|
|
38
|
+
model: str = "mayia-1",
|
|
39
|
+
messages: Iterable[Mapping[str, str]],
|
|
40
|
+
temperature: Optional[float] = None,
|
|
41
|
+
max_tokens: Optional[int] = None,
|
|
42
|
+
extra: Optional[Mapping[str, Any]] = None,
|
|
43
|
+
) -> MayiaResponse:
|
|
44
|
+
body: Dict[str, Any] = {
|
|
45
|
+
"model": model,
|
|
46
|
+
"messages": list(messages),
|
|
47
|
+
}
|
|
48
|
+
if temperature is not None:
|
|
49
|
+
body["temperature"] = temperature
|
|
50
|
+
if max_tokens is not None:
|
|
51
|
+
body["max_tokens"] = max_tokens
|
|
52
|
+
if extra:
|
|
53
|
+
body.update(dict(extra))
|
|
54
|
+
raw = self._client._request("POST", "/v1/chat/completions", body)
|
|
55
|
+
return _to_response(raw)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class _Chat:
|
|
59
|
+
def __init__(self, client: "Mayia") -> None:
|
|
60
|
+
self.completions = _Completions(client)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class _Plugins:
|
|
64
|
+
def __init__(self, client: "Mayia") -> None:
|
|
65
|
+
self._client = client
|
|
66
|
+
|
|
67
|
+
def list(self) -> Dict[str, Any]:
|
|
68
|
+
return self._client._request("GET", "/v1/plugins")
|
|
69
|
+
|
|
70
|
+
def get(self, plugin_id: str) -> Dict[str, Any]:
|
|
71
|
+
return self._client._request("GET", f"/v1/plugins/{plugin_id}")
|
|
72
|
+
|
|
73
|
+
def configure(self, plugin_id: str, config: Mapping[str, Any]) -> Dict[str, Any]:
|
|
74
|
+
return self._client._request("PUT", f"/v1/plugins/{plugin_id}", dict(config))
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class _Account:
|
|
78
|
+
def __init__(self, client: "Mayia") -> None:
|
|
79
|
+
self._client = client
|
|
80
|
+
|
|
81
|
+
def me(self) -> Dict[str, Any]:
|
|
82
|
+
return self._client._request("GET", "/v1/account")
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class Mayia:
|
|
86
|
+
"""Official Mayia API client.
|
|
87
|
+
|
|
88
|
+
Keep API keys server-side. Do not embed secret keys into public browser/game client code.
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
def __init__(
|
|
92
|
+
self,
|
|
93
|
+
api_key: Optional[str] = None,
|
|
94
|
+
*,
|
|
95
|
+
base_url: str = DEFAULT_BASE_URL,
|
|
96
|
+
timeout: float = 60.0,
|
|
97
|
+
user_agent: str = "mayia-python/0.1.1",
|
|
98
|
+
) -> None:
|
|
99
|
+
self.api_key = api_key or os.getenv("MAYIA_API_KEY")
|
|
100
|
+
if not self.api_key:
|
|
101
|
+
raise MayiaError("Missing Mayia API key. Pass api_key=... or set MAYIA_API_KEY.")
|
|
102
|
+
self.base_url = base_url.rstrip("/")
|
|
103
|
+
self.timeout = timeout
|
|
104
|
+
self.user_agent = user_agent
|
|
105
|
+
self.chat = _Chat(self)
|
|
106
|
+
self.plugins = _Plugins(self)
|
|
107
|
+
self.account = _Account(self)
|
|
108
|
+
|
|
109
|
+
def health(self) -> Dict[str, Any]:
|
|
110
|
+
return self._request("GET", "/health", auth=False)
|
|
111
|
+
|
|
112
|
+
def models(self) -> Dict[str, Any]:
|
|
113
|
+
return self._request("GET", "/v1/models")
|
|
114
|
+
|
|
115
|
+
def verify(self) -> Dict[str, Any]:
|
|
116
|
+
return self._request("POST", "/v1/verify", {"message": "Mayia SDK verification"})
|
|
117
|
+
|
|
118
|
+
def ask(self, message: str, *, model: str = "mayia-1", system: Optional[str] = None) -> MayiaResponse:
|
|
119
|
+
messages: List[Dict[str, str]] = []
|
|
120
|
+
if system:
|
|
121
|
+
messages.append({"role": "system", "content": system})
|
|
122
|
+
messages.append({"role": "user", "content": message})
|
|
123
|
+
return self.chat.completions.create(model=model, messages=messages)
|
|
124
|
+
|
|
125
|
+
def _request(self, method: str, path: str, body: Optional[Mapping[str, Any]] = None, *, auth: bool = True) -> Dict[str, Any]:
|
|
126
|
+
url = self.base_url + (path if path.startswith("/") else "/" + path)
|
|
127
|
+
data = None if body is None else json.dumps(dict(body)).encode("utf-8")
|
|
128
|
+
headers = {
|
|
129
|
+
"Accept": "application/json",
|
|
130
|
+
"Content-Type": "application/json",
|
|
131
|
+
"User-Agent": self.user_agent,
|
|
132
|
+
}
|
|
133
|
+
if auth:
|
|
134
|
+
headers["Authorization"] = f"Bearer {self.api_key}"
|
|
135
|
+
headers["X-Mayia-API-Key"] = self.api_key
|
|
136
|
+
req = urllib.request.Request(url, data=data, headers=headers, method=method.upper())
|
|
137
|
+
try:
|
|
138
|
+
with urllib.request.urlopen(req, timeout=self.timeout) as response:
|
|
139
|
+
text = response.read().decode("utf-8")
|
|
140
|
+
if not text:
|
|
141
|
+
return {}
|
|
142
|
+
parsed = json.loads(text)
|
|
143
|
+
return parsed if isinstance(parsed, dict) else {"data": parsed}
|
|
144
|
+
except urllib.error.HTTPError as exc:
|
|
145
|
+
payload_text = exc.read().decode("utf-8", errors="replace")
|
|
146
|
+
try:
|
|
147
|
+
payload = json.loads(payload_text)
|
|
148
|
+
except Exception:
|
|
149
|
+
payload = payload_text
|
|
150
|
+
message = payload.get("error") if isinstance(payload, dict) else payload_text
|
|
151
|
+
if isinstance(message, dict):
|
|
152
|
+
message = message.get("message") or str(message)
|
|
153
|
+
raise MayiaError(str(message or f"Mayia API returned HTTP {exc.code}"), status=exc.code, payload=payload) from exc
|
|
154
|
+
except urllib.error.URLError as exc:
|
|
155
|
+
raise MayiaError(f"Could not reach Mayia API at {self.base_url}: {exc.reason}") from exc
|
|
156
|
+
except json.JSONDecodeError as exc:
|
|
157
|
+
raise MayiaError("Mayia API returned invalid JSON.") from exc
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def _to_response(raw: Dict[str, Any]) -> MayiaResponse:
|
|
161
|
+
content = ""
|
|
162
|
+
try:
|
|
163
|
+
content = raw["choices"][0]["message"]["content"]
|
|
164
|
+
except Exception:
|
|
165
|
+
content = raw.get("content") or raw.get("response") or raw.get("message") or ""
|
|
166
|
+
if isinstance(content, dict):
|
|
167
|
+
content = content.get("content", "")
|
|
168
|
+
return MayiaResponse(
|
|
169
|
+
id=raw.get("id"),
|
|
170
|
+
model=raw.get("model"),
|
|
171
|
+
content=str(content),
|
|
172
|
+
raw=raw,
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def api(api_key: Optional[str] = None, **kwargs: Any) -> Mayia:
|
|
177
|
+
"""Short factory matching `from mayia import api` usage."""
|
|
178
|
+
return Mayia(api_key=api_key, **kwargs)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mayia-ai
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Official Python SDK for the Mayia AI API
|
|
5
|
+
Author: ORF (Filip O.)
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://ai-mayia.web.app
|
|
8
|
+
Project-URL: Documentation, https://ai-mayia.web.app/api-center
|
|
9
|
+
Keywords: mayia,ai,sdk,api,llm
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Requires-Python: >=3.9
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
Dynamic: license-file
|
|
16
|
+
|
|
17
|
+
# Mayia Python SDK
|
|
18
|
+
|
|
19
|
+
Official Python client for the Mayia API.
|
|
20
|
+
|
|
21
|
+
## Install
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pip install mayia-ai
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Quick start
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
from mayia import api
|
|
31
|
+
|
|
32
|
+
client = api(api_key="mayia_sk_...")
|
|
33
|
+
print(client.ask("Explain quantum computing simply."))
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
OpenAI-style chat:
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
from mayia import Mayia
|
|
40
|
+
|
|
41
|
+
client = Mayia(api_key="mayia_sk_...")
|
|
42
|
+
response = client.chat.completions.create(
|
|
43
|
+
model="mayia-1",
|
|
44
|
+
messages=[{"role": "user", "content": "Build a Flask API."}],
|
|
45
|
+
)
|
|
46
|
+
print(response.content)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Environment variables:
|
|
50
|
+
|
|
51
|
+
- `MAYIA_API_KEY`
|
|
52
|
+
- `MAYIA_API_URL` (default: `https://ai-mayia.web.app/api`)
|
|
53
|
+
|
|
54
|
+
> Keep API keys server-side. Never ship a secret Mayia API key in a public website, Roblox LocalScript, downloadable game client, or mobile bundle.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/mayia/__init__.py
|
|
5
|
+
src/mayia/cli.py
|
|
6
|
+
src/mayia/client.py
|
|
7
|
+
src/mayia_ai.egg-info/PKG-INFO
|
|
8
|
+
src/mayia_ai.egg-info/SOURCES.txt
|
|
9
|
+
src/mayia_ai.egg-info/dependency_links.txt
|
|
10
|
+
src/mayia_ai.egg-info/entry_points.txt
|
|
11
|
+
src/mayia_ai.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
mayia
|