retry get request; use "logging"

This commit is contained in:
Daniel Langbein 2020-12-03 15:53:17 +01:00
parent 81f1042bf8
commit 04c29d21e5
7 changed files with 58 additions and 19 deletions

View File

@ -3,8 +3,9 @@
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.8 (xfconf-backup)" jdkType="Python SDK" />
<orderEntry type="jdk" jdkName="Python 3.7 (venv37)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PackageRequirementsSettings">

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8 (xfconf-backup)" project-jdk-type="Python SDK" />
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (venv37)" project-jdk-type="Python SDK" />
</project>

View File

@ -2,7 +2,7 @@ version: '3.7'
services:
bbb-status:
build: .
command: ["log"] # see main.py for available commandline arguments
command: ["log-verbose"] # see main.py for available commandline arguments
environment:
- PYTHONPATH=/usr/src/ # pythonpath is required to import from self created modules ("from langfingaz ...")
- PYTHONUNBUFFERED=1

View File

@ -1,17 +1,27 @@
import hashlib
import logging
import requests
from requests.adapters import HTTPAdapter
import requests.packages.urllib3.exceptions
from requests.packages.urllib3.util.retry import Retry
from xml.etree import ElementTree
import langfingaz.util.fileUtil as fileUtil
import langfingaz.util.util as util
def requestMeetingData() -> str:
def requestMeetingData(maxRetry=0, gracePeriod: int = 1) -> str:
"""
:arg maxRetry: maximum connection retries; if maxRetry=None, then unlimited retires
:arg gracePeriod: seconds to wait before retry
:return: XML file containing data about currently active BBB meetings
See also: https://docs.bigbluebutton.org/dev/api.html#monitoring
as well as: https://docs.bigbluebutton.org/dev/api.html#getmeetings
"""
requestUrl = getRequestUrl()
util.debug("starting request for " + requestUrl)
response = requests.get(requestUrl)
if not response.ok:
raise ValueError("error during request, got status code {}".format(response.status_code))
response: requests.Response = doGetRequest(requestUrl)
tree = ElementTree.fromstring(response.content)
if tree.find('returncode').text != 'SUCCESS':
@ -20,6 +30,37 @@ def requestMeetingData() -> str:
return str(response.content, encoding=response.encoding)
def doGetRequest(requestUrl: str, maxRetries=6) -> requests.Response:
"""
Performs a HTTPS GET request for the given url and does at most maxRetries retries
on connection errors.
:raises requests.exceptions.HTTPError: If status code not 200 (will retry if 502, 503, 504)
:raises requests.packages.urllib3.exceptions.MaxRetryError:
"""
logLevel = logging.root.level # https://stackoverflow.com/a/53951759/6334421
logging.basicConfig(level=logging.DEBUG)
# https://stackoverflow.com/a/35636367/6334421
# Retry on basic connectivity issues (including DNS lookup failures),
# and HTTP status codes of 502, 503 and 504
# Grace period increases after each retry.
# See also:
# - Session: https://requests.readthedocs.io/en/master/user/advanced/
s: requests.sessions.Session = requests.Session()
retries: Retry = Retry(total=maxRetries, backoff_factor=5, status_forcelist=[502, 503, 504])
s.mount('https://', HTTPAdapter(max_retries=retries))
response: requests.Response = s.get(requestUrl)
logging.basicConfig(level=logLevel)
# raise exception if status conde NOT 200
response.raise_for_status()
return response
def getRequestUrl(api_method: str = 'getMeetings', query_string: str = '') -> str:
url = getUrl()
api_url = url + "api/"
@ -48,4 +89,3 @@ def getSecret() -> str:
if len(secret) <= min_length:
raise ValueError("secret should be longer than {} characters!".format(min_length))
return secret

View File

@ -14,9 +14,7 @@ def sleepFiveMin(verbose=False):
if verbose:
print(">> Sleeping for five minutes <<")
sys.stdout.flush()
time.sleep(fiveMinutes)
util.sleep(fiveMinutes)
def v2(folder: Path = saveData.getDefaultFolder()):

View File

@ -1,14 +1,14 @@
#!/usr/bin/python3
from sys import argv
import logging
from langfingaz import plotMeetings
from langfingaz import logMeetingData
from langfingaz.util import util
def main():
print("=== bbb-status ===")
util.debug(str(argv))
logging.debug(str(argv))
print()
usageStr = 'Usage:\n' + argv[0] + ' [log|log-verbose|plot]\n' + \

View File

@ -1,9 +1,9 @@
BBB_STATUS_DEBUG = True
import time
def debug(message: str):
if BBB_STATUS_DEBUG:
print(">> " + message)
def sleep(seconds: float):
print(flush=True) # print newline -> so that all characters of current line get flushed as well
time.sleep(seconds)
def indentMultilineStr(s: str, indentWith='\t'):