check-in first files
This commit is contained in:
15
.vscode/launch.json
vendored
Normal file
15
.vscode/launch.json
vendored
Normal 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
47
config/runCfg.json
Normal 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
35
docker-compose.yaml
Normal 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
25
dockerfile
Normal 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
2
requirements.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
scheduler==0.8.5
|
||||
scripts==3.0
|
||||
180
src/watchdog.py
Normal file
180
src/watchdog.py
Normal 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
1
update_reqs.sh
Executable file
@@ -0,0 +1 @@
|
||||
pipreqs . --force
|
||||
Reference in New Issue
Block a user