mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-05-02 04:12:47 +02:00
refactor: move Linear OAuth utils to connector, use httpx.AsyncClient
This commit is contained in:
parent
4b3d427e90
commit
f1a715e04e
4 changed files with 50 additions and 67 deletions
|
|
@ -399,11 +399,6 @@ async def fetch_airtable_user_email(access_token: str) -> str | None:
|
||||||
Returns:
|
Returns:
|
||||||
User's email address or None if fetch fails
|
User's email address or None if fetch fails
|
||||||
"""
|
"""
|
||||||
import httpx
|
|
||||||
import logging
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
async with httpx.AsyncClient() as client:
|
async with httpx.AsyncClient() as client:
|
||||||
response = await client.get(
|
response = await client.get(
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import logging
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
import httpx
|
||||||
import requests
|
import requests
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from sqlalchemy.future import select
|
from sqlalchemy.future import select
|
||||||
|
|
@ -21,6 +22,53 @@ from app.utils.oauth_security import TokenEncryption
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
LINEAR_GRAPHQL_URL = "https://api.linear.app/graphql"
|
||||||
|
|
||||||
|
ORGANIZATION_QUERY = """
|
||||||
|
query {
|
||||||
|
organization {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
async def fetch_linear_organization_name(access_token: str) -> str | None:
|
||||||
|
"""
|
||||||
|
Fetch organization/workspace name from Linear GraphQL API.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
access_token: The Linear OAuth access token
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Organization name or None if fetch fails
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
async with httpx.AsyncClient() as client:
|
||||||
|
response = await client.post(
|
||||||
|
LINEAR_GRAPHQL_URL,
|
||||||
|
headers={
|
||||||
|
"Authorization": access_token,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
json={"query": ORGANIZATION_QUERY},
|
||||||
|
timeout=10.0,
|
||||||
|
)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
data = response.json()
|
||||||
|
org_name = data.get("data", {}).get("organization", {}).get("name")
|
||||||
|
if org_name:
|
||||||
|
logger.debug(f"Fetched Linear organization name: {org_name}")
|
||||||
|
return org_name
|
||||||
|
|
||||||
|
logger.warning(f"Failed to fetch Linear org info: {response.status_code}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"Error fetching Linear organization name: {e!s}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
class LinearConnector:
|
class LinearConnector:
|
||||||
"""Class for retrieving issues and comments from Linear."""
|
"""Class for retrieving issues and comments from Linear."""
|
||||||
|
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
"""
|
|
||||||
Linear OAuth Utilities.
|
|
||||||
|
|
||||||
Provides functions for fetching user/organization info from Linear API.
|
|
||||||
Separated from linear_connector.py to avoid circular imports.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import httpx
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
LINEAR_GRAPHQL_URL = "https://api.linear.app/graphql"
|
|
||||||
|
|
||||||
ORGANIZATION_QUERY = """
|
|
||||||
query {
|
|
||||||
organization {
|
|
||||||
name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
async def fetch_linear_organization_name(access_token: str) -> str | None:
|
|
||||||
"""
|
|
||||||
Fetch organization/workspace name from Linear GraphQL API.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
access_token: The Linear OAuth access token
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Organization name or None if fetch fails
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
async with httpx.AsyncClient() as client:
|
|
||||||
response = await client.post(
|
|
||||||
LINEAR_GRAPHQL_URL,
|
|
||||||
headers={
|
|
||||||
"Authorization": access_token,
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
json={"query": ORGANIZATION_QUERY},
|
|
||||||
timeout=10.0,
|
|
||||||
)
|
|
||||||
|
|
||||||
if response.status_code == 200:
|
|
||||||
data = response.json()
|
|
||||||
org_name = data.get("data", {}).get("organization", {}).get("name")
|
|
||||||
if org_name:
|
|
||||||
logger.debug(f"Fetched Linear organization name: {org_name}")
|
|
||||||
return org_name
|
|
||||||
|
|
||||||
logger.warning(f"Failed to fetch Linear org info: {response.status_code}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.warning(f"Error fetching Linear organization name: {e!s}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
@ -23,7 +23,7 @@ from app.db import (
|
||||||
User,
|
User,
|
||||||
get_async_session,
|
get_async_session,
|
||||||
)
|
)
|
||||||
from app.connectors.linear_oauth import fetch_linear_organization_name
|
from app.connectors.linear_connector import fetch_linear_organization_name
|
||||||
from app.schemas.linear_auth_credentials import LinearAuthCredentialsBase
|
from app.schemas.linear_auth_credentials import LinearAuthCredentialsBase
|
||||||
from app.users import current_active_user
|
from app.users import current_active_user
|
||||||
from app.utils.connector_naming import check_duplicate_connector, generate_unique_connector_name
|
from app.utils.connector_naming import check_duplicate_connector, generate_unique_connector_name
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue