From 18bcf55f784038d43b4609fc6c1936322c711058 Mon Sep 17 00:00:00 2001 From: Nikhil <118773738+pablohashescobar@users.noreply.github.com> Date: Wed, 4 Oct 2023 19:06:38 +0530 Subject: [PATCH] dev: configuration endpoint for frontend client (#2355) * dev: configuration endpoint for frontend clients * dev: configuration enable magic and email/password signup * dev: update unsplash keys * dev: add unsplash API and add env for magic login --- apiserver/.env.example | 8 ++++ apiserver/plane/api/urls.py | 28 ++++++++---- apiserver/plane/api/views/__init__.py | 9 ++-- apiserver/plane/api/views/config.py | 40 +++++++++++++++++ .../plane/api/views/{gpt.py => external.py} | 45 ++++++++++++++++++- apiserver/plane/api/views/release.py | 21 --------- apiserver/plane/settings/local.py | 3 ++ apiserver/plane/settings/production.py | 4 ++ apiserver/plane/settings/selfhosted.py | 1 + apiserver/plane/settings/staging.py | 4 ++ 10 files changed, 128 insertions(+), 35 deletions(-) create mode 100644 apiserver/plane/api/views/config.py rename apiserver/plane/api/views/{gpt.py => external.py} (62%) delete mode 100644 apiserver/plane/api/views/release.py diff --git a/apiserver/.env.example b/apiserver/.env.example index 8772dfd53..8193b5e77 100644 --- a/apiserver/.env.example +++ b/apiserver/.env.example @@ -60,5 +60,13 @@ DEFAULT_PASSWORD="password123" # SignUps ENABLE_SIGNUP="1" + +# Enable Email/Password Signup +ENABLE_EMAIL_PASSWORD="1" + +# Enable Magic link Login +ENABLE_MAGIC_LINK_LOGIN="0" + # Email redirections and minio domain settings WEB_URL="http://localhost" + diff --git a/apiserver/plane/api/urls.py b/apiserver/plane/api/urls.py index c10c4a745..7d6b8e83d 100644 --- a/apiserver/plane/api/urls.py +++ b/apiserver/plane/api/urls.py @@ -150,12 +150,11 @@ from plane.api.views import ( GlobalSearchEndpoint, IssueSearchEndpoint, ## End Search - # Gpt + # External GPTIntegrationEndpoint, - ## End Gpt - # Release Notes ReleaseNotesEndpoint, - ## End Release Notes + UnsplashEndpoint, + ## End External # Inbox InboxViewSet, InboxIssueViewSet, @@ -186,6 +185,9 @@ from plane.api.views import ( ## Exporter ExportIssuesEndpoint, ## End Exporter + # Configuration + ConfigurationEndpoint, + ## End Configuration ) @@ -1446,20 +1448,23 @@ urlpatterns = [ name="project-issue-search", ), ## End Search - # Gpt + # External path( "workspaces//projects//ai-assistant/", GPTIntegrationEndpoint.as_view(), name="importer", ), - ## End Gpt - # Release Notes path( "release-notes/", ReleaseNotesEndpoint.as_view(), name="release-notes", ), - ## End Release Notes + path( + "unsplash/", + UnsplashEndpoint.as_view(), + name="release-notes", + ), + ## End External # Inbox path( "workspaces//projects//inboxes/", @@ -1728,4 +1733,11 @@ urlpatterns = [ name="workspace-project-boards", ), ## End Public Boards + # Configuration + path( + "configs/", + ConfigurationEndpoint.as_view(), + name="configuration", + ), + ## End Configuration ] diff --git a/apiserver/plane/api/views/__init__.py b/apiserver/plane/api/views/__init__.py index c03d6d5b7..35863a7c0 100644 --- a/apiserver/plane/api/views/__init__.py +++ b/apiserver/plane/api/views/__init__.py @@ -147,16 +147,13 @@ from .page import ( from .search import GlobalSearchEndpoint, IssueSearchEndpoint -from .gpt import GPTIntegrationEndpoint +from .external import GPTIntegrationEndpoint, ReleaseNotesEndpoint, UnsplashEndpoint from .estimate import ( ProjectEstimatePointEndpoint, BulkEstimatePointEndpoint, ) - -from .release import ReleaseNotesEndpoint - from .inbox import InboxViewSet, InboxIssueViewSet, InboxIssuePublicViewSet from .analytic import ( @@ -169,4 +166,6 @@ from .analytic import ( from .notification import NotificationViewSet, UnreadNotificationEndpoint, MarkAllReadNotificationViewSet -from .exporter import ExportIssuesEndpoint \ No newline at end of file +from .exporter import ExportIssuesEndpoint + +from .config import ConfigurationEndpoint \ No newline at end of file diff --git a/apiserver/plane/api/views/config.py b/apiserver/plane/api/views/config.py new file mode 100644 index 000000000..ea1b39d9c --- /dev/null +++ b/apiserver/plane/api/views/config.py @@ -0,0 +1,40 @@ +# Python imports +import os + +# Django imports +from django.conf import settings + +# Third party imports +from rest_framework.permissions import AllowAny +from rest_framework import status +from rest_framework.response import Response +from sentry_sdk import capture_exception + +# Module imports +from .base import BaseAPIView + + +class ConfigurationEndpoint(BaseAPIView): + permission_classes = [ + AllowAny, + ] + + def get(self, request): + try: + data = {} + data["google"] = os.environ.get("GOOGLE_CLIENT_ID", None) + data["github"] = os.environ.get("GITHUB_CLIENT_ID", None) + data["github_app_name"] = os.environ.get("GITHUB_APP_NAME", None) + data["magic_login"] = ( + bool(settings.EMAIL_HOST_USER) and bool(settings.EMAIL_HOST_PASSWORD) + ) and os.environ.get("ENABLE_MAGIC_LINK_LOGIN", "0") == "1" + data["email_password_login"] = ( + os.environ.get("ENABLE_EMAIL_PASSWORD", "0") == "1" + ) + return Response(data, status=status.HTTP_200_OK) + except Exception as e: + capture_exception(e) + return Response( + {"error": "Something went wrong please try again later"}, + status=status.HTTP_400_BAD_REQUEST, + ) diff --git a/apiserver/plane/api/views/gpt.py b/apiserver/plane/api/views/external.py similarity index 62% rename from apiserver/plane/api/views/gpt.py rename to apiserver/plane/api/views/external.py index 63c3f4f18..00a0270e4 100644 --- a/apiserver/plane/api/views/gpt.py +++ b/apiserver/plane/api/views/external.py @@ -2,9 +2,10 @@ import requests # Third party imports +import openai from rest_framework.response import Response from rest_framework import status -import openai +from rest_framework.permissions import AllowAny from sentry_sdk import capture_exception # Django imports @@ -15,6 +16,7 @@ from .base import BaseAPIView from plane.api.permissions import ProjectEntityPermission from plane.db.models import Workspace, Project from plane.api.serializers import ProjectLiteSerializer, WorkspaceLiteSerializer +from plane.utils.integrations.github import get_release_notes class GPTIntegrationEndpoint(BaseAPIView): @@ -73,3 +75,44 @@ class GPTIntegrationEndpoint(BaseAPIView): {"error": "Something went wrong please try again later"}, status=status.HTTP_400_BAD_REQUEST, ) + + +class ReleaseNotesEndpoint(BaseAPIView): + def get(self, request): + try: + release_notes = get_release_notes() + return Response(release_notes, status=status.HTTP_200_OK) + except Exception as e: + capture_exception(e) + return Response( + {"error": "Something went wrong please try again later"}, + status=status.HTTP_400_BAD_REQUEST, + ) + + +class UnsplashEndpoint(BaseAPIView): + + def get(self, request): + try: + query = request.GET.get("query", False) + page = request.GET.get("page", 1) + per_page = request.GET.get("per_page", 20) + + url = ( + f"https://api.unsplash.com/search/photos/?client_id={settings.UNSPLASH_ACCESS_KEY}&query={query}&page=${page}&per_page={per_page}" + if query + else f"https://api.unsplash.com/photos/?client_id={settings.UNSPLASH_ACCESS_KEY}&page={page}&per_page={per_page}" + ) + + headers = { + "Content-Type": "application/json", + } + + resp = requests.get(url=url, headers=headers) + return Response(resp.json(), status=status.HTTP_200_OK) + except Exception as e: + capture_exception(e) + return Response( + {"error": "Something went wrong please try again later"}, + status=status.HTTP_400_BAD_REQUEST, + ) diff --git a/apiserver/plane/api/views/release.py b/apiserver/plane/api/views/release.py deleted file mode 100644 index de827c896..000000000 --- a/apiserver/plane/api/views/release.py +++ /dev/null @@ -1,21 +0,0 @@ -# Third party imports -from rest_framework.response import Response -from rest_framework import status -from sentry_sdk import capture_exception - -# Module imports -from .base import BaseAPIView -from plane.utils.integrations.github import get_release_notes - - -class ReleaseNotesEndpoint(BaseAPIView): - def get(self, request): - try: - release_notes = get_release_notes() - return Response(release_notes, status=status.HTTP_200_OK) - except Exception as e: - capture_exception(e) - return Response( - {"error": "Something went wrong please try again later"}, - status=status.HTTP_400_BAD_REQUEST, - ) diff --git a/apiserver/plane/settings/local.py b/apiserver/plane/settings/local.py index 9d293c019..6f4833a6c 100644 --- a/apiserver/plane/settings/local.py +++ b/apiserver/plane/settings/local.py @@ -114,3 +114,6 @@ CELERY_BROKER_URL = os.environ.get("REDIS_URL") GITHUB_ACCESS_TOKEN = os.environ.get("GITHUB_ACCESS_TOKEN", False) ENABLE_SIGNUP = os.environ.get("ENABLE_SIGNUP", "1") == "1" + +# Unsplash Access key +UNSPLASH_ACCESS_KEY = os.environ.get("UNSPLASH_ACCESS_KEY") diff --git a/apiserver/plane/settings/production.py b/apiserver/plane/settings/production.py index 170a2067c..9c6bd95a9 100644 --- a/apiserver/plane/settings/production.py +++ b/apiserver/plane/settings/production.py @@ -275,3 +275,7 @@ ENABLE_SIGNUP = os.environ.get("ENABLE_SIGNUP", "1") == "1" SCOUT_MONITOR = os.environ.get("SCOUT_MONITOR", False) SCOUT_KEY = os.environ.get("SCOUT_KEY", "") SCOUT_NAME = "Plane" + +# Unsplash Access key +UNSPLASH_ACCESS_KEY = os.environ.get("UNSPLASH_ACCESS_KEY") + diff --git a/apiserver/plane/settings/selfhosted.py b/apiserver/plane/settings/selfhosted.py index 948ba22da..ee529a7c3 100644 --- a/apiserver/plane/settings/selfhosted.py +++ b/apiserver/plane/settings/selfhosted.py @@ -126,3 +126,4 @@ ANALYTICS_BASE_API = False OPENAI_API_BASE = os.environ.get("OPENAI_API_BASE", "https://api.openai.com/v1") OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY", False) GPT_ENGINE = os.environ.get("GPT_ENGINE", "gpt-3.5-turbo") + diff --git a/apiserver/plane/settings/staging.py b/apiserver/plane/settings/staging.py index 5e274f8f3..f776afd91 100644 --- a/apiserver/plane/settings/staging.py +++ b/apiserver/plane/settings/staging.py @@ -218,3 +218,7 @@ CELERY_BROKER_URL = broker_url GITHUB_ACCESS_TOKEN = os.environ.get("GITHUB_ACCESS_TOKEN", False) ENABLE_SIGNUP = os.environ.get("ENABLE_SIGNUP", "1") == "1" + + +# Unsplash Access key +UNSPLASH_ACCESS_KEY = os.environ.get("UNSPLASH_ACCESS_KEY")