bluebird-api 0.1.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.
- bluebird_api-0.1.0/.gitignore +192 -0
- bluebird_api-0.1.0/PKG-INFO +37 -0
- bluebird_api-0.1.0/README.md +24 -0
- bluebird_api-0.1.0/bluebird_api/__init__.py +77 -0
- bluebird_api-0.1.0/bluebird_api/models.py +39 -0
- bluebird_api-0.1.0/bluebird_api/route_tags.py +23 -0
- bluebird_api-0.1.0/bluebird_api/routers/__init__.py +19 -0
- bluebird_api-0.1.0/bluebird_api/routers/core.py +295 -0
- bluebird_api-0.1.0/bluebird_api/routes.py +50 -0
- bluebird_api-0.1.0/bluebird_api/runner.py +27 -0
- bluebird_api-0.1.0/bluebird_api/runnerabc.py +148 -0
- bluebird_api-0.1.0/docs/index.md +58 -0
- bluebird_api-0.1.0/docs/source.md +11 -0
- bluebird_api-0.1.0/mkdocs.yml +11 -0
- bluebird_api-0.1.0/pyproject.toml +85 -0
- bluebird_api-0.1.0/tests/api/conftest.py +89 -0
- bluebird_api-0.1.0/tests/api/test_routes.py +535 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
downloads/
|
|
14
|
+
eggs/
|
|
15
|
+
.eggs/
|
|
16
|
+
lib/
|
|
17
|
+
lib64/
|
|
18
|
+
parts/
|
|
19
|
+
sdist/
|
|
20
|
+
var/
|
|
21
|
+
wheels/
|
|
22
|
+
share/python-wheels/
|
|
23
|
+
*.egg-info/
|
|
24
|
+
.installed.cfg
|
|
25
|
+
*.egg
|
|
26
|
+
MANIFEST
|
|
27
|
+
.python-version
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py,cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
# .python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
#Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# UV
|
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
100
|
+
# commonly ignored for libraries.
|
|
101
|
+
#uv.lock
|
|
102
|
+
|
|
103
|
+
# poetry
|
|
104
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
105
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
106
|
+
# commonly ignored for libraries.
|
|
107
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
108
|
+
#poetry.lock
|
|
109
|
+
|
|
110
|
+
# pdm
|
|
111
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
112
|
+
#pdm.lock
|
|
113
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
114
|
+
# in version control.
|
|
115
|
+
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
|
|
116
|
+
.pdm.toml
|
|
117
|
+
.pdm-python
|
|
118
|
+
.pdm-build/
|
|
119
|
+
|
|
120
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
121
|
+
__pypackages__/
|
|
122
|
+
|
|
123
|
+
# Celery stuff
|
|
124
|
+
celerybeat-schedule
|
|
125
|
+
celerybeat.pid
|
|
126
|
+
|
|
127
|
+
# SageMath parsed files
|
|
128
|
+
*.sage.py
|
|
129
|
+
|
|
130
|
+
# Environments
|
|
131
|
+
.env
|
|
132
|
+
.venv
|
|
133
|
+
env/
|
|
134
|
+
venv/
|
|
135
|
+
ENV/
|
|
136
|
+
env.bak/
|
|
137
|
+
venv.bak/
|
|
138
|
+
|
|
139
|
+
# Spyder project settings
|
|
140
|
+
.spyderproject
|
|
141
|
+
.spyproject
|
|
142
|
+
|
|
143
|
+
# Rope project settings
|
|
144
|
+
.ropeproject
|
|
145
|
+
|
|
146
|
+
# mkdocs documentation
|
|
147
|
+
/site
|
|
148
|
+
/docs/src/examples/**/*.ipynb
|
|
149
|
+
/docs/src/examples/**/*.gif
|
|
150
|
+
|
|
151
|
+
# mypy
|
|
152
|
+
.mypy_cache/
|
|
153
|
+
.dmypy.json
|
|
154
|
+
dmypy.json
|
|
155
|
+
|
|
156
|
+
# Pyre type checker
|
|
157
|
+
.pyre/
|
|
158
|
+
|
|
159
|
+
# pytype static type analyzer
|
|
160
|
+
.pytype/
|
|
161
|
+
|
|
162
|
+
# Cython debug symbols
|
|
163
|
+
cython_debug/
|
|
164
|
+
|
|
165
|
+
# PyCharm
|
|
166
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
167
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
168
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
169
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
170
|
+
.idea/
|
|
171
|
+
|
|
172
|
+
# Ruff stuff:
|
|
173
|
+
.ruff_cache/
|
|
174
|
+
|
|
175
|
+
# PyPI configuration file
|
|
176
|
+
.pypirc
|
|
177
|
+
|
|
178
|
+
# Vim temporary files
|
|
179
|
+
*.swp
|
|
180
|
+
*.swo
|
|
181
|
+
|
|
182
|
+
# VSCode config
|
|
183
|
+
.vscode/
|
|
184
|
+
|
|
185
|
+
# emacs autosave
|
|
186
|
+
*~
|
|
187
|
+
|
|
188
|
+
# BluebirdATC files
|
|
189
|
+
bluebird-dt/bluebird_dt/scenario_data/scenario_logs/*
|
|
190
|
+
|
|
191
|
+
# MacOS files
|
|
192
|
+
.DS_store
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bluebird-api
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A REST API for the Project Bluebird Digital Twin
|
|
5
|
+
Author: Project Bluebird
|
|
6
|
+
License-Expression: AGPL-3.0-or-later
|
|
7
|
+
Requires-Python: <3.15,>=3.10
|
|
8
|
+
Requires-Dist: bluebird-dt
|
|
9
|
+
Requires-Dist: fastapi<0.137,>=0.136.1
|
|
10
|
+
Requires-Dist: lxml-html-clean>=0.4.4
|
|
11
|
+
Requires-Dist: uvicorn<0.47,>=0.46.0
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
|
|
14
|
+
## The REST API for BluebirdATC
|
|
15
|
+
|
|
16
|
+
It is possible to run the BluebirdATC digital twin in a server process, such that the simulation will evolve at regular time intervals, and Agents and/or frontend visualization software can interact with it via HTTP requests.
|
|
17
|
+
In particular, users can:
|
|
18
|
+
* Query available scenario categories and scenarios.
|
|
19
|
+
* Load a selected scenario.
|
|
20
|
+
* Evolve the simulation by a specified time interval.
|
|
21
|
+
* Obtain the current state of the `Environment`.
|
|
22
|
+
* Submit `Actions` to individual aircraft.
|
|
23
|
+
* Save logfiles with data on all steps of the simulation.
|
|
24
|
+
|
|
25
|
+
In order to run the app, with all the correct dependencies for this feature, from the `BluebirdATC/bluebird-api` directory, run the command:
|
|
26
|
+
|
|
27
|
+
```shell
|
|
28
|
+
uv run uvicorn bluebird_api:app --port 8000
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
You should then be able to go to [http://localhost:8000](http://localhost:8000) in a web browser, and see the message "Hello, BluebirdATC!".
|
|
32
|
+
|
|
33
|
+
To see the full list and description of API endpoints, with the application running, go to [http://localhost:8000/docs](http://localhost:8000/docs).
|
|
34
|
+
|
|
35
|
+
## Frontend visualisation
|
|
36
|
+
|
|
37
|
+
The app also serves the frontend visualization (more details on that can be found [here](../bluebird-hmi/README.md)), at the URL [http://localhost:8000/hmi](http://localhost:8000/hmi).
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
## The REST API for BluebirdATC
|
|
2
|
+
|
|
3
|
+
It is possible to run the BluebirdATC digital twin in a server process, such that the simulation will evolve at regular time intervals, and Agents and/or frontend visualization software can interact with it via HTTP requests.
|
|
4
|
+
In particular, users can:
|
|
5
|
+
* Query available scenario categories and scenarios.
|
|
6
|
+
* Load a selected scenario.
|
|
7
|
+
* Evolve the simulation by a specified time interval.
|
|
8
|
+
* Obtain the current state of the `Environment`.
|
|
9
|
+
* Submit `Actions` to individual aircraft.
|
|
10
|
+
* Save logfiles with data on all steps of the simulation.
|
|
11
|
+
|
|
12
|
+
In order to run the app, with all the correct dependencies for this feature, from the `BluebirdATC/bluebird-api` directory, run the command:
|
|
13
|
+
|
|
14
|
+
```shell
|
|
15
|
+
uv run uvicorn bluebird_api:app --port 8000
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
You should then be able to go to [http://localhost:8000](http://localhost:8000) in a web browser, and see the message "Hello, BluebirdATC!".
|
|
19
|
+
|
|
20
|
+
To see the full list and description of API endpoints, with the application running, go to [http://localhost:8000/docs](http://localhost:8000/docs).
|
|
21
|
+
|
|
22
|
+
## Frontend visualisation
|
|
23
|
+
|
|
24
|
+
The app also serves the frontend visualization (more details on that can be found [here](../bluebird-hmi/README.md)), at the URL [http://localhost:8000/hmi](http://localhost:8000/hmi).
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
import re
|
|
4
|
+
from collections.abc import Awaitable, Callable
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from bluebird_dt import logger
|
|
8
|
+
from fastapi import FastAPI, Request, Response
|
|
9
|
+
from fastapi.middleware.cors import CORSMiddleware
|
|
10
|
+
from fastapi.middleware.gzip import GZipMiddleware
|
|
11
|
+
from fastapi.routing import APIRoute
|
|
12
|
+
from fastapi.staticfiles import StaticFiles
|
|
13
|
+
|
|
14
|
+
from .route_tags import tags_metadata
|
|
15
|
+
from .routes import router
|
|
16
|
+
|
|
17
|
+
bluebird_logger = logging.getLogger("bluebird_dt")
|
|
18
|
+
bluebird_logger.setLevel(logging.DEBUG)
|
|
19
|
+
stream_handler = logging.StreamHandler()
|
|
20
|
+
stream_handler.setFormatter(logger.CustomFormatter())
|
|
21
|
+
bluebird_logger.addHandler(stream_handler)
|
|
22
|
+
|
|
23
|
+
app = FastAPI(
|
|
24
|
+
title="BluebirdATC: AI for air traffic control",
|
|
25
|
+
description="FastAPI interface to control the simulation framework BluebirdATC.",
|
|
26
|
+
license_info={
|
|
27
|
+
"name": "License",
|
|
28
|
+
"url": "https://github.com/project-bluebird/BluebirdATC/blob/dev/LICENSE",
|
|
29
|
+
},
|
|
30
|
+
openapi_tags=tags_metadata,
|
|
31
|
+
strict_content_type=False,
|
|
32
|
+
)
|
|
33
|
+
app.include_router(router)
|
|
34
|
+
app.add_middleware(
|
|
35
|
+
CORSMiddleware,
|
|
36
|
+
allow_origins=["*"],
|
|
37
|
+
allow_credentials=True,
|
|
38
|
+
allow_methods=["*"],
|
|
39
|
+
allow_headers=["*"],
|
|
40
|
+
)
|
|
41
|
+
app.add_middleware(GZipMiddleware, minimum_size=500)
|
|
42
|
+
|
|
43
|
+
# serve the frontend
|
|
44
|
+
repo_root = Path(__file__).resolve().parents[2]
|
|
45
|
+
dist_path = repo_root / "bluebird-hmi" / "dist"
|
|
46
|
+
|
|
47
|
+
if dist_path.is_dir():
|
|
48
|
+
app.mount("/hmi", StaticFiles(directory=str(dist_path), html=True), name="frontend")
|
|
49
|
+
app.mount("/hmi/assets", StaticFiles(directory=os.path.join(dist_path, "assets")), name="assets")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
# For webapp, requests will be prepended with "/api" - strip that out here
|
|
53
|
+
@app.middleware("http")
|
|
54
|
+
async def strip_api_prefix(request: Request, call_next: Callable[[Request], Awaitable[Response]]) -> Response:
|
|
55
|
+
path = request.url.path
|
|
56
|
+
if path.startswith("/api"):
|
|
57
|
+
newpath = re.sub("/api", "", path)
|
|
58
|
+
request.scope["path"] = newpath
|
|
59
|
+
return await call_next(request)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def use_route_names_as_operation_ids(app: FastAPI) -> None:
|
|
63
|
+
"""
|
|
64
|
+
Simplify operation IDs so that generated API clients have simpler function
|
|
65
|
+
names.
|
|
66
|
+
|
|
67
|
+
Must be called after all routes have been added.
|
|
68
|
+
"""
|
|
69
|
+
for route in app.routes:
|
|
70
|
+
if isinstance(route, APIRoute):
|
|
71
|
+
route.operation_id = route.name
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
use_route_names_as_operation_ids(app)
|
|
75
|
+
|
|
76
|
+
# keep track of current simulation instance
|
|
77
|
+
# app.state.current_runner = None
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
from bluebird_dt.utility.supported_actions import SUPPORTED_ACTIONS
|
|
4
|
+
from pydantic import BaseModel, Field
|
|
5
|
+
|
|
6
|
+
from bluebird_api.runnerabc import RunnerABC
|
|
7
|
+
|
|
8
|
+
SUPPORTED_ACTIONS_LIST = [action for actions in SUPPORTED_ACTIONS.values() for action in actions]
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class RunnerStore:
|
|
12
|
+
current_runner: RunnerABC = None
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ActionInput(BaseModel):
|
|
16
|
+
"""An action to be sent to the simulator."""
|
|
17
|
+
|
|
18
|
+
agent: str = Field(
|
|
19
|
+
description="The agent performing the action.",
|
|
20
|
+
json_schema_extra={"example": "atc_1"},
|
|
21
|
+
)
|
|
22
|
+
callsign: str = Field(
|
|
23
|
+
description="The callsign of the flight being acted on.",
|
|
24
|
+
json_schema_extra={"example": "AIR123"},
|
|
25
|
+
)
|
|
26
|
+
kind: typing.Literal[tuple(SUPPORTED_ACTIONS_LIST)] = Field(
|
|
27
|
+
description="The kind of action to perform. Must be a string that is one of the supported actions.",
|
|
28
|
+
json_schema_extra={"example": "change_heading_to"},
|
|
29
|
+
)
|
|
30
|
+
value: typing.Any = Field(
|
|
31
|
+
description=(
|
|
32
|
+
"The value associated with the action. The type of this value depends on the action being performed."
|
|
33
|
+
),
|
|
34
|
+
json_schema_extra={"example": 90},
|
|
35
|
+
)
|
|
36
|
+
sector: str = Field(
|
|
37
|
+
description="The sector that the action is being performed in.",
|
|
38
|
+
json_schema_extra={"example": "sector_1"},
|
|
39
|
+
)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# FastAPI metadata tags for use in Swagger autodocs.
|
|
2
|
+
tags_metadata = [
|
|
3
|
+
{
|
|
4
|
+
"name": "Control",
|
|
5
|
+
"description": "High level control of BluebirdATC.",
|
|
6
|
+
},
|
|
7
|
+
{
|
|
8
|
+
"name": "Scenarios",
|
|
9
|
+
"description": "Routes to get information about scenarios.",
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"name": "Evolve",
|
|
13
|
+
"description": "Routes to start, stop and evolve the simulation.",
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"name": "State",
|
|
17
|
+
"description": "Routes to get the state of the simulation.",
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"name": "Submit",
|
|
21
|
+
"description": "Routes to submit actions, plans and more to the simulation.",
|
|
22
|
+
},
|
|
23
|
+
]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module contains all the routers for the different features available in BluebirdATC. Note that, unlike in compiled
|
|
3
|
+
programming languages where disabled features are not included in the machine code, not including certain routers just
|
|
4
|
+
means that the endpoint is not available but the logic will continue to be available in BluebirdATC,
|
|
5
|
+
and therefore logged.
|
|
6
|
+
|
|
7
|
+
All the following routers are independent on the implementation of the storage of the runners and get this through the
|
|
8
|
+
fastapi dependency. See the respective documentation in ../runnerabc.py.
|
|
9
|
+
|
|
10
|
+
Note the endpoint for loading a run, that the HMI and most clients expect, is not included here as they are dependent on
|
|
11
|
+
the implementation of the store, which is dependent on the use case. An example of this endpoint, and any other
|
|
12
|
+
endpoints not included within the groups defined here are available in ../routes.py
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from .core import core_router
|
|
16
|
+
|
|
17
|
+
__all__ = [
|
|
18
|
+
"core_router",
|
|
19
|
+
]
|