From 3f8616fbf17746d0378c3417830e08bcf2d91352 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Thu, 2 Jan 2025 06:20:33 +0400 Subject: [PATCH 01/12] Add src/ directory and move airbrakes/ there --- pyproject.toml | 4 ++-- {airbrakes => src/airbrakes}/__init__.py | 0 {airbrakes => src/airbrakes}/airbrakes.py | 0 {airbrakes => src/airbrakes}/data_handling/__init__.py | 0 .../airbrakes}/data_handling/apogee_predictor.py | 0 {airbrakes => src/airbrakes}/data_handling/data_processor.py | 0 {airbrakes => src/airbrakes}/data_handling/imu_data_packet.py | 0 .../airbrakes}/data_handling/logged_data_packet.py | 0 {airbrakes => src/airbrakes}/data_handling/logger.py | 0 .../airbrakes}/data_handling/processed_data_packet.py | 0 {airbrakes => src/airbrakes}/hardware/__init__.py | 0 {airbrakes => src/airbrakes}/hardware/imu.py | 0 {airbrakes => src/airbrakes}/hardware/servo.py | 0 {airbrakes => src/airbrakes}/mock/__init__.py | 0 {airbrakes => src/airbrakes}/mock/display.py | 0 {airbrakes => src/airbrakes}/mock/mock_imu.py | 0 {airbrakes => src/airbrakes}/mock/mock_logger.py | 0 {airbrakes => src/airbrakes}/state.py | 0 18 files changed, 2 insertions(+), 2 deletions(-) rename {airbrakes => src/airbrakes}/__init__.py (100%) rename {airbrakes => src/airbrakes}/airbrakes.py (100%) rename {airbrakes => src/airbrakes}/data_handling/__init__.py (100%) rename {airbrakes => src/airbrakes}/data_handling/apogee_predictor.py (100%) rename {airbrakes => src/airbrakes}/data_handling/data_processor.py (100%) rename {airbrakes => src/airbrakes}/data_handling/imu_data_packet.py (100%) rename {airbrakes => src/airbrakes}/data_handling/logged_data_packet.py (100%) rename {airbrakes => src/airbrakes}/data_handling/logger.py (100%) rename {airbrakes => src/airbrakes}/data_handling/processed_data_packet.py (100%) rename {airbrakes => src/airbrakes}/hardware/__init__.py (100%) rename {airbrakes => src/airbrakes}/hardware/imu.py (100%) rename {airbrakes => src/airbrakes}/hardware/servo.py (100%) rename {airbrakes => src/airbrakes}/mock/__init__.py (100%) rename {airbrakes => src/airbrakes}/mock/display.py (100%) rename {airbrakes => src/airbrakes}/mock/mock_imu.py (100%) rename {airbrakes => src/airbrakes}/mock/mock_logger.py (100%) rename {airbrakes => src/airbrakes}/state.py (100%) diff --git a/pyproject.toml b/pyproject.toml index bd1095fb..70218aec 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,7 +45,7 @@ select = ["E", "F", "I", "PL", "UP", "RUF", "PTH", "C4", "B", "PIE", "SIM", "RET [tool.ruff.lint.per-file-ignores] "main.py" = ["T201"] -"airbrakes/mock/display.py" = ["T201"] +"src/airbrakes/mock/display.py" = ["T201"] "tests/*.py" = ["T20", "S101", "D100", "ARG001", "RUF012"] [tool.pytest.ini_options] @@ -61,7 +61,7 @@ source = ["airbrakes"] omit = [ "*/tests/*", "*/site-packages/*", - "airbrakes/mock/*" + "src/airbrakes/mock/*" ] [tool.coverage.report] diff --git a/airbrakes/__init__.py b/src/airbrakes/__init__.py similarity index 100% rename from airbrakes/__init__.py rename to src/airbrakes/__init__.py diff --git a/airbrakes/airbrakes.py b/src/airbrakes/airbrakes.py similarity index 100% rename from airbrakes/airbrakes.py rename to src/airbrakes/airbrakes.py diff --git a/airbrakes/data_handling/__init__.py b/src/airbrakes/data_handling/__init__.py similarity index 100% rename from airbrakes/data_handling/__init__.py rename to src/airbrakes/data_handling/__init__.py diff --git a/airbrakes/data_handling/apogee_predictor.py b/src/airbrakes/data_handling/apogee_predictor.py similarity index 100% rename from airbrakes/data_handling/apogee_predictor.py rename to src/airbrakes/data_handling/apogee_predictor.py diff --git a/airbrakes/data_handling/data_processor.py b/src/airbrakes/data_handling/data_processor.py similarity index 100% rename from airbrakes/data_handling/data_processor.py rename to src/airbrakes/data_handling/data_processor.py diff --git a/airbrakes/data_handling/imu_data_packet.py b/src/airbrakes/data_handling/imu_data_packet.py similarity index 100% rename from airbrakes/data_handling/imu_data_packet.py rename to src/airbrakes/data_handling/imu_data_packet.py diff --git a/airbrakes/data_handling/logged_data_packet.py b/src/airbrakes/data_handling/logged_data_packet.py similarity index 100% rename from airbrakes/data_handling/logged_data_packet.py rename to src/airbrakes/data_handling/logged_data_packet.py diff --git a/airbrakes/data_handling/logger.py b/src/airbrakes/data_handling/logger.py similarity index 100% rename from airbrakes/data_handling/logger.py rename to src/airbrakes/data_handling/logger.py diff --git a/airbrakes/data_handling/processed_data_packet.py b/src/airbrakes/data_handling/processed_data_packet.py similarity index 100% rename from airbrakes/data_handling/processed_data_packet.py rename to src/airbrakes/data_handling/processed_data_packet.py diff --git a/airbrakes/hardware/__init__.py b/src/airbrakes/hardware/__init__.py similarity index 100% rename from airbrakes/hardware/__init__.py rename to src/airbrakes/hardware/__init__.py diff --git a/airbrakes/hardware/imu.py b/src/airbrakes/hardware/imu.py similarity index 100% rename from airbrakes/hardware/imu.py rename to src/airbrakes/hardware/imu.py diff --git a/airbrakes/hardware/servo.py b/src/airbrakes/hardware/servo.py similarity index 100% rename from airbrakes/hardware/servo.py rename to src/airbrakes/hardware/servo.py diff --git a/airbrakes/mock/__init__.py b/src/airbrakes/mock/__init__.py similarity index 100% rename from airbrakes/mock/__init__.py rename to src/airbrakes/mock/__init__.py diff --git a/airbrakes/mock/display.py b/src/airbrakes/mock/display.py similarity index 100% rename from airbrakes/mock/display.py rename to src/airbrakes/mock/display.py diff --git a/airbrakes/mock/mock_imu.py b/src/airbrakes/mock/mock_imu.py similarity index 100% rename from airbrakes/mock/mock_imu.py rename to src/airbrakes/mock/mock_imu.py diff --git a/airbrakes/mock/mock_logger.py b/src/airbrakes/mock/mock_logger.py similarity index 100% rename from airbrakes/mock/mock_logger.py rename to src/airbrakes/mock/mock_logger.py diff --git a/airbrakes/state.py b/src/airbrakes/state.py similarity index 100% rename from airbrakes/state.py rename to src/airbrakes/state.py From e1e39e1d4057e4203c0b83ca1c46176edf192201 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Thu, 2 Jan 2025 09:38:52 +0400 Subject: [PATCH 02/12] Move constants, utils, main to airbrakes package Also add ability to run with uvx --- pyproject.toml | 12 ++- scripts/run_imu.py | 2 +- scripts/run_logger.py | 2 +- scripts/run_servo.py | 2 +- src/airbrakes/airbrakes.py | 2 +- constants.py => src/airbrakes/constants.py | 0 .../data_handling/apogee_predictor.py | 6 +- src/airbrakes/data_handling/data_processor.py | 7 +- src/airbrakes/data_handling/logger.py | 10 +-- src/airbrakes/hardware/imu.py | 12 +-- src/airbrakes/hardware/servo.py | 2 +- main.py => src/airbrakes/main.py | 82 ++++++++++--------- src/airbrakes/mock/display.py | 2 +- src/airbrakes/mock/mock_imu.py | 16 ++-- src/airbrakes/state.py | 4 +- utils.py => src/airbrakes/utils.py | 0 tests/conftest.py | 12 +-- tests/test_airbrakes.py | 2 +- tests/test_apogee_predictor.py | 2 +- tests/test_imu.py | 2 +- tests/test_integration.py | 4 +- tests/test_logger.py | 2 +- tests/test_servo.py | 2 +- tests/test_state.py | 16 ++-- tests/test_utils.py | 2 +- 25 files changed, 112 insertions(+), 93 deletions(-) rename constants.py => src/airbrakes/constants.py (100%) rename main.py => src/airbrakes/main.py (71%) rename utils.py => src/airbrakes/utils.py (100%) diff --git a/pyproject.toml b/pyproject.toml index 70218aec..03410eab 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,9 +25,17 @@ dev = [ "pre-commit", ] -[tool.setuptools] -packages = ["airbrakes"] +[project.scripts] +mock = "airbrakes.main:run_mock_flight" +real = "airbrakes.main:run_real_flight" +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +# HATCH: +[tool.hatch.build.targets.wheel] +packages = ["src/airbrakes"] # RUFF: [tool.ruff] diff --git a/scripts/run_imu.py b/scripts/run_imu.py index 19598bcf..04ff5c75 100644 --- a/scripts/run_imu.py +++ b/scripts/run_imu.py @@ -4,7 +4,7 @@ For the pi, you will have to use python3 """ -from constants import IMU_PORT +from airbrakes.constants import IMU_PORT from airbrakes.hardware.imu import IMU diff --git a/scripts/run_logger.py b/scripts/run_logger.py index 49f79fd3..ab26c957 100644 --- a/scripts/run_logger.py +++ b/scripts/run_logger.py @@ -4,7 +4,7 @@ from collections import deque from airbrakes.data_handling.data_processor import IMUDataProcessor -from constants import TEST_LOGS_PATH +from airbrakes.constants import TEST_LOGS_PATH from airbrakes.data_handling.imu_data_packet import RawDataPacket from airbrakes.data_handling.logger import Logger diff --git a/scripts/run_servo.py b/scripts/run_servo.py index a528668a..2f94a5cb 100644 --- a/scripts/run_servo.py +++ b/scripts/run_servo.py @@ -4,7 +4,7 @@ For the pi, you will have to use python3 """ -from constants import ServoExtension, SERVO_PIN +from airbrakes.constants import ServoExtension, SERVO_PIN from airbrakes.hardware.servo import Servo servo = Servo(SERVO_PIN) diff --git a/src/airbrakes/airbrakes.py b/src/airbrakes/airbrakes.py index 45084c6a..dbcc47fd 100644 --- a/src/airbrakes/airbrakes.py +++ b/src/airbrakes/airbrakes.py @@ -3,6 +3,7 @@ from collections import deque from typing import TYPE_CHECKING +from airbrakes.constants import ServoExtension from airbrakes.data_handling.apogee_predictor import ApogeePredictor from airbrakes.data_handling.data_processor import IMUDataProcessor from airbrakes.data_handling.imu_data_packet import EstimatedDataPacket @@ -10,7 +11,6 @@ from airbrakes.hardware.imu import IMU from airbrakes.hardware.servo import Servo from airbrakes.state import StandbyState, State -from constants import ServoExtension if TYPE_CHECKING: from airbrakes.data_handling.processed_data_packet import ProcessedDataPacket diff --git a/constants.py b/src/airbrakes/constants.py similarity index 100% rename from constants.py rename to src/airbrakes/constants.py diff --git a/src/airbrakes/data_handling/apogee_predictor.py b/src/airbrakes/data_handling/apogee_predictor.py index 08689dc1..cd4e345e 100644 --- a/src/airbrakes/data_handling/apogee_predictor.py +++ b/src/airbrakes/data_handling/apogee_predictor.py @@ -16,8 +16,7 @@ from scipy.optimize import curve_fit -from airbrakes.data_handling.processed_data_packet import ProcessedDataPacket -from constants import ( +from airbrakes.constants import ( APOGEE_PREDICTION_MIN_PACKETS, BUFFER_SIZE_IN_BYTES, CURVE_FIT_INITIAL, @@ -28,7 +27,8 @@ STOP_SIGNAL, UNCERTAINTY_THRESHOLD, ) -from utils import modify_multiprocessing_queue_windows +from airbrakes.data_handling.processed_data_packet import ProcessedDataPacket +from airbrakes.utils import modify_multiprocessing_queue_windows PREDICTED_COAST_TIMESTAMPS = np.arange(0, FLIGHT_LENGTH_SECONDS, INTEGRATION_TIME_STEP_SECONDS) diff --git a/src/airbrakes/data_handling/data_processor.py b/src/airbrakes/data_handling/data_processor.py index 1a9b219e..3d0d1b49 100644 --- a/src/airbrakes/data_handling/data_processor.py +++ b/src/airbrakes/data_handling/data_processor.py @@ -4,10 +4,13 @@ import numpy.typing as npt from scipy.spatial.transform import Rotation as R +from airbrakes.constants import ( + ACCEL_DEADBAND_METERS_PER_SECOND_SQUARED, + GRAVITY_METERS_PER_SECOND_SQUARED, +) from airbrakes.data_handling.imu_data_packet import EstimatedDataPacket from airbrakes.data_handling.processed_data_packet import ProcessedDataPacket -from constants import ACCEL_DEADBAND_METERS_PER_SECOND_SQUARED, GRAVITY_METERS_PER_SECOND_SQUARED -from utils import deadband +from airbrakes.utils import deadband class IMUDataProcessor: diff --git a/src/airbrakes/data_handling/logger.py b/src/airbrakes/data_handling/logger.py index 42510825..3b72f5fe 100644 --- a/src/airbrakes/data_handling/logger.py +++ b/src/airbrakes/data_handling/logger.py @@ -8,23 +8,23 @@ from pathlib import Path from typing import Any, Literal -from utils import modify_multiprocessing_queue_windows +from airbrakes.utils import modify_multiprocessing_queue_windows if sys.platform != "win32": from faster_fifo import Queue from msgspec import to_builtins -from airbrakes.data_handling.imu_data_packet import EstimatedDataPacket, IMUDataPacket -from airbrakes.data_handling.logged_data_packet import LoggedDataPacket -from airbrakes.data_handling.processed_data_packet import ProcessedDataPacket -from constants import ( +from airbrakes.constants import ( BUFFER_SIZE_IN_BYTES, IDLE_LOG_CAPACITY, LOG_BUFFER_SIZE, MAX_GET_TIMEOUT_SECONDS, STOP_SIGNAL, ) +from airbrakes.data_handling.imu_data_packet import EstimatedDataPacket, IMUDataPacket +from airbrakes.data_handling.logged_data_packet import LoggedDataPacket +from airbrakes.data_handling.processed_data_packet import ProcessedDataPacket class Logger: diff --git a/src/airbrakes/hardware/imu.py b/src/airbrakes/hardware/imu.py index 1559ac20..83cd7288 100644 --- a/src/airbrakes/hardware/imu.py +++ b/src/airbrakes/hardware/imu.py @@ -17,12 +17,7 @@ else: from multiprocessing.queues import Empty -from airbrakes.data_handling.imu_data_packet import ( - EstimatedDataPacket, - IMUDataPacket, - RawDataPacket, -) -from constants import ( +from airbrakes.constants import ( BUFFER_SIZE_IN_BYTES, ESTIMATED_DESCRIPTOR_SET, IMU_TIMEOUT_SECONDS, @@ -31,6 +26,11 @@ RAW_DESCRIPTOR_SET, STOP_SIGNAL, ) +from airbrakes.data_handling.imu_data_packet import ( + EstimatedDataPacket, + IMUDataPacket, + RawDataPacket, +) class IMU: diff --git a/src/airbrakes/hardware/servo.py b/src/airbrakes/hardware/servo.py index 1a3b279c..dbb74424 100644 --- a/src/airbrakes/hardware/servo.py +++ b/src/airbrakes/hardware/servo.py @@ -6,7 +6,7 @@ import gpiozero -from constants import SERVO_DELAY_SECONDS, ServoExtension +from airbrakes.constants import SERVO_DELAY_SECONDS, ServoExtension class Servo: diff --git a/main.py b/src/airbrakes/main.py similarity index 71% rename from main.py rename to src/airbrakes/main.py index 49f1c2a3..82bab718 100644 --- a/main.py +++ b/src/airbrakes/main.py @@ -7,6 +7,7 @@ from gpiozero.pins.mock import MockFactory, MockPWMPin from airbrakes.airbrakes import AirbrakesContext +from airbrakes.constants import IMU_PORT, LOGS_PATH, SERVO_PIN from airbrakes.data_handling.apogee_predictor import ApogeePredictor from airbrakes.data_handling.data_processor import IMUDataProcessor from airbrakes.data_handling.logger import Logger @@ -15,11 +16,37 @@ from airbrakes.mock.display import FlightDisplay from airbrakes.mock.mock_imu import MockIMU from airbrakes.mock.mock_logger import MockLogger -from constants import IMU_PORT, LOGS_PATH, SERVO_PIN -from utils import arg_parser +from airbrakes.utils import arg_parser -def create_components(args: argparse.Namespace) -> tuple[Servo, IMU, Logger]: +def run_real_flight() -> None: + """Entry point for the application to run the real flight.""" + args = arg_parser() + run_flight(args) + + +def run_mock_flight() -> None: + """Entry point for the application to run the mock flight.""" + args = arg_parser() + args.mock = True + run_flight(args) + + +def run_flight(args: argparse.Namespace) -> None: + sim_time_start = time.time() + + servo, imu, logger, data_processor, apogee_predictor = create_components(args) + # Initialize the airbrakes context and display + airbrakes = AirbrakesContext(servo, imu, logger, data_processor, apogee_predictor) + flight_display = FlightDisplay(airbrakes, sim_time_start, args) + + # Run the main flight loop + run_flight_loop(airbrakes, flight_display, args.mock) + + +def create_components( + args: argparse.Namespace, +) -> tuple[Servo, IMU, Logger, IMUDataProcessor, ApogeePredictor]: """ Creates the system components needed for the airbrakes system. Depending on its arguments, it will return either mock or real components. @@ -45,7 +72,10 @@ def create_components(args: argparse.Namespace) -> tuple[Servo, IMU, Logger]: imu = IMU(IMU_PORT) logger = Logger(LOGS_PATH) - return servo, imu, logger + # Initialize data processing and prediction + data_processor = IMUDataProcessor() + apogee_predictor = ApogeePredictor() + return servo, imu, logger, data_processor, apogee_predictor def run_flight_loop( @@ -84,36 +114,14 @@ def run_flight_loop( airbrakes.stop() -def main(args: argparse.Namespace) -> None: - """ - Sets up and runs the airbrakes system. - :param args: Command line arguments for configuration. - """ - sim_time_start = time.time() - - # Creates the components for the airbrakes system - servo, imu, logger = create_components(args) - - # Initialize data processing and prediction - data_processor = IMUDataProcessor() - apogee_predictor = ApogeePredictor() - - # Initialize the airbrakes context and display - airbrakes = AirbrakesContext(servo, imu, logger, data_processor, apogee_predictor) - flight_display = FlightDisplay(airbrakes, sim_time_start, args) - - # Run the main flight loop - run_flight_loop(airbrakes, flight_display, args.mock) - - -if __name__ == "__main__": - # Command line args (after these are run, you can press Ctrl+C to exit the program): - # python main.py -v: Shows the display with much more data - # python main.py -m: Runs a simulation on your computer - # python main.py -m -r: Runs a simulation on your computer with the real servo - # python main.py -m -l: Runs a simulation on your computer and keeps the log file after the - # simulation stops - # python main.py -m -f: Runs a simulation on your computer at full speed - # python main.py -m -d: Runs a simulation on your computer in debug mode (doesn't show display) - args = arg_parser() - main(args) +# if __name__ == "__main__": +# # Command line args (after these are run, you can press Ctrl+C to exit the program): +# # uvx real -v: Shows the display with much more data +# # uvx mock: Runs a simulation on your computer +# # uvx mock -r: Runs a simulation on your computer with the real servo +# # uvx mock -l: Runs a simulation on your computer and keeps the log file after the +# # simulation stops +# # uvx mock -f: Runs a simulation on your computer at full speed +# # uvx mock -d: Runs a simulation on your computer in debug mode (doesn't show display) +# args = arg_parser() +# main(args) diff --git a/src/airbrakes/mock/display.py b/src/airbrakes/mock/display.py index 2ea48c9f..dc97441e 100644 --- a/src/airbrakes/mock/display.py +++ b/src/airbrakes/mock/display.py @@ -9,7 +9,7 @@ import psutil from colorama import Fore, Style, init -from constants import DisplayEndingType +from airbrakes.constants import DisplayEndingType if TYPE_CHECKING: from airbrakes.airbrakes import AirbrakesContext diff --git a/src/airbrakes/mock/mock_imu.py b/src/airbrakes/mock/mock_imu.py index a19a90aa..511743f6 100644 --- a/src/airbrakes/mock/mock_imu.py +++ b/src/airbrakes/mock/mock_imu.py @@ -14,21 +14,21 @@ else: from functools import partial - from utils import get_all_from_queue + from airbrakes.utils import get_all_from_queue -from airbrakes.data_handling.imu_data_packet import ( - EstimatedDataPacket, - IMUDataPacket, - RawDataPacket, -) -from airbrakes.hardware.imu import IMU -from constants import ( +from airbrakes.constants import ( LOG_BUFFER_SIZE, MAX_FETCHED_PACKETS, MAX_QUEUE_SIZE, RAW_DATA_PACKET_SAMPLING_RATE, STOP_SIGNAL, ) +from airbrakes.data_handling.imu_data_packet import ( + EstimatedDataPacket, + IMUDataPacket, + RawDataPacket, +) +from airbrakes.hardware.imu import IMU class MockIMU(IMU): diff --git a/src/airbrakes/state.py b/src/airbrakes/state.py index 142d43a1..3bf2770e 100644 --- a/src/airbrakes/state.py +++ b/src/airbrakes/state.py @@ -3,7 +3,7 @@ from abc import ABC, abstractmethod from typing import TYPE_CHECKING -from constants import ( +from airbrakes.constants import ( GROUND_ALTITUDE_METERS, LANDED_SPEED_METERS_PER_SECOND, MAX_FREE_FALL_SECONDS, @@ -12,7 +12,7 @@ TAKEOFF_VELOCITY_METERS_PER_SECOND, TARGET_ALTITUDE_METERS, ) -from utils import convert_to_seconds +from airbrakes.utils import convert_to_seconds if TYPE_CHECKING: from airbrakes.airbrakes import AirbrakesContext diff --git a/utils.py b/src/airbrakes/utils.py similarity index 100% rename from utils.py rename to src/airbrakes/utils.py diff --git a/tests/conftest.py b/tests/conftest.py index af025b38..5471e65a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -7,18 +7,18 @@ from gpiozero.pins.mock import MockFactory, MockPWMPin from airbrakes.airbrakes import AirbrakesContext +from airbrakes.constants import ( + EST_DATA_PACKET_SAMPLING_RATE, + IMU_PORT, + RAW_DATA_PACKET_SAMPLING_RATE, + SERVO_PIN, +) from airbrakes.data_handling.apogee_predictor import ApogeePredictor from airbrakes.data_handling.data_processor import IMUDataProcessor from airbrakes.data_handling.logger import Logger from airbrakes.hardware.imu import IMU from airbrakes.hardware.servo import Servo from airbrakes.mock.mock_imu import MockIMU -from constants import ( - EST_DATA_PACKET_SAMPLING_RATE, - IMU_PORT, - RAW_DATA_PACKET_SAMPLING_RATE, - SERVO_PIN, -) from tests.auxil.utils import make_est_data_packet, make_raw_data_packet LOG_PATH = Path("tests/logs") diff --git a/tests/test_airbrakes.py b/tests/test_airbrakes.py index 9c02d837..e0675b0d 100644 --- a/tests/test_airbrakes.py +++ b/tests/test_airbrakes.py @@ -4,10 +4,10 @@ import pytest from airbrakes.airbrakes import AirbrakesContext +from airbrakes.constants import IMU_TIMEOUT_SECONDS, SERVO_DELAY_SECONDS, ServoExtension from airbrakes.data_handling.data_processor import IMUDataProcessor from airbrakes.data_handling.imu_data_packet import RawDataPacket from airbrakes.state import CoastState, StandbyState -from constants import IMU_TIMEOUT_SECONDS, SERVO_DELAY_SECONDS, ServoExtension from tests.auxil.utils import make_est_data_packet diff --git a/tests/test_apogee_predictor.py b/tests/test_apogee_predictor.py index 237701ac..a0c95280 100644 --- a/tests/test_apogee_predictor.py +++ b/tests/test_apogee_predictor.py @@ -8,9 +8,9 @@ import numpy as np import pytest +from airbrakes.constants import APOGEE_PREDICTION_MIN_PACKETS from airbrakes.data_handling.apogee_predictor import ApogeePredictor, LookupTable from airbrakes.data_handling.processed_data_packet import ProcessedDataPacket -from constants import APOGEE_PREDICTION_MIN_PACKETS @pytest.fixture diff --git a/tests/test_imu.py b/tests/test_imu.py index a58ade7e..0ea4c113 100644 --- a/tests/test_imu.py +++ b/tests/test_imu.py @@ -7,13 +7,13 @@ import faster_fifo import pytest +from airbrakes.constants import IMU_PORT, STOP_SIGNAL from airbrakes.data_handling.imu_data_packet import ( EstimatedDataPacket, IMUDataPacket, RawDataPacket, ) from airbrakes.hardware.imu import IMU -from constants import IMU_PORT, STOP_SIGNAL class TestIMU: diff --git a/tests/test_integration.py b/tests/test_integration.py index 6c6ff8e9..7beb8d03 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -11,14 +11,14 @@ import pytest from airbrakes.airbrakes import AirbrakesContext -from airbrakes.data_handling.logged_data_packet import LoggedDataPacket -from constants import ( +from airbrakes.constants import ( GROUND_ALTITUDE_METERS, LANDED_SPEED_METERS_PER_SECOND, TAKEOFF_HEIGHT_METERS, TAKEOFF_VELOCITY_METERS_PER_SECOND, ServoExtension, ) +from airbrakes.data_handling.logged_data_packet import LoggedDataPacket SNAPSHOT_INTERVAL = 0.01 # seconds diff --git a/tests/test_logger.py b/tests/test_logger.py index 8d555282..90ac6c97 100644 --- a/tests/test_logger.py +++ b/tests/test_logger.py @@ -9,6 +9,7 @@ import faster_fifo import pytest +from airbrakes.constants import IDLE_LOG_CAPACITY, LOG_BUFFER_SIZE, STOP_SIGNAL from airbrakes.data_handling.imu_data_packet import ( EstimatedDataPacket, IMUDataPacket, @@ -17,7 +18,6 @@ from airbrakes.data_handling.logged_data_packet import LoggedDataPacket from airbrakes.data_handling.logger import Logger from airbrakes.data_handling.processed_data_packet import ProcessedDataPacket -from constants import IDLE_LOG_CAPACITY, LOG_BUFFER_SIZE, STOP_SIGNAL from tests.conftest import LOG_PATH diff --git a/tests/test_servo.py b/tests/test_servo.py index 0560f47f..f70c62ea 100644 --- a/tests/test_servo.py +++ b/tests/test_servo.py @@ -3,8 +3,8 @@ import gpiozero +from airbrakes.constants import SERVO_DELAY_SECONDS, ServoExtension from airbrakes.hardware.servo import Servo -from constants import SERVO_DELAY_SECONDS, ServoExtension class TestServo: diff --git a/tests/test_state.py b/tests/test_state.py index c493658a..de0516c4 100644 --- a/tests/test_state.py +++ b/tests/test_state.py @@ -2,6 +2,14 @@ import pytest +from airbrakes.constants import ( + GROUND_ALTITUDE_METERS, + LANDED_SPEED_METERS_PER_SECOND, + LOG_BUFFER_SIZE, + MAX_FREE_FALL_SECONDS, + MAX_VELOCITY_THRESHOLD, + ServoExtension, +) from airbrakes.data_handling.imu_data_packet import EstimatedDataPacket from airbrakes.state import ( CoastState, @@ -11,14 +19,6 @@ StandbyState, State, ) -from constants import ( - GROUND_ALTITUDE_METERS, - LANDED_SPEED_METERS_PER_SECOND, - LOG_BUFFER_SIZE, - MAX_FREE_FALL_SECONDS, - MAX_VELOCITY_THRESHOLD, - ServoExtension, -) @pytest.fixture diff --git a/tests/test_utils.py b/tests/test_utils.py index 0c612d43..9ba61293 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,6 +1,6 @@ import pytest -from utils import convert_str_to_float, convert_to_nanoseconds, deadband +from airbrakes.utils import convert_str_to_float, convert_to_nanoseconds, deadband @pytest.mark.parametrize( From a7b5714fe6487bc1997e1bdeac4c0dc32517c381 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Thu, 2 Jan 2025 10:52:37 +0400 Subject: [PATCH 03/12] Don't use src/ in the file structure --- {src/airbrakes => airbrakes}/__init__.py | 0 {src/airbrakes => airbrakes}/airbrakes.py | 0 {src/airbrakes => airbrakes}/constants.py | 0 .../data_handling/__init__.py | 0 .../data_handling/apogee_predictor.py | 0 .../data_handling/data_processor.py | 0 .../data_handling/imu_data_packet.py | 0 .../data_handling/logged_data_packet.py | 0 .../data_handling/logger.py | 0 .../data_handling/processed_data_packet.py | 0 .../hardware/__init__.py | 0 {src/airbrakes => airbrakes}/hardware/imu.py | 0 .../airbrakes => airbrakes}/hardware/servo.py | 0 {src/airbrakes => airbrakes}/main.py | 31 +++++++++++-------- {src/airbrakes => airbrakes}/mock/__init__.py | 0 {src/airbrakes => airbrakes}/mock/display.py | 0 {src/airbrakes => airbrakes}/mock/mock_imu.py | 0 .../mock/mock_logger.py | 0 {src/airbrakes => airbrakes}/state.py | 0 {src/airbrakes => airbrakes}/utils.py | 0 pyproject.toml | 6 ++-- 21 files changed, 21 insertions(+), 16 deletions(-) rename {src/airbrakes => airbrakes}/__init__.py (100%) rename {src/airbrakes => airbrakes}/airbrakes.py (100%) rename {src/airbrakes => airbrakes}/constants.py (100%) rename {src/airbrakes => airbrakes}/data_handling/__init__.py (100%) rename {src/airbrakes => airbrakes}/data_handling/apogee_predictor.py (100%) rename {src/airbrakes => airbrakes}/data_handling/data_processor.py (100%) rename {src/airbrakes => airbrakes}/data_handling/imu_data_packet.py (100%) rename {src/airbrakes => airbrakes}/data_handling/logged_data_packet.py (100%) rename {src/airbrakes => airbrakes}/data_handling/logger.py (100%) rename {src/airbrakes => airbrakes}/data_handling/processed_data_packet.py (100%) rename {src/airbrakes => airbrakes}/hardware/__init__.py (100%) rename {src/airbrakes => airbrakes}/hardware/imu.py (100%) rename {src/airbrakes => airbrakes}/hardware/servo.py (100%) rename {src/airbrakes => airbrakes}/main.py (79%) rename {src/airbrakes => airbrakes}/mock/__init__.py (100%) rename {src/airbrakes => airbrakes}/mock/display.py (100%) rename {src/airbrakes => airbrakes}/mock/mock_imu.py (100%) rename {src/airbrakes => airbrakes}/mock/mock_logger.py (100%) rename {src/airbrakes => airbrakes}/state.py (100%) rename {src/airbrakes => airbrakes}/utils.py (100%) diff --git a/src/airbrakes/__init__.py b/airbrakes/__init__.py similarity index 100% rename from src/airbrakes/__init__.py rename to airbrakes/__init__.py diff --git a/src/airbrakes/airbrakes.py b/airbrakes/airbrakes.py similarity index 100% rename from src/airbrakes/airbrakes.py rename to airbrakes/airbrakes.py diff --git a/src/airbrakes/constants.py b/airbrakes/constants.py similarity index 100% rename from src/airbrakes/constants.py rename to airbrakes/constants.py diff --git a/src/airbrakes/data_handling/__init__.py b/airbrakes/data_handling/__init__.py similarity index 100% rename from src/airbrakes/data_handling/__init__.py rename to airbrakes/data_handling/__init__.py diff --git a/src/airbrakes/data_handling/apogee_predictor.py b/airbrakes/data_handling/apogee_predictor.py similarity index 100% rename from src/airbrakes/data_handling/apogee_predictor.py rename to airbrakes/data_handling/apogee_predictor.py diff --git a/src/airbrakes/data_handling/data_processor.py b/airbrakes/data_handling/data_processor.py similarity index 100% rename from src/airbrakes/data_handling/data_processor.py rename to airbrakes/data_handling/data_processor.py diff --git a/src/airbrakes/data_handling/imu_data_packet.py b/airbrakes/data_handling/imu_data_packet.py similarity index 100% rename from src/airbrakes/data_handling/imu_data_packet.py rename to airbrakes/data_handling/imu_data_packet.py diff --git a/src/airbrakes/data_handling/logged_data_packet.py b/airbrakes/data_handling/logged_data_packet.py similarity index 100% rename from src/airbrakes/data_handling/logged_data_packet.py rename to airbrakes/data_handling/logged_data_packet.py diff --git a/src/airbrakes/data_handling/logger.py b/airbrakes/data_handling/logger.py similarity index 100% rename from src/airbrakes/data_handling/logger.py rename to airbrakes/data_handling/logger.py diff --git a/src/airbrakes/data_handling/processed_data_packet.py b/airbrakes/data_handling/processed_data_packet.py similarity index 100% rename from src/airbrakes/data_handling/processed_data_packet.py rename to airbrakes/data_handling/processed_data_packet.py diff --git a/src/airbrakes/hardware/__init__.py b/airbrakes/hardware/__init__.py similarity index 100% rename from src/airbrakes/hardware/__init__.py rename to airbrakes/hardware/__init__.py diff --git a/src/airbrakes/hardware/imu.py b/airbrakes/hardware/imu.py similarity index 100% rename from src/airbrakes/hardware/imu.py rename to airbrakes/hardware/imu.py diff --git a/src/airbrakes/hardware/servo.py b/airbrakes/hardware/servo.py similarity index 100% rename from src/airbrakes/hardware/servo.py rename to airbrakes/hardware/servo.py diff --git a/src/airbrakes/main.py b/airbrakes/main.py similarity index 79% rename from src/airbrakes/main.py rename to airbrakes/main.py index 82bab718..1bd79b78 100644 --- a/src/airbrakes/main.py +++ b/airbrakes/main.py @@ -20,13 +20,15 @@ def run_real_flight() -> None: - """Entry point for the application to run the real flight.""" + """Entry point for the application to run the real flight. Entered when run with + `uv run real` or `uvx real`.""" args = arg_parser() run_flight(args) def run_mock_flight() -> None: - """Entry point for the application to run the mock flight.""" + """Entry point for the application to run the mock flight. Entered when run with + `uvx mock` or `uv run mock`.""" args = arg_parser() args.mock = True run_flight(args) @@ -114,14 +116,17 @@ def run_flight_loop( airbrakes.stop() -# if __name__ == "__main__": -# # Command line args (after these are run, you can press Ctrl+C to exit the program): -# # uvx real -v: Shows the display with much more data -# # uvx mock: Runs a simulation on your computer -# # uvx mock -r: Runs a simulation on your computer with the real servo -# # uvx mock -l: Runs a simulation on your computer and keeps the log file after the -# # simulation stops -# # uvx mock -f: Runs a simulation on your computer at full speed -# # uvx mock -d: Runs a simulation on your computer in debug mode (doesn't show display) -# args = arg_parser() -# main(args) +if __name__ == "__main__": + # Legacy way to run the program: + # python -m airbrakes.main [ARGS] + + # Command line args (after these are run, you can press Ctrl+C to exit the program): + # python -m airbrakes.main -v: Shows the display with much more data + # python -m airbrakes.main -m: Runs a simulation on your computer + # python -m airbrakes.main -r: Runs a simulation on your computer with the real servo + # python -m airbrakes.main -l: Runs a simulation on your computer and keeps the log file after + # the simulation stops + # python -m airbrakes.main -m -f: Runs a simulation on your computer at full speed + # python -m airbrakes.main -m -d: Runs a simulation on your computer in debug mode (w/o display) + args = arg_parser() + run_flight(args) diff --git a/src/airbrakes/mock/__init__.py b/airbrakes/mock/__init__.py similarity index 100% rename from src/airbrakes/mock/__init__.py rename to airbrakes/mock/__init__.py diff --git a/src/airbrakes/mock/display.py b/airbrakes/mock/display.py similarity index 100% rename from src/airbrakes/mock/display.py rename to airbrakes/mock/display.py diff --git a/src/airbrakes/mock/mock_imu.py b/airbrakes/mock/mock_imu.py similarity index 100% rename from src/airbrakes/mock/mock_imu.py rename to airbrakes/mock/mock_imu.py diff --git a/src/airbrakes/mock/mock_logger.py b/airbrakes/mock/mock_logger.py similarity index 100% rename from src/airbrakes/mock/mock_logger.py rename to airbrakes/mock/mock_logger.py diff --git a/src/airbrakes/state.py b/airbrakes/state.py similarity index 100% rename from src/airbrakes/state.py rename to airbrakes/state.py diff --git a/src/airbrakes/utils.py b/airbrakes/utils.py similarity index 100% rename from src/airbrakes/utils.py rename to airbrakes/utils.py diff --git a/pyproject.toml b/pyproject.toml index 03410eab..7add173c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,7 @@ build-backend = "hatchling.build" # HATCH: [tool.hatch.build.targets.wheel] -packages = ["src/airbrakes"] +packages = ["airbrakes"] # RUFF: [tool.ruff] @@ -53,7 +53,7 @@ select = ["E", "F", "I", "PL", "UP", "RUF", "PTH", "C4", "B", "PIE", "SIM", "RET [tool.ruff.lint.per-file-ignores] "main.py" = ["T201"] -"src/airbrakes/mock/display.py" = ["T201"] +"airbrakes/mock/display.py" = ["T201"] "tests/*.py" = ["T20", "S101", "D100", "ARG001", "RUF012"] [tool.pytest.ini_options] @@ -69,7 +69,7 @@ source = ["airbrakes"] omit = [ "*/tests/*", "*/site-packages/*", - "src/airbrakes/mock/*" + "airbrakes/mock/*" ] [tool.coverage.report] From 1339baad0d85c7570a120fce183adade838d7807 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Thu, 2 Jan 2025 12:46:03 +0400 Subject: [PATCH 04/12] Use PEP 735 dependency groups --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7add173c..56dbf377 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,7 @@ dependencies = [ # "mscl" https://github.com/LORD-MicroStrain/MSCL/blob/master/BuildScripts/buildReadme_Linux.md ] -[project.optional-dependencies] +[dependency-groups] dev = [ "pytest", "pytest-cov", From 091dc2484af6d28d719f1648d3401faae7175313 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Thu, 2 Jan 2025 12:46:34 +0400 Subject: [PATCH 05/12] Update readme to reflect how to use uv --- README.md | 109 +++++++++++++++++++++++++++++++--------- legacy_project_setup.md | 67 ++++++++++++++++++++++++ scripts/run_logger.py | 2 +- 3 files changed, 152 insertions(+), 26 deletions(-) create mode 100644 legacy_project_setup.md diff --git a/README.md b/README.md index 774d602c..e9349d0b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,31 @@ # AirbrakesV2 🚀 +# Table of Contents + +- [Overview](#overview) +- [Design](#design) +- [System Architecture Flowchart](#system-architecture-flowchart) +- [Launch Data](#launch-data) +- [File Structure](#file-structure) +- [Quick Start](#quick-start) +- [Local Setup](#local-setup) + - [1. Clone the repository](#1-clone-the-repository) + - [2. Install the project](#2-install-the-project) + - [3. Install the pre-commit hook](#3-install-the-pre-commit-hook) + - [4. Make your changes and commit](#4-make-your-changes-and-commit) +- [Advanced Local Usage](#advanced-local-usage) + - [Running Mock Launches](#running-mock-launches) + - [Running Tests](#running-tests) + - [Running the Linter](#running-the-linter) +- [Pi Usage](#pi-usage) + - [Connecting to the Pi (SSH)](#connecting-to-the-pi-ssh) + - [Install and start the pigpio daemon on the Raspberry Pi](#install-and-start-the-pigpio-daemon-on-the-raspberry-pi) + - [Run a real flight with real hardware](#run-a-real-flight-with-real-hardware) + - [Running Test Scripts](#running-test-scripts) +- [Contributing](#contributing) +- [License](#license) + + ## Overview This project is for controlling our Air brakes system with the goal of making our rocket "hit" its target apogee. We have a Raspberry Pi 4 as the brains of our system which runs our code. It connects to a servo motor to control the extension of our air brakes and an [IMU](https://www.microstrain.com/inertial-sensors/3dm-cx5-15) (basically an altimeter, accelerometer, and gyroscope). The code follows the [finite state machine](https://www.tutorialspoint.com/design_pattern/state_pattern.htm) design pattern, using the [`AirbrakesContext`](https://github.com/NCSU-High-Powered-Rocketry-Club/AirbrakesV2/blob/main/airbrakes/airbrakes.py) to manage interactions between the states, hardware, logging, and data processing. @@ -121,67 +147,92 @@ AirbrakesV2/ | ├── data_handling/ │ │ ├── [files related to the processing of data ...] │ ├── [files which control the airbrakes at a high level ...] +| ├── main.py [main file used to run on the rocket] +| ├── constants.py [file for constants used in the project] ├── tests/ [used for testing all the code] │ ├── ... ├── logs/ [log files made by the logger] │ ├── ... ├── scripts/ [small files to test individual components like the servo] │ ├── ... -├── main.py [main file used to run on the rocket] -├── constants.py [file for constants used in the project] ├── pyproject.toml [configuration file for the project] ├── README.md ``` + +## Quick Start + +This project strongly recommends using [`uv`](https://docs.astral.sh/uv/) to manage and install +the project. To quickly run the mock simulation, simply run: + +```bash +uvx --from git+https://github.com/NCSU-High-Powered-Rocketry-Club/AirbrakesV2.git mock +``` + +You should see the mock simulation running with a display! + +_Note: We will continue using `uv` for the rest of this README, if you don't want to use `uv`, you can set up the project using Python. See [Legacy Project Setup](legacy_project_setup.md) for more information._ + ## Local Setup -**This project uses Python 3.13. Using an older version may not work since we use newer language features** +If you want to contribute to the project, you will need to set up the project locally. Luckily, +the only other thing you need to install is [`git`](https://git-scm.com/) for version control. -### Clone the repository: +### 1. Clone the repository: ``` git clone https://github.com/NCSU-High-Powered-Rocketry-Club/AirbrakesV2.git cd AirbrakesV2 ``` -### Set up a virtual environment: - +### 2. Install the project: ```bash -python -m venv .venv - -# For Linux -source .venv/bin/activate -# For Windows -.\.venv\Scripts\activate +uv run mock ``` -### Install the required dependencies: +This will install the project, including development dependencies, activate the virtual environment and run the mock simulation. -```bash -pip install .[dev] -``` -_There are libraries that only fully work when running on the Pi (gpiozero, mscl), so if you're having trouble importing them locally, program the best you can and test your changes on the pi._ +_Note: It is important to use `uv run` instead of `uvx` since the `uvx` environment is isolated from +the project. See the [uv documentation](https://docs.astral.sh/uv/concepts/tools/#relationship-to-uv-run) for more information._ +_Note 2: The more "correct" command to run is `uv sync`. This will install the project and its dependencies, but not run the mock simulation._ + +### 3. Install the pre-commit hook: ``` pre-commit install ``` This will install a pre-commit hook that will run the linter before you commit your changes. -## Local Usage +### 4. Make your changes and commit: + +After you have made your changes, you can commit them: +```bash +git add . +git commit -m "Your commit message" +``` + +You will see the linter run now. If one of the checks failed, you can resolve them by following the +instructions in [Running the Linter](#running-the-linter). + +```bash +git push -u origin branch-name +``` + +## Advanced Local Usage ### Running Mock Launches Testing our code can be difficult, so we've developed a way to run mock launches based on previous flight data--the rocket pretends, in real-time, that it's flying through a previous launch. -To run a mock launch, make sure to first specify the path to the CSV file for the previous launch's data in `constants.py` and then run: +To run a mock launch, run: ```bash -python3 main.py -m +uv run mock ``` If you want to run a mock launch, but with the real servo running, run: ```bash -python3 main.py -m -r +uv run mock -r ``` There are some additional options you can use when running a mock launch. To view them all, run: ```bash -python3 main.py --help +uv run mock --help ``` ### Running Tests @@ -216,11 +267,14 @@ ruff format . ## Pi Usage +_There are libraries that only fully work when running on the Pi (gpiozero, mscl), so if you're having trouble importing them locally, program the best you can and test your changes on the pi._ + + ### Connecting to the Pi (SSH) In order to connect to the Pi, you need first to set up a mobile hotspot with the name `HPRC`, password `tacholycos`, and `2.4 GHz` band. Next, turn on the Pi and it will automatically connect to your hotspot. Once it's connected, find the Pi's IP Address, and in your terminal run: ```bash ssh pi@[IP.ADDRESS] -# Its password is raspberry +# Its password is "raspberry" cd AirbrakesV2/ ``` @@ -231,11 +285,16 @@ _Every time the pi boots up, you must run this in order for the servo to work. W sudo pigpiod ``` +### Run a real flight with real hardware: +```bash +uv run real +``` + ### Running Test Scripts During development, you may want to run individual scripts to test components. For example, to test the servo, run: ```bash -# Make sure you are in the root directory, -python3 -m scripts.run_servo +# Make sure you are in the root directory: +uv run scripts/run_servo.py ``` ## Contributing diff --git a/legacy_project_setup.md b/legacy_project_setup.md new file mode 100644 index 00000000..01d9ada1 --- /dev/null +++ b/legacy_project_setup.md @@ -0,0 +1,67 @@ +# Local setup for the rebels + +If you don't want to use `uv`, you can set up the project using Python. + +**This project uses Python 3.13. Using an older version may not work since we use newer language features** + + +### 1. Clone the repository: + +``` +git clone https://github.com/NCSU-High-Powered-Rocketry-Club/AirbrakesV2.git +cd AirbrakesV2 +``` + +### 2. Set up a virtual environment: + +```bash +python -m venv .venv + +# For Linux +source .venv/bin/activate +# For Windows +.\.venv\Scripts\activate +``` + +### 3. Install the required dependencies: + +```bash +pip install . -e +``` + +This command will install the required dependencies for the project. If you want to install the development dependencies, you can run: + +```bash +pip install pytest pytest-cov ruff pre-commit +``` + +Then, follow from [step 3 on the main README](README.md#3-install-the-pre-commit-hook) to finish the local setup and make a commit. + + +## Advanced Local Usage + +The python equivalent command to `uv` is: + +```bash +python -m airbrakes.main -m +``` + +for running a mock. So to run a mock sim with the real servo, you would run: + +```bash +python -m airbrakes.main -m -r +``` + +To run a real flight, you would run: + +```bash +python -m airbrakes.main +``` + +To run a script for testing, you would run: + +```bash +python scripts/run_logger.py +``` + +_There are libraries that only fully work when running on the Pi (gpiozero, mscl), so if you're having trouble importing them locally, program the best you can and test your changes on the pi._ \ No newline at end of file diff --git a/scripts/run_logger.py b/scripts/run_logger.py index ab26c957..c6592298 100644 --- a/scripts/run_logger.py +++ b/scripts/run_logger.py @@ -12,7 +12,7 @@ def main(): # Initialize the logger logger = Logger(TEST_LOGS_PATH) - data_processor = IMUDataProcessor(False) + data_processor = IMUDataProcessor() # Log for 5 seconds, and automatically stops logging start_time = time.time() From 36bd70b8362137aeab973231737829fdcc0bc7d6 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Thu, 2 Jan 2025 12:47:23 +0400 Subject: [PATCH 06/12] Commit uv.lock --- uv.lock | 464 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 464 insertions(+) create mode 100644 uv.lock diff --git a/uv.lock b/uv.lock new file mode 100644 index 00000000..9cd53996 --- /dev/null +++ b/uv.lock @@ -0,0 +1,464 @@ +version = 1 +requires-python = ">=3.13" + +[[package]] +name = "airbrakesv2" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "colorama" }, + { name = "faster-fifo", marker = "sys_platform != 'win32'" }, + { name = "gpiozero" }, + { name = "msgspec" }, + { name = "numpy" }, + { name = "pandas" }, + { name = "pigpio" }, + { name = "psutil" }, + { name = "scipy" }, +] + +[package.dev-dependencies] +dev = [ + { name = "pre-commit" }, + { name = "pytest" }, + { name = "pytest-cov" }, + { name = "ruff" }, +] + +[package.metadata] +requires-dist = [ + { name = "colorama" }, + { name = "faster-fifo", marker = "sys_platform != 'win32'" }, + { name = "gpiozero" }, + { name = "msgspec" }, + { name = "numpy" }, + { name = "pandas" }, + { name = "pigpio" }, + { name = "psutil" }, + { name = "scipy" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "pre-commit" }, + { name = "pytest" }, + { name = "pytest-cov" }, + { name = "ruff" }, +] + +[[package]] +name = "cfgv" +version = "3.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/11/74/539e56497d9bd1d484fd863dd69cbbfa653cd2aa27abfe35653494d85e94/cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560", size = 7114 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249 }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, +] + +[[package]] +name = "colorzero" +version = "2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "setuptools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b3/ca/688824a06e8c4d04c7d2fd2af2d8da27bed51af20ee5f094154e1d680334/colorzero-2.0.tar.gz", hash = "sha256:e7d5a5c26cd0dc37b164ebefc609f388de24f8593b659191e12d85f8f9d5eb58", size = 25382 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/a6/ddd0f130e44a7593ac6c55aa93f6e256d2270fd88e9d1b64ab7f22ab8fde/colorzero-2.0-py2.py3-none-any.whl", hash = "sha256:0e60d743a6b8071498a56465f7719c96a5e92928f858bab1be2a0d606c9aa0f8", size = 26573 }, +] + +[[package]] +name = "coverage" +version = "7.6.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/84/ba/ac14d281f80aab516275012e8875991bb06203957aa1e19950139238d658/coverage-7.6.10.tar.gz", hash = "sha256:7fb105327c8f8f0682e29843e2ff96af9dcbe5bab8eeb4b398c6a33a16d80a23", size = 803868 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/25/6d/31883d78865529257bf847df5789e2ae80e99de8a460c3453dbfbe0db069/coverage-7.6.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05fca8ba6a87aabdd2d30d0b6c838b50510b56cdcfc604d40760dae7153b73d9", size = 208308 }, + { url = "https://files.pythonhosted.org/packages/70/22/3f2b129cc08de00c83b0ad6252e034320946abfc3e4235c009e57cfeee05/coverage-7.6.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9e80eba8801c386f72e0712a0453431259c45c3249f0009aff537a517b52942b", size = 208565 }, + { url = "https://files.pythonhosted.org/packages/97/0a/d89bc2d1cc61d3a8dfe9e9d75217b2be85f6c73ebf1b9e3c2f4e797f4531/coverage-7.6.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a372c89c939d57abe09e08c0578c1d212e7a678135d53aa16eec4430adc5e690", size = 241083 }, + { url = "https://files.pythonhosted.org/packages/4c/81/6d64b88a00c7a7aaed3a657b8eaa0931f37a6395fcef61e53ff742b49c97/coverage-7.6.10-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec22b5e7fe7a0fa8509181c4aac1db48f3dd4d3a566131b313d1efc102892c18", size = 238235 }, + { url = "https://files.pythonhosted.org/packages/9a/0b/7797d4193f5adb4b837207ed87fecf5fc38f7cc612b369a8e8e12d9fa114/coverage-7.6.10-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26bcf5c4df41cad1b19c84af71c22cbc9ea9a547fc973f1f2cc9a290002c8b3c", size = 240220 }, + { url = "https://files.pythonhosted.org/packages/65/4d/6f83ca1bddcf8e51bf8ff71572f39a1c73c34cf50e752a952c34f24d0a60/coverage-7.6.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e4630c26b6084c9b3cb53b15bd488f30ceb50b73c35c5ad7871b869cb7365fd", size = 239847 }, + { url = "https://files.pythonhosted.org/packages/30/9d/2470df6aa146aff4c65fee0f87f58d2164a67533c771c9cc12ffcdb865d5/coverage-7.6.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2396e8116db77789f819d2bc8a7e200232b7a282c66e0ae2d2cd84581a89757e", size = 237922 }, + { url = "https://files.pythonhosted.org/packages/08/dd/723fef5d901e6a89f2507094db66c091449c8ba03272861eaefa773ad95c/coverage-7.6.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:79109c70cc0882e4d2d002fe69a24aa504dec0cc17169b3c7f41a1d341a73694", size = 239783 }, + { url = "https://files.pythonhosted.org/packages/3d/f7/64d3298b2baf261cb35466000628706ce20a82d42faf9b771af447cd2b76/coverage-7.6.10-cp313-cp313-win32.whl", hash = "sha256:9e1747bab246d6ff2c4f28b4d186b205adced9f7bd9dc362051cc37c4a0c7bd6", size = 210965 }, + { url = "https://files.pythonhosted.org/packages/d5/58/ec43499a7fc681212fe7742fe90b2bc361cdb72e3181ace1604247a5b24d/coverage-7.6.10-cp313-cp313-win_amd64.whl", hash = "sha256:254f1a3b1eef5f7ed23ef265eaa89c65c8c5b6b257327c149db1ca9d4a35f25e", size = 211719 }, + { url = "https://files.pythonhosted.org/packages/ab/c9/f2857a135bcff4330c1e90e7d03446b036b2363d4ad37eb5e3a47bbac8a6/coverage-7.6.10-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ccf240eb719789cedbb9fd1338055de2761088202a9a0b73032857e53f612fe", size = 209050 }, + { url = "https://files.pythonhosted.org/packages/aa/b3/f840e5bd777d8433caa9e4a1eb20503495709f697341ac1a8ee6a3c906ad/coverage-7.6.10-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0c807ca74d5a5e64427c8805de15b9ca140bba13572d6d74e262f46f50b13273", size = 209321 }, + { url = "https://files.pythonhosted.org/packages/85/7d/125a5362180fcc1c03d91850fc020f3831d5cda09319522bcfa6b2b70be7/coverage-7.6.10-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bcfa46d7709b5a7ffe089075799b902020b62e7ee56ebaed2f4bdac04c508d8", size = 252039 }, + { url = "https://files.pythonhosted.org/packages/a9/9c/4358bf3c74baf1f9bddd2baf3756b54c07f2cfd2535f0a47f1e7757e54b3/coverage-7.6.10-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e0de1e902669dccbf80b0415fb6b43d27edca2fbd48c74da378923b05316098", size = 247758 }, + { url = "https://files.pythonhosted.org/packages/cf/c7/de3eb6fc5263b26fab5cda3de7a0f80e317597a4bad4781859f72885f300/coverage-7.6.10-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7b444c42bbc533aaae6b5a2166fd1a797cdb5eb58ee51a92bee1eb94a1e1cb", size = 250119 }, + { url = "https://files.pythonhosted.org/packages/3e/e6/43de91f8ba2ec9140c6a4af1102141712949903dc732cf739167cfa7a3bc/coverage-7.6.10-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b330368cb99ef72fcd2dc3ed260adf67b31499584dc8a20225e85bfe6f6cfed0", size = 249597 }, + { url = "https://files.pythonhosted.org/packages/08/40/61158b5499aa2adf9e37bc6d0117e8f6788625b283d51e7e0c53cf340530/coverage-7.6.10-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:9a7cfb50515f87f7ed30bc882f68812fd98bc2852957df69f3003d22a2aa0abf", size = 247473 }, + { url = "https://files.pythonhosted.org/packages/50/69/b3f2416725621e9f112e74e8470793d5b5995f146f596f133678a633b77e/coverage-7.6.10-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f93531882a5f68c28090f901b1d135de61b56331bba82028489bc51bdd818d2", size = 248737 }, + { url = "https://files.pythonhosted.org/packages/3c/6e/fe899fb937657db6df31cc3e61c6968cb56d36d7326361847440a430152e/coverage-7.6.10-cp313-cp313t-win32.whl", hash = "sha256:89d76815a26197c858f53c7f6a656686ec392b25991f9e409bcef020cd532312", size = 211611 }, + { url = "https://files.pythonhosted.org/packages/1c/55/52f5e66142a9d7bc93a15192eba7a78513d2abf6b3558d77b4ca32f5f424/coverage-7.6.10-cp313-cp313t-win_amd64.whl", hash = "sha256:54a5f0f43950a36312155dae55c505a76cd7f2b12d26abeebbe7a0b36dbc868d", size = 212781 }, +] + +[[package]] +name = "distlib" +version = "0.3.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0d/dd/1bec4c5ddb504ca60fc29472f3d27e8d4da1257a854e1d96742f15c1d02d/distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403", size = 613923 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/91/a1/cf2472db20f7ce4a6be1253a81cfdf85ad9c7885ffbed7047fb72c24cf87/distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87", size = 468973 }, +] + +[[package]] +name = "faster-fifo" +version = "1.5.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2f/f0/8747adf39f3f337b09217ceebb6e415ef874e360718d0e52837c889cc217/faster_fifo-1.5.2.tar.gz", hash = "sha256:a2a544fef4d6e31ebd4bb4c7bbfced315d741c3b7ccad23fe0a359d7b408527e", size = 11743 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/01/21/84f7d0b86027ac85182d3d3b40daed4c0963a9e9b2c61493017ec8de5b08/faster_fifo-1.5.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:996a17e28f3fba04b3c540546592b390d274887cb95e396253a625e6f6e57a2a", size = 73730 }, + { url = "https://files.pythonhosted.org/packages/d9/e1/4b8ee7b5f7b92852121c31baaf2b232fa11fdb60ef1b330959e7ca01f01e/faster_fifo-1.5.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0e3e62dd3682384bf73ede63263a2ca84f0ec5b66979b5c5063359887c431d6e", size = 69819 }, + { url = "https://files.pythonhosted.org/packages/9e/8b/d519fc8b60f9abb678773008a27d65b517c0abcd672d9667f94d59314167/faster_fifo-1.5.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25234d347e3fdd2f8eca08ebe5bceefb8be411dc04dbc747675411598c350cea", size = 427358 }, + { url = "https://files.pythonhosted.org/packages/7f/72/94fe96439cc0d80984c522af13d3454debb1eaeda75d7fad8a73aefca829/faster_fifo-1.5.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5804d9012b3ca9f742cd1a7a36cc7b0153247abb3e6eea6c8861a7e247010176", size = 399030 }, + { url = "https://files.pythonhosted.org/packages/a8/cf/ae29c0e8c62792f2d308ca455de9a6d3f6a198160e9bc9506981b5e20c41/faster_fifo-1.5.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a54cec635fc3967d04067f11192649fef5a54e7f5c8aa098f573b0638fd62d81", size = 1500871 }, + { url = "https://files.pythonhosted.org/packages/7f/51/64c1a1a90233327ff953638a452ce7b8bd102cb164aa94754896941a1201/faster_fifo-1.5.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:db0b2989586ac8d1247d83474992e565a7ae92c89ca455d780b489293c4ea7bf", size = 1424206 }, +] + +[[package]] +name = "filelock" +version = "3.16.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9d/db/3ef5bb276dae18d6ec2124224403d1d67bccdbefc17af4cc8f553e341ab1/filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435", size = 18037 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b9/f8/feced7779d755758a52d1f6635d990b8d98dc0a29fa568bbe0625f18fdf3/filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0", size = 16163 }, +] + +[[package]] +name = "gpiozero" +version = "2.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorzero" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/47/334b8db8a981eca9a0fb1e7e48e1997a5eaa8f40bb31c504299dcca0e6ff/gpiozero-2.0.1.tar.gz", hash = "sha256:d4ea1952689ec7e331f9d4ebc9adb15f1d01c2c9dcfabb72e752c9869ab7e97e", size = 136176 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/eb/6518a1b00488d48995034226846653c382d676cf5f04be62b3c3fae2c6a1/gpiozero-2.0.1-py3-none-any.whl", hash = "sha256:8f621de357171d574c0b7ea0e358cb66e560818a47b0eeedf41ce1cdbd20c70b", size = 150818 }, +] + +[[package]] +name = "identify" +version = "2.6.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/49/a5/7de3053524ee006b91099968d7ecb2e0b420f7ae728094394c33e8a2a2b9/identify-2.6.4.tar.gz", hash = "sha256:285a7d27e397652e8cafe537a6cc97dd470a970f48fb2e9d979aa38eae5513ac", size = 99209 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/9d/52f036403ae86474804f699c0d084b4b071e333a390b20269bb8accc65e0/identify-2.6.4-py2.py3-none-any.whl", hash = "sha256:993b0f01b97e0568c179bb9196391ff391bfb88a99099dbf5ce392b68f42d0af", size = 99072 }, +] + +[[package]] +name = "iniconfig" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 }, +] + +[[package]] +name = "msgspec" +version = "0.19.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cf/9b/95d8ce458462b8b71b8a70fa94563b2498b89933689f3a7b8911edfae3d7/msgspec-0.19.0.tar.gz", hash = "sha256:604037e7cd475345848116e89c553aa9a233259733ab51986ac924ab1b976f8e", size = 216934 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/cb/2842c312bbe618d8fefc8b9cedce37f773cdc8fa453306546dba2c21fd98/msgspec-0.19.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f12d30dd6266557aaaf0aa0f9580a9a8fbeadfa83699c487713e355ec5f0bd86", size = 190498 }, + { url = "https://files.pythonhosted.org/packages/58/95/c40b01b93465e1a5f3b6c7d91b10fb574818163740cc3acbe722d1e0e7e4/msgspec-0.19.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82b2c42c1b9ebc89e822e7e13bbe9d17ede0c23c187469fdd9505afd5a481314", size = 183950 }, + { url = "https://files.pythonhosted.org/packages/e8/f0/5b764e066ce9aba4b70d1db8b087ea66098c7c27d59b9dd8a3532774d48f/msgspec-0.19.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19746b50be214a54239aab822964f2ac81e38b0055cca94808359d779338c10e", size = 210647 }, + { url = "https://files.pythonhosted.org/packages/9d/87/bc14f49bc95c4cb0dd0a8c56028a67c014ee7e6818ccdce74a4862af259b/msgspec-0.19.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60ef4bdb0ec8e4ad62e5a1f95230c08efb1f64f32e6e8dd2ced685bcc73858b5", size = 213563 }, + { url = "https://files.pythonhosted.org/packages/53/2f/2b1c2b056894fbaa975f68f81e3014bb447516a8b010f1bed3fb0e016ed7/msgspec-0.19.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac7f7c377c122b649f7545810c6cd1b47586e3aa3059126ce3516ac7ccc6a6a9", size = 213996 }, + { url = "https://files.pythonhosted.org/packages/aa/5a/4cd408d90d1417e8d2ce6a22b98a6853c1b4d7cb7669153e4424d60087f6/msgspec-0.19.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a5bc1472223a643f5ffb5bf46ccdede7f9795078194f14edd69e3aab7020d327", size = 219087 }, + { url = "https://files.pythonhosted.org/packages/23/d8/f15b40611c2d5753d1abb0ca0da0c75348daf1252220e5dda2867bd81062/msgspec-0.19.0-cp313-cp313-win_amd64.whl", hash = "sha256:317050bc0f7739cb30d257ff09152ca309bf5a369854bbf1e57dffc310c1f20f", size = 187432 }, +] + +[[package]] +name = "nodeenv" +version = "1.9.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 }, +] + +[[package]] +name = "numpy" +version = "2.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/a5/fdbf6a7871703df6160b5cf3dd774074b086d278172285c52c2758b76305/numpy-2.2.1.tar.gz", hash = "sha256:45681fd7128c8ad1c379f0ca0776a8b0c6583d2f69889ddac01559dfe4390918", size = 20227662 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/d6/91a26e671c396e0c10e327b763485ee295f5a5a7a48c553f18417e5a0ed5/numpy-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f1d09e520217618e76396377c81fba6f290d5f926f50c35f3a5f72b01a0da780", size = 20896464 }, + { url = "https://files.pythonhosted.org/packages/8c/40/5792ccccd91d45e87d9e00033abc4f6ca8a828467b193f711139ff1f1cd9/numpy-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3ecc47cd7f6ea0336042be87d9e7da378e5c7e9b3c8ad0f7c966f714fc10d821", size = 14111350 }, + { url = "https://files.pythonhosted.org/packages/c0/2a/fb0a27f846cb857cef0c4c92bef89f133a3a1abb4e16bba1c4dace2e9b49/numpy-2.2.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f419290bc8968a46c4933158c91a0012b7a99bb2e465d5ef5293879742f8797e", size = 5111629 }, + { url = "https://files.pythonhosted.org/packages/eb/e5/8e81bb9d84db88b047baf4e8b681a3e48d6390bc4d4e4453eca428ecbb49/numpy-2.2.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5b6c390bfaef8c45a260554888966618328d30e72173697e5cabe6b285fb2348", size = 6645865 }, + { url = "https://files.pythonhosted.org/packages/7a/1a/a90ceb191dd2f9e2897c69dde93ccc2d57dd21ce2acbd7b0333e8eea4e8d/numpy-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:526fc406ab991a340744aad7e25251dd47a6720a685fa3331e5c59fef5282a59", size = 14043508 }, + { url = "https://files.pythonhosted.org/packages/f1/5a/e572284c86a59dec0871a49cd4e5351e20b9c751399d5f1d79628c0542cb/numpy-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f74e6fdeb9a265624ec3a3918430205dff1df7e95a230779746a6af78bc615af", size = 16094100 }, + { url = "https://files.pythonhosted.org/packages/0c/2c/a79d24f364788386d85899dd280a94f30b0950be4b4a545f4fa4ed1d4ca7/numpy-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:53c09385ff0b72ba79d8715683c1168c12e0b6e84fb0372e97553d1ea91efe51", size = 15239691 }, + { url = "https://files.pythonhosted.org/packages/cf/79/1e20fd1c9ce5a932111f964b544facc5bb9bde7865f5b42f00b4a6a9192b/numpy-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f3eac17d9ec51be534685ba877b6ab5edc3ab7ec95c8f163e5d7b39859524716", size = 17856571 }, + { url = "https://files.pythonhosted.org/packages/be/5b/cc155e107f75d694f562bdc84a26cc930569f3dfdfbccb3420b626065777/numpy-2.2.1-cp313-cp313-win32.whl", hash = "sha256:9ad014faa93dbb52c80d8f4d3dcf855865c876c9660cb9bd7553843dd03a4b1e", size = 6270841 }, + { url = "https://files.pythonhosted.org/packages/44/be/0e5cd009d2162e4138d79a5afb3b5d2341f0fe4777ab6e675aa3d4a42e21/numpy-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:164a829b6aacf79ca47ba4814b130c4020b202522a93d7bff2202bfb33b61c60", size = 12606618 }, + { url = "https://files.pythonhosted.org/packages/a8/87/04ddf02dd86fb17c7485a5f87b605c4437966d53de1e3745d450343a6f56/numpy-2.2.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4dfda918a13cc4f81e9118dea249e192ab167a0bb1966272d5503e39234d694e", size = 20921004 }, + { url = "https://files.pythonhosted.org/packages/6e/3e/d0e9e32ab14005425d180ef950badf31b862f3839c5b927796648b11f88a/numpy-2.2.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:733585f9f4b62e9b3528dd1070ec4f52b8acf64215b60a845fa13ebd73cd0712", size = 14119910 }, + { url = "https://files.pythonhosted.org/packages/b5/5b/aa2d1905b04a8fb681e08742bb79a7bddfc160c7ce8e1ff6d5c821be0236/numpy-2.2.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:89b16a18e7bba224ce5114db863e7029803c179979e1af6ad6a6b11f70545008", size = 5153612 }, + { url = "https://files.pythonhosted.org/packages/ce/35/6831808028df0648d9b43c5df7e1051129aa0d562525bacb70019c5f5030/numpy-2.2.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:676f4eebf6b2d430300f1f4f4c2461685f8269f94c89698d832cdf9277f30b84", size = 6668401 }, + { url = "https://files.pythonhosted.org/packages/b1/38/10ef509ad63a5946cc042f98d838daebfe7eaf45b9daaf13df2086b15ff9/numpy-2.2.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27f5cdf9f493b35f7e41e8368e7d7b4bbafaf9660cba53fb21d2cd174ec09631", size = 14014198 }, + { url = "https://files.pythonhosted.org/packages/df/f8/c80968ae01df23e249ee0a4487fae55a4c0fe2f838dfe9cc907aa8aea0fa/numpy-2.2.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1ad395cf254c4fbb5b2132fee391f361a6e8c1adbd28f2cd8e79308a615fe9d", size = 16076211 }, + { url = "https://files.pythonhosted.org/packages/09/69/05c169376016a0b614b432967ac46ff14269eaffab80040ec03ae1ae8e2c/numpy-2.2.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:08ef779aed40dbc52729d6ffe7dd51df85796a702afbf68a4f4e41fafdc8bda5", size = 15220266 }, + { url = "https://files.pythonhosted.org/packages/f1/ff/94a4ce67ea909f41cf7ea712aebbe832dc67decad22944a1020bb398a5ee/numpy-2.2.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:26c9c4382b19fcfbbed3238a14abf7ff223890ea1936b8890f058e7ba35e8d71", size = 17852844 }, + { url = "https://files.pythonhosted.org/packages/46/72/8a5dbce4020dfc595592333ef2fbb0a187d084ca243b67766d29d03e0096/numpy-2.2.1-cp313-cp313t-win32.whl", hash = "sha256:93cf4e045bae74c90ca833cba583c14b62cb4ba2cba0abd2b141ab52548247e2", size = 6326007 }, + { url = "https://files.pythonhosted.org/packages/7b/9c/4fce9cf39dde2562584e4cfd351a0140240f82c0e3569ce25a250f47037d/numpy-2.2.1-cp313-cp313t-win_amd64.whl", hash = "sha256:bff7d8ec20f5f42607599f9994770fa65d76edca264a87b5e4ea5629bce12268", size = 12693107 }, +] + +[[package]] +name = "packaging" +version = "24.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 }, +] + +[[package]] +name = "pandas" +version = "2.2.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "python-dateutil" }, + { name = "pytz" }, + { name = "tzdata" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9c/d6/9f8431bacc2e19dca897724cd097b1bb224a6ad5433784a44b587c7c13af/pandas-2.2.3.tar.gz", hash = "sha256:4f18ba62b61d7e192368b84517265a99b4d7ee8912f8708660fb4a366cc82667", size = 4399213 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/22/3b8f4e0ed70644e85cfdcd57454686b9057c6c38d2f74fe4b8bc2527214a/pandas-2.2.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f00d1345d84d8c86a63e476bb4955e46458b304b9575dcf71102b5c705320015", size = 12477643 }, + { url = "https://files.pythonhosted.org/packages/e4/93/b3f5d1838500e22c8d793625da672f3eec046b1a99257666c94446969282/pandas-2.2.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3508d914817e153ad359d7e069d752cdd736a247c322d932eb89e6bc84217f28", size = 11281573 }, + { url = "https://files.pythonhosted.org/packages/f5/94/6c79b07f0e5aab1dcfa35a75f4817f5c4f677931d4234afcd75f0e6a66ca/pandas-2.2.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22a9d949bfc9a502d320aa04e5d02feab689d61da4e7764b62c30b991c42c5f0", size = 15196085 }, + { url = "https://files.pythonhosted.org/packages/e8/31/aa8da88ca0eadbabd0a639788a6da13bb2ff6edbbb9f29aa786450a30a91/pandas-2.2.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3a255b2c19987fbbe62a9dfd6cff7ff2aa9ccab3fc75218fd4b7530f01efa24", size = 12711809 }, + { url = "https://files.pythonhosted.org/packages/ee/7c/c6dbdb0cb2a4344cacfb8de1c5808ca885b2e4dcfde8008266608f9372af/pandas-2.2.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:800250ecdadb6d9c78eae4990da62743b857b470883fa27f652db8bdde7f6659", size = 16356316 }, + { url = "https://files.pythonhosted.org/packages/57/b7/8b757e7d92023b832869fa8881a992696a0bfe2e26f72c9ae9f255988d42/pandas-2.2.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6374c452ff3ec675a8f46fd9ab25c4ad0ba590b71cf0656f8b6daa5202bca3fb", size = 14022055 }, + { url = "https://files.pythonhosted.org/packages/3b/bc/4b18e2b8c002572c5a441a64826252ce5da2aa738855747247a971988043/pandas-2.2.3-cp313-cp313-win_amd64.whl", hash = "sha256:61c5ad4043f791b61dd4752191d9f07f0ae412515d59ba8f005832a532f8736d", size = 11481175 }, + { url = "https://files.pythonhosted.org/packages/76/a3/a5d88146815e972d40d19247b2c162e88213ef51c7c25993942c39dbf41d/pandas-2.2.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3b71f27954685ee685317063bf13c7709a7ba74fc996b84fc6821c59b0f06468", size = 12615650 }, + { url = "https://files.pythonhosted.org/packages/9c/8c/f0fd18f6140ddafc0c24122c8a964e48294acc579d47def376fef12bcb4a/pandas-2.2.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:38cf8125c40dae9d5acc10fa66af8ea6fdf760b2714ee482ca691fc66e6fcb18", size = 11290177 }, + { url = "https://files.pythonhosted.org/packages/ed/f9/e995754eab9c0f14c6777401f7eece0943840b7a9fc932221c19d1abee9f/pandas-2.2.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ba96630bc17c875161df3818780af30e43be9b166ce51c9a18c1feae342906c2", size = 14651526 }, + { url = "https://files.pythonhosted.org/packages/25/b0/98d6ae2e1abac4f35230aa756005e8654649d305df9a28b16b9ae4353bff/pandas-2.2.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1db71525a1538b30142094edb9adc10be3f3e176748cd7acc2240c2f2e5aa3a4", size = 11871013 }, + { url = "https://files.pythonhosted.org/packages/cc/57/0f72a10f9db6a4628744c8e8f0df4e6e21de01212c7c981d31e50ffc8328/pandas-2.2.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:15c0e1e02e93116177d29ff83e8b1619c93ddc9c49083f237d4312337a61165d", size = 15711620 }, + { url = "https://files.pythonhosted.org/packages/ab/5f/b38085618b950b79d2d9164a711c52b10aefc0ae6833b96f626b7021b2ed/pandas-2.2.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ad5b65698ab28ed8d7f18790a0dc58005c7629f227be9ecc1072aa74c0c1d43a", size = 13098436 }, +] + +[[package]] +name = "pigpio" +version = "1.78" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/4a/3ebdfd90906553fb5420e80a475eb52f0809f2a29b547ba3b260db0cbc8f/pigpio-1.78.tar.gz", hash = "sha256:91efa50e4990649da97408a384782d6ccf58342fc59cdfe21ed7a42911569975", size = 40738 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/a0/991ac7f96f83936c15f4b26b51d1fdba63e7bc9866411bfda022b649c2a7/pigpio-1.78-py2.py3-none-any.whl", hash = "sha256:81e46f640c4e6342881fa9bbe290dbcd4fc179619dc6591e57a9d4a084dc49fa", size = 39622 }, +] + +[[package]] +name = "platformdirs" +version = "4.3.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/fc/128cc9cb8f03208bdbf93d3aa862e16d376844a14f9a0ce5cf4507372de4/platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", size = 21302 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/a6/bc1012356d8ece4d66dd75c4b9fc6c1f6650ddd5991e421177d9f8f671be/platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb", size = 18439 }, +] + +[[package]] +name = "pluggy" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, +] + +[[package]] +name = "pre-commit" +version = "4.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2e/c8/e22c292035f1bac8b9f5237a2622305bc0304e776080b246f3df57c4ff9f/pre_commit-4.0.1.tar.gz", hash = "sha256:80905ac375958c0444c65e9cebebd948b3cdb518f335a091a670a89d652139d2", size = 191678 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/16/8f/496e10d51edd6671ebe0432e33ff800aa86775d2d147ce7d43389324a525/pre_commit-4.0.1-py2.py3-none-any.whl", hash = "sha256:efde913840816312445dc98787724647c65473daefe420785f885e8ed9a06878", size = 218713 }, +] + +[[package]] +name = "psutil" +version = "6.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1f/5a/07871137bb752428aa4b659f910b399ba6f291156bdea939be3e96cae7cb/psutil-6.1.1.tar.gz", hash = "sha256:cf8496728c18f2d0b45198f06895be52f36611711746b7f30c464b422b50e2f5", size = 508502 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/61/99/ca79d302be46f7bdd8321089762dd4476ee725fce16fc2b2e1dbba8cac17/psutil-6.1.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:fc0ed7fe2231a444fc219b9c42d0376e0a9a1a72f16c5cfa0f68d19f1a0663e8", size = 247511 }, + { url = "https://files.pythonhosted.org/packages/0b/6b/73dbde0dd38f3782905d4587049b9be64d76671042fdcaf60e2430c6796d/psutil-6.1.1-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0bdd4eab935276290ad3cb718e9809412895ca6b5b334f5a9111ee6d9aff9377", size = 248985 }, + { url = "https://files.pythonhosted.org/packages/17/38/c319d31a1d3f88c5b79c68b3116c129e5133f1822157dd6da34043e32ed6/psutil-6.1.1-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6e06c20c05fe95a3d7302d74e7097756d4ba1247975ad6905441ae1b5b66003", size = 284488 }, + { url = "https://files.pythonhosted.org/packages/9c/39/0f88a830a1c8a3aba27fededc642da37613c57cbff143412e3536f89784f/psutil-6.1.1-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97f7cb9921fbec4904f522d972f0c0e1f4fabbdd4e0287813b21215074a0f160", size = 287477 }, + { url = "https://files.pythonhosted.org/packages/47/da/99f4345d4ddf2845cb5b5bd0d93d554e84542d116934fde07a0c50bd4e9f/psutil-6.1.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33431e84fee02bc84ea36d9e2c4a6d395d479c9dd9bba2376c1f6ee8f3a4e0b3", size = 289017 }, + { url = "https://files.pythonhosted.org/packages/38/53/bd755c2896f4461fd4f36fa6a6dcb66a88a9e4b9fd4e5b66a77cf9d4a584/psutil-6.1.1-cp37-abi3-win32.whl", hash = "sha256:eaa912e0b11848c4d9279a93d7e2783df352b082f40111e078388701fd479e53", size = 250602 }, + { url = "https://files.pythonhosted.org/packages/7b/d7/7831438e6c3ebbfa6e01a927127a6cb42ad3ab844247f3c5b96bea25d73d/psutil-6.1.1-cp37-abi3-win_amd64.whl", hash = "sha256:f35cfccb065fff93529d2afb4a2e89e363fe63ca1e4a5da22b603a85833c2649", size = 254444 }, +] + +[[package]] +name = "pytest" +version = "8.3.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/05/35/30e0d83068951d90a01852cb1cef56e5d8a09d20c7f511634cc2f7e0372a/pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761", size = 1445919 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/11/92/76a1c94d3afee238333bc0a42b82935dd8f9cf8ce9e336ff87ee14d9e1cf/pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", size = 343083 }, +] + +[[package]] +name = "pytest-cov" +version = "6.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coverage" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/be/45/9b538de8cef30e17c7b45ef42f538a94889ed6a16f2387a6c89e73220651/pytest-cov-6.0.0.tar.gz", hash = "sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0", size = 66945 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/3b/48e79f2cd6a61dbbd4807b4ed46cb564b4fd50a76166b1c4ea5c1d9e2371/pytest_cov-6.0.0-py3-none-any.whl", hash = "sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35", size = 22949 }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 }, +] + +[[package]] +name = "pytz" +version = "2024.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3a/31/3c70bf7603cc2dca0f19bdc53b4537a797747a58875b552c8c413d963a3f/pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a", size = 319692 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/11/c3/005fcca25ce078d2cc29fd559379817424e94885510568bc1bc53d7d5846/pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725", size = 508002 }, +] + +[[package]] +name = "pyyaml" +version = "6.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309 }, + { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679 }, + { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428 }, + { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361 }, + { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523 }, + { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660 }, + { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597 }, + { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527 }, + { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 }, +] + +[[package]] +name = "ruff" +version = "0.8.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/34/37/9c02181ef38d55b77d97c68b78e705fd14c0de0e5d085202bb2b52ce5be9/ruff-0.8.4.tar.gz", hash = "sha256:0d5f89f254836799af1615798caa5f80b7f935d7a670fad66c5007928e57ace8", size = 3402103 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/05/67/f480bf2f2723b2e49af38ed2be75ccdb2798fca7d56279b585c8f553aaab/ruff-0.8.4-py3-none-linux_armv6l.whl", hash = "sha256:58072f0c06080276804c6a4e21a9045a706584a958e644353603d36ca1eb8a60", size = 10546415 }, + { url = "https://files.pythonhosted.org/packages/eb/7a/5aba20312c73f1ce61814e520d1920edf68ca3b9c507bd84d8546a8ecaa8/ruff-0.8.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ffb60904651c00a1e0b8df594591770018a0f04587f7deeb3838344fe3adabac", size = 10346113 }, + { url = "https://files.pythonhosted.org/packages/76/f4/c41de22b3728486f0aa95383a44c42657b2db4062f3234ca36fc8cf52d8b/ruff-0.8.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:6ddf5d654ac0d44389f6bf05cee4caeefc3132a64b58ea46738111d687352296", size = 9943564 }, + { url = "https://files.pythonhosted.org/packages/0e/f0/afa0d2191af495ac82d4cbbfd7a94e3df6f62a04ca412033e073b871fc6d/ruff-0.8.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e248b1f0fa2749edd3350a2a342b67b43a2627434c059a063418e3d375cfe643", size = 10805522 }, + { url = "https://files.pythonhosted.org/packages/12/57/5d1e9a0fd0c228e663894e8e3a8e7063e5ee90f8e8e60cf2085f362bfa1a/ruff-0.8.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bf197b98ed86e417412ee3b6c893f44c8864f816451441483253d5ff22c0e81e", size = 10306763 }, + { url = "https://files.pythonhosted.org/packages/04/df/f069fdb02e408be8aac6853583572a2873f87f866fe8515de65873caf6b8/ruff-0.8.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c41319b85faa3aadd4d30cb1cffdd9ac6b89704ff79f7664b853785b48eccdf3", size = 11359574 }, + { url = "https://files.pythonhosted.org/packages/d3/04/37c27494cd02e4a8315680debfc6dfabcb97e597c07cce0044db1f9dfbe2/ruff-0.8.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:9f8402b7c4f96463f135e936d9ab77b65711fcd5d72e5d67597b543bbb43cf3f", size = 12094851 }, + { url = "https://files.pythonhosted.org/packages/81/b1/c5d7fb68506cab9832d208d03ea4668da9a9887a4a392f4f328b1bf734ad/ruff-0.8.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4e56b3baa9c23d324ead112a4fdf20db9a3f8f29eeabff1355114dd96014604", size = 11655539 }, + { url = "https://files.pythonhosted.org/packages/ef/38/8f8f2c8898dc8a7a49bc340cf6f00226917f0f5cb489e37075bcb2ce3671/ruff-0.8.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:736272574e97157f7edbbb43b1d046125fce9e7d8d583d5d65d0c9bf2c15addf", size = 12912805 }, + { url = "https://files.pythonhosted.org/packages/06/dd/fa6660c279f4eb320788876d0cff4ea18d9af7d9ed7216d7bd66877468d0/ruff-0.8.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5fe710ab6061592521f902fca7ebcb9fabd27bc7c57c764298b1c1f15fff720", size = 11205976 }, + { url = "https://files.pythonhosted.org/packages/a8/d7/de94cc89833b5de455750686c17c9e10f4e1ab7ccdc5521b8fe911d1477e/ruff-0.8.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:13e9ec6d6b55f6da412d59953d65d66e760d583dd3c1c72bf1f26435b5bfdbae", size = 10792039 }, + { url = "https://files.pythonhosted.org/packages/6d/15/3e4906559248bdbb74854af684314608297a05b996062c9d72e0ef7c7097/ruff-0.8.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:97d9aefef725348ad77d6db98b726cfdb075a40b936c7984088804dfd38268a7", size = 10400088 }, + { url = "https://files.pythonhosted.org/packages/a2/21/9ed4c0e8133cb4a87a18d470f534ad1a8a66d7bec493bcb8bda2d1a5d5be/ruff-0.8.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ab78e33325a6f5374e04c2ab924a3367d69a0da36f8c9cb6b894a62017506111", size = 10900814 }, + { url = "https://files.pythonhosted.org/packages/0d/5d/122a65a18955bd9da2616b69bc839351f8baf23b2805b543aa2f0aed72b5/ruff-0.8.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:8ef06f66f4a05c3ddbc9121a8b0cecccd92c5bf3dd43b5472ffe40b8ca10f0f8", size = 11268828 }, + { url = "https://files.pythonhosted.org/packages/43/a9/1676ee9106995381e3d34bccac5bb28df70194167337ed4854c20f27c7ba/ruff-0.8.4-py3-none-win32.whl", hash = "sha256:552fb6d861320958ca5e15f28b20a3d071aa83b93caee33a87b471f99a6c0835", size = 8805621 }, + { url = "https://files.pythonhosted.org/packages/10/98/ed6b56a30ee76771c193ff7ceeaf1d2acc98d33a1a27b8479cbdb5c17a23/ruff-0.8.4-py3-none-win_amd64.whl", hash = "sha256:f21a1143776f8656d7f364bd264a9d60f01b7f52243fbe90e7670c0dfe0cf65d", size = 9660086 }, + { url = "https://files.pythonhosted.org/packages/13/9f/026e18ca7d7766783d779dae5e9c656746c6ede36ef73c6d934aaf4a6dec/ruff-0.8.4-py3-none-win_arm64.whl", hash = "sha256:9183dd615d8df50defa8b1d9a074053891ba39025cf5ae88e8bcb52edcc4bf08", size = 9074500 }, +] + +[[package]] +name = "scipy" +version = "1.14.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/62/11/4d44a1f274e002784e4dbdb81e0ea96d2de2d1045b2132d5af62cc31fd28/scipy-1.14.1.tar.gz", hash = "sha256:5a275584e726026a5699459aa72f828a610821006228e841b94275c4a7c08417", size = 58620554 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/50/ef/ac98346db016ff18a6ad7626a35808f37074d25796fd0234c2bb0ed1e054/scipy-1.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1729560c906963fc8389f6aac023739ff3983e727b1a4d87696b7bf108316a79", size = 39091068 }, + { url = "https://files.pythonhosted.org/packages/b9/cc/70948fe9f393b911b4251e96b55bbdeaa8cca41f37c26fd1df0232933b9e/scipy-1.14.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:4079b90df244709e675cdc8b93bfd8a395d59af40b72e339c2287c91860deb8e", size = 29875417 }, + { url = "https://files.pythonhosted.org/packages/3b/2e/35f549b7d231c1c9f9639f9ef49b815d816bf54dd050da5da1c11517a218/scipy-1.14.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e0cf28db0f24a38b2a0ca33a85a54852586e43cf6fd876365c86e0657cfe7d73", size = 23084508 }, + { url = "https://files.pythonhosted.org/packages/3f/d6/b028e3f3e59fae61fb8c0f450db732c43dd1d836223a589a8be9f6377203/scipy-1.14.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:0c2f95de3b04e26f5f3ad5bb05e74ba7f68b837133a4492414b3afd79dfe540e", size = 25503364 }, + { url = "https://files.pythonhosted.org/packages/a7/2f/6c142b352ac15967744d62b165537a965e95d557085db4beab2a11f7943b/scipy-1.14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b99722ea48b7ea25e8e015e8341ae74624f72e5f21fc2abd45f3a93266de4c5d", size = 35292639 }, + { url = "https://files.pythonhosted.org/packages/56/46/2449e6e51e0d7c3575f289f6acb7f828938eaab8874dbccfeb0cd2b71a27/scipy-1.14.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5149e3fd2d686e42144a093b206aef01932a0059c2a33ddfa67f5f035bdfe13e", size = 40798288 }, + { url = "https://files.pythonhosted.org/packages/32/cd/9d86f7ed7f4497c9fd3e39f8918dd93d9f647ba80d7e34e4946c0c2d1a7c/scipy-1.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4f5a7c49323533f9103d4dacf4e4f07078f360743dec7f7596949149efeec06", size = 42524647 }, + { url = "https://files.pythonhosted.org/packages/f5/1b/6ee032251bf4cdb0cc50059374e86a9f076308c1512b61c4e003e241efb7/scipy-1.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:baff393942b550823bfce952bb62270ee17504d02a1801d7fd0719534dfb9c84", size = 44469524 }, +] + +[[package]] +name = "setuptools" +version = "75.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/54/292f26c208734e9a7f067aea4a7e282c080750c4546559b58e2e45413ca0/setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6", size = 1337429 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/55/21/47d163f615df1d30c094f6c8bbb353619274edccf0327b185cc2493c2c33/setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d", size = 1224032 }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 }, +] + +[[package]] +name = "tzdata" +version = "2024.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e1/34/943888654477a574a86a98e9896bae89c7aa15078ec29f490fef2f1e5384/tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc", size = 193282 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a6/ab/7e5f53c3b9d14972843a647d8d7a853969a58aecc7559cb3267302c94774/tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd", size = 346586 }, +] + +[[package]] +name = "virtualenv" +version = "20.28.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "distlib" }, + { name = "filelock" }, + { name = "platformdirs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bf/75/53316a5a8050069228a2f6d11f32046cfa94fbb6cc3f08703f59b873de2e/virtualenv-20.28.0.tar.gz", hash = "sha256:2c9c3262bb8e7b87ea801d715fae4495e6032450c71d2309be9550e7364049aa", size = 7650368 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/f9/0919cf6f1432a8c4baa62511f8f8da8225432d22e83e3476f5be1a1edc6e/virtualenv-20.28.0-py3-none-any.whl", hash = "sha256:23eae1b4516ecd610481eda647f3a7c09aea295055337331bb4e6892ecce47b0", size = 4276702 }, +] From 5e89cd340c73b6d14c87e8937ab3c6b4de55aed4 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Thu, 2 Jan 2025 15:24:20 +0400 Subject: [PATCH 07/12] try something to get uvx one liner working --- airbrakes/main.py | 5 +++++ pyproject.toml | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/airbrakes/main.py b/airbrakes/main.py index 1bd79b78..dc8ee2bf 100644 --- a/airbrakes/main.py +++ b/airbrakes/main.py @@ -3,9 +3,11 @@ import argparse import time +from pathlib import Path from gpiozero.pins.mock import MockFactory, MockPWMPin +import airbrakes from airbrakes.airbrakes import AirbrakesContext from airbrakes.constants import IMU_PORT, LOGS_PATH, SERVO_PIN from airbrakes.data_handling.apogee_predictor import ApogeePredictor @@ -31,6 +33,9 @@ def run_mock_flight() -> None: `uvx mock` or `uv run mock`.""" args = arg_parser() args.mock = True + print(Path().cwd()) + print(airbrakes.__file__) + print(airbrakes.__path__) run_flight(args) diff --git a/pyproject.toml b/pyproject.toml index 56dbf377..f49041d9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,6 +3,7 @@ name = "AirbrakesV2" description = "Logic for airbrakes as a part of the NASA Student Launch Competition" requires-python = ">=3.13" version = "0.1.0" +readme = "README.md" dependencies = [ "gpiozero", "pigpio", # Run sudo pigpiod before running the program @@ -36,6 +37,13 @@ build-backend = "hatchling.build" # HATCH: [tool.hatch.build.targets.wheel] packages = ["airbrakes"] +include = [ + "launch_data/genesis_launch_1.csv" +] +[tool.hatch.build.targets.sdist] +include = [ + "launch_data/genesis_launch_1.csv" +] # RUFF: [tool.ruff] From c1d30378fa477e04a4c74d373676a392b8d7ecf5 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Thu, 2 Jan 2025 16:32:34 +0400 Subject: [PATCH 08/12] Get the uvx one liner working --- airbrakes/main.py | 5 ----- airbrakes/mock/mock_imu.py | 5 ++++- pyproject.toml | 11 ++++------- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/airbrakes/main.py b/airbrakes/main.py index dc8ee2bf..1bd79b78 100644 --- a/airbrakes/main.py +++ b/airbrakes/main.py @@ -3,11 +3,9 @@ import argparse import time -from pathlib import Path from gpiozero.pins.mock import MockFactory, MockPWMPin -import airbrakes from airbrakes.airbrakes import AirbrakesContext from airbrakes.constants import IMU_PORT, LOGS_PATH, SERVO_PIN from airbrakes.data_handling.apogee_predictor import ApogeePredictor @@ -33,9 +31,6 @@ def run_mock_flight() -> None: `uvx mock` or `uv run mock`.""" args = arg_parser() args.mock = True - print(Path().cwd()) - print(airbrakes.__file__) - print(airbrakes.__path__) run_flight(args) diff --git a/airbrakes/mock/mock_imu.py b/airbrakes/mock/mock_imu.py index 511743f6..c41b4666 100644 --- a/airbrakes/mock/mock_imu.py +++ b/airbrakes/mock/mock_imu.py @@ -61,7 +61,10 @@ def __init__( # Check if the launch data file exists: if log_file_path is None: # Just use the first file in the `launch_data` directory: - self._log_file_path = next(iter(Path("launch_data").glob("*.csv"))) + # Note: We do this convoluted way because we want to make it work with the one liner + # `uvx --from git+... mock` on any machine from any state. + root_dir = Path(__file__).parent.parent.parent + self._log_file_path = next(iter(Path(root_dir / "launch_data").glob("*.csv"))) # If it's not a real time sim, we limit how big the queue gets when doing an integration # test, because we read the file much faster than update(), sometimes resulting thousands diff --git a/pyproject.toml b/pyproject.toml index f49041d9..d7c27434 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,13 +37,10 @@ build-backend = "hatchling.build" # HATCH: [tool.hatch.build.targets.wheel] packages = ["airbrakes"] -include = [ - "launch_data/genesis_launch_1.csv" -] -[tool.hatch.build.targets.sdist] -include = [ - "launch_data/genesis_launch_1.csv" -] + +[tool.hatch.build.targets.wheel.force-include] +# specify one launch file so that the mock flight can be run as a demo with uvx. +"launch_data/genesis_launch_1.csv" = "/launch_data/genesis_launch_1.csv" # RUFF: [tool.ruff] From 093cbfa49a7cd43fa8d653eb8c18bc35c09c8128 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Thu, 2 Jan 2025 16:43:47 +0400 Subject: [PATCH 09/12] Adjust arg parsing handling for mock invocation --- airbrakes/main.py | 5 ++--- airbrakes/utils.py | 7 +++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/airbrakes/main.py b/airbrakes/main.py index 1bd79b78..3431b92d 100644 --- a/airbrakes/main.py +++ b/airbrakes/main.py @@ -29,8 +29,7 @@ def run_real_flight() -> None: def run_mock_flight() -> None: """Entry point for the application to run the mock flight. Entered when run with `uvx mock` or `uv run mock`.""" - args = arg_parser() - args.mock = True + args = arg_parser(mock_invocation=True) run_flight(args) @@ -53,7 +52,7 @@ def create_components( Creates the system components needed for the airbrakes system. Depending on its arguments, it will return either mock or real components. :param args: Command line arguments determining the configuration. - :return: A tuple containing the servo, IMU, and logger objects. + :return: A tuple containing the servo, IMU, Logger, data processor, and apogee predictor objects """ if args.mock: # Replace hardware with mock objects for simulation diff --git a/airbrakes/utils.py b/airbrakes/utils.py index 778c7a4a..4e0036fb 100644 --- a/airbrakes/utils.py +++ b/airbrakes/utils.py @@ -76,9 +76,12 @@ def deadband(input_value: float, threshold: float) -> float: return input_value -def arg_parser() -> argparse.Namespace: +def arg_parser(mock_invocation: bool = False) -> argparse.Namespace: """Handles the command line arguments for the main airbrakes script. + :param mock_invocation: Whether the application is running in mock mode from `uv run mock`. + Defaults to False, to keep compatibility with the `python -m airbrakes.main` invocation method. + :return: The parsed arguments as a class with attributes. """ @@ -92,7 +95,7 @@ def arg_parser() -> argparse.Namespace: "--mock", help="Run in simulation mode with mock data and mock servo", action="store_true", - default=False, + default=mock_invocation, ) parser.add_argument( From 5cc3e459462e48201459b77e88dae5b3d20f72b1 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Thu, 2 Jan 2025 16:48:44 +0400 Subject: [PATCH 10/12] Adjust docs --- README.md | 2 ++ airbrakes/main.py | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e9349d0b..c0c0d85d 100644 --- a/README.md +++ b/README.md @@ -153,6 +153,8 @@ AirbrakesV2/ │ ├── ... ├── logs/ [log files made by the logger] │ ├── ... +├── launch_data/ [real flight data collected from the rocket] +│ ├── ... ├── scripts/ [small files to test individual components like the servo] │ ├── ... ├── pyproject.toml [configuration file for the project] diff --git a/airbrakes/main.py b/airbrakes/main.py index 3431b92d..5aabb5e2 100644 --- a/airbrakes/main.py +++ b/airbrakes/main.py @@ -21,14 +21,14 @@ def run_real_flight() -> None: """Entry point for the application to run the real flight. Entered when run with - `uv run real` or `uvx real`.""" + `uv run real` or `uvx --from git+... real`.""" args = arg_parser() run_flight(args) def run_mock_flight() -> None: """Entry point for the application to run the mock flight. Entered when run with - `uvx mock` or `uv run mock`.""" + `uvx --from git+... mock` or `uv run mock`.""" args = arg_parser(mock_invocation=True) run_flight(args) @@ -122,9 +122,9 @@ def run_flight_loop( # Command line args (after these are run, you can press Ctrl+C to exit the program): # python -m airbrakes.main -v: Shows the display with much more data # python -m airbrakes.main -m: Runs a simulation on your computer - # python -m airbrakes.main -r: Runs a simulation on your computer with the real servo - # python -m airbrakes.main -l: Runs a simulation on your computer and keeps the log file after - # the simulation stops + # python -m airbrakes.main -m -r: Runs a simulation on your computer with the real servo + # python -m airbrakes.main -m -l: Runs a simulation on your computer and keeps the log file + # after the simulation stops # python -m airbrakes.main -m -f: Runs a simulation on your computer at full speed # python -m airbrakes.main -m -d: Runs a simulation on your computer in debug mode (w/o display) args = arg_parser() From 6747099f7776816c8ac51fec7070ed1d1b1d9750 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Thu, 2 Jan 2025 17:04:58 +0400 Subject: [PATCH 11/12] Make CI use uv --- .github/workflows/integration_tests.yml | 20 ++++++++------------ .github/workflows/unit_tests.yml | 25 +++++++++++-------------- 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml index 6df0373e..178e72a4 100644 --- a/.github/workflows/integration_tests.yml +++ b/.github/workflows/integration_tests.yml @@ -15,28 +15,24 @@ jobs: timeout-minutes: 5 strategy: matrix: - python-version: ['3.13'] os: [ubuntu-latest, windows-latest] fail-fast: False steps: - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} + - name: Install uv + uses: astral-sh/setup-uv@v5 + + - name: Set up Python uses: actions/setup-python@v5 with: - python-version: ${{ matrix.python-version }} - cache: 'pip' - cache-dependency-path: '**/requirements*.txt' + python-version-file: "pyproject.toml" - - name: Install dependencies - run: | - python -W ignore -m pip install --upgrade pip - python -W ignore -m pip install . - python -W ignore -m pip install .[dev] - pip install pytest + - name: Install the project + run: uv sync - name: Run integration tests timeout-minutes: 3 run: | - pytest -v tests/test_integration.py \ No newline at end of file + uv run pytest -v tests/test_integration.py \ No newline at end of file diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 7776ce21..2559aaa6 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -11,31 +11,28 @@ jobs: pytest: name: pytest - runs-on: ${{matrix.os}} + runs-on: ubuntu-latest timeout-minutes: 5 strategy: - matrix: - python-version: ['3.13'] - os: [ubuntu-latest] fail-fast: False steps: - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} + + - name: Install uv + uses: astral-sh/setup-uv@v5 + + - name: Set up Python uses: actions/setup-python@v5 with: - python-version: ${{ matrix.python-version }} - cache: 'pip' - cache-dependency-path: '**/requirements*.txt' - - name: Install dependencies - run: | - python -W ignore -m pip install --upgrade pip - python -W ignore -m pip install . - python -W ignore -m pip install .[dev] + python-version-file: "pyproject.toml" + + - name: Install the project + run: uv sync - name: Run tests with coverage run: | # Run tests with coverage except for the integration tests - pytest --cov=airbrakes --cov-report=term --cov-report=html --ignore=tests/test_integration.py -v tests/ + uv run pytest --cov=airbrakes --cov-report=term --cov-report=html --ignore=tests/test_integration.py -v tests/ # Add this new step to upload the coverage report as an artifact - name: Upload coverage report From 9392a69e9499fa92301b56efe4d7152f2c5af440 Mon Sep 17 00:00:00 2001 From: wlsanderson Date: Wed, 8 Jan 2025 17:08:41 -0500 Subject: [PATCH 12/12] readme update --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c0c0d85d..302ae685 100644 --- a/README.md +++ b/README.md @@ -200,7 +200,7 @@ _Note 2: The more "correct" command to run is `uv sync`. This will install the p ### 3. Install the pre-commit hook: ``` -pre-commit install +uv run pre-commit install ``` This will install a pre-commit hook that will run the linter before you commit your changes. @@ -244,9 +244,11 @@ _Note: Unit tests do not work on Windows (only `test_integration.py` will work). To run the tests, run this command from the project root directory: ```bash -pytest +uv run pytest ``` +If your virtual environment is activated, you can simply run the tests with `pytest` + To generate a coverage report from the tests: ```bash pytest --cov=airbrakes --cov-report=term