From 4caebeb6be0740f3308a69404ee83a5c512ad77e Mon Sep 17 00:00:00 2001 From: Eliot Berriot <contact@eliotberriot.com> Date: Wed, 29 May 2019 01:15:24 +0200 Subject: [PATCH] WIP ASGI --- config/asgi.py | 9 +++++++ config/routing.py | 15 ++++++++++-- config/settings/base.py | 22 ++++++++--------- config/wsgi.py | 39 ------------------------------ retribute_api/search/consumers.py | 7 +++++- retribute_api/search/exceptions.py | 10 +++++--- retribute_api/search/webfinger.py | 8 +++++- 7 files changed, 52 insertions(+), 58 deletions(-) create mode 100644 config/asgi.py delete mode 100644 config/wsgi.py diff --git a/config/asgi.py b/config/asgi.py new file mode 100644 index 0000000..a2b51e7 --- /dev/null +++ b/config/asgi.py @@ -0,0 +1,9 @@ +import os + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.base") + +import django # noqa + +django.setup() + +from .routing import application # noqa diff --git a/config/routing.py b/config/routing.py index 1175710..cfe3534 100644 --- a/config/routing.py +++ b/config/routing.py @@ -1,6 +1,16 @@ +import os +import sys + +app_path = os.path.abspath( + os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir) +) +sys.path.append(os.path.join(app_path, "retribute_api")) +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.base") + + from django.conf.urls import url -from channels.routing import ProtocolTypeRouter, URLRouter +from channels.routing import ProtocolTypeRouter, URLRouter, AsgiHandler from retribute_api.search import consumers @@ -11,7 +21,8 @@ application = ProtocolTypeRouter( url( r"^api/v1/search/(?P<lookup_type>.+):(?P<lookup>.+)$", consumers.SearchSingleConsumer, - ) + ), + url(r"", AsgiHandler), ] ) } diff --git a/config/settings/base.py b/config/settings/base.py index 2aa5241..3c6f357 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -52,7 +52,7 @@ DATABASES["default"]["CONN_MAX_AGE"] = env.int("CONN_MAX_AGE", default=60) # no ROOT_URLCONF = "config.urls" # https://docs.djangoproject.com/en/dev/ref/settings/#wsgi-application WSGI_APPLICATION = "config.wsgi.application" - +ASGI_APPLICATION = "config.routing.application" # APPS # ------------------------------------------------------------------------------ DJANGO_APPS = [ @@ -63,7 +63,7 @@ DJANGO_APPS = [ "django.contrib.staticfiles", "django.contrib.admin", ] -THIRD_PARTY_APPS = ["rest_framework"] +THIRD_PARTY_APPS = ["rest_framework", "channels"] LOCAL_APPS = [ # Your stuff: custom apps go here ] @@ -180,15 +180,6 @@ EMAIL_BACKEND = env( "DJANGO_EMAIL_BACKEND", default="django.core.mail.backends.console.EmailBackend" ) -# ADMIN -# ------------------------------------------------------------------------------ -# Django Admin URL. -ADMIN_URL = "admin/" -# https://docs.djangoproject.com/en/dev/ref/settings/#admins -ADMINS = [("""Eliot Berriot""", "contact@eliotberriot.com")] -# https://docs.djangoproject.com/en/dev/ref/settings/#managers -MANAGERS = ADMINS - # LOGGING # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#logging @@ -228,6 +219,13 @@ ALLOWED_HOSTS = env.list("DJANGO_ALLOWED_HOSTS", default=["retribute.me"]) # ------------------------------------------------------------------------------ CACHES = {"default": env.cache()} +CHANNEL_LAYERS = { + "default": { + "BACKEND": "channels_redis.core.RedisChannelLayer", + "CONFIG": {"hosts": [CACHES["default"]["LOCATION"]]}, + } +} + # SECURITY # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#secure-proxy-ssl-header @@ -280,7 +278,7 @@ EMAIL_SUBJECT_PREFIX = env("DJANGO_EMAIL_SUBJECT_PREFIX", default="[Retribute AP # ADMIN # ------------------------------------------------------------------------------ # Django Admin URL regex. -ADMIN_URL = env("DJANGO_ADMIN_URL", default="^api/admin/") +ADMIN_URL = env("DJANGO_ADMIN_URL", default="admin/") # ------------------------------------------------------------------------------ # http://whitenoise.evans.io/en/latest/django.html#enable-whitenoise diff --git a/config/wsgi.py b/config/wsgi.py deleted file mode 100644 index 44972ce..0000000 --- a/config/wsgi.py +++ /dev/null @@ -1,39 +0,0 @@ -""" -WSGI config for Retribute API project. - -This module contains the WSGI application used by Django's development server -and any production WSGI deployments. It should expose a module-level variable -named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover -this application via the ``WSGI_APPLICATION`` setting. - -Usually you will have the standard Django WSGI application here, but it also -might make sense to replace the whole Django WSGI application with a custom one -that later delegates to the Django one. For example, you could introduce WSGI -middleware here, or combine a Django application with an application of another -framework. - -""" -import os -import sys - -from django.core.wsgi import get_wsgi_application - -# This allows easy placement of apps within the interior -# retribute_api directory. -app_path = os.path.abspath( - os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir) -) -sys.path.append(os.path.join(app_path, "retribute_api")) -# We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks -# if running multiple sites in the same mod_wsgi process. To fix this, use -# mod_wsgi daemon mode with each site in its own daemon process, or use -# os.environ["DJANGO_SETTINGS_MODULE"] = "config.settings.production" -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.production") - -# This application object is used by any WSGI server configured to use this -# file. This includes Django's development server, if the WSGI_APPLICATION -# setting points here. -application = get_wsgi_application() -# Apply WSGI middleware here. -# from helloworld.wsgi import HelloWorldApplication -# application = HelloWorldApplication(application) diff --git a/retribute_api/search/consumers.py b/retribute_api/search/consumers.py index 2cc4e2a..01a53ef 100644 --- a/retribute_api/search/consumers.py +++ b/retribute_api/search/consumers.py @@ -3,6 +3,7 @@ import json from channels.generic.http import AsyncHttpConsumer +from . import exceptions from . import sources @@ -23,9 +24,13 @@ class SearchSingleConsumer(AsyncHttpConsumer): except KeyError: await json_response(self, 400, {"detail": "Invalid lookup"}) try: + import ipdb + + ipdb.set_trace() async with aiohttp.client.ClientSession() as session: data = await source.get(lookup, session) - except Exception: + except exceptions.SearchError as e: + await json_response(self, 400, {"detail": e.message}) raise try: profile = sources.result_to_retribute_profile(lookup_type, lookup, data) diff --git a/retribute_api/search/exceptions.py b/retribute_api/search/exceptions.py index 19836fb..7c0f7a7 100644 --- a/retribute_api/search/exceptions.py +++ b/retribute_api/search/exceptions.py @@ -1,10 +1,14 @@ class SearchError(ValueError): - pass + message = "Error while retrieving remote profile" + + +class InvalidLookup(SearchError): + message = "Invalid lookup" class MeansNotFound(SearchError): - pass + message = "No payment means found on remote profile" class SkippedProfile(SearchError): - pass + message = "Profile skipped" diff --git a/retribute_api/search/webfinger.py b/retribute_api/search/webfinger.py index 84ed55f..9e8cc44 100644 --- a/retribute_api/search/webfinger.py +++ b/retribute_api/search/webfinger.py @@ -1,8 +1,14 @@ from rest_framework import serializers +from . import exceptions + async def lookup(name, session): - username, domain = name.split("@") + try: + username, domain = name.split("@") + except ValueError: + raise exceptions.InvalidLookup() + async with session.get( "https://{}/.well-known/webfinger".format(domain), params={"resource": "acct:{}".format(name)}, -- GitLab