Initial commit

This commit is contained in:
Pünkösd Marcell 2021-04-16 19:53:02 +02:00
commit e7041b2ccd
13 changed files with 194 additions and 0 deletions

25
.drone.yml Normal file
View File

@ -0,0 +1,25 @@
kind: pipeline
type: docker
name: default
steps:
- name: code-analysis
image: aosapps/drone-sonar-plugin
settings:
sonar_host:
from_secret: SONAR_HOST
sonar_token:
from_secret: SONAR_CODE
- name: kaniko
image: banzaicloud/drone-kaniko
settings:
registry: registry.kmlabz.com
repo: universalrobots/${DRONE_REPO_NAME}
username:
from_secret: DOCKER_USERNAME
password:
from_secret: DOCKER_PASSWORD
tags:
- latest
- ${DRONE_BUILD_NUMBER}

8
.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
*.swp
venv
*.pyc
__pycache__/*
__pycache__
*.wpr
*.log
.idea

10
Dockerfile Normal file
View File

@ -0,0 +1,10 @@
FROM python:3.9
ADD job_orchestrator_service requirements.txt /job_orchestrator_service/
WORKDIR /job_orchestrator_service/
RUN pip3 install -r requirements.txt && pip3 install gunicorn
EXPOSE 8000
CMD ["gunicorn", "-b", "0.0.0.0:8000", "app:app"]

View File

@ -0,0 +1,34 @@
#!/usr/bin/env python3
from config import Config
import sentry_sdk
from sentry_sdk.integrations.flask import FlaskIntegration
from flask import Flask
from utils import register_all_error_handlers
# import views
from views import JobView
# Setup sentry
if Config.SENTRY_DSN:
sentry_sdk.init(
dsn=Config.SENTRY_DSN,
integrations=[FlaskIntegration()],
send_default_pii=True,
release=Config.RELEASE_ID,
environment=Config.RELEASEMODE
)
# create flask app
app = Flask(__name__)
app.config.from_object(Config)
register_all_error_handlers(app)
# register views
for view in [JobView]:
view.register(app, trailing_slash=False)
# start debuggig if needed
if __name__ == "__main__":
app.run(debug=True)

View File

@ -0,0 +1,15 @@
#!/usr/bin/env python3
import os
"""
Configuration
"""
class Config:
SECRET_KEY = os.environ.get("SECRET_KEY", os.urandom(12))
CORS_ORIGINS = os.environ.get("ALLOWED_ORIGINS", "*")
SENTRY_DSN = os.environ.get("SENTRY_DSN")
RELEASE_ID = os.environ.get("RELEASE_ID", "test")
RELEASEMODE = os.environ.get("RELEASEMODE", "dev")

View File

@ -0,0 +1,2 @@
#!/usr/bin/env python3
from .job_schema import JobSchema

View File

@ -0,0 +1,22 @@
from marshmallow import Schema, fields
from marshmallow.validate import Length
from marshmallow import RAISE
from datetime import datetime
import uuid
class ControlConfigurationSchema(Schema):
pod_id = fields.UUID(required=False, missing=uuid.uuid4)
robot_address = fields.Str(required=True)
program_url = fields.Str(required=True)
class JobSchema(Schema):
id = fields.UUID(required=False, missing=uuid.uuid4)
created_at = fields.DateTime(required=False, missing=datetime.now)
controllers = fields.Nested(ControlConfigurationSchema, many=True, required=True, validate=Length(min=1))
class Meta:
unknown = RAISE

View File

@ -0,0 +1,3 @@
#!/usr/bin/env python3
from .require_decorators import json_required
from .error_handlers import register_all_error_handlers

View File

@ -0,0 +1,18 @@
#!/usr/bin/env python3
def get_standard_error_handler(code: int):
def error_handler(err):
return {"msg": str(err)}, code
return error_handler
# function to register all handlers
def register_all_error_handlers(app):
error_codes_to_override = [404, 403, 401, 405, 400, 409, 422]
for code in error_codes_to_override:
app.register_error_handler(code, get_standard_error_handler(code))

View File

@ -0,0 +1,16 @@
#!/usr/bin/env python3
from flask import request, current_app, abort
from functools import wraps
def json_required(f):
@wraps(f)
def call(*args, **kwargs):
if request.is_json:
return f(*args, **kwargs)
else:
abort(400, "JSON required")
return call

View File

@ -0,0 +1,3 @@
#!/usr/bin/env python3
from .job_view import JobView

View File

@ -0,0 +1,31 @@
#!/usr/bin/env python3
from flask import request, jsonify, current_app, abort, Response
from flask_classful import FlaskView, route
from utils import json_required
from marshmallow.exceptions import ValidationError
from schemas import JobSchema
class JobView(FlaskView):
job_schema = JobSchema(many=False)
jobs_schema = JobSchema(many=True, exclude=['controllers'])
def index(self):
# List all jobs
pass
def get(self, _id: str):
# Get info about a job
pass
@json_required
def post(self):
# Start (schedule) a job
pass
def delete(self, _id: str):
# stop a job
pass

7
requirements.txt Normal file
View File

@ -0,0 +1,7 @@
pyyaml
blinker
Flask
marshmallow
Flask-Classful
sentry-sdk