Skip to content

Commit

Permalink
[plugin][feat] Better docs and docs_url (#2210)
Browse files Browse the repository at this point in the history
  • Loading branch information
aquamatthias authored Oct 1, 2024
1 parent 5aee8cb commit 4ba56c1
Show file tree
Hide file tree
Showing 70 changed files with 1,184 additions and 1,037 deletions.
9 changes: 6 additions & 3 deletions fixcore/fixcore/model/exportable_model.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import List
from typing import List, Union

from fixcore.model.model import (
Model,
Expand All @@ -18,7 +18,7 @@ def json_export_simple_schema(
model: Model,
with_properties: bool = True,
with_relatives: bool = True,
with_metadata: bool = True,
with_metadata: Union[bool, List[str]] = True,
) -> List[Json]:
def export_simple(kind: SimpleKind) -> Json:
result = kind.as_json()
Expand Down Expand Up @@ -56,7 +56,10 @@ def export_complex(kind: ComplexKind) -> Json:
aggregate_root=kind.aggregate_root,
)
if with_metadata:
result["metadata"] = kind.metadata
if isinstance(with_metadata, list):
result["metadata"] = {k: v for k, v in kind.metadata.items() if k in with_metadata}
else:
result["metadata"] = kind.metadata
if with_properties:
result["allow_unknown_props"] = kind.allow_unknown_props
result["properties"] = {prop.name: export_property(prop, kind) for prop, kind in kind.all_props_with_kind()}
Expand Down
10 changes: 7 additions & 3 deletions fixcore/fixcore/model/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -945,14 +945,18 @@ def is_complex(self) -> bool:

def as_json(self, **kwargs: bool) -> Json:
result: Json = {"fqn": self.fqn, "aggregate_root": self.aggregate_root}
if kwargs.get("with_metadata", True):
result["metadata"] = self.metadata
if wm := kwargs.get("with_metadata", True):
if isinstance(wm, list):
result["metadata"] = {k: v for k, v in self.metadata.items() if k in wm}
else:
result["metadata"] = self.metadata
if kwargs.get("with_properties", True):
result["allow_unknown_props"] = self.allow_unknown_props
result["properties"] = [to_js(prop) for prop in self.properties]
if kwargs.get("with_relatives", True):
result["bases"] = self.bases
result["successor_kinds"] = self.successor_kinds
if kwargs.get("with_bases", True):
result["bases"] = self.bases
return result

def copy(
Expand Down
48 changes: 39 additions & 9 deletions fixcore/fixcore/static/api-doc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ paths:
schema:
type: boolean
default: false
- name: format
description: "The format of the returned json"
in: query
schema:
type: string
enum:
- schema
- simple
required: false
- name: kind
description: "Only return information about the defined kinds. Comma separated list."
in: query
Expand All @@ -69,27 +78,48 @@ paths:
schema:
type: string
default: null
- name: with_bases
description: "Render all base classes. Only together with kind or filter"
- name: aggregate_roots_only
description: "Only return aggregate roots."
in: query
schema:
type: boolean
default: false
- name: format
description: "The format of the returned json"
- name: with_bases
description: "Include base classes and render the base section"
in: query
schema:
type: string
enum:
- schema
- simple
required: false
type: boolean
default: false
- name: with_property_kinds
description: "Render types of property values. Only together with kind or filter"
in: query
schema:
type: boolean
default: false
- name: with_properties
description: "Render the properties of complex kinds"
in: query
schema:
type: boolean
default: true
- name: with_relatives
description: "Include information about relationships to other kinds."
in: query
schema:
type: boolean
default: true
- name: with_metadata
description: "Include metadata information."
in: query
schema:
oneOf:
- type: boolean
description: "If true, all metadata is included."
- type: array
description: "List of metadata keys to include."
items:
type: string
default: true


responses:
Expand Down
17 changes: 15 additions & 2 deletions fixcore/fixcore/web/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -961,13 +961,21 @@ async def model_uml(self, request: Request, deps: TenantDependencies) -> StreamR
return response

async def get_model(self, request: Request, deps: TenantDependencies) -> StreamResponse:
def parse_bool_or_list(s: str) -> Union[bool, List[str]]:
lwr = s.lower()
if lwr == "true":
return True
if lwr == "false":
return False
return s.split(",")

graph_id = GraphName(request.match_info.get("graph_id", "fix"))
full_model = await deps.model_handler.load_model(graph_id)
with_bases = if_set(request.query.get("with_bases"), lambda x: x.lower() == "true", False)
with_property_kinds = if_set(request.query.get("with_property_kinds"), lambda x: x.lower() == "true", False)
with_properties = if_set(request.query.get("with_properties"), lambda x: x.lower() == "true", True)
with_relatives = if_set(request.query.get("with_relatives"), lambda x: x.lower() == "true", True)
with_metadata = if_set(request.query.get("with_metadata"), lambda x: x.lower() == "true", True)
with_metadata = if_set(request.query.get("with_metadata"), parse_bool_or_list, True)
aggregate_roots_only = if_set(request.query.get("aggregate_roots_only"), lambda x: x.lower() == "true", False)
md = full_model
if kind := request.query.get("kind"):
Expand All @@ -990,7 +998,12 @@ async def get_model(self, request: Request, deps: TenantDependencies) -> StreamR
)
else:
json_model = [
m.as_json(with_properties=with_properties, with_relatives=with_relatives, with_metadata=with_metadata)
m.as_json(
with_properties=with_properties,
with_relatives=with_relatives,
with_metadata=with_metadata,
with_bases=with_bases,
)
for m in md.kinds.values()
]
return await single_result(request, json.loads(json.dumps(json_model, sort_keys=True)))
Expand Down
4 changes: 3 additions & 1 deletion fixlib/fixlib/baseresources.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,9 +268,11 @@ class BaseResource(ABC):
_metadata: ClassVar[Dict[str, Any]] = {"icon": "resource", "group": "misc"}
# Categories of this resource kind.
_categories: ClassVar[List[Category]] = []
# Link to the cloud providers product documentation of this resource kind.
_docs_url: ClassVar[Optional[str]] = None

################################################################################
# InstanceVariables
# Instance Variables

# Identifier of this resource. Does not need to be globally unique. chksum is used to compute a unique identifier.
id: str
Expand Down
2 changes: 2 additions & 0 deletions fixlib/fixlib/core/model_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ def export_data_class(clazz: type) -> None:
metadata["service"] = s
if (slc := getattr(clazz, "categories", None)) and callable(slc) and (sl := slc()):
metadata["categories"] = sl
if (docs_url := getattr(clazz, "_docs_url", None)) and isinstance(docs_url, str):
metadata["docs_url"] = docs_url
if ( # only export kind description on aggregate roots
with_kind_description
and (ar := aggregate_root)
Expand Down
4 changes: 3 additions & 1 deletion plugins/aws/fix_plugin_aws/collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,8 @@ def add_accounts(parent: Union[AwsOrganizationalRoot, AwsOrganizationalUnit]) ->
class AwsOrganizationalRoot(BaseOrganizationalRoot, AwsResource):
kind: ClassVar[str] = "aws_organizational_root"
_kind_display: ClassVar[str] = "AWS Organizational Root"
_kind_description: ClassVar[str] = "An AWS Organizational Root is the root of an AWS Organization."
_kind_description: ClassVar[str] = "AWS Organizational Root is the top-level entity in AWS Organizations. It serves as the starting point for creating and managing multiple AWS accounts within an organization. The root provides centralized control over billing, access management, and resource allocation across all member accounts, ensuring consistent policies and governance throughout the organizational structure." # fmt: skip
_docs_url: ClassVar[str] = "https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_org_root.html"
_kind_service = "organizations"
_metadata: ClassVar[Dict[str, Any]] = {"icon": "group", "group": "management"}

Expand All @@ -471,5 +472,6 @@ class AwsOrganizationalUnit(BaseOrganizationalUnit, AwsResource):
kind: ClassVar[str] = "aws_organizational_unit"
_kind_display: ClassVar[str] = "AWS Organizational Unit"
_kind_description: ClassVar[str] = "An AWS Organizational Unit is a container for AWS Accounts."
_docs_url: ClassVar[str] = "https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_ous.html"
_kind_service = "organizations"
_metadata: ClassVar[Dict[str, Any]] = {"icon": "group", "group": "management"}
3 changes: 2 additions & 1 deletion plugins/aws/fix_plugin_aws/resource/acm.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ class AwsAcmCertificate(AwsResource, BaseCertificate):
kind: ClassVar[str] = "aws_acm_certificate"
_kind_display: ClassVar[str] = "AWS ACM Certificate"
_aws_metadata: ClassVar[Dict[str, Any]] = {"provider_link_tpl": "https://{region_id}.console.aws.amazon.com/acm/home?region={region}#/certificates/{id}", "arn_tpl": "arn:{partition}:acm:{region}:{account}:certificate/{id}"} # fmt: skip
_kind_description: ClassVar[str] = "An AWS ACM Certificate is used to provision, manage, and deploy Secure Sockets Layer/Transport Layer Security (SSL/TLS) certificates for secure web traffic on AWS services." # fmt: skip
_kind_description: ClassVar[str] = "AWS ACM Certificate is a digital credential issued by Amazon Web Services Certificate Manager. It authenticates the identity of websites and secures connections between clients and servers. ACM Certificates encrypt data in transit, prevent unauthorized access, and establish trust for online services. They support various AWS services and can be deployed across multiple regions." # fmt: skip
_docs_url: ClassVar[str] = "https://docs.aws.amazon.com/acm/latest/userguide/acm-overview.html"
_kind_service: ClassVar[Optional[str]] = service_name
api_spec: ClassVar[AwsApiSpec] = AwsApiSpec("acm", "describe-certificate", "Certificate")
mapping: ClassVar[Dict[str, Bender]] = {
Expand Down
Loading

0 comments on commit 4ba56c1

Please sign in to comment.