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
14 changes: 0 additions & 14 deletions docs/development/socketio_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,6 @@ Response:
- `"2.0.0"`
- `"2.0.0b2`

### Get Pinpoint ID

| Event | Input | Response |
|-------------------|-------|----------|
| `get_pinpoint_id` | None | `string` |

Proxy connection ID (first 8 characters of a UUID v4).

__Example:__

Input: None

Response: `"81f8de08"`

### Get Platform Info

| Event | Input | Return |
Expand Down
10 changes: 0 additions & 10 deletions docs/usage/experiment_automation.md

This file was deleted.

1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,5 +107,6 @@ nav:
- development/index.md
- development/socketio_api.md
- development/adding_a_manipulator.md
- development/jackhammer_mode.md
- development/code_organization.md
- Source Code Reference: reference/
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ dependencies = [
"packaging==25.0",
"platformdirs==4.5.1",
"pyserial==3.5",
"python-socketio[asyncio_client]==5.15.1",
"python-socketio==5.15.1",
"requests==2.32.5",
"sensapex==1.504.1",
"rich==14.2.0",
"vbl-aquarium==1.1.0"
"vbl-aquarium==1.2.0"
]

[project.urls]
Expand Down
54 changes: 11 additions & 43 deletions src/ephys_link/back_end/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,20 @@
```
"""

from asyncio import new_event_loop, run
from asyncio import new_event_loop
from collections.abc import Callable, Coroutine
from json import JSONDecodeError, dumps, loads
from typing import Any, TypeVar, final
from uuid import uuid4

from aiohttp.web import Application, run_app
from pydantic import ValidationError
from socketio import AsyncClient, AsyncServer # pyright: ignore [reportMissingTypeStubs]
from socketio import AsyncServer # pyright: ignore [reportMissingTypeStubs]
from vbl_aquarium.models.ephys_link import (
EphysLinkOptions,
SetDepthRequest,
SetInsideBrainRequest,
SetPositionRequest,
)
from vbl_aquarium.models.proxy import PinpointIdResponse
from vbl_aquarium.utils.vbl_base_model import VBLBaseModel

from ephys_link.__about__ import __version__
Expand All @@ -36,8 +34,6 @@
from ephys_link.utils.constants import (
MALFORMED_REQUEST_ERROR,
PORT,
PROXY_CLIENT_NOT_INITIALIZED_ERROR,
SERVER_NOT_INITIALIZED_ERROR,
UNKNOWN_EVENT_ERROR,
cannot_connect_as_client_is_already_connected_error,
client_disconnected_without_being_connected_error,
Expand All @@ -64,35 +60,24 @@ def __init__(self, options: EphysLinkOptions, platform_handler: PlatformHandler,
self._platform_handler = platform_handler
self._console = console

# Initialize based on proxy usage.
self._sio: AsyncServer | AsyncClient = AsyncClient() if self._options.use_proxy else AsyncServer()
if not self._options.use_proxy:
# Exit if _sio is not a Server.
if not isinstance(self._sio, AsyncServer):
self._console.critical_print(SERVER_NOT_INITIALIZED_ERROR)
raise TypeError(SERVER_NOT_INITIALIZED_ERROR)
# Initialize server.
self._sio: AsyncServer = AsyncServer()

self._app = Application()
self._sio.attach(self._app) # pyright: ignore [reportUnknownMemberType]
self._app = Application()
self._sio.attach(self._app) # pyright: ignore [reportUnknownMemberType]

# Bind connection events.
_ = self._sio.on("connect", self.connect) # pyright: ignore [reportUnknownMemberType, reportUnknownVariableType]
_ = self._sio.on("disconnect", self.disconnect) # pyright: ignore [reportUnknownMemberType, reportUnknownVariableType]
# Bind connection events.
_ = self._sio.on("connect", self.connect) # pyright: ignore [reportUnknownMemberType, reportUnknownVariableType]
_ = self._sio.on("disconnect", self.disconnect) # pyright: ignore [reportUnknownMemberType, reportUnknownVariableType]

# Store connected client.
self._client_sid: str = ""

# Generate Pinpoint ID for proxy usage.
self._pinpoint_id = str(uuid4())[:8]

# Bind events.
_ = self._sio.on("*", self.platform_event_handler) # pyright: ignore [reportUnknownMemberType, reportUnknownVariableType]

def launch(self) -> None:
"""Launch the server.

Based on the options, either connect to a proxy or launch the server locally.
"""
"""Launch the server."""

# List platform and available manipulators.
self._console.info_print("PLATFORM", self._platform_handler.get_display_name())
Expand All @@ -108,22 +93,7 @@ def launch(self) -> None:
loop.close()

# Launch server
if self._options.use_proxy:
self._console.info_print("PINPOINT ID", self._pinpoint_id)

async def connect_proxy() -> None:
# Exit if _sio is not a proxy client.
if not isinstance(self._sio, AsyncClient):
self._console.critical_print(PROXY_CLIENT_NOT_INITIALIZED_ERROR)
raise TypeError(PROXY_CLIENT_NOT_INITIALIZED_ERROR)

# noinspection HttpUrlsUsage
await self._sio.connect(f"http://{self._options.proxy_address}:{PORT}") # pyright: ignore [reportUnknownMemberType]
await self._sio.wait()

run(connect_proxy())
else:
run_app(self._app, port=PORT)
run_app(self._app, port=PORT)

# Helper functions.
def _malformed_request_response(self, request: str, data: tuple[tuple[Any], ...]) -> str: # pyright: ignore [reportExplicitAny]
Expand Down Expand Up @@ -250,8 +220,6 @@ async def platform_event_handler(self, event: str, _: str, data: Any) -> str: #
# Server metadata.
case "get_version":
return __version__
case "get_pinpoint_id":
return PinpointIdResponse(pinpoint_id=self._pinpoint_id, is_requester=False).to_json_string()
case "get_platform_info":
return (await self._platform_handler.get_platform_info()).to_json_string()

Expand Down
15 changes: 0 additions & 15 deletions src/ephys_link/front_end/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,6 @@ def __init__(self) -> None:
action="store_true",
help="Enable debug mode.",
)
_ = self._parser.add_argument(
"-p",
"--use-proxy",
dest="use_proxy",
action="store_true",
help="Enable proxy mode.",
)
_ = self._parser.add_argument(
"-a",
"--proxy-address",
type=str,
default="proxy2.virtualbrainlab.org",
dest="proxy_address",
help="Proxy IP address.",
)
_ = self._parser.add_argument(
"--mpm-port",
type=int,
Expand Down
29 changes: 4 additions & 25 deletions src/ephys_link/front_end/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ def __init__(self) -> None:
self._ignore_updates = BooleanVar(value=options.ignore_updates)
self._type = StringVar(value=options.type)
self._debug = BooleanVar(value=options.debug)
self._use_proxy = BooleanVar(value=options.use_proxy)
self._proxy_address = StringVar(value=options.proxy_address)
self._mpm_port = IntVar(value=options.mpm_port)
self._serial = StringVar(value=options.serial)

Expand All @@ -80,8 +78,6 @@ def get_options(self) -> EphysLinkOptions:
ignore_updates=self._ignore_updates.get(),
type=self._type.get(),
debug=self._debug.get(),
use_proxy=self._use_proxy.get(),
proxy_address=self._proxy_address.get(),
mpm_port=self._mpm_port.get(),
serial=self._serial.get(),
)
Expand Down Expand Up @@ -115,40 +111,23 @@ def _build_gui(self) -> None:
ttk.Label(server_serving_settings, text="Local IP:", anchor=E, justify=RIGHT).grid(column=0, row=0, sticky="we")
ttk.Label(server_serving_settings, text=gethostbyname(gethostname())).grid(column=1, row=0, sticky="we")

# Proxy.
ttk.Label(server_serving_settings, text="Use Proxy:", anchor=E, justify=RIGHT).grid(
column=0, row=1, sticky="we"
)
ttk.Checkbutton(
server_serving_settings,
variable=self._use_proxy,
).grid(column=1, row=1, sticky="we")

# Proxy address.
ttk.Label(server_serving_settings, text="Proxy Address:", anchor=E, justify=RIGHT).grid(
column=0, row=2, sticky="we"
)
ttk.Entry(server_serving_settings, textvariable=self._proxy_address, justify=CENTER).grid(
column=1, row=2, sticky="we"
)

# Ignore updates.
ttk.Label(server_serving_settings, text="Ignore Updates:", anchor=E, justify=RIGHT).grid(
column=0, row=4, sticky="we"
column=0, row=1, sticky="we"
)
ttk.Checkbutton(
server_serving_settings,
variable=self._ignore_updates,
).grid(column=1, row=4, sticky="we")
).grid(column=1, row=1, sticky="we")

# Debug mode.
ttk.Label(server_serving_settings, text="Debug mode:", anchor=E, justify=RIGHT).grid(
column=0, row=5, sticky="we"
column=0, row=2, sticky="we"
)
ttk.Checkbutton(
server_serving_settings,
variable=self._debug,
).grid(column=1, row=5, sticky="we")
).grid(column=1, row=2, sticky="we")

# ---

Expand Down
3 changes: 0 additions & 3 deletions src/ephys_link/utils/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,6 @@ def did_not_reach_target_depth_error(request: SetDepthRequest, final_unified_dep

EMERGENCY_STOP_MESSAGE = "Emergency Stopping All Manipulators..."

SERVER_NOT_INITIALIZED_ERROR = "Server not initialized."
PROXY_CLIENT_NOT_INITIALIZED_ERROR = "Proxy client not initialized."


def cannot_connect_as_client_is_already_connected_error(new_client_sid: str, current_client_sid: str) -> str:
"""Generate an error message for when the client is already connected.
Expand Down
Loading