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

docs: update architecture description and examples #550

Merged
merged 7 commits into from
Feb 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .isort.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ skip_glob =
.git/*,.tox/*,.venv/*,venv/*,.venv*/*,venv*/*,
_OLD/*,_TEST/*,
docs/*
examples/*
combine_as_imports = true
default_section = THIRDPARTY
ensure_newline_before_comments = true
Expand Down
3 changes: 1 addition & 2 deletions docs/architecture.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Architecture

This library broadly is separated into three key functional areas:

1. **Model**: Internal models used to unify data from different parsers
1. **Model**: Internal models used to unify data.

**Note:** As of version 4.0.0 of this library we support deserialization from JSON and XML as well as
serialization to JSON and XML.
Expand All @@ -30,7 +30,6 @@ When wishing to generate a BOM, the process is as follows:
1. Generate a Model by either:
1. Programmatically using this library
2. By deserializing from an existing CycloneDX BOM document
3. From a :py:mod:`cyclonedx.parser`
2. Output the Model using an :py:mod:`cyclonedx.output` instance that reflects the schema version and format you require

.. toctree::
Expand Down
14 changes: 11 additions & 3 deletions docs/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,17 @@
Examples
========

Complex
-------
Complex Serialize
-----------------

.. literalinclude:: ../examples/complex.py
.. literalinclude:: ../examples/complex_serialize.py
:language: python
:linenos:


Complex Deserialize
-------------------

.. literalinclude:: ../examples/complex_deserialize.py
:language: python
:linenos:
20 changes: 3 additions & 17 deletions docs/modelling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
Modelling
=========

You can create a BOM Model from either a :py:mod:`cyclonedx.parser` instance or manually using the methods available
directly on the :py:mod:`cyclonedx.model.bom.Bom` class.
You can create a BOM Model from either manually using the methods available
directly on the :py:class:`cyclonedx.model.bom.Bom` class,
or deserialize a JSON/XML via :py:meth:`cyclonedx.model.bom.Bom.from_json`/:py:meth:`cyclonedx.model.bom.Bom.from_xml`

Vulnerabilities are supported by the Model as of version 0.3.0.

Expand Down Expand Up @@ -76,21 +77,6 @@ you use a library such as `defusedxml` instead of the native `xml.etree.ElementT
deserialized_bom = cast(Bom, Bom.from_xml(data=ElementTree.fromstring(input_xml.read())))


Example BOM using a Parser
--------------------------

**Note:** Concreate parser implementations were moved out of this library and into `CycloneDX Python`_ as of version
``1.0.0``.

.. code-block:: python

from cyclonedx.model.bom import Bom
from cyclonedx_py.parser.environment import EnvironmentParser

parser = EnvironmentParser()
bom = Bom.from_parser(parser=parser)




.. _CycloneDX Python: https://github.com/CycloneDX/cyclonedx-python
Expand Down
3 changes: 2 additions & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Examples

* [Build & Serialize](build_and_serialize.py)
* [Build & Serialize](complex_serialize.py)
* [Deserialize](complex_deserialize.py)

----

Expand Down
267 changes: 267 additions & 0 deletions examples/complex_deserialize.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,267 @@
# This file is part of CycloneDX Python Lib
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
# Copyright (c) OWASP Foundation. All Rights Reserved.

import sys
from json import loads as json_loads
from typing import TYPE_CHECKING

from defusedxml import ElementTree as SafeElementTree # type:ignore[import-untyped]

from cyclonedx.exception import MissingOptionalDependencyException
from cyclonedx.model.bom import Bom
from cyclonedx.schema import OutputFormat, SchemaVersion
from cyclonedx.validation import make_schemabased_validator
from cyclonedx.validation.json import JsonStrictValidator

if TYPE_CHECKING:
from cyclonedx.validation.xml import XmlValidator

# region JSON

json_data = """{
"$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"serialNumber": "urn:uuid:88fabcfa-7529-4ba2-8256-29bec0c03900",
"version": 1,
"metadata": {
"timestamp": "2024-02-10T21:38:53.313120+00:00",
"tools": [
{
"vendor": "CycloneDX",
"name": "cyclonedx-python-lib",
"version": "6.4.1",
"externalReferences": [
{
"type": "build-system",
"url": "https://github.com/CycloneDX/cyclonedx-python-lib/actions"
},
{
"type": "distribution",
"url": "https://pypi.org/project/cyclonedx-python-lib/"
},
{
"type": "documentation",
"url": "https://cyclonedx-python-library.readthedocs.io/"
},
{
"type": "issue-tracker",
"url": "https://github.com/CycloneDX/cyclonedx-python-lib/issues"
},
{
"type": "license",
"url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE"
},
{
"type": "release-notes",
"url": "https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md"
},
{
"type": "vcs",
"url": "https://github.com/CycloneDX/cyclonedx-python-lib"
},
{
"type": "website",
"url": "https://github.com/CycloneDX/cyclonedx-python-lib/#readme"
}
]
}
],
"component": {
"bom-ref": "myApp",
"name": "myApp",
"type": "application",
"licenses": [
{
"license": {
"id": "MIT"
}
}
]
}
},
"components": [
{
"bom-ref": "myComponent@1.33.7-beta.1",
"type": "library",
"group": "acme",
"name": "some-component",
"version": "1.33.7-beta.1",
"purl": "pkg:generic/acme/some-component@1.33.7-beta.1",
"licenses": [
{
"license": {
"name": "(c) 2021 Acme inc."
}
}
],
"supplier": {
"name": "Acme Inc",
"url": [
"https://www.acme.org"
]
}
},
{
"bom-ref": "some-lib",
"type": "library",
"name": "some-library",
"licenses": [
{
"expression": "GPL-3.0-only WITH Classpath-exception-2.0"
}
]
}
],
"dependencies": [
{
"ref": "some-lib"
},
{
"dependsOn": [
"myComponent@1.33.7-beta.1"
],
"ref": "myApp"
},
{
"dependsOn": [
"some-lib"
],
"ref": "myComponent@1.33.7-beta.1"
}
]
}"""
my_json_validator = JsonStrictValidator(SchemaVersion.V1_5)
try:
validation_errors = my_json_validator.validate_str(json_data)
if validation_errors:
print('JSON invalid', 'ValidationError:', repr(validation_errors), sep='\n', file=sys.stderr)
sys.exit(2)
print('JSON valid')
except MissingOptionalDependencyException as error:
print('JSON-validation was skipped due to', error)
bom_from_json = Bom.from_json( # type: ignore[attr-defined]
json_loads(json_data))
print('bom_from_json', repr(bom_from_json))

# endregion JSON

print('', '=' * 30, '', sep='\n')

# endregion XML

xml_data = """<?xml version="1.0" ?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.5"
serialNumber="urn:uuid:88fabcfa-7529-4ba2-8256-29bec0c03900"
version="1"
>
<metadata>
<timestamp>2024-02-10T21:38:53.313120+00:00</timestamp>
<tools>
<tool>
<vendor>CycloneDX</vendor>
<name>cyclonedx-python-lib</name>
<version>6.4.1</version>
<externalReferences>
<reference type="build-system">
<url>https://github.com/CycloneDX/cyclonedx-python-lib/actions</url>
</reference>
<reference type="distribution">
<url>https://pypi.org/project/cyclonedx-python-lib/</url>
</reference>
<reference type="documentation">
<url>https://cyclonedx-python-library.readthedocs.io/</url>
</reference>
<reference type="issue-tracker">
<url>https://github.com/CycloneDX/cyclonedx-python-lib/issues</url>
</reference>
<reference type="license">
<url>https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE</url>
</reference>
<reference type="release-notes">
<url>https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md</url>
</reference>
<reference type="vcs">
<url>https://github.com/CycloneDX/cyclonedx-python-lib</url>
</reference>
<reference type="website">
<url>https://github.com/CycloneDX/cyclonedx-python-lib/#readme</url>
</reference>
</externalReferences>
</tool>
</tools>
<component type="application" bom-ref="myApp">
<name>myApp</name>
<licenses>
<license>
<id>MIT</id>
</license>
</licenses>
</component>
</metadata>
<components>
<component type="library" bom-ref="myComponent@1.33.7-beta.1">
<supplier>
<name>Acme Inc</name>
<url>https://www.acme.org</url>
</supplier>
<group>acme</group>
<name>some-component</name>
<version>1.33.7-beta.1</version>
<licenses>
<license>
<name>(c) 2021 Acme inc.</name>
</license>
</licenses>
<purl>pkg:generic/acme/some-component@1.33.7-beta.1</purl>
</component>
<component type="library" bom-ref="some-lib">
<name>some-library</name>
<licenses>
<expression>GPL-3.0-only WITH Classpath-exception-2.0</expression>
</licenses>
</component>
</components>
<dependencies>
<dependency ref="some-lib"/>
<dependency ref="myApp">
<dependency ref="myComponent@1.33.7-beta.1"/>
</dependency>
<dependency ref="myComponent@1.33.7-beta.1">
<dependency ref="some-lib"/>
</dependency>
</dependencies>
</bom>"""
my_xml_validator: 'XmlValidator' = make_schemabased_validator(OutputFormat.XML, SchemaVersion.V1_5)
try:
validation_errors = my_xml_validator.validate_str(xml_data)
if validation_errors:
print('XML invalid', 'ValidationError:', repr(validation_errors), sep='\n', file=sys.stderr)
sys.exit(2)
print('XML valid')
except MissingOptionalDependencyException as error:
print('XML-validation was skipped due to', error)
bom_from_xml = Bom.from_xml( # type: ignore[attr-defined]
SafeElementTree.fromstring(xml_data))
print('bom_from_xml', repr(bom_from_xml))

# endregion XML

print('', '=' * 30, '', sep='\n')

print('assert bom_from_json equals bom_from_xml')
assert bom_from_json == bom_from_xml, 'expected to have equal BOMs from JSON and XML'
7 changes: 3 additions & 4 deletions examples/complex.py → examples/complex_serialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
# Copyright (c) OWASP Foundation. All Rights Reserved.

import sys
from typing import TYPE_CHECKING

from packageurl import PackageURL

Expand All @@ -26,11 +27,9 @@
from cyclonedx.model.component import Component, ComponentType
from cyclonedx.output import make_outputter
from cyclonedx.output.json import JsonV1Dot5
from cyclonedx.schema import SchemaVersion, OutputFormat
from cyclonedx.validation.json import JsonStrictValidator
from cyclonedx.schema import OutputFormat, SchemaVersion
from cyclonedx.validation import make_schemabased_validator

from typing import TYPE_CHECKING
from cyclonedx.validation.json import JsonStrictValidator

if TYPE_CHECKING:
from cyclonedx.output.json import Json as JsonOutputter
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ include = [
{ path="README.md", format =["sdist","wheel"] },
{ path="LICENSE", format=["sdist","wheel"] },
{ path="NOTICE", format=["sdist","wheel"] },
{ path="tests", format=["sdist"] },
{ path="CHANGELOG.md", format=["sdist"] },
{ path="docs", format=["sdist"] },
{ path="examples", format=["sdist"] },
{ path="tests", format=["sdist"] },
]
exclude = [
# exclude dotfiles and dotfolders
Expand Down
Loading