Skip to content

Commit

Permalink
[api] Add all APIs for Sql Scratchpad
Browse files Browse the repository at this point in the history
  • Loading branch information
romainr committed May 27, 2021
1 parent cd1b675 commit be01df6
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 72 deletions.
9 changes: 7 additions & 2 deletions desktop/core/src/desktop/api_public.py
Expand Up @@ -17,9 +17,16 @@

from rest_framework.decorators import api_view

from desktop import api2 as desktop_api
from notebook import api as notebook_api


@api_view(["POST"])
def get_config(request):
django_request = request._request
return desktop_api.get_config(django_request)


@api_view(["POST"])
def create_notebook(request):
django_request = request._request
Expand Down Expand Up @@ -70,14 +77,12 @@ def close_statement(request):
django_request = request._request
return notebook_api.close_statement(django_request)


@api_view(["POST"])
def get_logs(request):
django_request = request._request
return notebook_api.get_logs(django_request)



@api_view(["POST"])
def autocomplete(request, server=None, database=None, table=None, column=None, nested=None):
django_request = request._request
Expand Down
53 changes: 25 additions & 28 deletions desktop/core/src/desktop/api_public_urls.py
Expand Up @@ -25,52 +25,49 @@
from django.conf.urls import url as re_path


# New "query" API
# https://demo.gethue.com/api/query
#
# https://demo.gethue.com/api/query/execute/hive
# https://demo.gethue.com/api/query/status
# https://demo.gethue.com/api/query/result
# https://demo.gethue.com/api/query/logs
# "New" query API (i.e. connector based, lean arguments).
# e.g. https://demo.gethue.com/api/query/execute/hive
urlpatterns = [
re_path(r'^query/create_notebook/?$', api_public.create_notebook, name='api_create_notebook'),
re_path(r'^query/autocomplete/?$', api_public.autocomplete, name='api_autocomplete_databases'),
]

# Compatibility with private API
# https://demo.gethue.com/notebook/api/editor/execute/hive
# Compatibility with "old" private API.
# e.g. https://demo.gethue.com/notebook/api/execute/hive
urlpatterns += [
re_path(r'^create_notebook/?$', api_public.create_notebook, name='api_create_notebook'),
re_path(r'^create_session/?$', api_public.create_session, name='create_session'),
re_path(r'^close_session/?$', api_public.close_session, name='close_session'),
re_path(r'^execute(?:/(?P<dialect>.+))?/?$', api_public.execute, name='execute'),
re_path(r'^check_status/?$', api_public.check_status, name='check_status'),
re_path(r'^fetch_result_data/?$', api_public.fetch_result_data, name='fetch_result_data'),
re_path(r'^fetch_result_metadata/?$', api_public.fetch_result_metadata, name='fetch_result_metadata'),
re_path(r'^fetch_result_size/?$', api_public.fetch_result_size, name='fetch_result_size'),
re_path(r'^cancel_statement/?$', api_public.cancel_statement, name='cancel_statement'),
re_path(r'^close_statement/?$', api_public.close_statement, name='close_statement'),
re_path(r'^get_logs/?$', api_public.get_logs, name='get_logs'),
re_path(r'^iam/get_config/?$', api_public.get_config),

re_path(r'^editor/create_notebook/?$', api_public.create_notebook, name='api_create_notebook'),
re_path(r'^editor/create_session/?$', api_public.create_session, name='api_create_session'),
re_path(r'^editor/close_session/?$', api_public.close_session, name='api_close_session'),
re_path(r'^editor/execute(?:/(?P<dialect>.+))?/?$', api_public.execute, name='api_execute'),
re_path(r'^editor/check_status/?$', api_public.check_status, name='api_check_status'),
re_path(r'^editor/fetch_result_data/?$', api_public.fetch_result_data, name='api_fetch_result_data'),
re_path(r'^editor/fetch_result_metadata/?$', api_public.fetch_result_metadata, name='api_fetch_result_metadata'),
re_path(r'^editor/fetch_result_size/?$', api_public.fetch_result_size, name='api_fetch_result_size'),
re_path(r'^editor/cancel_statement/?$', api_public.cancel_statement, name='api_cancel_statement'),
re_path(r'^editor/close_statement/?$', api_public.close_statement, name='api_close_statement'),
re_path(r'^editor/get_logs/?$', api_public.get_logs, name='api_get_logs'),

re_path(r'^editor/autocomplete/?$', api_public.autocomplete, name='api_autocomplete_databases'),
re_path(
r"^autocomplete/(?P<database>[^/?]*)/?$",
r"^editor/autocomplete/(?P<database>[^/?]*)/?$",
api_public.autocomplete,
name="autocomplete_tables",
name="api_autocomplete_tables",
),
re_path(
r"^autocomplete/(?P<database>[^/?]*)/(?P<table>[\w_\-]+)/?$",
r"^editor/autocomplete/(?P<database>[^/?]*)/(?P<table>[\w_\-]+)/?$",
api_public.autocomplete,
name="autocomplete_columns",
name="api_autocomplete_columns",
),
re_path(
r"^autocomplete/(?P<database>[^/?]*)/(?P<table>[\w_\-]+)/(?P<column>\w+)/?$",
r"^editor/autocomplete/(?P<database>[^/?]*)/(?P<table>[\w_\-]+)/(?P<column>\w+)/?$",
api_public.autocomplete,
name="autocomplete_column",
name="api_autocomplete_column",
),
re_path(
r"^autocomplete/(?P<database>[^/?]*)/(?P<table>[\w_\-]+)/(?P<column>\w+)/(?P<nested>.+)/?$",
r"^editor/autocomplete/(?P<database>[^/?]*)/(?P<table>[\w_\-]+)/(?P<column>\w+)/(?P<nested>.+)/?$",
api_public.autocomplete,
name="autocomplete_nested",
name="api_autocomplete_nested",
),
]
33 changes: 6 additions & 27 deletions desktop/core/src/desktop/js/api/auth.ts
Expand Up @@ -14,35 +14,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import { get, post } from 'api/utils';
import { post } from 'api/utils';

export enum AuthType {
hue = 'hue',
jwt = 'jwt'
}
const JWT_URL = 'api/iam/token/auth/';

const LOGOUT_URL = '/hue/accounts/logout';
const LOGIN_URL = '/hue/accounts/login';

const JWT_URL = 'iam/v1/get/auth-token/';

export const login = async (
username: string,
password: string,
auth = AuthType.jwt
): Promise<void> => {
if (auth === AuthType.jwt) {
export const login = async (username: string, email: string, password: string): Promise<void> => {
if (email !== '') {
return post(JWT_URL, { email, password });
} else {
return post(JWT_URL, { username, password });
}

if (auth === AuthType.hue) {
await get(LOGOUT_URL);
const response = await get<string>(LOGIN_URL);
const csrfMatch = response.match(/name='csrfmiddlewaretoken'\s+value='([^']+)'/);
if (csrfMatch) {
return post(LOGIN_URL, { username, password, csrfmiddlewaretoken: csrfMatch[1] });
}
throw new Error('No csrf middleware token found!');
}
throw new Error('Unknown auth method specified!');
};
Expand Up @@ -66,7 +66,7 @@
import ResultTable from '../result/ResultTable.vue';
import Executor from '../../execution/executor';
import SqlExecutable from '../../execution/sqlExecutable';
import { AuthType, login } from 'api/auth';
import { login } from 'api/auth';
import { setBaseUrl } from 'api/utils';
import contextCatalog from 'catalog/contextCatalog';
import HueIcons from 'components/icons/HueIcons.vue';
Expand All @@ -87,29 +87,29 @@
AceEditor
},
props: {
dialect: {
apiUrl: {
type: String as PropType<string | null>,
default: null
},
auth: {
type: String as PropType<AuthType | null>,
default: AuthType.jwt
dialect: {
type: String as PropType<string | null>,
default: null
},
user: {
username: {
type: String as PropType<string | null>,
default: null
},
password: {
email: {
type: String as PropType<string | null>,
default: null
},
apiUrl: {
password: {
type: String as PropType<string | null>,
default: null
}
},
setup(props) {
const { apiUrl, auth, dialect, pass, user } = toRefs(props);
const { apiUrl, dialect, username, email, password } = toRefs(props);
const activeExecutable = ref<SqlExecutable>(null);
const executor = ref<Executor>(null);
const loading = ref<boolean>(true);
Expand Down Expand Up @@ -140,9 +140,13 @@
setBaseUrl(apiUrl.value);
}
if (user.value !== null && pass.value !== null) {
if (password.value !== null) {
try {
await login(user.value, pass.value, auth.value);
await login(
username.value ? username.value : '',
email.value ? email.value : '',
password.value
);
} catch (err) {
errorMessage.value = 'Login failed!';
console.error(err);
Expand Down
Expand Up @@ -22,6 +22,7 @@ import 'utils/json.bigDataParse';

wrap('sql-scratchpad', SqlScratchpad);

// Dup of auth.ts?
const login = async (username: string, password: string): Promise<void> =>
post('iam/v1/get/auth-token/', { username, password });

Expand Down
1 change: 1 addition & 0 deletions desktop/core/src/desktop/settings.py
Expand Up @@ -385,6 +385,7 @@
MIDDLEWARE.remove('django.middleware.csrf.CsrfViewMiddleware')
if sys.version_info[0] > 2:
CORS_ALLOW_ALL_ORIGINS = True
# CORS_URLS_REGEX = r'^/api/.*$'
else:
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True # For when cookie auth
Expand Down
6 changes: 3 additions & 3 deletions desktop/core/src/desktop/urls.py
Expand Up @@ -208,9 +208,9 @@
]

dynamic_patterns += [
re_path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
re_path('api/token/verify/', TokenVerifyView.as_view(), name='token_verify'),
re_path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
re_path('api/iam/token/refresh/?$', TokenRefreshView.as_view(), name='token_refresh'),
re_path('api/iam/token/verify/?$', TokenVerifyView.as_view(), name='token_verify'),
re_path('api/iam/token/auth/?$', TokenObtainPairView.as_view(), name='token_obtain_pair'),

re_path(r'^api/', include('desktop.api_public_urls')),
]
Expand Down
Expand Up @@ -21,7 +21,7 @@ We have the `gethue` [dependency](/developer/components/) in `packages.json` or

<body>
<div style="position: absolute; height: 100%; width: 100%">
<sql-scratchpad api-url="http://localhost:8005" dialect="mysql" />
<sql-scratchpad api-url="http://localhost:8005" username="demo" password="demo" dialect="mysql" />
</div>
</body>

Expand Down

0 comments on commit be01df6

Please sign in to comment.