Skip to content

Commit

Permalink
passes ruff format.
Browse files Browse the repository at this point in the history
  • Loading branch information
birkin committed Oct 26, 2024
1 parent e9ab12f commit a889695
Show file tree
Hide file tree
Showing 9 changed files with 209 additions and 161 deletions.
47 changes: 23 additions & 24 deletions config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@
## load envars ------------------------------------------------------
dotenv_path = pathlib.Path(__file__).resolve().parent.parent.parent / '.env'
assert dotenv_path.exists(), f'file does not exist, ``{dotenv_path}``'
load_dotenv(
find_dotenv( str(dotenv_path), raise_error_if_not_found=True ),
override=True
)
load_dotenv(find_dotenv(str(dotenv_path), raise_error_if_not_found=True), override=True)


log = logging.getLogger(__name__)
Expand All @@ -41,16 +38,16 @@

# SECURITY WARNING: keep the secret key used in production secret!
# SECRET_KEY = 'django-insecure-3ory+ty87_wq8-21ki6d&a+x=z9_$2m(gr4@vxri@@^g7u!*oc'
SECRET_KEY = os.environ[ 'SECRET_KEY' ]
SECRET_KEY = os.environ['SECRET_KEY']

# SECURITY WARNING: don't run with debug turned on in production!
# DEBUG = True
DEBUG = json.loads( os.environ['DEBUG_JSON'] )
DEBUG = json.loads(os.environ['DEBUG_JSON'])

ADMINS = json.loads( os.environ['ADMINS_JSON'] )
ADMINS = json.loads(os.environ['ADMINS_JSON'])

ALLOWED_HOSTS = json.loads( os.environ['ALLOWED_HOSTS_JSON'] )
CSRF_TRUSTED_ORIGINS = json.loads( os.environ['CSRF_TRUSTED_ORIGINS_JSON'] )
ALLOWED_HOSTS = json.loads(os.environ['ALLOWED_HOSTS_JSON'])
CSRF_TRUSTED_ORIGINS = json.loads(os.environ['CSRF_TRUSTED_ORIGINS_JSON'])

# Application definition

Expand Down Expand Up @@ -79,7 +76,7 @@
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
# 'DIRS': [ '%s/foo_app' % BASE_DIR ],
'DIRS': [ f'{BASE_DIR}/foo_app/foo_app_templates' ],
'DIRS': [f'{BASE_DIR}/foo_app/foo_app_templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
Expand All @@ -97,7 +94,7 @@

# Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases
DATABASES = json.loads( os.environ['DATABASES_JSON'] )
DATABASES = json.loads(os.environ['DATABASES_JSON'])

# Password validation
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators
Expand Down Expand Up @@ -141,24 +138,24 @@
# Email
SERVER_EMAIL = os.environ['SERVER_EMAIL']
EMAIL_HOST = os.environ['EMAIL_HOST']
EMAIL_PORT = int( os.environ['EMAIL_PORT'] )
EMAIL_PORT = int(os.environ['EMAIL_PORT'])


# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

## reminder:
## "Each 'logger' will pass messages above its log-level to its associated 'handlers',
## reminder:
## "Each 'logger' will pass messages above its log-level to its associated 'handlers',
## ...which will then output messages above the handler's own log-level."
LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'formatters': {
'standard': {
'format': "[%(asctime)s] %(levelname)s [%(module)s-%(funcName)s()::%(lineno)d] %(message)s",
'datefmt': "%d/%b/%Y %H:%M:%S"
'format': '[%(asctime)s] %(levelname)s [%(module)s-%(funcName)s()::%(lineno)d] %(message)s',
'datefmt': '%d/%b/%Y %H:%M:%S',
},
},
'handlers': {
Expand All @@ -168,15 +165,17 @@
'include_html': True,
},
'logfile': {
'level': os.environ.get( 'LOG_LEVEL', 'INFO' ), # add LOG_LEVEL=DEBUG to the .env file to see debug messages
'class':'logging.FileHandler', # note: configure server to use system's log-rotate to avoid permissions issues
'level': os.environ.get(
'LOG_LEVEL', 'INFO'
), # add LOG_LEVEL=DEBUG to the .env file to see debug messages
'class': 'logging.FileHandler', # note: configure server to use system's log-rotate to avoid permissions issues
'filename': os.environ['LOG_PATH'],
'formatter': 'standard',
},
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
'formatter': 'standard'
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'standard',
},
},
'loggers': {
Expand All @@ -188,12 +187,12 @@
'foo_app': {
'handlers': ['logfile'],
'level': 'DEBUG', # messages above this will get sent to the `logfile` handler
'propagate': False
'propagate': False,
},
# 'django.db.backends': { # re-enable to check sql-queries! <https://docs.djangoproject.com/en/4.2/ref/logging/#django-db-backends>
# 'handlers': ['logfile'],
# 'level': os.environ['LOG_LEVEL'],
# 'propagate': False
# },
}
},
}
10 changes: 5 additions & 5 deletions config/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@

urlpatterns = [
## main ---------------------------------------------------------
path( 'info/', views.info, name='info_url' ),
path('info/', views.info, name='info_url'),
## other --------------------------------------------------------
path( '', views.root, name='root_url' ),
path( 'admin/', admin.site.urls ),
path( 'error_check/', views.error_check, name='error_check_url' ),
path( 'version/', views.version, name='version_url' ),
path('', views.root, name='root_url'),
path('admin/', admin.site.urls),
path('error_check/', views.error_check, name='error_check_url'),
path('version/', views.version, name='version_url'),
]
2 changes: 1 addition & 1 deletion config/wsgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
PROJECT_DIR_PATH = pathlib.Path(__file__).resolve().parent.parent
# print( f'PROJECT_DIR_PATH, ``{PROJECT_DIR_PATH}``' )

sys.path.append( str(PROJECT_DIR_PATH) )
sys.path.append(str(PROJECT_DIR_PATH))

os.environ['DJANGO_SETTINGS_MODULE'] = 'config.settings' # so django can access its settings

Expand Down
79 changes: 45 additions & 34 deletions foo_app/lib/version_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,60 +9,68 @@
log = logging.getLogger(__name__)


def make_context( request, rq_now, info_txt ):
""" Assembles data-dct.
Called by views.version() """
def make_context(request, rq_now, info_txt):
"""
Assembles data-dct.
Called by views.version()"""
context = {
'request': {
'url': '%s://%s%s' % (
request.scheme,
request.META.get( 'HTTP_HOST', '127.0.0.1' ), # HTTP_HOST doesn't exist for client-tests
request.META.get('REQUEST_URI', request.META['PATH_INFO'])
'url': '%s://%s%s'
% (
request.scheme,
request.META.get(
'HTTP_HOST', '127.0.0.1'
), # HTTP_HOST doesn't exist for client-tests
request.META.get('REQUEST_URI', request.META['PATH_INFO']),
),
'timestamp': str( rq_now )
'timestamp': str(rq_now),
},
'response': {
'ip': request.META.get('REMOTE_ADDR', 'unknown'),
'version': info_txt,
'timetaken': str( datetime.datetime.now() - rq_now )
}
'timetaken': str(datetime.datetime.now() - rq_now),
},
}
return context


class GatherCommitAndBranchData:
"""
Note:
Note:
- Originally this class made two separate asyncronous subprocess calls to git.
- Now it reads the `.git/HEAD` file to get the commit and branch data, so it doesn't need to be asyncronous.
"""

def __init__( self ):
def __init__(self):
self.commit_data = ''
self.branch_data = ''

async def manage_git_calls( self ):
""" Triggers separate version and commit preparation concurrently.
- Originally this class made two separate asyncronous subprocess calls to git.
- Now it reads the `.git/HEAD` file to get both the commit and branch data (to avoid the `dubious ownership` issues),
so it no longer benefits from asyncronous calls, but keeping for reference.
Called by views.version() """
log.debug( 'manage_git_calls' )
async def manage_git_calls(self):
"""
Triggers separate version and commit preparation concurrently.
- Originally this class made two separate asyncronous subprocess calls to git.
- Now it reads the `.git/HEAD` file to get both the commit and branch data (to avoid the `dubious ownership` issues),
so it no longer benefits from asyncronous calls, but keeping for reference.
Called by views.version()
"""
log.debug('manage_git_calls')
results_holder_dct = {} # receives git responses as they're produced
async with trio.open_nursery() as nursery:
nursery.start_soon( self.fetch_commit_data, results_holder_dct )
nursery.start_soon( self.fetch_branch_data, results_holder_dct )
log.debug( f'final results_holder_dct, ```{pprint.pformat(results_holder_dct)}```' )
nursery.start_soon(self.fetch_commit_data, results_holder_dct)
nursery.start_soon(self.fetch_branch_data, results_holder_dct)
log.debug(f'final results_holder_dct, ```{pprint.pformat(results_holder_dct)}```')
self.commit = results_holder_dct['commit']
self.branch = results_holder_dct['branch']
log.debug( f'self.branch, ``{self.branch}``' )
log.debug(f'self.branch, ``{self.branch}``')
return

async def fetch_commit_data(self, results_holder_dct):
""" Fetches commit-data by reading the `.git/HEAD` file (avoiding calling git via subprocess due to `dubious ownership` issue).
Called by manage_git_calls() """
"""
Fetches commit-data by reading the `.git/HEAD` file (avoiding calling git via subprocess due to `dubious ownership` issue).
Called by manage_git_calls()
"""
log.debug('fetch_commit_data')
git_dir = pathlib.Path( settings.BASE_DIR ) / '.git'
git_dir = pathlib.Path(settings.BASE_DIR) / '.git'
try:
## read the HEAD file to find the current branch ------------
head_file: pathlib.Path = git_dir / 'HEAD'
Expand All @@ -71,22 +79,24 @@ async def fetch_commit_data(self, results_holder_dct):
ref_path = ref_line.split(' ')[1] # extract the ref path
commit_file: pathlib.Path = git_dir / ref_path
commit: str = commit_file.read_text().strip()
else: #if it's a detached HEAD, the commit hash is directly in the HEAD file
else: # if it's a detached HEAD, the commit hash is directly in the HEAD file
commit: str = ref_line
except FileNotFoundError:
log.error( 'no `.git` directory or HEAD file found.' )
log.error('no `.git` directory or HEAD file found.')
commit = 'commit_not_found'
except Exception:
log.exception( 'other problem fetching commit data' )
log.exception('other problem fetching commit data')
commit = 'commit_not_found'
log.debug( f'commit, ``{commit}``' )
log.debug(f'commit, ``{commit}``')
## update holder --------------------------------------------
results_holder_dct['commit'] = commit
return

async def fetch_branch_data(self, results_holder_dct):
""" Fetches branch-data by reading the `.git/HEAD` file (avoiding calling git via subprocess due to `dubious ownership` issue).
Called by manage_git_calls() """
"""
Fetches branch-data by reading the `.git/HEAD` file (avoiding calling git via subprocess due to `dubious ownership` issue).
Called by manage_git_calls()
"""
log.debug('fetch_branch_data')
git_dir = pathlib.Path(settings.BASE_DIR) / '.git'
try:
Expand All @@ -98,13 +108,14 @@ async def fetch_branch_data(self, results_holder_dct):
else:
branch = 'detached'
except FileNotFoundError:
log.error( 'no `.git` directory or HEAD file found.' )
log.error('no `.git` directory or HEAD file found.')
branch = 'branch_not_found'
except Exception:
log.exception( 'other problem fetching branch data')
log.exception('other problem fetching branch data')
branch = 'branch_not_found'
## update holder --------------------------------------------
results_holder_dct['branch'] = branch
return


## end class GatherCommitAndBranchData
34 changes: 22 additions & 12 deletions foo_app/tests.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging

from django.conf import settings as project_settings

# from django.test import TestCase # TestCase requires db
from django.test import SimpleTestCase as TestCase # SimpleTestCase does not require db
from django.test.utils import override_settings
Expand All @@ -10,22 +11,31 @@
TestCase.maxDiff = 1000


class ErrorCheckTest( TestCase ):
""" Checks urls. """
class ErrorCheckTest(TestCase):
"""
Checks urls.
"""

@override_settings(DEBUG=True) # for tests, DEBUG autosets to False
def test_dev_errorcheck(self):
""" Checks that dev error_check url triggers error.. """
log.debug( f'debug, ``{project_settings.DEBUG}``' )
"""
Checks that dev error_check url triggers error.
"""
log.debug(f'debug, ``{project_settings.DEBUG}``')
try:
log.debug( 'about to initiate client.get()' )
self.client.get( '/error_check/' )
log.debug('about to initiate client.get()')
self.client.get('/error_check/')
except Exception as e:
log.debug( f'e, ``{repr(e)}``' )
self.assertEqual( "Exception('Raising intentional exception to check email-admins-on-error functionality.')", repr(e) )
log.debug(f'e, ``{repr(e)}``')
self.assertEqual(
"Exception('Raising intentional exception to check email-admins-on-error functionality.')",
repr(e),
)

def test_prod_errorcheck(self):
""" Checks that production error_check url returns 404. """
log.debug( f'debug, ``{project_settings.DEBUG}``' )
response = self.client.get( '/error_check/' )
self.assertEqual( 404, response.status_code )
"""
Checks that production error_check url returns 404.
"""
log.debug(f'debug, ``{project_settings.DEBUG}``')
response = self.client.get('/error_check/')
self.assertEqual(404, response.status_code)
Loading

0 comments on commit a889695

Please sign in to comment.