va-lis-client
Python client for the Virginia Legislative Information System (LIS) REST API.
Built from live API responses — the official OpenAPI specs are unreliable (response envelope keys, field casing, and parameter behavior all differ from the docs).
This package doubles as the API documentation, recording behavior found nowhere else, such as pagination.
- Developer portal: https://lis.virginia.gov/developers
- API key registration: https://lis.virginia.gov/apiregistration
- Help desk: lis@dlas.virginia.gov
Installation
pip install va-lis-client
With Redis rate limiting support:
pip install "va-lis-client[rate-limiting]"
Quick start
import os
from va_lis_client import LISClient
# Pass the key directly, or set the LIS_API_KEY environment variable
client = LISClient(api_key="your-api-key-here")
# or: os.environ["LIS_API_KEY"] = "your-key"; client = LISClient()
# The GA's current working session. During the interim this is the
# *upcoming* session, not the one that just ended — see
# "Bill identity & carry-over" below.
session = client.get_default_session()
# All bills in that session
bills = client.get_session_bills(session_code=int(session.SessionCode))
# Full detail for a bill
bill = client.get_bill(legislation_id=98525)
# Bill text (HTML) and summaries
texts = client.get_bill_text_detail(legislation_id=98525, session_code=20261)
summaries = client.get_bill_summaries(legislation_number="HB1", session_code=20261)
Documentation
This README covers setup and the traps that apply to every call. Each domain
has its own guide in docs/.
| Guide | What it covers |
|---|---|
| API services | Every wired endpoint, grouped by LIS service, the event vocabulary join, and the paths left unwired and why |
| Bills | Keyword search and its duplicate rows, the versions of a bill, amendments and conference bills |
| Voting records | Roll calls, block votes and voice votes, why a vote id on a bill event can belong to another bill, and the full voting record of a member |
| Members and committees | The session roster, the bills a member patrons, committee seats, clerks and offices |
| Chamber records | Minutes books, communications between the chambers, and session statistics |
| The Virginia legislative process | How a bill becomes law, the status groups, and how meetings and dockets work |
Service layer
LISClient is transport: one method per endpoint, and no interpretation.
LISService sits above it. It does the work every caller would otherwise
repeat: resolving human bill numbers to IDs, joining the reference
vocabularies, caching the large lists, and flattening bill text HTML.
from va_lis_client import LISClient, LISService, strip_html
from va_lis_client.models import CHIEF_PATRON
service = LISService(LISClient()) # or LISService() to build the client for you
# Bill numbers, not surrogate keys. Case and padding are normalized.
bill = service.get_bill("hb0001", 20261)
bill_id = service.resolve_bill_id("HB1", 20261) # ~1.3 KB, via the text list
item = service.resolve_bill("HB1", 20261) # the session row; needs the 3 MB list
# Text: the newest version by default, or name one by DocumentCode.
item, detail = service.bill_text("HB1", 20261)
item, detail = service.bill_text("HB1", 20261, "HB1ER")
print(strip_html(detail.DraftText))
# The versions of many bills in one request, grouped back by bill.
versions = service.bill_versions(["HB1", "HB1503"], 20261)
# Who voted which way, with party and district already attached.
for row in service.roll_call("HB1", 20261):
print(row.name, row.party, row.district, row.response)
# Lashrecse D. Aird D 13th Y
# Luther Cifers, III R 10th N
# The other axis: everything one member voted on.
for v in service.member_votes(503, 20261):
print(v.bill_number, v.response, "BLOCK" if v.is_block else "")
votes = service.member_votes_on(503, "hb0001", 20261)
# Members by name, and the bills a member patrons, co-patronage included.
schmidt = service.find_members("schmidt", 20261)[0] # MemberID 544
for b in service.member_bills(schmidt.MemberID, 20261):
print(b.LegislationNumber, b.LegislationStatus, b.SummaryVersion)
chief = service.member_bills(schmidt.MemberID, 20261, role=CHIEF_PATRON)
patrons = service.bill_patrons("HB1408", 20261) # every role
# Committees: who sits where, with party and district, and the reverse.
courts = service.resolve_committee("Courts of Justice", "H") # H08
for s in service.committee_members(courts.CommitteeID, 20261):
print(s.name, s.role, s.party, s.district)
seats = service.member_committees(schmidt.MemberID, 20261) # 14 cached requests
# Senate dockets: every bill a committee has scheduled, with the date and room.
for e in service.docket_entries("Courts of Justice", 20261):
print(e.date, e.bill_number, e.room)
# Minutes: a day's proceedings, flattened. The vote id here really is the
# bill's, which is not true of a bill event.
day = service.minutes_books(20261, chamber_code="S")[0]
for r in service.minutes_records(day.MinutesBookID):
print(r.bill_number, r.event_code, r.tally, r.vote_id)
# Who clerks a committee, and where to write to a member.
staff = service.committee_staff("Courts of Justice", chamber_code="H")
office = service.member_office(503) # the district address; None for many members
# Keyword search, in two grains. Both drop the duplicate rows LIS emits.
# A keyword needs keyword_location: without one LIS answers nothing.
firearm = dict(session_code=20261, keyword="firearm", keyword_location="Summary")
hits = service.search_bills(**firearm) # one row per bill
every = service.search_bill_summaries(**firearm) # one row per summary
# Every vote including the ones no member can be credited with.
for record in service.bill_votes("HB1", 20261):
notes = record.statements_by_member()
for code, members in record.responses().items(): # "Y" "N" "A" "X"
for m in members:
print(code, m.MemberNumber, m.name, notes.get(m.MemberID, []))
# Reference joins. Events carry a null type ID and a null status ID, so these
# index the vocabularies on the keys that events actually carry.
types = service.event_types_by_code() # EventCode -> [LegislationEventType]
kind = service.event_type_for(event) # the one row describing an event
statuses = service.statuses_by_name() # Name -> LegislationStatus
label = service.bill_status_label(bill, item) # best available status label
Voting records. bill_votes walks a bill's events, takes each VoteID,
and fetches the roll call behind it, one request per vote. HB1 in 20261
returns eight votes: two House committee, one House floor, two Senate
committee, three Senate floor. Six of the eight are attributable to HB1
alone. See Votes for why the other two are
not.
bill_shallow_votes lists the same votes without the members, in two
requests however often the bill was voted on. It returns seven for HB1,
because it leaves out most voice votes. Read
A bill's votes without the rosters
before you use it.
roll_call is bill_votes with the roster joined on. A ballot from LIS
names a member by MemberID and nothing else, so party and district take a
second lookup against the session roster, cached for an hour. roll_call
returns only the attributable votes, since naming a member on a block or voice
vote misstates the record. HB1 gives 214 named ballots across its six roll
calls. Each entry carries its own vote, because one bill has many.
Minutes are the reliable way into a roll call. minutes_records flattens
one day's book into a row per action, each carrying the bill, the event code,
the tally, and the VoteID. That vote id belongs to the bill beside it,
which is not true of a bill event's vote id, so it needs no repair. The
tally string also keeps a presiding officer's tiebreak that the Vote service
drops. See Minutes books.
EventCode is not unique. The event-type vocabulary holds 3,912 rows under
only 1,502 codes, and H1405 alone returns four. Two of those four read
"Reported from Labor and Commerce" and two read "Failed to report (defeated)
in Labor and Commerce". event_types_by_code therefore returns every row
per code, and event_type_for picks the one that describes a given event. See
Joining the event vocabulary.
Searching returns a bill more than once, twice over. Advanced search
emits one row per published summary version and a pile of exact duplicate
rows, so 20261 comes back as 3,007 rows over 2,827 bills. The two grains are
two methods: search_bills collapses to one row per bill by ranking the
summary label, and search_bill_summaries keeps every version and drops only
the exact duplicates. Both take dedupe=False to get LIS's own answer. The
raw client never touches the rows. See
Searching bills, which also covers why the endpoint
cannot be paged.
Resolving an id cheaply. The text list endpoint takes a bill number and
returns rows carrying the LegislationID, so resolve_bill_id costs about
1.3 KB instead of the 3 MB session list. It is session scoped, so it will not
resolve a bill into a session it does not belong to. Bills with no published
text fall back to the list. Use resolve_bill when you want the session row
itself, for its status, description, or chief patron.
Caching. The session bill list backs substring search and is the fallback
for id resolution. It runs to roughly 3 MB, so LISService caches it for 15
minutes (tune with bill_list_ttl=). The member roster changes only when a
member resigns or arrives, so it is cached for an hour (roster_ttl=), and a
member's 1.9 MB vote history rides the same TTL, keyed per member. A member's
bill list rides it too, keyed per member, session, and role. The static
reference vocabularies, the session reference included, are kept for the life
of the instance. Caches live on the instance, so build one service and keep
it. Instances are safe to share between threads.
Errors. Everything derives from LISError, so one except clause covers
the package. The resolution errors also derive from the builtin that fits them.
| Exception | Also a | Raised when |
|---|---|---|
LISClientError |
The API returns a non-success response | |
InvalidBillNumberError |
ValueError |
A string does not parse as a bill number |
BillNotFoundError |
LookupError |
A bill number is not in the session |
TextVersionNotFoundError |
LookupError |
No text version matches, or the version has no body |
SessionNotFoundError |
LookupError |
A session code is not in the session reference |
CommitteeNotFoundError |
LookupError |
No committee, or more than one, matches a number or name |
Authentication
Every request sends a WebAPIKey header with a partner GUID obtained at
https://lis.virginia.gov/apiregistration.
Set the key via environment variable:
export LIS_API_KEY=your-guid-here
Or pass it directly to the constructor:
client = LISClient(api_key="your-guid-here")
Important: Heartbeat endpoints accept any key — even garbage. Use
client.check_api_key() to actually validate a key via the
PartnerAuthentication service.
Data availability
- The session reference list reaches back to 1994.
- Bill data has been observed working for the 2024–2027 sessions (as of Aug 2026). Earlier guidance said only 2025–2026 was authorized via the API.
- Votes reach back to 1994 — much further than bills.
voteID=1is a January 1994 committee vote. Do not assume a vote ID belongs to a recent session. - Minutes books start at 20241 and are thin at the edges. 20241 holds 45 books, all of them Senate floor; 20251 holds 599 and 20261 holds 388; 20271 answered 204 on 2026-09-15. Floor books are Senate only in every session. See Minutes books.
- Older session data is available as
legacylis.virginia.govCSV downloads. - No rate limit is enforced, but usage is tracked per key. DLAS said in September 2026 that they do not rate limit, that they watch per key usage, and that they have revoked keys after sending warnings. Rate limit yourself; see Rate limiting.
Identifier cheat-sheet
Bills are uniquely identified by session + bill number, but the API uses several overlapping identifiers:
| Identifier | Example | Notes |
|---|---|---|
SessionCode |
20261 |
Year + sequence. 20261 = 2026 Regular, 20262 = Special I |
SessionID |
59 |
Surrogate PK. Either code or ID works as query param |
LegislationNumber |
"HB1" |
Must be unpadded — HB0001 returns 204 |
LegislationID |
98525 |
Surrogate PK for the logical bill — reused across carry-over (see below) |
DocumentCode |
"HB1ER" |
Bill number + version code, e.g. HB1503HC1. A chaptered version carries its chapter number instead, e.g. CHAP0350 |
LegislationTextID |
257719 |
PK for one immutable text snapshot — follows the bill across carry-over (see below) |
CommitteeID |
14 |
Surrogate PK for a committee |
MinutesBookID |
3861 |
Surrogate PK for one body's proceedings on one day |
CommunicationID |
4519 |
Surrogate PK for one message between the chambers |
AffiliationID |
8 |
On a personnel row this is a CommitteeID |
CommitteeNumber |
"H14" |
Chamber prefix + number, e.g. H14, S02 |
CalendarID |
21146 |
PK for a House floor calendar |
DocketID |
21114 |
PK for a Senate committee docket |
ScheduleID |
3626 |
PK for a scheduled meeting |
LegislationEventID |
1561089 |
PK for a bill history event — follows the bill across carry-over (see below) |
VoteID |
294006 |
PK for one vote. Reachable only from LegislationEvent.VoteID |
MemberID |
217 |
PK for a person. Stable across every vote and session |
VoteMemberID |
10988439 |
PK for one ballot — that person's response on that one vote. New every vote |
MemberNumber |
"H0206" |
Chamber prefix + number, the human-facing member id |
DistrictID |
98 |
Surrogate PK for a seat. The label is DistrictName on a member, Title on a district |
MemberID and VoteMemberID are not interchangeable, and one LIS field
mixes them up. See The VoteStatement.VoteMemberID
trap.
Bill identity & carry-over
Virginia's even-year sessions may carry unfinished bills over into the
following odd-year session — never the reverse, never twice, and never across
a two-year General Assembly term. The API models this by reusing the
LegislationID (confirmed against the live API, 2026-08-12):
- A carried-over bill appears in both sessions'
get_session_billslists with the sameLegislationID(e.g. HB9, ID98631, in20261and20271). get_bill(legislation_id)returns top-levelSessionCode/SessionIDasNone. TheSessionslist carries one cross-ref per session the bill appears in — both the even and odd session for a carried-over bill — and is the explicit lineage record.- So
LegislationIDidentifies the logical bill within a GA term: at most two session appearances (even, then odd if continued). Session-scoped identity is(SessionCode, LegislationNumber)or(SessionCode, LegislationID). - An odd-year bill list starts as pure carry-over — as of Aug 2026,
20271returned 443 bills, every one sharing its ID with20261. Continued bills must be acted on by mid-November of the even year or they die, so expect that set to shrink before the odd session convenes.
Texts and events are entity-level too. A bill's text versions and history
events belong to the logical bill, not to a session appearance, so they follow
it across the carry-over with their ids unchanged: get_bill_texts("HB9", 20261)
and get_bill_texts("HB9", 20271) return the identical record
(LegislationTextID=257905, the introduced text — verified live 2026-08-12).
A text id never mutates. When the text changes, LIS appends a new version
record with a new id (HB9 → HB9E → HB9H1 → HB9ER); a carried bill
brings its whole existing stack into the new session and appends any odd-year
amendments to it. Event histories behave the same way — the odd-year view
includes every even-year event under its original LegislationEventID.
Sync warning: if you mirror bills into a database, don't put a global
unique constraint on any of these ids. The first odd-year sync will violate a
global LegislationID constraint on the first carried-over bill, violate a
global LegislationTextID constraint on its first text version, and — worst —
an upsert keyed on a globally-unique LegislationEventID won't error at all:
it silently re-parents the even-year rows to the odd-year bill. Scope every
LIS surrogate to its owning parent: (session, LegislationID),
(bill, LegislationTextID), (bill, LegislationEventID).
Default session: get_default_session() tracks the GA's working
session, not the last one convened. Once a session wraps up (sine die, veto
session, enactments effective July 1), the default advances to the upcoming
session during the interim — by Aug 2026 it was already 20271, which is
where continued bills and (from mid-November) new prefiles accumulate. For
retrospective work on a just-ended session, pass its explicit session code.
Response envelope gotchas
The docs say ListItems everywhere. Reality:
| Endpoint | Docs say | Actual key |
|---|---|---|
| Sessions | ListItems |
Sessions |
| Legislation list | ListItems |
Legislations |
| Legislation detail | ListItems |
Legislations |
| Legislation statuses | ListItems |
References |
| Text list | ListItems |
LegislationTextList |
| Text detail | ListItems |
TextsList |
| Summaries | ListItems |
LegislationSummaries |
| Version refs | ListItems |
LegislationVersionList |
| Partner check | flat | PartnerList |
| Calendars | ListItems |
Calendars |
| Dockets | ListItems |
Dockets |
| Schedules | ListItems |
Schedules |
| Committees | ListItems |
Committees |
| Legislation events | ListItems |
LegislationEvents |
| Schedule types | ListItems |
ScheduleTypes |
| Meeting rooms | ListItems |
MeetingRooms |
| Minutes book list | ListItems |
Minutes |
| Minutes book detail | ListItems |
MinutesBooks |
| Action reference types | ListItems |
ActionReferenceTypeList |
| Calendar actions | ListItems |
CalendarActions |
| Communication list | ListItems |
CommunicationsList |
| Communication detail | ListItems |
CommunicationResponse |
| Communication files | ListItems |
CommunicationFileResponse |
| Personnel | ListItems |
Personnels |
| Contacts | ListItems |
Contacts |
| Agencies | ListItems |
Agencies |
| Category types | ListItems |
CategoryTypes |
| Chamber patron index | ListItems |
PatronLegislation |
| Bill versions (both calls) | ListItems |
LegislationsVersion |
| Chamber statistics | ListItems |
ChamberStatistics |
| Committee statistics | ListItems |
CommitteeStatistics |
| Session event types | ListItems |
SessionEventTypes |
| Amended legislation | ListItems |
LegislationAmendmentList |
| Conference legislation | ListItems |
ConferenceLegislationList |
| Legislation id list | LegislationIds |
LegislationIds |
| Member patron types | ListItems |
MemberPatronTypes |
| Subject index | ListItems |
SubjectsReference |
| Summary versions | ListItems |
SummaryVersions |
| Text dispositions | ListItems |
TextDispositionList |
| Text actions | ListItems |
LegislationTextActions |
| Sponsor types | ListItems |
SponsorTypes |
| Text hit counts | HitCounts |
HitCounts |
| Member statuses | ListItems |
MemberStatuses |
| Member contacts | ListItems |
MemberContactInformationList |
| Shallow member list | ListItems |
ShallowMembers |
| Organizations | ListItems |
Organizations |
| Shallow votes | ListItems |
ShallowVotes |
| Vote links | ListItems |
VoteLinks |
MinutesBook and LegislationCommunications each answer a list and a detail under different keys, so the spec is wrong twice for both.
LegislationsVersion is not a typo in this table. LIS pluralizes the first
word, and sends a SearchCriteria key beside it that was null on every call.
Pagination (undocumented)
Paging works but is documented nowhere, and it is not a query string
parameter. Every parameter name is silently ignored. It runs on an
X-Pagination request header carrying JSON:
curl -H "WebAPIKey: $LIS_API_KEY" \
-H 'X-Pagination: {"PageSize":3,"SkippedRecords":6}' \
"https://lis.virginia.gov/Legislation/api/getlegislationsessionlistasync?sessionCode=20271"
| Request field | Effect |
|---|---|
PageSize |
Caps the number of rows returned |
SkippedRecords |
Raw record offset. This is what moves the window |
PageNumber |
Accepted and ignored. Always echoed back as 1 |
Every response carries an X-Pagination header back. CurrentPage is derived
from SkippedRecords divided by PageSize:
{"PageSize":3,"PageNumber":1,"TotalPages":148,"TotalCount":443,
"CurrentPage":3,"SkippedRecords":6,"HasPrevious":true,"HasNext":true}
Using it
page = client.get_session_bills(session_code=20271, page_size=5, skip=10)
len(page) # 5. PagedList subclasses list.
page[0].LegislationNumber # "HB71"
page.pagination.TotalCount # 443
page.pagination.HasNext # True
# TotalCount without downloading the list: one row, about a kilobyte.
client.get_session_bill_count(session_code=20271) # 443
PagedList is a real list, so code that iterates or indexes it needs no
change. .pagination is None when the server sends no usable header.
Worth using: an unpaged row is about 820 bytes, so a full regular session runs to roughly 3 MB.
Which endpoints support it
Verified on getlegislationsessionlistasync only. It is not global
middleware. The event type reference endpoint ignores the header and returns
all 3,912 rows (2.19 MB) on every call, which is why the client caches that one
instead.
AdvancedLegislationSearch cannot be paged at all. It ignores pageNumber
and pageSize on the query string, its request body has no paging fields, and
the X-Pagination it sends back reports a TotalCount that matches neither
the row count nor the unique bill count. See
Searching bills.
Text that is not JSON
Four paths answer with something other than a JSON envelope. The client
returns each as a str, and None on a 204.
| Method | LIS sends | What it is |
|---|---|---|
get_bill_html |
text/html |
One text as the printed page, a fragment with inline styles |
get_committee_members_text |
text/plain |
"Aird (Chair), Stanley, McPike, ..." |
get_schedule_vcal |
text/calendar |
A VCALENDAR with one VEVENT per meeting |
get_bill_pdf_url |
a JSON string | The address of the PDF |
getpdfasync does not return a PDF. It returns the blob address, such
as https://lis.blob.core.windows.net/files/1081188.PDF, the same address
a bill version fetched by single id carries in PdfFile.
The HTML path calls its parameter documentNumber and wants a document
code. "HB1" is the introduced text and "HB1ER" the enrolled one. A
code the session does not hold answers 400, not 204.
hilite marks changes to the law, not search hits. It adds
color:red to struck text and background-color:yellow to new text.
The roster text answers 406 without a session, where every JSON path answers 400.
get_draft_text is JSON, and belongs beside these: it returns one text's
HTML body from its LegislationTextID alone, with no session, starting at
the enacting clause. get_bill_html returns the same bill with its session
line, number and patrons on top.
get_text_hit_counts counts a term in texts you name. Several terms add
up: "minimum" counts 12 and "wage" 11 in HB1's introduced text, and
"minimum AND wage" counts 23.
Rate limiting (optional)
LIS enforces no rate limit, but DLAS tracks usage per key and has revoked keys after sending warnings (stated September 2026). No threshold is published. Treat self imposed rate limiting as required in production, even though the extra is optional to install.
If you're running many workers and want to share a global rate limit across
them, install the rate-limiting extra and use try_acquire_request_permit:
pip install "va-lis-client[rate-limiting]"
import redis
from va_lis_client.rate_limiter import try_acquire_request_permit
r = redis.from_url("redis://localhost:6379/0")
if try_acquire_request_permit(redis_client=r, rate_limit=100):
client.get_session_bills(session_code=20261)
else:
# back off
...
Or set REDIS_URL and LIS_RATE_LIMIT environment variables and call with
no arguments — the module picks them up automatically.
TLS trust: the operating system's store
The client verifies TLS with truststore, so trust comes from the operating system. On Windows and macOS each chain goes to the platform verifier, so the platform's distrust list applies, as do enterprise and government roots that IT pushes to the machine. On Linux it verifies with OpenSSL against the system CA bundle.
Do not swap in ssl.create_default_context(). On Windows that copies the
root store into OpenSSL, which never reads Microsoft's distrust list: after
the eMudhra intermediate CA compromise (October 2026) such a context still
accepted both revoked chains.
requests also adds certifi's roots on each new connection. On Windows and
macOS those count only after the platform rejects a chain, and the distrust
list still applies. On Linux the trust is the union of the system bundle and
certifi, so keep both current: ca-certificates and certifi>=2026.10.19.
To choose trust yourself, pass a session:
import requests
from va_lis_client import LISClient
session = requests.Session()
session.verify = "/path/to/ca-bundle.pem"
client = LISClient(session=session)
Package structure
src/va_lis_client/
├── __init__.py # re-exports the client, the service, and the errors
├── client.py # HTTP client — returns Pydantic models
├── service.py # LISService — resolution, reference joins, text helpers
├── exceptions.py # LISError and its subclasses
├── http.py # SystemCertSSLAdapter + shared requests session
├── rate_limiter.py # optional Redis-based rate limiter
└── models/
├── __init__.py # re-exports all models
├── common.py # Heartbeat, Partner
├── session.py # Session, SessionEvent
├── legislation.py # Patron, Legislation, LegislationStatus, ...
├── text.py # LegislationTextItem, LegislationTextDetail, ...
├── bill_version.py # BillVersion: one bill's versions, not the LegislationVersion vocabulary
├── statistics.py # ChamberStatistic, CommitteeStatistic
├── search.py # LegislationSearchResult, SUMMARY_VERSION_RANK, ...
├── event.py # LegislationEvent, LegislationEventType, ActorType
├── pagination.py # Pagination, PagedList — the X-Pagination protocol
├── committee.py # Committee, CommitteeMember, CommitteeAction
├── schedule.py # Schedule, ScheduleType, MeetingRoom
├── calendar.py # CalendarDetail, Agenda, ...
├── vote.py # Vote, VoteMember, VoteLegislation, VoteStatement
├── member.py # Member, Party, District
├── member_vote.py # MemberVoteResult — the member-first axis
├── docket.py # DocketDetail, DocketItem, DocketCategory, ...
├── minutes.py # MinutesBook, MinutesEntry, MinutesActivity, ...
├── communication.py # Communication, CommunicationCategory, ...
└── directory.py # Personnel, Contact, Agency, StaffRoleType, ...
License
MIT
Metadata
Release files for va-lis-client 0.4.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| va_lis_client-0.4.2.tar.gz | 177.2 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| va_lis_client-0.4.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 312.5 kB
Release files / va_lis_client-0.4.2.tar.gz
| Download URL | va_lis_client-0.4.2.tar.gz |
|---|---|
| Size | 177.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4fc130c51cf8eb9ef6d55dfa2d8128802997f54faddfd6208ce5cbfd558dfe72
|
|
BLAKE2b-256 checksum How to use checksums |
e5dd42df1a398862c136bf66cb2865f84e089626a0b83e8f445542618a727c68
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logRelease files / va_lis_client-0.4.2-py3-none-any.whl
| Download URL | va_lis_client-0.4.2-py3-none-any.whl |
|---|---|
| Size | 135.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e2416ed447a99ae3a51f6a3750cf2f1e88947cb6e67cb21cdefef90c219d670e
|
|
BLAKE2b-256 checksum How to use checksums |
e09f5181321eb372e1001475edf72c9cf70ff0089ca18ffd866057fcfebaac6d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logSecurity for va-lis-client 0.4.2
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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for va_lis_client-0.4.2.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logA 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.