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
2 changes: 1 addition & 1 deletion examples/test_fire_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@


@register_scenario("fire_response")
def test_fire_response(fb_client: FlightBlenderClient, data_files: DataFiles) -> None:
async def test_fire_response(fb_client: FlightBlenderClient, data_files: DataFiles) -> None:
"""Runs the Fire Response scenario."""
pass
16 changes: 8 additions & 8 deletions src/openutm_verification/auth/oauth2.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,18 @@ def __init__(
self.token_url = token_url
self.client_id = client_id
self.client_secret = client_secret
self.client = httpx.Client(timeout=timeout)
self.client = httpx.AsyncClient(timeout=timeout)
self._token: Optional[OAuth2Token] = None

def get_access_token(self) -> str:
async def get_access_token(self) -> str:
"""Get valid access token, acquiring or refreshing as needed."""
if not self._token or self._token.is_expired():
self._acquire_token()
await self._acquire_token()
if not self._token:
raise OAuth2Error("Failed to acquire OAuth2 access token")
return self._token.access_token

def _acquire_token(self) -> None:
async def _acquire_token(self) -> None:
"""Acquire OAuth2 access token using client credentials flow."""
logger.debug("Acquiring new OAuth2 token...")
data = {
Expand All @@ -58,7 +58,7 @@ def _acquire_token(self) -> None:
"client_secret": self.client_secret,
}
try:
response = self.client.post(
response = await self.client.post(
self.token_url,
data=data,
headers={"Content-Type": "application/x-www-form-urlencoded"},
Expand All @@ -78,8 +78,8 @@ def _acquire_token(self) -> None:
logger.error(f"OAuth2 acquisition error: {e}")
raise OAuth2Error(f"Token acquisition failed: {e}") from e

def __enter__(self):
async def __aenter__(self):
return self

def __exit__(self, exc_type, exc_val, exc_tb):
self.client.close()
async def __aexit__(self, exc_type, exc_val, exc_tb):
await self.client.aclose()
3 changes: 2 additions & 1 deletion src/openutm_verification/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Command Line Interface for OpenUTM Verification Tool.
"""

import asyncio
import sys
from datetime import datetime, timezone
from pathlib import Path
Expand Down Expand Up @@ -49,7 +50,7 @@ def main():
log_file = setup_logging(output_dir, base_filename, config.reporting.formats, args.debug)

# Run verification scenarios
failed = run_verification_scenarios(config, args.config)
failed = asyncio.run(run_verification_scenarios(config, args.config))

if log_file:
from loguru import logger
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,13 @@ class AirTrafficClient(BaseAirTrafficAPIClient, BaseBlenderAPIClient):
"""Client for fetching live flight data from OpenSky Network and generating simulated air traffic data."""

def __init__(self, settings: AirTrafficSettings):
super().__init__(settings)
BaseAirTrafficAPIClient.__init__(self, settings)
# Initialize BaseBlenderAPIClient with dummy values since we don't use it for HTTP requests here
# but we inherit from it. Ideally, we should refactor to composition over inheritance.
BaseBlenderAPIClient.__init__(self, base_url="", credentials={})

@scenario_step("Generate Simulated Air Traffic Data")
def generate_simulated_air_traffic_data(
async def generate_simulated_air_traffic_data(
self,
config_path: Optional[str] = None,
duration: Optional[int] = None,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ class BaseAirTrafficAPIClient:
def __init__(self, settings: AirTrafficSettings):
self.settings = settings

def __enter__(self):
async def __aenter__(self):
return self

def __exit__(self, exc_type, exc_val, exc_tb):
async def __aexit__(self, exc_type, exc_val, exc_tb):
pass
28 changes: 14 additions & 14 deletions src/openutm_verification/core/clients/flight_blender/base_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class BaseBlenderAPIClient:

def __init__(self, base_url: str, credentials: dict, request_timeout: int = 10):
self.base_url = base_url
self.client = httpx.Client(timeout=request_timeout)
self.client = httpx.AsyncClient(timeout=request_timeout)
if credentials and "access_token" in credentials:
self.client.headers.update(
{
Expand All @@ -27,7 +27,7 @@ def __init__(self, base_url: str, credentials: dict, request_timeout: int = 10):
}
)

def _request(
async def _request(
self,
method: str,
endpoint: str,
Expand All @@ -36,7 +36,7 @@ def _request(
) -> httpx.Response:
url = f"{self.base_url}{endpoint}"
try:
response = self.client.request(method, url, json=json)
response = await self.client.request(method, url, json=json)
if not (silent_status and response.status_code in silent_status):
response.raise_for_status()
return response
Expand All @@ -47,23 +47,23 @@ def _request(
logger.error(f"Request error occurred: {e}")
raise FlightBlenderError("Request failed") from e

def get(self, endpoint: str, silent_status: list[int] | None = None) -> httpx.Response:
return self._request("GET", endpoint, silent_status=silent_status)
async def get(self, endpoint: str, silent_status: list[int] | None = None) -> httpx.Response:
return await self._request("GET", endpoint, silent_status=silent_status)

def post(self, endpoint: str, json: dict, silent_status: list[int] | None = None) -> httpx.Response:
return self._request("POST", endpoint, json=json, silent_status=silent_status)
async def post(self, endpoint: str, json: dict, silent_status: list[int] | None = None) -> httpx.Response:
return await self._request("POST", endpoint, json=json, silent_status=silent_status)

def put(self, endpoint: str, json: dict, silent_status: list[int] | None = None) -> httpx.Response:
return self._request("PUT", endpoint, json=json, silent_status=silent_status)
async def put(self, endpoint: str, json: dict, silent_status: list[int] | None = None) -> httpx.Response:
return await self._request("PUT", endpoint, json=json, silent_status=silent_status)

def delete(self, endpoint: str, silent_status: list[int] | None = None) -> httpx.Response:
return self._request("DELETE", endpoint, silent_status=silent_status)
async def delete(self, endpoint: str, silent_status: list[int] | None = None) -> httpx.Response:
return await self._request("DELETE", endpoint, silent_status=silent_status)

def __enter__(self):
async def __aenter__(self):
return self

def __exit__(self, exc_type, exc_val, exc_tb):
self.client.close()
async def __aexit__(self, exc_type, exc_val, exc_tb):
await self.client.aclose()

def create_websocket_connection(self, endpoint) -> Any:
"""Create and return a WebSocket connection to the Flight Blender service.
Expand Down
Loading