Skip to content

Commit

Permalink
feat: Add support for open api servers
Browse files Browse the repository at this point in the history
In openapi 3 the 'schemes' and 'basePath' were replaced with a single
property called 'servers', in this property we introduce the available
servers with the full path, for example:

```yaml
servers:
  - url: https://statsapi.web.nhl.com/api/v1
 ```

With this change, a flag is added in the parsing of the context
`is_open_api` that can be used to check for the new properties available
in open api 3.

fixes httpie#197

Signed-off-by: Arturo Volpe <[email protected]>
  • Loading branch information
aVolpe committed Apr 24, 2023
1 parent 030daed commit 3feb279
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 5 deletions.
20 changes: 15 additions & 5 deletions http_prompt/context/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from http_prompt.tree import Node
from urllib.parse import urlparse


class Context(object):
Expand All @@ -15,19 +16,28 @@ def __init__(self, url=None, spec=None):
# Create a tree for supporting API spec and ls command
self.root = Node('root')
if spec:
is_open_api = 'openapi' in spec

if not self.url:
self.url = spec.get('servers')[0].get('url')
if 'servers' in spec:
self.url = spec.get('servers')[0].get('url')
if is_open_api:
# In open api, the schemes are in the 'server' element,
self.url = spec.get('servers', [{'url': 'http://localhost:8000'}])[0].get('url')
else:
schemes = spec.get('schemes')
scheme = schemes[0] if schemes else 'https'
self.url = (scheme + '://' +
spec.get('host', 'http://localhost:8000') +
spec.get('basePath', ''))

base_path_tokens = list(filter(lambda s: s,
spec.get('basePath', '').split('/')))
# in open api, there is no 'basePath', we should extract that from the url
if is_open_api:
server = spec.get('servers', [{'url': 'http://localhost:8000'}])[0].get('url')
base_path_tokens = list(filter(lambda s: s,
urlparse(server).path.split('/')))
else:
base_path_tokens = list(filter(lambda s: s,
spec.get('basePath', '').split('/')))

paths = spec.get('paths')
if paths:
for path in paths:
Expand Down
22 changes: 22 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,28 @@ def test_spec_from_local_yml(self):
self.assertEqual(set([n.name for n in context.root.children]),
set(['users', 'orgs']))

def test_spec_from_local_yml_openapi(self):
spec_filepath = self.make_tempfile("""
openapi: "3.0.0"
servers:
- url: https://localhost:8080/
paths:
/api/users:
get:
description:
/api/orgs:
get:
description:
""")
result, context = run_and_exit(['example.com/api', "--spec",
spec_filepath])
self.assertEqual(result.exit_code, 0)
self.assertEqual(context.url, 'http://example.com/api')
self.assertEqual(set([n.name for n in context.root.children]),
set(['api']))
self.assertEqual(set([n.name for n in context.root.ls('api')]),
set(['users', 'orgs']))

def test_spec_basePath(self):
spec_filepath = self.make_tempfile(json.dumps({
'basePath': '/api/v1',
Expand Down

0 comments on commit 3feb279

Please sign in to comment.