-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10 from lsst-ts/release/2.0.0
Release/2.0.0
- Loading branch information
Showing
143 changed files
with
23,366 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,4 +6,6 @@ virtualenv | |
*.cache | ||
.vscode | ||
**/__pycache__ | ||
**/.DS_Store | ||
**/.DS_Store | ||
**/*.log | ||
pytest_* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
FROM lsstts/develop-env:b65 | ||
FROM lsstts/develop-env:b101 | ||
|
||
WORKDIR /usr/src/love/ | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,65 @@ | ||
# LOVE-commander | ||
|
||
LOVE service to send SAL commands from http endpoints using salobj | ||
|
||
## Running tests | ||
|
||
Disabling plugins that may throw errors due to not having write access is recommended: | ||
|
||
## Running tests | ||
Disabling plugins that may throw errors due to not having write access is recommended: | ||
``` | ||
pytest -p no:cacheprovider -p no:pytest_session2file | ||
``` | ||
|
||
## 1. Use as part of the LOVE system | ||
|
||
In order to use the LOVE-commander as part of the LOVE system we recommend to use the docker-compose and configuration files provided in the [LOVE-integration-tools](https://github.com/lsst-ts/LOVE-integration-tools) repo. Please follow the instructions there. | ||
|
||
## 2. Local load for development | ||
|
||
We provide a docker image and a docker-compose file in order to load the LOVE-commander locally for development purposes, i.e. run tests and build documentation. | ||
|
||
This docker-compose does not copy the code into the image, but instead it mounts the repository inside the image, this way you can edit the code from outside the docker container with no need to rebuild or restart. | ||
|
||
### 2.1 Load and get into the docker image | ||
|
||
Follow these instructions to run the application in a docker container and get into it: | ||
|
||
1. Launch and get into the container: | ||
|
||
``` | ||
docker-compose up -d | ||
docker-exec commander bash | ||
``` | ||
|
||
2. Inside the container:, load the setup and got to love folder | ||
|
||
``` | ||
source .setup.sh | ||
cd /usr/src/love | ||
``` | ||
|
||
### 2.2 Run tests | ||
|
||
Once inside the container and in the `love` folder you can run the tests. Disabling plugins that may throw errors due to not having write access is recommended: | ||
|
||
``` | ||
pytest -p no:cacheprovider -p no:pytest_session2file | ||
``` | ||
|
||
You may filter tests with the `-k <filter-substring>` flag, where `<filter-substring>` can be a file or a test suite name. | ||
For example the following command: | ||
|
||
``` | ||
pytest -p no:cacheprovider -p no:pytest_session2file -k metadata | ||
``` | ||
|
||
will run the `test_metadata` test of the `test_salinfo.py` file. | ||
|
||
### 2.3 Build documentation | ||
|
||
Once inside the container and in the `love` folder you can build the documentation as follows: | ||
|
||
``` | ||
cd docsrc | ||
./create_docs.sh | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,27 @@ | ||
"""Main application, instantiates the aiohtttp app.""" | ||
import json | ||
from aiohttp import web | ||
from lsst.ts import salobj | ||
from .commands import create_app as create_cmd_app | ||
from .heartbeats import create_app as create_heartbeat_app | ||
from .salinfo import create_app as create_salinfo_app | ||
|
||
|
||
def create_app(*args, **kwargs): | ||
app = web.Application( | ||
middlewares=[web.normalize_path_middleware()]) | ||
async def create_app(*args, **kwargs): | ||
"""Create the aaplication with its subapplications | ||
app.add_subapp('/cmd/', create_cmd_app()) | ||
Returns | ||
------- | ||
object | ||
the application | ||
""" | ||
app = web.Application(middlewares=[web.normalize_path_middleware()]) | ||
|
||
app.add_subapp("/cmd/", create_cmd_app()) | ||
app.add_subapp("/heartbeat/", create_heartbeat_app()) | ||
app.add_subapp( | ||
"/salinfo/", | ||
await create_salinfo_app(remotes_len_limit=kwargs.get("remotes_len_limit")), | ||
) | ||
|
||
return app |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,47 +1,60 @@ | ||
"""Define the Commands subapplication, which provides the endpoints to accept command requests.""" | ||
from aiohttp import web | ||
from lsst.ts import salobj | ||
import json | ||
|
||
|
||
def create_app(): | ||
"""Create the Commands application | ||
Returns | ||
------- | ||
object | ||
The application instance | ||
""" | ||
remotes = {} | ||
|
||
cmd = web.Application() | ||
|
||
async def start_cmd(request): | ||
data = await request.json() | ||
try: | ||
assert 'csc' in data | ||
assert 'salindex' in data | ||
assert 'cmd' in data | ||
assert 'params' in data | ||
assert "csc" in data | ||
assert "salindex" in data | ||
assert "cmd" in data | ||
assert "params" in data | ||
except AssertionError: | ||
return web.json_response({"ack": f'Request must have JSON data with the following keys: csc, salindex, cmd_name, params. Received {json.dumps(data)}'}, status=400) | ||
return web.json_response( | ||
{ | ||
"ack": f"Request must have JSON data with the following keys: csc, salindex, cmd_name, params. Received {json.dumps(data)}" | ||
}, | ||
status=400, | ||
) | ||
|
||
csc = data["csc"] | ||
salindex = data["salindex"] | ||
cmd_name = data["cmd"] | ||
params = data["params"] | ||
remote_name = f"{csc}.{salindex}" | ||
if remote_name not in remotes: | ||
remotes[remote_name] = salobj.Remote( | ||
salobj.Domain(), csc, salindex) | ||
remotes[remote_name] = salobj.Remote(salobj.Domain(), csc, salindex) | ||
await remotes[remote_name].start_task | ||
|
||
cmd = getattr(remotes[remote_name], cmd_name) | ||
cmd.set(**params) | ||
|
||
try: | ||
cmd_result = await cmd.start(timeout=10) | ||
return web.json_response({'ack': cmd_result.result}) | ||
return web.json_response({"ack": cmd_result.result}) | ||
except salobj.AckTimeoutError: | ||
return web.json_response({"ack": "Command time out"}, status=504) | ||
|
||
cmd.router.add_post('/', start_cmd) | ||
cmd.router.add_post("/", start_cmd) | ||
|
||
async def on_cleanup(cmd): | ||
for remote_name in remotes: | ||
await remotes[remote_name].close() | ||
|
||
cmd.on_cleanup.append(on_cleanup) | ||
|
||
return cmd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
"""Define the Heartbeats subapplication, which provides the endpoints to request a heartbeat.""" | ||
from aiohttp import web | ||
import json | ||
from datetime import datetime | ||
|
||
|
||
def create_app(): | ||
"""Create the Heartbeats application | ||
Returns | ||
------- | ||
object | ||
The application instance | ||
""" | ||
remotes = {} | ||
|
||
heartbeat = web.Application() | ||
|
||
async def start_heartbeat(request): | ||
data = await request.read() | ||
now = datetime.now() | ||
timestamp = datetime.timestamp(now) | ||
return web.json_response({"timestamp": timestamp}) | ||
|
||
heartbeat.router.add_get("/", start_heartbeat) | ||
|
||
async def on_cleanup(heartbeat): | ||
for remote_name in remotes: | ||
await remotes[remote_name].close() | ||
|
||
heartbeat.on_cleanup.append(on_cleanup) | ||
|
||
return heartbeat |
Oops, something went wrong.