I'm building an automatic proxy generator around any arbitrary API given it's swagger document. The intended output would be a python module that could be used as a client for said API. The API itself would import the proxy generator, point it at its own Swagger page and export the dynamically constructed python client as part of a module.
Currently I'm using the prance library to parse the swagger.json document into a nested-dict structure.
parser = ResolvingParser(swagger_url)
print(parser.specification.keys())
>> dict_keys(['openapi', 'info', 'paths', 'components'])
The paths key here contains most of the juicy bits as a nested dictionary. This can be thought of as a tree, where the root of the tree is the given api path. For example '/api/v1/products' and the rest of the dictionaries are describing details of this path given the OpenAPI spec.
My goal is to take this nested dictionary structure and produce a set of objects that can be used to dynamically create a proxy around the API. The end-goal is to have a structure similar to the below
class Schema:
""" This class would define the object that is going to be returned. aka schema)"""
class Parameter:
name: str
type: str
in: str (Example: query, path, etc.)
class Get(Method):
parameters: List[Parameter]
body: Body = None
return_schema: Schema
class Endpoint():
path: str
description: str
methods: List[Type[Method]]
I would use these objects to dynamically generate a set of methods on a proxy for each endpoint.
I've explored a couple different paths to achieve the goal but am getting stuck on how to best handle the data structure given to me via Prance. I have a vague notion that flattening the data-structure is the best way to continue but need some guidance after this point.
I've:
- Explored using
pd.json_normalize()to normalize the json into a more usable format. This is promising but I'm unsure of how to continue - Flattening the nested dictionary into one level where the keys are the path through the tree separated by
.. - Tried using the built in prance iterators (although I found them to be a bit obtuse to use)
- Tried using openapi-generator but it didn't work for my purposes, as well as the python client being outdated
I'm looking for resources on how I can continue development, given my goals and this data-structure I'm working with.
Although this is the current path I've decided to take, other suggestions are welcome.
I've been working on a standard parser for OpenAPI that is modeled similarly to the classes you described. I've been referring to the format as
OpenAPIIntermediateRepresentationand you can see how the object is modeled in this yaml file. The parser is open source and published under the npm package @fern-api/openapi-parser.For context, I work on an open source project called Fern and we are building an OpenAPI alternative but we also are compatible with existing OpenAPI documents. We have a python SDK generator that generates modern, idiomatic code. If you want to check it out, here are our docs: https://buildwithfern.com/docs/spec/openapi.