analitics

Pages

Saturday, May 30, 2026

Python 3.10.11 : MiniMax-M2.7 tested with python.

Today, I tested MiniMax-M2.7 with api key from nvidia and openai python package.
The script is one default example:
python -m pip install openai
Collecting openai
  Downloading openai-2.38.0-py3-none-any.whl.metadata (31 kB)
...
Successfully installed distro-1.9.0 jiter-0.15.0 openai-2.38.0
from openai import OpenAI

client = OpenAI(
  base_url = "https://integrate.api.nvidia.com/v1",
  api_key = "nvapi-nvidia"
)

completion = client.chat.completions.create(
  model="minimaxai/minimax-m2.7",
  messages=[{"role":"user","content":""}],
  temperature=1,
  top_p=0.95,
  max_tokens=8192,
  stream=False
)

print(completion.choices[0].message.content)
This will show only:
python minimax_27_001.py
Hello! How can I help you today?
I tested with this python script and works well:
import sys
from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, 
                             QHBoxLayout, QTextEdit, QLineEdit, QPushButton, QLabel)
from PyQt6.QtCore import QThread, pyqtSignal, Qt
from PyQt6.QtGui import QFont
from openai import OpenAI

# --- WORKER THREAD API ---
# Previne blocarea interfeței grafice în timpul apelului de rețea
class ApiWorker(QThread):
    response_received = pyqtSignal(str)
    error_occurred = pyqtSignal(str)

    def __init__(self, user_message):
        super().__init__()
        self.user_message = user_message

    def run(self):
        try:
            # Inițializare client OpenAI cu endpoint-ul Nvidia specificat de tine
            client = OpenAI(
                base_url="https://integrate.api.nvidia.com/v1",
                api_key="nvapi-KEY"  # nvidia api key
            )

            completion = client.chat.completions.create(
                model="minimaxai/minimax-m2.7",
                messages=[{"role": "user", "content": self.user_message}],
                temperature=1,
                top_p=0.95,
                max_tokens=8192,
                stream=False
            )
            
            # Trimite răspunsul înapoi către fereastra principală
            answer = completion.choices[0].message.content
            self.response_received.emit(answer)
            
        except Exception as e:
            self.error_occurred.emit(str(e))

class MiniMaxChatApp(QMainWindow):
    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle("MiniMax M2.7 - Interactive Chat")
        self.resize(600, 700)

        # Widget-ul central și layout-ul principal
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        main_layout = QVBoxLayout(central_widget)

        # 1. Zona de afișare a istoricului chat-ului
        self.chat_display = QTextEdit()
        self.chat_display.setReadOnly(True)
        self.chat_display.setFont(QFont("Segoe UI", 11))
        self.chat_display.setPlaceholderText("Conversația va apărea aici...")
        main_layout.addWidget(self.chat_display)

        # 2. Zona de introducere text și butonul (aranjate pe orizontală)
        input_layout = QHBoxLayout()
        
        self.input_field = QLineEdit()
        self.input_field.setFont(QFont("Segoe UI", 11))
        self.input_field.setPlaceholderText("Scrie un mesaj sau o comandă de Windows...")
        # Trimite mesajul când apeși tasta Enter
        self.input_field.returnPressed.connect(self.send_message) 
        input_layout.addWidget(self.input_field)

        self.send_button = QPushButton("Trimite")
        self.send_button.setFont(QFont("Segoe UI", 11, QFont.Weight.Bold))
        self.send_button.clicked.connect(self.send_message)
        input_layout.addWidget(self.send_button)

        main_layout.addLayout(input_layout)

        # 3. Indicator de status (jos de tot)
        self.status_label = QLabel("Pregătit")
        self.status_label.setStyleSheet("color: gray;")
        main_layout.addWidget(self.status_label)

    def send_message(self):
        user_text = self.input_field.text().strip()
        
        if not user_text:
            return  # Nu trimite dacă e gol

        # Adaugă mesajul utilizatorului în istoric și curăță câmpul de input
        self.chat_display.append(f"Tu: {user_text}\n")
        self.input_field.clear()

        # Dezactivează butoanele în timp ce AI-ul se gândește
        self.input_field.setEnabled(False)
        self.send_button.setEnabled(False)
        self.status_label.setText("MiniMax M2.7 gândește...")

        # Pornirea Thread-ului separat pentru apelul API
        self.worker = ApiWorker(user_text)
        self.worker.response_received.connect(self.handle_response)
        self.worker.error_occurred.connect(self.handle_error)
        self.worker.finished.connect(self.cleanup_worker)
        self.worker.start()

    def handle_response(self, ai_response):
        # Afișează răspunsul primit de la MiniMax
        self.chat_display.append(f"MiniMax M2.7: {ai_response}\n")
        self.chat_display.append("-" * 40 + "\n")
        self.status_label.setText("Răspuns primit.")

    def handle_error(self, error_msg):
        # Afișează eroarea în caz că pică netul sau cheia API e greșită
        self.chat_display.append(f"Eroare: {error_msg}\n")
        self.status_label.setText("A apărut o eroare.")

    def cleanup_worker(self):
        # Reatonează butoanele după ce procesul s-a încheiat
        self.input_field.setEnabled(True)
        self.send_button.setEnabled(True)
        self.input_field.setFocus()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    chat_window = MiniMaxChatApp()
    chat_window.show()
    sys.exit(app.exec())
This is the result:

News : ... Django 6.1 alpha 1 released by Jacob Walls on May 20, 2026!

Django 6.1 alpha 1 is now available. It represents the first stage in the 6.1 release cycle and is an opportunity to try out the changes coming in Django 6.1.
Django 6.1 offers a harmonious mélange of new features and usability improvements, which you can read about in the in-development 6.1 release notes.
This alpha milestone marks the feature freeze. The current release schedule calls for a beta release in about a month and a release candidate roughly a month after that. We'll only be able to keep this schedule with early and frequent testing from the community. Updates on the release schedule are available on the Django forum.

Python Qt : Testing new google_news_api released May 22, 2026.

Today, this script will help you too search and find results with google_news_api python package, released: May 22, 2026 by Paolo Mazza. Use your keywords, or make drag and drop ... See the official website - pypi.org.
import sys
import asyncio
import webbrowser
from functools import partial

from PyQt6.QtWidgets import (
QApplication, QWidget, QVBoxLayout, QHBoxLayout, QListWidget,
QListWidgetItem, QPushButton, QTextEdit, QLineEdit, QLabel,
QProgressBar, QFileDialog, QDialog
)
from PyQt6.QtCore import Qt, QThread, pyqtSignal

from google_news_api import AsyncGoogleNewsClient


# ---------------------------------------------------------
# Worker Thread for Async Google News
# ---------------------------------------------------------
class NewsWorker(QThread):
progress = pyqtSignal(int)
finished = pyqtSignal(list)

def __init__(self, queries):
super().__init__()
self.queries = queries

async def fetch_news(self):
results = []
async with AsyncGoogleNewsClient(language="en", country="US") as client:
batch = await client.batch_search(
queries=self.queries,
when="7d",
max_results=10
)

for idx, (topic, articles) in enumerate(batch.items()):
for article in articles:
url = await client.decode_url(article["link"])
results.append({
"title": article["title"],
"source": article["source"],
"url": url
})

self.progress.emit(int((idx + 1) / len(batch) * 100))

return results

def run(self):
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
results = loop.run_until_complete(self.fetch_news())
self.finished.emit(results)


# ---------------------------------------------------------
# HTML Results Dialog
# ---------------------------------------------------------
class ResultsDialog(QDialog):
def __init__(self, results):
super().__init__()
self.setWindowTitle("Search Results")

layout = QVBoxLayout(self)

self.text = QTextEdit()
self.text.setReadOnly(True)
layout.addWidget(self.text)

html = "<h2>Search Results</h2>"
for r in results:
html += f"""
<p>
<b>{r['title']}</b><br>
<i>{r['source']}</i><br>
<a href="{r['url']}">{r['url']}</a>
</p>
"""

self.text.setHtml(html)

save_btn = QPushButton("Save Results")
save_btn.clicked.connect(lambda: self.save_results(html))
layout.addWidget(save_btn)

def save_results(self, html):
file, _ = QFileDialog.getSaveFileName(self, "Save HTML", "", "HTML Files (*.html)")
if not file:
return
with open(file, "w", encoding="utf-8") as f:
f.write(html)


# ---------------------------------------------------------
# Main GUI
# ---------------------------------------------------------
class NewsGUI(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Google News Search Tool")
self.resize(900, 600)

main = QHBoxLayout(self)

# ---------------- LEFT: predefined keywords ----------------
left_layout = QVBoxLayout()
left_layout.addWidget(QLabel("Predefined Keywords"))

self.left_list = QListWidget()
self.left_list.setDragEnabled(True)
self.left_list.setSelectionMode(QListWidget.SelectionMode.SingleSelection)

predefined = [
"inteligență artificială", "python", "godot engine", "shaders",
"2D", "3D", "C#", "programming", "catafest",
"Catalin George Festila", "Fălticeni", "Suceava",
"investiții", "2026"
]

for word in predefined:
self.left_list.addItem(word)

left_layout.addWidget(self.left_list)

# Add custom keyword
self.add_keyword_input = QLineEdit()
self.add_keyword_input.setPlaceholderText("Add new keyword...")
left_layout.addWidget(self.add_keyword_input)

add_btn = QPushButton("Add Keyword")
add_btn.clicked.connect(self.add_keyword)
left_layout.addWidget(add_btn)

main.addLayout(left_layout)

# ---------------- RIGHT: search keywords ----------------
right_layout = QVBoxLayout()
right_layout.addWidget(QLabel("Search Keywords (drag from left)"))

self.right_list = QListWidget()
self.right_list.setAcceptDrops(True)
self.right_list.setDragEnabled(True)
self.right_list.setDefaultDropAction(Qt.DropAction.MoveAction)
right_layout.addWidget(self.right_list)

# Custom search input
self.custom_query = QLineEdit()
self.custom_query.setPlaceholderText("Custom search query...")
right_layout.addWidget(self.custom_query)

# Progress bar
self.progress = QProgressBar()
right_layout.addWidget(self.progress)

# Search button
search_btn = QPushButton("Process Search")
search_btn.clicked.connect(self.start_search)
right_layout.addWidget(search_btn)

main.addLayout(right_layout)

# ---------------------------------------------------------
# Add keyword
# ---------------------------------------------------------
def add_keyword(self):
text = self.add_keyword_input.text().strip()
if text:
self.left_list.addItem(text)
self.add_keyword_input.clear()

# ---------------------------------------------------------
# Start search
# ---------------------------------------------------------
def start_search(self):
queries = []

# from right canvas
for i in range(self.right_list.count()):
queries.append(self.right_list.item(i).text())

# custom query
if self.custom_query.text().strip():
queries.append(self.custom_query.text().strip())

if not queries:
QMessageBox.warning(self, "Warning", "No search keywords selected.")
return

self.worker = NewsWorker(queries)
self.worker.progress.connect(self.progress.setValue)
self.worker.finished.connect(self.show_results)
self.worker.start()

# ---------------------------------------------------------
# Show results dialog
# ---------------------------------------------------------
def show_results(self, results):
dlg = ResultsDialog(results)
dlg.exec()


# ---------------------------------------------------------
# MAIN
# ---------------------------------------------------------
if __name__ == "__main__":
app = QApplication(sys.argv)
gui = NewsGUI()
gui.show()
sys.exit(app.exec())
This is the result: