Build OpenAPI and AsyncAPI specs based off one or more resource json schema files
Project description
Firestone
A Resource-Based Approach to Building APIs
firestone
allows you to build OpenAPI, AsyncAPI and gRPC specs based off one or more resource JSON schema files. This allows you to focus on what really matters, the resource you are developing!
Once you have generated the appropriate specification file for your project, you can then use the myriad of libraries and frameworks to generate stub code.
The primary premise of this project is not to introduce any new "language" to describe your resources(s), rather, use JSON Schema!
This makes it easy to come up to speed with little to no prior knowledge to get going.
Having said that, the schema for a resource provides additional helpful functionality, see the schema section for further details.
Quick Start
You can use pip
or poetry
to install and run firestone
. We suggest using pip
if you wish to install firestone
globally, or for virtual environments, use poetry
.
pip
It's a simple as running the following pip
command:
sudo pip install firestoned
Yes,
firestone**d**
, notfirestone
! This is because there already is a, albeit emtpy, repository on pypi.org with the same name ...
poetry
Poetry is a great build tool for Python that allows you to build and run all locally in a virtual environment. This is great for checking out the tool and playing around with firestone
itself.
If you're starting with a new project, declare firestoned
in your dependencies during the poetry install
process:
poetry install
poetry build
If you're adding firestone
to a poetry
project:
poetry add firestoned
poetry build
Running
Now that you have a copy of firestone
, let's try running it with the example resource provided, an addressbook!
If running within
poetry
build, simply prepend commands withpoetry run
.
For the remainder of this documentation, we will assume you have installed
firestone
.
Generate an OpenAPI Spec
firestone \
generate \
--title 'Addressbook resource' \
--description 'A simple addressBook example' \
--resources examples/addressBook/resource.yaml \
openapi
--security '{"name": "bearer_auth", "scheme": "bearer", "type": "http", "bearerFormat": "JWT"}' \
Let's quickly dissect this command:
- We are telling firestone to generate an
openapi
spec, given thetitle
,description
, and the two given resource files. - By default, this will output the specification file to
stdout
, alternatively, you can provide the-O
option to output to a specific file.
You can also add the command line --ui-server
to the end, which will launch a small webserver and run the Swagger UI to view this specification file.
firestone --debug generate --title 'Example person and addressBook API' \
--description 'An example API with more than one resource' \
--resources examples/addressBook.yaml,examples/person.yaml \
openapi \
--security '{"name": "bearer_auth", "scheme": "bearer", "type": "http", "bearerFormat": "JWT"}' \
--ui-server
# ...
* Serving Quart app 'firestone.__main__'
* Environment: production
* Please use an ASGI server (e.g. Hypercorn) directly in production
* Debug mode: False
* Running on http://127.0.0.1:5000 (CTRL + C to quit)
[2022-10-31 02:47:17 -0500] [87590] [INFO] Running on http://127.0.0.1:5000 (CTRL + C to quit)
# 2022-10-31 02:47:17,120 - [MainThread] hypercorn.error:102 INFO - Running on http://127.0.0.1:5000 (CTRL + C to quit)
Now you can use your browser to navigate to http://127.0.0.1:5000/apidocs
to view the Swagger UI.
Schema
It all begins with your resource definition! This is done using JSON schema and we have provided an example in our examples
directory, called addressBook. We will use this to describe how the schema is setup and how you can adapt to your own.
Here is the full file:
# Metadata: start
name: addressbook
description: An example of an addressbook resource
version: 1.0
version_in_path: false
default_query_params:
- name: limit
description: Limit the number of responses back
in: query
schema:
type: integer
- name: offset
description: The offset to start returning resources
in: query
schema:
type: integer
asyncapi:
servers:
dev:
url: ws://localhost
protocol: ws
description: The development websocket server
channels:
resources: true
instances: true
instance_attrs: true
# You can limit the overall HTTP methods for the high level resource endpoint
methods:
resource:
- get
- post
instance:
- delete
- get
- head
- put
instance_attrs:
- delete
- get
- head
- put
descriptions:
resource:
get: List all addresses in this addressbook.
head: Determine the existence and size of addresses in this addressbook.
patch: Patch one or more addresses in this addressbook.
post: Create a new address in this addressbook, a new address key will be created.
delete: Delete all addresses from this addressbook.
instance:
get: Get a specific address from this addressbook.
head: Determine the existence and size of this address.
patch: Patch this address in the addressbook.
put: Update an existing address in this addressbook, with the given address key.
delete: Delete an address from this addressbook.
# Metadata: end
schema:
type: array
key:
name: address_key
description: A unique identifier for an addressbook entry.
schema:
type: string
#responseCodes:
# - 200
# - 201
query_params:
- name: city
description: Filter by city name
required: false
schema:
type: string
methods:
- get
items:
type: object
properties:
# embeded person
person:
description: This is a person object that lives at this address.
schema:
$ref: "person.yaml#/schema"
addrtype:
description: The address type, e.g. work or home
type: string
# Don't expose this attribute in the URL/specification
# expose: false
enum:
- work
- home
street:
description: The street and civic number of this address
type: string
city:
description: The city of this address
type: string
state:
description: The state of this address
type: string
country:
description: The country of this address
type: string
people:
description: A list of people's names living there
type: array
items:
type: string
required:
- addrtype
- street
- city
- state
- country
Schema Metadata Fields
name
Name is used in various places, including as the root to API URLs, for example in OpenAPI, /addressBook
description
The description of this resource is used in the generated specification files.
version
The version of this resource definition, this can alternatively be used in the URL as well, see below version_in_path
.
version_in_path
This attribute defines whether to prepend the version defined above in the URL paths. For example, for the
above, you would get: /v1.0/addressBook
.
default_query_params
You can provide a list of default query parameters that will be added to all HTTP methods,
or optionally you can provide a list of the HTTP methods, for which firestone
will add.
methods
This is a map/dict of resource
, and/or instance
, and/or instance_attrs
(the instance attributes to expose), and a list of methods to explicitly expose.
descriptions
This is a map/dict of either resource
and/or instance
, which itself is a map or methods to descriptions.
Generate OpenAPI Client
Now, to generate your OpenAPI client, you will need the openapi-generator
command (installation instructions to generate client code in many languages.
Please check out the OpenAPI Project for more details.
This client code can then be used as an SDK or used by our CLI generation, for example:
openapi-generator generate \
-i examples/addressbook/openapi.yaml \
-g python-nextgen \
-o /tmp/addressbook-client \
--skip-validate-spec \
-c examples/addressbook/openapi-gen-config.json
Generate Python CRUD CLI
Now that you have generated the client code, you can also generate a CRUD, Python Click-based CLI around your code. This generator creates a standalone script or as a module to be used in your console scripts, as part of your project build.
Please checkout the Click Project for more details.
Here is an example command we use to generate the example Addressbook.
firestone generate \
--title 'Addressbook CLI' \
--description 'This is the CLI for the example Addressbook' \
--resources examples/addressbook/addressbook.yaml,examples/addressbook/person.yaml \
--version 1.0 \
cli \
--pkg addressbook \
--client-pkg addressbook.client > examples/addressbook/main.py
Contributing
firestone
and the larger Firestone Project are open-source projects and we welcome contributions. Please follow standard GitHub practices, including forking the project, creating a branch, and submitting a PR.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file firestoned-0.4.2.tar.gz
.
File metadata
- Download URL: firestoned-0.4.2.tar.gz
- Upload date:
- Size: 24.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.9.19
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1aedd52ce5d93ade524b1764d0901e956b91a91cd470335096953090c099fb96 |
|
MD5 | c9bb8ec4158e5a56a6924714d069632d |
|
BLAKE2b-256 | 91c1196382465a1f4b5cf94e70c8472e01131710909229092006897c0c582907 |
File details
Details for the file firestoned-0.4.2-py3-none-any.whl
.
File metadata
- Download URL: firestoned-0.4.2-py3-none-any.whl
- Upload date:
- Size: 26.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.9.19
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 651e2d0b7f31be00f553fd02d9703754f68450dc2c805e1ee9532e783af183a8 |
|
MD5 | acc2677c082c6c5f02b825cfb30dce55 |
|
BLAKE2b-256 | ba48944999ec10c18d7ddaaabda3b28763e4a3c2fb782ffd245f36f2762b4e1f |