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.8.tar.gz (128.8 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.8-pp311-pypy311_pp73-win_amd64.whl (4.0 MB view details)

Uploaded PyPyWindows x86-64

granian-2.7.8-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl (6.9 MB view details)

Uploaded PyPymusllinux: musl 1.1+ x86-64

granian-2.7.8-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl (7.4 MB view details)

Uploaded PyPymusllinux: musl 1.1+ ARMv7l

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

Uploaded PyPymusllinux: musl 1.1+ ARM64

granian-2.7.8-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl (7.1 MB view details)

Uploaded PyPymanylinux: glibc 2.28+ ARM64

granian-2.7.8-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.8-pp311-pypy311_pp73-macosx_11_0_arm64.whl (6.2 MB view details)

Uploaded PyPymacOS 11.0+ ARM64

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

Uploaded PyPymacOS 10.12+ x86-64

granian-2.7.8-cp314-cp314t-win_amd64.whl (4.0 MB view details)

Uploaded CPython 3.14tWindows x86-64

granian-2.7.8-cp314-cp314t-musllinux_1_1_x86_64.whl (6.9 MB view details)

Uploaded CPython 3.14tmusllinux: musl 1.1+ x86-64

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

Uploaded CPython 3.14tmusllinux: musl 1.1+ ARMv7l

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

Uploaded CPython 3.14tmusllinux: musl 1.1+ ARM64

granian-2.7.8-cp314-cp314t-manylinux_2_28_aarch64.whl (6.8 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.28+ ARM64

granian-2.7.8-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (6.7 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.17+ x86-64

granian-2.7.8-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (7.3 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.17+ ARMv7l

granian-2.7.8-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.8-cp314-cp314t-macosx_11_0_arm64.whl (6.1 MB view details)

Uploaded CPython 3.14tmacOS 11.0+ ARM64

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

Uploaded CPython 3.14tmacOS 10.12+ x86-64

granian-2.7.8-cp314-cp314-win_amd64.whl (4.0 MB view details)

Uploaded CPython 3.14Windows x86-64

granian-2.7.8-cp314-cp314-musllinux_1_1_x86_64.whl (7.0 MB view details)

Uploaded CPython 3.14musllinux: musl 1.1+ x86-64

granian-2.7.8-cp314-cp314-musllinux_1_1_armv7l.whl (7.4 MB view details)

Uploaded CPython 3.14musllinux: musl 1.1+ ARMv7l

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

Uploaded CPython 3.14musllinux: musl 1.1+ ARM64

granian-2.7.8-cp314-cp314-manylinux_2_28_aarch64.whl (7.2 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.28+ ARM64

granian-2.7.8-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (7.0 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ x86-64

granian-2.7.8-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.8-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (7.3 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ ARMv7l

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

Uploaded CPython 3.14macOS 11.0+ ARM64

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

Uploaded CPython 3.14macOS 10.12+ x86-64

granian-2.7.8-cp313-cp313t-win_amd64.whl (4.0 MB view details)

Uploaded CPython 3.13tWindows x86-64

granian-2.7.8-cp313-cp313t-musllinux_1_1_x86_64.whl (7.0 MB view details)

Uploaded CPython 3.13tmusllinux: musl 1.1+ x86-64

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

Uploaded CPython 3.13tmusllinux: musl 1.1+ ARMv7l

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

Uploaded CPython 3.13tmusllinux: musl 1.1+ ARM64

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

Uploaded CPython 3.13tmanylinux: glibc 2.28+ ARM64

granian-2.7.8-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.8-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (7.2 MB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.17+ ARMv7l

granian-2.7.8-cp313-cp313t-manylinux_2_12_i686.manylinux2010_i686.whl (6.3 MB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.12+ i686

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

Uploaded CPython 3.13tmacOS 11.0+ ARM64

granian-2.7.8-cp313-cp313t-macosx_10_12_x86_64.whl (6.3 MB view details)

Uploaded CPython 3.13tmacOS 10.12+ x86-64

granian-2.7.8-cp313-cp313-win_amd64.whl (4.0 MB view details)

Uploaded CPython 3.13Windows x86-64

granian-2.7.8-cp313-cp313-musllinux_1_1_x86_64.whl (7.0 MB view details)

Uploaded CPython 3.13musllinux: musl 1.1+ x86-64

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

Uploaded CPython 3.13musllinux: musl 1.1+ ARMv7l

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

Uploaded CPython 3.13musllinux: musl 1.1+ ARM64

granian-2.7.8-cp313-cp313-manylinux_2_28_aarch64.whl (7.2 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ ARM64

granian-2.7.8-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.8-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl (6.5 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ i686

granian-2.7.8-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (7.2 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARMv7l

granian-2.7.8-cp313-cp313-macosx_11_0_arm64.whl (6.2 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

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

Uploaded CPython 3.13macOS 10.12+ x86-64

granian-2.7.8-cp312-cp312-win_amd64.whl (4.0 MB view details)

Uploaded CPython 3.12Windows x86-64

granian-2.7.8-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.8-cp312-cp312-musllinux_1_1_armv7l.whl (7.3 MB view details)

Uploaded CPython 3.12musllinux: musl 1.1+ ARMv7l

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

Uploaded CPython 3.12musllinux: musl 1.1+ ARM64

granian-2.7.8-cp312-cp312-manylinux_2_28_aarch64.whl (7.2 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ ARM64

granian-2.7.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (6.9 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

granian-2.7.8-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl (6.5 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ i686

granian-2.7.8-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (7.2 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARMv7l

granian-2.7.8-cp312-cp312-macosx_11_0_arm64.whl (6.2 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

granian-2.7.8-cp312-cp312-macosx_10_12_x86_64.whl (6.4 MB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

granian-2.7.8-cp311-cp311-win_amd64.whl (4.0 MB view details)

Uploaded CPython 3.11Windows x86-64

granian-2.7.8-cp311-cp311-musllinux_1_1_x86_64.whl (6.9 MB view details)

Uploaded CPython 3.11musllinux: musl 1.1+ x86-64

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

Uploaded CPython 3.11musllinux: musl 1.1+ ARMv7l

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

Uploaded CPython 3.11musllinux: musl 1.1+ ARM64

granian-2.7.8-cp311-cp311-manylinux_2_28_aarch64.whl (7.1 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ ARM64

granian-2.7.8-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.8-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl (6.4 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ i686

granian-2.7.8-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (7.2 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ARMv7l

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

Uploaded CPython 3.11macOS 11.0+ ARM64

granian-2.7.8-cp311-cp311-macosx_10_12_x86_64.whl (6.4 MB view details)

Uploaded CPython 3.11macOS 10.12+ x86-64

granian-2.7.8-cp310-cp310-win_amd64.whl (4.0 MB view details)

Uploaded CPython 3.10Windows x86-64

granian-2.7.8-cp310-cp310-musllinux_1_1_x86_64.whl (6.9 MB view details)

Uploaded CPython 3.10musllinux: musl 1.1+ x86-64

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

Uploaded CPython 3.10musllinux: musl 1.1+ ARMv7l

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

Uploaded CPython 3.10musllinux: musl 1.1+ ARM64

granian-2.7.8-cp310-cp310-manylinux_2_28_aarch64.whl (7.1 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ ARM64

granian-2.7.8-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.8-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl (6.4 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ i686

granian-2.7.8-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (7.2 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ ARMv7l

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

Uploaded CPython 3.10macOS 11.0+ ARM64

granian-2.7.8-cp310-cp310-macosx_10_12_x86_64.whl (6.4 MB view details)

Uploaded CPython 3.10macOS 10.12+ x86-64

File details

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

File metadata

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

File hashes

Hashes for granian-2.7.8.tar.gz
Algorithm Hash digest
SHA256 e384b1f08ed3deebdee3516c6db583a26aa20d5e893ce8e8867301fda3902c10
MD5 29dc8eab262a807fc19150caa541ecba
BLAKE2b-256 98d570694e4d7ed4e065a1b3a53695a02fe575bad5cca91c4a0107dfb02711ed

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-pp311-pypy311_pp73-win_amd64.whl
Algorithm Hash digest
SHA256 1659018e97fcb75f58efb2a3ed8a6ffbb1b1a1f414c3343be36b5d48d281ac93
MD5 44317c1dbce07ba9d231e9ed624d49c5
BLAKE2b-256 af58f80bf89dfccbf1ae339b7d147b8fb5882d89ec9ccbbeef1e2ed99e9133db

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 08cbac5715cf9d48f018d5666a3c2a9303549a5169ed7dcd44c452aebe6e4c10
MD5 1cc7793e087b1c604e3137644110bdb1
BLAKE2b-256 df7fa715a90bbcaf6f71785cadfb90a318c07890037c9c0f621eb09373c8fe2b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 064c800677bc9e019ca5d10ee66b27c173f98dbbadbe59a0cbc9515f65a2f786
MD5 a073573171c938a743c9f98099f00e5a
BLAKE2b-256 8805482c725e09b682742cb4b06b9face75d974518d4e5d94deca0776068fd04

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 e152c5412056f203b26ea6b331771c9e92ea513601d14644e5b21d040ed3e211
MD5 6a9e445c67fd1bf16fab921313a0747e
BLAKE2b-256 c5cec628daf6a7071d5cceadce24f058afaa420cf86da1d5c0114a921131e281

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 aba7ea80143fc0ca83584781021d74d39593bb18c48c54d8a5511119804cad0b
MD5 b440f8289005f1d410f041e3ee85d9ff
BLAKE2b-256 ce5c813efe18addb5d59b5e5d95d178ce4e12f6d84adcaf56e94bf82c348a174

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 7394cf4f8c6fe074b03182fc63b2ede55812ebfc548eae6b4104eee2d4059991
MD5 fa7468318362ca80bada95b8ba085a6d
BLAKE2b-256 9c18e49dae62f596dc14aef106eff66fa530555188651d7b0f54e6a37e3f6eb9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-pp311-pypy311_pp73-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 83f74e504268df9354e8aca6da81cba3215fb0709d524adcf2d6ec05c6c16cca
MD5 881f55af2b39b69200426297d5a94937
BLAKE2b-256 75593b0e1449ed53587f7e88a10c272ef2df71621f53b293142d091b2c11b408

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-pp311-pypy311_pp73-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 d0759e53fce8b511ec182c552b280b814bd60c599ab543432eae77cc59d0c239
MD5 a415c445be02aabfbd042e44cb8ad9f3
BLAKE2b-256 f64f4d7bc6f60fc8e852a015b4eac6dd9ceae354846fb20c5b6f4a7a0b267d35

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for granian-2.7.8-cp314-cp314t-win_amd64.whl
Algorithm Hash digest
SHA256 b0d588fd0769730b68d767bdc9013e8069a1a29bbe16b67699bf8500227f8f2b
MD5 526e2204e38aab889af1f1bc91db7893
BLAKE2b-256 e920c14507ee2e62800bb356ca782757e2bb7acc65cff8ff80b83fffe71e3301

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp314-cp314t-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 a2c0be25fc3c55a6cad9b6c2e9f54fd55937591e708ca0bf5db394cc0b34bf7c
MD5 98c9789f1672de6cd94c047e93f377d5
BLAKE2b-256 51991976784d46e78452555b2c552e7ec636b5c10f9f4a7e18dddc0d9718e235

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp314-cp314t-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 efe6bf9cb1e220d6eefb529f34c7a7edf30003a4cd023e65b8a58f2c9feca769
MD5 77548e57beb5818bfb465c170c30ef87
BLAKE2b-256 d77c8621d04b92eb1380ef0b2539b9dcac161af494681e479328556aaa39fb34

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp314-cp314t-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 5e4583a1b013eb7eb4032cfdf7f755714d2df1fb876f73357239a8fff22e579e
MD5 8b82711246e0aa2d707a3a30b0a6e3f4
BLAKE2b-256 974724d84410f76eb5abd6c96d982ffeed02369bce98543487cd37407639aa63

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp314-cp314t-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 3ed3e3f0c0813a6df13da2a1f738afaab41183d7171e65eeb0088204e5fb8ec9
MD5 6828b319c694f207013dd2fe929fd813
BLAKE2b-256 0268ac3333fa30bce76092797b5b2abcc095c0af412a958201778da63808df18

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 5333919dc120abb09e5fefc8d61a56a7729d30ddd612974a0e8589cfccea8ad3
MD5 7163e75efc374b5889f037fa7cf8149e
BLAKE2b-256 9ab43d81ef6a048ca2c860be884b141db65945326edd31f95d841fdd03be7bee

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 686aac81a28f6285a8748f847a6650e2096da6c93e022b4fafbd2c4bd1a27469
MD5 409ca27b67cb3d35a5f2988a79077f47
BLAKE2b-256 e732e99264e9074533a00bb8c2f0586e1895e898a3f57212d79f34aadda22e23

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 7697330c3a6316d29dcc92de264a6b89d9bb45a1601ee76652f43dab6ac03126
MD5 70fc711a819706bdf937548b6cb9c3e9
BLAKE2b-256 510017e53f13c6f27f96fa8566b5585d25b5ed27a2658ddc7166bdd03d09019c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp314-cp314t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 5e79f15e461e5cf94e3f13d6f1eba6d777db128e5b64c284c077dabdc7d879fa
MD5 bb2669a34e1eb3091842625ebd7fef1c
BLAKE2b-256 867f84ac8f8e7258d1e70864e11f7f8146538ffe7e45d2dbcb698d5f97251805

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp314-cp314t-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 0508113eaf4d74079e110b267927b843dc8528f56ca1a84bc9a7e5438507b449
MD5 5f2ab601934fa7439efc119f6164d5bc
BLAKE2b-256 ac62f56c030b7f6f912b7b7227771b247a7bceffe9b7ee513d9822c4e1b0a0b3

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for granian-2.7.8-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 22096b38513b142e1bccc42c2a8fac013250e47f26c1bf1514c24a5ac33ccb87
MD5 5331e14e31b860ef836689625c5b3394
BLAKE2b-256 4c09e21ca0e8174dd6502151a9420d780c2acb94ee90a1b22ce0a26a479f32a6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp314-cp314-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 805a4cf75dff1ff4f8ac0bd46016e74893e43f28e319bed50ab46149fabf2ea7
MD5 68f6ea144f7996309c5776efafe54812
BLAKE2b-256 032cf8031160c11464fc9f9c4a87dbbda69cc86afa52f6e93866a0b65851958d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp314-cp314-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 28167bbd887a91e537e66a4b52e117b270bc67b5c9ce6e21734fd200acfdae24
MD5 72ad136537f56c8b351ebd25a3c1077a
BLAKE2b-256 0110986ae9776f346aaf2d1ca6c96f4ea4bd2ceb64e0b348d747161f231d2ce5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp314-cp314-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 d8cf6e5b0f13f09136f3573f8317eeccf625c65daf28b35e54ea3378938739cc
MD5 6cfe4b55cc41087db172c08e0b028642
BLAKE2b-256 d1169e7d1aff7ff58ed6c746dfb27398c91995d78844f46229e63c406403a3ed

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp314-cp314-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 df2f19313a399b02df5edcd4113bd8a9e08dcc05a1dc92c7f6f72517121389c1
MD5 8c1d0b2d0b1e355292c70630977a564d
BLAKE2b-256 912c9dac305c16276cc8b2b4a74ab47a8deaeff9ae8e4d9455d1322cf7477429

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 ee71a2e3da5fb8c673eaa9a3cdbfe231555a62a5dd2ffbbdd45dad3640747fd9
MD5 f1acf7545305422154b69429436df95e
BLAKE2b-256 12cf437bbddc90c8d93121df8ba8c33a45e7f839d5d1d9f62cb0599eeb6f4570

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 f87f8dc11fc4bfcdffb7dfa2f6927cb08cd1f34d688dbdcb9a399f457f170949
MD5 2b031de1e1ee5f0d45f6137a4d9a4a6e
BLAKE2b-256 7418f14b882c99446a6fcdcc0317cc4e35cea939122dbd4e86da400cf9315a7a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 c20c6dbbb0027b7c07eb19d24bbe497632e1f07537f922f5feebecb36f2d0d6b
MD5 da77a1dddc139c06bccecea29ffe2a0b
BLAKE2b-256 b9260d9d5cd84e7ee3003d7fed448b4547c0ceaea649e6500ca69541c35c420a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2b667b2af53e1536535d41232593640603d1098be192efa1bb20a0aa53f4efad
MD5 e491bbd5f2442e9d27e822f4837ecfcc
BLAKE2b-256 a3a9b84432d92ebba56402ca82a8482da4bf4b229411a17b806547da0d4830e3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp314-cp314-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 6e044d41e3610c79c23694dd780225745da743df77085bdc02db0aa9bb1616e0
MD5 b6dde735b09802a7c683167c1f91110b
BLAKE2b-256 02f40a54b6d7b244938e16bef7ab35501c9946012305c00d1438fc78d060d606

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for granian-2.7.8-cp313-cp313t-win_amd64.whl
Algorithm Hash digest
SHA256 6fb67bf33cd6a7d30df2b21c973699d932cb15ee84f5573d13a985dacb5e7261
MD5 042005b4eb9f7c9fcae1404a24c9c959
BLAKE2b-256 ee9826b0c48e120cea36762b738751dea42b5b5529c74c0c48e9bd524c064252

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp313-cp313t-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 6c27288f561689bfbc91275ce4fe3596d1e1f6923158b528673014f6d52f63bd
MD5 93a002a8f3857f007a7b5c88b42968ad
BLAKE2b-256 767c971c4ebd7e7bf68d8731a822d720911c1252fd0cfe1b77c951c81a6c0985

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp313-cp313t-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 1f861fdb01aa86682f786d62320c60d114101945c8a6c4d46e1a5133ed170fa5
MD5 19f0a1225e6466fa9b34e7330c576ef5
BLAKE2b-256 402d81fe4cddceaabc6bf454a64e3141725cbad93043445c34519fed0a984237

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp313-cp313t-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 85570cc41db97a11dbd6c2e393d6438f62a649de11f11bafb09c99b8127e2aae
MD5 81c3af4a61dbee1664d6bf28898bdf3d
BLAKE2b-256 ea0f68769de4e9ab2bcc845e889dee149c86df1b455ecb8af011d624f87c4498

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp313-cp313t-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 4282c77e583c7e69701c94e590cbdd5f3b7e9cfbe2f3a018cd14f428cf9587e6
MD5 9ef148980b9b1cee3058838fa09959c4
BLAKE2b-256 e18a5c6e47be75f8af62d942d574e114318a96116e0ff79da49bbd477c7b0022

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 7fbd4910078f950944f418e49d244a4a8bb0ac7bf548deb6b0c3ae41726ed16f
MD5 c92cc040c5aabad67e91f12a98535e0c
BLAKE2b-256 23bbbc1b836e1a7efb03e78c8ac94e9ae2dd76606ffd48b5ac1db4756ea45eb1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 ff6e3d4eabef33d76cf02afc50b7b77460cf0ba8e0bd00e9b705a6c2d6b7c6c6
MD5 f20c8961c4a41ad33c67ba4f2c5481d4
BLAKE2b-256 1141d22e4b7dead21558da9c07a2cd8436912c77b49f114a59a71fe7bd49c3d2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp313-cp313t-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 a0c2448ddc8eb96db67531d4fdd71d9349de57b923756b54060f90ec0fe7bdc9
MD5 f20669d0cdab2207d65d8b6ef7fed9d8
BLAKE2b-256 48884d6834d5a7eb646c8a79f9a2ac9fe9bac1a68058ba199fecfb7b9013c74a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp313-cp313t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 cfa1e8745d3a9f855eb6213fba33a6fab0fafe28aa0bf12d511e1174415f7066
MD5 aa45e3c9439a352dd29813470e19e3f4
BLAKE2b-256 df9d5310ff5c409c45e5b4265ef8b7845aeef1b8748ef53e5b3451bb4b416a8a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp313-cp313t-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 c49c42d50a89ac66dede690b8a5b41d84973e9df3bd5f604e4338c134e9a2619
MD5 e031add4af989babc2ac638aa9960327
BLAKE2b-256 b9951d1384785249012d4d91ad14594fc5609017bd864474919c6dc463f873bb

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for granian-2.7.8-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 b40187b6bf8b98c3c5f55989b443280a234c66b3b40e4cf2a8e76303a1e78658
MD5 d708bf6e08c38c915eb748d1693d16a1
BLAKE2b-256 e83ea0bada2a74d67166f872251f66195cd0d369f2a500abf161f2766c8f3197

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp313-cp313-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 0572d0fc41c7c6429ed8adf0c37979e2fe661a9410d795991e32c06771ed972f
MD5 c579292d6d8170dac01ddc0617abb16a
BLAKE2b-256 078957b6dc76eb0a686c5ddd383f68a7d301e717e73b0867399071b8c86b02dc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp313-cp313-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 055ab90bf11b7e3e149f104a4e33069748cb09997f57b68a248f447dd9f8a9ec
MD5 df5b93f4c9b0796caefd71263eb28024
BLAKE2b-256 653e7aa8a1968e309f79ef9c1a196485392cbb4ea90886f067a0060ab5f88029

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp313-cp313-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 53f588a59db89c422aeaf6f0a5d1144dd688a753223abdb5a22c980792c80962
MD5 b358f03d7b3e89d6fb09dcd0f10fa7d8
BLAKE2b-256 365e737d0d84456d5be9a5249bcf7cc9eba731a70a0a03ccd7cdecd2addddccb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp313-cp313-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 46feb2cc36bbf262ac29e79496bd42554d036a35ab45f7e517c315925c8f8034
MD5 65f667cd8fe31595fbbcc5b571aea1bc
BLAKE2b-256 90c1a4f84be3a4ae7fe3c028ad7ab2cbec683b79ee21be7020ab3adbeff3abb2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 7d22943980c7516a64411e04d7119c0ae7cf540fc4a6ec09c60f4c8d633581df
MD5 05d6b0e15aa5f3ee5fbbead3e178fda5
BLAKE2b-256 208261859412d613c29f4a8ffe9fdcaf1393958eaf4932891ec3b7ee45464344

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 ab76cb78726adee52cd2565e0cc5e26508fd3519a16b634fb0207c95405c9814
MD5 2d0ac37e452a4c3710a2cc644d20d6be
BLAKE2b-256 a05ac0e616da2ada06cb455b81833d2ca5ac567c762082c88f285489beaca183

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 20378307e8705cc328ab512de6a7d72590e3406bbd7094f90b1124c2d402224f
MD5 ce3e8ed14e4e12ffa9741d8504a7448d
BLAKE2b-256 d11725a622b68afe99f81a60f2e94232e4bedc888beea415d806fbc8d2e37bf1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 8c532e2d58a6d7078caabbbd725d3d08414d0929438b1c28af88255d0fdde615
MD5 dfd9feacd8e86a75c03d7907a104b5d8
BLAKE2b-256 f0d7b52fdb8202afac25ee638a07561464b598b26ff1542186d54113d5b13724

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp313-cp313-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 d75394668a8465cc053266b589593d43b185f986ec67d324d91d02a227a35f8c
MD5 48553d15814ad0151dfb738b5b82e7f8
BLAKE2b-256 a17ed00becd226e5076da180e9a735a397c6c750590e49f04004411949fd5b53

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for granian-2.7.8-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 46c4b81ad590af60aed5727926edcc80f0f8ebf16e6e2effb3c78eb4399c5be6
MD5 0c16782b218dabc87e9cd5cccfc46a5f
BLAKE2b-256 0c04dccd3f261affa376adf679b88264cd3456ab19c0e408435e3107acaf581b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp312-cp312-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 6714233ac6041ae201cfbf9b5978b18979268604ac2616278a4281a973ddfe18
MD5 fdb32c1da9664e3f008192074477d874
BLAKE2b-256 c5f66601110db897c76c69025ede25041f174090810b735ffa90ca16f48406ba

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp312-cp312-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 bca090674248ce007f9996458b88746980a415432301fb6cad7ca9cfd7b19db5
MD5 e6560ae4fd793fb1e9df7c160569fd21
BLAKE2b-256 16a3606da026cd23dfcf566a786a35cf780dc9ba15c0dd46c506253934ab0f03

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp312-cp312-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 cf58286ae4a34b8d58d327d82943e92221343e2a65b85f0c6d1ce41e2ed93b3d
MD5 e6a309f8dbba9d345af995a74af0f11f
BLAKE2b-256 3be6686452abe5a46708047d7e3ed50798534bd9745163fd830ae8b7843af98a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp312-cp312-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 7a5832921130cdfbc67a893e284ccc90e4ed09208eee9574e110cd18506ad676
MD5 44b52c56854c5c1e3dc2a130f648ea9e
BLAKE2b-256 16a749b0a0a0bc8457148518f87a776098abe5ff374f82ca5d48788ee94478e6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 6b212dc338595d3ee0b25af172413e5de7497ce2120c75e03f5808c8ba68b987
MD5 c08c85bc86e0fb111b18b79bc248b598
BLAKE2b-256 90e1e9535c775dcdbea52a7ac9ca46b7be788bde2050a12b11d3f99eb5ce4427

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 ba4b7d0b058a562cbce184076999df929c2a2fad3686532f4260dd8c19e8ad4f
MD5 4a37e4c92168d5fecbbf526c631c64b5
BLAKE2b-256 57b05ce2ad7fc6621f7bc8c32dcbaacbb432912c09b8c9f31355bedbf561e3cf

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 806451ace414b5069d683486340d697a68bc0c67347c7fbc2eaa9c2f97aad4f0
MD5 c9d8b47f9063ebae6466d78564ec24b4
BLAKE2b-256 696bb4bb56842b2798c3d03dd4e69c7d31ae8b2b837a7a48fa7b5ff2ed7195cc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7be22a64a52322a7521bdd427197478c54158136093e38eddc6f23c102897134
MD5 383dcbbcfb33696243582f8f51aa5e20
BLAKE2b-256 b65487cdd465be35ee3eb3cf8202c2823c6d65d3d903de5ed1fed305b74819c0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 7ea0f5e70bae07da53435e43dd2e0c4313dbcdd79cb02fb6e5b22d6740a7b389
MD5 fbb1824542152c9a1c53cb2f8e8b1650
BLAKE2b-256 3c59d5aa3d0866b9ac5437b628a6661584522b5c54ec67247f13beebcf524502

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for granian-2.7.8-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 a1bbe2682b273539893dca42ab89dcbc1bc31b9d6e9c2c4ccb6d8e8bd29bf74e
MD5 99eec2d006832b850974507ca7d07385
BLAKE2b-256 930989f578f0d9af4627fceaf0a163609aa57614ec2ad9f5fdaf6a7bcf445ab7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp311-cp311-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 d20a44340035da0b0197799e06d1d859678a1a1445b74d6b16ae8d968ca7c00a
MD5 7bd7124b74eb4fbe8a17c7d6e6018b39
BLAKE2b-256 0d626a4a5da3f34a3b4c2635e4176aa5fb5e04fed493129acac1a29b8f18481f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp311-cp311-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 7c7ab8158bea3ff0236ba646a511ab05d816898b555ea672093a08ec56a8f38e
MD5 80992b5cabf19b3f99845b5d7c6ebc16
BLAKE2b-256 95527e35223193a72465695394de79f26f889dcd0d7c95804180bf5350467fdd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp311-cp311-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 57fc8743252d4c9a3a9d1298fd9a8ed024605bf20e9fc07ff36ca7c256b96edc
MD5 8f62e74c13a3206b9e278db3c0600678
BLAKE2b-256 d08b5ac6256ba101995cd49f8aea93a88fb0b6363fc39d65b67348a442b1511b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp311-cp311-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 a724ebd0c9ecd9e49bc8b5a3db517a393ba3670899633689038e6a8e938318c3
MD5 7a1abc4b4b2f659a06f8d46adcacd2f8
BLAKE2b-256 b97bcf2c19703e1e66058065c000964c8a68b0db8504849d28da3c208ce2907f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 4828b0fcdce826bd42cf66237e2025aa5a0cffa39a7b0b2ad95b3c10e510f7ee
MD5 15fa0e9b9f9902501aea036848557014
BLAKE2b-256 42560642dd715f46869651908832869841bd848025c2a364586d4bfc30c9b04f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 720b97e070efbd8c6cb350809e080e870815162c36308d9a8db81662b5455545
MD5 45c2519ec4d08f67a7caa9576d5e20c9
BLAKE2b-256 8ed94ddb1128fc269656fbb3876edf0321a3883336a9a54176147477bc291cb5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 5f469f09046fc9c2f93e820a21ca1f724a94c0e838368b290c86e6de38462ae3
MD5 c5d5ed405474b7e37dd0f880f2c4c8d0
BLAKE2b-256 fad01e14b1749e67f6c2f6ea944b5382b13a6828958e22687c2c17c68dfcbb3f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f3bae5903575401896c7989ea79ee2e30f95f8e7f3c851c19187101b9e155b78
MD5 4553417abfacc06a0e7cb629d2cfa4ea
BLAKE2b-256 113e58f2563878eab4e4c9263eb69745a32ba525cde2e25a954eacc86777febc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 d078d553d1a18d9ee5d372a25f169359e972d6a4fa0829aa9f0424514715f157
MD5 a88e41e2a190a4b519565b39b2342740
BLAKE2b-256 d4832c77df42c1bb243428979a55e68f516fbe086369d69cce1f947d016ebaaf

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for granian-2.7.8-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 9e651a2b23a9c38b61e9cecdd88aa8c7b07e4024134203abbb7956404ab5f7f8
MD5 5c2a575dfaaec858d5577eab19a5f7d5
BLAKE2b-256 ea92663e0fcbb8a3544b424f4866ddefda09ea53b18c8883be98eb1ce6f3f168

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp310-cp310-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 038587913bee060a0d6ea1fea32541e521985860e2f996635b4eddb016fe25ce
MD5 21655994966c9afb0bf4faffbe16d426
BLAKE2b-256 5db22c3715e47c59f1cd7cb0d0a1c707daff01b7502ef2aeb71baf6e67b5d157

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp310-cp310-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 c76018acc9dd1e44da7c07b622697a94bd4531c946aaa67c66a0812b888ff020
MD5 32202b9d073f682d5e8dbfb9fed7d9ed
BLAKE2b-256 fc0d02e3e2b78d351e493feaeafa45329ac7258c92d62f2cf3b3bdef8d45c173

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp310-cp310-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 c2682ffe5e76d0aa11270d5a7a3ad7b3c24a2ac5f399fdbdc27d35d579188895
MD5 c94d5257c816edc7de2923ca37c673fe
BLAKE2b-256 63d5187e2772ab7e211ea40ea00d965369fa1afc921c89c1d1cda64344aef927

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp310-cp310-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 577a476d5c6225eb8e980f24ed5f48c3e893adf066dd37029fa1e18511ea1cf8
MD5 a7ad1fc23cd08537e9723ea00259895d
BLAKE2b-256 94721f123ac02c0651201f69064dd43c6f6032a924fea9837c3e98732f521ed4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 4359dbd2805c0500358261bc75149193539acc4d8251adc7c821b5c05c5446dc
MD5 d4d3121f48109dac4adbc38266c0fbae
BLAKE2b-256 67894facd091003f3e3171539b3779f4aa3f1c1dc7a7044e0f80217ef939eb3f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 4b4b947ec7b9a4bfc22b7ab84cf5dd3dadd00bc09b1d49bb37376b4f823fbd6f
MD5 99310e425ab6f7445f40971f5d0a0a28
BLAKE2b-256 f302939fa01af5172d72c28ceb43995291b699035030c6e4bc6bc53c12d02518

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 9d4c5ad2cede6805b906f367b75f29c1978f7cfd95094fd5639dea584bee1b96
MD5 7a7588c4da8ef31c4cd7fd87739be8ad
BLAKE2b-256 9bfbd9a70ea895d7850d7d1a07cd176a7227165ef5db45f5876d35336ad047e1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 83c5eb3d6b37b05a80e376620d20ef9f8cc776718b489bc65d75a71499138d1f
MD5 6de5293c27ea943611472897bc9dd233
BLAKE2b-256 c6d6eb17192ec8cf9d0379dae21e0943e035535fe4b7dd7e2afd6aaa8b1d9c67

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.8-cp310-cp310-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 0a2df87048484eb7b026e83d20a9532944e23c3260ff34d36d2b5e55ee3b6555
MD5 c4bde9b3b40b14aad9f035e51dd3ef1f
BLAKE2b-256 c51902b469ca6007641b2c53d8053a47340bb51b817abff4f9d0ee92329f1dfb

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