vitalwatch (Python)
VitalWatch Hub için Python raporlayıcı: sunucu
hataları, yavaş istekler, canlılık. Ayrıca sunucunun kendisini izleyen
vitalwatch-agent: web sunucusu, PHP-FPM, veritabanı,
systemd, Docker, OOM ve disk.
Bağımlılık yok. Build adımı yok. Python 3.9+.
Kardeş paketler: cestnytr/vitalwatch-laravel (Laravel), vitalwatch-node (Node),
t.js (tarayıcı, hub reposunda resources/sdk/t.js).
Kapsam — ve neden bu kadar dar
Bu paket yalnızca sunucu tarafını kapsar. Tarayıcı hataları hub'dan servis edilen
t.js ile toplanır; o dosya bilinçli olarak pakete taşınmadı — hosted olması bir
düzeltmenin dakikalar içinde tüm sitelere yayılmasını sağlıyor, paket olsaydı her
düzeltme için bütün projelerin yeniden dağıtılması gerekirdi.
Toplanmayanlar — yapılandırmayla dahi açılamaz:
IP adresi · User-Agent · istek gövdesi · query string değerleri (yalnızca yol) · oturum verisi · çerez · ham SQL literalleri
Kurulum
pip install vitalwatch
.env dosyasına — kardeş paketlerle aynı değişken isimleri:
VITALWATCH_ENABLED=true
VITALWATCH_URL=https://vitalwatch.example.com
VITALWATCH_KEY=proje-anahtari
VITALWATCH_SECRET=<panelden alınan 64 karakterlik secret>
VITALWATCH_ENV=production
Flask
from flask import Flask
from vitalwatch.flask import VitalWatchFlask
app = Flask(__name__)
VitalWatchFlask(app)
Tek satır şunları kurar: yakalanmamış istisnalar (teardown_request), 5xx ve yavaş
istekler (after_request), süreç düzeyi kancalar (sys.excepthook,
threading.excepthook) ve 8 saatlik canlılık isteği.
- Tek arıza, tek kayıt: hata veren istek yalnızca stack'li
exceptionaçar; aynı istek için ayrıcahttp_5xxgönderilmez (0.1.1+). - Kendi hata işleyiciniz varsa:
@app.errorhandler(Exception)ya daerrorhandler(500)tanımlıysa hata yine stack'iyle gelir. İşleyici 4xx dönerse gönderilmez. Eskiden bu durumda hata kayboluyor, yalnızca stack'sizhttp_5xxgeliyordu. abort(4xx)gönderilmez: bilinçli yanıt, arıza değil.- Kurulum sırası serbest:
VitalWatchFlask(app)önce,vitalwatch.init(...)sonra çağrılabilir; istek kancaları da süreç kancaları da (sys.excepthook,threading.excepthook) güncel raporlayıcıyı çağrı anında çözer. Kurulumda yapılandırma yoksa canlılıkinit(...)çağrılınca başlar. - İki kez kurmak zararsız: aynı uygulamada ikinci
VitalWatchFlask(app)hiçbir şey eklemez; süreç kancaları süreç başına bir kez kurulur. - Uygulamayı düşürmez: kurulum (bozuk ya da UTF-8 olmayan
.envdahil) hiçbir koşulda hata fırlatmaz. - Süreç kancalarını kapatmak:
VitalWatchFlask(app, hook_process_errors=False)yalnızca istek kancalarını kurar.
Django
# settings.py
MIDDLEWARE = [
"vitalwatch.django.VitalWatchMiddleware", # listenin başına yakın
# ...
]
Ara katman yavaş ve 5xx istekleri ölçer, yakalanmamış istisnayı stack'iyle gönderir.
Hata iki yoldan görülür: Django'nun istisnayı 500'e çevirirken yolladığı
got_request_exception sinyali (görünümün yanında alttaki ara katmanlardan çıkan
hatalar da) ve process_exception. Kurallar Flask'la aynı:
- Tek arıza, tek kayıt; hata veren istek için ayrıca
http_5xxaçılmaz. - 4xx gönderilmez:
Http404,PermissionDenied,BadRequest,SuspiciousOperation. - Rota deseni gider:
/urun/<int:urun_id>/, gerçek id değil.re_pathdesenlerinde baştaki^ve sondaki$atılır. - Hata yutulmaz:
process_exceptionNonedöner; Django'nun 500 sayfası vehandler500olduğu gibi çalışır. - Süreç kancaları ilk kurulumda bir kez açılır; kapatmak için
VITALWATCH_HOOK_PROCESS = False.
FastAPI / Starlette (ASGI)
from fastapi import FastAPI
from vitalwatch.asgi import VitalWatchASGIMiddleware
app = FastAPI()
app.add_middleware(VitalWatchASGIMiddleware)
Starlette'te aynı satır (Starlette(middleware=[Middleware(VitalWatchASGIMiddleware)]) de
olur). Başka bir ASGI uygulaması doğrudan sarılabilir: app = VitalWatchASGIMiddleware(app).
Saf ASGI ara katmanıdır; Starlette/FastAPI import anında yüklenmez.
- Tek arıza, tek kayıt; 4xx
HTTPExceptionve doğrulama hataları (422) gönderilmez. BilinçliHTTPException(5xx)stack'sizhttp_5xxolarak düşer. - Rota deseni gider:
/urun/{urun_id};include_routeröneki veMountyolu desene eklenir. - Kendi hata işleyiciniz varsa:
@app.exception_handler(Exception)hatayı yine bizim katmanımızdan geçirir. Belirli bir sınıfa bağlı işleyici (@app.exception_handler(ValueError)) 5xx dönerse hata yine stack'iyle gelir, 4xx dönerse gönderilmez. Ara katman sırası fark etmez (add_middlewareya damiddleware=[...]içinde herhangi bir yer). Elle sarılan uygulamada (VitalWatchASGIMiddleware(app)) Starlette yığınını ilk istekte kurduğu için bu ilk istekten sonra devreye girer; o ilk istekte 5xx stack'sizhttp_5xxolur. - Süre yanıtın son baytında durur:
BackgroundTasksve yanıt sonrası işler yavaş istek sayılmaz. Uzun akış (SSE, büyük indirme) son parçaya kadar sürer ve yavaş sayılabilir. - İç içe katman tek kayıt açar:
Mountedilen alt uygulamada daVitalWatchASGIMiddlewarevarsa istek yalnızca dıştakinde ölçülür. - Hata yutulmaz: raporlanır ve yeniden fırlatılır; lifespan ve websocket olduğu gibi geçer.
- Süreç kancalarını kapatmak:
app.add_middleware(VitalWatchASGIMiddleware, hook_process_errors=False).
Çerçevesiz
import vitalwatch
vitalwatch.hook_process() # kancalar + canlılık
vitalwatch.report(error) # elle bildirim
vitalwatch.init(ignore=(KeyboardInterrupt, "BenimBeklenenHatam")) # sınıf ya da ad
vitalwatch.start_heartbeat() # yalnızca canlılık (hook_process zaten başlatır)
vitalwatch.stop_heartbeat()
init() ortam değişkenlerini okur; verilen argümanlar onları ezer. Çağrılmazsa ilk
kullanımda kendiliğinden kurulur.
Kurulumu doğrulayın
vitalwatch-status
Bu adım atlanmamalı. Paketin en pahalı arıza biçimi sessiz çalışmamadır: secret
eksik kopyalanmışsa hiçbir şey patlamaz, hiçbir log düşmez — hub geçersiz imzaya da
204 döner. Kurulum aylarca çalışmıyor olabilir ve o sessizlik "sorun yok" sanılır.
vitalwatch-status --test # gerçek bir sınama olayı — panelde hata olarak görünür
vitalwatch-status --vitalwatch # yalnızca canlılık isteği — panele hata düşürmez
--test tek bir kurulumu doğrularken doğru seçim. Onlarca kurulumu gezen bir
güncelleme döngüsünde --vitalwatch kullanılır — --test orada panele onlarca sahte hata
bırakır, yani izleme aracı kendi gürültüsünü üretir.
Verinin gerçekten ulaştığı yalnızca hub panelinden doğrulanır: proje satırındaki
bağlantı durumu Bağlı görünmelidir. Komut bunu kendi başına söyleyemez, çünkü hub
geçerli ile geçersiz imzayı dışarıya aynı yanıtla karşılar.
Komut ayrıca şunları gösterir:
Sürüm etiketi— olaylara eklenecekreleaseve nereden bulunduğu:abc123def456 (kaynak: .git); kaynakVITALWATCH_RELEASE, bir CI/PaaS değişkeninin adı,.gitya dayok. Ayrıntı: Sürüm etiketi.Güncel sürüm— PyPI'daki en yeni kararlı sürüm (info.version). Kurulu sürümden yeniyse birGüncelleme var: pip install -U vitalwatchsatırı yazılır; bu bir uyarıdır, çıkış kodunu değiştirmez. Ağ yoksa ya da PyPI yanıt vermezsedenetlenemediyazar (2 sn zaman aşımı). Ağa hiç çıkılmaması içinVITALWATCH_STATUS_OFFLINE=1(1,true,yes,on,evet; büyük/küçük harf fark etmez) — o durumdaGüncel sürümsatırı hiç yazılmaz.
Yapılandırma
| Değişken | Varsayılan | Açıklama |
|---|---|---|
VITALWATCH_ENABLED |
true |
false iken hiçbir veri gönderilmez |
VITALWATCH_URL |
— | Hub adresi (https) |
VITALWATCH_KEY |
— | Proje anahtarı |
VITALWATCH_SECRET |
— | 64 karakterlik imza secret'i |
VITALWATCH_ENV |
APP_ENV |
production · staging · local. Takma adlar çevrilir: prod/live → production, stage/stg/preprod/uat → staging, dev/development/test/testing → local. Tanınmayan değeri hub reddeder; teşhis komutu hata verir |
VITALWATCH_RELEASE |
kendiliğinden | Sürüm etiketi. Boşsa CI/PaaS commit değişkenlerinden ya da .git'ten bulunur — aşağıya bakın |
VITALWATCH_STATUS_OFFLINE |
— | 1/true/yes/on/evet iken vitalwatch-status güncelleme denetimi için ağa çıkmaz |
VITALWATCH_TIMEOUT |
2.0 |
Gönderim zaman aşımı, saniye. 100 ve üstü milisaniye sayılır — Node aynı adla ms bekliyor, 2000 yazan 2000 saniye beklemesin. Geçersiz, sıfır/eksi, NaN ya da sonsuz → 2 sn; sonuç 0.1–10 sn aralığına sıkıştırılır |
VITALWATCH_SLOW_REQUEST_MS |
1000 |
Yavaş istek eşiği |
Ortam değişkenleri os.environ ve .env / .env.local / .env.<APP_ENV>
dosyalarından okunur; süreç ortamı her zaman kazanır. Yalnızca VITALWATCH_ önekli
anahtarlar okunur.
Sürüm etiketi (release)
VITALWATCH_RELEASE neredeyse hiçbir kurulumda doldurulmuyordu; hub bu yüzden bir hatanın
hangi deploy ile başladığını söyleyemiyordu. Deploy'larımız çoğunlukla sunucuda
git pull + gunicorn yeniden başlatma: yeni süreç açılışta commit'i kendisi okur, deploy
sonrası ilk hatada panel yeni sürümü görür. Etiket kurulumda bir kez çözülür (olay başına
değil); ilk dolu kaynak kazanır:
init(release=...)ile açıkça verilen değer.VITALWATCH_RELEASE— kırpılır, en çok 64 karakter, olduğu gibi.- Sırasıyla
GIT_COMMIT,GIT_SHA,COMMIT_SHA,SOURCE_VERSION,VERCEL_GIT_COMMIT_SHA,RENDER_GIT_COMMIT,HEROKU_SLUG_COMMIT,CI_COMMIT_SHA. 7–40 hane hex ise küçük harfle ilk 12 hane; değilse kırpılmış, en çok 64 karakter. - Çalışma dizinindeki git checkout'u:
.git/HEAD→ dal ref dosyası, yoksapacked-refs; ayrık HEAD'de sha'nın kendisi..gitbir dosyaysa (submodule vb.)gitdir:izlenir. Yalnızca geçerli 40 hane sha, küçük harfle ilk 12 hane.gitkomutu çalıştırılmaz, dosyalar okunur; okunamazsa sessizce vazgeçilir.ref:yalnızcarefs/altını gösterebilir,..içeremez. Git worktree'leri (commondir) desteklenmez — dal ref'i ortak dizinde durur ve bulunamaz; oradaVITALWATCH_RELEASEkullanın. - Hiçbiri yoksa etiket gönderilmez.
Kural Node ve Laravel paketleriyle aynı. Gunicorn'un çalışma dizini uygulama kökü
değilse (--chdir yoksa) 4. adım bir şey bulamaz; vitalwatch-status aynı dizinden
çalıştırılınca bunu kaynak: yok olarak gösterir.
Neler raporlanır
| Tür | Ne zaman |
|---|---|
exception |
Yakalanmamış istisna, report() çağrısı |
fatal |
MemoryError, RecursionError, SystemError — yorumlayıcının sınırına çarpmak |
http_5xx |
Yanıt kodu ≥ 500 |
slow_request |
Süre ≥ VITALWATCH_SLOW_REQUEST_MS |
Başarılı ve hızlı istekler raporlanmaz: her isteği göndermek izlenen uygulamaya da hub'a da yük olurdu.
Sunucu ajanı (vitalwatch-agent)
SDK uygulamanın içinden bakar. Uygulamanın dışında kalan arızalar — nginx'in
502/504'ü, PHP-FPM'in pm.max_children sınırı, PostgreSQL FATAL, düşen bir systemd
servisi, sürekli yeniden başlayan bir Docker konteyneri, OOM killer, dolan disk — ancak
sunucudan görülür. vitalwatch-agent sunucuda servis olarak çalışır, bunları izler ve
hata olayı olarak hub'ın sunucu ucuna gönderir. Dil bağımsızdır: .NET, Go ya da statik
site — sunucuda ne çalışıyorsa onun web sunucusu, veritabanı ve servis yöneticisi izlenir.
Aynı paketle gelir; bağımlılık yok. Önerilen: her sunucu için hub'da ayrı bir proje
(ör. vps-ornek), beyanı agent.
Kurulum
sudo python3 -m venv /opt/vitalwatch
sudo /opt/vitalwatch/bin/pip install vitalwatch
sudo ln -s /opt/vitalwatch/bin/vitalwatch-agent /usr/local/bin/vitalwatch-agent
sudo install -d -m 700 /etc/vitalwatch
sudo nano /etc/vitalwatch/agent.ini # aşağıdaki örnek
sudo chmod 600 /etc/vitalwatch/agent.ini
sudo vitalwatch-agent check # kaynaklar ve yapılandırma
sudo vitalwatch-agent check --test # panele bir sınama olayı düşürür
sudo sh -c 'vitalwatch-agent systemd > /etc/systemd/system/vitalwatch-agent.service'
sudo systemctl daemon-reload && sudo systemctl enable --now vitalwatch-agent
Sanal ortam /opt altında olmalı: ProtectHome=yes ev dizinlerini, PrivateTmp=yes
/tmp'yi servisten gizler. systemd komutu çalışan kurulumun yorumlayıcı yolunu yazar;
yol ev dizinindeyse ya da /tmp altındaysa ilgili korumayı gevşetip yorum satırıyla
belirtir.
/etc/vitalwatch/agent.ini
[hub]
url = https://vitalwatch.example.com
key = vps-anahtari
secret = <panelden alınan 64 karakter>
env = production
[sources]
# hepsi varsayılan "auto": varsa ve okunabiliyorsa açık. "on": yoksa check hata verir.
nginx = auto
apache = auto
plesk = auto
php_fpm = auto
postgresql = auto
mysql = auto
mongodb = auto
redis = auto
journal = auto
systemd = auto
docker = auto
disk = auto
journal_errors = off ; tüm err seviyesi journald satırları (gürültülü)
docker_logs = ; logu izlenecek konteyner adları, virgülle
[disk]
threshold = 90
[ignore]
hosts = ; hub'ın kendi host'u her zaman eklenir
patterns = ; satır başına bir düzenli ifade; ham satır eşleşirse atılır
[log:plesk-panel]
path = /var/log/plesk/panel.log
pattern = \b(ERR|CRIT|ALERT|EMERG)\b
kind = log_error
Yol sırası: --config → VITALWATCH_AGENT_CONFIG → /etc/vitalwatch/agent.ini.
VITALWATCH_URL, VITALWATCH_KEY, VITALWATCH_SECRET, VITALWATCH_ENV ve
VITALWATCH_ENABLED ortam değişkenleri [hub]'ı ezer. Ajan .env dosyası okumaz:
check bir proje dizininde çalıştırılınca o projenin anahtarını almasın. Satır sonu
yorumu yalnızca ; (düzenli ifadelerde # geçebilir). Durum dosyası
/var/lib/vitalwatch-agent/state.json (VITALWATCH_AGENT_STATE_DIR ile değişir).
Komutlar
| Komut | Ne yapar |
|---|---|
vitalwatch-agent run |
Servis olarak çalışır. SIGTERM'de alt süreçleri kapatır, kuyruğu son kez gönderir, durumu kaydeder |
vitalwatch-agent check |
Her kaynağı bulundu / bulunamadı / okunamıyor / kapalı olarak listeler; hub yapılandırmasını denetler (secret 64 karakter, https, ortam adı) |
vitalwatch-agent check --test |
Ek olarak bir log_error sınama olayı gönderir ve HTTP durumunu olduğu gibi yazar |
vitalwatch-agent systemd |
Sertleştirilmiş birim dosyasını yazdırır: root, ProtectSystem=strict, ReadWritePaths=/var/lib/vitalwatch-agent, NoNewPrivileges, ProtectHome, PrivateTmp, Restart=always |
Servis root çalışır, çünkü Plesk vhost logları ve Docker soketi başka türlü okunamıyor.
Ajan durum dosyası dışında hiçbir yere yazmaz; yalnızca journalctl, systemctl --failed,
docker events ve docker logs komutlarını okumak için çalıştırır. journalctl ya da
docker yoksa veya izin yoksa stderr'e tek bir uyarı yazar ve çalışmaya devam eder.
Ne toplanır
| Tür | Kaynak | Örnek |
|---|---|---|
web_server |
/var/log/nginx/*error*.log, /var/log/apache2/*error*.log, /var/log/httpd/*error*, Plesk /var/www/vhosts/system/*/logs/{error_log,proxy_error_log} |
[ornek.com] upstream timed out … while reading response header from upstream (+ route: GET /api/x, status: 504) |
php_fpm |
/var/log/php*-fpm.log, /var/log/php-fpm/*.log, /opt/plesk/php/*/var/log/php-fpm.log |
[pool www] server reached pm.max_children setting (5), consider raising it |
database |
/var/log/postgresql/*.log, /var/log/mysql/error.log, /var/log/mariadb/*.log, /var/log/mysqld.log, /var/log/mongodb/mongod.log, /var/log/redis/*.log |
FATAL: remaining connection slots are reserved … |
service_failed |
journald + 5 dakikada bir systemctl --failed |
php8.4-fpm.service: Failed with result 'exit-code' |
container_failed |
docker events |
api: exited with code 137, api: restart loop (3 in 10 min), api: unhealthy, api: killed by OOM |
oom |
journald (çekirdek, systemd-oomd) | Out of memory: Killed process <n> (php-fpm8.4) |
kernel |
journald (çekirdek) | php-fpm8.4[<n>]: segfault in libc.so.6, disk G/Ç hataları |
disk_full |
/proc/mounts'taki gerçek dosya sistemleri |
/var: disk 93% full, /: inodes 91% used — bağlama noktası başına saatte en fazla bir |
log_error |
[log:<ad>] bölümleri, docker_logs, journal_errors = on |
desen eşleşen satır |
- Her log ilk görüldüğünde sonundan okunur; geçmiş içe aktarılmaz. Konumlar (inode + ofset) ve journald imleci durum dosyasında tutulur; log döndürme ve kırpılma algılanır. Glob'lar dakikada bir yeniden taranır: Plesk'te yeni açılan site yeniden başlatma gerektirmeden izlenir.
- Gürültü elenir: 404'lerin
open() … failed'ı, TLS el sıkışma hataları,[warn], PHP uyarıları (yalnızcaFatal error/Parse errorgelir), uygulama düzeyi SQL hataları (SDK'nın işi),docker stop'un ürettiği çıkış kodları. - Aynı mesaj dakikada en fazla 20, toplam dakikada en fazla 300 olay. Gönderim 5 sn'de bir ya da 25 olayda; gövde 8 KB ve istek başına 8 olaya bölünür. Hub erişilemezse en fazla 1000 olay bekletilir ve üstel geri çekilmeyle yeniden denenir.
- 5 dakikada bir canlılık isteği (
{"events": [], "runtime": "agent", …}): ajan durursa projenin sunucu kanalı susar ve hub'ın kurulum sağlığı bunu gösterir. - Hub'ın kendi alan adı (
url'in host'u) her zaman yok sayılır: hub aynı sunucudaysa kendi hatası ajanı, ajanın gönderimi yeni hatayı tetiklemesin.
Bilinçli olarak toplanmayanlar
- IP adresleri — her satırda
[ip]olur; nginx'inclient:alanı tamamen silinir. - Query string ve fragment — istek satırından, URL'lerden ve yollardan atılır;
routeyalnızcaGET /yoltaşır. referrer/referervehostbaşlıkları — tamamen silinir. Site adı istemcinin yazdığıhost'tan değil, yapılandırmadakiserver_name'den ya da Plesk yolundan alınır.- Ardından SDK'nın maskesi: e-posta, kart, telefon, TC kimlik, IBAN, uzun jetonlar;
veritabanı mesajlarındaki tırnaklı değerler
?olur. - SSH / kimlik doğrulama logları (her satır IP taşır, IP'siz hâli anlamsız),
erişim logları (
access.log— hata değil trafik; ziyaret modülü zaten var), posta logları (alıcı adresleri) hiç okunmaz.journal_errors = onmodunda dasshd,sudo,postfix,dovecotgibi kaynaklar atlanır. - CPU/RAM/disk grafiği, sürekli metrik ve süreç listesi yoktur: yalnızca eşik aşıldığında tek olay.
Davranış garantileri
- Hata yutulmaz. Handler zinciri korunur,
raiseengellenmez. - Süreç yönetimine karışılmaz.
sys.exitçağrılmaz, mevcutexcepthookzincirlenir. - Kendi hatasını raporlamaz. Tüm SDK kodu
try/exceptile sarılır. - Kullanıcı isteğini bekletmez. Gönderim arka plan thread'inden, kısa zaman aşımıyla.
- Hub erişilemezse sessizce vazgeçilir.
VITALWATCH_ENABLED=falseiken hiçbir veri gönderilmez.
Güncelleme ve sürümleme
Paket PyPI'dadır: pip install -U vitalwatch en yeni kararlı sürümü kurar. Sürüm
sabitlenmezse kurulan her zaman son yayındır; karşılığında bir kural zorunlu hâle
gelir — her yayında sürüm numarası yükseltilmelidir. pip, numarası kuruluyla aynı
olan paketi yeniden kurmaz; PyPI aynı numarayla ikinci yüklemeyi zaten reddeder.
Numara yükseltilmeden yapılan bir düzeltme kurulu projelere hiç ulaşmaz ve bu
sessizce olur — paketin bütün tasarımının karşı durduğu arıza biçimi.
Sürüm çıkarma sırası:
pyproject.tomliçindekiversionvesrc/vitalwatch/reporter.pyiçindekiSDK_VERSIONbirlikte yükseltilir. İkisi ayrışırsa panelde yanlış SDK sürümü görünür.CHANGELOG.md'ye giriş.python -m pytest -q- Commit,
git tag vX.Y.Z,git push origin vX.Y.Z. Etiketpublishiş akışını tetikler: testler geçerse ve etiket paket sürümüyle eşleşirse PyPI'ye yüklenir. - Kurulu projelerde
pip install -U vitalwatch, ardındanvitalwatch-statusile doğrulama. Panelde SDK sürümünün yenilendiği görülmelidir. Sunucu ajanı için/opt/vitalwatch/bin/pip install -U vitalwatch && systemctl restart vitalwatch-agent.
Test
# Çerçeve testleri için — yoksa 53 test sessizce atlanır
pip install "Flask==3.0.0" Django fastapi starlette httpx
python -m unittest discover -s tests
Çıktıda skipped= görünüyorsa bir çerçeve kurulu değildir ve o entegrasyon
sınanmamıştır (Flask 17, Django 12, FastAPI/Starlette 24 test).
0.1.0'daki çift kayıt ve kaybolan hata tam bu yüzden fark edilmedi.
Testler hub'ın imza doğrulamasını (VerifyProjectSignature) ve gövde sınırlarını
birebir uygulayan sahte bir hub'a karşı koşar: imzanın gerçekten kabul edilip
edilmediği burada görülür, "204 aldım" demek yeterli değildir.
Metadata
Release files for vitalwatch 0.2.0
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 | |
|---|---|---|---|---|
| vitalwatch-0.2.0.tar.gz | 106.4 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| vitalwatch-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 185.3 kB
Release files / vitalwatch-0.2.0.tar.gz
| Download URL | vitalwatch-0.2.0.tar.gz |
|---|---|
| Size | 106.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
270c0d894f4f16d1eb661f7b1ba72e84377c1cfbba06f023ea4f68b183bf4e15
|
|
BLAKE2b-256 checksum How to use checksums |
67337851450fca1e70b88309b301dfdda260740739d438c32988f6cde30a3158
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|
Release files / vitalwatch-0.2.0-py3-none-any.whl
| Download URL | vitalwatch-0.2.0-py3-none-any.whl |
|---|---|
| Size | 78.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
92eede462d84bfcbd5bcf5b0dfb979ed2de4246984f25b3f7fda2c036e330040
|
|
BLAKE2b-256 checksum How to use checksums |
1998c43c5ed0e09f9c527721ab5ea9386157a23bcc44ca9b8d785ade9dca9852
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|
Security for vitalwatch 0.2.0
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.