chore: format
This commit is contained in:
@@ -56,10 +56,7 @@ def extract_ssl_mode_from_url(url: str) -> tuple[str, str | None]:
|
||||
|
||||
Non-PostgreSQL URLs are returned unchanged with ``ssl_mode=None``.
|
||||
"""
|
||||
if not url or not any(
|
||||
url.startswith(prefix)
|
||||
for prefix in ('postgresql://', 'postgresql+', 'postgres://')
|
||||
):
|
||||
if not url or not any(url.startswith(prefix) for prefix in ('postgresql://', 'postgresql+', 'postgres://')):
|
||||
return url, None
|
||||
|
||||
parsed = urlparse(url)
|
||||
@@ -126,7 +123,6 @@ def reattach_ssl_mode_to_url(url_without_ssl: str, ssl_mode: str | None) -> str:
|
||||
return f'{url_without_ssl}{separator}sslmode={ssl_mode}'
|
||||
|
||||
|
||||
|
||||
class JSONField(types.TypeDecorator):
|
||||
impl = types.Text
|
||||
cache_ok = True
|
||||
@@ -188,7 +184,9 @@ if ENABLE_DB_MIGRATIONS:
|
||||
DATABASE_URL_WITHOUT_SSL, DATABASE_SSL_MODE = extract_ssl_mode_from_url(DATABASE_URL)
|
||||
|
||||
# For psycopg2 (sync engine), re-append sslmode=<value>.
|
||||
SQLALCHEMY_DATABASE_URL = reattach_ssl_mode_to_url(DATABASE_URL_WITHOUT_SSL, DATABASE_SSL_MODE) if DATABASE_SSL_MODE else DATABASE_URL
|
||||
SQLALCHEMY_DATABASE_URL = (
|
||||
reattach_ssl_mode_to_url(DATABASE_URL_WITHOUT_SSL, DATABASE_SSL_MODE) if DATABASE_SSL_MODE else DATABASE_URL
|
||||
)
|
||||
|
||||
|
||||
def _make_async_url(url: str) -> str:
|
||||
@@ -332,15 +330,13 @@ get_db = contextmanager(get_session)
|
||||
# ============================================================
|
||||
|
||||
# Use the SSL-stripped URL for asyncpg — SSL is injected via connect_args.
|
||||
ASYNC_SQLALCHEMY_DATABASE_URL = _make_async_url(DATABASE_URL_WITHOUT_SSL if DATABASE_SSL_MODE else SQLALCHEMY_DATABASE_URL)
|
||||
ASYNC_SQLALCHEMY_DATABASE_URL = _make_async_url(
|
||||
DATABASE_URL_WITHOUT_SSL if DATABASE_SSL_MODE else SQLALCHEMY_DATABASE_URL
|
||||
)
|
||||
|
||||
if 'sqlite' in ASYNC_SQLALCHEMY_DATABASE_URL:
|
||||
# Generous default — async coroutines + no session sharing = high connection demand.
|
||||
_sqlite_pool_size = (
|
||||
DATABASE_POOL_SIZE
|
||||
if isinstance(DATABASE_POOL_SIZE, int) and DATABASE_POOL_SIZE > 0
|
||||
else 512
|
||||
)
|
||||
_sqlite_pool_size = DATABASE_POOL_SIZE if isinstance(DATABASE_POOL_SIZE, int) and DATABASE_POOL_SIZE > 0 else 512
|
||||
async_engine = create_async_engine(
|
||||
ASYNC_SQLALCHEMY_DATABASE_URL,
|
||||
connect_args={'check_same_thread': False},
|
||||
|
||||
@@ -307,8 +307,6 @@ class CalendarTable:
|
||||
cal = result.scalars().first()
|
||||
return await self._to_calendar_model(cal, db=db) if cal else None
|
||||
|
||||
|
||||
|
||||
async def insert_new_calendar(
|
||||
self, user_id: str, form_data: CalendarForm, db: Optional[AsyncSession] = None
|
||||
) -> Optional[CalendarModel]:
|
||||
|
||||
@@ -122,9 +122,7 @@ def build_loader_from_config(request):
|
||||
)
|
||||
|
||||
|
||||
def _extract_text_from_binary_response(
|
||||
request, response: requests.Response, url: str
|
||||
) -> tuple[str, list]:
|
||||
def _extract_text_from_binary_response(request, response: requests.Response, url: str) -> tuple[str, list]:
|
||||
"""Download response body to a temp file and extract text using the Loader pipeline."""
|
||||
import mimetypes
|
||||
import tempfile
|
||||
|
||||
@@ -55,9 +55,7 @@ async def _user_has_automations(request: Request, user) -> bool:
|
||||
return False
|
||||
if user.role == 'admin':
|
||||
return True
|
||||
return await has_permission(
|
||||
user.id, 'features.automations', request.app.state.config.USER_PERMISSIONS
|
||||
)
|
||||
return await has_permission(user.id, 'features.automations', request.app.state.config.USER_PERMISSIONS)
|
||||
|
||||
|
||||
async def _check_calendar_access(calendar_id: str, user: UserModel, permission: str = 'write') -> CalendarModel:
|
||||
|
||||
@@ -293,7 +293,9 @@ async def verify_terminal_server_connection(
|
||||
) as session:
|
||||
# Orchestrators expose a policies API; plain terminals don't.
|
||||
try:
|
||||
async with session.get(f'{base_url}/api/v1/policies', headers=headers, ssl=AIOHTTP_CLIENT_SESSION_SSL) as resp:
|
||||
async with session.get(
|
||||
f'{base_url}/api/v1/policies', headers=headers, ssl=AIOHTTP_CLIENT_SESSION_SSL
|
||||
) as resp:
|
||||
if resp.ok:
|
||||
return {'status': True, 'type': 'orchestrator'}
|
||||
except Exception:
|
||||
@@ -301,7 +303,9 @@ async def verify_terminal_server_connection(
|
||||
|
||||
# Fall back to open-terminal config endpoint.
|
||||
try:
|
||||
async with session.get(f'{base_url}/api/config', headers=headers, ssl=AIOHTTP_CLIENT_SESSION_SSL) as resp:
|
||||
async with session.get(
|
||||
f'{base_url}/api/config', headers=headers, ssl=AIOHTTP_CLIENT_SESSION_SSL
|
||||
) as resp:
|
||||
if resp.ok:
|
||||
return {'status': True, 'type': 'terminal'}
|
||||
except Exception:
|
||||
@@ -342,7 +346,9 @@ async def put_terminal_server_policy(
|
||||
timeout=aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT),
|
||||
) as session:
|
||||
policy_url = f'{base_url}/api/v1/policies/{form_data.policy_id}'
|
||||
async with session.put(policy_url, headers=headers, json=form_data.policy_data, ssl=AIOHTTP_CLIENT_SESSION_SSL) as resp:
|
||||
async with session.put(
|
||||
policy_url, headers=headers, json=form_data.policy_data, ssl=AIOHTTP_CLIENT_SESSION_SSL
|
||||
) as resp:
|
||||
if resp.ok:
|
||||
return await resp.json()
|
||||
detail = await resp.text()
|
||||
@@ -369,7 +375,9 @@ async def verify_tool_servers_config(request: Request, form_data: ToolServerConn
|
||||
trust_env=True,
|
||||
timeout=aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT),
|
||||
) as session:
|
||||
async with session.get(discovery_url, ssl=AIOHTTP_CLIENT_SESSION_SSL) as oauth_server_metadata_response:
|
||||
async with session.get(
|
||||
discovery_url, ssl=AIOHTTP_CLIENT_SESSION_SSL
|
||||
) as oauth_server_metadata_response:
|
||||
if oauth_server_metadata_response.status == 200:
|
||||
try:
|
||||
oauth_server_metadata = OAuthMetadata.model_validate(
|
||||
|
||||
@@ -117,7 +117,9 @@ async def load_function_from_url(request: Request, form_data: LoadUrlForm, user=
|
||||
async with aiohttp.ClientSession(
|
||||
trust_env=True, timeout=aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT)
|
||||
) as session:
|
||||
async with session.get(url, headers={'Content-Type': 'application/json'}, ssl=AIOHTTP_CLIENT_SESSION_SSL) as resp:
|
||||
async with session.get(
|
||||
url, headers={'Content-Type': 'application/json'}, ssl=AIOHTTP_CLIENT_SESSION_SSL
|
||||
) as resp:
|
||||
if resp.status != 200:
|
||||
raise HTTPException(status_code=resp.status, detail='Failed to fetch the function')
|
||||
data = await resp.text()
|
||||
|
||||
@@ -274,7 +274,9 @@ async def load_tool_from_url(request: Request, form_data: LoadUrlForm, user=Depe
|
||||
async with aiohttp.ClientSession(
|
||||
trust_env=True, timeout=aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT)
|
||||
) as session:
|
||||
async with session.get(url, headers={'Content-Type': 'application/json'}, ssl=AIOHTTP_CLIENT_SESSION_SSL) as resp:
|
||||
async with session.get(
|
||||
url, headers={'Content-Type': 'application/json'}, ssl=AIOHTTP_CLIENT_SESSION_SSL
|
||||
) as resp:
|
||||
if resp.status != 200:
|
||||
raise HTTPException(status_code=resp.status, detail='Failed to fetch the tool')
|
||||
data = await resp.text()
|
||||
|
||||
@@ -34,19 +34,19 @@ MARKDOWN_IMAGE_URL_PATTERN = re.compile(r'!\[(.*?)\]\((.+?)\)', re.IGNORECASE)
|
||||
|
||||
# Extension-based MIME fallback, only used when ENABLE_IMAGE_CONTENT_TYPE_EXTENSION_FALLBACK is True.
|
||||
_IMAGE_MIME_FALLBACK = {
|
||||
".webp": "image/webp",
|
||||
".png": "image/png",
|
||||
".jpg": "image/jpeg",
|
||||
".jpeg": "image/jpeg",
|
||||
".gif": "image/gif",
|
||||
".svg": "image/svg+xml",
|
||||
".bmp": "image/bmp",
|
||||
".tiff": "image/tiff",
|
||||
".tif": "image/tiff",
|
||||
".ico": "image/x-icon",
|
||||
".heic": "image/heic",
|
||||
".heif": "image/heif",
|
||||
".avif": "image/avif",
|
||||
'.webp': 'image/webp',
|
||||
'.png': 'image/png',
|
||||
'.jpg': 'image/jpeg',
|
||||
'.jpeg': 'image/jpeg',
|
||||
'.gif': 'image/gif',
|
||||
'.svg': 'image/svg+xml',
|
||||
'.bmp': 'image/bmp',
|
||||
'.tiff': 'image/tiff',
|
||||
'.tif': 'image/tiff',
|
||||
'.ico': 'image/x-icon',
|
||||
'.heic': 'image/heic',
|
||||
'.heif': 'image/heif',
|
||||
'.avif': 'image/avif',
|
||||
}
|
||||
|
||||
|
||||
@@ -75,10 +75,7 @@ async def get_image_base64_from_url(url: str) -> Optional[str]:
|
||||
if file_path.is_file():
|
||||
with open(file_path, 'rb') as image_file:
|
||||
encoded_string = base64.b64encode(image_file.read()).decode('utf-8')
|
||||
content_type = (
|
||||
mimetypes.guess_type(file_path.name)[0]
|
||||
or (file.meta or {}).get('content_type')
|
||||
)
|
||||
content_type = mimetypes.guess_type(file_path.name)[0] or (file.meta or {}).get('content_type')
|
||||
if not content_type and ENABLE_IMAGE_CONTENT_TYPE_EXTENSION_FALLBACK:
|
||||
content_type = _IMAGE_MIME_FALLBACK.get(file_path.suffix.lower())
|
||||
if not content_type:
|
||||
@@ -204,10 +201,7 @@ async def get_image_base64_from_file_id(id: str) -> Optional[str]:
|
||||
if file_path.is_file():
|
||||
with open(file_path, 'rb') as image_file:
|
||||
encoded_string = base64.b64encode(image_file.read()).decode('utf-8')
|
||||
content_type = (
|
||||
mimetypes.guess_type(file_path.name)[0]
|
||||
or (file.meta or {}).get('content_type')
|
||||
)
|
||||
content_type = mimetypes.guess_type(file_path.name)[0] or (file.meta or {}).get('content_type')
|
||||
if not content_type and ENABLE_IMAGE_CONTENT_TYPE_EXTENSION_FALLBACK:
|
||||
content_type = _IMAGE_MIME_FALLBACK.get(file_path.suffix.lower())
|
||||
if not content_type:
|
||||
|
||||
@@ -908,7 +908,9 @@ async def get_terminal_cwd(
|
||||
timeout=aiohttp.ClientTimeout(total=5),
|
||||
trust_env=True,
|
||||
) as session:
|
||||
async with session.get(cwd_url, headers=headers, cookies=cookies or {}, ssl=AIOHTTP_CLIENT_SESSION_SSL) as resp:
|
||||
async with session.get(
|
||||
cwd_url, headers=headers, cookies=cookies or {}, ssl=AIOHTTP_CLIENT_SESSION_SSL
|
||||
) as resp:
|
||||
if resp.status == 200:
|
||||
data = await resp.json()
|
||||
return data.get('cwd')
|
||||
@@ -943,7 +945,9 @@ async def get_terminal_system_prompt(
|
||||
return None
|
||||
|
||||
# 2. Fetch system prompt
|
||||
async with session.get(f'{base}/system', headers=headers, cookies=cookies or {}, ssl=AIOHTTP_CLIENT_SESSION_SSL) as resp:
|
||||
async with session.get(
|
||||
f'{base}/system', headers=headers, cookies=cookies or {}, ssl=AIOHTTP_CLIENT_SESSION_SSL
|
||||
) as resp:
|
||||
if resp.status == 200:
|
||||
data = await resp.json()
|
||||
return data.get('prompt')
|
||||
|
||||
Reference in New Issue
Block a user