Python library for generating CycloneDX SBOMs

Overview

Python Library for generating CycloneDX

GitHub Workflow Status Python Version Support PyPI Version GitHub license GitHub issues GitHub forks GitHub stars


This CycloneDX module for Python can generate valid CycloneDX bill-of-material document containing an aggregate of all project dependencies.

This module is not designed for standalone use. If you're looking for a CycloneDX tool to run to generate (SBOM) software bill-of-materials documents, why not checkout:

Additionally, the following tool can be used as well (and this library was written to help improve it)

Additionally, you can use this module yourself in your application to programmatically generate SBOMs.

CycloneDX is a lightweight BOM specification that is easily created, human-readable, and simple to parse.

Installation

Install from pypi.org as you would any other Python module:

pip install cyclonedx-python-lib

Architecture

This module break out into three key areas:

  1. Parser: Use a parser that suits your needs to automatically gather information about your environment or application
  2. Model: Internal models used to unify data from different parsers
  3. Output: Choose and configure an output which allows you to define output format as well as the CycloneDX schema version

Parsing

You can use one of the parsers to obtain information about your project or environment. Available parsers:

Parser Class / Import Description
Environment from cyclonedx.parser.environment import EnvironmentParser Looks at the packaged installed in your current Python environment.
PoetryParser from cyclonedx.parser.poetry import PoetryParser Parses poetry.lock content passed in as a string.
PoetryFileParser from cyclonedx.parser.poetry import PoetryFileParser Parses the poetry.lock file at the supplied path.
RequirementsParser from cyclonedx.parser.requirements import RequirementsParser Parses a multiline string that you provide that conforms to the requirements.txt PEP-508 standard.
RequirementsFileParser from cyclonedx.parser.requirements import RequirementsFileParser Parses a file that you provide the path to that conforms to the requirements.txt PEP-508 standard.

Example

from cyclonedx.parser.environment import EnvironmentParser

parser = EnvironmentParser()

Modelling

You can create a BOM Model from either an Parser instance or manually using the methods avaialbel directly on the Bom class.

Example from a Parser

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

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

Generating Output

Once you have an instance of a Bom you can produce output in either JSON or XML against any of the supporting CycloneDX schema versions as you require.

We provide two helper methods:

  1. Output to string (for you to do with as you require)
  2. Output directly to a filename you provide
Example as JSON
from cyclonedx.output import get_instance, OutputFormat

outputter = get_instance(bom=bom, output_format=OutputFormat.JSON)
outputter.output_as_string()
Example as XML
from cyclonedx.output import get_instance, SchemaVersion

outputter = get_instance(bom=bom, schema_version=SchemaVersion.V1_2)
outputter.output_to_file(filename='/tmp/sbom-v1.2.xml')

Schema Support

This library is a work in progress and complete support for all parts of the CycloneDX schema will come in future releases.

Here is a summary of the parts of the schema supported by this library:

Note: We refer throughout using XPath, but the same is true for both XML and JSON output formats.

XPath Support v1.3 Support v1.2 Support v1.1 Support v1.0 Notes
/bom Y Y Y Y This is the root element and is supported with all it's defined attributes.
/bom/metadata Y Y N/A N/A Only timestamp is currently supported
/bom/components Y Y Y Y  
/bom/components/component
./author Y Y N/A N/A  
./name Y Y Y Y  
./version Y Y Y Y  
./purl Y Y Y Y  

Notes on Schema Support

  1. N/A is where the CycloneDX standard does not include this
  2. If the table above does not refer to an element, it is not currently supported

Python Support

We endeavour to support all functionality for all current actively supported Python versions. However, some features may not be possible/present in older Python versions due to their lack of support.

Changelog

See our CHANGELOG.

Copyright & License

CycloneDX Python Lib is Copyright (c) OWASP Foundation. All Rights Reserved.

Permission to modify and redistribute is granted under the terms of the Apache 2.0 license.

Comments
  • Can some of the runtime dependencies be loosened?

    Can some of the runtime dependencies be loosened?

    Thanks for this!

    I know poetry makes it easy lock every little thing down, and it makes testing easier, higher assurance, yadda yadda, but practically, it's quite inflexible when the effective ranges are very small... and on a self-declared lib to boot.

    Specifically, hooray for declaring a setuptools dependency: so many pkgutils-using packages forget to.

    However the size of the range covered by setuptools ^50.3.2 makes it relatively hard to appease (as in: exactly 1 version).

    Selfishly, this is blocking me downstream in packaging this and ultimately jake 1.x for conda-forge.

    The same goes for importlib_metadata which unfortunately gets pinned in a number of packages, and seems to change a lot for a backport package.

    Anyhow: would the maintainers be open to a PR that:

    • loosened the range of e.g. setuptools to be something more like >=50.3.2,<59
    • added a CI test excursion for the lowest and highest bound

    In the meantime, I may try patching the pin over on conda-forge and running the full test suite...

    enhancement dependencies 
    opened by bollwyvl 23
  • 2.5.0 regression: `SortedSet` assumes comparability of members, but `Vulnerability` model is not comparable

    2.5.0 regression: `SortedSet` assumes comparability of members, but `Vulnerability` model is not comparable

    Hi there! Thanks a ton for this library.

    We currently use it to generate SBOMs in pip-audit, and I noticed an interested regression upon upgrading to 2.5.0: it looks like Component.add_vulnerability attempts to add the underlying Vulnerability model to a SortedSet, which in turn fails because Vulnerability doesn't appear to implement the standard comparable operators (e.g. __lt__).

    Here's the failing code on our side, which worked in 2.4.0:

            for (dep, vulns) in result.items():
                if dep.is_skipped():
                    continue
                dep = cast(service.ResolvedDependency, dep)
    
                c = Component(name=dep.name, version=str(dep.version))
                for vuln in vulns:
                    c.add_vulnerability(
                        Vulnerability(
                            id=vuln.id,
                            description=vuln.description,
                            recommendation="Upgrade",
                        )
                    )
    
                self._components.append(c)
    

    and the failing CI tests on 2.5.0: https://github.com/trailofbits/pip-audit/runs/6832431942?check_suite_focus=true

    In my estimation, this looks like a bug/regression, rather than a SemVer breakage -- the Vulnerability model also comes from CycloneDX, so it probably should have been made comparable at the same time that comparability was assumed by introducing SortedSet.

    xref https://github.com/trailofbits/pip-audit/pull/292

    opened by woodruffw 17
  • [FEATURE] Support for version 1.4 schema

    [FEATURE] Support for version 1.4 schema

    Creating issue to track adoption of the forthcoming version 1.4 schema specification for CycloneDX.

    Preview work can be seen here, but this IS NOT FINAL.

    Current estimates are that version 1.4 will be finalised late 2021, early 2022.

    enhancement schema 1.4 
    opened by madpah 14
  • feat: use `SortedSet` in model to improve reproducibility

    feat: use `SortedSet` in model to improve reproducibility

    Added __lt__() to all model classes used in SortedSet, with tests Explicitly declared Enums as (str, Enum) to allow sorting Added dependency to sortedcollections package Added ComparableTuple to make sorting compound objects easier

    Signed-off-by: Rodney Richardson [email protected]

    opened by RodneyRichardson 11
  • [BUG] Nested Components or Services breaks BOM validation

    [BUG] Nested Components or Services breaks BOM validation

    The schema documents suggest that components can be nested inside other components (i.e. for/with hierarchical merging).

    Hoewever, if I try to generate such a bom an exception is raised in the validate method here: https://github.com/CycloneDX/cyclonedx-python-lib/blob/6e12be70fb2a71de60428155b4d0ae82fa43ef2d/cyclonedx/model/bom.py#L384 The reason for that is, because nested bom_refs underneath other components are not found by the implementation inside validate.

    Am I misunderstanding the schema or is this missing from the validation?

    bug 
    opened by peschuster 9
  • [FEATURE]  option to generate reproducible output

    [FEATURE] option to generate reproducible output

    I would like the tool to create exactly the same output if I run it on the same (Pipfile.lock) input file twice. This would make it easier to detect changes over time.

    There are several places where the outputs differ:

    1. The bom-ref is a GUID, newly generated on each run. This could be the purl (as cyclonedx-dotnet appears to do).
    2. The order of externalReferences is not maintained.
    3. The order of components/libraries is not maintained.
    enhancement 
    opened by RodneyRichardson 9
  • feat(deps): remove unused `typing-extensions` constraints

    feat(deps): remove unused `typing-extensions` constraints

    To be able to use new types, which will be introduced in Python 3.11, the package version shouldn't be pinned to 3.10.x and the package can be installed with any Python version, because you can't know, what the user will use. Here is the official explanation on version pinning

    Starting with version 4.0.0, typing_extensions uses Semantic Versioning. The major version is incremented for all backwards-incompatible changes. Therefore, it’s safe to depend on typing_extensions like this: typing_extensions >=x.y, <(x+1), where x.y is the first version that includes all features you need.

    opened by gruebel 9
  • fix: type hint for get_component_by_purl is incorrect

    fix: type hint for get_component_by_purl is incorrect

    Signed-off-by: gruebel [email protected]

    • adjusted the type hint for get_component_by_purl and added a test for it 🙂
    • changed the list/filter expression to use a list comprehension, which is almost 2x faster in this case 🚀
    bug 
    opened by gruebel 8
  • [FEATURE] SPDX License factory

    [FEATURE] SPDX License factory

    have a license factory, a thing that i feed a string and that returns the appropriate license model: expression, named license, spdx license.

    required for

    • https://github.com/CycloneDX/cyclonedx-python/discussions/377
    • https://github.com/CycloneDX/cyclonedx-python/issues/378

    as a contrast implementation of https://github.com/CycloneDX/cyclonedx-python/pull/410

    solution ala

    • https://github.com/CycloneDX/cyclonedx-javascript-library/blob/main/src/factories/license.ts
    • https://github.com/CycloneDX/cyclonedx-php-library/blob/master/src/Core/Factories/LicenseFactory.php
    enhancement 
    opened by jkowalleck 7
  • Documentation is failing to build and publish since #93 was merged

    Documentation is failing to build and publish since #93 was merged

    See https://github.com/CycloneDX/cyclonedx-python-lib/runs/4595932920?check_suite_focus=true.

    This appears to be the case since #93 was merged.

    FYI: @jkowalleck

    documentation CI 
    opened by madpah 7
  • feat: add option to assign a UUID in `BOM` constructor

    feat: add option to assign a UUID in `BOM` constructor

    Mainly the BOM receives a newly generated uuid assigned on the fly. This is basically a fix to enable passing an optional parameter within the constructor to be used as the uuid.

    enhancement 
    opened by hakandilek 6
  • chore(deps): bump Gr1N/setup-poetry from 7 to 8

    chore(deps): bump Gr1N/setup-poetry from 7 to 8

    Bumps Gr1N/setup-poetry from 7 to 8.

    Release notes

    Sourced from Gr1N/setup-poetry's releases.

    v8

    • Action updated to use Node 16
    • Support for Python 3.10 and 3.11
    • Breaking Change, removed support for Python 3.6
    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • feat: add support for python 3.11

    feat: add support for python 3.11

    the library supports python 3.11 in general.

    • [ ] add py 311 support to tox
    • [ ] add py 311 support to GH workflows
    • [ ] add py 311 support to trove classifiers
    documentation enhancement CI CT 
    opened by jkowalleck 0
  • chore(deps): bump relekang/python-semantic-release from 7.31.2 to 7.32.2

    chore(deps): bump relekang/python-semantic-release from 7.31.2 to 7.32.2

    Bumps relekang/python-semantic-release from 7.31.2 to 7.32.2.

    Release notes

    Sourced from relekang/python-semantic-release's releases.

    v7.32.2

    Fix

    • Fix changelog generation in tag-mode (#171) (482a62e)

    Documentation

    v7.32.1

    Fix

    • Corrections for deprecation warnings (#505) (d47afb6)

    Documentation

    v7.32.0

    Feature

    • Add setting for enforcing textual changelog sections (#502) (988437d)

    Documentation

    • Correct documented default behaviour for commit_version_number (#497) (ffae2dc)

    v7.31.4

    Fix

    • Account for trailing newlines in commit messages (#495) (111b151)

    v7.31.3

    Fix

    • Use commit_subject when searching for release commits (#488) (3849ed9)
    Changelog

    Sourced from relekang/python-semantic-release's changelog.

    v7.32.2 (2022-10-22)

    Fix

    • Fix changelog generation in tag-mode (#171) (482a62e)

    Documentation

    v7.32.1 (2022-10-07)

    Fix

    • Corrections for deprecation warnings (#505) (d47afb6)

    Documentation

    v7.32.0 (2022-09-25)

    Feature

    • Add setting for enforcing textual changelog sections (#502) (988437d)

    Documentation

    • Correct documented default behaviour for commit_version_number (#497) (ffae2dc)

    v7.31.4 (2022-08-23)

    Fix

    • Account for trailing newlines in commit messages (#495) (111b151)

    v7.31.3 (2022-08-22)

    Fix

    • Use commit_subject when searching for release commits (#488) (3849ed9)
    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • The resolves entries of a Patch object are not serialized to XML

    The resolves entries of a Patch object are not serialized to XML

    When a BOM is created that has Patch objects with a non empty resolves property, the Issues are ignored and do not appear in the output.

    The resolves property stored in a ReleaseNote object is already correctly serialized, so it is just a matter of some code reuse.

    See: https://github.com/CycloneDX/cyclonedx-python-lib/pull/312 for a patch and test.

    opened by schlenk 0
Releases(v3.1.1)
Owner
CycloneDX SBOM Standard
CycloneDX is a lightweight Software Bill of Materials (SBOM) standard, purpose-built for cybersecurity use cases. CycloneDX is a OWASP Flagship Project.
CycloneDX SBOM Standard
Mannaggia is a python application to praise or more likely to curse the saints

Mannaggia-py 👼 Remember Mannaggia? This is a Python remake of it, with new features. mannaggia is a python application to praise or more likely to cu

Christian Visintin 9 Aug 12, 2022
Restaurant-finder - Restaurant finder With Python

restaurant-finder APIs /restaurants query-params: a. filter: column based on whi

Kumar saurav 1 Feb 22, 2022
An educational platform for students

Watch N Learn About Watch N Learn is an educational platform for students. Watch N Learn incentivizes students to learn with fun activities and reward

Brian Law 3 May 04, 2022
An application to see if your Ethereum staking validator(s) are members of the current or next post-Altair sync committees.

eth_sync_committee.py Since the Altair upgrade, 512 validators are randomly chosen every 256 epochs (~27 hours) to form a sync committee. Validators i

4 Oct 27, 2022
Xoroshiro-cairo - A xoroshiro128** pseudorandom number generator implementation in Cairo

xoroshiro-cairo A xoroshiro128** pseudorandom number generator implementation in

Milan Cermak 26 Oct 05, 2022
Python API for HotBits random data generator

HotBits Python API Python API for HotBits random data generator. Description This project is random data generator. It uses is HotBits API web service

Filip Š 2 Sep 11, 2020
Addon for Blender 2.8+ that automatically creates NLA tracks for all animations. Useful for GLTF export.

PushDownAll An addon for Blender 2.8+ that runs Push Down on all animations, creating NLA tracks for each. This is useful if you have an object with m

Cory Petkovsek 16 Oct 06, 2022
Make pack up python files easier.

python-easy-pack make pack up python files easier. 目前只提供了中文环境 如何使用? 将index.py复制到你的项目文件夹,或者把.py文件拷贝到这个文件夹。 打开你的cmd或者powershell 切换到程序所在目录,输入python index

2 Dec 15, 2021
Standard mutable string (character array) implementation for Python.

chararray A standard mutable character array implementation for Python.

Tushar Sadhwani 3 Dec 18, 2021
8 Nov 04, 2022
Runtime inspection utilities for Python typing module

Typing Inspect The typing_inspect module defines experimental API for runtime inspection of types defined in the Python standard typing module. Works

Ivan Levkivskyi 284 Dec 29, 2022
Weblate is a copylefted libre software web-based continuous localization system

Weblate is a copylefted libre software web-based continuous localization system, used by over 2500 libre projects and companies in more than 165 count

Weblate 7 Dec 15, 2022
Checking-For-Fibonacci-Syquence-In-Python - Checking For Fibonacci Syquence In Python

Checking-For-Fibonacci-Syquence-In-Python The Fibonacci sequence is a set of num

John Michael Oliba 1 Feb 14, 2022
The little-endian version of MessagePack

MessagePackEL This is the little-endian version of MessagePack, except the endianness is different, the rest is exactly the same as MessagePack. C lib

dukelec 9 May 13, 2022
Install JetBrains Toolbox

ansible-role-jetbrains-toolbox Install JetBrains Toolbox Example Playbook This example is taken from molecule/default/converge.yml and is tested on ea

Antoine Mace 2 Feb 04, 2022
Sodium is a general purpose programming language which is instruction-oriented (a new programming concept that we are developing and devising) [Still developing...]

Sodium Programming Language Sodium is a general purpose programming language which is instruction-oriented (a new programming concept that we are deve

Instruction Oriented Programming 22 Jan 11, 2022
Fried Chicken Programming Language

Fried-Chicken Fried Chicken Programming Language How To Run Once downloaded and opened, choose any file for code. Any file extensions work. Just make

Attachment Studios 9 Jul 11, 2022
Automation of VASP DFT workflows with ASE - application scripts

This repo contains a library that aims at automatizing some Density Functional Theory (DFT) workflows in VASP by using the ASE toolkit.

Frank Niessen 5 Sep 06, 2022
Python Interactive Graphical System made during Computer Graphics classes (INE5420-2021.1)

PY-IGS - The PYthon Interactive Graphical System The PY-IGS Installation To install this software you will need these dependencies (with their thevelo

Enzo Coelho Albornoz 4 Dec 03, 2021
This repo holds custom callback plugin, so your Ansible could write everything in the PostgreSQL database.

English What is it? This is callback plugin that dumps most of the Ansible internal state to the external PostgreSQL database. What is this for? If yo

Sergey Pechenko 19 Oct 21, 2022