Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes v2 dev website dashboard not loading #1256

Merged
merged 19 commits into from
Jul 15, 2022
Merged

Fixes v2 dev website dashboard not loading #1256

merged 19 commits into from
Jul 15, 2022

Conversation

joshuayhwu
Copy link
Contributor

@joshuayhwu joshuayhwu commented Jun 23, 2022

Fixes #1251

Resolve typeName key error by reloading older data when filtered table is empty

  • Up to date with dev branch
  • Branch name follows guidelines
  • All PR Status checks are successful
  • Peer reviewed and approved

Any questions? See the getting started guide

@joshuayhwu joshuayhwu requested a review from nichhk June 23, 2022 01:06
@joshuayhwu joshuayhwu self-assigned this Jun 23, 2022
Copy link
Member

@nichhk nichhk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the debugging!

If there's really no data for the given time range, we should display that one way or another instead of loading data from a different time range. Is that possible?

@joshuayhwu
Copy link
Contributor Author

Thanks for the debugging!

If there's really no data for the given time range, we should display that one way or another instead of loading data from a different time range. Is that possible?

It maybe possible to put the problematic code into a callback function so that whenever there is no data, we use the PreventUpdate() method (which should be available in older versions of dash as well...?) to stop the graph content from rendering.

From my understanding so far, the code breaks when there is no data because the pandas groupby method generates an empty dataframe, with columns that plotly fails to index. I will need to take a look at this again tomorrow.

@nichhk
Copy link
Member

nichhk commented Jun 23, 2022

Gotcha. If it turns out that we can only fix this issue in the newer version of Dash, we can lump those together.

@joshuayhwu
Copy link
Contributor Author

@nichhk this will probably the only one we need to merge now. Will make a new PR for combine dashboards.

Copy link
Member

@nichhk nichhk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some partial comments for now.

server/dash/dashboards/neighborhood_recent.py Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Outdated Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Outdated Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Outdated Show resolved Hide resolved
Copy link
Member

@nichhk nichhk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates!

Can you also add screenshots showing how the graphs look on this PR?

server/dash/dashboards/neighborhood_recent.py Show resolved Hide resolved

# Populate the neighborhood dropdown
fig = px.line()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer to have more descriptive variable names, e.g., requests_over_time_line_fig.

server/dash/dashboards/neighborhood_recent.py Outdated Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Outdated Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Outdated Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Outdated Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Outdated Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Outdated Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Outdated Show resolved Hide resolved
Copy link
Member

@nichhk nichhk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Just a few more readability/style comments.

In the future, I think we would greatly benefit from having function docstrings so that we know exactly what the arguments and return types are. But we can work on that in a different PR.

server/dash/dashboards/neighborhood_recent.py Outdated Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Outdated Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Outdated Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Outdated Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Outdated Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Outdated Show resolved Hide resolved
Copy link
Member

@nichhk nichhk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for working on this! Please add screenshots of the dashboard when there is no data.

@joshuayhwu
Copy link
Contributor Author

LGTM, thanks for working on this! Please add screenshots of the dashboard when there is no data.

Still trying to work on that. Getting feedback is a slow process as dash/gunicorn is a little buggy - sometimes showing no data on the dashboard. Hot reloading is not that useful on this front as dashboards tend to be cached and takes some "waiting time" before it refreshes. Regardless, I will work on the function documentation before updating that.

@nichhk
Copy link
Member

nichhk commented Jul 12, 2022

Ah gotcha, that sounds finicky. Eventually, we would want unit tests to test this sort of scenario for us. But for now, would it help to simply replace the call to the API here with something that just creates an empty dataframe, or something like that?

@joshuayhwu
Copy link
Contributor Author

There are too many dependencies in the code that relies on the table columns, so what I did was basically hav date range in the future such that there is no data. The problem is a "successful reload" (i.e. refresh with code changes) takes too long becuaes of either 1) buggy gunicorn/dash interaction causing no data (happens when none of the calllback function gets fired), or 2) dashboards are cached so it's still using old code. Multiple manual refresh is necessary to get 1 "successful reload".

@joshuayhwu
Copy link
Contributor Author

joshuayhwu commented Jul 12, 2022

There seems to be some error popping up that I missed before. First line is "selected_council'" 's datatype, and second line is "start_date" 's datatype. Do you have any suggestions?

<class 'str'>
<class 'datetime.date'>
Exception on /_dash-update-component [POST]
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/usr/local/lib/python3.7/site-packages/dash/dash.py", line 1078, in dispatch
    response.set_data(func(*args, outputs_list=outputs_list))
  File "/usr/local/lib/python3.7/site-packages/dash/dash.py", line 1009, in add_context
    output_value = func(*args, **kwargs)  # %% callback invoked %%
  File "/app/dashboards/neighborhood_recent.py", line 203, in update_text
    close_count = df.query(f"councilName == '{selected_council}' and closedDate >= '{start_date}'")['srnumber'].count()  # noqa
  File "/usr/local/lib/python3.7/site-packages/pandas/core/frame.py", line 3345, in query
    res = self.eval(expr, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/pandas/core/frame.py", line 3475, in eval
    return _eval(expr, inplace=inplace, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/pandas/core/computation/eval.py", line 346, in eval
    ret = eng_inst.evaluate()
  File "/usr/local/lib/python3.7/site-packages/pandas/core/computation/engines.py", line 127, in evaluate
    return self.expr()
  File "/usr/local/lib/python3.7/site-packages/pandas/core/computation/expr.py", line 794, in __call__
    return self.terms(self.env)
  File "/usr/local/lib/python3.7/site-packages/pandas/core/computation/ops.py", line 397, in __call__
    right = self.rhs(env)
  File "/usr/local/lib/python3.7/site-packages/pandas/core/computation/ops.py", line 399, in __call__
    return self.func(left, right)
  File "/usr/local/lib/python3.7/site-packages/pandas/core/ops/common.py", line 65, in new_method
    return method(self, other)
  File "/usr/local/lib/python3.7/site-packages/pandas/core/ops/__init__.py", line 370, in wrapper
    res_values = comparison_op(lvalues, rvalues, op)
  File "/usr/local/lib/python3.7/site-packages/pandas/core/ops/array_ops.py", line 241, in comparison_op
    return invalid_comparison(lvalues, rvalues, op)
  File "/usr/local/lib/python3.7/site-packages/pandas/core/ops/invalid.py", line 34, in invalid_comparison
    raise TypeError(f"Invalid comparison between dtype={left.dtype} and {typ}")
TypeError: Invalid comparison between dtype=float64 and str

I also added the docstrings for the functions in nc_recent. Will continue working on this tmr.

@nichhk
Copy link
Member

nichhk commented Jul 13, 2022

Hmm I'm not sure. It looks like closedDate (within the df) is converted to a string, while start_date is a datetime object. The datetime object might be getting coerced to a float64. We can represent start_date as a string and try that.

@joshuayhwu
Copy link
Contributor Author

joshuayhwu commented Jul 13, 2022

Yeah the coercing seems to be the problem. The dataframe from the API gets one request with only created date and no close date (NaN) value, which the pd.to_datetime coerce as a float. The weird thing is that I have set the start date so far ahead of time and the API still return this request with a startdate close to today. I revert to your suggestion on using empty data frame.

I also update the last row assignment in the line chart dataframe using the following code

figure_df.loc[figure_df.shape[0]] = ...

If we simply use J, the same request type will be assigned on all date range (since the j value remains constant on the outer loop). But we want all request types to have value 0 in all date range.

For the pie chart, turns out using value 0 would just cause the chart to disappear altogether. I use 1 in this case.

Let me know what you think.

Plotly_Recent_Empty

EDIT: on the other hand, we do need to figure out a way to deal with dataframe with createdDates only and no closedDates (incomplete requests). Any thoughts?

Copy link
Member

@nichhk nichhk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Josh! Just a few comments about the docstring and then this should be good to go.

server/dash/dashboards/neighborhood_recent.py Outdated Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Outdated Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Outdated Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Outdated Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Outdated Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Show resolved Hide resolved
@joshuayhwu joshuayhwu requested a review from nichhk July 14, 2022 04:06
@joshuayhwu
Copy link
Contributor Author

Thanks for the review. Updated docstrings with args and returns.

Copy link
Member

@nichhk nichhk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your patience Josh! LGTM. Just a few comments. I approved the PR so that you can merge it after fixing the comments without waiting for another review from me.

server/dash/dashboards/neighborhood_recent.py Outdated Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Outdated Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Outdated Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Outdated Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Outdated Show resolved Hide resolved
server/dash/dashboards/neighborhood_recent.py Outdated Show resolved Hide resolved
@joshuayhwu joshuayhwu merged commit a1b9e61 into dev Jul 15, 2022
@joshuayhwu joshuayhwu deleted the requestTypeColors branch July 15, 2022 00:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Dash not working on dev site
2 participants