diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..eda7e40 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,40 @@ +name: CI +on: + push: + branches: + - main + pull_request: +jobs: + full_test_and_build: + name: full test and build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v1 + with: + python-version: 3.9 + - uses: snok/install-poetry@v1 + - run: poetry install + - name: Run backend tests + run: |- + poetry run python3 manage.py test + mypy: + name: mypy + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v1 + with: + python-version: 3.9 + - uses: snok/install-poetry@v1 + - run: |- + poetry install + poetry run mypy + black: + name: black + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: psf/black@stable + with: + src: "." diff --git a/frog_api/apps.py b/frog_api/apps.py index c5476ef..e98ec10 100644 --- a/frog_api/apps.py +++ b/frog_api/apps.py @@ -2,5 +2,5 @@ from django.apps import AppConfig class FrogApiConfig(AppConfig): - default_auto_field = 'django.db.models.BigAutoField' - name = 'frog_api' + default_auto_field = "django.db.models.BigAutoField" + name = "frog_api" diff --git a/frog_api/migrations/0001_initial.py b/frog_api/migrations/0001_initial.py index 0dcb040..56c59bc 100644 --- a/frog_api/migrations/0001_initial.py +++ b/frog_api/migrations/0001_initial.py @@ -8,7 +8,7 @@ class Migration(migrations.Migration): initial = True - dependencies = [] + dependencies: list[tuple[str, str]] = [] operations = [ migrations.CreateModel( diff --git a/frog_api/views.py b/frog_api/views.py index 4d8971d..e8f5dae 100644 --- a/frog_api/views.py +++ b/frog_api/views.py @@ -1,6 +1,8 @@ +from typing import Any from rest_framework import status from rest_framework.exceptions import APIException from rest_framework.response import Response +from rest_framework.request import Request from rest_framework.views import APIView from frog_api.models import Category, Entry, Project, Version @@ -19,7 +21,7 @@ class ProjectView(APIView): API endpoint that allows projects to be viewed. """ - def get(self, request, format=None): + def get(self, request: Request) -> Response: """ Return a list of all projects. """ @@ -28,11 +30,9 @@ class ProjectView(APIView): return Response(serializer.data) -def get_latest_entry(project, version, category) -> dict: +def get_latest_entry(project: str, version: str, category: str) -> dict[Any, Any]: if not Project.objects.filter(slug=project).exists(): - raise MissingModelException( - f"Project {project} not found", code=status.HTTP_404_NOT_FOUND - ) + raise MissingModelException(f"Project {project} not found") if not Version.objects.filter(slug=version, project__slug=project).exists(): raise MissingModelException( @@ -63,7 +63,7 @@ def get_latest_entry(project, version, category) -> dict: return entry_data -def get_versions_digest_for_project(project) -> dict: +def get_versions_digest_for_project(project: str) -> dict[Any, Any]: versions = {} for version in Version.objects.filter(project__slug=project): entry = get_latest_entry(project, version.slug, "total") @@ -77,7 +77,7 @@ class RootDigestView(APIView): API endpoint that returns the most recent entry for each version of each project. """ - def get(self, request): + def get(self, request: Request) -> Response: """ Return the most recent entry for ovreall progress for each version of each project. """ @@ -96,7 +96,7 @@ class ProjectDigestView(APIView): API endpoint that returns the most recent entry for each version of a project. """ - def get(self, request, project): + def get(self, request: Request, project: str) -> Response: """ Return the most recent entry for overall progress for each version of a project. """ @@ -118,7 +118,7 @@ class VersionDigestView(APIView): API endpoint that returns the most recent entry for overall progress for a version of a project. """ - def get(self, request, project, version): + def get(self, request: Request, project: str, version: str) -> Response: """ Return the most recent entry for overall progress for a version of a project. """ @@ -133,7 +133,9 @@ class CategoryDigestView(APIView): API endpoint that returns the most recent entry for a specific cagory and a version of a project. """ - def get(self, request, project, version, category): + def get( + self, request: Request, project: str, version: str, category: str + ) -> Response: """ Return the most recent entry for a specific cagory and a version of a project. """ diff --git a/frogress/asgi.py b/frogress/asgi.py index aa44513..ca9c3c9 100644 --- a/frogress/asgi.py +++ b/frogress/asgi.py @@ -11,6 +11,6 @@ import os from django.core.asgi import get_asgi_application -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'frogress.settings') +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "frogress.settings") application = get_asgi_application() diff --git a/frogress/settings.py b/frogress/settings.py index 607cc50..4f52c79 100644 --- a/frogress/settings.py +++ b/frogress/settings.py @@ -25,7 +25,7 @@ SECRET_KEY = "django-insecure-4g&!7-muxr8a*6!pxk$agny_3z5w_bztudcbb7(*@ynco%$c6k # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True -ALLOWED_HOSTS = [] +ALLOWED_HOSTS: list[str] = [] # Application definition diff --git a/frogress/urls.py b/frogress/urls.py index 7965f7f..7537353 100644 --- a/frogress/urls.py +++ b/frogress/urls.py @@ -2,6 +2,6 @@ from django.contrib import admin from django.urls import path, include urlpatterns = [ - path('', include('frog_api.urls')), + path("", include("frog_api.urls")), path("admin/", admin.site.urls), ] diff --git a/frogress/wsgi.py b/frogress/wsgi.py index a7106b7..6383b36 100644 --- a/frogress/wsgi.py +++ b/frogress/wsgi.py @@ -11,6 +11,6 @@ import os from django.core.wsgi import get_wsgi_application -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'frogress.settings') +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "frogress.settings") application = get_wsgi_application() diff --git a/manage.py b/manage.py index 95d512a..0eab5d0 100755 --- a/manage.py +++ b/manage.py @@ -6,7 +6,7 @@ import sys def main(): """Run administrative tasks.""" - os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'frogress.settings') + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "frogress.settings") try: from django.core.management import execute_from_command_line except ImportError as exc: @@ -18,5 +18,5 @@ def main(): execute_from_command_line(sys.argv) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/mypy.ini b/mypy.ini index bb8b722..a3f0cd4 100644 --- a/mypy.ini +++ b/mypy.ini @@ -22,8 +22,12 @@ namespace_packages = True disallow_untyped_defs = True files = - frogress/**/*.py + frogress/**/*.py, + frog_api/**/*.py plugins = mypy_django_plugin.main, mypy_drf_plugin.main + +[mypy.plugins.django-stubs] +django_settings_module = frogress.settings \ No newline at end of file