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

Add path_pattern property to routes and resources #2993

Merged
merged 1 commit into from
May 27, 2018

Conversation

pposca
Copy link
Contributor

@pposca pposca commented May 11, 2018

The path_pattern is the raw path used to add a new route. For example,
/foo/bar/{name:\d+}.

  • Add path_pattern property to AbstractRoute and AbstractResource
  • Add path pattern implementation to PlainResource, DynamicResource,
    PrefixResource, StaticResource, ResourceRoute and SystemRoute.
  • Add tests

Closes #2968

What do these changes do?

Add path_pattern property to routes and resources.
The path_pattern is the raw path used to add a new route. For example, /bar/{name:\d+}.

Are there changes in behavior for the user?

The public API of Route and Resource has now a new property path_name to expose directly the raw path used to add a new route. Significant values have been selected for each implementation of the abstract classes.

Related issue number

2968

Checklist

  • I think the code is well written
  • Unit tests for the changes exist
  • Documentation reflects the changes
  • If you provide code modification, please add yourself to CONTRIBUTORS.txt
    • The format is <Name> <Surname>.
    • Please keep alphabetical order, the file is sorted by names.
  • Add a new news fragment into the CHANGES folder
    • name it <issue_id>.<type> for example (588.bugfix)
    • if you don't have an issue_id change it to the pr id after creating the pr
    • ensure type is one of the following:
      • .feature: Signifying a new feature.
      • .bugfix: Signifying a bug fix.
      • .doc: Signifying a documentation improvement.
      • .removal: Signifying a deprecation or removal of public API.
      • .misc: A ticket has been closed, but it is not of interest to users.
    • Make sure to use full sentences with correct case and punctuation, for example: "Fix issue with non-ascii contents in doctest text files."

@asvetlov
Copy link
Member

Thank for the PR.
We have 2 options: use regex pattern or formatter string.
The first is stricter, the second looks nicer: /foo/bar/{name}.

I have no personal opinion.
@aio-libs/aiohttp-committers what do you think?

@kxepal
Copy link
Member

kxepal commented May 11, 2018

I'm for formatted string, or, actually, placeholders.

Regexps are more powerful, but with their power they move part of data validation on router side. Say, /user/:id vs /user/{id:\d+} - placeholder knowns nothing about what ids are valid and delegates their check to handler side. Regular expression tries to ensure that they are numeric ones. This may sounds sweet, but you still would do int(id) in handler and if that id is not valid you still would like to throw some exception back.

Also, I would like to note, that /foo/bar/{baz} syntax not quite common. The /foo/bar/:baz would be a bit more wide used.

@pposca
Copy link
Contributor Author

pposca commented May 11, 2018

As far as I've understood, regex patterns only exist in DynamicResource. If other resources return a string and DynamicResource returns a regex, it looks a bit like a broken API, inconsistent. It seems more logic to me that all resources return a string.

On the other hand, I think regex is more useful than formatted string, as /user/{id:\d+} provides more information than /user/{id}, and this is why I chose to return exactly the same string it is used when calling add_routes., whether it is a normal string (PlainResource) or a regex pattern string (DynamicResource)

PD: Sorry if I've misunderstood something. It is the first time I dive into aiohttp code.

@asvetlov
Copy link
Member

@jettify could you help to make a decision?
It is your request anyway.

@codecov-io
Copy link

codecov-io commented May 18, 2018

Codecov Report

Merging #2993 into master will increase coverage by <.01%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2993      +/-   ##
==========================================
+ Coverage   98.09%   98.09%   +<.01%     
==========================================
  Files          42       42              
  Lines        7711     7718       +7     
  Branches     1345     1345              
==========================================
+ Hits         7564     7571       +7     
  Misses         51       51              
  Partials       96       96
Impacted Files Coverage Δ
aiohttp/web_urldispatcher.py 99.11% <100%> (+0.01%) ⬆️
aiohttp/web_app.py 99.1% <0%> (-0.01%) ⬇️

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 af53fe0...5ff1917. Read the comment docs.

@jettify
Copy link
Member

jettify commented May 20, 2018

Sorry for late reply, was out of town. My use case is tracing system [1] where canonical name can be used for grouping spans, this also useful for metrics subsystems too to count number of requests per specific route, using path pattern as a key instead of full actual path (with user is for example).

For this purpose I think formatted string is better since it is easier to read.

[1] openzipkin/zipkin#1874

Copy link
Member

@asvetlov asvetlov left a comment

Choose a reason for hiding this comment

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

@pposca please update the PR:

  1. Rename path_pattern to canonical (I don't like long complex names).
  2. Use formatting template instead of regex.

@pposca
Copy link
Contributor Author

pposca commented May 21, 2018

@asvetlov , do you prefer a 2nd commit with the update or that I amend the first commit?

@asvetlov
Copy link
Member

Don't care, PRs are squashed on merging anyway.

Copy link
Member

@asvetlov asvetlov left a comment

Choose a reason for hiding this comment

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

The documentation update is required.
The property audience is not very wide, perhaps changing web_reference.rst is enough.

@@ -131,6 +140,15 @@ def handler(self):
def name(self):
"""Optional route's name, always equals to resource's name."""

@property
@abc.abstractmethod
def canonical(self):
Copy link
Member

Choose a reason for hiding this comment

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

Should we have route.canonical?
route.resource.canonical should be enough.
route.name exists for historical reasons, routes were added before the resource invention.

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 issue was asking for a route property, that's why I added it.

I will change it and I will update the docs (I completely forgot them...)

@@ -457,6 +478,10 @@ def __init__(self, prefix, directory, *, name=None,
'HEAD': ResourceRoute('HEAD', self._handle, self,
expect_handler=expect_handler)}

@property
def canonical(self):
return self._prefix + str(self._directory)
Copy link
Member

Choose a reason for hiding this comment

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

Looks like there is an error here.
Canonical URL should contain the prefix only, the directory is a local path.
It never returns in URLs but url_for() constructs a return value from the prefix and a relative to the directory path.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, I will remove it from StaticResource, as canonical is already the prefix in PrefixResource and StaticResource will inherit the property.

Copy link
Member

@asvetlov asvetlov left a comment

Choose a reason for hiding this comment

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

Everything is perfect, the last neat is left.


Read-only *canonical path* associate with the resource. For example
``/path/to`` or ``/path/{to}``

Copy link
Member

Choose a reason for hiding this comment

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

.. versionadded:: 3.3

.. attribute:: canonical

Read-only *canonical path* associate with the resource. Returns the path
used to create the PlainResource. For example ``/path/to``
Copy link
Member

Choose a reason for hiding this comment

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

versionadded


Read-only *canonical path* associate with the resource. Returns the
formatter obtained from the path used to create the DynamicResource.
For example, from a path ``/get/{num:^\d+}``, it returns ``/get/{num}``
Copy link
Member

Choose a reason for hiding this comment

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

versionadded


Read-only *canonical path* associate with the resource. Returns the prefix
used to create the StaticResource. For example ``/prefix``

Copy link
Member

Choose a reason for hiding this comment

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

versionadded

Read-only *canonical path* associate with the resource. Returns the
prefix used to create the PrefixedSubAppResource.
For example ``/prefix``

Copy link
Member

Choose a reason for hiding this comment

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

versionadded

The canonical is the path used to add a new route. For example,
/foo/bar/{name}. For DynamicResource, canonical exposes the
formatter.

 - Add canonical property to AbstractResource
 - Add canonical implementation to DynamicResource, PrefixResource
 and StaticResource.
 - Add tests
 - Add docs

Closes aio-libs#2968
@asvetlov asvetlov merged commit 0e11b36 into aio-libs:master May 27, 2018
@asvetlov
Copy link
Member

Well done!
Thank you for patience.

@pposca
Copy link
Contributor Author

pposca commented May 27, 2018

My pleasure. Really happy to help.

@jettify
Copy link
Member

jettify commented Jun 9, 2018

Thanks @pposca @asvetlov ! I have already added this property to aiozipkin integration (aio-libs/aiozipkin#138)

@pposca pposca deleted the issue_2968 branch June 9, 2018 20:01
@lock
Copy link

lock bot commented Oct 28, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a [new issue] for related bugs.
If you feel like there's important points made in this discussion, please include those exceprts into that [new issue].
[new issue]: https://github.com/aio-libs/aiohttp/issues/new

@lock lock bot added the outdated label Oct 28, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Oct 28, 2019
@psf-chronographer psf-chronographer bot added the bot:chronographer:provided There is a change note present in this PR label Oct 28, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bot:chronographer:provided There is a change note present in this PR outdated
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add canonical name for the route
5 participants