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.
@@ -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
+ ]