-
-
Notifications
You must be signed in to change notification settings - Fork 0
feat: updates #23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: updates #23
Conversation
Reviewer's GuideThis pull request introduces a major refactor and modularization of the application's configuration, service, and schema layers, as well as significant improvements to environment variable handling, Docker/Kubernetes deployment, and code organization. The changes include moving and restructuring settings/configuration, introducing new service and schema modules, updating dependency injection patterns, enhancing environment variable parsing, and adding new deployment scripts and templates. Sequence Diagram for System Health ChecksequenceDiagram
actor Client
participant SystemController
participant Database
Client->>SystemController: GET /health
activate SystemController
SystemController->>Database: Execute query (e.g., SELECT 1)
activate Database
Database-->>SystemController: Query Result (Success/Failure)
deactivate Database
alt Connection Successful
SystemController-->>Client: HTTP 200 OK (SystemHealth: database_status='online')
else Connection Failed
SystemController-->>Client: HTTP 500 Internal Server Error (SystemHealth: database_status='offline')
end
deactivate SystemController
Updated Class Diagram for Settings ConfigurationclassDiagram
class Settings {
+app: AppSettings
+db: DatabaseSettings
+vite: ViteSettings
+server: ServerSettings
+saq: SaqSettings
+log: LogSettings
+storage: StorageSettings
+from_env(dotenv_filename: str) Settings
}
note for Settings "RedisSettings removed, StorageSettings added.
from_env() logic updated to use dotenv and load individual settings components."
class AppSettings {
+NAME: str
+VERSION: str
+CONTACT_NAME: str
+CONTACT_EMAIL: str
+URL: str
+DEBUG: bool
+SECRET_KEY: str
+JWT_ENCRYPTION_ALGORITHM: str
+ALLOWED_CORS_ORIGINS: list[str] | str
+CSRF_COOKIE_NAME: str
+CSRF_HEADER_NAME: str
+CSRF_COOKIE_SECURE: bool
+STATIC_DIR: Path
+STATIC_URL: str
+BASE_URL: str | None
+DEV_MODE: bool
+ENABLE_INSTRUMENTATION: bool
+GOOGLE_OAUTH2_CLIENT_ID: str
+GOOGLE_OAUTH2_CLIENT_SECRET: str
+ENV_SECRETS: str
-OPENTELEMETRY_ENABLED: bool (removed)
-LOGFIRE_ENABLED: bool (removed)
-GITHUB_OAUTH2_CLIENT_ID: str (removed)
-GITHUB_OAUTH2_CLIENT_SECRET: str (removed)
}
note for AppSettings "Fields now use get_env from app.utils.env for defaults."
class DatabaseSettings {
+ECHO: bool
+ECHO_POOL: bool
+POOL_DISABLED: bool
+POOL_MAX_OVERFLOW: int
+POOL_SIZE: int
+POOL_TIMEOUT: int
+POOL_RECYCLE: int
+POOL_PRE_PING: bool
+URL: str
+MIGRATION_CONFIG: str
+MIGRATION_PATH: str
+MIGRATION_DDL_VERSION_TABLE: str
+FIXTURE_PATH: str
+get_engine() AsyncEngine
}
note for DatabaseSettings "URL default changed to Postgres.
get_engine() now uses app.utils.engine_factory.create_sqlalchemy_engine.
Fields now use get_env for defaults."
class ViteSettings {
+DEV_MODE: bool
+USE_SERVER_LIFESPAN: bool
+HOST: str
+PORT: int
+HOT_RELOAD: bool
+ENABLE_REACT_HELPERS: bool
+BUNDLE_DIR: Path
+RESOURCE_DIR: Path
+TEMPLATE_DIR: Path
+ASSET_URL: str
}
note for ViteSettings "Default paths for BUNDLE_DIR, RESOURCE_DIR, ASSET_URL changed.
Fields now use get_env for defaults."
class ServerSettings {
+APP_LOC: str
+HOST: str
+PORT: int
+KEEPALIVE: int
+RELOAD: bool
+RELOAD_DIRS: list[str]
-HTTP_WORKERS: int | None (removed)
}
note for ServerSettings "Fields now use get_env for defaults."
class SaqSettings {
+PROCESSES: int
+CONCURRENCY: int
+WEB_ENABLED: bool
+USE_SERVER_LIFESPAN: bool
}
note for SaqSettings "Fields now use get_env for defaults."
class LogSettings {
+EXCLUDE_PATHS: str
+INCLUDE_COMPRESSED_BODY: bool
+LEVEL: int
+OBFUSCATE_COOKIES: set[str]
+OBFUSCATE_HEADERS: set[str]
+REQUEST_FIELDS: list[RequestExtractorField]
+RESPONSE_FIELDS: list[ResponseExtractorField]
+SAQ_LEVEL: int
+SQLALCHEMY_LEVEL: int
+ASGI_ACCESS_LEVEL: int
+ASGI_ERROR_LEVEL: int
-HTTP_EVENT: str (removed)
-JOB_FIELDS: list[str] (removed)
-WORKER_EVENT: str (removed)
-UVICORN_ACCESS_LEVEL: int (removed)
-UVICORN_ERROR_LEVEL: int (removed)
}
note for LogSettings "Significantly refactored. Fields now use get_env for defaults."
class StorageSettings {
<<new>>
+PUBLIC_STORAGE_KEY: str
+PUBLIC_STORAGE_URI: str
+PUBLIC_STORAGE_OPTIONS: dict[str, Any]
+PRIVATE_STORAGE_KEY: str
+PRIVATE_STORAGE_URI: str
+PRIVATE_STORAGE_OPTIONS: dict[str, Any]
}
note for StorageSettings "New class for storage configurations.
Fields use get_env for defaults."
Settings *-- AppSettings
Settings *-- DatabaseSettings
Settings *-- ViteSettings
Settings *-- ServerSettings
Settings *-- SaqSettings
Settings *-- LogSettings
Settings *-- StorageSettings
class env_utils {
<<utility>>
+get_env(key, default, type_hint) Callable
+get_config_val(key, default, type_hint) any
}
AppSettings ..> env_utils : uses
DatabaseSettings ..> env_utils : uses
ViteSettings ..> env_utils : uses
ServerSettings ..> env_utils : uses
SaqSettings ..> env_utils : uses
LogSettings ..> env_utils : uses
StorageSettings ..> env_utils : uses
Class Diagram for New SystemControllerclassDiagram
class SystemController {
<<Controller>>
+tags: list[str]
+check_system_health(db_session: AsyncSession) Response[SystemHealth]
}
class SystemHealth {
<<Schema>>
+database_status: Literal['online', 'offline']
}
SystemController ..> SystemHealth : returns
SystemController ..> AsyncSession : uses
Class Diagram for Renamed UserOAuthAccount ModelclassDiagram
class UserOauthAccount {
<<model, old name>>
# Attributes...
}
note for UserOauthAccount "This class was renamed."
class UserOAuthAccount {
<<model, new name>>
+id: UUID (PK)
+user_id: UUID (FK)
+oauth_name: str
+access_token: str
+expires_at: int | None
+refresh_token: str | None
+account_id: str
+account_email: str
+created_at: DateTimeUTC
+updated_at: DateTimeUTC
+user: User (Relationship)
}
class User {
<<model>>
+oauth_accounts: list[UserOAuthAccount]
}
User "1" -- "0..*" UserOAuthAccount : has
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We've reviewed this pull request using the Sourcery rules engine. If you would also like our AI-powered code review then let us know.
Returns: | ||
The ISO formatted datetime string. | ||
""" | ||
dt = dt.replace(tzinfo=datetime.UTC) if not dt.tzinfo else dt.astimezone(datetime.UTC) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (code-quality): Swap if/else branches of if expression to remove negation (swap-if-expression
)
dt = dt.replace(tzinfo=datetime.UTC) if not dt.tzinfo else dt.astimezone(datetime.UTC) | |
dt = dt.astimezone(datetime.UTC) if dt.tzinfo else dt.replace(tzinfo=datetime.UTC) |
Explanation
Negated conditions are more difficult to read than positive ones, so it is bestto avoid them where we can. By swapping the
if
and else
conditions around wecan invert the condition and make it positive.
msg = f"Internal error: List parsing requested for key '{key}' but no item constructor determined." | ||
raise RuntimeError(msg) | ||
|
||
if parse_as_list and item_constructor: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (code-quality): We've found these issues:
- Remove redundant conditional (
remove-redundant-if
) - Low code quality found in get_config_val - 9% (
low-code-quality
)
if parse_as_list and item_constructor: | |
if parse_as_list: |
Explanation
The quality score for this function is below the quality threshold of 25%.
This score is a combination of the method length, cognitive complexity and working memory.
How can you solve this?
It might be worth refactoring this function to make it shorter and more readable.
- Reduce the function length by extracting pieces of functionality out into
their own functions. This is the most important thing you can do - ideally a
function should be less than 10 lines. - Reduce nesting, perhaps by introducing guard clauses to return early.
- Ensure that variables are tightly scoped, so that code using related concepts
sits together within the function rather than being scattered.
for item in items: | ||
constructed_list.append(item_constructor(item.strip())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (code-quality): Replace a for append loop with list extend (for-append-to-extend
)
for item in items: | |
constructed_list.append(item_constructor(item.strip())) | |
constructed_list.extend(item_constructor(item.strip()) for item in items) |
console.print("[bold red]Error executing kubectl command:[/bold red]") | ||
console.print(f"Command: {' '.join(e.cmd)}") | ||
console.print(f"Return Code: {e.returncode}") | ||
console.print(f"Stderr:\n{e.stderr}") | ||
console.print(f"Stdout:\n{e.stdout}") | ||
# Re-raise the error if check was True, otherwise just report | ||
if check: | ||
raise | ||
# Explicitly return the error object if check is False. Type checker might complain. | ||
# Consider a more robust error handling strategy if needed. | ||
return e # type: ignore |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (code-quality): Extract code out into function (extract-method
)
# Validate required secrets | ||
missing = [key for key in REQUIRED_SECRETS if key not in os.environ] | ||
if missing: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (code-quality): We've found these issues:
- Use named expression to simplify assignment and conditional (
use-named-expression
) - Low code quality found in deploy - 24% (
low-code-quality
)
# Validate required secrets | |
missing = [key for key in REQUIRED_SECRETS if key not in os.environ] | |
if missing: | |
if missing := [key for key in REQUIRED_SECRETS if key not in os.environ]: |
Explanation
The quality score for this function is below the quality threshold of 25%.
This score is a combination of the method length, cognitive complexity and working memory.
How can you solve this?
It might be worth refactoring this function to make it shorter and more readable.
- Reduce the function length by extracting pieces of functionality out into
their own functions. This is the most important thing you can do - ideally a
function should be less than 10 lines. - Reduce nesting, perhaps by introducing guard clauses to return early.
- Ensure that variables are tightly scoped, so that code using related concepts
sits together within the function rather than being scattered.
# Validate required secrets (for delete, warn if missing but do not exit) | ||
missing = [key for key in REQUIRED_SECRETS if key not in os.environ] | ||
if missing: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (code-quality): Use named expression to simplify assignment and conditional (use-named-expression
)
# Validate required secrets (for delete, warn if missing but do not exit) | |
missing = [key for key in REQUIRED_SECRETS if key not in os.environ] | |
if missing: | |
if missing := [key for key in REQUIRED_SECRETS if key not in os.environ]: |
Description
Closes
Summary by Sourcery
Restructure and modularize application configuration, settings, and service layers, introduce new schema and service modules, and add comprehensive deployment tooling for Docker and Kubernetes environments.
New Features:
Enhancements:
Build:
Documentation:
Tests: