from harsh3466@lemmy.ml to programming@programming.dev on 21 Dec 21:22
https://lemmy.ml/post/40635326
Hello Programming.dev gang,
I’m still wrapping my head around classes, oop, and scoping, and was hoping to get some feedback. on a class definition.
Here’s the background:
I’m implementing pydantic for handing my .env secrets and constants (Haven’t gotten to a secrets manager yet), with pydantic_settings’s BaseSettings and SettingsConfigDict, as well as pydantic’s SecretStr.
I set up a parent class in settings.py to configure the .env file and settings, which you can see below.
settings.py Parent Class (click to expand)
from pydantic_settings import BaseSettings, SettingsConfigDict from pydantic import SecretStr class Settings(BaseSettings): model_config = SettingsConfigDict( env_file=“/opt/pyprojects/media-scripts/.env.dev”, extra=“ignore” )
I’ve got a self hosted Baserow database that I’m using for my project, and I defined a class in baserow.py that inherits from the Settings class for the .env config, and has all of the fucntions for interacting with the database as methods of the class, which you can see below.
(I’ve got a number of other classes similar to Baserow planned that will inherit from the Settings class, provided I’m on the right track with this layout.)
I thought it was a good idea to put the methods in the class with the .env var attributes to keep scoping focused and local. I’m wondering if this is a good idea or not, and am also open to any other feedback on the code/classes anyone might have. Thank you to anyone taking the time to read and/or respond.
baserow.py with Baserow child class (click to expand)
import json import requests from pydantic import SecretStr from mods.settings import Settings class Baserow(Settings): br_url: str br_api: SecretStr def query_db(self, urlFilters): url = f"{self.br_url}?user_field_names=true&{urlFilters}" headers = {“Authorization”: f"Token {self.br_api}“} brQueryResults = requests.get(url, headers=headers) return brQueryResults.json() def get_all_shows(self): url = f”{self.br_url}?user_field_names=true&size=200" headers = {“Authorization”: f"Token {self.br_api.get_secret_value()}“} brQueryResults = requests.get(url, headers=headers) return brQueryResults.json() def post_db(self, showDictionary): brPostResults = requests.post( f”{self.br_url}?user_field_names=true", headers={ “Authorization”: f"Token {self.br_api.get_secret_value()}“, “Content-Type”: “application/json”, }, json=showDictionary, ) print(json.dumps(brPostResults.json(), indent=2)) def patch_db(self, showDictionary, row): brPatchResults = requests.patch( f”{self.br_url}?user_field_names=true", headers={ “Authorization”: f"Token {self.br_api.get_secret_value()}“, “Content-Type”: “application/json”, }, json=showDictionary, ) print(brPatchResults) def delete_db_row(self, row): brDeleteResults = requests.delete( f”{self.br_url}{row}/“, headers={ “Authorization”: f"Token {self.br_api.get_secret_value()}”, }, ) print(brDeleteResults)
#programming
threaded - newest
Settings should just facilitate getting the configuration from your dotenv file. Rule of thumb: Each class should preferably serve a single purpose.
You should have a Database class that you can initialize with the relevant configuration from you Settings object and will handle the DB connectivity and session.
You should take a look at SQLModel and its examples.