Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

libciss

Python client for CISS applications. Currently supports CISS Control, with helpers for authentication and pré-carga / separação (warehouse pre-load picking).

Status: 0.1.0a3 (alpha) — the API surface may change.

Requirements

  • Python 3.10+ (uses X | None type syntax and dataclass(slots=True))
  • requests>=2.31.0

Installation

pip install libciss

Everything is imported from the single top-level libciss package:

from libciss import CISSClient

Upgrading from 0.1.0a1: that release was unusable — it shipped its modules under a top-level services package (which collided with any application that had its own services/), left client and exceptions out of the distribution entirely, and imported from a src package that was never packaged. 0.1.0a2 moves everything under libciss, so from src import ... becomes from libciss import ....

Quick start

from datetime import datetime

from libciss import CISSClient
from libciss.services.cisscontrol.models import PreCargaSeparacaoSubmission

client = CISSClient("https://your-ciss-host.example.com")

# Authenticate — stores the bearer token on the shared session
user = client.cisscontrol.auth.login("username", "password")
print(user.id_empresa, user.razao_social)

# List pre-loads
preloads = client.cisscontrol.precarga_separacao.get_all(
    id_empresa=user.id_empresa,
    num_dias_sync=30,
)

# Fetch the line items of one pre-load
items = client.cisscontrol.precarga_separacao.items(
    id_empresa=user.id_empresa,
    id_precarga=preloads[0].id_pre_carga,
    id_usuario=user.id_user,
)

# Report a separated item back to CISS
item = items[0]
submission = PreCargaSeparacaoSubmission(
    id_usuario=user.id_user,
    id_empresa=item.id_empresa,
    id_documento=item.id_documento,
    id_pre_carga=item.id_pre_carga,
    id_produto=item.id_produto,
    id_subproduto=item.id_subproduto,
    id_local_retirada=item.id_local_retirada,
    ds_local_retirada=item.ds_local_retirada,
    num_sequencia=item.num_sequencia,
    qtd_produto=item.qtd_produto,
    fg_separado="S",
    qtd_contada=item.qtd_produto,
    dt_hr_inicio=datetime.now(),
)

response = client.cisscontrol.precarga_separacao.submit([submission])

client.cisscontrol.auth.logout()

Architecture

One CISSClient owns a single requests.Session. Services never hold their own transport — they call back into client.request(...), so the token set at login is automatically applied to every later call.

CISSClient(base_url)
├── session          # requests.Session (shared headers / cookies)
├── request(...)     # low-level HTTP helper, raises on 4xx/5xx
└── cisscontrol      # CISSControl
      ├── auth                 # AuthenticationService
      │     ├── login / logout
      │     ├── token / authenticated
      │     └── user → LoginResponse | None
      ├── pre_carga            # PreCargaService — conferência
      │     ├── get_all(...)    → list[PreCarga]
      │     ├── submit(...)     → requests.Response
      │     └── set_status(...) → requests.Response
      └── precarga_separacao   # PreCargaSeparacaoService — separação
            ├── get_all(...)  → list[PreCargaSeparacao]
            ├── items(...)    → list[PreCargaSeparacaoItem]
            └── submit(...)   → requests.Response

pre_carga and precarga_separacao are different CISS modules, not two views of one. pre_carga covers conferência — checking a picked order against its invoice. precarga_separacao covers separação — the warehouse picking itself. Their payloads share almost no fields.

How conferência works

Conferência is the checking step: a conferente walks a pré-carga that has already been picked, counts what is physically there, and reports the counted quantities back so the order can be released.

Everything in this section is derived from one real session captured in conferencia/ — the Flutter app (Dart/3.9) talking to a CISS backend on versao-backend: 8.14.2. Where the capture does not settle a question, this says so rather than guessing.

The flow

1. get_all(id_empresa, id_conferente)
   └── the pré-cargas assigned to this conferente        → list[PreCarga]

2. ...the conferente counts the physical items...
   └── the item list does NOT come from this module — see below

3. submit(pre_carga, itens)
   └── the header + every counted line, in one request   → 201 + persisted items

4. set_status(id_precarga, status_code, id_usuario_conferente)
   └── closes / moves the pré-carga                      → 200 + echo of the request

5. get_all(...) again
   └── refreshed queue

Steps 3 and 4 are two separate requests. Submitting the items does not change the status, and the library does not chain them for you — a crash between the two leaves the items recorded and the status untouched.

Step by step

# Call Sends Gets back
1 get_all idEmpresa, numDiasSync, dsPreCarga, dsPontoRetirada, idConferente as query keys Array of headers, each with clientes[] and cliForList[]
3 submit {"preCargaList": [header], "itens": [...]} 201 + the persisted lines, minus idLote / corredor / gondola / prateleira
4 set_status {"idPreCarga", "statusCode", "idUsuarioConferente"} 200 + the same three fields echoed verbatim

Where the items come from

This module has no endpoint that returns the lines of a pré-carga. get_all returns headers only, and the capture shows the app already holding a complete itens array when it POSTs. Whatever produced that array was not part of the captured traffic.

So a caller of pre_carga.submit() must source the lines themselves. Note that precarga_separacao.items() is not a drop-in substitute: it is keyed on idDocumento / numSequencia and returns fgSeparado, while conferência lines are keyed on the sale and carry qtdContada. Resolving this is an open question, not a solved one.

How a line is identified

A conferência line is identified by the sale it came from, not by the product:

idEmpresaVenda + idPlanilhaVenda + numSequenciaVenda

The capture proves this matters — idProduto 134640 appears twice in the same pré-carga, once under idPlanilhaVenda 21675444 and once under 21689087, with different quantities (90.0 and 30.0). Deduplicating by product would silently merge two legitimate lines.

Quantities

qtdProduto is what the system expects; qtdContada is what the conferente actually counted. Nothing is validated client-side, and a divergence is resolved server-side.

Worth knowing: in the captured session all seven lines matched exactly (2/2, 5/5, 1/1, 5/5, 90/90, 30/30, 30/30). A divergent count was never observed, so how the backend reacts to one is untested here.

Statuses

This is the part the capture does not settle. What it shows, literally:

Where Field Value
Header sent in preCargaList idStatus 1
Header sent in preCargaList idConferente null
set_status body statusCode 0
A different pré-carga in the later listing idStatus 0
That same pré-carga idConferente 617

Only statusCode: 0 was ever sent, so the set of valid codes and their meanings is unknown. idStatus and statusCode are also not demonstrably the same scale — they are different field names in different payloads, and nothing in the capture links them. The library therefore passes status codes through untouched and neither validates nor enumerates them.

Open questions

Genuinely unresolved — do not treat any of these as documented behaviour.

Question Why it is open
What do the statusCode values mean? Only 0 was ever sent
Are idStatus and statusCode the same scale? Different fields, different payloads, no observed link
Where does the itens array come from? No captured request produces it
Does submitting remove a pré-carga from the queue? The submitted 43797 is absent from the later listing — but that listing filtered on idConferente=617 and the submitted header carried idConferente: null, so the filter alone explains it
Does preCargaList accept more than one header? Only ever sent with one
Is submit idempotent? Never sent twice
Is idPedidoPreCarga ever non-null? Only observed as null

API reference

CISSClient

Entry point for all services.

CISSClient(base_url: str)
Attribute / method Description
base_url API root URL; a trailing / is stripped
session Shared requests.Session — holds the Authorization header after login
cisscontrol CISSControl service namespace
request(method, endpoint, **kwargs) Sends method to base_url + endpoint, calls raise_for_status(), returns the Response

endpoint is concatenated onto base_url verbatim, so it must start with /. Any extra keyword argument is forwarded to requests.Session.request (json=, params=, timeout=, …).

Session-level configuration goes on client.session:

client.session.verify = "/path/to/ca-bundle.pem"
client.session.proxies = {"https": "http://proxy.internal:3128"}

Every request is bounded by a default (connect, read) timeout of (5.0, 30.0) seconds, exposed as libciss.client.DEFAULT_TIMEOUT. The read half is short deliberately: CISS Control tends to stall rather than answer when a company has no pre-load.

Change it per client, or per call:

client = CISSClient("https://ciss.example.com", timeout=(5, 60))
client.timeout = None                     # wait forever
client.request("GET", "/ciss-control/precarga_separacao", timeout=10)  # this call only

A request that exceeds it raises requests.Timeout. Note that setting client.session.timeout does not work — requests.Session has no such attribute; use the constructor argument above.


Authentication — client.cisscontrol.auth

login(username, password) -> LoginResponse

POST /ciss-control/login

Sends {"username": ..., "password": ...} as JSON. On success it writes the returned tokenBearer into session.headers["Authorization"] and caches the parsed payload on auth.user.

The token is stored exactly as the API returns it — the library does not prepend a Bearer prefix. razao_social is right-stripped of trailing whitespace; all other fields are passed through unchanged.

logout() -> None

Removes the Authorization header and clears auth.user. Client-side only — no request is sent, so the token stays valid server-side until it expires.

Properties

Property Type Description
token str | None Current Authorization header value, or None
authenticated bool True when a token is set
user LoginResponse | None Payload of the last successful login

authenticated only reports whether a token is present — it does not validate or check expiry. An expired token still reads as True, and the call then fails with requests.HTTPError (401).

requires_login decorator

libciss.services.cisscontrol.auth.requires_login guards service methods. It reads self.client.cisscontrol.auth.authenticated and raises NotAuthenticatedError when no token is set, so it can only decorate methods of a service that holds a client attribute.

from libciss.services.cisscontrol.auth import requires_login

class MyService:
    def __init__(self, client):
        self.client = client

    @requires_login
    def do_something(self):
        return self.client.request("GET", "/ciss-control/something")

Conferência — client.cisscontrol.pre_carga

Every method is decorated with @requires_login and raises NotAuthenticatedError when called before login().

The flow is: get_all to find the pré-carga, submit to send the counted items, set_status to close it.

from libciss.services.cisscontrol.models import PreCargaItem

user = client.cisscontrol.auth.login("username", "password")

pre_cargas = client.cisscontrol.pre_carga.get_all(
    id_empresa=user.id_empresa,
    id_conferente=user.id_user,
)

pre_carga = pre_cargas[0]
item = PreCargaItem(
    id_usuario=user.id_user,
    id_empresa=pre_carga.id_empresa,
    id_pre_carga=pre_carga.id_pre_carga,
    id_empresa_venda=1,
    id_planilha_venda=21675444,
    num_sequencia_venda=4,
    id_produto=21089,
    id_subproduto=21089,
    qtd_produto=2.0,
    qtd_contada=2.0,
    ds_local_retirada="01 - KENIO TRIUNFO MATRIZ",
)

client.cisscontrol.pre_carga.submit(pre_carga, [item])
client.cisscontrol.pre_carga.set_status(
    id_precarga=pre_carga.id_pre_carga,
    status_code=0,
    id_usuario_conferente=user.id_user,
)

get_all(*, id_empresa, id_conferente, ...) -> list[PreCarga]

GET /ciss-control/pre_carga

Parameter Query key Default
id_empresa idEmpresa required
id_conferente idConferente required
num_dias_sync numDiasSync 99
ds_precarga dsPreCarga ""
ds_ponto_retirada dsPontoRetirada ""

All keys are sent on every call, empty strings included. Returns [] on HTTP 204 or an empty/non-array body.

submit(pre_carga, itens) -> requests.Response

POST /ciss-control/pre_carga

Posts {"preCargaList": [pre_carga.to_dict()], "itens": [i.to_dict() for i in itens]}. The wire format takes a list of headers, but only one pré-carga per call has ever been observed, so the method takes a single PreCarga and wraps it.

Returns the raw requests.Response — 201 on success, carrying the persisted items as its body. The body is not parsed, so read response.json() yourself if you need it.

This does not close the pré-carga; call set_status afterwards.

set_status(*, id_precarga, status_code, id_usuario_conferente) -> requests.Response

POST /ciss-control/pre_carga/status

Posts {"idPreCarga": ..., "statusCode": ..., "idUsuarioConferente": ...}. Status codes are passed through as CISS defines them — the library neither validates nor enumerates them. CISS echoes the request body back, so there is nothing to parse.


Pré-carga separação — client.cisscontrol.precarga_separacao

Every method is decorated with @requires_login and raises NotAuthenticatedError when called before login().

get_all(*, id_empresa, ...) -> list[PreCargaSeparacao]

GET /ciss-control/precarga_separacao

Keyword-only. All filter parameters are always sent, empty strings included.

Parameter Type Default API query key
id_empresa int required idEmpresa
num_dias_sync int 99 numDiasSync
ds_separacao str "" dsSeparacao
ds_precarga str "" dsPreCarga
ds_ponto_retirada str "" dsPontoRetirada
dt_inicio str "" dtInicio
ds_pre_separacao str "" dsPreSeparacao
dt_fim str "" dtFim

Returns [] on HTTP 204 or an empty/non-array body, otherwise one PreCargaSeparacao per element of the JSON array.

Date filters (dt_inicio / dt_fim) are typed str and forwarded verbatim — the library does not format date objects for you.

A large num_dias_sync can make this endpoint stall. It no longer hangs indefinitely — the default read timeout caps it — but a stalled call still costs you that timeout, so prefer a bounded window (e.g. num_dias_sync=30).

items(*, id_empresa, id_precarga, id_usuario, ...) -> list[PreCargaSeparacaoItem]

GET /ciss-control/precarga_separacao/itens

Parameter Type Default API query key
id_empresa int required idEmpresa
id_precarga int required idPreCarga
id_usuario int required idUsuario
ds_separacao str "" dsSeparacao
ds_precarga str "" dsPreCarga
ds_ponto_retirada str "" dsPontoRetirada
dt_inicio str "" dtInicio
ds_pre_separacao str "" dsPreSeparacao
dt_fim str "" dtFim

Returns [] on HTTP 204 or an empty/non-array body, matching get_all.

submit(items) -> requests.Response

POST /ciss-control/precarga_separacao

Takes a positional list[PreCargaSeparacaoSubmission] and posts [item.to_dict() for item in items] as a JSON array. Returns the raw requests.Response — the body is not parsed, so inspect response.status_code / response.json() yourself.


Data models

Models live in libciss.services.cisscontrol.models. They are @dataclass(slots=True), use snake_case in Python, and map to the API's camelCase. Response models expose from_dict, request models expose to_dict, and PreCarga exposes both because CISS hands the same header back to you on submit.

Being slotted dataclasses, they take positional or keyword arguments, compare by value, and reject attributes that are not declared fields.

from_dict requires the keys that identify a record and tolerates the merely descriptive ones, because CISS omits those on some pre-loads and losing a description is not a reason to fail a whole batch. Each model below lists what it tolerates.

LoginResponse

Built by auth.login().

Field Type API field
token_bearer str tokenBearer
id_user int idUser
id_grupo int idGrupo
username str username
enabled bool enabled
id_empresa int idEmpresa
cnpj_empresa str cnpjEmpresa
razao_social str razaoSocial (right-stripped)
permissions list[str] permissionsList

A missing or null razaoSocial becomes "" and a missing permissionsList becomes []. The remaining keys are required.

PreCarga

Returned by pre_carga.get_all() and accepted back by pre_carga.submit().

Field Type API field
id_empresa int idEmpresa
id_pre_carga int idPreCarga
descr_pre_carga str descrPreCarga (right-stripped)
id_status int idStatus
dt_alteracao datetime | None dtAlteracao
num_nota int numNota
id_orcamento int idOrcamento
id_pedido_pre_carga int | None idPedidoPreCarga
id_conferente int | None idConferente
emp_alias str empAlias — GET only
clientes list[Cliente] clientes — GET only
cli_for_list list[CliFor] cliForList — GET only

idEmpresa, idPreCarga, idStatus, numNota and idOrcamento are required — a missing one raises KeyError. A missing or null descrPreCarga / empAlias becomes "", the two nested arrays become [], and the remaining keys become None.

to_dict() emits only the nine non-GET-only keys, which is exactly what CISS accepts in preCargaList. The intended use is to take an object from get_all(), adjust id_status / id_conferente, and pass it straight to submit().

dtAlteracao keeps its fractional seconds rather than being truncated to a date, because it round-trips verbatim. CISS is inconsistent about the width — "2026-08-11T17:14:40.161" and "2026-07-20T19:33:12.966555" both occur — so parsing accepts either and serialization emits milliseconds, reproducing what the app sends.

Cliente

Element of PreCarga.clientes.

Field Type API field
id_clifor int idClifor
nome_cliente str nomeCliente (right-stripped)

idClifor is required; a missing or null nomeCliente becomes "".

CliFor

Element of PreCarga.cli_for_list. Overlaps with Cliente — CISS returns the same party under both keys with different field names — but adds the activity flag and the last-change timestamp.

Field Type API field
id_fornecedor int idFornecedor
nome_fornecedor str nomeFornecedor (right-stripped)
flag_inativo str flagInativo ("F" / "T"), not coerced to bool
dt_alteracao datetime | None dtAlteracao

idFornecedor is required; the rest fall back to "" / None.

PreCargaItem

Request model for pre_carga.submit(). A line is identified by the sale it came from — idEmpresaVenda / idPlanilhaVenda / numSequenciaVenda — not by the product, so the same idProduto legitimately appears more than once in one pré-carga.

Field Type API field Default
id_usuario int idUsuario required
id_empresa int idEmpresa required
id_pre_carga int idPreCarga required
id_empresa_venda int idEmpresaVenda required
id_planilha_venda int idPlanilhaVenda required
num_sequencia_venda int numSequenciaVenda required
id_produto int idProduto required
id_subproduto int idSubproduto required
qtd_produto float qtdProduto required
qtd_contada float qtdContada required
ds_local_retirada str dsLocalRetirada required
id_lote str | None idLote None
visualiza_qtd_pre_carga bool visualizaQtdPreCarga True
corredor str | None corredor None
gondola str | None gondola None
prateleira str | None prateleira None

Nothing is validated: a qtd_contada differing from qtd_produto is accepted and resolved server-side.

visualizaQtdPreCarga is serialized as the string "true" / "false", not as a JSON boolean. That is what the app sends, even though CISS answers with a real boolean. Sending an actual boolean is untested.

PreCargaSeparacao

Field Type API field
id_empresa int idEmpresa
id_pre_carga int idPreCarga
descricao str descricao
dt_movimento date dtMovimento, coerced to a date

idEmpresa, idPreCarga and dtMovimento are required — a missing one raises KeyError. A missing or null descricao becomes "", and it is right-stripped since CISS pads it to a fixed width.

dtMovimento accepts "2026-08-05", a full "2026-08-05T00:00:00" timestamp, or an already-decoded date/datetime; CISS returns all of these for the same field. Anything else raises ValueError.

PreCargaSeparacaoItem

Field Type API field
id_pre_carga int idPreCarga
id_empresa int idEmpresa
id_documento int idDocumento
id_produto int idProduto
id_subproduto int idSubproduto
ds_local_retirada str dsLocalRetirada
num_sequencia int numSequencia
id_lote str | None idLote — optional, None when absent
qtd_produto float qtdProduto
fg_separado str fgSeparado
qtd_contada_divergente bool qtdContadaDivergente
id_local_retirada int idLocalRetirada

Required: idPreCarga, idEmpresa, idDocumento, idProduto, idSubproduto, numSequencia and qtdProduto — these identify the line, so a missing one raises KeyError. The rest fall back when missing or null:

Key Fallback
dsLocalRetirada ""
idLote None
fgSeparado ""
qtdContadaDivergente False
idLocalRetirada 0

Because of that fallback, id_local_retirada == 0 means "CISS did not say", not pick-up location number zero. qtd_produto is coerced with float() and id_local_retirada with int(), since CISS sometimes sends them as strings.

PreCargaSeparacaoSubmission

Request DTO for submit(). Every field is required — there are no defaults, so all thirteen must be supplied.

Field Type JSON key
id_usuario int idUsuario
id_empresa int idEmpresa
id_documento int idDocumento
id_pre_carga int idPreCarga
id_produto int idProduto
id_subproduto int idSubproduto
id_local_retirada int idLocalRetirada
ds_local_retirada str dsLocalRetirada
num_sequencia int numSequencia
qtd_produto float qtdProduto
fg_separado str fgSeparado
qtd_contada float qtdContada
dt_hr_inicio datetime.datetime dtHrInicio, serialized with .isoformat()

to_dict() calls .isoformat() on dt_hr_inicio, so it must be a datetime — passing a string raises AttributeError. Nothing is validated beyond that: fg_separado is sent as-is ("S" / "N"), and a qtd_contada that differs from qtd_produto is accepted and resolved server-side.


Exceptions

Exception
└── CISSClientError
    └── AuthenticationError
        └── NotAuthenticatedError

Defined in libciss.exceptions.

Exception Raised when
CISSClientError Base class for library errors — catch this to catch them all
AuthenticationError Auth-related failures
NotAuthenticatedError A @requires_login method is called with no token set

Transport and HTTP failures are not wrapped: client.request() calls raise_for_status(), so 4xx/5xx surface as requests.HTTPError, and connection/timeout problems surface as the corresponding requests.RequestException subclasses.

import requests

from libciss.exceptions import NotAuthenticatedError

try:
    preloads = client.cisscontrol.precarga_separacao.get_all(id_empresa=1)
except NotAuthenticatedError:
    client.cisscontrol.auth.login("user", "pass")
except requests.HTTPError as e:
    print(e.response.status_code, e.response.text)

A 401 from an expired token arrives as requests.HTTPError, not NotAuthenticatedError — the local check only sees that a token exists. To recover, call login() again.


Endpoint map

HTTP Path Client method
POST /ciss-control/login auth.login
GET /ciss-control/pre_carga pre_carga.get_all
POST /ciss-control/pre_carga pre_carga.submit
POST /ciss-control/pre_carga/status pre_carga.set_status
GET /ciss-control/precarga_separacao precarga_separacao.get_all
GET /ciss-control/precarga_separacao/itens precarga_separacao.items
POST /ciss-control/precarga_separacao precarga_separacao.submit

Known issues

These are current limitations of the code, not of the documentation.

Issue Impact
get_all can stall on wide sync windows Bounded by the read timeout now, but a stalled call still costs you those seconds — keep num_dias_sync small
logout() is client-side only The token remains valid on the server
Transport errors are not wrapped Callers catch requests exceptions (HTTPError, Timeout) alongside CISSClientError
Empty query filters are sent as key= The reference app sends bare key with no =. Both decode to an empty string server-side, but this is the one place the library is not byte-identical to the captured traffic
pre_carga.submit / set_status return unparsed responses The 201 body (the persisted items) and the status echo are yours to read
No test suite Changes are unverified

Glossary

Portuguese terms used by the CISS API, kept untranslated in the model field names.

Term Meaning
Empresa Company / store (id_empresa, CNPJ, razão social)
Pré-carga Pre-load batch for warehouse picking
Separação Product picking / separation
Conferência Checking a picked order against its invoice
Conferente The person doing the conferência (id_conferente)
Nota Invoice (num_nota)
Orçamento Quote (id_orcamento, 0 when there is none)
Planilha de venda Sale sheet a line item came from (id_planilha_venda)
Clifor Cliente/fornecedor — customer or supplier, one record for both
Corredor / gôndola / prateleira Aisle / gondola / shelf, the item's physical location
Local de retirada Pick-up location
Documento Related document ID
Produto / Subproduto Product and subproduct IDs
Lote Lot / batch code (optional)
Qtd produto Expected quantity on the pre-load
Qtd contada Quantity actually counted during separation
fgSeparado Separation flag, an API string ("S" / "N")
numDiasSync Days of history to sync (default 99)

License

MIT © Redson

Metadata

Release files for libciss 0.1.0a5

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

Source distribution (sdist)

Source distribution for libciss 0.1.0a5
File Size Uploaded Provenance Actions
libciss-0.1.0a5.tar.gz 29.3 kB Without provenance Details for libciss-0.1.0a5.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for libciss 0.1.0a5
File Interpreter ABI Platform Actions
libciss-0.1.0a5-py3-none-any.whl Python 3 none any Details for libciss-0.1.0a5-py3-none-any.whl

Total release size: 53.7 kB

Release files / libciss-0.1.0a5.tar.gz

Download URL libciss-0.1.0a5.tar.gz
Size 29.3 kB
Tags Source
SHA-256 checksum
How to use checksums
2a7c448bb5c4dad5e56ea75612a9369479302252a8a868005b32d7be16202516
BLAKE2b-256 checksum
How to use checksums
f1aaba314914e6750b757d18d6fe9d3cbbc8418fae86dd759009cc1994aaf2ab
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / libciss-0.1.0a5-py3-none-any.whl

Download URL libciss-0.1.0a5-py3-none-any.whl
Size 24.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
aa7c954345d1f10fbe2219c77d5e59f388c248b8b15fd436ab76eaec666a8f78
BLAKE2b-256 checksum
How to use checksums
f317f179f443af6baf2c03cddb3cdecaff1b1cd5710dd1eb09d595990197853e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Security for libciss 0.1.0a5

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