Skip to main content

No project description provided

Project description

Is Python an interpreted or compiled language? Trick question. It’s actually both. With tools like Cython, we can take the compilation step further and remove the interpreter loop almost entirely. Cython produces binaries much like C++, Go, and Rust do. Now with GitHub Actions the cross-platform build and release process can be automated for free for Open Source projects. This is an enormous opportunity to make the Python ecosystem 20-50% faster with a single pull request. This lightning talk walks through a GitHub workflow that publishes Cython-optimized wheels to PyPI. Discover how Cython can turbo-charge your Python code and GitHub Actions can simplify your cross-platform release process for free.

SF Python Holiday Party 2019

Is Python interpreted or compiled?

.
.
.
?
.
.
.
?
.
.
.
?

c2f.py

"Celsius to Fahrenheit Library"

def convert(celsius: float) -> float:
    "Convert Celsius to Fahrenheit"
    fahrenheit = celsius * 1.8 + 32
    return fahrenheit

c2f.cpython-38.pyc

>>> import c2f
>>> dis.dis(c2f.convert)
  6           0 LOAD_FAST                0 (celsius)
              2 LOAD_CONST               1 (1.8)
              4 BINARY_MULTIPLY
              6 LOAD_CONST               2 (32)
              8 BINARY_ADD
             10 STORE_FAST               1 (fahrenheit)
  7          12 LOAD_FAST                1 (fahrenheit)
             14 RETURN_VALUE

setup.py

from setuptools import setup
from Cython.Build import cythonize

setup(
    name='c2f',
    version='0.0.0',
    py_modules=['c2f'],
    ext_modules=cythonize('c2f.py'),
)

c2f.c

$ cython c2f.py
static PyObject * __pyx_convert(double __pyx_v_celsius)
{
  double __pyx_v_fahrenheit;
  PyObject *__pyx_r = NULL;
  __pyx_v_fahrenheit = ((__pyx_v_celsius * 1.8) + 32.0);
  __pyx_r = PyFloat_FromDouble(__pyx_v_fahrenheit);
  return __pyx_r;
}

c2f.so

$ python setup.py bdist_wheel
___pyx_convert:
push   rbp
mov    rbp, rsp
sub    rsp, 16
movsd  xmm0, qword ptr [rbp - 8]
mulsd  xmm0, qword ptr [rip + 1379]
addsd  xmm0, qword ptr [rip + 1379]
call   502 <PyFloat_FromDouble ...>
add    rsp, 16
pop    rbp
ret

.github/workflows/release.yml

name: release
on:
  push:
    tags:
      - v*
jobs:
  build-linux-cp38:
    runs-on: ubuntu-latest
    container: quay.io/pypa/manylinux2014_x86_64
    steps:
    ...

Matrix Build

build-macos:
  runs-on: macos-latest
  strategy:
    max-parallel: 4
    matrix:
      python-version: [3.5, 3.6, 3.7, 3.8]
  steps:
  ...

Mac Build Steps

- name: Set up Python ${{ matrix.python-version }} x64
  uses: actions/setup-python@v1
  with:
    python-version: ${{ matrix.python-version }}
    architecture: x64

- name: Install package dependencies
  run: pip install cython wheel

- name: Build binary wheel
  run: python setup.py bdist_wheel

Linux auditwheel Tool

- name: Build binary wheel
  run: /opt/python/cp38-cp38/bin/python setup.py bdist_wheel

- name: Apply auditwheel for manylinux wheel
  run: auditwheel repair -w dist dist/*

- name: Remove linux wheel
  run: rm dist/*-linux_x86_64.whl

Windows Build Steps

- name: Download Build Tools for Visual Studio 2019
  run: Invoke-WebRequest -Uri https://aka.ms/vs/16/rel...

- name: Run vs_buildtools.exe install
  run: ./vs_buildtools.exe --quiet --wait --norestart ...

Store Build Artifacts

- name: Archive dist artifacts
  uses: actions/upload-artifact@v1
  with:
    name: dist-macos-${{ matrix.python-version }}
    path: dist

Source Distribution

upload:
  needs: [build-linux-cp35, ...]
  runs-on: ubuntu-latest
  steps:
  ...
  - name: Install dependencies
    run: pip install -r requirements.txt

  - name: Create source dist
    run: python setup.py sdist

Stage Binary Wheels

- name: Stage linux 3.8
  uses: actions/download-artifact@v1
  with:
    name: dist-linux-3.8
- run: mv -v dist-linux-3.8/* dist/

- name: Stage macos 3.8
  uses: actions/download-artifact@v1
  with:
    name: dist-macos-3.8
- run: mv -v dist-macos-3.8/* dist/
...

Upload with Twine

- name: Upload with twine
  env:
    TWINE_USERNAME: ${{ secrets.TWINE_USERNAME }}
    TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }}
  run: |
    ls -l dist/*
    pip install twine
    twine upload dist/*

Cythonize all the Things!

PLEASE STEAL THE CODE!

Cythonize all the Things!

Cythonize all the Things!

Cythonize all the Things!

Cythonize all the Things!

Cythonize all the Things!

Cythonize all the Things!

Appendix

Dumping Assembly

$ gcc -g -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing -I/Library/Frameworks/Python.framework/Versions/3.8/include/python3.8 -L/Library/Frameworks/Python.framework/Versions/3.8/lib -o c2f.so c2f.c -lpython3.8
$ objdump -S -df=___pyx_pw_3c2f_1convert c2f.so

Git Tagging

$ git tag -a v0.0.2 -m v0.0.2
$ git push
$ git push --tags

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

c2f-1.0.5.tar.gz (28.5 kB view details)

Uploaded Source

Built Distributions

c2f-1.0.5-cp38-cp38-win_amd64.whl (16.7 kB view details)

Uploaded CPython 3.8 Windows x86-64

c2f-1.0.5-cp38-cp38-manylinux2014_x86_64.whl (49.3 kB view details)

Uploaded CPython 3.8

c2f-1.0.5-cp38-cp38-manylinux1_x86_64.whl (49.3 kB view details)

Uploaded CPython 3.8

c2f-1.0.5-cp38-cp38-macosx_10_13_x86_64.whl (13.8 kB view details)

Uploaded CPython 3.8 macOS 10.13+ x86-64

c2f-1.0.5-cp37-cp37m-win_amd64.whl (16.6 kB view details)

Uploaded CPython 3.7m Windows x86-64

c2f-1.0.5-cp37-cp37m-manylinux2014_x86_64.whl (47.1 kB view details)

Uploaded CPython 3.7m

c2f-1.0.5-cp37-cp37m-manylinux1_x86_64.whl (47.1 kB view details)

Uploaded CPython 3.7m

c2f-1.0.5-cp37-cp37m-macosx_10_13_x86_64.whl (13.7 kB view details)

Uploaded CPython 3.7m macOS 10.13+ x86-64

c2f-1.0.5-cp36-cp36m-win_amd64.whl (16.5 kB view details)

Uploaded CPython 3.6m Windows x86-64

c2f-1.0.5-cp36-cp36m-manylinux2014_x86_64.whl (46.1 kB view details)

Uploaded CPython 3.6m

c2f-1.0.5-cp36-cp36m-manylinux1_x86_64.whl (46.1 kB view details)

Uploaded CPython 3.6m

c2f-1.0.5-cp36-cp36m-macosx_10_13_x86_64.whl (13.6 kB view details)

Uploaded CPython 3.6m macOS 10.13+ x86-64

c2f-1.0.5-cp35-cp35m-manylinux2014_x86_64.whl (45.4 kB view details)

Uploaded CPython 3.5m

c2f-1.0.5-cp35-cp35m-manylinux1_x86_64.whl (45.4 kB view details)

Uploaded CPython 3.5m

c2f-1.0.5-cp35-cp35m-macosx_10_13_x86_64.whl (13.5 kB view details)

Uploaded CPython 3.5m macOS 10.13+ x86-64

File details

Details for the file c2f-1.0.5.tar.gz.

File metadata

  • Download URL: c2f-1.0.5.tar.gz
  • Upload date:
  • Size: 28.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.40.1 CPython/3.8.0

File hashes

Hashes for c2f-1.0.5.tar.gz
Algorithm Hash digest
SHA256 32a37e81f9011eda171b1e18efcff6f71a87642ce73f9cdae1e8ad885df2d24b
MD5 419e2aebfb117470ec3c104dedc544a9
BLAKE2b-256 38a40e62e09b7caeb357e7f0a752a560e64f59d0b0d00f1845020a2a3fb9a3a7

See more details on using hashes here.

Provenance

File details

Details for the file c2f-1.0.5-cp38-cp38-win_amd64.whl.

File metadata

  • Download URL: c2f-1.0.5-cp38-cp38-win_amd64.whl
  • Upload date:
  • Size: 16.7 kB
  • Tags: CPython 3.8, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.40.1 CPython/3.8.0

File hashes

Hashes for c2f-1.0.5-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 8b7d71c8995a1192f494a8e45a0a523eddd869290b1933ef53d681ba68331cc3
MD5 bb6a1844a992e0cfb1a5e638c65c4df5
BLAKE2b-256 8c1997cd9261f66a6fc4a8ea65c4ca4506c4f7097fec2422c7f8e82101f8ee50

See more details on using hashes here.

Provenance

File details

Details for the file c2f-1.0.5-cp38-cp38-manylinux2014_x86_64.whl.

File metadata

  • Download URL: c2f-1.0.5-cp38-cp38-manylinux2014_x86_64.whl
  • Upload date:
  • Size: 49.3 kB
  • Tags: CPython 3.8
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.40.1 CPython/3.8.0

File hashes

Hashes for c2f-1.0.5-cp38-cp38-manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b35ae1fb5879d1afbe5b2e7bfb714edd8fc083dc5a4b02e12212f791f6fb5775
MD5 10b50506d80580ba4ecb6eeded56851f
BLAKE2b-256 78c9501ed8f49eb7ab8a6d83fdd79bd963f98ce68e2aae67958b8af9efab321d

See more details on using hashes here.

Provenance

File details

Details for the file c2f-1.0.5-cp38-cp38-manylinux1_x86_64.whl.

File metadata

  • Download URL: c2f-1.0.5-cp38-cp38-manylinux1_x86_64.whl
  • Upload date:
  • Size: 49.3 kB
  • Tags: CPython 3.8
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.40.1 CPython/3.8.0

File hashes

Hashes for c2f-1.0.5-cp38-cp38-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 af22ee0b125a11e952a5b0c4beb38608c8a6bee47c3d8ec9fce278b317c4e543
MD5 aaf8e214a8369c5839f713b7f22d4479
BLAKE2b-256 d5c6dee61af712f188f7893773e1ac37b2c256df9710dfc1c03174ed8da11913

See more details on using hashes here.

Provenance

File details

Details for the file c2f-1.0.5-cp38-cp38-macosx_10_13_x86_64.whl.

File metadata

  • Download URL: c2f-1.0.5-cp38-cp38-macosx_10_13_x86_64.whl
  • Upload date:
  • Size: 13.8 kB
  • Tags: CPython 3.8, macOS 10.13+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.40.1 CPython/3.8.0

File hashes

Hashes for c2f-1.0.5-cp38-cp38-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 592d56360ec5fa7525c8874b2a8ba3e4d91e347152be296209378e4c7e5fe75e
MD5 f589dc56dd8dfe18ac700e398cf5c0ec
BLAKE2b-256 fdceb1338deadbaadac1dab0edf5b0e5c88cf497bf8d691eba7765cbf93713ad

See more details on using hashes here.

Provenance

File details

Details for the file c2f-1.0.5-cp37-cp37m-win_amd64.whl.

File metadata

  • Download URL: c2f-1.0.5-cp37-cp37m-win_amd64.whl
  • Upload date:
  • Size: 16.6 kB
  • Tags: CPython 3.7m, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.40.1 CPython/3.8.0

File hashes

Hashes for c2f-1.0.5-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 5f007efd3d1e01fb77c5413f19532d0d2b90051d51b73f4f87bb4927c73bafaa
MD5 df976dafdcd352496aa5116a544da3f2
BLAKE2b-256 92bdfc05400a4b90ddb555bd0c0cf29795d533e8be0e9ae3edad2929beee85b2

See more details on using hashes here.

Provenance

File details

Details for the file c2f-1.0.5-cp37-cp37m-manylinux2014_x86_64.whl.

File metadata

  • Download URL: c2f-1.0.5-cp37-cp37m-manylinux2014_x86_64.whl
  • Upload date:
  • Size: 47.1 kB
  • Tags: CPython 3.7m
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.40.1 CPython/3.8.0

File hashes

Hashes for c2f-1.0.5-cp37-cp37m-manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 62fc80307d7058f1ab197cfcc0414bcaae64674e9ef86909c24900e4646e4948
MD5 a6ccd36f2e65ae0191d333ddab185b6f
BLAKE2b-256 d31f042cca0538e4ec7d174bbf3b3f7a3cc7681d1c8ba03b3cd9b11426c9f98b

See more details on using hashes here.

Provenance

File details

Details for the file c2f-1.0.5-cp37-cp37m-manylinux1_x86_64.whl.

File metadata

  • Download URL: c2f-1.0.5-cp37-cp37m-manylinux1_x86_64.whl
  • Upload date:
  • Size: 47.1 kB
  • Tags: CPython 3.7m
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.40.1 CPython/3.8.0

File hashes

Hashes for c2f-1.0.5-cp37-cp37m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 e55252cc0da11995c3ec1ed9893d49f89d21a420c5c312503d9a0b03002e4b99
MD5 e90b80376ac82a1d7f032b29437a78fc
BLAKE2b-256 3c98b241e9c4e10dea2e7c552a25eebc8b83fb2b20a4607d7c3aa7869bf1f119

See more details on using hashes here.

Provenance

File details

Details for the file c2f-1.0.5-cp37-cp37m-macosx_10_13_x86_64.whl.

File metadata

  • Download URL: c2f-1.0.5-cp37-cp37m-macosx_10_13_x86_64.whl
  • Upload date:
  • Size: 13.7 kB
  • Tags: CPython 3.7m, macOS 10.13+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.40.1 CPython/3.8.0

File hashes

Hashes for c2f-1.0.5-cp37-cp37m-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 cefd1ece181fda3dab69758f4dc479fe00c9cbb66ed0c31531b03a77d4bc5615
MD5 d3f0c3e42d012ee642b888f7d8bd51eb
BLAKE2b-256 b6754edf497ecf0023e75f477c4875311a0ac321cc4b5ecb3f80988644e03f8d

See more details on using hashes here.

Provenance

File details

Details for the file c2f-1.0.5-cp36-cp36m-win_amd64.whl.

File metadata

  • Download URL: c2f-1.0.5-cp36-cp36m-win_amd64.whl
  • Upload date:
  • Size: 16.5 kB
  • Tags: CPython 3.6m, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.40.1 CPython/3.8.0

File hashes

Hashes for c2f-1.0.5-cp36-cp36m-win_amd64.whl
Algorithm Hash digest
SHA256 921d4ec85ab00660d062169ad66907eb32f4e1ec97f3b123b87727effeb37194
MD5 6b77512af8d23097edd9f9dd02577dde
BLAKE2b-256 ec73e67420ed0dc962a2cf7f6db039ed7f1869a39b6474d0ba263bbd8e7c7350

See more details on using hashes here.

Provenance

File details

Details for the file c2f-1.0.5-cp36-cp36m-manylinux2014_x86_64.whl.

File metadata

  • Download URL: c2f-1.0.5-cp36-cp36m-manylinux2014_x86_64.whl
  • Upload date:
  • Size: 46.1 kB
  • Tags: CPython 3.6m
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.40.1 CPython/3.8.0

File hashes

Hashes for c2f-1.0.5-cp36-cp36m-manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 2d0828f6ec2325b262df735d24fe759d4468506f4afad2695cd9ca82065cab90
MD5 7431def9474b812973f84f3bd1ddc761
BLAKE2b-256 703f4a949a5ffb058039fc5c32a175ad26c8e088f5dbd04978e961eb7f5145ae

See more details on using hashes here.

Provenance

File details

Details for the file c2f-1.0.5-cp36-cp36m-manylinux1_x86_64.whl.

File metadata

  • Download URL: c2f-1.0.5-cp36-cp36m-manylinux1_x86_64.whl
  • Upload date:
  • Size: 46.1 kB
  • Tags: CPython 3.6m
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.40.1 CPython/3.8.0

File hashes

Hashes for c2f-1.0.5-cp36-cp36m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 e8107bd90fd33d505bc116f0499431969e55b7fc489bb45d2514a4931605d2c8
MD5 55bed57307c989d70fe0744cbdbdfdfb
BLAKE2b-256 b31074d162ca7b7f65e714e957a35ee1f9b0fd293fbcd87989e31e3a23103679

See more details on using hashes here.

Provenance

File details

Details for the file c2f-1.0.5-cp36-cp36m-macosx_10_13_x86_64.whl.

File metadata

  • Download URL: c2f-1.0.5-cp36-cp36m-macosx_10_13_x86_64.whl
  • Upload date:
  • Size: 13.6 kB
  • Tags: CPython 3.6m, macOS 10.13+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.40.1 CPython/3.8.0

File hashes

Hashes for c2f-1.0.5-cp36-cp36m-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 7177a2034f173efda0cad6a34353f61cb70e2a81124f60942405c0e811210d62
MD5 0e8c04aae65cdafea32d0a54c03845ac
BLAKE2b-256 6e3817f6846d92af4e00f2a38f0e03fabeb1305c6c6dd579671e0df9f4f6dd18

See more details on using hashes here.

Provenance

File details

Details for the file c2f-1.0.5-cp35-cp35m-manylinux2014_x86_64.whl.

File metadata

  • Download URL: c2f-1.0.5-cp35-cp35m-manylinux2014_x86_64.whl
  • Upload date:
  • Size: 45.4 kB
  • Tags: CPython 3.5m
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.40.1 CPython/3.8.0

File hashes

Hashes for c2f-1.0.5-cp35-cp35m-manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 55d1687e7f585f09273ad3204f6d48c36b590b1232226b22575820e4e6fbf0f8
MD5 4b001883e8b50fe85246944704b02877
BLAKE2b-256 e3586efd27bd8d6df65702c91637478d41f3fbec703da974baa6aa1c0a8d15ac

See more details on using hashes here.

Provenance

File details

Details for the file c2f-1.0.5-cp35-cp35m-manylinux1_x86_64.whl.

File metadata

  • Download URL: c2f-1.0.5-cp35-cp35m-manylinux1_x86_64.whl
  • Upload date:
  • Size: 45.4 kB
  • Tags: CPython 3.5m
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.40.1 CPython/3.8.0

File hashes

Hashes for c2f-1.0.5-cp35-cp35m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 c40c5947b8a9ae50e16191cc8281ffadfec52d901289d79fd5ec42f025b67f17
MD5 527cd3180b3906ed1ab2b773e884db29
BLAKE2b-256 0d608e3f24bb3d34ace4843a27d4dde16212e6bf89e2e9b0cdad7388823a5fcd

See more details on using hashes here.

Provenance

File details

Details for the file c2f-1.0.5-cp35-cp35m-macosx_10_13_x86_64.whl.

File metadata

  • Download URL: c2f-1.0.5-cp35-cp35m-macosx_10_13_x86_64.whl
  • Upload date:
  • Size: 13.5 kB
  • Tags: CPython 3.5m, macOS 10.13+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.40.1 CPython/3.8.0

File hashes

Hashes for c2f-1.0.5-cp35-cp35m-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 219cd3324f836703df7bb3ca89d4ea2e5b29584c03474905b34804b930de14fe
MD5 765a6967c38b6c4e2e62e0cdaa64280a
BLAKE2b-256 5db17ab342c928dc157b521bd73459aeb3ee8e698e28a30afaf6a4ff39c372bb

See more details on using hashes here.

Provenance

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page