Apsi
Browse the docs · Apsi 2.4.4

Docs 2.4.4 · 5 min read

Libraries (.apsil)

Apsi libraries are distributed as .apsil files through the official registry. One command installs the newest version, every file is verified, and a library is used exactly like a standard module.

Installing

apsi install NAME                   # newest stable version
apsi install [email protected]             # exactly this version
apsi install NAME@^1.4              # newest 1.x that is at least 1.4
apsi install NAME@~1.4.2            # newest 1.4.x that is at least 1.4.2
apsi install "NAME>=1.2,<2"         # any range
apsi install ./dist/NAME-1.0.0.apsil   # a local file
apsi install                        # everything in [dependencies] of apsi.toml
apsi install -U NAME                # upgrade to the newest matching version
apsi install -g NAME                # for your user account instead of the project
apsi uninstall NAME
apsi lib list                       # installed libraries
apsi search WORDS                   # search the registry
apsi lib info NAME                  # versions, sizes and dates

Inside a project (a folder with apsi.toml), libraries go into apsi_packages/ and a lock file, apsi-packages.lock, records the exact versions and file hashes. Outside a project, or with -g, they go into your user folder (~/.apsi/packages, or %USERPROFILE%\.apsi\packages on Windows). Project libraries take precedence.

Dependencies of a library are installed automatically. If two libraries need incompatible versions of the same dependency, installation stops with a clear message instead of picking one silently.

Pre-release versions (2.0.0-rc.1) are installed only when a requirement names a pre-release.

Version requirements

Requirement Allows
* or nothing the newest stable version
1.4.2 or ==1.4.2 exactly 1.4.2
1 any 1.x.y
1.4 any 1.4.y
^1.4.2 ≥ 1.4.2 and < 2.0.0 (for 0.x: ^0.3.1 allows < 0.4.0)
~1.4.2 ≥ 1.4.2 and < 1.5.0
>=1.2,<2 a combination of >, >=, <, <=, ==, !=

Using a library

use physics_units          # dashes in the library name become underscores
print(physics_units.version)

use transformer_kit as tk
let model = tk.gpt(layers=12, width=768)

use NAME makes the library’s public names available directly and as NAME.member. Names starting with _ are private. The checker loads the library before your program runs, so unit and type errors across library boundaries are reported as usual.

What is verified on installation

  1. The SHA-256 of the downloaded file must match the registry’s record.
  2. The archive must contain exactly the files listed in its manifest, with the listed sizes; paths may not leave the package folder; encrypted entries are refused.
  3. Every file’s SHA-256 must match the manifest.
  4. The library must accept your Apsi version (apsi = ">=2.0.0" in its manifest).
  5. Apsi Guard scans the code. Critical findings remove the library again; high findings are shown.

Creating a library

apsi new my-physics --template lib

The [package] table of apsi.toml describes the library:

[project]
name = "my-physics"              # lowercase letters, digits, "-" or "_"; 2–64 characters; starts with a letter
version = "1.0.0"                # semantic versioning
description = "Orbital mechanics helpers"

[package]
entry = "src/main.apsi"          # what `use my_physics` loads
summary = "Orbital mechanics helpers"
license = "MIT"
authors = ["Your Name"]
keywords = ["physics", "orbits"]
homepage = "https://example.org"
repository = "https://github.com/you/my-physics"
apsi = ">=2.0.0"                 # Apsi versions the library works with
include = ["src/**", "README*", "LICENSE*", "examples/**", "data/**"]
exclude = ["data/raw/**"]

[dependencies]
linalg-extra = "^1.2"

Libraries may be of any size and contain data files (weights, tables, datasets) next to the code; files larger than 2 GB are stored with ZIP64.

Building: apsi pack

apsi pack                  # writes dist/my-physics-1.0.0.apsil
apsi pack --out build/     # another folder

apsi pack first checks every .apsi file (syntax, names, types and units) and stops if anything is wrong. It then writes the archive deterministically — sorted entries, fixed timestamps — so the same sources always give the same bytes and the same SHA-256.

Publishing: apsi publish

Libraries are published only from the command line, with an API token:

  1. On the website, open Settings → Developer and create a token. Give it a name, choose its permissions (publish:new to create new libraries, publish:update to add versions, yank to hide versions) and optionally limit it to one library. Copy it — it is shown once.

  2. Store the token (the file is readable only by you). The official registry, https://apsi.dev, is used by default; apsi lib registry URL (or APSI_REGISTRY) switches to a private one.

    apsi lib login --token apsi_…
    
  3. Publish:

    apsi pack
    apsi publish               # uploads the newest file in dist/
    apsi publish dist/my-physics-1.0.0.apsil --token apsi_…
    

In continuous integration, set APSI_TOKEN (and APSI_REGISTRY) as secret environment variables instead of storing them.

Rules enforced by the registry:

  • Files larger than 64 MB are uploaded automatically in resumable 32 MB pieces, so libraries of any size get through proxies that limit request sizes; an interrupted upload continues where it stopped.
  • A version can be published once and never replaced. Publish a new version to fix a mistake.
  • Only the owner can publish new versions of a library. Names that differ only in - and _ are the same name.
  • A broken version can be yanked: new installations skip it, while lock files that already name it keep working.

The .apsil format

An .apsil file is a ZIP archive (format version 1):

apsil.json        manifest
src/…             the library's source files
README.md, LICENSE, examples/, data/ …

apsil.json holds format ("apsil"), format_version, name, version, summary, authors, license, homepage, repository, keywords, apsi (supported Apsi versions), entry, dependencies, built_with, and files — the path, size and SHA-256 of every other file in the archive.

Registry API

The registry speaks a small JSON API, so other tools can use it too:

Request Answer
GET /api/v1/packages/NAME name, summary, owner, latest, downloads, and every version with size, SHA-256, publish time and download URL
GET /api/v1/packages/NAME/VERSION one version including its manifest
GET /api/v1/packages/NAME/VERSION/download the file (supports Range)
GET /api/v1/search?q=WORDS matching libraries
POST /api/v1/upload multipart form with file, name, version, sha256 — or JSON {"upload_id": …} after a chunked upload; header Authorization: Bearer TOKEN
POST /api/v1/uploads · PUT /api/v1/uploads/ID · GET /api/v1/uploads/ID resumable chunked upload: create with {"purpose": "library", "size", "sha256"}, send pieces with Content-Range: bytes START-END/TOTAL, ask how much arrived
POST /api/v1/packages/NAME/VERSION/yank JSON {"yanked": true} or false; needs the yank permission

Python packages

apsi pkg (described in Interop) manages Python packages used through use python. It is separate from Apsi libraries.

Found a mistake? Report it · Markdown source