Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
AmendsenProject
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Shaik Janipasha
AmendsenProject
Commits
69bf5b77
Unverified
Commit
69bf5b77
authored
Mar 25, 2020
by
Jin Hyuk Chang
Committed by
GitHub
Mar 25, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Dashboard usage model (#226)
* Added Dashboard usage model * Update * Update * Update
parent
3a141f96
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
170 additions
and
5 deletions
+170
-5
db_api_extractor.py
databuilder/extractor/db_api_extractor.py
+1
-0
column_usage_model.py
databuilder/models/column_usage_model.py
+6
-4
dashboard_usage.py
databuilder/models/dashboard/dashboard_usage.py
+96
-0
__init__.py
databuilder/models/usage/__init__.py
+0
-0
usage_constants.py
databuilder/models/usage/usage_constants.py
+7
-0
setup.py
setup.py
+1
-1
test_dashboard_usage.py
tests/unit/models/dashboard/test_dashboard_usage.py
+59
-0
No files found.
databuilder/extractor/db_api_extractor.py
View file @
69bf5b77
...
...
@@ -46,6 +46,7 @@ class DBAPIExtractor(Extractor):
Use cursor to execute the {sql}
:return:
"""
LOGGER
.
info
(
'Executing query:
\n
{}'
.
format
(
self
.
sql
))
self
.
cursor
.
execute
(
self
.
sql
)
return
self
.
cursor
.
fetchall
()
...
...
databuilder/models/column_usage_model.py
View file @
69bf5b77
...
...
@@ -4,9 +4,11 @@ from databuilder.models.neo4j_csv_serde import (
Neo4jCsvSerializable
,
RELATION_START_KEY
,
RELATION_END_KEY
,
RELATION_START_LABEL
,
RELATION_END_LABEL
,
RELATION_TYPE
,
RELATION_REVERSE_TYPE
)
from
databuilder.models.usage.usage_constants
import
(
READ_RELATION_TYPE
,
READ_REVERSE_RELATION_TYPE
,
READ_RELATION_COUNT_PROPERTY
)
from
databuilder.models.table_metadata
import
TableMetadata
from
databuilder.models.user
import
User
from
databuilder.publisher.neo4j_csv_publisher
import
UNQUOTED_SUFFIX
class
ColumnUsageModel
(
Neo4jCsvSerializable
):
...
...
@@ -18,11 +20,11 @@ class ColumnUsageModel(Neo4jCsvSerializable):
TABLE_NODE_LABEL
=
TableMetadata
.
TABLE_NODE_LABEL
TABLE_NODE_KEY_FORMAT
=
TableMetadata
.
TABLE_KEY_FORMAT
USER_TABLE_RELATION_TYPE
=
'READ'
TABLE_USER_RELATION_TYPE
=
'READ_BY'
USER_TABLE_RELATION_TYPE
=
READ_RELATION_TYPE
TABLE_USER_RELATION_TYPE
=
READ_REVERSE_RELATION_TYPE
# Property key for relationship read, readby relationship
READ_RELATION_COUNT
=
'read_count{}'
.
format
(
UNQUOTED_SUFFIX
)
READ_RELATION_COUNT
=
READ_RELATION_COUNT_PROPERTY
def
__init__
(
self
,
database
,
# type: str
...
...
databuilder/models/dashboard/dashboard_usage.py
0 → 100644
View file @
69bf5b77
import
logging
from
typing
import
Optional
,
Dict
,
Any
,
Union
,
Iterator
# noqa: F401
from
databuilder.models.dashboard.dashboard_metadata
import
DashboardMetadata
from
databuilder.models.neo4j_csv_serde
import
(
Neo4jCsvSerializable
,
RELATION_START_KEY
,
RELATION_END_KEY
,
RELATION_START_LABEL
,
RELATION_END_LABEL
,
RELATION_TYPE
,
RELATION_REVERSE_TYPE
)
from
databuilder.models.usage.usage_constants
import
(
READ_RELATION_TYPE
,
READ_REVERSE_RELATION_TYPE
,
READ_RELATION_COUNT_PROPERTY
)
from
databuilder.models.user
import
User
LOGGER
=
logging
.
getLogger
(
__name__
)
class
DashboardUsage
(
Neo4jCsvSerializable
):
"""
A model that encapsulate Dashboard usage between Dashboard and User
"""
def
__init__
(
self
,
dashboard_group_id
,
# type: Optional[str]
dashboard_id
,
# type: Optional[str]
email
,
# type: str
view_count
,
# type: int
should_create_user_node
=
False
,
# type: Optional[bool]
product
=
''
,
# type: Optional[str]
cluster
=
'gold'
,
# type: Optional[str]
**
kwargs
):
# type: () -> None
"""
:param dashboard_group_id:
:param dashboard_id:
:param email:
:param view_count:
:param should_create_user_node: Enable this if it is fine to create/update User node with only with email
address. Please be advised that other fields will be emptied. Current use case is to create anonymous user.
For example, Mode dashboard does not provide which user viewed the dashboard and anonymous user can be used
to show the usage.
:param product:
:param cluster:
:param kwargs:
"""
self
.
_dashboard_group_id
=
dashboard_group_id
self
.
_dashboard_id
=
dashboard_id
self
.
_email
=
email
self
.
_view_count
=
view_count
self
.
_product
=
product
self
.
_cluster
=
cluster
self
.
_user_model
=
User
(
email
=
email
)
self
.
_should_create_user_node
=
bool
(
should_create_user_node
)
self
.
_relation_iterator
=
self
.
_create_relation_iterator
()
def
create_next_node
(
self
):
# type: () -> Union[Dict[str, Any], None]
if
self
.
_should_create_user_node
:
return
self
.
_user_model
.
create_next_node
()
def
create_next_relation
(
self
):
# type: () -> Union[Dict[str, Any], None]
try
:
return
next
(
self
.
_relation_iterator
)
except
StopIteration
:
return
None
def
_create_relation_iterator
(
self
):
# type: () -> Iterator[[Dict[str, Any]]]
yield
{
RELATION_START_LABEL
:
DashboardMetadata
.
DASHBOARD_NODE_LABEL
,
RELATION_END_LABEL
:
User
.
USER_NODE_LABEL
,
RELATION_START_KEY
:
DashboardMetadata
.
DASHBOARD_KEY_FORMAT
.
format
(
product
=
self
.
_product
,
cluster
=
self
.
_cluster
,
dashboard_group
=
self
.
_dashboard_group_id
,
dashboard_name
=
self
.
_dashboard_id
),
RELATION_END_KEY
:
User
.
get_user_model_key
(
email
=
self
.
_email
),
RELATION_TYPE
:
READ_REVERSE_RELATION_TYPE
,
RELATION_REVERSE_TYPE
:
READ_RELATION_TYPE
,
READ_RELATION_COUNT_PROPERTY
:
self
.
_view_count
}
def
__repr__
(
self
):
return
'DashboardUsage({!r}, {!r}, {!r}, {!r}, {!r}, {!r}, {!r})'
.
format
(
self
.
_dashboard_group_id
,
self
.
_dashboard_id
,
self
.
_email
,
self
.
_view_count
,
self
.
_should_create_user_node
,
self
.
_product
,
self
.
_cluster
)
databuilder/models/usage/__init__.py
0 → 100644
View file @
69bf5b77
databuilder/models/usage/usage_constants.py
0 → 100644
View file @
69bf5b77
from
databuilder.publisher.neo4j_csv_publisher
import
UNQUOTED_SUFFIX
READ_RELATION_TYPE
=
'READ'
READ_REVERSE_RELATION_TYPE
=
'READ_BY'
READ_RELATION_COUNT_PROPERTY
=
'read_count{}'
.
format
(
UNQUOTED_SUFFIX
)
setup.py
View file @
69bf5b77
...
...
@@ -2,7 +2,7 @@ import os
from
setuptools
import
setup
,
find_packages
__version__
=
'2.4.
1
'
__version__
=
'2.4.
2
'
requirements_path
=
os
.
path
.
join
(
os
.
path
.
dirname
(
os
.
path
.
realpath
(
__file__
)),
'requirements.txt'
)
with
open
(
requirements_path
)
as
requirements_file
:
...
...
tests/unit/models/dashboard/test_dashboard_usage.py
0 → 100644
View file @
69bf5b77
import
unittest
from
databuilder.models.dashboard.dashboard_usage
import
DashboardUsage
from
databuilder.models.neo4j_csv_serde
import
RELATION_START_KEY
,
RELATION_START_LABEL
,
RELATION_END_KEY
,
\
RELATION_END_LABEL
,
RELATION_TYPE
,
RELATION_REVERSE_TYPE
class
TestDashboardOwner
(
unittest
.
TestCase
):
def
test_dashboard_usage_user_nodes
(
self
):
# type: () -> None
dashboard_usage
=
DashboardUsage
(
dashboard_group_id
=
'dashboard_group_id'
,
dashboard_id
=
'dashboard_id'
,
email
=
'foo@bar.com'
,
view_count
=
123
,
cluster
=
'cluster_id'
,
product
=
'product_id'
,
should_create_user_node
=
True
)
actual
=
dashboard_usage
.
create_next_node
()
expected
=
{
'is_active:UNQUOTED'
:
True
,
'last_name'
:
''
,
'full_name'
:
''
,
'employee_type'
:
''
,
'first_name'
:
''
,
'updated_at'
:
0
,
'LABEL'
:
'User'
,
'slack_id'
:
''
,
'KEY'
:
'foo@bar.com'
,
'github_username'
:
''
,
'team_name'
:
''
,
'email'
:
'foo@bar.com'
,
'role_name'
:
''
}
self
.
assertDictEqual
(
expected
,
actual
)
self
.
assertIsNone
(
dashboard_usage
.
create_next_node
())
def
test_dashboard_usage_no_user_nodes
(
self
):
# type: () -> None
dashboard_usage
=
DashboardUsage
(
dashboard_group_id
=
'dashboard_group_id'
,
dashboard_id
=
'dashboard_id'
,
email
=
'foo@bar.com'
,
view_count
=
123
,
should_create_user_node
=
False
,
cluster
=
'cluster_id'
,
product
=
'product_id'
)
self
.
assertIsNone
(
dashboard_usage
.
create_next_node
())
def
test_dashboard_owner_relations
(
self
):
# type: () -> None
dashboard_usage
=
DashboardUsage
(
dashboard_group_id
=
'dashboard_group_id'
,
dashboard_id
=
'dashboard_id'
,
email
=
'foo@bar.com'
,
view_count
=
123
,
cluster
=
'cluster_id'
,
product
=
'product_id'
)
actual
=
dashboard_usage
.
create_next_relation
()
expected
=
{
'read_count:UNQUOTED'
:
123
,
RELATION_END_KEY
:
'foo@bar.com'
,
RELATION_START_LABEL
:
'Dashboard'
,
RELATION_END_LABEL
:
'User'
,
RELATION_START_KEY
:
'product_id_dashboard://cluster_id.dashboard_group_id/dashboard_id'
,
RELATION_TYPE
:
'READ_BY'
,
RELATION_REVERSE_TYPE
:
'READ'
}
self
.
assertDictEqual
(
expected
,
actual
)
self
.
assertIsNone
(
dashboard_usage
.
create_next_relation
())
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment