pyswagger icon indicating copy to clipboard operation
pyswagger copied to clipboard

Load local files problem

Open kvlahromei opened this issue 9 years ago • 20 comments

I hope it's not my mistake, but maybe there is an issue if you try to refer to local files on Windows:

app = SwaggerApp._create_('file:///C:/Users/me/.../my.yaml')

I thought it would be a general python problem, but didn't found anything...

kvlahromei avatar Apr 17 '15 11:04 kvlahromei

Currently, yaml is still under development. If your problem is specific to 'yaml', I'm working on it right now. If you have problem on loading json file, then that would be a bug.

mission-liao avatar Apr 20 '15 08:04 mission-liao

Just finished supporting YAML, could you help to try this issue against new version (v0.8.7 on pypi) and post me the stack trace if not work? (I didn't have a Windows platform by hand, :( )

mission-liao avatar Apr 21 '15 11:04 mission-liao

Hi, thanks for adressing this issue :-)

I you are right about the filetype, but indeed I tested both (JSON+YAML) again with 0.8.7 and there seem to be still an problem. Here is what I try:

app = SwaggerApp._create_('file:///C:/Users/my007/workspace/Swagger/petstore/swagger.yaml')

But it throws an exception

IOError: [Errno 22] invalid mode ('r') or filename: '/C:/Users/R62ad003/workspace/Swagger/petstore/swagger.json'

I also tried different altered strings, but no success. Unfortunatly even if I start ipython from that path, I just get an error ( I guess it's expecting a valid URL):

 app = SwaggerApp._create_('swagger.json')

...\Lib\site-packages\pyswagger\scanner\v2_ 0\patch_obj.pyc in _path_item(self, path, obj, app) 42 k = jp_split(path)[-1] # key to the dict containing PathItem(s) 43 if isinstance(app.root, Swagger): ---> 44 url = app.root.host + (app.root.basePath or '') + k 45 base_path = app.root.basePath 46 else:

TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'

kvlahromei avatar Apr 21 '15 13:04 kvlahromei

Thanks, the first one is pyswagger split the path in a wrong way. the second one seems to be a obvious bug and should be able to be reproduced on my platform. I will check these 2 problems tomorrow morning.

mission-liao avatar Apr 21 '15 16:04 mission-liao

I think I got the right position of the first issue:

  • /C:/Users/R62ad003/workspace/Swagger/petstore/swagger.json pyswagger would utilise urlparse and compose 'path' and 'netloc' to get real path. It works well on Linux but not on Windows, a leading slash is not legal.

    To workaround it, I trim the leading slash and now it work.

    • TypeError: unsupported operand type(s) for +: 'NoneType' and 'str' I didn't reproduce this issue even on a Windows platform. When accessing via relative path, what I got is '/swagger.json', a similar issue with leading slash.

mission-liao avatar Apr 22 '15 06:04 mission-liao

This issue should be fixed in v0.8.8, reopen it if not.

mission-liao avatar Apr 22 '15 07:04 mission-liao

Hi, to sad but the bug seems to be still present in 0.8.8 :-(

I tested it with an Linux Mint 17 and virtualenv:

url='file://home/matthias/workspace/swagger/open311-georeporter.yaml'
app = SwaggerApp._create_(url)

throws this exception:

... /home/matthias/.virtualenvs/swagger/lib/python2.7/site-packages/pyswagger/getter.pyc in init(self, path) 94 break 95 else: ---> 96 raise ValueError('Unable to locate resource file: [{0}]'.format(path)) 97 98 def load(self, path): ValueError: Unable to locate resource file: [/matthias/workspace/swagger/open311-georeporter.yaml]

kvlahromei avatar Apr 28 '15 06:04 kvlahromei

I just verified it and it's fine on my platform (OSX 10.9.5) To follow up this issue, I need to know about the right path of your resource file?

  • /matthias/workspace/swagger/open311-georeporter.yaml, or
  • /home/matthias/workspace/swagger/open311-georeporter.yaml

The part between the second and third slash would be taken as hostname. Therefore, a better way for a local path, in URI format, would be

  • file:///home/matthias/workspace/swagger/open311-georeporter.yaml, or
  • file://localhost/home/matthias/workspace/swagger/open311-georeporter.yaml, or not in URI
  • /home/matthias/workspace/swagger/open311-georeporter.yaml

Hope this helps, if not, reopen this case (I'm not familiar with github, can you reopen a case I closed?)

mission-liao avatar Apr 28 '15 10:04 mission-liao

On OS X 10.10.3, I just installed the latest pyswagger from pypi. Also tried fresh master from here.

I have a YAML file at /Users/petri/Code/vidamin/api.yaml and try to load it using:

app = SwaggerApp._create_('file:///Users/petri/Code/vidamin/api.yaml')
app = SwaggerApp._create_('api.yaml')

Both fail this way:

Traceback (most recent call last):
  File "swag.py", line 7, in <module>
    app = SwaggerApp._create_('api.yaml')
  File "/Users/petri/Code/thirdparty/pyswagger/pyswagger/core.py", line 335, in create
    app = kls.load(url)
  File "/Users/petri/Code/thirdparty/pyswagger/pyswagger/core.py", line 275, in load
    app._load_obj(url, getter, parser)
  File "/Users/petri/Code/thirdparty/pyswagger/pyswagger/core.py", line 161, in _load_obj
    getter = LocalGetter(os.path.join(p.netloc, p.path))
  File "/Users/petri/Code/thirdparty/pyswagger/pyswagger/getter.py", line 101, in __init__
    raise ValueError('Unable to locate resource file: [{0}]'.format(path))
ValueError: Unable to locate resource file: [/Users/petri/Code/vidamin/api.yaml]

Same failure with JSON file.

petri avatar Jun 12 '15 06:06 petri

I think I figured the problem. The code in getter.py. __init__ expects a directory path and then tries to find one of default pyswagger files in that directory (either 'resource_list.json', 'swagger.json' or 'swagger.yaml').

So... it receives a full path user's YAML/JSON file, not a directory path, and it's only looking for those predefined files, NOT an arbitrary YAML / JSON file, so obviously it fails, twice, sort of.

petri avatar Jun 12 '15 07:06 petri

There's also a bug in __load__, see line 111

petri avatar Jun 12 '15 07:06 petri

Hi, thanks for reporting issue.

The file name: swagger.json is predefined in spec. But indeed, it's really easy for new comer to encounter such issue.

I'm going to fix this issue in one of these ways:

  • more reasonable message in exception, or
  • behaviour change: check extension only(.json, .yaml) instead of full name(swagger.json, swagger.yaml)

Now I prefer option#2, any idea?

And, what's the bug in line 111?

mission-liao avatar Jun 12 '15 15:06 mission-liao

Option two sounds good to me - that way swagger newbies such as me won't get tripped by the convention in the spec that you point to. I agree that it would increase user-friendliness of pyswagger.

The buggy code is meant to assign ext the extension from path if it exists, right? And leave ext as it is, otherwise. Instead, it does unpacking of the string (if ext is nonempty). So this:

_, ext = os.path.splitext(path) if ext == '' else ext

Should be for example:

_, ext = os.path.splitext(path) if ext == '' else (None, ext)

Or,

ext = os.path.splitext(path)[-1] if ext == '' else ext

petri avatar Jun 13 '15 15:06 petri

(Y) That's the bug, thx. I will go for option#2 and include that change in next version, which will be released on Monday.

mission-liao avatar Jun 13 '15 23:06 mission-liao

Hi. It seems that this issue refers to two problems. I encountered the other one with pyswagger 0.8.11 on Ubuntu, when loading swagger JSON schema from a local file.

My code looks like this:

from pyswagger import SwaggerApp
SWAGGER_PATH = "<absolute-path-to-directory>/swagger.json"
app = SwaggerApp._create_(SWAGGER_PATH)

And got the following stacktrace:

Traceback (most recent call last):
  File ".../api_client.py", line 13, in <module>
    app = SwaggerApp._create_(SWAGGER_PATH)
  File ".../virtualenvs/.../lib/python3.2/site-packages/pyswagger/core.py", line 318, in create
    app.prepare(strict=strict)
  File ".../virtualenvs/.../lib/python3.2/site-packages/pyswagger/core.py", line 286, in prepare
    self._prepare_obj(strict=strict)
  File ".../virtualenvs/.../lib/python3.2/site-packages/pyswagger/core.py", line 235, in _prepare_obj
    s.scan(root=self.__root, route=[PatchObject()])
  File ".../virtualenvs/.../lib/python3.2/site-packages/pyswagger/scan.py", line 124, in scan
    handle_cls(cls)
  File ".../virtualenvs/.../lib/python3.2/site-packages/pyswagger/scan.py", line 117, in handle_cls
    ret = ff(the_self, path, obj, self.app)
  File ".../virtualenvs/.../lib/python3.2/site-packages/pyswagger/scanner/v2_0/patch_obj.py", line 44, in _path_item
    url = app.root.host + (app.root.basePath or '') + k
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'

ugolowic avatar Jun 26 '15 07:06 ugolowic

Hi @ugolowic ,

You problem is related to this one in Swagger Spec. I will implement the algorithm to deduce basePath & host when they are None later.

mission-liao avatar Jun 26 '15 10:06 mission-liao

Hi @ugolowic ,

Your problem is resolved in v0.8.12.

mission-liao avatar Jun 29 '15 16:06 mission-liao

@mission-liao : I am using pyswagger-0.8.23 and i am still facing issues with loading local files. Firstly, this is the error.

This is because my folder name is v0.1 and hence, line 103 here is setting ext to 0.1. I commented out the code and made the file loading work.

Then I am getting this error.

This is my swagger.yaml. Couldn't debug this.

draxxxeus avatar Oct 07 '16 07:10 draxxxeus

@draxxxeus it seems an obvious bug for "swagger.yaml.1", I'll look into this part this weekend and update my finding here.

@draxxxeus I create a dedicated issue for your case https://github.com/mission-liao/pyswagger/issues/91 and v0.8.24 is dedicated for this

mission-liao avatar Oct 07 '16 18:10 mission-liao

why I need to provide here two aruguments?
app = App.create("/local/data/home/eqtdata/sandbox/khanshi/qfix_newone/rooster/swagger.json") File "/local/data/home/eqtdata/sandbox/khanshi/qfix_newone/rooster/pyswagger-develop/pyswagger/core.py", line 364, in create app = kls.load(url) File "/local/data/home/eqtdata/sandbox/khanshi/qfix_newone/rooster/pyswagger-develop/pyswagger/core.py", line 285, in load app.__raw, app.__version = app.load_obj(url, getter=getter, parser=parser) File "/local/data/home/eqtdata/sandbox/khanshi/qfix_newone/rooster/pyswagger-develop/pyswagger/core.py", line 166, in load_obj obj = self.__resolver.resolve(jref, getter) File "/local/data/home/eqtdata/sandbox/khanshi/qfix_newone/rooster/pyswagger-develop/pyswagger/resolve.py", line 62, in resolve obj = six.advance_iterator(getter) File "/local/data/home/eqtdata/sandbox/khanshi/qfix_newone/rooster/pyswagger-develop/pyswagger/getter.py", line 48, in next obj = yaml.load(obj) TypeError: load() missing 1 required positional argument: 'Loader'

shivangi06 avatar Dec 01 '21 06:12 shivangi06