Package: licence
licenceIf you ever wanted to add a license file automatically or wanted to add a
license header to an automatically generated file, look no further, because
that is exactly what this module does. It allows you to select from the
preconfigured licenses and you can also add your own licenses.It does not need any external modules at all!Another advantage is, that it is easy to add new licenses: Just prepare the
license file and save it either in the default directory (seeLicense.paths)
or a directory of your own and tellLicenceto use it. No fiddling with
Python code!Homepagehttps://codeberg.org/sph/licence/https://pypi.org/project/licence/A word of warningWatch the British spelling of "licence" with regard to computer code
throughout! This avoids a name conflict with the built-in statementlicense.How to install?pip3installlicenceor to upgrade an existing installationpip3install--upgradelicenceHow to use?Import the module:>>>fromlicenceimportLicenceLoad the license:>>>lic=Licence('GPL-3.0')Render the license with default values:>>>t=lic.licence()>>># `t` now contains a string with the license text, which can be written>>># to a file, such as:>>>withopen('LICENSE','w')asf:...f.write(t)Render the header string to be included into each file:>>>t=lic.header()If the license does not support rendering aheader, anAttributeErrorwill
be thrown!If you want the header to be enclosed in triple quotations marks:>>>t=lic.header(prolog='"""',epilog='"""')or if you want to have it as a comment:>>>t=lic.header(comment="# ")How to find a license?Import the module:>>>fromlicenceimportLicenceFind the license:>>>lice=Licence.find(id='MIT')>>># `lice` now contains a list with licenses, whose ids are 'MIT' - since>>># ids is unique, there should be only one license>>>lice[<Licence('MIT')]Find all GNU licenses:>>>lice=Licence.find(pypi='License :: OSI Approved :: GNU')>>>lice[<Licence('GPL-2.0+')>,<Licence('GPL-2.0')>,<Licence('AGPL-3.0')>,...]Get all available licenses:>>>lice=Licence.find()Note, that after a license has been found, the license texts have to be loaded,
otherwise anAttributeErrorwill be thrown!>>>lice=Licence.find(id='MIT')>>>lice[<Licence('MIT')]>>>lic=lice[0]>>>t=lic.licence()AttributeError:'The MIT license'doesnotuse'licence'>>>lic.load()>>>t=lic.licence()TheLicence.find()class method takes keyword arguments and will filter the
available licenses based on these keywords, e.g. "id='MIT'" looks for all
licenses whose id is exactly 'MIT'. Other keywords are:id: Exact match
(seehttps://spdx.org/licenses/)name: Exact match
(seehttps://spdx.org/licenses/)pypi: Matches the start of the meta data value
(seehttps://pypi.org/classifiers/)rpm: Exact match
(seehttps://fedoraproject.org/wiki/Licensing:Main#SoftwareLicenses)url: Exact matchMultiple keywords are supported and they areANDed together.How to add a new license?All that is required is to add a license file to a location from the listLicence.paths!Start with a text file containing the license text. Then add the meta data at
the beginning of the file:# name: <full name of the license>
# rpm: <identifier used by rpm>
# pypi: <identifier used by PyPi>
# url: <link to the license>The<full name of the license>can be looked up athttps://spdx.org/licenses/The<identifier used by rpm>can be looked up athttps://fedoraproject.org/wiki/Licensing:Main#SoftwareLicensesThe<identifier used by PyPi>can be looked up athttps://pypi.org/classifiers/If the license asks for a header to be included into each source file, add a
header section:# header:
#    Copyright (C) yyyy  author name
# header: endIf the license asks to display some information for interactive programs, add
a interactive section:# interactive:
#     program  Copyright (C) yyyy  author name
# interactive: endNow replace the variable parts of the license with tokens starting with$.
These are replaced, when the text is rendered. Standard tokens are:$year: The year (or current year, if not given)$login: The author's login name (if not given, the login name of the
current user as provided by the operating system will be used).$author: The author's full name (if not given, the full name of the
current user as provided by the operating system will be used).$email: The author's email address (if not given, the email address of
the current user as provided by the operating system will be used - note,
that this is not available most of the time).$name_email: The string "name " (if not given, it will be
calculated from$authorand$email).Any other tokens can be used as well, but they do not have a default value.Now look back tohttps://spdx.org/licenses/and make a note of the identifier.
This will be the file name and the internal 'id' of the license. So save the
file under the identifier with a suffix of '.txt' in any location mentioned in
theLicence.paths(see next section).Please also consider to make it available athttps://codeberg.org/sph/licence,
either by making apull requestwith the new license file or open anew issueand attach the new
license file.How to have your own repository of license files?The license files are stored in any location mentioned in theLicence.paths.
The standard paths, such as the user and site data directories as well as this
module's path, are implemented in the module, but the list can be modified, if
the nees should arise:Add a new path at the beginning of the list:>>>Licence.add_path('~/licenses')Remove a path:>>>Licence.del_path('~/licenses')Show all paths:>>>Licence.pathsClear the list of paths - it will be empty afterwards:>>>Licence.clear_paths()Reset the list of paths to its default values:>>>Licence.reset_paths()Note, that it is possible to modifyLicence.pathsdirectly (but you have to
usepathlib.Pathobjects!), but the above mentioned methods take care of
that and also make some sanity checks, so they are preferred.Alternativeslicense: The original license module,
but the author lost interest and does not want to hand over the project. BTW
that project names clashes with the Python built-inlicensestatement.licenraptor: Based on the originallicensewith one (Chinese) license
added.Command line utilities:choosealicense-clilicenserlicenlicegarnishAPIClassLicence(id, meta_only=False)This class reads the license file and renders the license texts. It also makes
the meta data accessible. In addition it provides some useful class methods,
which can be called without initiating a class object.InitializationParametersid(str):
TheSPDXidentifier of the license (this is
the name of the license file).meta_only(bool, optional):
IfTrue, return only the meta data, but no template or multi-line meta
data (multi-line data is replaced with their boolean value).
The default isFalse.ExceptionsAValueErroris raised, if the license file<id>.txtdoes not exist in any
of the directories specified inLicence.paths.AKeyErroris raised, if the license file states a key twice (or uses any of
the reserved keys 'file' or 'id').Meta dataThe class behaves like a dictionary, albeit a read-only one, so that the meta
data can be accessed with their key, e.g.>>>l=Licence('MIT')>>>l['name']returns the full name (thenamemeta data) of the MIT license.Basically every key given in the license file is accessed in that manner; the
main keys are:id: TheSPDXidentifier of the license (not
read from the license file)file: The file path to the license file (not read from the license file)name: The fullSPDXname of the licenserpm: The identifier used byRPMpypi: The identifier used byPyPiurl: The link to the licenseSome licenses specify aheaderand even aninteractivetext. These are used
to be included into the every file of the project or as message for interactive
programs, respectively. They are accessed with theheaderandinteractivekeys (and return a list of strings, were each string is one line of the text).The license text itself is accessible with thelicencekey (and again is a
list of strings, where each string is one line of the license text).Method `load(meta_only=False)Loads the contents of the file stored in the 'file' key. This can be used to
reload the contents of the file, e.g. to read in the contents of the templates,
if the class was initialized withmeta_only=True(which is done when finding
licenses).Themeta_onlykeyword parameter, has the same meaning as during the
initialization of the class.Static methodtext(template, prolog=None, comment=None, epilog=None, **kwargs)Generate any license string, encapsulating it betweenprologandepilogand
prependingcommentin front of every line.Thekwargsare used to substitute the placeholders with the same name in the
template.Since this is a static method, it can theoretically be used without loading the
license file first.Parameterstemplate(list):
The list with the lines of the template text.prolog(str|None, optional): A string to be put before the header, e.g. "/*" for C. IfNone, no prolog is added, if the empty string "", an empty line is added. The default isNone`.comment(str|None):
A string to be put in front of each header line, e.g. " * " for C (or "# "
for Python). IfNone, nothing is added before the line.
The default isNone.epilog(str|None):
A string to be put after the header, e.g. " */" for C. IfNone, no epilog
is added, if the empty string "", an empty line is added.
The default isNone.**kwargs:
Keyword arguments with replacements for tokens in the license file.
The most important keys are:year(optional):
The year to be put into the copyright line.
The default is the current year.login(optional):
The author`s login name. The default is extracted from information
provided by the operating system.author(optional):
The author`s full name to be put into the copyright line.
The default is extracted from information provided by the
operating system.email(optional):
The author's email address to be put into the copyright line. Mainly
used to calculate thename_emailkey: If empty, no email address is
inserted into thename_emailkey.
The default is extracted from information provided by the operating
system (which most of the time is an empty string!)name_email(optional):
The author's full name and the email address to be put into the
copyright line.
The default is calculated from theauthorandemailkeys:
"author " (if theemailkey is empty, no email is added andname_emailsimply becomes "author").Class methodfind(**kwargs)Looks for licenses using the given criteria. It uses the meta data and returns
a list with all licenses matching the criteria.The keyword arguments are the criteria used to filter the available licenses,
e.g.id='MIT'looks for all licenses whose id is exactly 'MIT' (there should
be only one license in the list, because theidshould be unique). The main
keywords are (see also the section about the meta data above):id(exact match):
Seehttps://spdx.org/licenses/for standard identifiers.name(exact match):
Seehttps://spdx.org/licenses/for standard names.pypi(matches the start of the meta data value):
Seehttps://pypi.org/classifiers/for valid identifiers.rpm(exact match):
Seehttps://fedoraproject.org/wiki/Licensing:Main#SoftwareLicensesfor valid
names.url(exact match)header(boolean)
Filter if the license asks for a header to be included into each source file.interactive(boolean)
Filter if the license asks to display some information for interactive
programs.Multiple keywords are supported and they areANDed together.Note that a license found that way does not contain the license texts yet. These
need to be loaded withload()!Class methodslicence(),header(),interactive(), …If some data should be rendered into a license text, call that meta data with
the same arguments as thetext()method, but without thetemplateparameter, which will be gotten from the meta data, e.g.licence()will
render the meta datalicence,header(comment='# ')will render the meta
dataheaderand adds a '# ' in front of each line.pathsmanipulationClass attributepathsThe class attributeLicence.pathscontains the list ofpathlib.Paths for
each directory, where license files are stored. It already contains the path
to the licenses supplied with the module.This class attribute can be accessed without initiating theLicenceclass!The list of paths can be manipulated with the help of the.…_path()class
methods (see below). Any subsequent calls ofLicence()will then use this
modified list of paths to look for a license file.Class methodadd_path(path)Add the new directorypaththe list of paths at its end. Thepathcan
either be a string or apathlib.Path. The special character~will be
expanded with the user's home directory. It checks, if the path is an
existing directory and if it is not already in the list.RaisesFileNotFoundError, if thepathdoes not exists.Class methoddel_path(path)Deletes the directorypathfrom the list of paths. Thepathcan either be
a string or apathlib.Path. The special character~will be expanded with
the user's home directory.RaisesAttributeError, if thepathis not in the list of paths.Class methodclear_path(path)Clears the list of paths and set it to the empty list.Helper functionsFunctionget_year()Returns the current year.Functionget_login()Returns the login name for the current user.Functionget_fullname()Returns the full user name from the information provided by the operating
system.Functionget_email()Returns the email address from the information provided by the operating
system.DecoratorclasspropertyMakes a class property attribute and can be used very similar to the@propertydecorator.CLIThe file can be called from the command line:python3idlicence|header|...**kwargswhereidis the license identifier (as in the class initialization),licence|header|...the part of the license to be rendered and the keyword
arguments**kwargsthe same as for thetext()method (without thetemplateparameter).