Skip to main content

A Rust HTTP server for Python applications

Project description

granian

The Rust HTTP server for Python


Granian is a Rust HTTP server for Python applications built on top of Hyper and Tokio.

Rationale

The main reasons behind Granian design are:

  • Have a single, correct HTTP implementation, supporting versions 1, 2 (and eventually 3)
  • Provide a single package for several platforms
  • Avoid the usual Gunicorn + uvicorn + http-tools dependency composition on unix systems
  • Provide stable performance when compared to existing alternatives

Adopting Granian would thus be a good choice when:

  • wanting a modern, single dependency to serve both ASGI and WSGI applications
  • looking for the most performant way to serve your Python application under HTTP/2
  • you need great concurrency capabilities, especially with websockets
  • you care about throughput more than everything else

On the other hand, Granian won't be the ideal option if:

  • you want a pure Python solution
  • you need advanced debugging features
  • your application relies on trio or gevent
  • you're looking for ASGI extensions not (yet) implemented

Features

  • Supports ASGI/3, RSGI and WSGI interface applications
  • HTTP/1 and HTTP/2 protocols
  • HTTPS and mTLS
  • Websockets
  • Direct static files serving
  • ASGI pathsend extension

Quickstart

You can install Granian using pip:

$ pip install granian

ASGI

Create an application in your main.py:

async def app(scope, receive, send):
    assert scope['type'] == 'http'

    await send({
        'type': 'http.response.start',
        'status': 200,
        'headers': [
            [b'content-type', b'text/plain'],
        ],
    })
    await send({
        'type': 'http.response.body',
        'body': b'Hello, world!',
    })

and serve it using Granian CLI:

$ granian --interface asgi main:app

RSGI

Create an application your main.py:

async def app(scope, proto):
    assert scope.proto == 'http'

    proto.response_str(
        status=200,
        headers=[
            ('content-type', 'text/plain')
        ],
        body="Hello, world!"
    )

and serve it using Granian CLI:

$ granian --interface rsgi main:app

WSGI

Create an application your main.py:

def app(environ, start_response):
    start_response('200 OK', [('content-type', 'text/plain')])
    return [b"Hello, world!"]

and serve it using Granian CLI:

$ granian --interface wsgi main:app

Extra dependencies

Mind that Granian also provides several extra dependencies you might be interested into, in particular:

  • dotenv (allows to load environment files)
  • pname (allows to customize processes' names)
  • reload (adds reload on changes functionality)
  • rloop
  • uvloop
  • winloop

You can combine the above extras to suit your needs, eg:

$ pip install granian[pname,uvloop]

For further information, check the options below.

Options

You can check all the options provided by Granian with the --help command:

$ granian --help
Usage: granian [OPTIONS] APP

  APP  Application target to serve.  [required]

Options:
  --host TEXT                     Host address to bind to  [env var:
                                  GRANIAN_HOST; default: (127.0.0.1)]
  --port INTEGER                  Port to bind to.  [env var: GRANIAN_PORT;
                                  default: 8000]
  --uds PATH                      Unix Domain Socket to bind to.  [env var:
                                  GRANIAN_UDS]
  --uds-permissions OCTAL INTEGER
                                  Unix Domain Socket file permissions  [env
                                  var: GRANIAN_UDS_PERMISSIONS]
  --interface [asgi|asginl|rsgi|wsgi]
                                  Application interface type  [env var:
                                  GRANIAN_INTERFACE; default: (rsgi)]
  --http [auto|1|2]               HTTP version  [env var: GRANIAN_HTTP;
                                  default: (auto)]
  --ws / --no-ws                  Enable websockets handling  [env var:
                                  GRANIAN_WEBSOCKETS; default: (enabled)]
  --workers INTEGER RANGE         Number of worker processes  [env var:
                                  GRANIAN_WORKERS; default: 1; x>=1]
  --blocking-threads INTEGER RANGE
                                  Number of blocking threads (per worker)
                                  [env var: GRANIAN_BLOCKING_THREADS; x>=1]
  --blocking-threads-idle-timeout DURATION
                                  The maximum amount of time in seconds (or a
                                  human-readable duration) an idle blocking
                                  thread will be kept alive  [env var:
                                  GRANIAN_BLOCKING_THREADS_IDLE_TIMEOUT;
                                  default: 30; 5<=x<=600]
  --runtime-threads INTEGER RANGE
                                  Number of runtime threads (per worker)  [env
                                  var: GRANIAN_RUNTIME_THREADS; default: 1;
                                  x>=1]
  --runtime-blocking-threads INTEGER RANGE
                                  Number of runtime I/O blocking threads (per
                                  worker)  [env var:
                                  GRANIAN_RUNTIME_BLOCKING_THREADS; x>=1]
  --runtime-mode [auto|mt|st]     Runtime mode to use (single/multi threaded)
                                  [env var: GRANIAN_RUNTIME_MODE; default:
                                  (auto)]
  --loop [auto|asyncio|rloop|uvloop|winloop]
                                  Event loop implementation  [env var:
                                  GRANIAN_LOOP; default: (auto)]
  --task-impl [asyncio|rust]      Async task implementation to use  [env var:
                                  GRANIAN_TASK_IMPL; default: (asyncio)]
  --backlog INTEGER RANGE         Maximum number of connections to hold in
                                  backlog (globally)  [env var:
                                  GRANIAN_BACKLOG; default: 1024; x>=128]
  --backpressure INTEGER RANGE    Maximum number of requests to process
                                  concurrently (per worker)  [env var:
                                  GRANIAN_BACKPRESSURE; default:
                                  (backlog/workers); x>=1]
  --http1-buffer-size INTEGER RANGE
                                  Sets the maximum buffer size for HTTP/1
                                  connections  [env var:
                                  GRANIAN_HTTP1_BUFFER_SIZE; default: 417792;
                                  x>=8192]
  --http1-header-read-timeout INTEGER RANGE
                                  Sets a timeout (in milliseconds) to read
                                  headers  [env var:
                                  GRANIAN_HTTP1_HEADER_READ_TIMEOUT; default:
                                  30000; 1<=x<=60000]
  --http1-keep-alive / --no-http1-keep-alive
                                  Enables or disables HTTP/1 keep-alive  [env
                                  var: GRANIAN_HTTP1_KEEP_ALIVE; default:
                                  (enabled)]
  --http1-pipeline-flush / --no-http1-pipeline-flush
                                  Aggregates HTTP/1 flushes to better support
                                  pipelined responses (experimental)  [env
                                  var: GRANIAN_HTTP1_PIPELINE_FLUSH; default:
                                  (disabled)]
  --http2-adaptive-window / --no-http2-adaptive-window
                                  Sets whether to use an adaptive flow control
                                  for HTTP2  [env var:
                                  GRANIAN_HTTP2_ADAPTIVE_WINDOW; default:
                                  (disabled)]
  --http2-initial-connection-window-size INTEGER RANGE
                                  Sets the max connection-level flow control
                                  for HTTP2  [env var: GRANIAN_HTTP2_INITIAL_C
                                  ONNECTION_WINDOW_SIZE; default: 1048576;
                                  x>=1024]
  --http2-initial-stream-window-size INTEGER RANGE
                                  Sets the `SETTINGS_INITIAL_WINDOW_SIZE`
                                  option for HTTP2 stream-level flow control
                                  [env var:
                                  GRANIAN_HTTP2_INITIAL_STREAM_WINDOW_SIZE;
                                  default: 1048576; x>=1024]
  --http2-keep-alive-interval INTEGER RANGE
                                  Sets an interval (in milliseconds) for HTTP2
                                  Ping frames should be sent to keep a
                                  connection alive  [env var:
                                  GRANIAN_HTTP2_KEEP_ALIVE_INTERVAL;
                                  1<=x<=60000]
  --http2-keep-alive-timeout DURATION
                                  Sets a timeout (in seconds or a human-
                                  readable duration) for receiving an
                                  acknowledgement of the HTTP2 keep-alive ping
                                  [env var: GRANIAN_HTTP2_KEEP_ALIVE_TIMEOUT;
                                  default: 20; x>=1]
  --http2-max-concurrent-streams INTEGER RANGE
                                  Sets the SETTINGS_MAX_CONCURRENT_STREAMS
                                  option for HTTP2 connections  [env var:
                                  GRANIAN_HTTP2_MAX_CONCURRENT_STREAMS;
                                  default: 200; x>=10]
  --http2-max-frame-size INTEGER RANGE
                                  Sets the maximum frame size to use for HTTP2
                                  [env var: GRANIAN_HTTP2_MAX_FRAME_SIZE;
                                  default: 16384; x>=1024]
  --http2-max-headers-size INTEGER RANGE
                                  Sets the max size of received header frames
                                  [env var: GRANIAN_HTTP2_MAX_HEADERS_SIZE;
                                  default: 16777216; x>=1]
  --http2-max-send-buffer-size INTEGER RANGE
                                  Set the maximum write buffer size for each
                                  HTTP/2 stream  [env var:
                                  GRANIAN_HTTP2_MAX_SEND_BUFFER_SIZE; default:
                                  409600; x>=1024]
  --log / --no-log                Enable logging  [env var:
                                  GRANIAN_LOG_ENABLED; default: (enabled)]
  --log-level [critical|error|warning|warn|info|debug|notset]
                                  Log level  [env var: GRANIAN_LOG_LEVEL;
                                  default: (info)]
  --log-config FILE               Logging configuration file (json)  [env var:
                                  GRANIAN_LOG_CONFIG]
  --access-log / --no-access-log  Enable access log  [env var:
                                  GRANIAN_LOG_ACCESS_ENABLED; default:
                                  (disabled)]
  --access-log-fmt TEXT           Access log format  [env var:
                                  GRANIAN_LOG_ACCESS_FMT]
  --ssl-certificate FILE          SSL certificate file  [env var:
                                  GRANIAN_SSL_CERTIFICATE]
  --ssl-keyfile FILE              SSL key file (PKCS#8 format only)  [env var:
                                  GRANIAN_SSL_KEYFILE]
  --ssl-keyfile-password TEXT     SSL key password  [env var:
                                  GRANIAN_SSL_KEYFILE_PASSWORD]
  --ssl-protocol-min [tls1.2|tls1.3]
                                  Set the minimum supported protocol for SSL
                                  connections.  [env var:
                                  GRANIAN_SSL_PROTOCOL_MIN; default: (tls1.3)]
  --ssl-ca FILE                   Root SSL cerificate file for client
                                  verification  [env var: GRANIAN_SSL_CA]
  --ssl-crl FILE                  SSL CRL file(s)  [env var: GRANIAN_SSL_CRL]
  --ssl-client-verify / --no-ssl-client-verify
                                  Verify clients SSL certificates  [env var:
                                  GRANIAN_SSL_CLIENT_VERIFY; default:
                                  (disabled)]
  --url-path-prefix TEXT          URL path prefix the app is mounted on  [env
                                  var: GRANIAN_URL_PATH_PREFIX]
  --respawn-failed-workers / --no-respawn-failed-workers
                                  Enable workers respawn on unexpected exit
                                  [env var: GRANIAN_RESPAWN_FAILED_WORKERS;
                                  default: (disabled)]
  --respawn-interval FLOAT        The number of seconds to sleep between
                                  workers respawn  [env var:
                                  GRANIAN_RESPAWN_INTERVAL; default: 3.5]
  --rss-sample-interval DURATION  The sample rate in seconds (or a human-
                                  readable duration) for the resource monitor
                                  [env var: GRANIAN_RSS_SAMPLE_INTERVAL;
                                  default: 30; 1<=x<=300]
  --rss-samples INTEGER RANGE     The number of consecutive samples to
                                  consider a worker over resource limit  [env
                                  var: GRANIAN_RSS_SAMPLES; default: 1; x>=1]
  --workers-lifetime DURATION     The maximum amount of time in seconds (or a
                                  human-readable duration) a worker will be
                                  kept alive before respawn  [env var:
                                  GRANIAN_WORKERS_LIFETIME; x>=60]
  --workers-max-rss INTEGER RANGE
                                  The maximum amount of memory (in MiB) a
                                  worker can consume before respawn  [env var:
                                  GRANIAN_WORKERS_MAX_RSS; x>=1]
  --workers-kill-timeout DURATION
                                  The amount of time in seconds (or a human-
                                  readable duration) to wait for killing
                                  workers that refused to gracefully stop
                                  [env var: GRANIAN_WORKERS_KILL_TIMEOUT;
                                  default: (disabled); 1<=x<=1800]
  --factory / --no-factory        Treat target as a factory function, that
                                  should be invoked to build the actual target
                                  [env var: GRANIAN_FACTORY; default:
                                  (disabled)]
  --working-dir DIRECTORY         Set the working directory  [env var:
                                  GRANIAN_WORKING_DIR]
  --env-files FILE                Environment file(s) to load (requires
                                  granian[dotenv] extra)  [env var:
                                  GRANIAN_ENV_FILES]
  --static-path-route TEXT        Route(s) for static file serving  [env var:
                                  GRANIAN_STATIC_PATH_ROUTE; default:
                                  (/static)]
  --static-path-mount DIRECTORY   Path(s) to mount for static file serving
                                  [env var: GRANIAN_STATIC_PATH_MOUNT]
  --static-path-dir-to-file TEXT  Serve the specified file as the index for
                                  directory listings  [env var:
                                  GRANIAN_STATIC_PATH_DIR_TO_FILE]
  --static-path-expires DURATION  Cache headers expiration (in seconds or a
                                  human-readable duration) for static file
                                  serving. 0 to disable.  [env var:
                                  GRANIAN_STATIC_PATH_EXPIRES; default: 86400;
                                  x>=0]
  --metrics / --no-metrics        Enable the prometheus metrics exporter.
                                  [env var: GRANIAN_METRICS_ENABLED; default:
                                  (disabled)]
  --metrics-scrape-interval DURATION
                                  Configure the interval for metrics
                                  collection.  [env var:
                                  GRANIAN_METRICS_SCRAPE_INTERVAL; default:
                                  15; 1<=x<=60]
  --metrics-address TEXT          Metrics exporter host address to bind to
                                  [env var: GRANIAN_METRICS_ADDRESS; default:
                                  (127.0.0.1)]
  --metrics-port INTEGER          Metrics exporter port to bind to.  [env var:
                                  GRANIAN_METRICS_PORT; default: 9090]
  --reload / --no-reload          Enable auto reload on application's files
                                  changes (requires granian[reload] extra)
                                  [env var: GRANIAN_RELOAD; default:
                                  (disabled)]
  --reload-paths PATH             Paths to watch for changes  [env var:
                                  GRANIAN_RELOAD_PATHS; default: (Working
                                  directory)]
  --reload-ignore-dirs TEXT       Names of directories to ignore changes for.
                                  Extends the default list of directories to
                                  ignore in watchfiles' default filter  [env
                                  var: GRANIAN_RELOAD_IGNORE_DIRS]
  --reload-ignore-patterns TEXT   File/directory name patterns (regex) to
                                  ignore changes for. Extends the default list
                                  of patterns to ignore in watchfiles' default
                                  filter  [env var:
                                  GRANIAN_RELOAD_IGNORE_PATTERNS]
  --reload-ignore-paths PATH      Absolute paths to ignore changes for  [env
                                  var: GRANIAN_RELOAD_IGNORE_PATHS]
  --reload-tick INTEGER RANGE     The tick frequency (in milliseconds) the
                                  reloader watch for changes  [env var:
                                  GRANIAN_RELOAD_TICK; default: 50;
                                  50<=x<=5000]
  --reload-ignore-worker-failure / --no-reload-ignore-worker-failure
                                  Ignore worker failures when auto reload is
                                  enabled  [env var:
                                  GRANIAN_RELOAD_IGNORE_WORKER_FAILURE;
                                  default: (disabled)]
  --process-name TEXT             Set a custom name for processes (requires
                                  granian[pname] extra)  [env var:
                                  GRANIAN_PROCESS_NAME]
  --pid-file FILE                 A path to write the PID file to  [env var:
                                  GRANIAN_PID_FILE]
  --version                       Show the version and exit.
  --help                          Show this message and exit.

Human-readable durations

Whenever Granian accepts a duration, it can be specified either as sole number, in which case it is interpreted as a number of seconds, or using one of the following suffixes:

suffix meaning
s seconds (same as no suffix)
m minutes
h hours
d days

Logging

Despite being a Rust project, Granian is a good Python citizen and uses the standard library's logging module to produce logs. This means you can freely configure your logging level and format using the standard idioms you probably familiar with.

As many other web servers, Granian uses two different loggers, specifically:

  • the _granian logger for runtime messages
  • the granian.access logger for access logs

Access log format

The access log format can be configured by specifying the atoms (see below) to include in a specific format. By default Granian will use [%(time)s] %(addr)s - "%(method)s %(path)s %(protocol)s" %(status)d %(dt_ms).3f as the format.

Access log atoms

The following atoms are available for use:

identifier description
addr Client remote address
time Datetime of the request
dt_ms Request duration in ms
status HTTP response status
path Request path (without query string)
query_string Request query string
method Request HTTP method
scheme Request scheme
protocol HTTP protocol version

Workers and threads

Granian offers different options to configure the number of workers and threads to be run, in particular:

  • workers: the total number of processes holding a dedicated Python interpreter that will run the application
  • blocking threads: the number of threads per worker interacting with the Python interpreter
  • runtime threads: the number of Rust threads per worker that will perform network I/O
  • runtime blocking threads: the number of Rust threads per worker involved in blocking operations. The main role of these threads is dealing with blocking I/O – like file system operations.

In general, Granian will try its best to automatically pick proper values for the threading configuration, leaving to you the responsibility to choose the number of workers you need.
There is no golden rule here, as these numbers will vastly depend both on your application behavior and the deployment target, but we can list some suggestions:

  • matching the amount of CPU cores for the workers is generally the best starting point; on containerized environments like docker or k8s is best to have 1 worker per container though and scale your containers using the relevant orchestrator;
  • the default number of runtime threads and runtime blocking threads is fine for the vast majority of applications out there; you might want to increase the first for applications dealing with several concurrently opened websockets or if you primarily use HTTP/2, and lowering the second only if you serve the same few files to a lot of connections;

In regards of blocking threads, the option is irrelevant on asynchronous protocols, as all the interop will happen with the AsyncIO event loop which will also be the one holding the GIL for the vast majority of the time, and thus the value is fixed to a single thread; on synchronous protocols like WSGI instead, it will be the maximum amount of threads interacting – and thus trying to acquire the GIL – with your application code. All those threads will be spawned on-demand depending on the amount of concurrency, and they'll be shutdown after the amount of inactivity time specified with the relevant setting.
In general, and unless you have a very specific use-case to do so (for example, if your application have an average millisecond response, a very limited amount of blocking threads usually delivers better throughput) you should avoid to tune this threadpool size and configure a backpressure value that suits your needs instead. In that regards, please check the next section.

Also, you should generally avoid to configure workers and threads based on numbers suggested for other servers, as Granian architecture is quite different from projects like Gunicorn or Uvicorn.

Backpressure

Since Granian runs a separated Rust runtime aside of your application that will handle I/O and "send work" to the Python interpreter, a mechanism to avoid pushing more work that what the Python interpreter can actually do is provided: backpressure.

Backpressure in Granian operates at the single worker's connections accept loop, practically interrupting the loop in case too many requests are waiting to be processed down the line. You can think of it as a secondary backlog, handled by Granian itself in addition to the network stack one provided by the OS kernel (and configured with apposite parameter).

While on asynchronous protocols, the default value for the backpressure should work fine for the vast majority of applications, as work will be handled and suspended by the AsyncIO event loop, on synchronous protocols there's no way to predict the amount of interrupts (and thus GIL releases) your application would do on a single request, and thus you should configure a value that makes sense in your environment. For example, if your WSGI application never does I/O within a request-reponse flow, then you can't really go beyond serial, and thus any backpressure value above 2 wouldn't probably make any difference, as all the requests will just be waiting to acquire the GIL in order to be processed. On the other hand, if your application makes external network requests within the standard request-response flow, a large backpressure can help, as during the time spent on those code paths you can still process other requests. Another example would be if your application communicate with a database, and you have a limited amount of connections that can be opened to that database: in this case setting the backpressure to that value would definitely be the best option.

In general, think of backpressure as the maximum amount of concurrency you want to handle (per worker) in your application, after which Granian will halt and wait before pushing more work.

Warning: since backpressure interacts with the accept loop, it will limit connections, not the single requests. Keep-alive connections will handle multiple requests within a single connection, but Granian won't count those requests in the actual pressure. This also means, if you typically have several long-running keep-alive connections to your service (for example, if you run behind a reverse proxy), a backpressure value can prevent Granian to accept new connections once the amount of keep-alive connections reaches that limit. Under this circumstances, you want to ensure the configured backpressure is higher than the expected amount of keep-alive connections, and if you're trying to limit the concurrency, it's probably better to configure the blocking threads number rather than the backpressure itself.

Runtime mode

Granian offers two different runtime threading paradigms, due to the fact the runtime can be multi-threaded – in opposition to what happens in Python event-loop which can only run as a single thread.

Given you specify N threads with the relevant option, in st mode Granian will spawn N single-threaded Rust runtimes, while in mt mode Granian will spawn a single multi-threaded runtime with N threads.

Benchmarks suggests st mode to be more efficient with a small amount of processes, while mt mode seems to scale more efficiently where you have a large number of CPUs. Real performance will though depend on specific application code, and thus your mileage might vary.

By default (auto mode), Granian will pick the best option based on the rest of its configuration.

Metrics

Granian exposes the following runtime metrics in Prometheus format. All the metrics are prefixed with granian_, and the ones marked with worker scope are tagged with a worker label containing the worker ID.

metric name type unit scope description
workers_spawns counter absolute number global Number of times Granian spawned a worker
workers_respawns_for_err counter absolute number global Number of times Granian respawned a worker due to an error
workers_respawns_for_lifetime counter absolute number global Number of times Granian respawned a worker due to exceeding lifetime
workers_respawns_for_rss counter absolute number global Number of times Granian respawned a worker due to exceeding resources usage
workers_respawns_for_lifetime counter absolute number global Number of times Granian respawned a worker due to exceeding lifetime
worker_lifetime counter seconds worker Current lifetime of the worker
connections_active gauge absolute number worker Number of active connections
connections_handled counter absolute number worker Number of accepted connections
connections_err gauge absolute number worker Number of failed connections
requests_handled counter absolute number worker Number of processed requests
static_requests_handled counter absolute number worker Number of processed requests for static files
static_requests_err counter absolute number worker Number of requests for static files resulted in a non 200 response code
blocking_threads gauge absolute number worker Current number of blocking threads in the pool (on async protocols this is always 1)
blocking_queue gauge absolute number worker Number of pending tasks for the blocking threadpool
blocking_idle_cumulative counter microseconds worker Cumulative idle time spent in the blocking threadpool
blocking_busy_cumulative counter microseconds worker Cumulative busy time spent in the blocking threadpool
py_wait_cumulative counter microseconds worker Cumulative time spent waiting on GIL (on the free-threaded build this is always 0)

Static files

Granian offers the ability to offload static files serving directly to the server, without calling your Python application in the process.

The --static-path-route and --static-path-mount options accept multiple values, thus you can serve an arbitrary number of static locations in your application, the only condition being the number of routes and mounts specified should be the same:

$ granian \
    --static-path-route /static \
    --static-path-mount assets/static \
    --static-path-route /media \
    --static-path-mount assets/media \
    package:app

Serving a specific file for directory listings

Granian also provides the option to rewrite a static location pointing to a directory to a file contained in such directory. This allows you to serve, for example, an index.html file in the static path tree:

$ granian \
    --static-path-route /docs \
    --static-path-mount generated/docs \
    --static-path-dir-to-file index.html \
    package:app

Note: while Granian performs a rewrite on the target directory, the file will still be served if the request path points to it directly (in the example above, requests pointing to /docs/somefolder and /docs/somefolder/index.html will both respond with the contents of index.html – if present). Also, the option will enable this behavior on all the static paths defined.

Proxies and forwarded headers

Since none of the supported applications protocols define a strategy for proxies' forwarded headers, Granian doesn't provide any option to configure its behaviour around them.

What Granian provides instead, for contexts in which is being run behind a reverse proxy, are wrappers you can use on top of your application, in order to alter the request scope based on the headers forwarded by the proxy itself. You can find such wrappers in the granian.utils.proxies module:

from granian.utils.proxies import wrap_asgi_with_proxy_headers, wrap_wsgi_with_proxy_headers

async def my_asgi_app(scope, receive, send):
    ...

def my_wsgi_app(environ, start_response):
    ...

my_asgi_app = wrap_asgi_with_proxy_headers(my_asgi_app, trusted_hosts="1.2.3.4")
my_wsgi_app = wrap_wsgi_with_proxy_headers(my_wsgi_app, trusted_hosts="1.2.3.4")

With these wrappers, Granian will use:

and replace the relevant request scope attributes with these values.

Since altering the request scope based on values from headers is security-sensitive, Granian will check the request is coming from a trusted host as specified by the trusted_hosts argument. By default this value is set to 127.0.0.1, which means Granian will only intercept those headers if the proxy resides on the same machine, but most likely that's not the case in a production environment: you should thus provide the correct set of addresses to the wrappers.

The trusted_hosts argument accepts either a string or a list of strings, where valid values are IP addresses (for example, 192.0.2.1 or fd12:3456:789a::1) and CIDR ranges (for example, 192.0.2.0/24 or 2001:db8:abcd::/48). The special catch-all value "*" (or ["*"]) will make Granian trust all hosts and effectively disable the security check.

Free-threaded Python

Warning: free-threaded Python support is still experimental and highly discouraged in production environments.

Since version 2.0 Granian supports free-threaded Python. While the installation process remains the same, as wheels for the free-threaded version are published separately, here we list some key differences from the GIL version.

  • Workers are threads instead of separated processes, so there will always be a single Python interpreter running
  • The application is thus loaded a single time and shared between workers
  • In asynchronous protocols like ASGI and RSGI each worker runs its own AsyncIO event loop like the GIL version, but the loop will run in the worker thread instead of the Python main thread

Note: if for any reason the GIL gets enabled on the free-threaded build, Granian will refuse to start. This means you can't use the free-threaded build on GIL enabled interpreters.

While for asynchronous protocols nothing really changes in terms of workers and threads configuration, as the scaling will be still driven by the number of AsyncIO event loops running (so the same rules for GIL workers apply), on synchronous protocols like WSGI every GIL-related limitation is theoretically absent.
While the general rules in terms of I/O-bound vs CPU-bound load still apply, at the time being there's not enough data to make suggestions in terms of workers and threads tuning in the free-threaded Python land, and thus you will need to experiment with those values depending on your specific workload.

Customising Granian

Running Granian directly from Python instead of its CLI gives you access to some customization interfaces that let you alter its standard behaviour.

AsyncIO event loop initialization

As soon as you run Granian directly from Python instead of its CLI, you can customise the default event loop initialisation policy by overwriting the auto policy. Let's say, for instance, you want to use the selector event loop on Windows:

import asyncio
from granian import Granian, loops

@loops.register('auto')
def build_loop():
    asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
    return asyncio.new_event_loop()


Granian(...).serve()

Hooks

Granian provides hooks registration interfaces to run code during specific phases of its lifecycle. Specifically, you have the following methods available:

  • on_startup
  • on_shutdown
  • on_reload

The mentioned methods accept a callable with no arguments that will be invoked during the relevant lifecycle phases. You can register your hooks simply passing them to the relevant method:

from granian import Granian

def my_hook():
    print("hello from reload!")

server = Granian(...)
server.on_reload(my_hook)

Embedding Granian in your project

For projects requiring advance lifecycle management, or implementing their own process management strategy, Granian provides an embeddable server implementation, which provides async interfaces and won't spawn workers as processes or threads, but will run them as AsyncIO tasks.

Warning: the embeddable server is still experimental.

Note: the embeddable server only supports async protocols, thus WSGI is not supported. It's also limited to a single worker, as it runs over an existing event loop.

To embed Granian in your project, you can import the server from the relevant module:

from granian.server.embed import Server

server = Server(my_app, interface="asgi")

async def my_main():
    await server.serve()

Note: as you might already figured out, the embed server accepts the application object as its first argument, instead of the import target string of the standard servers.

Given the serve method is now async, the embeddable server also provides two methods to manage its lifecycle, specifically:

  • stop
  • reload

The idea is that you can spawn the server as a task, and later on interact with it in your own process loop:

async def my_main():
    server_task = asyncio.create_task(server.serve())
    await my_logic()
    server.stop()
    await server_task

Project status

Granian is being actively maintained and is compatible with Python 3.10 and above versions.

Granian follows a semantic versioning scheme for its releases, with a {major}.{minor}.{patch} scheme for versions numbers, where:

  • major versions might introduce breaking changes
  • minor versions introduce new features and backward compatible changes
  • patch versions only introduce bug and security fixes

Mind that bug and security fixes are usually provided for the latest minor version only.

Granian is used in production by projects like paperless-ngx, reflex, searxng and Weblate, and by companies like Microsoft, Mozilla and Sentry.

License

Granian is released under the BSD License.

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

granian-2.7.2.tar.gz (129.0 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

granian-2.7.2-pp311-pypy311_pp73-win_amd64.whl (4.2 MB view details)

Uploaded PyPyWindows x86-64

granian-2.7.2-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl (7.0 MB view details)

Uploaded PyPymusllinux: musl 1.1+ x86-64

granian-2.7.2-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl (7.3 MB view details)

Uploaded PyPymusllinux: musl 1.1+ ARMv7l

granian-2.7.2-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl (7.1 MB view details)

Uploaded PyPymusllinux: musl 1.1+ ARM64

granian-2.7.2-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl (7.0 MB view details)

Uploaded PyPymanylinux: glibc 2.28+ ARM64

granian-2.7.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (6.9 MB view details)

Uploaded PyPymanylinux: glibc 2.17+ x86-64

granian-2.7.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl (6.1 MB view details)

Uploaded PyPymacOS 11.0+ ARM64

granian-2.7.2-pp311-pypy311_pp73-macosx_10_12_x86_64.whl (6.5 MB view details)

Uploaded PyPymacOS 10.12+ x86-64

granian-2.7.2-cp314-cp314t-win_amd64.whl (4.1 MB view details)

Uploaded CPython 3.14tWindows x86-64

granian-2.7.2-cp314-cp314t-musllinux_1_1_x86_64.whl (7.1 MB view details)

Uploaded CPython 3.14tmusllinux: musl 1.1+ x86-64

granian-2.7.2-cp314-cp314t-musllinux_1_1_armv7l.whl (7.3 MB view details)

Uploaded CPython 3.14tmusllinux: musl 1.1+ ARMv7l

granian-2.7.2-cp314-cp314t-musllinux_1_1_aarch64.whl (7.1 MB view details)

Uploaded CPython 3.14tmusllinux: musl 1.1+ ARM64

granian-2.7.2-cp314-cp314t-manylinux_2_28_aarch64.whl (6.9 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.28+ ARM64

granian-2.7.2-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (6.8 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.17+ x86-64

granian-2.7.2-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (7.1 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.17+ ARMv7l

granian-2.7.2-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl (6.3 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.12+ i686

granian-2.7.2-cp314-cp314t-macosx_11_0_arm64.whl (6.1 MB view details)

Uploaded CPython 3.14tmacOS 11.0+ ARM64

granian-2.7.2-cp314-cp314t-macosx_10_12_x86_64.whl (6.4 MB view details)

Uploaded CPython 3.14tmacOS 10.12+ x86-64

granian-2.7.2-cp314-cp314-win_amd64.whl (4.1 MB view details)

Uploaded CPython 3.14Windows x86-64

granian-2.7.2-cp314-cp314-musllinux_1_1_x86_64.whl (7.1 MB view details)

Uploaded CPython 3.14musllinux: musl 1.1+ x86-64

granian-2.7.2-cp314-cp314-musllinux_1_1_armv7l.whl (7.3 MB view details)

Uploaded CPython 3.14musllinux: musl 1.1+ ARMv7l

granian-2.7.2-cp314-cp314-musllinux_1_1_aarch64.whl (7.0 MB view details)

Uploaded CPython 3.14musllinux: musl 1.1+ ARM64

granian-2.7.2-cp314-cp314-manylinux_2_28_aarch64.whl (7.0 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.28+ ARM64

granian-2.7.2-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (6.9 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ x86-64

granian-2.7.2-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl (6.5 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ i686

granian-2.7.2-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (7.1 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ ARMv7l

granian-2.7.2-cp314-cp314-macosx_11_0_arm64.whl (6.1 MB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

granian-2.7.2-cp314-cp314-macosx_10_12_x86_64.whl (6.4 MB view details)

Uploaded CPython 3.14macOS 10.12+ x86-64

granian-2.7.2-cp313-cp313t-win_amd64.whl (4.1 MB view details)

Uploaded CPython 3.13tWindows x86-64

granian-2.7.2-cp313-cp313t-musllinux_1_1_x86_64.whl (7.1 MB view details)

Uploaded CPython 3.13tmusllinux: musl 1.1+ x86-64

granian-2.7.2-cp313-cp313t-musllinux_1_1_armv7l.whl (7.3 MB view details)

Uploaded CPython 3.13tmusllinux: musl 1.1+ ARMv7l

granian-2.7.2-cp313-cp313t-musllinux_1_1_aarch64.whl (7.1 MB view details)

Uploaded CPython 3.13tmusllinux: musl 1.1+ ARM64

granian-2.7.2-cp313-cp313t-manylinux_2_28_aarch64.whl (6.9 MB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.28+ ARM64

granian-2.7.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (6.8 MB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.17+ x86-64

granian-2.7.2-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (7.1 MB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.17+ ARMv7l

granian-2.7.2-cp313-cp313t-manylinux_2_12_i686.manylinux2010_i686.whl (6.2 MB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.12+ i686

granian-2.7.2-cp313-cp313t-macosx_11_0_arm64.whl (6.1 MB view details)

Uploaded CPython 3.13tmacOS 11.0+ ARM64

granian-2.7.2-cp313-cp313t-macosx_10_12_x86_64.whl (6.4 MB view details)

Uploaded CPython 3.13tmacOS 10.12+ x86-64

granian-2.7.2-cp313-cp313-win_amd64.whl (4.1 MB view details)

Uploaded CPython 3.13Windows x86-64

granian-2.7.2-cp313-cp313-musllinux_1_1_x86_64.whl (7.1 MB view details)

Uploaded CPython 3.13musllinux: musl 1.1+ x86-64

granian-2.7.2-cp313-cp313-musllinux_1_1_armv7l.whl (7.3 MB view details)

Uploaded CPython 3.13musllinux: musl 1.1+ ARMv7l

granian-2.7.2-cp313-cp313-musllinux_1_1_aarch64.whl (7.1 MB view details)

Uploaded CPython 3.13musllinux: musl 1.1+ ARM64

granian-2.7.2-cp313-cp313-manylinux_2_28_aarch64.whl (7.0 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ ARM64

granian-2.7.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (6.9 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

granian-2.7.2-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl (6.4 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ i686

granian-2.7.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (7.1 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARMv7l

granian-2.7.2-cp313-cp313-macosx_11_0_arm64.whl (6.1 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

granian-2.7.2-cp313-cp313-macosx_10_12_x86_64.whl (6.4 MB view details)

Uploaded CPython 3.13macOS 10.12+ x86-64

granian-2.7.2-cp312-cp312-win_amd64.whl (4.2 MB view details)

Uploaded CPython 3.12Windows x86-64

granian-2.7.2-cp312-cp312-musllinux_1_1_x86_64.whl (7.0 MB view details)

Uploaded CPython 3.12musllinux: musl 1.1+ x86-64

granian-2.7.2-cp312-cp312-musllinux_1_1_armv7l.whl (7.2 MB view details)

Uploaded CPython 3.12musllinux: musl 1.1+ ARMv7l

granian-2.7.2-cp312-cp312-musllinux_1_1_aarch64.whl (7.1 MB view details)

Uploaded CPython 3.12musllinux: musl 1.1+ ARM64

granian-2.7.2-cp312-cp312-manylinux_2_28_aarch64.whl (7.0 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ ARM64

granian-2.7.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (7.0 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

granian-2.7.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl (6.4 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ i686

granian-2.7.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (7.1 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARMv7l

granian-2.7.2-cp312-cp312-macosx_11_0_arm64.whl (6.1 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

granian-2.7.2-cp312-cp312-macosx_10_12_x86_64.whl (6.5 MB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

granian-2.7.2-cp311-cp311-win_amd64.whl (4.2 MB view details)

Uploaded CPython 3.11Windows x86-64

granian-2.7.2-cp311-cp311-musllinux_1_1_x86_64.whl (7.0 MB view details)

Uploaded CPython 3.11musllinux: musl 1.1+ x86-64

granian-2.7.2-cp311-cp311-musllinux_1_1_armv7l.whl (7.3 MB view details)

Uploaded CPython 3.11musllinux: musl 1.1+ ARMv7l

granian-2.7.2-cp311-cp311-musllinux_1_1_aarch64.whl (7.1 MB view details)

Uploaded CPython 3.11musllinux: musl 1.1+ ARM64

granian-2.7.2-cp311-cp311-manylinux_2_28_aarch64.whl (7.0 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ ARM64

granian-2.7.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (6.9 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

granian-2.7.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl (6.5 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ i686

granian-2.7.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (7.1 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ARMv7l

granian-2.7.2-cp311-cp311-macosx_11_0_arm64.whl (6.1 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

granian-2.7.2-cp311-cp311-macosx_10_12_x86_64.whl (6.5 MB view details)

Uploaded CPython 3.11macOS 10.12+ x86-64

granian-2.7.2-cp310-cp310-win_amd64.whl (4.2 MB view details)

Uploaded CPython 3.10Windows x86-64

granian-2.7.2-cp310-cp310-musllinux_1_1_x86_64.whl (7.0 MB view details)

Uploaded CPython 3.10musllinux: musl 1.1+ x86-64

granian-2.7.2-cp310-cp310-musllinux_1_1_armv7l.whl (7.3 MB view details)

Uploaded CPython 3.10musllinux: musl 1.1+ ARMv7l

granian-2.7.2-cp310-cp310-musllinux_1_1_aarch64.whl (7.1 MB view details)

Uploaded CPython 3.10musllinux: musl 1.1+ ARM64

granian-2.7.2-cp310-cp310-manylinux_2_28_aarch64.whl (7.0 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ ARM64

granian-2.7.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (6.9 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

granian-2.7.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl (6.5 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ i686

granian-2.7.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (7.1 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ ARMv7l

granian-2.7.2-cp310-cp310-macosx_11_0_arm64.whl (6.1 MB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

granian-2.7.2-cp310-cp310-macosx_10_12_x86_64.whl (6.5 MB view details)

Uploaded CPython 3.10macOS 10.12+ x86-64

File details

Details for the file granian-2.7.2.tar.gz.

File metadata

  • Download URL: granian-2.7.2.tar.gz
  • Upload date:
  • Size: 129.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for granian-2.7.2.tar.gz
Algorithm Hash digest
SHA256 cdae2f3a26fa998d41fefad58f1d1c84a0b035a6cc9377addd81b51ba82f927f
MD5 6f40dad3295613c5ae41eda8759fc780
BLAKE2b-256 5719d4ea523715ba8dd2ed295932cc3dda6bb197060f78aada6e886ff08587b2

See more details on using hashes here.

File details

Details for the file granian-2.7.2-pp311-pypy311_pp73-win_amd64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-pp311-pypy311_pp73-win_amd64.whl
Algorithm Hash digest
SHA256 001bab0862857d3f029eb2819e88754e746547f4cd8cc28ae229090fc929fbaf
MD5 6e844217f8f78195760621e2669aa662
BLAKE2b-256 aba8d9ba7a0d05303f57279ca8b17364945d5090ed90b32b92df219129039f50

See more details on using hashes here.

File details

Details for the file granian-2.7.2-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 362a6001daa2ce62532a49df407fe545076052ef29289a76d5760064d820f48b
MD5 878d7360d06f0c2f870e49225142e544
BLAKE2b-256 8cac8b142ed352bc525e3c97440aab312928beebc735927b0cf979692bfcda3b

See more details on using hashes here.

File details

Details for the file granian-2.7.2-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl.

File metadata

File hashes

Hashes for granian-2.7.2-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 406c0bb1f5bf55c72cfbfdfd2ccec21299eb3f7b311d85c4889dde357fd36f33
MD5 4f5187aa6f87d73fa167d6c8e9169fd4
BLAKE2b-256 a98737124b2ee0cddce6ba438b0ff879ddae094ae2c92b24b28ffbe35110931f

See more details on using hashes here.

File details

Details for the file granian-2.7.2-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 2392ab03cb92b1b2d4363f450b2d875177e10f0e22d67a4423052e6885e430f2
MD5 0fd72ff68255bc3819fb1938d2ab0e13
BLAKE2b-256 36cedf9bba3b211cda2d47535bb21bc040007e021e8c8adc20ce36619f903bc4

See more details on using hashes here.

File details

Details for the file granian-2.7.2-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 a6adea5fb8a537d18f3f2b848023151063bc45896415fdebfeb0bf0663d5a03b
MD5 68adcff8ab3f94e0206bb8eff4d8d362
BLAKE2b-256 c72fa2671cc160f29ccf8e605eb8fa113c01051b0d7947048c5b29eb4e603384

See more details on using hashes here.

File details

Details for the file granian-2.7.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 e94c825f8b327114f7062d158c502a540ef5819f809e10158f0edddddaf41bb9
MD5 676fa09b263050a6108ea634ae043d3a
BLAKE2b-256 e7e0b578709020f84c07ad2ca88f77ac67fd2c62e6b16f93ff8c8d65b7d99296

See more details on using hashes here.

File details

Details for the file granian-2.7.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 0cd6fee79f585de2e1a90b6a311f62b3768c7cda649bc0e02908157ffa2553cc
MD5 574daeb8ce33f7fc7458483d47f5f7ab
BLAKE2b-256 6e68282fbf5418f9348f657f505dc744cdca70ac850d39a805b21395211bf099

See more details on using hashes here.

File details

Details for the file granian-2.7.2-pp311-pypy311_pp73-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-pp311-pypy311_pp73-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 5613ee8c1233a79e56e1735e19c8c70af22a8c6b5808d7c1423dc5387bee4c05
MD5 1c44eede4db2b96572a5ce9375674dc4
BLAKE2b-256 5971f21b26c7dc7a8bc9d8288552c9c12128e73f1c3f04799b6e28a0a269b9b0

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp314-cp314t-win_amd64.whl.

File metadata

  • Download URL: granian-2.7.2-cp314-cp314t-win_amd64.whl
  • Upload date:
  • Size: 4.1 MB
  • Tags: CPython 3.14t, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for granian-2.7.2-cp314-cp314t-win_amd64.whl
Algorithm Hash digest
SHA256 e8b87d7ada696eec7e9023974665c83cec978cb83c205eae8fe377de20622f25
MD5 e72141ed56fe8e51176d81339d09e336
BLAKE2b-256 29b3fd13123ac936a4f79f1ba20ad67328a8d09d586262b8f28cc1cfaa555213

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp314-cp314t-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp314-cp314t-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 82f34e78c1297bf5a1b6a5097e30428db98b59fce60a7387977b794855c0c3bc
MD5 2240d10b5345c954beda4864ce161cef
BLAKE2b-256 492f58cba479254530ab09132e150e4ab55362f6e875d9e82b6790477843e0aa

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp314-cp314t-musllinux_1_1_armv7l.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp314-cp314t-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 0ffac19208ae548f3647c849579b803beaed2b50dfb0f3790ad26daac0033484
MD5 ce9f3e66803c555f71b3bb91fd3addac
BLAKE2b-256 cfeb91ed4646ce1c920ad39db0bcddb6f4755e1823002b14fb026104e3eb8bce

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp314-cp314t-musllinux_1_1_aarch64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp314-cp314t-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 1777166c3c853eed4440adb3cbbf34bba2b77d595bfc143a5826904a80b22f34
MD5 c23ac7c5b32be43eb8ca3b7db89f805a
BLAKE2b-256 248a8ce186826066f6d453316229383a5be3b0b8a4130146c21f321ee64fe2cb

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp314-cp314t-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp314-cp314t-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 b1c77189335070c6ba6b8d158518fde4c50f892753620f0b22a7552ad4347143
MD5 375535ff6d382194e1d5f0b03fb3466c
BLAKE2b-256 a146eabab80e07a14527c336dec6d902329399f3ba2b82dc94b6435651021359

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 9bb1ef13125bc05ab2e18869ed311beaeb085a4c4c195d55d0865f5753a4c0b4
MD5 0c6d039f525dd47acf9c6c99c5132c69
BLAKE2b-256 81eed9ed836316607401f158ac264a3f770469d1b1edbf119402777a9eff1833

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 e50fb13e053384b8bd3823d4967606c6fd89f2b0d20e64de3ae212b85ffdfed2
MD5 ab14b353721ed13ddbeb3219456db978
BLAKE2b-256 545665776c6d759dcef9cce15bc11bdea2c64fe668088faf35d87916bd88f595

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 96b0fd9eac60f939b3cbe44c8f32a42fdb7c1a1a9e07ca89e7795cdc7a606beb
MD5 c1af68a274f0e2e6961a405ba300e27b
BLAKE2b-256 ec107d58a922b44417a6207c0a3230b0841cd7385a36fc518ac15fed16ebf6f7

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp314-cp314t-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp314-cp314t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 17516095b520b3c039ddbe41a6beb2c59d554b668cc229d36d82c93154a799af
MD5 39404e82be87ad816482d7a09cf45fb4
BLAKE2b-256 27bc3e69305bf34806cd852f4683deec844a2cb9a4d8888d7f172b507f6080a8

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp314-cp314t-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp314-cp314t-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 a698d9b662d5648c8ae3dc01ad01688e1a8afc3525e431e7cddb841c53e5e291
MD5 348e3fa28bc40145c2b7863fee14ad02
BLAKE2b-256 cc070e56fb4f178e14b4c1fa1f6f00586ca81761ccbe2d8803f2c12b6b17a7d6

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: granian-2.7.2-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 4.1 MB
  • Tags: CPython 3.14, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for granian-2.7.2-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 a69cafb6518c630c84a9285674d45ea6f7342a6279dc25c6bd933b6fad5c55ab
MD5 ffb41d023abcf4f3dd9d01ba82926495
BLAKE2b-256 23e428097a852d8f93f8e3be2014a81f03aa914b8a2c12ca761fac5ae1344b8b

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp314-cp314-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp314-cp314-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 7c1ce9b0c9446b680e9545e7fc95a75f0c53a25dedcf924b1750c3e5ba5bf908
MD5 e88e3cad72cd30115e7b68be7fdc136b
BLAKE2b-256 003704245c7259e65f1083ce193875c6c44da4c98604d3b00a264a74dd4f042b

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp314-cp314-musllinux_1_1_armv7l.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp314-cp314-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 6590f8092c2bb6614e561ba771f084cbf72ecbc38dbf9849762ac38718085c29
MD5 3ba3a0e9838f9031a547ec6bc2d62155
BLAKE2b-256 907638d205cb527046241a9ee4f51048bf44101c626ad4d2af16dd9d14dc1db6

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp314-cp314-musllinux_1_1_aarch64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp314-cp314-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 76c987c3ca78bf7666ab053c3ed7e3af405af91b2e5ce2f1cf92634c1581e238
MD5 7737d3a2d99fe5cb23e9a5f2bbdb1060
BLAKE2b-256 374b44fde33fe10245a3fba76bf843c387fad2d548244345115b9d87e1c40994

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp314-cp314-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp314-cp314-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 a52effb9889f0944f0353afd6ce5a9d9aa83826d44bbf3c8013e978a3d6ef7b7
MD5 27b9fd8a284bcc4a2f4b6bf4e22ae790
BLAKE2b-256 982ec86d95f324248fcc5dcaf034c9f688b32f7a488f0b2a4a25e6673776107f

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 4ff7a93123ab339ba6cad51cc7141f8880ec47b152ce2491595bb08edda20106
MD5 1b7965f065f1fbdc1072133811844f0c
BLAKE2b-256 4c55a6d08cfecc808149a910e51c57883ab26fad69d922dc2e76fb2d87469e2d

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 66d28b078e8087f794b83822055f95caf93d83b23f47f4efcd5e2f0f7a5d8a81
MD5 cb320cfc8f8b3ebe70d251f2f93dfddd
BLAKE2b-256 0a7635e240d107e0f158662652fd61191de4fb0c2c080e3786ca8f16c71547b7

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 6d4d78408283ec51f0fb00557856b4593947ad5b48287c04e1c22764a0ac28a5
MD5 545aaf2b556089ed675ad142259ab153
BLAKE2b-256 b4c517fea68f4cb280c217cbd65534664722c9c9b0138c2754e20c235d70b5f4

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c9dcde3968b921654bde999468e97d03031f28668bc1fc145c81d8bedb0fb2a4
MD5 1f37ee74dd95421142110b07a90633f8
BLAKE2b-256 27627d36ed38a40a68c2856b6d2a6fedd40833e7f82eb90ba0d03f2d69ffadf5

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp314-cp314-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp314-cp314-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 592806c28c491f9c1d1501bac706ecf5e72b73969f20f912678d53308786d658
MD5 68a938fff5e7295059edaf5f9a87e94d
BLAKE2b-256 694a8ce622f4f7d58e035d121b9957dd5a8929028dc99cfc5d2bf7f2aa28912c

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp313-cp313t-win_amd64.whl.

File metadata

  • Download URL: granian-2.7.2-cp313-cp313t-win_amd64.whl
  • Upload date:
  • Size: 4.1 MB
  • Tags: CPython 3.13t, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for granian-2.7.2-cp313-cp313t-win_amd64.whl
Algorithm Hash digest
SHA256 841c48608e55daa2fa434392397cc24175abd48bc5bcefa1e4f74b7243e36c72
MD5 2389204164829ac6f951d7e9227f41c3
BLAKE2b-256 ee0e4321e361bccb9681e1045c75e783476de5be7aa47cf05066907530772eba

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp313-cp313t-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp313-cp313t-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 34708b145e31b4538e0556704a07454a76d6776c55c5bc3a1335e80ef6b3bae3
MD5 a9b870bc69e18ccff3bec8e4199799d9
BLAKE2b-256 19ae00884ab77045a2f54db90932f9d1ca522201e2a6b2cf2a9b38840db0fd54

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp313-cp313t-musllinux_1_1_armv7l.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp313-cp313t-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 3612eb6a3f4351dd2c4df246ed0d21056c0556a6b1ed772dd865310aa55a9ba9
MD5 c62783b87d8b7b61c03d84d0572eeddc
BLAKE2b-256 38bc1521dbf026d1c9d2465cd54e016efd8ff6e1e72eff521071dab20dd61c44

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp313-cp313t-musllinux_1_1_aarch64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp313-cp313t-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 5ac1843c6084933a54a07d9dcae643365f1d83aaff3fd4f2676ea301185e4e8b
MD5 b02c9d62c7fe7be6155196cb5e4edc6c
BLAKE2b-256 44b8832970d2d4b144b87be39f5b9dfd31fdb17f298dc238a0b2100c95002cf8

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp313-cp313t-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp313-cp313t-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 746555ac8a2dcd9257bfe7ad58f1d7a60892bc4613df6a7d8f736692b3bb3b88
MD5 35c7c8bbb2741e4c1ce1a74750538c34
BLAKE2b-256 86bf4b6f45882f8341e7c6cb824d693deb94c306be6525b483c76fb373d1e749

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a196125c4837491c139c9cc83541b48c408c92b9cfbbf004fd28717f9c02ad21
MD5 b74ae0f0f86fa1ba9cc174e95db3b8ea
BLAKE2b-256 84d1539907ee96d0ee2bcceabb4a6a9643b75378d6dfea09b7a9e4fd22cdf977

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 3258419c741897273ce155568b5a9cbacb7700a00516e87119a90f7d520d6783
MD5 8a8f36791f611bfbcd80d6a8f29cadf0
BLAKE2b-256 efccd83a351560a3d6377672636129c52f06f8393f5831c5ee0f06f274883ea6

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp313-cp313t-manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp313-cp313t-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 283ba23817a685784b66f45423d2f25715fdc076c8ffb43c49a807ee56a0ffc0
MD5 54f8bf7b6c19ca09d237a0a7434cb843
BLAKE2b-256 07820df56a42b9f4c327d0e0b052f43369127e1b565b9e66bf2c9488f1c8d759

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp313-cp313t-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp313-cp313t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 dcbe01fa141adf3f90964e86a959e250754aa7c6dad8fa7a855e6fd382de4c13
MD5 2b986ca3057360c50ffa2904c420f09d
BLAKE2b-256 e38085726ad9999ed89cb6a32f7f57eb50ce7261459d9c30c3b194ae4c5aa2c5

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp313-cp313t-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp313-cp313t-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 016c5857c8baedeab7eb065f98417f5ea26bb72b0f7e0544fe76071efc5ab255
MD5 4df30a36542e57b9fe47e5fae354920a
BLAKE2b-256 4c499eb88875d709db7e7844e1c681546448dab5ff5651cd1c1d80ac4b1de4e3

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: granian-2.7.2-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 4.1 MB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for granian-2.7.2-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 7a4bd347694ace7a48cd784b911f2d519c2a22154e0d1ed59f5b4864914a8cfe
MD5 ef65e0243ca943fd5a36ee1539ef1a32
BLAKE2b-256 04c983e546d5f6b0447a4b9ee48ce15c29e43bb3f6b5e1040d33ac61fc9e3b6f

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp313-cp313-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp313-cp313-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 1617cbb4efe3112f07fb6762cf81d2d9fe4bdb78971d1fd0a310f8b132f6a51e
MD5 be2eb3faa2c67faaaa7448a1d25b0b5f
BLAKE2b-256 c52b64779e69b08c1ff1bfc09a4ede904ab761ff63f936c275710886057c52f7

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp313-cp313-musllinux_1_1_armv7l.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp313-cp313-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 63f426d793f2116d23be265dd826bec1e623680baf94cc270fe08923113a86ba
MD5 5660a676502537fef50174a245ff4d83
BLAKE2b-256 3982acec732a345cd03b2f6e48ac04b66b7b8b61f5c50eb08d7421fc8c56591a

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp313-cp313-musllinux_1_1_aarch64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp313-cp313-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 8ec167ab30f5396b5caaff16820a39f4e91986d2fe5bdc02992a03c2b2b2b313
MD5 1c56bd1843ee42bc3a7b1a64312d007a
BLAKE2b-256 5898dfed3966ed7fbd3aae56e123598f90dc206484092b8373d0a71e2d8b82a8

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp313-cp313-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp313-cp313-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 e37fab2be919ceb195db00d7f49ec220444b1ecaa07c03f7c1c874cacff9de83
MD5 21955f2438f25b63d5a43af2dfd27b3d
BLAKE2b-256 fa4ccb74c367f9efb874f2c8433fe9bf3e824f05cf719f2251d40e29e07f08c0

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 8e5c9ae65af5e572dca27d8ca0da4c5180b08473ac47e6f5329699e9455a5cc3
MD5 bbce6a69966c1690bec700512f513a29
BLAKE2b-256 52707b24e187aed3fb7ac2b29d2480a045559a509ef9fec54cffb8694a2d94af

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 681c6fbe3354aaa6251e6191ec89f5174ac3b9fbc4b4db606fea456d01969fcb
MD5 927e62960873e8eb278f14d8913f94df
BLAKE2b-256 89413b44386d636ac6467f0f13f45474c71fc3b90a4f0ba8b536de91b2845a09

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 675987c1b321dc8af593db8639e00c25277449b32e8c1b2ddd46b35f28d9fac4
MD5 7439165413dce4a1ec9e14c977c731e9
BLAKE2b-256 657d3e0a7f32b0ad5faa1d847c51191391552fa239821c95fc7c022688985df2

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 00ccc8d7284bc7360f310179d0b4d17e5ca3077bbe24427e9e9310df397e3831
MD5 d6844c72b3eff7ec08c41f6635b1eec5
BLAKE2b-256 2f0dbae1dcd2182ba5d9a5df33eb50b56dc5bbe67e31033d822e079aa8c1ff30

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp313-cp313-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp313-cp313-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 76b840ff13dde8838fd33cd096f2e7cadf2c21a499a67f695f53de57deab6ff8
MD5 23a562f6a418f62227d021e39ca65be1
BLAKE2b-256 abbccf0bc29f583096a842cf0f26ae2fe40c72ed5286d4548be99ecfcdbb17e2

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: granian-2.7.2-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 4.2 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for granian-2.7.2-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 1e438096c36ed6aa4f6c0c8dde22bebe08ac008d08257517b15182c262a08cfa
MD5 7c8ce57dacb30b39398c780868e020e8
BLAKE2b-256 39644502918f7d92a7e668d9e2fba83e2decbbf44c8ea896bacd8551d64f1d29

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp312-cp312-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp312-cp312-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 a052ed466da5922cb443435a95a0c751566943278a6f22cef3d2e19d4e7ecdea
MD5 79ea80864d71906f4070bcba3e03487a
BLAKE2b-256 c9faab39e39c6b78eab6b42cf5bb36f56badde2aaafc3807f03f781d00e7861a

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp312-cp312-musllinux_1_1_armv7l.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp312-cp312-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 41c7b8390b78647fe34662ed7296e1465dad4a5112af9b0ecf8e367083d6c76a
MD5 e8bc754d8c78fddc62250fa5f8fb7d14
BLAKE2b-256 ce243952c464432b904ec1cf537d2bd80d2dfde85524fa428ab9db2b5afe653c

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp312-cp312-musllinux_1_1_aarch64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp312-cp312-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 f761a748cc7f3843b430422d2539da679daf5d3ef0259a101b90d5e55a0aafa7
MD5 5e75969ba61e51588d0365de3fba3884
BLAKE2b-256 b199a35ed838a3095dcad02ae3944d19ebafe1d5a98cdc72bb61835fb5faf933

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp312-cp312-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp312-cp312-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 9cf69aaff6f632074ffbe7c1ee214e50f64be36101b7cb8253eeec1d460f2dba
MD5 01cc173874729c6232fca91dcd261f73
BLAKE2b-256 61c0a639ceabd59b8acae2d71b5c918fcb2d42f8ef98994eedcf9a8b6813731d

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 d9eda33dca2c8bc6471bb6e9e25863077bca3877a1bba4069cd5e0ee2de41765
MD5 7b5b895aa45101f8e39af50829652645
BLAKE2b-256 4709228626706554b389407270e2a6b19b7dee06d6890e8c01a39c6a785827fd

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 8c86081d8c87989db69650e9d0e50ed925b8cd5dad21e0a86aa72d7a45f45925
MD5 44798b4faf9fc4524a9a536a180fc162
BLAKE2b-256 7ee80f37b531d3cc96b8538cca2dc86eda92102e0ee345b30aa689354194a4cb

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 6d334d4fbefb97001e78aa8067deafb107b867c102ba2120b4b2ec989fa58a89
MD5 3363dd914a821c5c4393934fe23d61ec
BLAKE2b-256 ed50ece7dc8efe144542cd626b88b1475b649e2eaa3eb5f7541ca57390151b05

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 09b1c543ba30886dea515a156baf6d857bbb8b57dbfd8b012c578b93c80ef0c3
MD5 f6f8170dcb41cc35660951b274196294
BLAKE2b-256 1e0684ee67a68504836a52c48ec3b4b2b406cbd927c9b43aae89d82db8d097a0

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp312-cp312-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 a836f3f8ebfe61cb25d9afb655f2e5d3851154fd2ad97d47bb4fb202817212fc
MD5 7c23165d1a99028082e2a633302d090d
BLAKE2b-256 eced37f5d7d887ec9159dd8f5b1c9c38cee711d51016d203959f2d51c536a33b

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: granian-2.7.2-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 4.2 MB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for granian-2.7.2-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 7f8d5d16a1cd277cc6244f13f97d924b4cc0ea24506a71ca21b0546541d57ab0
MD5 1692af2d3879242532adf569cdb7636a
BLAKE2b-256 5392db2978c55dee2330868615526797a503f5d68f05dac05cb2e3a277e2b17c

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp311-cp311-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp311-cp311-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 ea46e3f43d94715aa89d1f2f5754753d46e6b653d561b82b0291e62a31bdfb35
MD5 aeb7ad55ca534f49bb7405bea59e5cfd
BLAKE2b-256 06c0ebd68144a3ce9ead1a3192ac02e1c26e4874df1257435ce6137adf92fedb

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp311-cp311-musllinux_1_1_armv7l.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp311-cp311-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 56ba4bef79d0ae3736328038deed2b5d281b11672bc0b08ffc8ce6210e406ef8
MD5 58de4172c2b2d597bee30b2dbf9685f0
BLAKE2b-256 ca51e5c923b1baa003f5b4b7fc148be6f8d2e3cabe55d41040fe8139da52e31b

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp311-cp311-musllinux_1_1_aarch64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp311-cp311-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 1f9a899123b0d084783626e5225608094f1d2f6fc81b3a7c77ab8daac33ab74a
MD5 c20500a4cba28dde48e3f9514c2ff2b7
BLAKE2b-256 ccad79eaae0cddd90c4e191b37674cedd8f4863b44465cb435b10396d0f12c82

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp311-cp311-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp311-cp311-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 ca4402e8f28a958f0c0f6ebff94cd0b04ca79690aded785648a438bc3c875ba3
MD5 c117a7f88fa9f5ba15eb734274cb2f6a
BLAKE2b-256 accda604e38237857f4ad4262eadc409f94fe08fed3e86fa0b8734479cc5bfb1

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 7f742f3ca1797a746fae4a9337fe5d966460c957fa8efeaccf464b872e158d3d
MD5 451b63179ae49ba2ec7c7197e105d232
BLAKE2b-256 659a5de24d7e2dba1aa9fbac6f0a80dace975cfac1b7c7624ece21da75a38987

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 6e377d03a638fecb6949ab05c8fd4a76f892993aed17c602d179bfd56aebc2de
MD5 9ac3881d60841d8568429afc0d5f364d
BLAKE2b-256 0a90e424fd8a703add1e8922390503be8d057882b35b42ba51796157aabd659b

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 f52338cfab08b8cdaadaa5b93665e0be5b4c4f718fbd132d76ceacacb9ff864e
MD5 321d21989e5a1befdc7cbc0e8a8001eb
BLAKE2b-256 67b77bf635bbdfb88dfc6591fa2ce5c3837ab9535e57e197a780c4a338363de7

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ee26f0258cc1b6ccf87c7bdcee6d1f90710505522fc9880ec02b299fb15679ad
MD5 efd7a7ba88522f049a00d5e84cf8a42e
BLAKE2b-256 2bdd398de0f273fdcf0e96bd70d8cd97364625176990e67457f11e23f95772bd

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp311-cp311-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 3a0d33ada95a1421e5a22d447d918e5615ff0aa37f12de5b84455afe89970875
MD5 81c80f881df3b9b6c71f71ee926194f9
BLAKE2b-256 f858dcf0e8a54b9a7f8b7482ed617bca08503a47eb6b702aea73cda9efd2c81c

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: granian-2.7.2-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 4.2 MB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for granian-2.7.2-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 3627a82c87a066f37ec15dae6f63372e748fc6a0d722c165700dfd4a466baa37
MD5 387a57a8623f116d7a6648a039b95fab
BLAKE2b-256 fe8ac18c2faf5dd7aacb016ffb513fa2b2b72ac7f8c9deb29e322595c030ab5a

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp310-cp310-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp310-cp310-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 bd2d0438d07a1f5daba035825a86abdafc44285ad4062c2a867dec107f0742c5
MD5 8c742011eb9105d9a918f55c29a177ae
BLAKE2b-256 2e42a767291821f3ac4aa57c1aa2fff729f9d547f256fc91a2e946dc66acf585

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp310-cp310-musllinux_1_1_armv7l.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp310-cp310-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 4b8b409cfe743130dad1f59edee9f729e6fe5e86bcba1cea633e8cc045beb6f5
MD5 1f67fa692891c1cf6461bc665397d382
BLAKE2b-256 bce8bf8f20535b1e830c7839439b61221885edd9449ab2261d5cbec9a84e20bb

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp310-cp310-musllinux_1_1_aarch64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp310-cp310-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 ec6027a53d88eca16620f0c617f4efa9961bfea74a48166619a291545bd9fc38
MD5 b979a8321e17a1f3439d75c10d4cf422
BLAKE2b-256 c39fc3bbfb9f1c7327b5deb68b69c03bc1f7cf55e723307d5ddc6e339f604aeb

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp310-cp310-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp310-cp310-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 2c7e1303e5b913298e3d7ada3a4a72c4ce75589574eee744ef30bc123a836a55
MD5 74a56feb6eb1b7b08fde55172ccd5905
BLAKE2b-256 686a91022ee4da3bd616ac2426aed2154c97dac8ef3cd50ac3d971d07ed168d6

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 2edda56ab8f15a83503b9e753785b0bcb01e7476418cb2326e683b3f2ca26202
MD5 c93c612eede583a8d5689c3376364f9d
BLAKE2b-256 8d287eb0ea0632b119ccd03f7ed6ca3a7bf6642fb7c680a7a5813a2a22b9dd17

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 24925bc301707c8bb21dd87a668e806a972a818a1929caa47f7af5f3108816fb
MD5 f264c3b4ceca472e6e3570c269ae3f8b
BLAKE2b-256 278f6b691e419d6ec78724351233a521c3c00131fc279b864ac9d374191bfcbe

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 3f4287275dd360935ed3d95da67da104d96ad9a19d4b9fde176dc7c3becf3553
MD5 aa2cbd1e22d45b8e042e0e60e8bce0b8
BLAKE2b-256 cfd1df30d998fab7317b4c9f81f76955c230d9b7e7a16d730388e7013b4c820d

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ae8786a13e8054c0dda96e9f22e27c5d94dcad72fc89de191ae5ea83e2d6b023
MD5 94177102cd1723dfc2f377ff331e221d
BLAKE2b-256 daeddc91f663d3681ba480ff028cb96fefde0b9db5318d1508b6a69691d4a78e

See more details on using hashes here.

File details

Details for the file granian-2.7.2-cp310-cp310-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for granian-2.7.2-cp310-cp310-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 c3a2e5734fc71d3b8c64ecb614570836b2c37a7df293d78de981a10f756464b0
MD5 7ed72e7232a1d71a3a6ef42851715368
BLAKE2b-256 15d425d4315e1bb07bb7ad9ce4558773ceaac70b023450e672586dac48675241

See more details on using hashes here.

Supported by

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