GitPasha MCP Server - Ready for deployment
هذا الالتزام موجود في:
13
helpers/__init__.py
Normal file
13
helpers/__init__.py
Normal file
@@ -0,0 +1,13 @@
|
||||
from helpers.logger import log
|
||||
from helpers.headers import get_headers
|
||||
from helpers.descriptions import suggest_description
|
||||
from helpers.error_formatter import format_error
|
||||
from helpers.http_client import build_client
|
||||
|
||||
__all__ = [
|
||||
"log",
|
||||
"get_headers",
|
||||
"suggest_description",
|
||||
"format_error",
|
||||
"build_client"
|
||||
]
|
||||
3
helpers/descriptions.py
Normal file
3
helpers/descriptions.py
Normal file
@@ -0,0 +1,3 @@
|
||||
def suggest_description(name: str) -> str:
|
||||
name = (name or "").strip()
|
||||
return f"{name or 'test'}: Repository for testing and experiments"
|
||||
15
helpers/error_formatter.py
Normal file
15
helpers/error_formatter.py
Normal file
@@ -0,0 +1,15 @@
|
||||
import httpx
|
||||
|
||||
|
||||
def format_error(prefix: str, e: Exception) -> str:
|
||||
if isinstance(e, httpx.HTTPStatusError):
|
||||
code = e.response.status_code
|
||||
text = e.response.text
|
||||
if code in (301, 302, 307, 308):
|
||||
return f"{prefix}: {code} - Redirect detected. Probably web UI, not API."
|
||||
if "CSRF" in text:
|
||||
return f"{prefix}: {code} - CSRF error. Wrong domain."
|
||||
if code in (401, 403):
|
||||
return f"{prefix}: {code} - Invalid or expired API key."
|
||||
return f"{prefix}: {code} - {text}"
|
||||
return f"{prefix}: {str(e)}"
|
||||
10
helpers/headers.py
Normal file
10
helpers/headers.py
Normal file
@@ -0,0 +1,10 @@
|
||||
import os
|
||||
|
||||
|
||||
def get_headers():
|
||||
api_key = os.getenv("GITPASHA_API_KEY", "")
|
||||
return {
|
||||
"Authorization": f"token {api_key}",
|
||||
"Content-Type": "application/json",
|
||||
"Accept": "application/json",
|
||||
}
|
||||
33
helpers/http_client.py
Normal file
33
helpers/http_client.py
Normal file
@@ -0,0 +1,33 @@
|
||||
import httpx
|
||||
from helpers.logger import log
|
||||
|
||||
|
||||
def log_request(req: httpx.Request):
|
||||
safe_headers = {
|
||||
k: ("<hidden>" if k.lower() == "authorization" else v)
|
||||
for k, v in req.headers.items()
|
||||
}
|
||||
log.info(f"=> {req.method} {req.url}")
|
||||
log.debug(f"Headers: {safe_headers}")
|
||||
try:
|
||||
log.debug(f"Body: {req.content.decode()[:1000]}")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def log_response(res: httpx.Response):
|
||||
log.info(f"<= {res.status_code} {res.request.method} {res.request.url}")
|
||||
try:
|
||||
if res.status_code >= 400:
|
||||
content = res.read()
|
||||
log.debug(f"Response: {content.decode()[:2000]}")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def build_client() -> httpx.Client:
|
||||
return httpx.Client(
|
||||
follow_redirects=False,
|
||||
timeout=120.0,
|
||||
event_hooks={"request": [log_request], "response": [log_response]},
|
||||
)
|
||||
16
helpers/logger.py
Normal file
16
helpers/logger.py
Normal file
@@ -0,0 +1,16 @@
|
||||
import os
|
||||
import logging
|
||||
|
||||
LOG_LEVEL = os.getenv("LOG_LEVEL", "DEBUG").upper()
|
||||
LOG_FILE = os.getenv("LOG_FILE", "logs/gitpasha.log")
|
||||
|
||||
logging.basicConfig(
|
||||
level=getattr(logging, LOG_LEVEL, logging.DEBUG),
|
||||
format="%(asctime)s | %(levelname)s | %(message)s",
|
||||
handlers=[
|
||||
logging.FileHandler(LOG_FILE, mode="a", encoding="utf-8"),
|
||||
logging.StreamHandler()
|
||||
],
|
||||
)
|
||||
|
||||
log = logging.getLogger("gitpasha")
|
||||
المرجع في مشكلة جديدة
حظر مستخدم