check-in first files

This commit is contained in:
2024-02-24 19:47:04 +01:00
commit 3c56072e55
7 changed files with 305 additions and 0 deletions

15
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,15 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python Debugger: Current File with Arguments",
"type": "debugpy",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
}
]
}

47
config/runCfg.json Normal file
View File

@@ -0,0 +1,47 @@
{
"_comment_jobs": "JobTypes can be: cyclic, minutely, daily, weekly, once",
"_comment_jobFunctions": "JobFunctions can be: printScheduler, generateOnePMTTechRoadmap",
"jobs": [
{
"jobName": "Print schedule",
"jobType": "cyclic",
"jobFunction": "printScheduler",
"dtTimeDelta": {
"minutes": 15
}
},
{
"jobName": "Example to show all possible scheduling options...",
"jobType": "once",
"jobFunction": "foo",
"dtTime": {
"_comment": "for minutely,hourly,daily,weekly & once jobs....",
"second": 0,
"minute": 0,
"hour": 0,
"dayOfWeek": [
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"
]
},
"dtTimeDelta": {
"_comment": "for cyclic & once jobs, in x minutes....",
"minutes": 0
},
"dtDateTime": {
"_comment": "for once jobs, at point in time....",
"year": 2022,
"month": 1,
"day": 1,
"hour": 0,
"minute": 0
}
}
]
}

35
docker-compose.yaml Normal file
View File

@@ -0,0 +1,35 @@
version: '3.4'
services:
watchdog:
image: watchdog
restart: always
build:
context: .
dockerfile: ./Dockerfile
mongo:
image: mongo
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: nils
MONGO_INITDB_ROOT_PASSWORD: mymongopw
ports:
- '27017-27019:27017-27019'
volumes:
- mongo-db:/data/db
- mongo-db:/data/configdb
mongo-express:
image: mongo-express
restart: always
ports:
- 8081:8081
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: nils
ME_CONFIG_MONGODB_ADMINPASSWORD: mymongopw
ME_CONFIG_MONGODB_URL: mongodb://nils:mymongopw@mongo:27017/
volumes:
mongo-db:

25
dockerfile Normal file
View File

@@ -0,0 +1,25 @@
FROM python:3.11-slim-bullseye
# Keeps Python from generating .pyc files in the container
ENV PYTHONDONTWRITEBYTECODE=1
#install ping for some network tests:
RUN apt-get update || : && apt-get install -y iputils-ping
# Turns off buffering for easier container logging
ENV PYTHONUNBUFFERED=1
# Install pip requirements
COPY . .
RUN python -m pip install -r requirements.txt
WORKDIR /app
COPY ./lib /app/src/lib
COPY ./services/scheduler /app
# Creates a non-root user with an explicit UID and adds permission to access the /app folder
RUN adduser -u 5678 --disabled-password --gecos "" appuser && chown -R appuser /app
USER appuser
# Start Server for API:
CMD ["python", "./src/watchdog.py"]

2
requirements.txt Normal file
View File

@@ -0,0 +1,2 @@
scheduler==0.8.5
scripts==3.0

180
src/watchdog.py Normal file
View File

@@ -0,0 +1,180 @@
import datetime as dt
from scheduler import Scheduler
import scheduler.trigger as trigger
import json
import os.path
import time
def foo():
# print("\nJust chilling...\n")
return
def printScheduler():
date = dt.datetime.now()
print(str(date)+": The currently available jobs are:\n")
print(schedule)
def addParameter(name, object, dict):
if name in object:
if type(object[name]) is int:
dict[name] = object[name]
elif type(object[name]) is str:
dict[name] = int(object[name])
else:
print("ERROR: Element cannot be interpreted correctly:",
object[name])
def addDtTimeDeltaJob(job, schedule: Scheduler, function, once):
dtTimeDelta = job['dtTimeDelta']
if 'minutes' in dtTimeDelta:
parameters = {}
addParameter('minutes', dtTimeDelta, parameters)
if once:
schedule.once(dt.timedelta(**parameters), function)
else:
schedule.cyclic(dt.timedelta(**parameters), function)
else:
print("ERROR: missing minutes in job: ", job['jobName'])
return
def scheduleDayOfWeek(day, daylist, schedule, function, parameters, once):
if day in daylist:
day_to_call = getattr(trigger, day)
if once:
if len(parameters) > 0:
# schedule.once(day_to_call(dt.time(**parameters)),function)
print("WARN: weekly jobs are currenlty not supported...")
else:
# schedule.once(day_to_call(),function())
print("WARN: weekly jobs are currenlty not supported...")
else:
if len(parameters) > 0:
# schedule.weekly(day_to_call(dt.time(**parameters)),function)
print("WARN: weekly jobs are currenlty not supported...")
else:
# schedule.weekly(day_to_call(),function)
print("WARN: weekly jobs are currenlty not supported...")
def addDtTimeJob(job, schedule: Scheduler, function, once):
dtTime = job['dtTime']
jobType = job['jobType']
parameters = {}
addParameter('second', dtTime, parameters)
addParameter('minute', dtTime, parameters)
addParameter('hour', dtTime, parameters)
if (jobType == "minutely") or (jobType == "hourly") or (jobType == "daily"):
cycle_to_call = getattr(schedule, jobType)
cycle_to_call(dt.time(**parameters), function)
pass
elif (jobType == 'once') or (jobType == 'weekly'):
if 'dayOfWeek' in dtTime:
scheduleDayOfWeek(
'Monday', dtTime['dayOfWeek'], schedule, function, parameters, once)
scheduleDayOfWeek(
'Tuesday', dtTime['dayOfWeek'], schedule, function, parameters, once)
scheduleDayOfWeek(
'Wednesday', dtTime['dayOfWeek'], schedule, function, parameters, once)
scheduleDayOfWeek(
'Thursday', dtTime['dayOfWeek'], schedule, function, parameters, once)
scheduleDayOfWeek(
'Friday', dtTime['dayOfWeek'], schedule, function, parameters, once)
scheduleDayOfWeek(
'Saturday', dtTime['dayOfWeek'], schedule, function, parameters, once)
scheduleDayOfWeek(
'Sunday', dtTime['dayOfWeek'], schedule, function, parameters, once)
else:
print(
"ERROR: dayOfWeek is mandatory for once and weekly jobs in job:", job['jobName'])
return
def addDtDateTimeOnceJob(job, schedule: Scheduler, function):
dtDateTime = job['dtDateTime']
parameters = {}
addParameter('year', dtDateTime, parameters)
addParameter('month', dtDateTime, parameters)
addParameter('day', dtDateTime, parameters)
addParameter('hour', dtDateTime, parameters)
addParameter('minute', dtDateTime, parameters)
schedule.once(dt.datetime(**parameters), function)
return
def addJob(job, schedule: Scheduler):
if 'jobFunction' in job:
jobFunction = job['jobFunction']
else:
print("ERROR: jobFunction is missing in job: ", job['jobName'])
return
if 'jobType' in job:
jobType = job['jobType']
else:
print("ERROR: jobType is missing in job: ", job['jobName'])
return
if jobFunction in globals():
function = globals()[jobFunction]
if jobType == "cyclic":
if 'dtTimeDelta' in job:
addDtTimeDeltaJob(job, schedule, function, once=False)
else:
print("ERROR: Missing dtTimeDelta in: ", job['jobName'])
elif (jobType == "minutely") or (jobType == "hourly") or (jobType == "daily") or (jobType == "weekly"):
if 'dtTime' in job:
addDtTimeJob(job, schedule, function, once=False)
else:
print("ERROR: Missing dtTime in: ", job['jobName'])
elif jobType == "once":
found = False
if 'dtTimeDelta' in job:
addDtTimeDeltaJob(job, schedule, function, once=True)
found = True
if 'dtDateTime' in job:
addDtDateTimeOnceJob(job, schedule, function)
found = True
if 'dtTime' in job:
addDtTimeJob(job, schedule, function, once=True)
found = True
else:
if not found:
print(
"ERROR: Missing either dtTime, dtTimeDelta or dtDateTime in: ", job['jobName'])
else:
print("Unkown JobType: ", jobType)
else:
print("\nERROR: Unknown Function: ", jobFunction)
print(" Ignoring job: ", job['jobName'])
print("\n")
def addJobs(schedule: Scheduler):
cfgFile = "./config/runCfg.json"
if os.path.isfile(cfgFile):
f = open("./config/runCfg.json")
data = json.load(f)
f.close()
if 'jobs' in data:
for job in data['jobs']:
if 'jobName' in job:
print("Setting up job: ", job['jobName'])
addJob(job, schedule)
else:
print("ERROR: Element is missing a jobName: ", job)
print("\n")
else:
print("WARN: No jobs configured in config file: ", cfgFile)
else:
print("ERROR: No config file found for scheduler: ", cfgFile)
# schedule = Scheduler(n_threads=0)
schedule = Scheduler()
addJobs(schedule)
printScheduler()
while True:
start_time = time.perf_counter()
n_exec = schedule.exec_jobs()
total_seconds = time.perf_counter() - start_time
if n_exec > 0:
print("Workers started: "+str(n_exec) +
". Total execution time: {:10.4f} s.\n\n".format(total_seconds))
time.sleep(1)

1
update_reqs.sh Executable file
View File

@@ -0,0 +1 @@
pipreqs . --force