Skip to content

Conversation

@paul-griffith
Copy link
Contributor

Summary

This is a direct copy-paste of the pseudo-library that wraps python-slackclient I use internally. The big advantage is obviously typed interactions - especially the newer stuff (ie, blockkit) has pretty solid type hinting throughout.

I'm offering up this PR without any adjustments having been made - if it's something y'all are interested in, I could potentially spend some time making changes to better fit it into this library. Happy to review with anybody - I'm also in the dev4slack group semi-often if you want to reach me realtime.

Requirements (place an x in each [ ])

@RodneyU215
Copy link
Contributor

@paul-griffith This is awesome! I'm still reading through it, but I'm very interested in working together to get this into a mergeable state for v2.

@1oglop1
Copy link
Contributor

1oglop1 commented May 8, 2019

This is super nice! it would help me a lot!

@DonDebonair
Copy link

DonDebonair commented Jun 2, 2019

It would be awesome for this to be integrated into python-slackclient. I realise that there is some overlap with the existing functionality (eg. api calls exposed as functions, instead of having to call by string), but what needs to be done for this to be properly integrated?

@RodneyU215
Copy link
Contributor

There are currently a few high priority bugs I'm working on so it's taken me a while to get to this. This is definitely still a PR we'd like to see merged! Right now the biggest blocker is Unit tests and documentation.

@RodneyU215 RodneyU215 added Priority: Medium enhancement M-T: A feature request for new functionality Version: 2x labels Jun 4, 2019
@DonDebonair
Copy link

DonDebonair commented Jun 4, 2019

The question is if you want to merge this as-is, with the extra wrapper, or if you maybe want to integrate the helper classes with the existing clients. I'd say the latter is preferable, but that requires some extra work which I don't know if @paul-griffith wants to put in.

@RodneyU215
Copy link
Contributor

RodneyU215 commented Jun 4, 2019

No, the extra wrapper is an area that I'd like to discuss more. Preferably, I'd love to work to get all of the message builder classes merged first. This could be used immediately with the existing API methods.

@RodneyU215
Copy link
Contributor

@paul-griffith I want to thank you again for contributing such a phenomenal PR. It's clear you've put a great deal of work into this and it's going to be provide a lot of value to the community.

@DonDebonair
Copy link

If I can help put this into the desired shape, let me know @paul-griffith @RodneyU215. This addition would greatly simplify the code of my own bot framework

@paul-griffith
Copy link
Contributor Author

paul-griffith commented Jun 4, 2019 via email

@RodneyU215
Copy link
Contributor

@paul-griffith Happy to chat this week. I've sent you a DM in dev4slack and you can also email me at rodney@slack-corp.com so we can coordinate with a calendar invite.

@paul-griffith paul-griffith changed the base branch from v2 to master June 6, 2019 16:54
@paul-griffith
Copy link
Contributor Author

I don't plan on significantly changing anything in the core lib at this point - just need to add test coverage at this point. Happy for anyone else to contribute tests, or even just known-failing-cases - coverage right now is basically limited to whatever is explicitly not allowed in the API documentation, but I'm confident there's plenty of scenarios that aren't covered by the JSON validation this currently has.

@paul-griffith paul-griffith marked this pull request as ready for review June 17, 2019 22:32
@codecov
Copy link

codecov bot commented Jun 17, 2019

Codecov Report

Merging #400 into master will increase coverage by 13.08%.
The diff coverage is 80.85%.

Impacted file tree graph

@@             Coverage Diff             @@
##           master     #400       +/-   ##
===========================================
+ Coverage   56.94%   70.03%   +13.08%     
===========================================
  Files           6       15        +9     
  Lines         734     1622      +888     
  Branches       42       91       +49     
===========================================
+ Hits          418     1136      +718     
- Misses        307      464      +157     
- Partials        9       22       +13
Impacted Files Coverage Δ
slack/web/classes/interactions.py 0% <0%> (ø)
slack/web/classes/messages.py 0% <0%> (ø)
slack/errors.py 100% <100%> (ø) ⬆️
slack/web/classes/dialogs.py 81.92% <81.92%> (ø)
slack/web/classes/elements.py 85.54% <85.54%> (ø)
slack/web/classes/attachments.py 92.59% <92.59%> (ø)
slack/web/classes/dialog_elements.py 93.65% <93.65%> (ø)
slack/web/classes/blocks.py 94.25% <94.25%> (ø)
slack/web/classes/objects.py 95.13% <95.13%> (ø)
slack/web/classes/actions.py 98.87% <98.87%> (ø)
... and 10 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 27ba907...3a686aa. Read the comment docs.

footer_icon: str = None,
ts: int = None,
):
"""
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The docstring/param list on these two classes is a bit ridiculous, but there's not really any meta-information to keep track of that helps make a builder class worthwhile, IMO

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree with this position. For now until new data surfaces let's stick with your recommendation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

On consideration, I could see some utility to an AttachmentBuilder - something like:

AttachmentBuilder()
  .text("Some attachment")
  .footer("footer", icon="icon url")
  .author("jim bob", link="jimbob.com", icon="jimbob.com/picture.jpg")
  .field("*Score*", "20")
  .field("*Series*", "Some book series")
  .linkbutton("button", "Click me!", "http://google.com")
  .user_selector()
  .callback_id("abcdefg")
  .build()

But, that also ties into the point that pure attachments shouldn't really be encouraged - although I do hope either blocks get a color attribute soon or BlockAttachments never go away 🤞

Choose a reason for hiding this comment

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

I like the AttachementBuilder!

Copy link
Contributor

Choose a reason for hiding this comment

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

While I agree an AttachementBuilder would be nice, I would not recommend investing too much time into it. Block Kit is the focus and will continue to see new features added.

Copy link
Contributor

@RodneyU215 RodneyU215 left a comment

Choose a reason for hiding this comment

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

Paul this is a world class PR! Thank you. I've added a few minor comments. Please let me know what you think.

footer_icon: str = None,
ts: int = None,
):
"""
Copy link
Contributor

Choose a reason for hiding this comment

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

I agree with this position. For now until new data surfaces let's stick with your recommendation.


def get_json(self, option_type: str = "block") -> dict:
if option_type == "action":
# deliberately skipping JSON validators here - can't find documentation
Copy link
Contributor

Choose a reason for hiding this comment

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

Note for myself: Check on limits described here.

@RodneyU215
Copy link
Contributor

@dandydev If you could spare a moment to review this PR I'd love your feedback on this as well.

@DonDebonair
Copy link

@RodneyU215 I will have a look at it tonight (GMT+2 time). Happy to help!

Copy link

@DonDebonair DonDebonair left a comment

Choose a reason for hiding this comment

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

This looks great! So useful!

Some general comments:

  • There are some places where you have constructors that accept parameters with default value None. Technically, a better type annotation for those parameters would be Optional[X] when X is the type of the value in case it's not None. This allows MyPy (or for example PyCharm's built-in type checker) to give even better type hints. Although I can also see how that would become a bit cumbersome.
  • I'm not a big fan of the name get_json(), because it doesn't strictly return json (string). It returns a dict. I realize that this dict is eventually converted into a json string, but I still feel it can be a confusing name. I must admit that I don't know of a better alternative right now. The same problem also exists with the JsonXXX classes (to a lesser extent in my opinion)

@DonDebonair
Copy link

@dandydev If you could spare a moment to review this PR I'd love your feedback on this as well.

Done!

@paul-griffith
Copy link
Contributor Author

Solid points, @dandydev. I moved the dialog sub-elements into a dialog_elements.py - I feel better about that so that users are "encouraged" to use the builder via slack.web.classes.dialogs, and have to go out of their way to pull in other classes. I also moved the common JSON handling into __init__.py for the package.

Agreed on get_json, but I'm just as unsure on a better replacement. to_dict or to_object might be better?

Also fixed the use of Optional and shadowing type when appropriate.

elements.py is fairly long (with the latest commit, it's the largest file in this directory) but I can't see a good way to split it up like what was possible with dialogs. Open to suggestions.

@DonDebonair
Copy link

Solid points, @dandydev. I moved the dialog sub-elements into a dialog_elements.py - I feel better about that so that users are "encouraged" to use the builder via slack.web.classes.dialogs, and have to go out of their way to pull in other classes. I also moved the common JSON handling into __init__.py for the package.
...
Also fixed the use of Optional and shadowing type when appropriate.

Great!

Agreed on get_json, but I'm just as unsure on a better replacement. to_dict or to_object might be better?

I like to_dict!

elements.py is fairly long (with the latest commit, it's the largest file in this directory) but I can't see a good way to split it up like what was possible with dialogs. Open to suggestions.

I see a couple of element categories that could be split out:

  • Select-related stuff
  • Menu-related stuff

That's the only split I can think of.

@paul-griffith
Copy link
Contributor Author

One other option with elements.py would be moving abstract/base classes to a subfile, so that from slack.web.classes.elements import <x> stays pretty clean for actual use classes, but that feels low value to me.

@DonDebonair
Copy link

I'd say, leave it for now. For me it's a minor nitpick. If stuff is added to elements.py in the future, it can be reevaluated.

@paul-griffith
Copy link
Contributor Author

Okay, @RodneyU215, I'll defer to you on decisions about:

  1. get_json() vs to_dict vs ???
  2. AttachmentBuilder, yea or nay?
  3. Refactor elements.py?

Otherwise, I think this is almost ready to merge? 🤞

@RodneyU215
Copy link
Contributor

@dandydev Thanks for the review!

@paul-griffith

  1. I agree to_dict() is a much better fit.
  2. AttachmentBuilder, nay. I'd prefer not to invest too much into something we're actively working to replace.
  3. elements.py is long, but the context is where it needs to be. Let's keep this as-is for now.

Thank you both for the progress on this. We're very close to getting this merged. Once the rename is complete let's get this shipped.

Copy link
Contributor

@RodneyU215 RodneyU215 left a comment

Choose a reason for hiding this comment

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

Awesome! This is great. Thank you!

@RodneyU215 RodneyU215 merged commit 4fc2467 into slackapi:master Jun 27, 2019
@RodneyU215 RodneyU215 mentioned this pull request Jul 1, 2019
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement M-T: A feature request for new functionality Version: 2x

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants