AstraAPI framework, high performance, easy to learn, fast to code, ready for production
Project description
⚡ AstraAPI
High-Performance · Easy to Learn · Fast to Code · Ready for Production
AstraAPI is a modern, production-grade Python web framework with a C++20 hot-path core. It is inspired by and fully API-compatible with FastAPI — you get the same beautiful decorator-based routing, automatic OpenAPI docs, Pydantic v2 validation, Depends injection, and WebSocket support, while the inner engine is a compiled C++ extension that handles HTTP parsing, route matching, parameter extraction, JSON serialization, CORS, compression, and response building — with zero Python overhead on the critical path.
"AstraAPI = FastAPI's developer experience + uWebSockets' throughput + Node.js cluster's multi-worker model"
✨ Key Features
| Feature | Description |
|---|---|
| 🚀 C++20 HTTP Core | HTTP parsing, route matching, param extraction, JSON encode/decode — all in compiled C++ (_astraapi_core.so) |
| 🎯 FastAPI-Compatible API | Same decorators (@app.get, @app.post, …), Depends, Body, Query, Path, Header, Cookie, Form, File, Security |
| 🔄 Zero-Lock Multi-Worker | Each worker is a fully independent OS process with its own GIL, event loop, and memory space. Zero shared state = zero lock contention |
| 🌀 uvloop / winloop Event Loop | Uses uvloop (Linux/macOS) or winloop (Windows) instead of CPython's default asyncio loop — up to 2–4× more I/O throughput |
| 📄 Auto OpenAPI + Swagger/ReDoc | Built-in /docs (Swagger UI) and /redoc (ReDoc) — served directly from C++ pre-built byte buffers |
| ✅ Pydantic v2 Validation | Full request body validation, response model serialization, and model_dump_json — all via Pydantic v2 |
| 🛡️ Built-in Middleware | CORS, TrustedHost, GZip/Brotli compression, Rate Limiting — implemented in C++ with zero Python allocation per request |
| 🔌 WebSocket Support | RFC 6455 compliant WebSocket with C++ ring-buffer frame parsing, echo auto-detection, batch frame building, and per-connection backpressure |
| ⚙️ Lazy Imports | Heavy imports (Pydantic, OpenAPI models) are deferred until first access. Cold startup reduced from ~4.7 s → ~1–1.5 s |
| 🔁 Hot Reload | File-watching reloader (watchfiles) restarts workers on code change |
| 🧪 Test Client | Drop-in TestClient based on httpx for sync/async endpoint testing |
| 📁 Static Files + Jinja2 Templates | Plug-and-play static file serving and HTML templating |
| 🔒 Security | OAuth2, HTTP Basic/Bearer, API Key — mirrors FastAPI's security utilities |
| 🪝 Lifespan Events | on_startup / on_shutdown callbacks and async context-manager lifespan |
| 🖥️ Cross-Platform | Linux (SO_REUSEPORT + uvloop), macOS (fork + uvloop), Windows (subprocess + winloop + socket.share) |
🌟 Inspired by FastAPI
AstraAPI was directly inspired by FastAPI created by Sebastián Ramírez. Every public-facing API — decorators, dependency injection, parameter declarations, OpenAPI generation, security utilities, response models — is intentionally compatible with FastAPI so that existing FastAPI applications can be migrated with minimal changes.
# This is valid AstraAPI code — and also valid FastAPI code
from astraapi import AstraAPI, Depends
from pydantic import BaseModel
app = AstraAPI(title="My API")
class Item(BaseModel):
name: str
price: float
@app.post("/items/", response_model=Item)
async def create_item(item: Item):
return item
What AstraAPI adds on top of the FastAPI mental model:
- A compiled C++20 extension replaces the entire ASGI hot path
- A built-in multi-worker supervisor replaces Gunicorn/Uvicorn
- A uvloop/winloop event loop replaces the default asyncio loop
- Zero-allocation per-request interning for HTTP method strings, header names, status lines
📦 Installation
pip install astraapi
Note: The package ships a pre-built
_astraapi_core.so(Linux) /.pyd(Windows). To build from source:cd cpp_core && mkdir build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release make -j$(nproc) cp _astraapi_core*.so ../../astraapi/_astraapi_core.so
🚀 Quick Start
from astraapi import AstraAPI
app = AstraAPI()
@app.get("/")
async def root():
return {"message": "Hello from AstraAPI ⚡"}
# Run with built-in multi-worker server
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000, workers=4)
🔄 Complete Request Flow
The following diagram shows the full lifecycle of an HTTP request inside AstraAPI:
┌─────────────────────────────────────────────────────────────────────────────┐
│ CLIENT (Browser / HTTP Client) │
└────────────────────────────────────┬────────────────────────────────────────┘
│ TCP Connection
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ MASTER PROCESS (Supervisor / Accept Thread) │
│ │
│ ① listen_sock.accept() — single blocking accept, no thundering herd │
│ ② Round-robin dispatch — SCM_RIGHTS (Linux) / socket.share() (Windows) │
│ ③ Worker restart — crashed workers are automatically re-spawned │
└────────────┬──────────────────────────┬────────────────────────────────────┘
│ fd / shared socket │ fd / shared socket
┌──────▼──────┐ ┌───────▼──────┐
│ Worker 0 │ │ Worker 1 │ ... (N workers)
│ (Process) │ │ (Process) │
│ own GIL │ │ own GIL │
│ own loop │ │ own loop │
└──────┬──────┘ └──────────────┘
│
▼ CppHttpProtocol.data_received()
┌─────────────────────────────────────────────────────────────────────────────┐
│ C++ HTTP LAYER (_astraapi_core.so) │
│ │
│ ④ HTTP Parse — llhttp (Node.js parser, zero-copy view) │
│ ⑤ Route Match — Radix trie, O(log n), pre-compiled at startup │
│ ⑥ Param Extract — Path params, query string, headers, cookies in C++ │
│ ⑦ JSON Parse — yyjson (SIMD-accelerated, strict mode) │
│ ⑧ CORS Check — case-insensitive origin matching, zero allocation │
│ ⑨ DI Resolution — Resolve Depends graph, inject typed params in C++ │
│ ⑩ Compression — libdeflate (gzip) / Brotli, chosen by Accept-Encoding │
│ ⑪ Rate Limiting — Sharded mutex counters (16 shards), per-IP │
└──────────────┬──────────────────────────┬──────────────────────────────────┘
│ │
┌───────────▼─────────┐ ┌───────────▼─────────────┐
│ SYNC ENDPOINT │ │ ASYNC / PYDANTIC │
│ (no Python touch) │ │ ENDPOINT │
│ │ │ │
│ C++ builds full │ │ C++ returns InlineResult│
│ HTTP response and │ │ Python: await endpoint │
│ calls │ │ Pydantic validates resp │
│ transport.write() │ │ C++ serializes JSON │
└─────────────────────┘ └──────────────────────────┘
│ │
└──────────┬───────────────┘
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ RESPONSE PATH │
│ │
│ C++ build_response_from_parts() → pre-cached status lines + headers → │
│ transport.write(bytes) — single syscall, keep-alive maintained │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
CLIENT ✅
Request Flow — Step by Step
- TCP Accept — The master supervisor calls
accept()once and dispatches the file descriptor to a worker via Unix socket (SCM_RIGHTS on Linux) orsocket.share()(Windows). Workers never compete for connections. - data_received — Python's asyncio protocol (
CppHttpProtocol) receives raw bytes and calls into_astraapi_corevia a single C-extension call. - HTTP Parse — C++ uses the
llhttpparser (same as Node.js) to parse headers and body. Strings are interned (PyUnicode_InternFromString) once and reused forever. - Route Match — A compiled radix trie matches the method + path in O(log n). Routes are frozen before workers fork — shared as read-only COW pages.
- Parameter Extraction — Path params, query strings, headers, cookies extracted in C++ with zero Python dict construction for sync routes.
- Endpoint Dispatch — Sync endpoints return directly; async endpoints yield an
InlineResultcapsule back to Python whichawaits the coroutine. - Pydantic Validation — Response models call
model_dump_json()— result is passed back to C++ for final serialization. - Response Write — C++ assembles the full HTTP response from pre-cached byte fragments and calls
transport.write()— a single syscall.
🏗️ Worker Architecture
┌──────────────────────────────────────────────────────────────────────┐
│ ASTRAAPI PROCESS MODEL │
├──────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ MASTER (Supervisor Process) │ │
│ │ │ │
│ │ • listen_sock.accept() ──► round-robin dispatch │ │
│ │ • Monitors child PIDs via os.waitpid() │ │
│ │ • Auto-restarts crashed workers │ │
│ │ • Tunes sysctl (somaxconn, tcp_max_syn_backlog) │ │
│ │ • Raises fd limit (RLIMIT_NOFILE → 65535) │ │
│ └──────────┬──────────────┬────────────────┬─────────────────┘ │
│ │ │ │ │
│ SCM_RIGHTS│ socket. │ SO_REUSEPORT │ │
│ (Linux) │ share() │ (kernel does │ + ─ ─ N workers │
│ │ (Windows) │ balancing) │ │
│ ┌─────────▼──┐ ┌────────▼──┐ ┌──────────▼──┐ │
│ │ Worker 0 │ │ Worker 1 │ │ Worker N │ │
│ │ │ │ │ │ │ │
│ │ own GIL │ │ own GIL │ │ own GIL │ │
│ │ own memory │ │ own memory │ │ own memory │ │
│ │ own loop │ │ own loop │ │ own loop │ │
│ │ uvloop/ │ │ uvloop/ │ │ uvloop/ │ │
│ │ winloop │ │ winloop │ │ winloop │ │
│ │ │ │ │ │ │ │
│ │ CPU pinned │ │ CPU pinned │ │ CPU pinned │ ← sched_setaff. │
│ │ (core 0) │ │ (core 1) │ │ (core N%k) │ │
│ └────────────┘ └────────────┘ └─────────────┘ │
│ │
│ • Route table frozen before fork → shared as read-only COW pages │
│ • Zero IPC after startup (SO_REUSEPORT mode) │
└──────────────────────────────────────────────────────────────────────┘
Linux — Three Modes (Best → Fallback)
| Mode | How it works | Latency |
|---|---|---|
| SO_REUSEPORT | Each worker binds its own socket; kernel dispatches SYN packets directly — no master accept thread, no IPC | Lowest |
| Master-Accept + SCM_RIGHTS | Master calls accept(), sends fd to worker via sendmsg + SCM_RIGHTS over Unix socketpair |
Low |
| Shared socket | Single listen socket shared via socket.share() |
Moderate |
Windows
Master uses socket.share(pid) + socket.fromshare() over AF_INET socketpairs. Same round-robin guarantee, no thundering herd.
⚡ Why AstraAPI is Faster Than Uvicorn + Gunicorn
The table below compares what happens on every single request:
| Component | Uvicorn + Gunicorn | AstraAPI |
|---|---|---|
| HTTP Parsing | Python ASGI scope dict allocation (7+ keys) | C++ llhttp, zero Python dict |
| Route Matching | Python regex, dictionary lookup per route | C++ radix trie, O(log n), pre-compiled |
| Param Extraction | Python re.match() + dict construction |
C++ param_extractor, direct struct write |
| JSON Decode | Python json.loads() / orjson.loads() |
C++ yyjson SIMD parser |
| JSON Encode | Python json.dumps() / orjson.dumps() |
C++ yyjson writer, single allocation |
| CORS | Python middleware, dict lookups, .encode() calls |
C++ case-insensitive origin match, no alloc |
| GZip | Python gzip module (GIL-bound) |
C++ libdeflate (2–3× faster than zlib) |
| Brotli | Requires separate brotli middleware |
C++ Brotli native, auto-negotiated |
| Response Build | Python bytearray + string formatting |
C++ pre-cached status lines + single memcpy |
| Worker Model | Gunicorn master-accept → WSGI/ASGI overhead | Zero-lock independent processes, no arbiter GIL |
| Event Loop | Default asyncio (libuv-less) | uvloop / winloop (libuv-based, 2–4× faster I/O) |
| Startup Time | FastAPI ~4–5 s cold import | AstraAPI ~1–1.5 s (lazy imports) |
| String Interning | .encode() per request for method/headers |
Pre-interned PyUnicode_InternFromString at startup |
| Memory per request | Multiple dict + list allocations in Python | Reused C++ buffer pool (buffer_pool.cpp) |
Key Architectural Advantages
1. C++ on the hot path, Python only where needed
Sync endpoint: TCP bytes → C++ parse → C++ route → C++ params → C++ response (zero Python)
Async endpoint: TCP bytes → C++ parse → C++ route → C++ params → Python await → C++ serialize
2. Zero thundering herd
Gunicorn's default pre-fork model has all workers call accept() simultaneously, causing a kernel stampede on connection arrival. AstraAPI's master process accepts once and dispatches — workers consume from a queue with guaranteed even distribution (Node.js cluster SCHED_RR pattern).
3. Per-worker CPU affinity
os.sched_setaffinity(0, {worker_id % cpu_count})
Each worker is pinned to a dedicated CPU core, eliminating L2/L3 cache thrashing and TLB flushes caused by process migration across cores.
4. Pre-warmed buffer pool
A C++ buffer_pool pre-allocates std::vector<char> buffers at startup. Per-request allocation becomes an O(1) list pop — no malloc/free on the critical path.
5. Route table frozen and COW-shared
Before forking, app._sync_routes_to_core() freezes the radix trie. All workers inherit it as read-only copy-on-write pages — never copied, never locked.
6. Lazy imports cut startup time by 3–4×
# Heavy imports (pydantic, openapi, routing) deferred to first use
# `from astraapi import AstraAPI` → ~1-1.5s (vs ~4.7s eager)
🔌 WebSocket Architecture
Client ──WS Frame──► C++ ws_frame_parser (ring buffer, RFC 6455)
│
▼
_WsFastChannel.feed() ──► Python endpoint await
│
(echo detected?) ──YES──► _handle_ws_frames_echo_fd
│ (direct FD write, no Python)
NO
▼
Python endpoint processes frame
│
ws.send_text() / send_bytes() / send_json()
│
C++ ws_build_frame_bytes() (single allocation)
│
transport.write()
- Echo auto-detection: if an endpoint echoes received data, AstraAPI switches to a direct-fd echo handler that bypasses Python entirely
- Batch frame building: multiple sends within the same event loop tick are coalesced into a single
transport.write()via_ws_build_frames_batch - Backpressure: pauses transport reading when buffer > 256 messages or 8 MB, resumes at 64 messages / 2 MB
- WebSocket Groups: broadcast to N connections using pre-built frames (
_ws_groups.py) — frame built once, sent to all
🧩 Project Structure
astraapi/
├── __init__.py # Lazy-import gateway (startup: ~1.5s)
├── applications.py # AstraAPI class — main app entrypoint
├── routing.py # APIRouter, APIRoute, path operation decorators
├── _cpp_server.py # asyncio.Protocol bridge to C++ core
├── _multiworker.py # Zero-lock multi-worker supervisor
├── _astraapi_core.so # Compiled C++20 extension
├── _request.py # Request object
├── _response.py # Response classes (JSON, HTML, Stream, File…)
├── _routing_base.py # Base routing primitives
├── _middleware_impl.py # Middleware stack builder
├── _websocket.py # WebSocket wrapper (CppWebSocket)
├── _ws_groups.py # WebSocket group broadcast
├── param_functions.py # Body, Query, Path, Header, Cookie, Form, File, Depends, Security
├── dependencies/ # DI resolver
├── openapi/ # OpenAPI schema generation
└── security/ # OAuth2, HTTP Basic/Bearer, API Key
cpp_core/
├── src/
│ ├── app.cpp # CoreApp, HTTP handler, InlineResult
│ ├── router.cpp # Radix trie route matching
│ ├── http_parser.cpp # llhttp wrapper
│ ├── param_extractor.cpp # Path/query/header param extraction
│ ├── json_writer.cpp # yyjson-based JSON serialization
│ ├── json_parser.cpp # yyjson-based JSON parsing
│ ├── ws_frame_parser.cpp # RFC 6455 WebSocket frame parser
│ ├── ws_ring_buffer.cpp # Ring buffer for WS frames
│ ├── middleware_engine.cpp # CORS, TrustedHost in C++
│ ├── body_parser.cpp # JSON/form body parsing
│ ├── response_pipeline.cpp# Response assembly
│ └── dependency_resolver.cpp # C++ DI graph resolution
├── third_party/
│ ├── llhttp/ # Node.js HTTP parser
│ ├── yyjson/ # Fast JSON (SIMD)
│ └── ryu/ # Fast float→string (d2s)
└── CMakeLists.txt # C++20, -O3 -march=native -flto
⚙️ Configuration
app = AstraAPI(
title="My API",
version="1.0.0",
description="API description (Markdown supported)",
docs_url="/docs", # Swagger UI
redoc_url="/redoc", # ReDoc
openapi_url="/openapi.json",
root_path="/api/v1", # For reverse proxy setups
)
app.run(
host="0.0.0.0",
port=8000,
workers=4, # Number of worker processes
reload=False, # Enable hot reload (dev only)
)
📚 Dependencies
| Package | Role |
|---|---|
pydantic ≥ 2.7 |
Request/response validation and serialization |
uvloop (Linux/macOS) |
High-performance asyncio event loop |
winloop (Windows) |
High-performance asyncio event loop for Windows |
orjson |
Fast JSON fallback for Python-side serialization |
watchfiles |
File change detection for hot reload |
annotated-doc |
Rich type annotation documentation |
Optional (install via pip install astraapi[standard]):
httpx, jinja2, python-multipart, email-validator, pydantic-settings, pydantic-extra-types
🤝 Contributing
See CONTRIBUTING.md for how to set up the development environment, build the C++ core, and run the test suite.
📄 License
MIT License — see LICENSE.
Made with ⚡ by Lumos Labs HQ · Inspired by FastAPI
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file astraapi-0.1.0.tar.gz.
File metadata
- Download URL: astraapi-0.1.0.tar.gz
- Upload date:
- Size: 1.5 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b0a5f6cc7ca24bab51056aac8cfcbfbadd1ba87e87cd8dd092e738e5584539d5
|
|
| MD5 |
d12d06826f34a94a4797f9cee59ce5f8
|
|
| BLAKE2b-256 |
e1606bcd8f807d77eea8a2bc095f6dc581fe444949ffd938f9eb518de6927942
|
File details
Details for the file astraapi-0.1.0-cp313-cp313-win_amd64.whl.
File metadata
- Download URL: astraapi-0.1.0-cp313-cp313-win_amd64.whl
- Upload date:
- Size: 455.5 kB
- Tags: CPython 3.13, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9329f1cdbfdd60d5d74d3e8eb3ada962c36a88e0d9b71a1e6856ad9e1b9fdb52
|
|
| MD5 |
b97dad7a54905f340723e25850a8f0e3
|
|
| BLAKE2b-256 |
79e293ce87a0cfb15ed480dafc94e1163b7d86c3134709d119d938e870d1b18a
|
File details
Details for the file astraapi-0.1.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: astraapi-0.1.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 1.2 MB
- Tags: CPython 3.13, manylinux: glibc 2.24+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a910a46220fbf045e5779beba592f9883f43f5c86a5d45fbbc2e4debf63e47db
|
|
| MD5 |
1bd0e18d5e66dc68d900919e26386464
|
|
| BLAKE2b-256 |
6964a474cdd0385e5733a2d31f5255ad38ed5170b68a9cab911e87adc6886974
|
File details
Details for the file astraapi-0.1.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl.
File metadata
- Download URL: astraapi-0.1.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
- Upload date:
- Size: 1.2 MB
- Tags: CPython 3.13, manylinux: glibc 2.24+ ARM64, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d58f1b0cffacbd88db5370fbe01d22f00b20b3a60d191b903e1acfe2bc8db0be
|
|
| MD5 |
ec6a81e2f4e21ad007fe9ea5ee8870d7
|
|
| BLAKE2b-256 |
b802233cc0d8edbc1c9d36a33afc0233c048087a92a0a7c4cb4a7896bf196807
|
File details
Details for the file astraapi-0.1.0-cp313-cp313-macosx_14_0_arm64.whl.
File metadata
- Download URL: astraapi-0.1.0-cp313-cp313-macosx_14_0_arm64.whl
- Upload date:
- Size: 919.8 kB
- Tags: CPython 3.13, macOS 14.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ef9a3490b52770303cb0e22f01d23ce1fa7a612d24d6542bdf020979230195ae
|
|
| MD5 |
7a7e15736c32e9937a5de5b08984c48e
|
|
| BLAKE2b-256 |
9b5c45e7383245fe5e63539f776137e7708b8c270f43a3ad35673aa34f03bf2f
|
File details
Details for the file astraapi-0.1.0-cp312-cp312-win_amd64.whl.
File metadata
- Download URL: astraapi-0.1.0-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 455.6 kB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
72ab0853c22b370a424821f4b2581f33fe7f3c859f5cd81477ba7b300e7c76dd
|
|
| MD5 |
64932c6ef526db83a4af85558a35c1d0
|
|
| BLAKE2b-256 |
785f685c1d2334e39a1a046d068b0915b91acb40e859d1759315a8dbe7ee2bf6
|
File details
Details for the file astraapi-0.1.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: astraapi-0.1.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 1.2 MB
- Tags: CPython 3.12, manylinux: glibc 2.24+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8ec63c760853b791916365c489c77497219a40a8ec401c931c5c37c8b947a12f
|
|
| MD5 |
32e395dfe01909e9c85462043536d511
|
|
| BLAKE2b-256 |
20a555ce551e16bc65ddb3b728177c5fa10d2d98767a3fd4a9fc627781e73caf
|
File details
Details for the file astraapi-0.1.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl.
File metadata
- Download URL: astraapi-0.1.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
- Upload date:
- Size: 1.2 MB
- Tags: CPython 3.12, manylinux: glibc 2.24+ ARM64, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c2e0c079528ec063eed15b772b7ad46cdce4cac7a15eab84c3c98dcbb2efd2a9
|
|
| MD5 |
088a6685329c782ec3efa3757bfccb86
|
|
| BLAKE2b-256 |
e88c5ef0e8b6676b513069b8f9c82cc4ac312ba5fe47941df708ff6fdcb53559
|
File details
Details for the file astraapi-0.1.0-cp312-cp312-macosx_14_0_arm64.whl.
File metadata
- Download URL: astraapi-0.1.0-cp312-cp312-macosx_14_0_arm64.whl
- Upload date:
- Size: 919.9 kB
- Tags: CPython 3.12, macOS 14.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed65110a339548b4728a6cba9a9aee60b4477de52b9850510ce75b9037308af6
|
|
| MD5 |
ec0d9e8e4b539080128ba12ea709e8c5
|
|
| BLAKE2b-256 |
eb35bbdede20313bf4534f572f0f4adffcf9c2192884e8d88f274b4a47364f57
|