Skip to content

Commit bd103d2

Browse files
committed
Merge branch 'charles/textual-gs-cli' of github.com:UWOrbital/OBC-firmware into charles/textual-gs-cli
2 parents a2dfe9c + 02b2873 commit bd103d2

File tree

125 files changed

+98924
-6744
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

125 files changed

+98924
-6744
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: Auto Milestone Management
2+
on:
3+
pull_request:
4+
branches:
5+
- main
6+
types:
7+
- closed
8+
9+
permissions:
10+
issues: write
11+
pull-requests: write
12+
13+
jobs:
14+
add-milestone:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- name: Add milestone on PR merge
18+
if: github.event.pull_request.merged == true
19+
uses: actions/github-script@v8
20+
with:
21+
script: |
22+
const date = new Date();
23+
const month = date.getMonth() + 1;
24+
const year = date.getFullYear();
25+
const yy = String(year % 100);
26+
27+
let term;
28+
if (month <= 4) term = "W";
29+
else if (month >= 9) term = "F";
30+
else term = "S";
31+
32+
const format = yy + term;
33+
34+
const { data: milestones } = await github.rest.issues.listMilestones({
35+
owner: context.repo.owner,
36+
repo: context.repo.repo,
37+
state: "open"
38+
});
39+
40+
let milestone = null;
41+
for (let i = 0; i < milestones.length; i++) {
42+
if (milestones[i].title == format) {
43+
milestone = milestones[i];
44+
break;
45+
}
46+
}
47+
48+
if (!milestone) {
49+
const { data: new_milestone } = await github.rest.issues.createMilestone({
50+
owner: context.repo.owner,
51+
repo: context.repo.repo,
52+
title: format
53+
});
54+
milestone = new_milestone;
55+
}
56+
57+
await github.rest.issues.update({
58+
owner: context.repo.owner,
59+
repo: context.repo.repo,
60+
issue_number: context.payload.pull_request.number,
61+
milestone: milestone.number
62+
});

.github/workflows/pr_stats.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
with:
1212
token: ${{ secrets.ADD_A_PERSONAL_ACCESS_TOKEN }}
1313
period: 120
14-
chats: true
14+
charts: true
1515
disable-links: false
1616
sort-by: 'REVIEWS'
1717
organization: 'UWOrbital'

.github/workflows/pytest.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,26 @@ jobs:
3030
pip install -r requirements.txt
3131
pip install -e .
3232
33+
- name: Set up PostgreSQL database
34+
run: |
35+
sudo service postgresql start
36+
sudo -u postgres psql -c "CREATE USER ci_user WITH PASSWORD 'ci_password' SUPERUSER;"
37+
sudo -u postgres psql -c "CREATE DATABASE gs;"
38+
39+
- name: Create CI .env file
40+
run: |
41+
cat > .env << EOF
42+
GS_DATABASE_USER=ci_user
43+
GS_DATABASE_PASSWORD=ci_password
44+
GS_DATABASE_LOCATION=localhost
45+
GS_DATABASE_PORT=5432
46+
GS_DATABASE_NAME=gs
47+
EOF
48+
49+
- name: Run Alembic migrations
50+
run: |
51+
alembic upgrade head
52+
3353
- name: Create binary directory
3454
run: |
3555
mkdir build_gs
@@ -42,5 +62,11 @@ jobs:
4262
cmake --build .
4363
4464
- name: Run pytest
65+
env:
66+
GS_DATABASE_USER: ci_user
67+
GS_DATABASE_PASSWORD: ci_password
68+
GS_DATABASE_LOCATION: localhost
69+
GS_DATABASE_PORT: 5432
70+
GS_DATABASE_NAME: gs
4571
run: |
4672
python -m pytest

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ compile_commands.json
6464
*.sw?
6565

6666
.env
67+
.*.env
6768
*.db
6869

6970
/build*
@@ -102,3 +103,5 @@ lerna-debug.log*
102103
*dist-ssr
103104
*.local
104105
*.vite
106+
107+
.DS_Store

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ repos:
99
- id: end-of-file-fixer
1010
exclude: '((libs|hal)/.*|\.(ts|tsx|css|html|json|md|yaml|yml|ipynb)$)'
1111
- id: check-added-large-files
12-
exclude: "(libs|hal)/.*"
12+
exclude: "(libs|hal)/.*|gs/backend/data/resources/callsigns\\.csv$"
1313
- repo: https://github.com/pre-commit/mirrors-clang-format
1414
rev: v17.0.6
1515
hooks:

Dockerfile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ FROM python:3.11-slim
33
WORKDIR /app
44
COPY requirements.txt /app/
55
COPY /gs/backend /app/
6+
RUN apt-get update && apt-get install -y gcc build-essential
67
RUN pip install -r requirements.txt
78
EXPOSE 8000
89

9-
CMD ["fastapi", "run", "gs/backend/main.py"]
10+
#CMD ["fastapi", "run", "gs/backend/main.py"]
11+
CMD ["uvicorn", "gs.backend.main:app", "--host", "0.0.0.0", "--port", "8000"]

alembic.ini

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# A generic, single database configuration.
2+
3+
[alembic]
4+
# path to migration scripts
5+
script_location = migrations
6+
7+
# template used to generate migration file names; The default value is %%(rev)s_%%(slug)s
8+
# Uncomment the line below if you want the files to be prepended with date and time
9+
# see https://alembic.sqlalchemy.org/en/latest/tutorial.html#editing-the-ini-file
10+
# for all available tokens
11+
# file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s
12+
13+
# sys.path path, will be prepended to sys.path if present.
14+
# defaults to the current working directory.
15+
prepend_sys_path = .
16+
17+
# timezone to use when rendering the date within the migration file
18+
# as well as the filename.
19+
# If specified, requires the python-dateutil library that can be
20+
# installed by adding `alembic[tz]` to the pip requirements
21+
# string value is passed to dateutil.tz.gettz()
22+
# leave blank for localtime
23+
# timezone =
24+
25+
# max length of characters to apply to the
26+
# "slug" field
27+
# truncate_slug_length = 40
28+
29+
# set to 'true' to run the environment during
30+
# the 'revision' command, regardless of autogenerate
31+
# revision_environment = false
32+
33+
# set to 'true' to allow .pyc and .pyo files without
34+
# a source .py file to be detected as revisions in the
35+
# versions/ directory
36+
# sourceless = false
37+
38+
# version location specification; This defaults
39+
# to migrations/versions. When using multiple version
40+
# directories, initial revisions must be specified with --version-path.
41+
# The path separator used here should be the separator specified by "version_path_separator" below.
42+
# version_locations = %(here)s/bar:%(here)s/bat:migrations/versions
43+
44+
# version path separator; As mentioned above, this is the character used to split
45+
# version_locations. The default within new alembic.ini files is "os", which uses os.pathsep.
46+
# If this key is omitted entirely, it falls back to the legacy behavior of splitting on spaces and/or commas.
47+
# Valid values for version_path_separator are:
48+
#
49+
# version_path_separator = :
50+
# version_path_separator = ;
51+
# version_path_separator = space
52+
version_path_separator = os # Use os.pathsep. Default configuration used for new projects.
53+
54+
# set to 'true' to search source files recursively
55+
# in each "version_locations" directory
56+
# new in Alembic version 1.10
57+
# recursive_version_locations = false
58+
59+
# the output encoding used when revision files
60+
# are written from script.py.mako
61+
# output_encoding = utf-8
62+
63+
sqlalchemy.url = driver://user:pass@localhost/dbname
64+
65+
66+
[post_write_hooks]
67+
# post_write_hooks defines scripts or Python functions that are run
68+
# on newly generated revision scripts. See the documentation for further
69+
# detail and examples
70+
71+
# format using "black" - use the console_scripts runner, against the "black" entrypoint
72+
# hooks = black
73+
# black.type = console_scripts
74+
# black.entrypoint = black
75+
# black.options = -l 79 REVISION_SCRIPT_FILENAME
76+
77+
# Logging configuration
78+
[loggers]
79+
keys = root,sqlalchemy,alembic
80+
81+
[handlers]
82+
keys = console
83+
84+
[formatters]
85+
keys = generic
86+
87+
[logger_root]
88+
level = WARN
89+
handlers = console
90+
qualname =
91+
92+
[logger_sqlalchemy]
93+
level = WARN
94+
handlers =
95+
qualname = sqlalchemy.engine
96+
97+
[logger_alembic]
98+
level = INFO
99+
handlers =
100+
qualname = alembic
101+
102+
[handler_console]
103+
class = StreamHandler
104+
args = (sys.stderr,)
105+
level = NOTSET
106+
formatter = generic
107+
108+
[formatter_generic]
109+
format = %(levelname)-5.5s [%(name)s] %(message)s
110+
datefmt = %H:%M:%S

gs/backend/api/backend_setup.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
import logging
2+
13
from fastapi import FastAPI
4+
from loguru import logger
25

36
from gs.backend.api.middleware.auth_middleware import AuthMiddleware
47
from gs.backend.api.middleware.cors_middleware import add_cors_middleware
@@ -9,6 +12,7 @@
912
from gs.backend.api.v1.mcc.endpoints.commands import commands_router
1013
from gs.backend.api.v1.mcc.endpoints.main_commands import main_commands_router
1114
from gs.backend.api.v1.mcc.endpoints.telemetry import telemetry_router
15+
from gs.backend.config.config import backend_config
1216

1317

1418
def setup_routes(app: FastAPI) -> None:
@@ -32,4 +36,22 @@ def setup_middlewares(app: FastAPI) -> None:
3236
"""Adds the middlewares to the app"""
3337
add_cors_middleware(app) # Cors middleware should be added first
3438
app.add_middleware(AuthMiddleware)
35-
app.add_middleware(LoggerMiddleware, excluded_endpoints=[])
39+
app.add_middleware(
40+
LoggerMiddleware,
41+
excluded_endpoints=backend_config.logger_config.excluded_endpoints,
42+
)
43+
44+
45+
def setup_logging() -> None:
46+
"""Sets all logs from SQLAlchemy to the custom logger level VERBOSE"""
47+
verbose_level = 15 # DEBUG=10, INFO=20
48+
logger.level("VERBOSE", no=verbose_level, color="<blue>")
49+
50+
class SQLAlchemyHandler(logging.Handler):
51+
def emit(self, record: logging.LogRecord) -> None:
52+
logger.log("VERBOSE", record.getMessage())
53+
54+
sqlalchemy_logger = logging.getLogger("sqlalchemy.engine")
55+
sqlalchemy_logger.setLevel(logging.INFO)
56+
sqlalchemy_logger.addHandler(SQLAlchemyHandler())
57+
sqlalchemy_logger.propagate = False

gs/backend/api/lifespan.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,22 @@
22
from contextlib import asynccontextmanager
33

44
from fastapi import FastAPI
5+
from fastapi_cache import FastAPICache
6+
from fastapi_cache.backends.inmemory import InMemoryBackend
57

68
from gs.backend.data.database.engine import get_db_session, setup_database
7-
from gs.backend.data.resources.utils import add_main_commands
9+
from gs.backend.data.resources.utils import add_callsigns, add_main_commands
810

911

1012
@asynccontextmanager
1113
async def lifespan(_: FastAPI) -> AsyncGenerator[None, None]:
1214
"""Lifecycle event for the FastAPI app."""
15+
# Initialize FastAPI Cache (in memory cache)
16+
FastAPICache.init(InMemoryBackend())
17+
1318
# Must all the get_db_session each time when pass it into a separate function.
1419
# Otherwise, will get transaction is inactive error
1520
setup_database(get_db_session())
1621
add_main_commands(get_db_session())
22+
add_callsigns(get_db_session())
1723
yield
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from fastapi import FastAPI
22
from fastapi.middleware.cors import CORSMiddleware
33

4+
from gs.backend.config.config import backend_config
5+
46

57
def add_cors_middleware(app: FastAPI) -> None:
68
"""
@@ -10,8 +12,8 @@ def add_cors_middleware(app: FastAPI) -> None:
1012
"""
1113
app.add_middleware(
1214
CORSMiddleware,
13-
allow_origins=["http://localhost:5173"],
14-
allow_credentials=True,
15-
allow_methods=["*"],
16-
allow_headers=["*"],
15+
allow_origins=backend_config.cors_config.allow_origins,
16+
allow_credentials=backend_config.cors_config.allow_credentials,
17+
allow_methods=backend_config.cors_config.allow_methods,
18+
allow_headers=backend_config.cors_config.allow_headers,
1719
)

0 commit comments

Comments
 (0)