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

Accept a urllib.requests.Request instead of a string in App.load #190

Open
multimeric opened this issue Jul 27, 2020 · 2 comments
Open

Accept a urllib.requests.Request instead of a string in App.load #190

multimeric opened this issue Jul 27, 2020 · 2 comments

Comments

@multimeric
Copy link

App.load() assumes that url is a string, for requesting the OpenAPI.json:

:param str url: url of path of Swagger API definition

However, these are cases where we need more configurability. For example, I've just encountered an OpenAPI endpoint that rejects the urllib UserAgent, so I would like to be able to provide a customised UserAgent via a Request instance, rather than simply a string.

@iainbryson
Copy link

This would be a great help. There are providers such as CloudFlare which explicitly block Python urllib requests; without the ability to pick a new UserAgent pyswagger cannot fetch the swagger file from these.

@marcosguedes
Copy link

Hi there!

I had the same problem. What I did as a workaround was subclassing App (which in turn would load a subclassed UrlGetter) and subclass Client.

import six
from pyswagger import App, Security
from pyswagger.getter import UrlGetter
from pyswagger.contrib.client.requests import Client

header_dict = {"User-agent": "Best Alpha Agent/0.0.1a"}

def _url_load(path):
    # original _url_load method is here:
    # https://github.com/pyopenapi/pyswagger/blob/333c4ca08e758cd2194943d9904a3eda3fe43977/pyswagger/getter.py#L141
    ret = f = None
    try:
        # This is new. create a Request object instead of path
        req = six.moves.urllib.request.Request(path, headers=header_dict)
        f = six.moves.urllib.request.urlopen(req)
        ret = f.read()
    finally:
        if f:
            f.close()

    return ret

class CustomUrlGetter(UrlGetter):
    __simple_getter_callback__ = _url_load

class CustomApp(App):
    def load_obj(self, jref, getter=None, parser=None):
        return super(CustomApp, self).load_obj(jref, getter=CustomUrlGetter, parser=parser)

class CustomClient(Client):
    def request(self, req_and_resp, opt=None, headers=None):
        return super(CustomClient, self).request(req_and_resp, opt, headers=header_dict)

Then I do

self.app = CustomApp._create_("https://example.com/swagger.json")
self.auth = Security(self.app)
self.auth.update_with("Basic", ("hello", "isItMeYoureLookingFor"))
self.client = CustomClient(self.auth)

resp = self.client.request(self.app.op["grabbing-from-swagger"](data=data))

Maybe this could help anyone facing the same issue. I hope I helped

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

No branches or pull requests

3 participants