Skip to content

Requests support #32

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

Closed
wants to merge 10 commits into from
Closed

Conversation

AMcManigal
Copy link

This is a preliminary version I'm submitting for review, so I am expecting to make some changes. If I sound critical it is meant constructively because I really think you did a great job with this library!

Dealing With the Lack of A Path Pattern

The Requests library does not have a concept of path pattern. This means that one must be manually entered when passing the request into the wrapper or choosing another way. I chose another way for the following reasons.

  1. Passing the path pattern in becomes tedious.
  2. By defining the path pattern we are 'begging the question'. A source of truth now exists outside of the spec. It feels like the library should be able to infer as much as possible about the request based only on the spec.
  3. We must still determine the path parameters as well, which means that we then have to manually determine two things when creating the request wrapper.

Solution

We already have all the possible path and server patterns that should exist in our API defined in the spec. I took these and converted them to regex expressions. This allowed the new logic to identify what should be the correct path using only the request url. Because I didn't want to have to rebuild the regex every time I made a new request wrapper I created a RequestsFactory.

Proposed Changes

I think that the functionality of the RequestsFactory should be moved into the core library. That way the regex could be created when the spec is thereby eliminating the need for the RequestsFactory. I see this being used as follows.

  1. The validator checks for a path_pattern in the wrapper.
  2. If 'None' it would try to deduce it from the regex created from the spec patterns.

The same process could be used for path parameters and server host urls. This should greatly simplify the implementation of new wrappers.

Please let me know what you think. The current implementation should be completely functional in its current form so feel free to try it out. If you think there is enough value to merge it now then let me know and I'll update the documentation. I'd also be more than happy to refactor it after you merge #25 .

@codecov
Copy link

codecov bot commented Apr 24, 2018

Codecov Report

Merging #32 into master will decrease coverage by 0.15%.
The diff coverage is 96.9%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #32      +/-   ##
==========================================
- Coverage   98.47%   98.32%   -0.16%     
==========================================
  Files          18       18              
  Lines         919     1015      +96     
==========================================
+ Hits          905      998      +93     
- Misses         14       17       +3
Impacted Files Coverage Δ
openapi_core/wrappers.py 97.54% <96.9%> (-0.97%) ⬇️

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 de0c9e0...1cfb857. Read the comment docs.

@@ -107,6 +110,73 @@ def mimetype(self):
return self.request.mimetype


class RequestsOpenAPIRequest(BaseOpenAPIRequest):

def __init__(self, response, path_pattern, regex_pattern, server_pattern):
Copy link
Collaborator

@p1c2u p1c2u Apr 25, 2018

Choose a reason for hiding this comment

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

I think it should accept request object (not response).
http://docs.python-requests.org/en/master/api/#lower-level-classes
User don't need to have response to be able to validate request.

Copy link
Author

Choose a reason for hiding this comment

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

I don't think the requests library explicitly uses a request object in its normal flow. Instead the response starts out as a function. You don't get an actual response object until after the http result is returned.
response = requests.post('http://httpbin.org/post', data = {'key':'value'}) request = response.request

Copy link
Author

@AMcManigal AMcManigal Apr 25, 2018

Choose a reason for hiding this comment

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

Ah, I misread what you were getting at. I pass in the response because of the way that the requests library distributes its data. For example, in order to get cookies it needs the response object even though cookies are a part of the request model in your interface.

I also use it to extract the correct mimetype in case the request doesn't have an 'Accept' header.

amcmanigal added 2 commits May 3, 2018 17:02
When a request doesn’t have a feature, like query params, then the
requests library will omit it. Unfortunately this causes a property not
found error in the previous code.
@p1c2u p1c2u mentioned this pull request Feb 24, 2020
@p1c2u p1c2u mentioned this pull request Mar 3, 2020
@p1c2u
Copy link
Collaborator

p1c2u commented Mar 3, 2020

Thank you for the contribution. Closing in favor of #209

@p1c2u p1c2u closed this Mar 3, 2020
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.

2 participants