interloper-api 0.29.0__tar.gz → 0.30.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.
- {interloper_api-0.29.0 → interloper_api-0.30.0}/PKG-INFO +1 -1
- {interloper_api-0.29.0 → interloper_api-0.30.0}/pyproject.toml +1 -1
- {interloper_api-0.29.0 → interloper_api-0.30.0}/src/interloper_api/app.py +19 -10
- {interloper_api-0.29.0 → interloper_api-0.30.0}/src/interloper_api/dependencies.py +20 -0
- {interloper_api-0.29.0 → interloper_api-0.30.0}/src/interloper_api/routes/auth.py +3 -1
- {interloper_api-0.29.0 → interloper_api-0.30.0}/README.md +0 -0
- {interloper_api-0.29.0 → interloper_api-0.30.0}/src/interloper_api/__init__.py +0 -0
- {interloper_api-0.29.0 → interloper_api-0.30.0}/src/interloper_api/email.py +0 -0
- {interloper_api-0.29.0 → interloper_api-0.30.0}/src/interloper_api/routes/__init__.py +0 -0
- {interloper_api-0.29.0 → interloper_api-0.30.0}/src/interloper_api/routes/admin.py +0 -0
- {interloper_api-0.29.0 → interloper_api-0.30.0}/src/interloper_api/routes/agent.py +0 -0
- {interloper_api-0.29.0 → interloper_api-0.30.0}/src/interloper_api/routes/assets.py +0 -0
- {interloper_api-0.29.0 → interloper_api-0.30.0}/src/interloper_api/routes/backfills.py +0 -0
- {interloper_api-0.29.0 → interloper_api-0.30.0}/src/interloper_api/routes/catalog.py +0 -0
- {interloper_api-0.29.0 → interloper_api-0.30.0}/src/interloper_api/routes/destinations.py +0 -0
- {interloper_api-0.29.0 → interloper_api-0.30.0}/src/interloper_api/routes/external/__init__.py +0 -0
- {interloper_api-0.29.0 → interloper_api-0.30.0}/src/interloper_api/routes/external/resolve.py +0 -0
- {interloper_api-0.29.0 → interloper_api-0.30.0}/src/interloper_api/routes/jobs.py +0 -0
- {interloper_api-0.29.0 → interloper_api-0.30.0}/src/interloper_api/routes/oauth.py +0 -0
- {interloper_api-0.29.0 → interloper_api-0.30.0}/src/interloper_api/routes/organisations.py +0 -0
- {interloper_api-0.29.0 → interloper_api-0.30.0}/src/interloper_api/routes/resources.py +0 -0
- {interloper_api-0.29.0 → interloper_api-0.30.0}/src/interloper_api/routes/runs.py +0 -0
- {interloper_api-0.29.0 → interloper_api-0.30.0}/src/interloper_api/routes/sources.py +0 -0
- {interloper_api-0.29.0 → interloper_api-0.30.0}/src/interloper_api/routes/ws.py +0 -0
|
@@ -12,7 +12,7 @@ from interloper.catalog.base import Catalog
|
|
|
12
12
|
from interloper.errors import ComponentDriftError
|
|
13
13
|
from interloper_db import Store
|
|
14
14
|
|
|
15
|
-
from interloper_api.dependencies import set_auth_config, set_catalog, set_smtp_config, set_store
|
|
15
|
+
from interloper_api.dependencies import set_auth_config, set_catalog, set_features, set_smtp_config, set_store
|
|
16
16
|
from interloper_api.routes import (
|
|
17
17
|
admin,
|
|
18
18
|
assets,
|
|
@@ -38,6 +38,7 @@ def create_app(
|
|
|
38
38
|
catalog: Catalog | None = None,
|
|
39
39
|
auth_config: Any | None = None,
|
|
40
40
|
smtp_config: Any | None = None,
|
|
41
|
+
agent_config: Any | None = None,
|
|
41
42
|
cors_origins: list[str] | None = None,
|
|
42
43
|
**kwargs: Any,
|
|
43
44
|
) -> FastAPI:
|
|
@@ -48,6 +49,8 @@ def create_app(
|
|
|
48
49
|
catalog: Catalog instance.
|
|
49
50
|
auth_config: ``AuthConfig`` instance for authentication settings.
|
|
50
51
|
smtp_config: ``SmtpConfig`` instance for sending invitation emails.
|
|
52
|
+
agent_config: ``AgentSettings`` instance; the agent routes mount only
|
|
53
|
+
when it's enabled (or None) and the ``agent`` extra is installed.
|
|
51
54
|
cors_origins: Allowed CORS origins. Only needed in dev mode for direct
|
|
52
55
|
WebSocket connections that bypass the Vite proxy.
|
|
53
56
|
**kwargs: Additional kwargs forwarded to ``FastAPI()``.
|
|
@@ -100,15 +103,21 @@ def create_app(
|
|
|
100
103
|
api.include_router(external.router, prefix="/external", tags=["external"])
|
|
101
104
|
api.include_router(ws.router, tags=["ws"])
|
|
102
105
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
106
|
+
agent_available = False
|
|
107
|
+
if agent_config is None or agent_config.enabled:
|
|
108
|
+
try:
|
|
109
|
+
from interloper_api.routes import agent as agent_routes
|
|
110
|
+
|
|
111
|
+
api.include_router(agent_routes.router, prefix="/agent", tags=["agent"])
|
|
112
|
+
agent_available = True
|
|
113
|
+
except ImportError:
|
|
114
|
+
logger.warning(
|
|
115
|
+
"Agent routes not mounted: the 'agent' extra is not installed "
|
|
116
|
+
"(install interloper-api[agent]); /agent endpoints will return 404."
|
|
117
|
+
)
|
|
118
|
+
else:
|
|
119
|
+
logger.info("Agent routes not mounted: disabled via settings.")
|
|
120
|
+
set_features({"agent": agent_available})
|
|
112
121
|
|
|
113
122
|
@api.get("/health")
|
|
114
123
|
def health() -> dict[str, str]:
|
|
@@ -14,6 +14,7 @@ _store: Store | None = None
|
|
|
14
14
|
_catalog: Catalog | None = None
|
|
15
15
|
_auth_config: Any | None = None
|
|
16
16
|
_smtp_config: Any | None = None
|
|
17
|
+
_features: dict[str, bool] = {}
|
|
17
18
|
|
|
18
19
|
# Role hierarchy: admin > editor > viewer
|
|
19
20
|
_ROLE_RANK = {"viewer": 0, "editor": 1, "admin": 2}
|
|
@@ -112,6 +113,25 @@ def get_smtp_config() -> Any:
|
|
|
112
113
|
return _smtp_config
|
|
113
114
|
|
|
114
115
|
|
|
116
|
+
def set_features(features: dict[str, bool]) -> None:
|
|
117
|
+
"""Set the optional-feature availability flags (resolved at app creation).
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
features: Feature name → availability.
|
|
121
|
+
"""
|
|
122
|
+
global _features # noqa: PLW0603
|
|
123
|
+
_features = features
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def get_features() -> dict[str, bool]:
|
|
127
|
+
"""Return the optional-feature availability flags.
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
Feature name → availability; empty if never set.
|
|
131
|
+
"""
|
|
132
|
+
return _features
|
|
133
|
+
|
|
134
|
+
|
|
115
135
|
# -- Auth dependencies -------------------------------------------------------
|
|
116
136
|
|
|
117
137
|
|
|
@@ -13,7 +13,7 @@ from fastapi.responses import RedirectResponse
|
|
|
13
13
|
from interloper_db import Organisation, Profile, Store
|
|
14
14
|
from pydantic import BaseModel
|
|
15
15
|
|
|
16
|
-
from interloper_api.dependencies import get_auth_config, get_current_user, get_store
|
|
16
|
+
from interloper_api.dependencies import get_auth_config, get_current_user, get_features, get_store
|
|
17
17
|
|
|
18
18
|
GOOGLE_AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth"
|
|
19
19
|
GOOGLE_TOKEN_URL = "https://oauth2.googleapis.com/token"
|
|
@@ -41,6 +41,7 @@ class AuthUserResponse(BaseModel):
|
|
|
41
41
|
is_super_admin: bool = False
|
|
42
42
|
organisation: OrganisationResponse | None = None
|
|
43
43
|
last_organisation_id: UUID | None = None
|
|
44
|
+
features: dict[str, bool] = {}
|
|
44
45
|
|
|
45
46
|
|
|
46
47
|
@router.get("/google")
|
|
@@ -193,6 +194,7 @@ def get_me(
|
|
|
193
194
|
is_super_admin=profile.is_super_admin,
|
|
194
195
|
organisation=OrganisationResponse.model_validate(org, from_attributes=True) if org else None,
|
|
195
196
|
last_organisation_id=profile.last_organisation_id,
|
|
197
|
+
features=get_features(),
|
|
196
198
|
)
|
|
197
199
|
|
|
198
200
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{interloper_api-0.29.0 → interloper_api-0.30.0}/src/interloper_api/routes/external/__init__.py
RENAMED
|
File without changes
|
{interloper_api-0.29.0 → interloper_api-0.30.0}/src/interloper_api/routes/external/resolve.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|