Skip to content

Commit

Permalink
get dataset by uri instead of if in rest api (#25770)
Browse files Browse the repository at this point in the history
* get dataset by uri in rest api

* encode uri in test
  • Loading branch information
bbovenzi authored Aug 17, 2022
1 parent 1b1f3fa commit 94d3e78
Show file tree
Hide file tree
Showing 12 changed files with 192 additions and 158 deletions.
7 changes: 4 additions & 3 deletions airflow/api_connexion/endpoints/dataset_endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,18 @@

@security.requires_access([(permissions.ACTION_CAN_READ, permissions.RESOURCE_DATASET)])
@provide_session
def get_dataset(id: int, session: Session = NEW_SESSION) -> APIResponse:
def get_dataset(uri: str, session: Session = NEW_SESSION) -> APIResponse:
"""Get a Dataset"""
dataset = (
session.query(DatasetModel)
.filter(DatasetModel.uri == uri)
.options(joinedload(DatasetModel.consuming_dags), joinedload(DatasetModel.producing_tasks))
.get(id)
.one_or_none()
)
if not dataset:
raise NotFound(
"Dataset not found",
detail=f"The Dataset with id: `{id}` was not found",
detail=f"The Dataset with uri: `{uri}` was not found",
)
return dataset_schema.dump(dataset)

Expand Down
15 changes: 8 additions & 7 deletions airflow/api_connexion/openapi/v1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1667,12 +1667,12 @@ paths:
'403':
$ref: '#/components/responses/PermissionDenied'

/datasets/{id}:
/datasets/{uri}:
parameters:
- $ref: '#/components/parameters/DatasetID'
- $ref: '#/components/parameters/DatasetURI'
get:
summary: Get a dataset
description: Get a dataset by id.
description: Get a dataset by uri.
x-openapi-router-controller: airflow.api_connexion.endpoints.dataset_endpoint
operationId: get_dataset
tags: [Dataset]
Expand Down Expand Up @@ -4313,13 +4313,14 @@ components:
required: true
description: The import error ID.

DatasetID:
DatasetURI:
in: path
name: id
name: uri
schema:
type: integer
type: string
format: path
required: true
description: The Dataset ID
description: The encoded Dataset URI

PoolName:
in: path
Expand Down
8 changes: 4 additions & 4 deletions airflow/www/static/js/api/useDataset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ import { getMetaValue } from 'src/utils';
import type { API } from 'src/types';

interface Props {
datasetId: string;
datasetUri: string;
}

export default function useDataset({ datasetId }: Props) {
export default function useDataset({ datasetUri }: Props) {
return useQuery(
['dataset', datasetId],
['dataset', datasetUri],
() => {
const datasetUrl = `${getMetaValue('datasets_api') || '/api/v1/datasets'}/${datasetId}`;
const datasetUrl = `${getMetaValue('datasets_api') || '/api/v1/datasets'}/${encodeURIComponent(datasetUri)}`;
return axios.get<AxiosResponse, API.Dataset>(datasetUrl);
},
);
Expand Down
4 changes: 2 additions & 2 deletions airflow/www/static/js/api/useDatasetEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ interface DatasetEventsData {
}

interface Props {
datasetId?: string;
datasetId?: number;
dagId?: string;
taskId?: string;
runId?: string;
Expand All @@ -52,7 +52,7 @@ export default function useDatasetEvents({
if (limit) params.set('limit', limit.toString());
if (offset) params.set('offset', offset.toString());
if (order) params.set('order_by', order);
if (datasetId) params.set('dataset_id', datasetId);
if (datasetId) params.set('dataset_id', datasetId.toString());
if (dagId) params.set('source_dag_id', dagId);
if (runId) params.set('source_run_id', runId);
if (taskId) params.set('source_task_id', taskId);
Expand Down
4 changes: 2 additions & 2 deletions airflow/www/static/js/components/Table/Cells.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ interface CellProps {

export const TimeCell = ({ cell: { value } }: CellProps) => <Time dateTime={value} />;

export const DatasetLink = ({ cell: { value, row } }: CellProps) => {
export const DatasetLink = ({ cell: { value } }: CellProps) => {
const datasetsUrl = getMetaValue('datasets_url');
return (
<Link
color="blue.600"
href={`${datasetsUrl}?dataset_id=${row.original.datasetId}`}
href={`${datasetsUrl}?dataset_uri=${encodeURIComponent(value)}`}
>
{value}
</Link>
Expand Down
2 changes: 1 addition & 1 deletion airflow/www/static/js/datasetUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export function openDatasetModal(dagId, summary = '', nextDatasets = [], error =

const uriCell = document.createElement('td');
const datasetLink = document.createElement('a');
datasetLink.href = `${datasetsUrl}?dataset_id=${d.id}`;
datasetLink.href = `${datasetsUrl}?dataset_uri=${encodeURIComponent(d.id)}`;
datasetLink.innerText = d.uri;
uriCell.append(datasetLink);

Expand Down
89 changes: 89 additions & 0 deletions airflow/www/static/js/datasets/DatasetEvents.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*!
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import React, { useMemo, useState } from 'react';
import { snakeCase } from 'lodash';
import type { SortingRule } from 'react-table';

import { useDatasetEvents } from 'src/api';
import {
Table, TimeCell, TaskInstanceLink,
} from 'src/components/Table';

const Events = ({
datasetId,
}: { datasetId: number }) => {
const limit = 25;
const [offset, setOffset] = useState(0);
const [sortBy, setSortBy] = useState<SortingRule<object>[]>([{ id: 'timestamp', desc: true }]);

const sort = sortBy[0];
const order = sort ? `${sort.desc ? '-' : ''}${snakeCase(sort.id)}` : '';

const {
data: { datasetEvents, totalEntries },
isLoading: isEventsLoading,
} = useDatasetEvents({
datasetId, limit, offset, order,
});

const columns = useMemo(
() => [
{
Header: 'Source Task Instance',
accessor: 'sourceTaskId',
Cell: TaskInstanceLink,
},
{
Header: 'When',
accessor: 'timestamp',
Cell: TimeCell,
},
],
[],
);

const data = useMemo(
() => datasetEvents,
[datasetEvents],
);

const memoSort = useMemo(() => sortBy, [sortBy]);

return (
<Table
data={data}
columns={columns}
manualPagination={{
offset,
setOffset,
totalEntries,
}}
manualSort={{
setSortBy,
sortBy,
initialSortBy: memoSort,
}}
pageSize={limit}
isLoading={isEventsLoading}
/>
);
};

export default Events;
Loading

0 comments on commit 94d3e78

Please sign in to comment.