comp-ai-task 0.1.0__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,48 @@
1
+ Metadata-Version: 2.5
2
+ Name: comp-ai-task
3
+ Version: 0.1.0
4
+ Summary: Fast AI calls using task['query'] syntax in Python
5
+ Project-URL: Homepage, https://github.com/yourusername/comp-ai
6
+ Author: Marat
7
+ License: MIT
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Classifier: Programming Language :: Python :: 3
11
+ Requires-Python: >=3.8
12
+ Description-Content-Type: text/markdown
13
+
14
+ # comp_ai
15
+
16
+ Удобная библиотека для мгновенных запросов к ИИ прямо в Python IDLE или скриптах.
17
+
18
+ ## Установка (после публикации на PyPI)
19
+
20
+ ```bash
21
+ pip install comp-ai-task
22
+ ```
23
+
24
+ ## Использование в Python IDLE
25
+
26
+ ```python
27
+ from comp_ai import *
28
+
29
+ # Отправка запроса:
30
+ task["Напиши стих про космос"]
31
+
32
+ # Или как функция:
33
+ task("Объясни теорию относительности за 2 предложения")
34
+ ```
35
+
36
+ ## Настройка API-ключа
37
+
38
+ При первом обращении библиотека сама попросит ввести API-ключ Gemini и сохранит его локально.
39
+
40
+ Также ключ можно указать:
41
+ 1. В коде:
42
+ ```python
43
+ task.set_key("AIzaSy...")
44
+ ```
45
+ 2. Через переменную окружения:
46
+ ```bash
47
+ set GEMINI_API_KEY=AIzaSy...
48
+ ```
@@ -0,0 +1,35 @@
1
+ # comp_ai
2
+
3
+ Удобная библиотека для мгновенных запросов к ИИ прямо в Python IDLE или скриптах.
4
+
5
+ ## Установка (после публикации на PyPI)
6
+
7
+ ```bash
8
+ pip install comp-ai-task
9
+ ```
10
+
11
+ ## Использование в Python IDLE
12
+
13
+ ```python
14
+ from comp_ai import *
15
+
16
+ # Отправка запроса:
17
+ task["Напиши стих про космос"]
18
+
19
+ # Или как функция:
20
+ task("Объясни теорию относительности за 2 предложения")
21
+ ```
22
+
23
+ ## Настройка API-ключа
24
+
25
+ При первом обращении библиотека сама попросит ввести API-ключ Gemini и сохранит его локально.
26
+
27
+ Также ключ можно указать:
28
+ 1. В коде:
29
+ ```python
30
+ task.set_key("AIzaSy...")
31
+ ```
32
+ 2. Через переменную окружения:
33
+ ```bash
34
+ set GEMINI_API_KEY=AIzaSy...
35
+ ```
@@ -0,0 +1,147 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ comp_ai - модуль для быстрых запросов к ИИ в Python IDLE и скриптах.
4
+ """
5
+
6
+ import os
7
+ import sys
8
+ import json
9
+ import urllib.request
10
+ import urllib.error
11
+ from pathlib import Path
12
+ from typing import Optional
13
+
14
+ CONFIG_FILE = Path.home() / ".comp_ai_key"
15
+
16
+ class AITask:
17
+ def __init__(self, model: str = "gemini-3.6-flash"):
18
+ self.model = model
19
+ self._api_key: Optional[str] = None
20
+ self._load_key()
21
+
22
+ def _load_key(self):
23
+ """Загрузка ключа из переменных окружения или файла"""
24
+ env_key = os.getenv("GEMINI_API_KEY")
25
+ if env_key:
26
+ self._api_key = env_key.strip()
27
+ return
28
+
29
+ if CONFIG_FILE.exists():
30
+ try:
31
+ cached_key = CONFIG_FILE.read_text(encoding="utf-8").strip()
32
+ if cached_key:
33
+ self._api_key = cached_key
34
+ except Exception:
35
+ pass
36
+
37
+ def set_key(self, api_key: str, save_locally: bool = True):
38
+ """Установка ключа API"""
39
+ self._api_key = api_key.strip()
40
+ if save_locally:
41
+ try:
42
+ CONFIG_FILE.write_text(self._api_key, encoding="utf-8")
43
+ except Exception:
44
+ pass
45
+ print("[comp_ai] API-ключ сохранен!")
46
+
47
+ @property
48
+ def key(self) -> Optional[str]:
49
+ return self._api_key
50
+
51
+ @key.setter
52
+ def key(self, value: str):
53
+ self.set_key(value)
54
+
55
+ def _ensure_api_key(self) -> str:
56
+ """Запрос ключа, если он не найден"""
57
+ if self._api_key:
58
+ return self._api_key
59
+
60
+ print("\n" + "=" * 50)
61
+ print(" [comp_ai] API-ключ Gemini не найден!")
62
+ print(" Получить бесплатный ключ: https://aistudio.google.com/app/apikey")
63
+ print("=" * 50)
64
+
65
+ try:
66
+ user_input = input(" Введите ваш GEMINI_API_KEY: ").strip()
67
+ except (EOFError, KeyboardInterrupt):
68
+ user_input = ""
69
+
70
+ if not user_input:
71
+ raise ValueError(
72
+ "API-ключ не указан! Задайте его через task.set_key('...') или переменную GEMINI_API_KEY"
73
+ )
74
+
75
+ self.set_key(user_input, save_locally=True)
76
+ return self._api_key
77
+
78
+ def query(self, prompt: str) -> str:
79
+ """Вызов Gemini API"""
80
+ api_key = self._ensure_api_key()
81
+
82
+ # Если модель не сработала, пробуем fallback-модели
83
+ fallback_models = [self.model, "gemini-2.0-flash", "gemini-1.5-flash"]
84
+ # Убираем дубликаты сохраняя порядок
85
+ models_to_try = []
86
+ for m in fallback_models:
87
+ if m not in models_to_try:
88
+ models_to_try.append(m)
89
+
90
+ last_error = ""
91
+ for mod in models_to_try:
92
+ url = f"https://generativelanguage.googleapis.com/v1beta/models/{mod}:generateContent?key={api_key}"
93
+ headers = {"Content-Type": "application/json"}
94
+ payload = {"contents": [{"parts": [{"text": str(prompt)}]}]}
95
+
96
+ req = urllib.request.Request(
97
+ url,
98
+ data=json.dumps(payload).encode("utf-8"),
99
+ headers=headers,
100
+ method="POST"
101
+ )
102
+
103
+ try:
104
+ with urllib.request.urlopen(req) as resp:
105
+ resp_data = json.loads(resp.read().decode("utf-8"))
106
+ candidates = resp_data.get("candidates", [])
107
+ if not candidates:
108
+ text_res = "[Пустой ответ от модели]"
109
+ else:
110
+ parts = candidates[0].get("content", {}).get("parts", [])
111
+ text_res = "".join(p.get("text", "") for p in parts)
112
+
113
+ # Запоминаем рабочую модель
114
+ self.model = mod
115
+ print(text_res)
116
+ return text_res
117
+
118
+ except urllib.error.HTTPError as e:
119
+ error_body = e.read().decode("utf-8", errors="ignore")
120
+ last_error = f"[Ошибка API Gemini {e.code}]: {error_body}"
121
+ if e.code == 404:
122
+ # Пробуем следующую модель из списка
123
+ continue
124
+ else:
125
+ print(last_error, file=sys.stderr)
126
+ return last_error
127
+ except Exception as e:
128
+ last_error = f"[Ошибка запроса]: {e}"
129
+ print(last_error, file=sys.stderr)
130
+ return last_error
131
+
132
+ print(last_error, file=sys.stderr)
133
+ return last_error
134
+
135
+ def __getitem__(self, prompt: str) -> str:
136
+ return self.query(prompt)
137
+
138
+ def __call__(self, prompt: str) -> str:
139
+ return self.query(prompt)
140
+
141
+ def __repr__(self) -> str:
142
+ status = "готов" if self._api_key else "ожидает ключ"
143
+ return f"<comp_ai.task (модель: {self.model}, статус: {status})>"
144
+
145
+
146
+ task = AITask()
147
+ __all__ = ["task", "AITask"]
@@ -0,0 +1,32 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "comp-ai-task"
7
+ version = "0.1.0"
8
+ description = "Fast AI calls using task['query'] syntax in Python"
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+ license = { text = "MIT" }
12
+ authors = [
13
+ { name = "Marat" }
14
+ ]
15
+ classifiers = [
16
+ "Programming Language :: Python :: 3",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Operating System :: OS Independent",
19
+ ]
20
+
21
+ [tool.hatch.build.targets.wheel]
22
+ packages = ["comp_ai"]
23
+
24
+ [tool.hatch.build.targets.sdist]
25
+ include = [
26
+ "/comp_ai",
27
+ "/README.md",
28
+ "/pyproject.toml"
29
+ ]
30
+
31
+ [project.urls]
32
+ "Homepage" = "https://github.com/yourusername/comp-ai"