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

Run an API spec, no boilerplate needed #284

Merged
merged 25 commits into from
Sep 15, 2016
Merged

Conversation

rafaelcaricio
Copy link
Collaborator

@rafaelcaricio rafaelcaricio commented Sep 12, 2016

Currently creating or developing an API with Connexion means that you need to Copy&Paste® a little boilerplate (small, but still) code.

import connexion

app = connexion.App(__name__, specification_dir='swagger/')
app.add_api('my_api.yaml')
app.run(port=8080)

Plus would be nice to configure some logging, more Copy&Paste®.

import logging
logging.basicConfig(level=logging.DEBUG)

Then would be nice to have a command line to run the project. Let me Copy&Paste® this little CLI tool boilerplate code structure.

import click
@click.command()
def run():
    ...

Alternatively, we could provide this minimal set of common practices of creating apps using Connexion bundled already within the installation of Connexion itself. To create a Microservice using Connexion, developers would only need to worry about the OpenAPI specification and the actual business logic/Python code. Then run the server using:

$ connexion run my_api.yaml

or

$ connexion run my_api.yaml -p 8080 --debug

Other use case is when during the development we want to run the server with partially implemented endpoints. Just run it:

$ connexion run my_unfinished_api.yaml --stub

Endpoints not implemented yet will return an error message saying that the operation is not yet implemented.

Those changes will make Connexion sail smoothly and providing fast satisfactory results will definitely improve the success of Connexion.

_Important to notice_
This is not a breaking change and all other functionality continues to work the same.

Changes proposed in this pull request:

  • Adds a the class StubResolver to provide a easy way to stub not implemented or not found operations;
  • Adds a command line tool for running specifications (connexion).

I hope you will like it! ❤️

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 82dcb61 on rafaelcaricio:cli into 1f317d2 on zalando:master.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling e7f96e4 on rafaelcaricio:cli into 1f317d2 on zalando:master.

@coveralls
Copy link

coveralls commented Sep 12, 2016

Coverage Status

Coverage remained the same at 100.0% when pulling 97adb25 on rafaelcaricio:cli into 1f317d2 on zalando:master.

@hjacobs
Copy link
Contributor

hjacobs commented Sep 13, 2016

👍 for having connexion as a runnable console script --- but I would only keep one, i.e. remove the cnx alias.

NOTE: I haven't reviewed the whole PR yet...

sys.path.insert(1, path.abspath(base_path or '.'))

resolver = None
if stub:
Copy link
Contributor

Choose a reason for hiding this comment

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

As a future improvement we could implement a resolver that mocks a response based on the specification.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That is definitely interesting. There are some open source tools that do that, but bringing together the possibility to have partially mocked API's, that can morph in a fully implemented one, is a new approach.

Copy link
Contributor

Choose a reason for hiding this comment

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

What I'm looking to do is use my resolving swagger parser prance to generate test cases for an API. That's coming from realizing that swagger-tester isn't quite what I'd like it to be.

Some of that code might well be useful for generating the mocked response. One way or another it's going through the spec and generating stuff.

Just a thought. But I can't guarantee I'll be able to spend time on that.

@jmcs
Copy link
Contributor

jmcs commented Sep 13, 2016

clickclick only supports python3, so we can't use it while we still support python 2.7.

@rafaelcaricio
Copy link
Collaborator Author

@jmcs That is 😒. I will try to make https://github.com/zalando/python-clickclick work with Python 2.7. Shouldn't be difficult.

@rafaelcaricio
Copy link
Collaborator Author

Clickclick supports Python 2.7 now in hjacobs/python-clickclick#9

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 8ef5794 on rafaelcaricio:cli into 58c99a0 on zalando:master.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling d9b59c6 on rafaelcaricio:cli into 58c99a0 on zalando:master.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 7ecb585 on rafaelcaricio:cli into 58c99a0 on zalando:master.

1 similar comment
@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 7ecb585 on rafaelcaricio:cli into 58c99a0 on zalando:master.

@@ -5,3 +5,4 @@ requests>=2.9.1
six>=1.7
strict-rfc3339>=0.6
swagger_spec_validator>=2.0.2
clickclick>=1.1
Copy link
Contributor

Choose a reason for hiding this comment

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

you can now require clickclick>=1.2 for Python 2.7 support

@hjacobs
Copy link
Contributor

hjacobs commented Sep 13, 2016

@rafaelcaricio we also need to add documentation for this CLI feature 😄

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 186f33b on rafaelcaricio:cli into 58c99a0 on zalando:master.

@coveralls
Copy link

coveralls commented Sep 14, 2016

Coverage Status

Coverage remained the same at 100.0% when pulling 6076f96 on rafaelcaricio:cli into 58c99a0 on zalando:master.

resolver_error = 501

app = App(__name__,
swagger_json=hide_spec is False,
Copy link
Contributor

Choose a reason for hiding this comment

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

not hide_spec


app = App(__name__,
swagger_json=hide_spec is False,
swagger_ui=hide_console_ui is False,
Copy link
Contributor

@jmcs jmcs Sep 15, 2016

Choose a reason for hiding this comment

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

not hide_console_ui

@jmcs
Copy link
Contributor

jmcs commented Sep 15, 2016

👍

@hjacobs
Copy link
Contributor

hjacobs commented Sep 15, 2016

@rafaelcaricio how do you run the CLI from the workdir? Can we add a __main__.py file or at least add if __name__ == '__main__' into cli.py?

@coveralls
Copy link

coveralls commented Sep 15, 2016

Coverage Status

Coverage remained the same at 100.0% when pulling 9b7cb99 on rafaelcaricio:cli into 58c99a0 on zalando:master.

@rafaelcaricio
Copy link
Collaborator Author

@hjacobs Added both.

@coveralls
Copy link

coveralls commented Sep 15, 2016

Coverage Status

Coverage decreased (-0.3%) to 99.721% when pulling a2c074d on rafaelcaricio:cli into 58c99a0 on zalando:master.

@rafaelcaricio
Copy link
Collaborator Author

Coverage down... 😞

@hjacobs
Copy link
Contributor

hjacobs commented Sep 15, 2016

We should configure INFO logging by default to at least see the HTTP port...


- BASE_MODULE_PATH (optional): filesystem path where the API endpoints handlers are going to be imported from.
"""
logging_level = logging.ERROR
Copy link
Contributor

Choose a reason for hiding this comment

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

I would use INFO by default.

Or alternatively: ues WARN by default and make it more verbose with -v (INFO) and -vv (DEBUG).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I like the idea of changing levels by adding -v or -vv. Will do that.

@hjacobs
Copy link
Contributor

hjacobs commented Sep 15, 2016

Please use INFO log level by default, having no output at all is really confusing right now... (first I thought it hangs)

$ python3 -m connexion run examples/helloworld/swagger/helloworld-api.yaml  --stub

@rafaelcaricio
Copy link
Collaborator Author

@hjacobs I've added support for different log levels. Please check.

is_flag=True, default=False)
@click.option('--debug', '-d', help='Show debugging information.',
is_flag=True, default=False)
@click.option('--verbose', '-v', help='Show logging information.',
Copy link
Contributor

Choose a reason for hiding this comment

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

@coveralls
Copy link

coveralls commented Sep 15, 2016

Coverage Status

Coverage remained the same at 100.0% when pulling 2d23ac9 on rafaelcaricio:cli into 58c99a0 on zalando:master.

@rafaelcaricio
Copy link
Collaborator Author

@hjacobs done.

@hjacobs
Copy link
Contributor

hjacobs commented Sep 15, 2016

👍

@hjacobs hjacobs merged commit 8b978f4 into spec-first:master Sep 15, 2016
@jmcs jmcs removed the in progress label Sep 15, 2016
@hjacobs
Copy link
Contributor

hjacobs commented Sep 15, 2016

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.

None yet

5 participants