Skip to main content

label-builder-service

label-builder-service integrates with telicent-label-builder to allow wrapping a model in a rest-api default endpoint is /api/v1/ingest which would convert a model to a label

Installation

pip install telicent-label-builder-service

Configuration

The application could only be configured through environment variables. When used in conjunction with telicent-label-builder there is no way to pass a configuration to rest_serivice.py->run_api_service

Configuration lives under telicent-lbapi/api_config/config.py and can be used for reference.

Supported env variables:

LOGGING_LEVEL - sets the log level for the REST Application - Default: INFO

CACHE_TIMEOUT - sets cache expiry time in seconds - Default: 5min

RESTAPI_PORT - the port to run the server on - Default: 8000

RESTAPI_HOST - the adress to run the server on - Default: 0.0.0.0

LOG_TO_CONSOLE - propagates logs to STDOUT - Default: true

LOGING_DIR - logfile storage directory, path will be created, ensure path is writable

Default: UNIX systems - /tmp/logs Windows - <TEMP>/logs

LOG_FILENAME - filename to use for the log file - Default: label-builder-service.log


Detail

Each request would be given a unique ID which is propagated in logs, the format is as follows:

"%(asctime)s [%(levelname)s] [%(name)s:%(funcName)s:%(lineno)d]" 
" [Request ID: %(request_id)s]"
" [Model Class: %(model_class)s] - %(message)s"

RequestID is preserved across the lifecycle of the request. The library supports additional endpoints definitions, see USAGE below. There is a concept of model_class, this is usually the model that was implemented using the label builder. Any endpoints which do data validation would try and use that model unless specified otherwise by the "@set_model_class" decorator. When the decorator is used a middleware, will revert the model back to the original one for this instance of the application.

e.g in the usage case below a call to /custom-endpoint-failing would use MyModel internally, after response is issued the model will be set back to TelicentModel.

The API provides a single endpoint /api/v1/ingest - it tries to convert a model instance to security labels, model in use must implement build_security_labels method, otherwise the endpoint would fail.

In cases where no additional endpoints are required, a function to run the model as a service utilising the /ingest endpoint could be achieved by wrapping run_api_service in a class method within the model itself.

All endpoints including customer defined ones are available under docs or redoc endpoint, default: http://localhost:8000/docs or http://localhost:8000/redoc

E.g:

from telicent_lbapi.rest_service import run_api_service

class MyModel(TelicentMixin):
    testSth: str | None = "sth"
    identifier: str
    classification: str
    orGroups: list[str]
    andGroups: list[str]
    permittedOrgs: list[str]
    permittedNats: list[str]

    def additional_method(self):
        print("Custom functionality here")

    def build_security_labels(self):
        return {"labels": "custom"}
    
    @classmethod
    def run_as_api(cls):
        run_api_service(cls)
    

Usage

from fastapi import APIRouter, Request, HTTPException
from telicent_lbapi.context import ModelContext
from telicent_labels.telicent_model import TelicentMixin
from telicent_lbapi.services.label_builder_service import build_security_labels
from telicent_lbapi.decorators import set_model_class
from pydantic import BaseModel, ValidationError


class MyModel(TelicentMixin):
    testSth: str | None = "sth"
    identifier: str
    classification: str
    orGroups: list[str]
    andGroups: list[str]
    permittedOrgs: list[str]
    permittedNats: list[str]

    def additional_method(self):
        print("Custom functionality here")

    def build_security_labels(self):
        return {"labels": "custom"}


class AnotherModel:
    def additional_method(self):
        print("Another custom functionality here")

    def build_security_labels(self):
        return {"labels": "another_custom"}


custom_router = APIRouter()


@custom_router.get("/custom-endpoint-failing")
@set_model_class(MyModel)
async def custom_endpoint_mymodel(request: Request):
    test_policy = {
        "testSth": "a",
        "classification": "b",
        "permittedOrgs": [
            "ABC",
        ],
        "permittedNats": [
            "GBR",
        ],
        "orGroups": [
            "Apple",
        ],
        "andGroups": [
            "doctor",
        ],
        "originator": "TestOriginator",
        "custodian": "TestCustodian",
        "policyRef": "TestPolicyRef"
    }
    try:
        labels = build_security_labels(data_header=test_policy)
    except ValidationError as e:
        raise HTTPException(status_code=400, detail=str(e)) from e

    return {"message": f"This is a custom endpoint using {MyModel.__name__}", "labels": labels}


@custom_router.get("/custom-endpoint-mymodel")
@set_model_class(MyModel)
async def custom_endpoint_mymodel(request: Request):
    test_policy = {
        "testSth": "a",
        "identifier": "sth",
        "classification": "b",
        "permittedOrgs": [
            "ABC",
        ],
        "permittedNats": [
            "GBR",
        ],
        "orGroups": [
            "Apple",
        ],
        "andGroups": [
            "doctor",
        ],
        "originator": "TestOriginator",
        "custodian": "TestCustodian",
        "policyRef": "TestPolicyRef"
    }
    try:
        labels = build_security_labels(data_header=test_policy)
    except ValidationError as e:
        raise HTTPException(status_code=400, detail=str(e)) from e

    return {"message": f"This is a custom endpoint using {MyModel.__name__}", "labels": labels}


@custom_router.get("/custom-endpoint-anothermodel")
@set_model_class(AnotherModel)
async def custom_endpoint_anothermodel(request: Request):
    return {"message": f"This is a custom endpoint using {ModelContext.get_model_class()}"}


if __name__ == "__main__":
    from telicent_labels import TelicentModel
    from telicent_lbapi.rest_service import run_api_service

    # TelicentModel used here just to illustrate the ability to switch models, the api is model driven.
    run_api_service(model_class=TelicentModel, custom_router=custom_router)

Metadata

Release files for telicent-label-builder-service 0.1.5

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

Source distribution (sdist)

Source distribution for telicent-label-builder-service 0.1.5
File Size Uploaded Provenance Actions
telicent_label_builder_service-0.1.5.tar.gz 23.0 kB Without provenance Details for telicent_label_builder_service-0.1.5.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for telicent-label-builder-service 0.1.5
File Interpreter ABI Platform Actions
telicent_label_builder_service-0.1.5-py2.py3-none-any.whl Python 3, Python 2 none any Details for telicent_label_builder_service-0.1.5-py2.py3-none-any.whl

Total release size: 52.9 kB

Release files / telicent_label_builder_service-0.1.5.tar.gz

Download URL telicent_label_builder_service-0.1.5.tar.gz
Size 23.0 kB
Tags Source
SHA-256 checksum
How to use checksums
2812dfd764a9a40ab14045a46d7b01a1f79572cc64404ef18b45667a1e2edf84
BLAKE2b-256 checksum
How to use checksums
b8d85363c4526511f1f9b616a3f078121e9932f72eac0ae0958b220d5a7334f8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/5.1.1 CPython/3.12.7

Release files / telicent_label_builder_service-0.1.5-py2.py3-none-any.whl

Download URL telicent_label_builder_service-0.1.5-py2.py3-none-any.whl
Size 29.9 kB
Tags Python 2 Python 3
SHA-256 checksum
How to use checksums
a8882527de51e39095f343f9ec33ee3e3b1b88cc5eade5a4b803d64c0b4e6012
BLAKE2b-256 checksum
How to use checksums
cf312d6b3c7e033948a8acf8e554f0ecfd21f426c13231c5db042e40eeffff7b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/5.1.1 CPython/3.12.7

Security for telicent-label-builder-service 0.1.5

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