Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/indigoapi/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import uvicorn

from indigoapi.config import Config
from indigoapi.main import start_api
from indigoapi.server import start_api

from ._version import __version__

Expand Down Expand Up @@ -61,7 +61,7 @@ def serve(ctx: click.Context):
logger.info(f"port {config.server.port}")

uvicorn.run(
f"indigoapi.main:{start_api.__name__}",
f"indigoapi.server:{start_api.__name__}",
factory=True,
host=config.server.host,
port=int(config.server.port),
Expand Down
20 changes: 1 addition & 19 deletions src/indigoapi/analyses/__init__.py
Original file line number Diff line number Diff line change
@@ -1,19 +1 @@
import importlib

from indigoapi.analyses.loader import load_analyses, load_plugins
from indigoapi.config import Config

MODULE_NAMES = []


def initialize_analyses(register_all: bool = False):
"""Load built-in analyses and user plugins. Call during server startup."""
global MODULE_NAMES

# load built-in analyses
package = importlib.import_module(__name__)
MODULE_NAMES = load_analyses(package)

# load user plugins from config
config = Config.load_config()
load_plugins(config, register_all=register_all)
"""Package containing built-in analysis modules."""
2 changes: 1 addition & 1 deletion src/indigoapi/analyses/peak_fitting.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import numpy as np
from scipy.optimize import curve_fit

from indigoapi.analyses.decorator import analysis
from indigoapi.analysis_core.decorator import analysis


def gaussian(x: np.ndarray, amplitude: float, x0: float, sigma: float) -> np.ndarray:
Expand Down
2 changes: 1 addition & 1 deletion src/indigoapi/analyses/simple_maths.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import numpy as np

from indigoapi.analyses.decorator import analysis
from indigoapi.analysis_core.decorator import analysis


@analysis()
Expand Down
41 changes: 41 additions & 0 deletions src/indigoapi/analysis_core/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import importlib

from indigoapi.config import Config

from .decorator import analysis
from .loader import get_async_function, load_analyses, load_plugins
from .registry import (
ANALYSIS_REGISTRY,
AnalysisNotFoundError,
get_analysis,
list_analyses,
register_analysis,
)

MODULE_NAMES: list[str] = []


def initialize_analyses(register_all: bool = False):
"""Load built-in analyses and user plugins. Call during server startup."""
global MODULE_NAMES

package = importlib.import_module("indigoapi.analyses")
MODULE_NAMES = load_analyses(package)

config = Config.load_config()
load_plugins(config, register_all=register_all)


__all__ = [
"analysis",
"get_async_function",
"load_analyses",
"load_plugins",
"ANALYSIS_REGISTRY",
"AnalysisNotFoundError",
"get_analysis",
"list_analyses",
"register_analysis",
"initialize_analyses",
"MODULE_NAMES",
]
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from collections.abc import Awaitable, Callable
from typing import ParamSpec, TypeVar

from indigoapi.analyses.loader import get_async_function
from indigoapi.analyses.registry import register_analysis
from indigoapi.analysis_core.loader import get_async_function
from indigoapi.analysis_core.registry import register_analysis

P = ParamSpec("P")
R = TypeVar("R")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from git import Repo

from indigoapi.analyses.registry import register_analysis
from indigoapi.analysis_core.registry import register_analysis
from indigoapi.config import Config

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -127,7 +127,7 @@ def load_plugins(config: Config, register_all: bool = False):


# if __name__ == "__main__":
# from indigoapi.analyses.registry import list_analyses
# from indigoapi.analysis_core.registry import list_analyses

# load_plugins(Config.load_config())

Expand Down
4 changes: 2 additions & 2 deletions src/indigoapi/api/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
from fastapi import APIRouter, HTTPException, Request
from fastapi.routing import APIRoute

from indigoapi.analyses.registry import get_analysis, list_analyses
from indigoapi.analysis_core.registry import get_analysis, list_analyses
from indigoapi.models import AnalysisRequest, AnalysisResult
from indigoapi.queue_manager import QueueManager
from indigoapi.queue import QueueManager

ROUTER = APIRouter()

Expand Down
5 changes: 5 additions & 0 deletions src/indigoapi/queue/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from .cleanup import cleanup_results
from .manager import QueueManager
from .rabbitmq import RabbitMQListener

__all__ = ["cleanup_results", "QueueManager", "RabbitMQListener"]
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from xrpd_toolbox.utils.messenger import DEFAULT_DII_PROCESSED_DESTINATION, Messenger

from indigoapi.analyses.registry import get_analysis
from indigoapi.analysis_core.registry import get_analysis
from indigoapi.models import AnalysisRequest, AnalysisResult

logging.basicConfig(level=logging.INFO)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from pydantic import BaseModel, Field

from indigoapi.models import AnalysisRequest
from indigoapi.queue_manager import QueueManager
from indigoapi.queue import QueueManager

logger = logging.getLogger(__name__)

Expand Down
8 changes: 3 additions & 5 deletions src/indigoapi/main.py → src/indigoapi/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@
from fastapi import FastAPI
from xrpd_toolbox.utils.messenger import Messenger

from indigoapi.analyses import MODULE_NAMES, initialize_analyses
from indigoapi.analysis_core import MODULE_NAMES, initialize_analyses
from indigoapi.api.routes import ROUTER
from indigoapi.cleanup import cleanup_results
from indigoapi.config import Config
from indigoapi.queue_manager import QueueManager
from indigoapi.rabbitmq_listener import RabbitMQListener
from indigoapi.queue import QueueManager, RabbitMQListener, cleanup_results

from . import __version__

Expand Down Expand Up @@ -88,7 +86,7 @@ def start_api() -> FastAPI:
logger.info(f"version: {__version__}")

app = FastAPI(
title="IndigoAPI",
title="indigoapi",
version=__version__,
description="An API for fast data analysis jobs",
lifespan=lifespan,
Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import importlib

from indigoapi.analyses.loader import load_analyses
from indigoapi.analysis_core.loader import load_analyses


def pytest_configure():
Expand Down
2 changes: 1 addition & 1 deletion tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
from fastapi.testclient import TestClient

from indigoapi.config import Config
from indigoapi.main import start_api
from indigoapi.models import AnalysisRequest
from indigoapi.server import start_api


def test_analysis_flow_with_post():
Expand Down
2 changes: 1 addition & 1 deletion tests/test_api_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

from fastapi.testclient import TestClient

from indigoapi.main import start_api
from indigoapi.models import AnalysisResult
from indigoapi.server import start_api


def test_api_health_and_endpoints_routes():
Expand Down
6 changes: 3 additions & 3 deletions tests/test_cleanup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import pytest

from indigoapi.cleanup import cleanup_results
from indigoapi.queue import cleanup_results


@pytest.mark.asyncio
Expand All @@ -19,7 +19,7 @@ class FakeQueue:
async def fake_sleep(interval):
raise asyncio.CancelledError

monkeypatch.setattr("indigoapi.cleanup.asyncio.sleep", fake_sleep)
monkeypatch.setattr("indigoapi.queue.cleanup.asyncio.sleep", fake_sleep)

with pytest.raises(asyncio.CancelledError):
await cleanup_results(fake_queue, ttl=1, interval=0)
Expand All @@ -39,7 +39,7 @@ class FakeQueue:
async def fake_sleep(interval):
raise asyncio.CancelledError

monkeypatch.setattr("indigoapi.cleanup.asyncio.sleep", fake_sleep)
monkeypatch.setattr("indigoapi.queue.cleanup.asyncio.sleep", fake_sleep)

with pytest.raises(asyncio.CancelledError):
await cleanup_results(fake_queue, ttl=60, interval=0)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_gaussian_fit.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from indigoapi.analyses.peak_fitting import gaussian, gaussian_fit
from indigoapi.client import AnalysisClient
from indigoapi.main import start_api
from indigoapi.server import start_api


def test_gaussian_fit_with_client():
Expand Down
8 changes: 4 additions & 4 deletions tests/test_loader.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import sys

from indigoapi.analyses.loader import (
from indigoapi.analysis_core.loader import (
clone_github_repo,
load_plugins,
load_plugins_from_dir,
)
from indigoapi.analyses.registry import ANALYSIS_REGISTRY, list_analyses
from indigoapi.analysis_core.registry import ANALYSIS_REGISTRY, list_analyses
from indigoapi.config import Config


Expand All @@ -28,7 +28,7 @@ def test_loader_load_plugins_from_dir(tmp_path):
def test_loader_load_plugins_registers_decorated_functions(tmp_path):
plugin_path = tmp_path / "custom_plugin.py"
plugin_path.write_text(
"from indigoapi.analyses.decorator import analysis\n"
"from indigoapi.analysis_core.decorator import analysis\n"
"@analysis()\n"
"def hello(name: str) -> str:\n"
" return f'hello {name}'\n"
Expand Down Expand Up @@ -71,5 +71,5 @@ def test_loader_load_plugins_handles_clone_error(monkeypatch):
def fake_clone(repo_url, dest_dir):
raise RuntimeError("unable to clone")

monkeypatch.setattr("indigoapi.analyses.loader.clone_github_repo", fake_clone)
monkeypatch.setattr("indigoapi.analysis_core.loader.clone_github_repo", fake_clone)
load_plugins(cfg)
12 changes: 7 additions & 5 deletions tests/test_loader_extra.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from unittest.mock import Mock

from indigoapi.analyses.loader import (
from indigoapi.analysis_core.loader import (
clone_github_repo,
get_async_function,
load_plugins,
load_plugins_from_dir,
)
from indigoapi.analyses.registry import list_analyses
from indigoapi.analysis_core.registry import list_analyses
from indigoapi.config import Config


Expand All @@ -20,7 +20,9 @@ async def coro():
def test_clone_github_repo_force(monkeypatch, tmp_path):
dest = tmp_path / "repo"
clone_from_mock = Mock()
monkeypatch.setattr("indigoapi.analyses.loader.Repo.clone_from", clone_from_mock)
monkeypatch.setattr(
"indigoapi.analysis_core.loader.Repo.clone_from", clone_from_mock
)
result = clone_github_repo(
"https://example.com/repo.git", str(tmp_path), force=True
)
Expand All @@ -46,7 +48,7 @@ def track_spec(name, location):
return real_spec(name, location)

monkeypatch.setattr(
"indigoapi.analyses.loader.importlib.util.spec_from_file_location",
"indigoapi.analysis_core.loader.importlib.util.spec_from_file_location",
track_spec,
)

Expand All @@ -68,7 +70,7 @@ def test_load_plugins_with_git_repo(monkeypatch, tmp_path):
fake_file.write_text("def hello():\n return 'hello'\n")

monkeypatch.setattr(
"indigoapi.analyses.loader.clone_github_repo", lambda url, dest: fake_path
"indigoapi.analysis_core.loader.clone_github_repo", lambda url, dest: fake_path
)
load_plugins(cfg, register_all=True)
assert "hello" in list_analyses() or True
2 changes: 1 addition & 1 deletion tests/test_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import pytest

from indigoapi.analyses.peak_fitting import gaussian
from indigoapi.analyses.registry import (
from indigoapi.analysis_core.registry import (
AnalysisNotFoundError,
get_analysis,
list_analyses,
Expand Down
6 changes: 3 additions & 3 deletions tests/test_queue_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from xrpd_toolbox.utils.messenger import Messenger

from indigoapi.models import AnalysisRequest
from indigoapi.queue_manager import QueueManager
from indigoapi.queue import QueueManager


async def wait_for_result(queue_manager, request_id, timeout=1.0):
Expand All @@ -26,7 +26,7 @@ async def fake_analysis(number):
return number * 2

monkeypatch.setattr(
"indigoapi.analyses.registry.get_analysis", lambda name: fake_analysis
"indigoapi.analysis_core.registry.get_analysis", lambda name: fake_analysis
)

job = AnalysisRequest(analysis_name="double", inputs={"number": 2})
Expand Down Expand Up @@ -60,7 +60,7 @@ def send_message(self, destination, message):
)

monkeypatch.setattr(
"indigoapi.analyses.registry.get_analysis",
"indigoapi.analysis_core.registry.get_analysis",
lambda name: (_ for _ in ()).throw(KeyError("missing")),
)

Expand Down
10 changes: 5 additions & 5 deletions tests/test_rabbitmq_listener.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
import pytest

from indigoapi.models import AnalysisRequest
from indigoapi.queue_manager import QueueManager
from indigoapi.rabbitmq_listener import _StompListener
from indigoapi.queue import QueueManager
from indigoapi.queue.rabbitmq import _StompListener


@pytest.mark.filterwarnings("ignore::ResourceWarning")
Expand All @@ -28,7 +28,7 @@ def fake_run_coro_threadsafe(coro, event_loop):
return None

monkeypatch.setattr(
"indigoapi.rabbitmq_listener.asyncio.run_coroutine_threadsafe",
"indigoapi.queue.rabbitmq.asyncio.run_coroutine_threadsafe",
fake_run_coro_threadsafe,
)

Expand All @@ -54,7 +54,7 @@ def test_stomp_listener_invalid_json(monkeypatch):
listener = _StompListener(queue_manager, loop) # type: ignore

monkeypatch.setattr(
"indigoapi.rabbitmq_listener.asyncio.run_coroutine_threadsafe",
"indigoapi.queue.rabbitmq.asyncio.run_coroutine_threadsafe",
lambda coro, event_loop: None,
)
frame = SimpleNamespace(body="not-a-json")
Expand Down Expand Up @@ -141,7 +141,7 @@ class BadFrame:
def fake_error(msg):
recorded.append(msg)

monkeypatch.setattr("indigoapi.rabbitmq_listener.logger.error", fake_error)
monkeypatch.setattr("indigoapi.queue.rabbitmq.logger.error", fake_error)
listener.on_message(BadFrame())

assert recorded
Loading
Loading