🧠 ASFESLIB — универсальная библиотека для хакатонов и серверов ASFES
ASFESLIB — асинхронная Python-библиотека для инфраструктуры ASFES (asfes.ru).
Она объединяет всё, что нужно для быстрых серверов, API, интеграций, микросервисов, обработки данных, автоматизации и хакатонов.
⚠️ Важно: асинхронный Market API и обновлённые модули
Последние изменения:
asfeslib.utils.market_apiтеперь полностью асинхронный:safe_get,CryptoAPI,StocksAPI,ForexAPI,Market.*— вызываются только черезawait.
asfeslib.net.http.HTTPClient:- строгая проверка схем (
http:///https://), - относительные URL без
base_url→ValueError, - логи без query/fragment (не светим токены).
- строгая проверка схем (
asfeslib.core.logger.Logger:- новый аргумент
level, - нет дублирования хендлеров,
- поддержка
colorlog, аккуратный лог в файл.
- новый аргумент
asfeslib.net.mail.MailConfig:- валидатор
retry_count(1..10), rate_limit— простая защита от спама.
- валидатор
asfeslib.core.sort.async_sort:- валидирует
delay >= 0,delay < 0→ValueError.
- валидирует
- Новый пакет
asfeslib.aviation:- аэродинамика, навигация, OpenSky-клиент, мини-база аэропортов.
🚀 Основные возможности
| Модуль | Описание |
|---|---|
asfeslib.core.logger |
Цветной логгер + вывод в файл, без дублирования хендлеров |
asfeslib.core.utils |
Токены, timestamp, SHA-256, случайные строки, красивый JSON |
asfeslib.core.sort |
Набор сортировок + учебный async_sort |
asfeslib.utils.conversions |
100+ универсальных конвертаций (Length, Mass, Time, Radio, Finance, Mechanics…) |
asfeslib.utils.market_api |
Async Binance / Yahoo Finance / ER-API (кэш, ретраи, логирование) |
asfeslib.net.http |
Асинхронный HTTP-клиент с логами, retry и безопасным URL-логированием |
asfeslib.net.mail |
Асинхронная отправка писем через smtplib в asyncio + retry + rate limit |
asfeslib.databases |
Асинхронные коннекторы MongoDB, PostgreSQL, MariaDB (без логирования паролей) |
asfeslib.weather |
Полный клиент WeatherAPI (current/forecast/history/… ) |
asfeslib.aviation |
Авиационные расчёты, навигация, OpenSky-клиент, мини-база аэропортов |
📦 Установка
🔧 Режим разработчика
git clone https://github.com/alxprgs/asfeslib.git
cd asfeslib
pip install -e .
🏭 Продакшн
pip install asfeslib
🟦 1. asfeslib.core
🪵 Логгер — asfeslib.core.logger
Упрощённая обёртка над logging, безопасная к многократному созданию.
from asfeslib.core.logger import Logger
log = Logger(
name="demo",
log_to_file=True,
log_file="logs/demo.log",
level=20, # logging.INFO
)
log.info("ASFESLIB запущен!")
log.warning("Предупреждение")
log.error("Ошибка")
log.debug("Отладочная информация")
Особенности:
- Не дублирует
StreamHandler/FileHandlerпри повторном создании с тем жеname. - Если установлен
colorlog— лог в консоль будет цветным. - Параметр
log_to_file=Trueсоздаёт лог-файл с UTF-8 и простым форматированием.
Уровни можно задавать как числа logging.DEBUG / INFO / WARNING и т.д.
🧰 Утилиты — asfeslib.core.utils
from asfeslib.core import utils
utils.now_str() # "2025-11-15 13:37:00" (локальное время)
utils.gen_token(32) # безопасный hex-токен длиной 32 символа
utils.hash_text("Привет") # SHA-256 от строки (utf-8)
utils.random_string(8) # случайная a-zA-Z0-9 строка
utils.pretty_json({"a": 1, "msg": "Привет"})
Особенности:
gen_token(length: int):- гарантирует длину токена не меньше
length, - поддерживает нечётные длины (
gen_token(31)→ строка длиной 31), length <= 0→ValueError.
- гарантирует длину токена не меньше
hash_textне для паролей — только для хешей ID/логов. Для паролей нужныbcrypt/scrypt/argon2.
🔁 Сортировки — asfeslib.core.sort
from asfeslib.core import sort
import asyncio
data = [5, 3, 4, 1, 2]
print(sort.quick_sort(data))
print(sort.merge_sort(data))
print(sort.sort_builtin(data, reverse=True))
# Учебная асинхронная пузырьковая сортировка
sorted_data = asyncio.run(sort.async_sort(data, delay=0.0))
Особенности:
- Есть несколько реализаций сортировок:
bubble_sort,insertion_sort,selection_sort,merge_sort,quick_sort,heap_sort,sort_builtin. - Все поддерживают
key=иreverse=. async_sort(data, key=…, delay=0.0):- имитация сортировки с визуализацией (например, через светодиоды),
delay < 0→ValueError,delay == 0— без реальных задержек.
🟩 2. Конвертации — asfeslib.utils.conversions
Модуль содержит 100+ функций в 17 категориях:
Length— длинаMass— массаTime— времяTemperature— температураArea— площадьVolume— объёмSpeed— скоростьEnergy— энергияPressure— давлениеData— данныеAngle— углыElectricity— электричество и закон ОмаMath— проценты, средниеMechanics— сила, мощность, л.с., узлыFinance— НДС, маржа, кредитыRadio— dBm, частоты, длина волныGeophysics— давление воды, g-force и т.п.
Пример
from asfeslib.utils.conversions import Length, Radio, Finance
Length.meters_to_km(2500) # 2.5
Radio.dbm_to_mw(10) # 10.0
Finance.loan_monthly_payment(
principal=1_000_000,
annual_rate_percent=12.0,
years=20,
)
Авто-инспекция API
from asfeslib.utils.conversions import list_categories, list_functions
print(list_categories()) # ['length', 'mass', 'time', ...]
print(list_functions("length")) # ['meters_to_km', 'km_to_meters', ...]
🟧 3. Market API (async) — asfeslib.utils.market_api
Единый асинхронный API для:
- криптовалют (Binance),
- акций/ETF (Yahoo Finance),
- валют (ER-API).
⚠️ Всё
awaitable:safe_get,CryptoAPI,StocksAPI,ForexAPI,Market.*.
Быстрый пример
import asyncio
from asfeslib.utils.market_api import Market
async def main():
btc = await Market.crypto_price("BTCUSDT")
aapl = await Market.stock_price("AAPL")
eur_usd = await Market.forex_rate("EUR", "USD")
print("BTCUSDT:", btc)
print("AAPL:", aapl)
print("EUR/USD:", eur_usd)
asyncio.run(main())
OHLC
import asyncio
from asfeslib.utils.market_api import Market
async def main():
candles = await Market.crypto_ohlc("BTCUSDT", interval="1h", limit=50)
first = candles[0]
print(first["open_time"], first["open"], first["close"])
asyncio.run(main())
Особенности:
- Внутренний кэш (TTL, отключается
use_cache=Falseилиcache_ttl <= 0). - Ретраи с задержкой.
- Безопасный лог: URL в ошибках обрезается до
scheme://host/path(без query/fragment), чтобы не светить токены. - Явные исключения:
APIError— общие ошибки API/сети/формата,NotFoundError— тикер/валюта не найдены.
🟦 4. HTTP-клиент — asfeslib.net.http
Асинхронный HTTP-клиент на базе aiohttp.
import asyncio
from asfeslib.net.http import HTTPClient
async def main():
async with HTTPClient("https://api.github.com") as http:
repo = await http.get("/repos/alxprgs/asfeslib")
print(repo["full_name"])
asyncio.run(main())
Особенности:
- Поддерживаются только схемы
http://иhttps://. - Относительный URL без
base_url→ValueError. - Любая другая схема (
file://,ftp://и т.п.) →ValueError. - Авто-разбор ответа:
application/json→dict/list,text/*→str,- остальное →
bytes.
- Ретраи с backoff.
- Логирование через
logging.getLogger(__name__):- в логах URL всегда без query/fragment (
?token=...и#fragне выводятся).
- в логах URL всегда без query/fragment (
Если нужно цветное логирование, можно сконфигурировать logging через Logger из asfeslib.core.logger.
🟨 5. SMTP-почта — asfeslib.net.mail
Асинхронная обёртка над стандартным smtplib, запускаемым через asyncio.to_thread.
Особенности:
- SSL / TLS,
- несколько попыток (
retry_count,retry_delay), - простая защита от спама —
rate_limit(минимальный интервал между отправками), - вложения,
- удобные Pydantic-модели:
MailConfig,MailMessage,MailAttachment.
Пример
import asyncio
from asfeslib.net.mail import MailConfig, MailMessage, MailClient
cfg = MailConfig(
host="mail.asfes.ru",
port=465,
username="hackathon@asfes.ru",
password="***",
from_name="ASFES Mailer",
retry_count=3,
retry_delay=1.0,
rate_limit=0.0,
)
msg = MailMessage(
to=["admin@asfes.ru"],
subject="ASFESLIB test",
body="Если ты читаешь это письмо — SMTP работает!",
html=False,
)
async def main():
async with MailClient(cfg) as mail:
ok = await mail.send(msg, log=True)
print("Sent:", ok)
asyncio.run(main())
⚠️
retry_countвалидируется Pydantic: 1..10, иначеValueError.
🗃 6. Базы данных — asfeslib.databases
Поддерживаются:
- MongoDB (
motor), - PostgreSQL (
psycopg[async]), - MariaDB/MySQL (
aiomysql).
Основные функции:
asfeslib.databases.MongoDB.connect_mongoasfeslib.databases.PostgreSQL.connect_postgresasfeslib.databases.MySQL.connect_mariadb- агрегатор
asfeslib.databases.connect_database
Пример MongoDB
import asyncio
from asfeslib.databases.MongoDB import MongoConnectScheme, connect_mongo
cfg = MongoConnectScheme(
host="mongodb.asfes.ru",
port=27017,
username="user",
password="password",
db_name="hackathon_db",
)
async def main():
client, db, ok = await connect_mongo(cfg)
print("Mongo status:", ok)
asyncio.run(main())
Особенности:
- URL-ы собираются с учётом спецсимволов (
quote_plusдля логина/пароля). - Для логирования используются «безопасные» описания (
host:port/db), пароль в логах никогда не светится. - Есть
serverSelectionTimeoutMS/connect_timeout, чтобы не висеть вечно.
Агрегатор — connect_database
from asfeslib.databases import connect_database
from asfeslib.databases.MongoDB import MongoConnectScheme
cfg = MongoConnectScheme(db_name="hackathon_db")
client, db_or_conn, ok = await connect_database("mongo", cfg)
🌦 7. WeatherAPI — asfeslib.weather
Полный клиент WeatherAPI:
current— текущая погода,forecast— прогноз,history— исторические данные,future,astronomy,alerts,marine,bulk,ip/timezoneи т.д.
Пример
import asyncio
from asfeslib.weather import WeatherApiClient
async def main():
async with WeatherApiClient(api_key="YOUR_WEATHERAPI_KEY") as w:
resp = await w.current("Moscow")
print(resp.location.name, resp.current.temp_c)
asyncio.run(main())
Особенности:
- Ленивый
httpx.AsyncClient— создаётся только при первом запросе. - Внутренние
_get/_postс аккуратной типизацией. - Все конечные методы возвращают Pydantic-модели (
CurrentResponse,ForecastResponse,AlertsResponseи т.п.).
✈️ 8. Aviation — asfeslib.aviation
Набор утилит для авиационных задач:
aero— атмосфера ISA, число Маха, подъёмная сила, скорость сваливания, fuel planning.nav— Haversine-расстояние, курсы, точка назначения, ETA, ветровые поправки.api— асинхронный клиент OpenSky Network (live-трафик самолётов).data— мини-база аэропортов (несколько популярных в мире).
Базовые расчёты
from asfeslib.aviation import (
air_density_isa,
speed_of_sound,
mach_to_kmh,
kmh_to_mach,
stall_speed,
)
rho0 = air_density_isa(0) # ≈ 1.225 кг/м³
a0 = speed_of_sound(0) # ≈ 340 м/с
m = kmh_to_mach(900, altitude_m=11000)
vs = stall_speed(
weight_kg=70000,
wing_area_m2=122,
cl_max=2.0,
altitude_m=0,
)
Навигация
from asfeslib.aviation import (
haversine_distance_km,
initial_bearing_deg,
destination_point,
eta_hours,
wind_corrected_heading,
)
d = haversine_distance_km(55.75, 37.61, 59.93, 30.33) # Москва – СПб
bearing = initial_bearing_deg(55.75, 37.61, 59.93, 30.33)
lat2, lon2 = destination_point(55.0, 37.0, bearing_deg=45, distance_km=100)
eta = eta_hours(distance_km=d, ground_speed_kmh=800)
heading, gs = wind_corrected_heading(
course_deg=90,
tas_kts=120,
wind_dir_from_deg=0,
wind_speed_kts=20,
)
Аэропорты
from asfeslib.aviation import get_airport, airport_coords, runway_length_m
ap = get_airport("UUDD") # ICAO или IATA (DME)
coords = airport_coords("DME")
rw_len = runway_length_m("UUEE")
OpenSky клиент
import asyncio
from asfeslib.aviation import OpenSkyClient
async def main():
async with OpenSkyClient() as sky:
data = await sky.live_area(
min_lat=54.0, min_lon=35.0,
max_lat=57.0, max_lon=39.0, # район Москвы
)
print("Бортов в зоне:", len(data))
asyncio.run(main())
⚠️ OpenSky API публичный, без ключа, но с лимитами.
При превышении лимита может прилететь 429 — в live-тестах это корректно обрабатывается какskip.
🧪 Тесты и live-режим
Все основные модули покрыты тестами pytest.
Обычные тесты
pytest
Live-тесты
Live-тесты по умолчанию отключены, включаются маркером live:
pytest -m live
Используются:
tests/test_mail_live.pytests/test_market_live.pytests/test_weather_live_api.pytests/test_aviation_live.py
Часть из них требует переменных окружения:
# PowerShell пример
$env:ASFESLIB_SMTP_USER = "hackathon@asfes.ru"
$env:ASFESLIB_SMTP_PASSWORD = "SMTP_PASSWORD"
$env:ASFESLIB_WEATHER_API_KEY = "YOUR_WEATHERAPI_KEY"
Часть тестов может быть скипнута:
- Yahoo Finance / OpenSky → при
HTTP 429(rate limit). - WeatherAPI → если нет
ASFESLIB_WEATHER_API_KEY.
📂 Структура проекта
asfeslib/
│
├── core/
│ ├── logger.py
│ ├── utils.py
│ └── sort.py
│
├── utils/
│ ├── conversions.py
│ └── market_api.py
│
├── databases/
│ ├── MongoDB.py
│ ├── MySQL.py
│ ├── PostgreSQL.py
│ └── __init__.py
│
├── net/
│ ├── http.py
│ └── mail.py
│
├── weather/
│ ├── client.py
│ ├── models/
│ └── ...
│
├── aviation/
│ ├── __init__.py
│ ├── aero.py
│ ├── nav.py
│ ├── api.py
│ └── data.py
│
└── tests/
🛠 Использование в FastAPI
Пример подключения БД и логгера в FastAPI-приложении:
from fastapi import FastAPI
from asfeslib.core.logger import Logger
from asfeslib.databases import connect_database
from asfeslib.databases.MongoDB import MongoConnectScheme
log = Logger("api")
app = FastAPI()
@app.on_event("startup")
async def startup():
cfg = MongoConnectScheme(db_name="hackathon_db")
client, app.state.db, ok = await connect_database("mongo", cfg)
if ok:
log.info("MongoDB подключена!")
else:
log.error("Не удалось подключиться к MongoDB")
📜 Лицензия
MIT License
👤 Контакты
- 🌐 https://asfes.ru/
- 🔧 GitHub: https://github.com/alxprgs/
- ✉️ Автор: Александр
Metadata
Release files for asfeslib 0.3.1
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 | |
|---|---|---|---|---|
| asfeslib-0.3.1.tar.gz | 72.0 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| asfeslib-0.3.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 134.4 kB
Release files / asfeslib-0.3.1.tar.gz
| Download URL | asfeslib-0.3.1.tar.gz |
|---|---|
| Size | 72.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a42fb106a6fd254a1046b3d39138ebcb8e4b84d131a28fbeeec0e5a35ec83f3d
|
|
BLAKE2b-256 checksum How to use checksums |
b5bbd8abf658a3bab089af8152fce5acd59f1a86284285fbe2eede6042c79e19
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / asfeslib-0.3.1-py3-none-any.whl
| Download URL | asfeslib-0.3.1-py3-none-any.whl |
|---|---|
| Size | 62.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8c64656aef54d8a98af3cf1fc26c269a3088b4d239c6ae5aada61616f46bb6a7
|
|
BLAKE2b-256 checksum How to use checksums |
9ba961edaf73a5491a860f26ecaeda33f50d6d07cf728a0a1703f1ae8c115ae0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Security for asfeslib 0.3.1
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.