Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
chmod +x ~/docker-compose
mv ~/docker-compose /usr/local/bin/docker-compose
- setup_remote_docker:
docker_layer_caching: true
docker_layer_caching: true

- run:
name: Start container and verify it is working
Expand Down
7 changes: 7 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"editor.formatOnSave": true,
"python.formatting.provider": "black",
"python.linting.pylintEnabled": false,
"python.linting.flake8Enabled": true,
"python.linting.enabled": true
}
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ USER human
ENV PATH="/home/human/.local/bin:${PATH}"

COPY --from=build-env /tmp/eradman-entr-33816756113b/entr /usr/local/bin/
COPY --from=build-env /tmp/ffmpeg-4.2.1-amd64-static/* /usr/local/bin/
COPY --from=build-env /tmp/ffmpeg-4.*-amd64-static/* /usr/local/bin/
COPY ./Pipfile* /app/

ENV LC_ALL C.UTF-8
Expand All @@ -54,7 +54,7 @@ COPY . /app
FROM debian:10.0 AS prod-env

RUN apt-get update -y && \
apt-get install -y python3-dev python3-pip postgresql-client libpq-dev ffmpeg && \
apt-get install -y python3-dev python3-pip postgresql-client libpq-dev && \
update-alternatives --install /usr/local/bin/python python /usr/bin/python3.7 1 && \
update-alternatives --install /usr/local/bin/pip pip /usr/bin/pip3 1 && \
rm -rf /var/lib/apt/lists/*
Expand All @@ -66,7 +66,7 @@ USER human

ENV PATH="/home/human/.local/bin:${PATH}"

COPY --from=build-env /tmp/ffmpeg-4.2.1-amd64-static/* /usr/local/bin/
COPY --from=build-env /tmp/ffmpeg-4.*-amd64-static/* /usr/local/bin/
COPY ./Pipfile* /app/

ENV LC_ALL C.UTF-8
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ test:
docker-compose exec api bash -c "FLASK_ENV=testing ENV_FOR_DYNACONF=testing pipenv run pytest"

.PHONY: test-dev
## Runs the tests
## Runs the tests continuously on file changes
test-dev:
docker-compose exec api bash -c "FLASK_ENV=testing ENV_FOR_DYNACONF=testing pipenv run ptw -- --testmon"

Expand Down
2 changes: 1 addition & 1 deletion Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]
pytest = "==4.6.3"
pytest = "*"
pytest-flask = "*"
pytest-factoryboy = "*"
pytest-watch = "*"
Expand Down
870 changes: 402 additions & 468 deletions Pipfile.lock

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ $ docker-compose up -d
$ make migrate
```

You may want to rebuild the image with `docker-compose build` or `docker-compose up --build`.

You should see output that looks like this:

```
Expand Down Expand Up @@ -70,6 +72,14 @@ We use [pipenv](https://github.com/pypa/pipenv) to manage our python dependencie
# pipenv install <dependency>
```

### Changing the DB

```bash
$ dc exec api pipenv run flask db migrate -m "message"
$ dc exec api pipenv run flask db upgrade
```


### Recreate the db and blow away old versions

rm migrations/versions/*
Expand Down
26 changes: 12 additions & 14 deletions api/admin/resources/video.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import structlog

from flask import request
from flask_restful import Resource
from flask_jwt_extended import jwt_required

from api.models import Video
from api.jobs import ingest_video
Expand All @@ -12,20 +10,20 @@


class VideoEncode(Resource):
@super_admin_required
def post(self, video_id):
video = Video.query.get_or_404(video_id)
log.info("Enqueueing for encoding", video_id=video.id)
ingest_video.delay(video.id)
@super_admin_required
def post(self, video_id):
video = Video.query.get_or_404(video_id)
log.info("Enqueueing for encoding", video_id=video.id)
ingest_video.delay(video.id)

return "ok", 201
return "ok", 201


class VideoEncodeAll(Resource):
@super_admin_required
def post(self):
for video in Video.where(encoded_at=None):
log.info("Enqueueing for encoding", video_id=video.id)
ingest_video.delay(video.id)
@super_admin_required
def post(self):
for video in Video.where(encoded_at=None):
log.info("Enqueueing for encoding", video_id=video.id)
ingest_video.delay(video.id)

return "ok", 201
return "ok", 201
11 changes: 5 additions & 6 deletions api/app.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
import os
import sys
import uuid
import json
import logging
import structlog

from dynaconf import FlaskDynaconf
from flask import Flask, request
from flask import Flask
from flask_bcrypt import Bcrypt
from flask_cors import CORS
from flask_marshmallow import Marshmallow
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy as _BaseSQLAlchemy
from flask_marshmallow import Marshmallow
from sqlalchemy.exc import DatabaseError
from sqlalchemy_mixins import AllFeaturesMixin

import sentry_sdk
from sentry_sdk.integrations.flask import FlaskIntegration
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration

# TODO: Hook up sentry with sqlalchemy
# from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration


class SQLAlchemy(_BaseSQLAlchemy):
Expand All @@ -43,7 +42,7 @@ def create_app(name=__name__):
from api.jobs import celery

app = Flask(name)
FlaskDynaconf(app, ENVVAR_PREFIX_FOR_DYNACONF="FLASK_") # Initialize config
FlaskDynaconf(app, ENVVAR_PREFIX_FOR_DYNACONF="FLASK") # Initialize config
config_logging(app)
config_sentry(app)
config_db(app)
Expand Down
50 changes: 22 additions & 28 deletions api/auth.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from functools import wraps
from flask import request, jsonify
from flask import request, jsonify, abort

from flask_jwt_extended import verify_jwt_in_request, get_jwt_claims

Expand All @@ -16,6 +16,24 @@ def is_admin():
return get_role() == "admin" or is_super_admin()


def abortUnauthorized():
abort(
403, "You are not authorized to access this resource", error="UnauthorizedError"
)


def unauthorized():
return (
jsonify(
{
"error": "UnauthorizedError",
"message": "You are not authorized to access this resource",
}
),
403,
)


def super_admin_required(fn):
@wraps(fn)
def wrapper(*args, **kwargs):
Expand All @@ -24,15 +42,7 @@ def wrapper(*args, **kwargs):
if is_super_admin():
return fn(*args, **kwargs)
else:
return (
jsonify(
{
"error": "UnauthorizedError",
"message": "You are not authorized to access this resource",
}
),
403,
)
return unauthorized()

return wrapper

Expand All @@ -45,15 +55,7 @@ def wrapper(*args, **kwargs):
if get_role() in set(["super_admin", "admin"]):
return fn(*args, **kwargs)
else:
return (
jsonify(
{
"error": "UnauthorizedError",
"message": "You are not authorized to access this resource",
}
),
403,
)
return unauthorized()

return wrapper

Expand All @@ -66,14 +68,6 @@ def wrapper(*args, **kwargs):
if get_role() in set(["super_admin", "admin", "user"]):
return fn(*args, **kwargs)
else:
return (
jsonify(
{
"error": "UnauthorizedError",
"message": "You are not authorized to access this resource",
}
),
403,
)
return unauthorized()

return wrapper
8 changes: 2 additions & 6 deletions api/jobs.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import os
import uuid
import ffmpeg
import subprocess

import structlog
from dynaconf import settings
from celery import Celery

from celery import Celery

from api.ffmpeg import encode_mp4
from api.utils import get_redis_url

redis_url = get_redis_url()
Expand Down
Loading