sans
Synchronous / Asynchronous NationStates
A fully typed extension for HTTPX for the NationStates API.
Installing
python3 -m pip install -U sans
Development version:
python3 -m pip install -U https://github.com/zephyrkul/sans/archive/master.zip#egg=sans
Support
If you need help with using sans, find a bug, or have a feature request, feel free to find me in the NS Coders Discord server, or file an issue.
Examples
Synchronous
import sans
from xml.etree import ElementTree as ET
def main():
sans.set_agent("Darcania")
request = sans.Nation(
"darcania",
"fullname population flag census",
mode="score",
scale="65 66",
)
root = sans.get(request).xml
sans.indent(root)
print(ET.tostring(root, encoding="unicode"))
with sans.stream("GET", sans.RegionsDump()) as response:
for region in response.iter_xml():
sans.indent(region)
print(ET.tostring(region, encoding="unicode"))
if __name__ == "__main__":
main()
Asynchronous
import asyncio
import sans
from xml.etree import ElementTree as ET
async def main():
sans.set_agent("Darcania")
async with sans.AsyncClient() as client:
request = sans.Nation(
"darcania",
"fullname population flag census",
mode="score",
scale="65 66",
)
root = (await client.get(request)).xml
sans.indent(root)
print(ET.tostring(root, encoding="unicode"))
async with client.stream("GET", sans.RegionsDump()) as response:
async for region in response.aiter_xml():
sans.indent(region)
print(ET.tostring(region, encoding="unicode"))
if __name__ == "__main__":
asyncio.run(main())
Authentication
auth = sans.NSAuth(password="hunter2")
sans.get(sans.Nation("testlandia", "ping"), auth=auth)
# X-Autologin is automatically retrieved and stored for when the auth object is re-used
print(auth.autologin)
# X-Pin is cached internally for repeated requests
root = sans.get(sans.Nation("testlandia", "packs"), auth=auth).xml
Telegrams
limiter = sans.TelegramLimiter(recruitment=False)
# The Telegram API can be used without a TelegramLimiter, but marking it ahead of time can save an API call.
response = sans.get(sans.Telegram(client="abcd1234", tgid="1234", key="abcdef1234567890", to="testlandia"), auth=limiter)
assert response.content == b"queued"
Server-Sent Events
for event in sans.serversent_events(
client, "move", "founding", "cte", "member", "endo"
).view(regions=["the north pacific"]):
print(event["str"])
Command Line
sans --nation darcania census --scale "65 66" --mode score --agent Darcania
<NATION id="darcania">
<CENSUS>
<SCALE id="65">
<SCORE>8145.00</SCORE>
</SCALE>
<SCALE id="66">
<SCORE>0.00</SCORE>
</SCALE>
</CENSUS>
</NATION>
sans --nation testlandia fullname
<NATION id="testlandia">
<FULLNAME>The Hive Mind of Testlandia</FULLNAME>
</NATION>
sans --region "the north pacific" numnations lastupdate
<REGION id="the_north_pacific">
<LASTUPDATE>1685681810</LASTUPDATE>
<NUMNATIONS>9535</NUMNATIONS>
</REGION>
sans --quit
No query provided. Exiting...
Requirements
Release files for sans 1.3.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sans-1.3.5.tar.gz | 32.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sans-1.3.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size:59.9 kB
Release files / sans-1.3.5.tar.gz
| Download URL | sans-1.3.5.tar.gz |
|---|---|
| Size | 32.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
546dad34abf0405f2858280a3c5fc899df01f210fab3f7c56cb023225c1d197a
|
|
BLAKE2b-256 checksum How to use checksums |
322f6474465f73981d6a35a43b0663c674c4c7fe5c18d699d053cd61e1ff6aeb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
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 Jul 23, 2026.
Transparency logRelease files / sans-1.3.5-py3-none-any.whl
| Download URL | sans-1.3.5-py3-none-any.whl |
|---|---|
| Size | 27.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1ab0f04cd461b743a37574ffeb6a9562eb5f39b67217349c0937382c33695cfb
|
|
BLAKE2b-256 checksum How to use checksums |
e9e9f99189e7b026b0bc345cddbc8639c6c3134ea44a915b01c179f90d7208e8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
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 Jul 23, 2026.
Transparency log