Cleaned up header elements
This commit is contained in:
parent
7a348a7d71
commit
8f5ac58c65
|
@ -1,6 +1,6 @@
|
|||
--------------
|
||||
==============
|
||||
Example Script
|
||||
--------------
|
||||
==============
|
||||
|
||||
Create a script that accepts keyword arguments, calls an external api using the arguments, and returns a result.
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
----------------
|
||||
================
|
||||
Example Workflow
|
||||
----------------
|
||||
================
|
||||
|
||||
Here is a simple workflow you can use to call this script.
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
----------------
|
||||
================
|
||||
Tutorial Service
|
||||
----------------
|
||||
================
|
||||
|
||||
Let's build a service that replaces the do_task method in our script. We can then call the service from our script.
|
||||
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
-------
|
||||
api.yml
|
||||
-------
|
||||
===================
|
||||
Define API Endpoint
|
||||
===================
|
||||
|
||||
The API endpoints are defined in `api.yml` in the `paths` section.
|
||||
|
||||
----------
|
||||
Definition
|
||||
----------
|
||||
|
||||
Endpoints all have a `path`. Our path will be `get_cards`.
|
||||
Endpoints can have `parameters`. Our parameters are `cards` and `decks`.
|
||||
Our parameters are included as part of the query.
|
||||
|
@ -55,6 +59,10 @@ Here is what that code looks like:
|
|||
items:
|
||||
$ref: "#/components/schemas/PlayingCards"
|
||||
|
||||
------
|
||||
Schema
|
||||
------
|
||||
|
||||
We need to define the schema for PlayingCards.
|
||||
|
||||
Our playing cards have two properties; suit and value.
|
||||
|
@ -84,3 +92,12 @@ The schema code looks like this:
|
|||
We use the `Connexion <https://connexion.readthedocs.io/en/latest/>`_ framework for our API.
|
||||
|
||||
You can check your YML code at https://editor.swagger.io/
|
||||
|
||||
|
||||
-----------
|
||||
Python Code
|
||||
-----------
|
||||
|
||||
In our definition, we defined the **operationId** and gave it the value **crc.api.tools.get_cards**.
|
||||
|
||||
We now need to write the Python code that should exist in `crc.api.tools.get_cards`.
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
We now need to write the Python code that should exist in `crc.api.tools.get_cards`.
|
||||
=======================
|
||||
Get Cards
|
||||
=======================
|
||||
|
||||
-----------------------
|
||||
crc.api.tools.get_cards
|
||||
-----------------------
|
||||
|
||||
We have defined an API endpoint. Now, we need to write the Python code to support it.
|
||||
We defined an API endpoint. Now, we need to write the Python code to support it.
|
||||
|
||||
When we defined the get_cards endpoint, we set `operationId` to `crc.api.tools.get_cards`.
|
||||
|
||||
|
@ -17,6 +15,7 @@ This means that the API expects a method called `get_cards` in the `crc.api.tool
|
|||
|
||||
We need to add this method.
|
||||
|
||||
---------
|
||||
get_cards
|
||||
---------
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---------
|
||||
=========
|
||||
Endpoints
|
||||
---------
|
||||
=========
|
||||
|
||||
At this point, we should have a functioning API endpoint that calls crc.api.tools.get_cards.
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
--------
|
||||
========
|
||||
ApiError
|
||||
--------
|
||||
========
|
||||
|
||||
----------
|
||||
Definition
|
||||
----------
|
||||
|
||||
|
@ -37,6 +38,7 @@ The other arguments allow us to pass along additional information depending on t
|
|||
self.task_user = user
|
||||
|
||||
|
||||
-----
|
||||
Usage
|
||||
-----
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
------------------------
|
||||
==============
|
||||
Helper Methods
|
||||
------------------------
|
||||
==============
|
||||
|
||||
ApiError has 2 useful methods; **from_task** and **from_task_spec**.
|
||||
|
||||
|
@ -11,6 +11,7 @@ TODO: task vs task spec
|
|||
|
||||
Notice that these are class methods.
|
||||
|
||||
---------
|
||||
from_task
|
||||
---------
|
||||
|
||||
|
@ -31,6 +32,7 @@ In addition to `code` and `message`, from_task requires a **task** argument.
|
|||
return instance
|
||||
|
||||
|
||||
--------------
|
||||
from_task_spec
|
||||
--------------
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
-------------
|
||||
=============
|
||||
Example Usage
|
||||
-------------
|
||||
=============
|
||||
|
||||
---------------
|
||||
Using from_task
|
||||
---------------
|
||||
|
||||
|
@ -31,6 +32,7 @@ We also catch a general Exception error and log it.
|
|||
app.logger.error(str(e), exc_info=True)
|
||||
|
||||
|
||||
----------------------
|
||||
Call ApiError directly
|
||||
----------------------
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--------------
|
||||
==============
|
||||
ApiErrorSchema
|
||||
--------------
|
||||
==============
|
||||
|
||||
CR Connect Workflow defines another class in crc.api.common that helps us format ApiError output as JSON so we can return it to the frontend
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--------------------
|
||||
====================
|
||||
Unhandled Exceptions
|
||||
--------------------
|
||||
====================
|
||||
|
||||
CR Connect Workflow uses a feature of flask to capture unhandled exceptions.
|
||||
In crc.api.common, we define a handler for InternalServerError and add a call to ApiError.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
----
|
||||
====
|
||||
More
|
||||
----
|
||||
====
|
||||
|
||||
More about Python error handling: https://docs.python.org/3/tutorial/errors.html#handling-exceptions
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
------
|
||||
======
|
||||
Layout
|
||||
------
|
||||
======
|
||||
|
||||
Tests are in the **/tests** directory.
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
.. _index-test-examples:
|
||||
|
||||
--------
|
||||
========
|
||||
Examples
|
||||
--------
|
||||
========
|
||||
|
||||
One of the best ways to learn about writing tests is to look at existing tests.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
===========
|
||||
Hello World
|
||||
===========
|
||||
|
||||
|
@ -7,6 +8,7 @@ Then, we can test the new feature by running the workflow and making assertions
|
|||
|
||||
Here is a simple test of a workflow.
|
||||
|
||||
----
|
||||
Code
|
||||
----
|
||||
|
||||
|
@ -30,6 +32,7 @@ Code
|
|||
|
||||
self.assertEqual('Hello asdf', second_task.documentation)
|
||||
|
||||
-----
|
||||
Setup
|
||||
-----
|
||||
|
||||
|
@ -56,6 +59,7 @@ You can have more than one test method in a test class.
|
|||
Each test method must begin with **test_**.
|
||||
|
||||
|
||||
------
|
||||
Detail
|
||||
------
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
============
|
||||
Email Script
|
||||
============
|
||||
|
||||
|
@ -6,6 +7,7 @@ and the scaffolding available in BaseTest.
|
|||
|
||||
These next examples test the email script, and they each show us something more than the basics.
|
||||
|
||||
----------
|
||||
Validation
|
||||
----------
|
||||
|
||||
|
@ -26,6 +28,7 @@ It shows us how to call an API endpoint.
|
|||
rv = self.app.get('/v1.0/workflow-specification/%s/validate' % spec_model.id, headers=self.logged_in_headers())
|
||||
self.assertEqual([], rv.json)
|
||||
|
||||
---------------
|
||||
with ... outbox
|
||||
---------------
|
||||
|
||||
|
@ -52,6 +55,7 @@ Flask mail has a way to intercept the emails and show you the results using a co
|
|||
self.assertEqual(['test@example.com'], outbox[0].recipients)
|
||||
self.assertIn('Thank you for using this email example', outbox[0].body)
|
||||
|
||||
---------
|
||||
Exception
|
||||
---------
|
||||
|
||||
|
@ -67,6 +71,7 @@ We can test for error conditions.
|
|||
self.complete_form(workflow, first_task, {'recipients': 'test@example'})
|
||||
|
||||
|
||||
--------
|
||||
Add data
|
||||
--------
|
||||
|
||||
|
|
Loading…
Reference in New Issue