project: ruff check and format

This commit is contained in:
Chris Milne 2026-06-15 09:45:55 +01:00
parent 0a9d941eea
commit 1e906fc3f0
27 changed files with 93 additions and 63 deletions

View file

@ -17,6 +17,7 @@ Exports:
- Dependencies should be used for db model get and validation where possible
- Verify module level docstring is still accurate after updates
"""
import threading
from typing import Annotated, Optional
@ -38,14 +39,16 @@ async def start_timer(request: Request, interval: int):
print("ping")
stop_event = threading.Event()
timer = create_timer(func=example_timer_target, interval=interval, stop_event=stop_event)
timer = create_timer(
func=example_timer_target, interval=interval, stop_event=stop_event
)
timer_ident = "example_timer"
timer_tracker = {
"ident": timer_ident,
"interval": interval,
"stop_event": stop_event,
"timer": timer
"timer": timer,
}
timer.start()
@ -58,7 +61,10 @@ async def start_timer(request: Request, interval: int):
async def stop_timer(request: Request, ident: str):
timers = request.app.state.timers
idx, timer_tracker = next(((i, timer) for i, timer in enumerate(timers) if timer["ident"] == ident), (None, None))
idx, timer_tracker = next(
((i, timer) for i, timer in enumerate(timers) if timer["ident"] == ident),
(None, None),
)
if not timer_tracker:
raise HTTPException(status_code=404, detail="Timer not found")
@ -72,9 +78,14 @@ async def stop_timer(request: Request, ident: str):
@router.get("/hub/access")
async def test_hub_access(headers: header_dependency, client: http_client_dependency, org_name: Annotated[str, Query()],
async def test_hub_access(
headers: header_dependency,
client: http_client_dependency,
org_name: Annotated[str, Query()],
resource_name: Annotated[str, Query()] = "example_resource",
action: Annotated[str, Query()] = "read", instance: Optional[Annotated[str, Query()]] = None):
action: Annotated[str, Query()] = "read",
instance: Optional[Annotated[str, Query()]] = None,
):
rn = generate_resource_name(resource=resource_name, org=org_name, instance=instance)
request_body = {
@ -83,33 +94,28 @@ async def test_hub_access(headers: header_dependency, client: http_client_depend
}
hub_response = await client.post(
f"http://localhost:8001/api/v1/iam/can_act_on_resource",
"http://localhost:8001/api/v1/iam/can_act_on_resource",
headers=headers,
json=request_body
json=request_body,
)
response = {
"response": {
"status": hub_response.status_code,
"json": hub_response.json()
}
"response": {"status": hub_response.status_code, "json": hub_response.json()}
}
return response
@router.get("/hub/user")
async def test_hub_user_details(headers: header_dependency, client: http_client_dependency):
async def test_hub_user_details(
headers: header_dependency, client: http_client_dependency
):
hub_response = await client.get(
f"http://localhost:8001/api/v1/user/self/db",
headers=headers
"http://localhost:8001/api/v1/user/self/db", headers=headers
)
response = {
"response": {
"status": hub_response.status_code,
"json": hub_response.json()
}
"response": {"status": hub_response.status_code, "json": hub_response.json()}
}
return response

View file

@ -1,15 +1,14 @@
"""
This module hooks the routers for the main endpoints into a single router for importing to the app.
"""
from fastapi import APIRouter
from src.auth.router import router as auth_router
from src._module_template.router import router as template_router
api_router = APIRouter(
prefix="/api/v1"
)
api_router = APIRouter(prefix="/api/v1")
api_router.include_router(auth_router)
api_router.include_router(template_router)

View file

@ -4,6 +4,7 @@ Configurations for the auth module
Exports:
- auth_settings: Contains OIDC & hub access information
"""
from src.config import CustomBaseSettings

View file

@ -3,6 +3,7 @@ Auth dependencies
Exports:
"""
from typing import Annotated, Any
from fastapi import Depends

View file

@ -4,6 +4,7 @@ Module specific exceptions for the auth module
Exceptions:
- UnauthorizedException: Takes an optional message string
"""
from typing import Optional
from fastapi import HTTPException, status

View file

@ -4,6 +4,7 @@ Router endpoints for the auth module
Exports:
- router: fastapi.APIRouter
"""
from fastapi import APIRouter
router = APIRouter(

View file

@ -38,6 +38,7 @@ class Config(CustomBaseSettings):
DATABASE_HOSTNAME: str = "localhost"
DATABASE_CREDENTIALS: SecretStr = ""
settings = Config()
DATABASE_NAME = settings.DATABASE_NAME
@ -45,10 +46,14 @@ DATABASE_PORT = settings.DATABASE_PORT
DATABASE_HOSTNAME = settings.DATABASE_HOSTNAME
DATABASE_CREDENTIALS = settings.DATABASE_CREDENTIALS.get_secret_value()
# this will support special chars for credentials
_DATABASE_CREDENTIAL_USER, _DATABASE_CREDENTIAL_PASSWORD = str(DATABASE_CREDENTIALS).split(":")
_DATABASE_CREDENTIAL_USER, _DATABASE_CREDENTIAL_PASSWORD = str(
DATABASE_CREDENTIALS
).split(":")
_QUOTED_DATABASE_PASSWORD = parse.quote_plus(str(_DATABASE_CREDENTIAL_PASSWORD))
SQLALCHEMY_DATABASE_URI = SecretStr(f"postgresql+psycopg://{_DATABASE_CREDENTIAL_USER}:{_QUOTED_DATABASE_PASSWORD}@{DATABASE_HOSTNAME}:{DATABASE_PORT}/{DATABASE_NAME}")
SQLALCHEMY_DATABASE_URI = SecretStr(
f"postgresql+psycopg://{_DATABASE_CREDENTIAL_USER}:{_QUOTED_DATABASE_PASSWORD}@{DATABASE_HOSTNAME}:{DATABASE_PORT}/{DATABASE_NAME}"
)
if settings.ENVIRONMENT == Environment.TESTING:
SQLALCHEMY_DATABASE_URI = SecretStr("sqlite:///:memory:")

View file

@ -4,6 +4,7 @@ Global constants
Exports:
- Environment(StrEnum): LOCAL, TESTING, STAGING, PRODUCTION
"""
from enum import StrEnum, auto

View file

@ -5,6 +5,7 @@ Exports:
- db_dependency
- Base (sqlalchemy base model)
"""
from typing import Annotated
from sqlalchemy import create_engine, StaticPool
from sqlalchemy.orm import DeclarativeBase, sessionmaker, Session
@ -16,7 +17,11 @@ from src.config import SQLALCHEMY_DATABASE_URI, settings as global_settings
if global_settings.ENVIRONMENT == Environment.TESTING:
connect_args = {"check_same_thread": False}
engine = create_engine(SQLALCHEMY_DATABASE_URI.get_secret_value(), connect_args=connect_args, poolclass=StaticPool)
engine = create_engine(
SQLALCHEMY_DATABASE_URI.get_secret_value(),
connect_args=connect_args,
poolclass=StaticPool,
)
else:
engine = create_engine(SQLALCHEMY_DATABASE_URI.get_secret_value())
@ -36,5 +41,7 @@ def get_db():
db_dependency = Annotated[Session, Depends(get_db)]
class Base(DeclarativeBase):
pass

View file

@ -3,13 +3,16 @@ Global dependencies
Exports:
"""
import httpx
from typing import Annotated
from fastapi import Depends
async def create_http_client():
async with httpx.AsyncClient() as client:
yield client
http_client_dependency = Annotated[httpx.AsyncClient, Depends(create_http_client)]

View file

@ -5,6 +5,7 @@ Exports:
- UnprocessableContentException
- ConflictException
"""
from typing import Optional
from fastapi import HTTPException, status

View file

@ -4,6 +4,7 @@ Application root file: Inits the FastAPI application
Prometheus client mounted at /metrics endpoint
Middleware: Session, CORS
"""
from contextlib import asynccontextmanager
from typing import AsyncGenerator
from prometheus_client import make_asgi_app
@ -44,7 +45,7 @@ app = FastAPI(
"scopes": "openid profile email",
},
openapi_tags=tags_metadata,
**app_configs
**app_configs,
)
metrics_app = make_asgi_app()

View file

@ -1,4 +1,3 @@
"""
Global database models
"""

View file

@ -5,6 +5,7 @@ Exports:
- CustomBaseModel: Schema used for all other Pydantic models
- ResourceName
"""
from pydantic import BaseModel
from typing import Optional

View file

@ -3,6 +3,7 @@ Global non-business-logic reusable functions and classes
Exports:
"""
import threading
from typing import Callable, Optional
@ -18,7 +19,9 @@ def create_timer(func: Callable, interval: int, stop_event: threading.Event):
return threading.Thread(target=target, daemon=True)
def generate_resource_name(org: str, resource: str, instance: Optional[str] = None) -> ResourceName:
def generate_resource_name(
org: str, resource: str, instance: Optional[str] = None
) -> ResourceName:
rn = ResourceName(
service=settings.SERVICE_NAME,
organisation=org,