Skip to main content

CaLi

Build Status PyPI version

A python package that defines a partial order over RDF licenses

Introduction

CaLi is a lattice-based model for license orderings. This repository contains a python package that implements this model.

Code uses the ODRL CaLi ordering ⟨A, LS, CL, C→⟩ such that:

  • A is the set of 72 actions of ODRL (e.g., cc:Distribution, cc:ShareAlike, etc.),
  • LS is the restrictiveness lattice of status Undefined <= Permissions <= Duty <= Prohibition (actions can be either permitted, obliged, prohibited or not specified; in this LS, the undefined status is the least restrictive and the prohibited one the most restrictive),
  • CL and
  • C→ are sets of constraints.

CaLi online demonstrator Is an exemple of license compliant search engine using CaLi model.

Installation

Installation in a virtualenv is recommended.

Assuming you already have python 3 and pip installed

pip install pycali

this will automatically install rdflib used to manipulate RDF.

Getting started

This section shows how to create a CaLi ordering with ease.

Load a vocabulary

A vocabulary object is a set of URIs (rdflib.term.URIRef) identifying actions (e.g., cc:Distribution, cc:ShareAlike, odrl:play, etc.)

Create your own vocabulary inheriting from Vocabulary object or use the implemented ODRL Vocabulary:

from pycali.vocabulary import ODRLVocabulary

odrl = ODRLVocabulary()
# access the list of actions
odrl.actions

Load a Restrictiveness lattice of status (LS)

LS is a lattice defining the restrictiveness order between statuses of the actions (permitted, obliged, prohibited). Repository contains examples of LS in RDF. A Restrictiveness lattice of status is instantiated using a LS in RDF (rdflib.Graph):

from rdflib import Graph
from pycali.restrictiveness_lattice_of_status import RestrictivenessLatticeOfStatus
from pycali.examples.restrictiveness_lattice_of_status.DL1 import dl1_rdf

# Load the LS in the examples
DL1 = RestrictivenessLatticeOfStatus(Graph().parse(data=dl1_rdf, format='ttl'))

Note that you can parse your own file using location parameter

Load licenses

A license i a set of statuses associated to actions of the vocabulary. You can define your own license by creating a class inheriting from License object or use the implemented ODRLLicense object. Repository contains examples of ODRL licenses dataset.

Load a dataset of licenses

ODRLLicenses object is able to generate a set of ODRLlicense object from a rdf dataset of licenses described using ODRL Vocabulary:

from rdflib import Graph
from pycali.license import ODRLLicenses
from pycali.examples.licenses.ld_licenses_odrl import ld_licenses_rdf

ld_licenses_graph = Graph().parse(data=ld_licenses_rdf,
                                  format='ttl')
licenses = ODRLLicenses(vocabulary=odrl,
                        ls=DL1,
                        rdf_graph=ld_licenses_graph)

Note that you can parse your own file using location parameter

Load a specific license

IRI of the license can be used to retrieve a specific license:

from pycali.license import ODRLLicense
from rdflib import Graph, URIRef
from pycali.vocabulary import ODRL
from pycali.ontologies.cali_onto import Permission
from pycali.examples.licenses.ld_licenses_odrl import ld_licenses_rdf

MIT = URIRef('http://cali.priloo.univ-nantes.fr/api/ld/licenses/65927752496731336041529177465061342556133156838395276')

ld_licenses_graph = Graph().parse(data=ld_licenses_rdf,
                                  format='ttl')
mit_license = ODRLLicense(vocabulary=odrl,
                      ls=DL1,
                      rdf_graph=ld_licenses_graph,
                      iri=MIT)
# Returns a list of actions in the specified state
actions = mit_license.get_action(vocabulary=odrl, status=Permission)
# Returns the state of an action
state = mit_license.get_status(vocabulary=odrl, action=ODRL['derive'])

Define constraints

Constraints on license CL defines if a license is valid or not. Compatibility constraints C→ defines if a restrictiveness relation is a compatibility relation or not. Repository contains examples of license and compatibility constraints.

Constraints on licenses

A constraints on license is a a python function that takes 2 parameters, a vocabulary and a license and returns a boolean:

from pycali.ontologies.cali_onto import Duty
from pycali.vocabulary import CC

# A License should not obligates the commercial use of a resource
def CommercialUse_Not_Duty(vocabulary, license):
    return license.get_status(vocabulary, CC['CommericalUse']) != Duty

Compatibility constraints

A compatibility constraint is a a python function that takes 3 parameters, a vocabulary and 2 licenses and returns a boolean:

from pycali.ontologies.cali_onto import Duty
from pycali.vocabulary import CC

# A license that obligates to share alike should not be compatible with another license
def ShareAlike_Compatibility(vocabulary, license1, license2):
    return license1.get_status(vocabulary, CC['ShareAlike']) != Duty

Instantiate constraints

Constraints are instantiated using LicenseConstraints and CompatibilityConstraints objects. They are initiated with a list of constraints (signature of functions (constraints) are tested during initialization).

from pycali.constraints import LicenseConstraints, CompatibilityConstraints
from pycali.examples.license_constraints import CommercialUse_Not_Duty, ShareAlike_Not_Prohibition, CommercialUse_Include_Use
from pycali.examples.compatibility_constraints import ShareAlike_Compatibility, DerivativeWorks_Compatibility

license_constraints = LicenseConstraints(odrl, [CommercialUse_Not_Duty, ShareAlike_Not_Prohibition, CommercialUse_Include_Use])
compatibility_constraints = CompatibilityConstraints(ODRL, [ShareAlike_Compatibility, DerivativeWorks_Compatibility])

# Checks if license respects all constraints on license
license_constraints.is_valid(license)
# Checks if the restrictiveness relation between license1 and license2 repects all compatibility relations
compatibility_constraints.is_compatible(license1, license2)

Instanciate a CaLi Ordering (Complete Example)

CaLi ordering automatically defines compatibility relations between licenses. It takes 4 parameters, the restrictiveness lattice of status (LS), the vocabulary, licenses constraints and compatibility constraints. Then, every license added in the cali_ordering is ordered among other using compatibility relation.

from rdflib import Graph
from pycali.cali_ordering import CaliOrdering
from pycali.restrictiveness_lattice_of_status import RestrictivenessLatticeOfStatus
from pycali.license import ODRLLicenses
from pycali.vocabulary import ODRLVocabulary
from pycali.constraints import LicenseConstraints, CompatibilityConstraints
from pycali.examples.license_constraints import CommercialUse_Not_Duty, ShareAlike_Not_Prohibition, CommercialUse_Include_Use
from pycali.examples.compatibility_constraints import ShareAlike_Compatibility, DerivativeWorks_Compatibility
from pycali.examples.restrictiveness_lattice_of_status.DL1 import dl1_rdf
from pycali.examples.licenses.ld_licenses_odrl import ld_licenses_rdf

# instantiate a cali ordering
odrl = ODRLVocabulary()
DL1 = RestrictivenessLatticeOfStatus(Graph().parse(data=dl1_rdf, format='ttl'))
cali_ordering = CaliOrdering(ls=DL1,
                             vocabulary=odrl,
                             license_constraints=LicenseConstraints(odrl, [CommercialUse_Not_Duty, ShareAlike_Not_Prohibition, CommercialUse_Include_Use]),
                             compatibility_constraints=CompatibilityConstraints(odrl, [ShareAlike_Compatibility, DerivativeWorks_Compatibility]))
# add licenses to order
ld_licenses_graph = Graph().parse(data=ld_licenses_rdf, format='ttl')
licenses = ODRLLicenses(vocabulary=odrl, ls=DL1, rdf_graph=ld_licenses_graph)
# use cali_ordering.add_license(license) to add one license
cali_ordering.add_licenses(licenses)

Browse the CaLi Ordering

# checks if license1 is compatible with license2
boolean = cali_ordering.is_compatible(license1, license2)
# checks if license2 is compatible with license1
boolean = cali_ordering.is_compliant(license1, license2)
# Returns all licenses that are compatible with license entered in parameter
licenses = cali_ordering.all_compatible(license)
# Returns all licenses that are compliant with license entered in parameter
licenses = cali_ordering.all_compliant(license)
# Returns an RDF graph containing license IRI's and compatibility relations
rdf_graph = cali_ordering.get_rdf_graph()
# serialize rdf graph in turtle
turtle_string = rdf_graph.serialize(format='turtle')

Metadata

Release files for pycali 3.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pycali 3.0.0
File Size Uploaded Provenance Actions
pycali-3.0.0.tar.gz 37.5 kB Without provenance Details for pycali-3.0.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pycali 3.0.0
File Interpreter ABI Platform Actions
pycali-3.0.0-py2-none-any.whl Python 2 none any Details for pycali-3.0.0-py2-none-any.whl

Total release size: 81.3 kB

Release files / pycali-3.0.0.tar.gz

Download URL pycali-3.0.0.tar.gz
Size 37.5 kB
Tags Source
SHA-256 checksum
How to use checksums
18d77af001c058d935e59d15b87df887453d05f71235ba78afaedbf9a17ba7c0
BLAKE2b-256 checksum
How to use checksums
be80234fcadc571181a1954b8f0a08947f17b98175cd80ca6b762723f6a73c8c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/40.6.2 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/3.7.2

Release files / pycali-3.0.0-py2-none-any.whl

Download URL pycali-3.0.0-py2-none-any.whl
Size 43.8 kB
Tags Python 2
SHA-256 checksum
How to use checksums
58050155a928a3e422575d86436ac55290130a7dc6162f84b0ea182539954d3e
BLAKE2b-256 checksum
How to use checksums
00dd4cbd63bc8c7e3546cc8e8d97faad0d83eb0fea3e6a6039333040dd72e627
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/40.6.2 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/3.7.2

Security for pycali 3.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page