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

Uploaded PyPyWindows x86-64

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

Uploaded PyPymusllinux: musl 1.1+ x86-64

granian-2.7.4-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl (7.1 MB view details)

Uploaded PyPymusllinux: musl 1.1+ ARMv7l

granian-2.7.4-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl (6.9 MB view details)

Uploaded PyPymusllinux: musl 1.1+ ARM64

granian-2.7.4-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl (6.8 MB view details)

Uploaded PyPymanylinux: glibc 2.28+ ARM64

granian-2.7.4-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (6.8 MB view details)

Uploaded PyPymanylinux: glibc 2.17+ x86-64

granian-2.7.4-pp311-pypy311_pp73-macosx_11_0_arm64.whl (6.0 MB view details)

Uploaded PyPymacOS 11.0+ ARM64

granian-2.7.4-pp311-pypy311_pp73-macosx_10_12_x86_64.whl (6.4 MB view details)

Uploaded PyPymacOS 10.12+ x86-64

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

Uploaded CPython 3.14tWindows x86-64

granian-2.7.4-cp314-cp314t-musllinux_1_1_x86_64.whl (6.8 MB view details)

Uploaded CPython 3.14tmusllinux: musl 1.1+ x86-64

granian-2.7.4-cp314-cp314t-musllinux_1_1_armv7l.whl (7.1 MB view details)

Uploaded CPython 3.14tmusllinux: musl 1.1+ ARMv7l

granian-2.7.4-cp314-cp314t-musllinux_1_1_aarch64.whl (6.8 MB view details)

Uploaded CPython 3.14tmusllinux: musl 1.1+ ARM64

granian-2.7.4-cp314-cp314t-manylinux_2_28_aarch64.whl (6.7 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.28+ ARM64

granian-2.7.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (6.6 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.17+ x86-64

granian-2.7.4-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (7.0 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.17+ ARMv7l

granian-2.7.4-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl (6.0 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.12+ i686

granian-2.7.4-cp314-cp314t-macosx_11_0_arm64.whl (5.9 MB view details)

Uploaded CPython 3.14tmacOS 11.0+ ARM64

granian-2.7.4-cp314-cp314t-macosx_10_12_x86_64.whl (6.3 MB view details)

Uploaded CPython 3.14tmacOS 10.12+ x86-64

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

Uploaded CPython 3.14Windows x86-64

granian-2.7.4-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.4-cp314-cp314-musllinux_1_1_armv7l.whl (7.1 MB view details)

Uploaded CPython 3.14musllinux: musl 1.1+ ARMv7l

granian-2.7.4-cp314-cp314-musllinux_1_1_aarch64.whl (6.9 MB view details)

Uploaded CPython 3.14musllinux: musl 1.1+ ARM64

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

Uploaded CPython 3.14manylinux: glibc 2.28+ ARM64

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

Uploaded CPython 3.14manylinux: glibc 2.17+ x86-64

granian-2.7.4-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl (6.3 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ i686

granian-2.7.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (7.0 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ ARMv7l

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

Uploaded CPython 3.14macOS 11.0+ ARM64

granian-2.7.4-cp314-cp314-macosx_10_12_x86_64.whl (6.3 MB view details)

Uploaded CPython 3.14macOS 10.12+ x86-64

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

Uploaded CPython 3.13tWindows x86-64

granian-2.7.4-cp313-cp313t-musllinux_1_1_x86_64.whl (6.8 MB view details)

Uploaded CPython 3.13tmusllinux: musl 1.1+ x86-64

granian-2.7.4-cp313-cp313t-musllinux_1_1_armv7l.whl (7.1 MB view details)

Uploaded CPython 3.13tmusllinux: musl 1.1+ ARMv7l

granian-2.7.4-cp313-cp313t-musllinux_1_1_aarch64.whl (6.8 MB view details)

Uploaded CPython 3.13tmusllinux: musl 1.1+ ARM64

granian-2.7.4-cp313-cp313t-manylinux_2_28_aarch64.whl (6.7 MB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.28+ ARM64

granian-2.7.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (6.6 MB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.17+ x86-64

granian-2.7.4-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (7.0 MB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.17+ ARMv7l

granian-2.7.4-cp313-cp313t-manylinux_2_12_i686.manylinux2010_i686.whl (6.0 MB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.12+ i686

granian-2.7.4-cp313-cp313t-macosx_11_0_arm64.whl (5.9 MB view details)

Uploaded CPython 3.13tmacOS 11.0+ ARM64

granian-2.7.4-cp313-cp313t-macosx_10_12_x86_64.whl (6.2 MB view details)

Uploaded CPython 3.13tmacOS 10.12+ x86-64

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

Uploaded CPython 3.13Windows x86-64

granian-2.7.4-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.4-cp313-cp313-musllinux_1_1_armv7l.whl (7.1 MB view details)

Uploaded CPython 3.13musllinux: musl 1.1+ ARMv7l

granian-2.7.4-cp313-cp313-musllinux_1_1_aarch64.whl (7.0 MB view details)

Uploaded CPython 3.13musllinux: musl 1.1+ ARM64

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

Uploaded CPython 3.13manylinux: glibc 2.28+ ARM64

granian-2.7.4-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.4-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl (6.3 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ i686

granian-2.7.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (7.0 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARMv7l

granian-2.7.4-cp313-cp313-macosx_11_0_arm64.whl (6.0 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

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

Uploaded CPython 3.13macOS 10.12+ x86-64

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

Uploaded CPython 3.12Windows x86-64

granian-2.7.4-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.4-cp312-cp312-musllinux_1_1_armv7l.whl (7.1 MB view details)

Uploaded CPython 3.12musllinux: musl 1.1+ ARMv7l

granian-2.7.4-cp312-cp312-musllinux_1_1_aarch64.whl (7.0 MB view details)

Uploaded CPython 3.12musllinux: musl 1.1+ ARM64

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

Uploaded CPython 3.12manylinux: glibc 2.28+ ARM64

granian-2.7.4-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.4-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl (6.3 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ i686

granian-2.7.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (7.0 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARMv7l

granian-2.7.4-cp312-cp312-macosx_11_0_arm64.whl (6.0 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

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

Uploaded CPython 3.12macOS 10.12+ x86-64

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

Uploaded CPython 3.11Windows x86-64

granian-2.7.4-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.4-cp311-cp311-musllinux_1_1_armv7l.whl (7.1 MB view details)

Uploaded CPython 3.11musllinux: musl 1.1+ ARMv7l

granian-2.7.4-cp311-cp311-musllinux_1_1_aarch64.whl (6.9 MB view details)

Uploaded CPython 3.11musllinux: musl 1.1+ ARM64

granian-2.7.4-cp311-cp311-manylinux_2_28_aarch64.whl (6.9 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ ARM64

granian-2.7.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (6.8 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

granian-2.7.4-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl (6.1 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ i686

granian-2.7.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (6.9 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ARMv7l

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

Uploaded CPython 3.11macOS 11.0+ ARM64

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

Uploaded CPython 3.11macOS 10.12+ x86-64

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

Uploaded CPython 3.10Windows x86-64

granian-2.7.4-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.4-cp310-cp310-musllinux_1_1_armv7l.whl (7.1 MB view details)

Uploaded CPython 3.10musllinux: musl 1.1+ ARMv7l

granian-2.7.4-cp310-cp310-musllinux_1_1_aarch64.whl (6.9 MB view details)

Uploaded CPython 3.10musllinux: musl 1.1+ ARM64

granian-2.7.4-cp310-cp310-manylinux_2_28_aarch64.whl (6.9 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ ARM64

granian-2.7.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (6.8 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

granian-2.7.4-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl (6.1 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ i686

granian-2.7.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (6.9 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ ARMv7l

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

Uploaded CPython 3.10macOS 11.0+ ARM64

granian-2.7.4-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.4.tar.gz.

File metadata

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

File hashes

Hashes for granian-2.7.4.tar.gz
Algorithm Hash digest
SHA256 1dc0530d7ae6b0ae43aafafe771ac0b8c38af68bbd71ab355828817faf13aac1
MD5 7c056fcb978687b53f8d93c1da0ac7bc
BLAKE2b-256 db0c27aa25280b6c1f323312e83088304da8a7f3e5c1e568d3a560365ec6fa67

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-pp311-pypy311_pp73-win_amd64.whl
Algorithm Hash digest
SHA256 efccd6818a1ac4cba7eededf5e2768f56d4a8c7c93bd5e3a8d7a901510976944
MD5 da76308866f184d8dbf84de52b58d98b
BLAKE2b-256 726ff45fa86c36fcc34f6e613bb223b10fd36c6acd9f7aa43d4f65d0f1eff4cc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 9247db25dd66f74766a6a9488f1279c9b40cf422c6d7a04010492fa1aa7c9019
MD5 8634df0e6ddc120c4013bd3e74e0281a
BLAKE2b-256 c704f2fa35dc2956edb9a5abaabc0840aed92b4121ce27adf684a1c75e3c70ac

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 03b5ce06df095b5db49bd4e976ac8d8419bb0e73dc160613fc3db5e5d5dcd1af
MD5 5316cf3dc30b0733f62f45fa85ec8fa4
BLAKE2b-256 445efd81492529bc2b02dafc63c95d03c2c7faa26ac883ccd94aa93b21fc68c3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 efa0d4fc35ab42562747e4103124e1c4f21afab081c1591de6472174a3416802
MD5 986269285cb403e516502e22d1fb02f3
BLAKE2b-256 31f975d51721069a184cd00310c4b0b0d614a6370905c13a096ccee193432ba3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 f0b0423fa33a1afb9730fbfb5700fef4dac16bf7a1b7a2a79d0349739c1b1f44
MD5 dabd1dff1c3c8577f440dc2a1cd0e2ad
BLAKE2b-256 459f572711f882423f599707aae577ccdbc1700cf0cc3ceb4e9500e00c6b8d14

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 abbab303b502a770355c13c93569e6c0c71ccc864ab41b59636720d5a643f6b3
MD5 f2fe658a0bbb1ba66fe4d22f55ba0520
BLAKE2b-256 bf5812b19b17fb79ee064a8a77a865a031bb49f4ea813789ad63186458ea02c9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-pp311-pypy311_pp73-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 eb7f727f14d7d485a5df4078e7cc3038864b4e7c380865968e75e1e51e62457a
MD5 fd68ee192ae247d8f0efa24719fabf41
BLAKE2b-256 484111a6219baa10270f1a6a2a101cfa372e5d55a46a839a43b49a8d087fac09

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-pp311-pypy311_pp73-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 ce50300cf876f418ba0545f6e8c56d8c75038fc503add0fd1b58d9a3057d95ea
MD5 2b44c72aac81ad15535679c4b2523ad9
BLAKE2b-256 5118577637bb861ab688db8eb5d698ad700133818debd7ae6f58c0574c43f70e

See more details on using hashes here.

File details

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

File metadata

  • Download URL: granian-2.7.4-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.12

File hashes

Hashes for granian-2.7.4-cp314-cp314t-win_amd64.whl
Algorithm Hash digest
SHA256 b9df8aead4d71562753788264db23d32db34147bb73294ddd90833bef1f4cf35
MD5 5c4825939b5a98bdc7a3f99656c29dc1
BLAKE2b-256 b449bcbaaeec0f68d3d1a3dd1fdd21e4a6963d303ae18027c42b2b53f87d6b89

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp314-cp314t-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 dbc620f35b67cf6b03d2b6a24b9b442d1bf52961eaebadb2c3ff214d3d0c8dc4
MD5 77b33f64993317bcc2fa2ba22b7b2fa4
BLAKE2b-256 190311cc0e08f59f03a3cd6a1fe46d7632a0f8690ef945a495b1303140bb7541

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp314-cp314t-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 df05e0f85712b3e90ddf28cb8be358664b1afa8cb8f09978141ca70052dca3a7
MD5 97a1692b3de4fd3a928d52865af1843b
BLAKE2b-256 3d790432f92f9df6e54394e4dd1c159c0d4814d255a2d2541fa9a5c187d19152

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp314-cp314t-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 8b992bbc667e3c74de4ad48ac8d735c7cddf3f709fc2097f7dd230ecc46fd7b3
MD5 f1f13ef129f705bcc62ee45f1203ba88
BLAKE2b-256 112ad0d9cdb10d2760e2f47bd4600c8eef02e326f8f7e253a80ce4ba384265e6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp314-cp314t-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 7c05f74fa5b5dcedc9f035a7c10b8afd90a3d941975a370f1e07c3f3095dd883
MD5 5e47ef76be10315bd7980091ef4b7684
BLAKE2b-256 ee200da1bb552746d74275017e1ffc7fc419dd1a33345f132f6f5a90f9f41142

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 058f9a4ebfc7b9c2577569c6ecfd333628d0d045de272afaa65ee9933849778c
MD5 067c18d0a0923e5d2182e1c12abe6675
BLAKE2b-256 b4f2fcca39f617bf70e29ef903bb7a4d037970c637023484f2112d9ed6882516

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 dce110217825cff60f68da83280bc20471b10e004e720fa94b845e01925d8698
MD5 ce807e0b0b962c54a9635cad96c35ebb
BLAKE2b-256 95521db412e63425cb12f5ca61877956583c6d12f21657b1a3e47eb3200e9c1b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 7e6b1f6e0fe873efa3393ef28803ff699a94254f2a7dc07422cc01d9849e2136
MD5 0d5093d0b262bf949200713a4ac12766
BLAKE2b-256 ae409a5070badaed4ceecf4082855985840c320f7232b8c1ddc93e1732c63265

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp314-cp314t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d4e0c8cc6850dec7180a26b6805b2c4cdbac4c1c48077fd7857a3cd8ff342d9d
MD5 32ca106a27a09f3423b35c019bb9be62
BLAKE2b-256 4cf52eefa8ff477cce7b119ed2fe97fc1f3b2d108397d4755e83a5198149f2c8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp314-cp314t-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 a7b1aca6c654f0e61c9e493dd6d3ddb1698f47dc33ed04566a6635948b081b64
MD5 9314a5b5aefdf70131427bf4aca6d61d
BLAKE2b-256 45a2609f8f0dca7f596b5fb6e57b988b4b8f4d6579724b2720933c379d43301a

See more details on using hashes here.

File details

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

File metadata

  • Download URL: granian-2.7.4-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.12

File hashes

Hashes for granian-2.7.4-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 97b5aeec98a9c6c0695bf8f068bd03aca83fc17c0d977a9c3a2e57bb5f10d47e
MD5 e313db8cf9e7901b2a892e9c2eeaab4c
BLAKE2b-256 c345bd1e521284714615996dcee48dad47d8b97ca2767a7e7cccd392f25fc176

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp314-cp314-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 13f0a39872afa81c6aaa8e29832371fd831373140f1f04de459ff862824f488b
MD5 8137ed8245db1a6a6defd7e93457780b
BLAKE2b-256 1d667209201856b7de8d3c643ba87e11272c4d651c216d05ea3fcbdce0da4ab0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp314-cp314-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 3bb99778ae05c1118cd694717d025cc0b85f5ee81f60cbcb2a8783692798db96
MD5 a2b556caedef6f4047719195a3acfa0a
BLAKE2b-256 ee5277e2abfba54523943eea275ebbe733a6d186fe646304fe25f6d22b243d03

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp314-cp314-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 baf1c390a25d3d9840204c39e7b801c909e99e896ae2713d898c46b563cbf962
MD5 fc6b267a8d2ce4a8a9199e0acb2acb73
BLAKE2b-256 066cba203ca40bd406db0412bca70281e44712f941bc6aafb59a628f4811d517

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp314-cp314-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 034ac1bfe8c19b5a7916d35a1ca426845db9ac11215f1b367566aec3b6530549
MD5 37edef48c7c866397e5fec9e198fda2b
BLAKE2b-256 66a790b85cc6a31cbee772fc8ee731479429a64169e389444a5fdd685d44a342

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 d7100a6a6d3835fec2a207fef536a259dd42d9efdb5c46933cf6f9d55d5bfaad
MD5 6ca1ee3e7d876e655e18abf85aa405ec
BLAKE2b-256 6b4f5574db17193d90a5831120a0ce2a2dc64a711110ccb9af5a3630260c3597

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 b550fb98b89465c8192b6e506993de6bfb956838e715ffb58e944aec1afdae99
MD5 e04e1d5e2f2e0a4360441c9edf246ac1
BLAKE2b-256 9835b8798c98c90d3293d9c85580ea6021f148d5ab73ab99d1f82a0e66f73131

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 a4bc5b54845bfb5f87537483f25c8f8e6003c3c1b4b0eadf6b93a432d0604265
MD5 0450372ec28967f6e543880fc1a8e855
BLAKE2b-256 ab9d23ec1fd519a4c0db961b05d1821869ed6371cbaf8b3d3a0a85c04f89e6ca

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 4cee0bdba9179537669c2fa0afab2ce89327a372f1b2a82f280798da321c996c
MD5 26a0fa73d938602611168082a6021e1e
BLAKE2b-256 5e99211da053030574f2402c750f3e3e5dc587f5192eac4888affe6ca8894a9f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp314-cp314-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 c19ebe797d7383cbb3497c599b8201af71f9fff6b18deaf9965d106f61588ab8
MD5 ba51041e1ef7fb8ab509eea6d99feefb
BLAKE2b-256 985da0c3d8778cd8aa68131974d34c439a38a00a32953e71e3b549759a5e3cdb

See more details on using hashes here.

File details

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

File metadata

  • Download URL: granian-2.7.4-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.12

File hashes

Hashes for granian-2.7.4-cp313-cp313t-win_amd64.whl
Algorithm Hash digest
SHA256 759140ceef02ef72e57a184461927d72bcc2ddd3664c3cbbf4def7516f818041
MD5 ff9f4b44927721f862eaee446bf934a2
BLAKE2b-256 0d9671f95c73220726aee3e908b3ad2745c4c44fbfba508cb5ed615a9d4d367f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp313-cp313t-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 ea6f97d2ade676f1bf49b79088fa4b5640b8b9804b7470218486df3d4be50046
MD5 118c0b4bbe653d7e92c935eb041d80ca
BLAKE2b-256 6cca8479e4d2a02f210ce68b5dc73c77953ec1dfd3769bf725d06e6ec420d502

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp313-cp313t-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 f62941a4ffa1f1c2c5750cfc0b0ad96aa85d63b016125289779eef8888f5340d
MD5 c49aa8f371ccbeb4439728dda5504a92
BLAKE2b-256 c2ad3453fc1212268a01fee957122f2b1699af0efe50eca07ac570e11d1be12b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp313-cp313t-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 b23194e1e0652297086224212605edb4998442511637e732d6009506277f8ff9
MD5 54005ebc2009c21b808699b78cf76664
BLAKE2b-256 8533740e0c9478be49c0778c4ea1773357680980e10e84b59bc19664033996dc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp313-cp313t-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 77103af44034e30505fb5577b8214b0ad39cd6cbdc854ff980d4755faf93adaa
MD5 bcb79b10b9d763a83639be1c162d81ec
BLAKE2b-256 bd069b19956d75277df44ee380e873a86b9890c431f2e2bcde32b3ba341f0efa

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 f7006dfe9852cded794bc60008a168faf4dc2ecc18f1d74b5fde545685b699ec
MD5 20566e5b40975febfcebe15ec5547a31
BLAKE2b-256 925f21eacdda27c38e4194de5f9bef36c4045058daf6d58533fadb7c54c70573

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 f708fea5024a40e0dfba1c17c1c4b09e02e00ac0ac9ac1e345b409f0c11b71e5
MD5 5bcc9f00ab1a7b69d05bae204be0cf6d
BLAKE2b-256 ced8835873a407279435fa0c8e8ac52392d3ba5c9a652bb15c0036aa07d9c302

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp313-cp313t-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 2b28d4aec5a9f2758a48da1897649a01b70ee1c00f2c4649db574527a3d00943
MD5 a2310076b9829aa6426d566f075b9bd6
BLAKE2b-256 72d879e51f9f794389a9d6cab3d7c6b834b87d65fba72a43784eb5d2664a57a6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp313-cp313t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 227889f821526b8b60c5edf31b01fc987c4193bb0fc198c0998e0841e0cb719c
MD5 ff83b54bd665591700a5f524e1f40376
BLAKE2b-256 ec46c7eda2e71a89a13e174598649f721c63ed3d908c0904b62621e8a433af0f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp313-cp313t-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 4e093fe9511387313ad7ec9a76b0c78397cc584ef3dff47d46c336c5aee9cd8d
MD5 450a2dc7422198260f3ea20cf590cae6
BLAKE2b-256 215110344430e495bfa128dccc114957b33e712e971f91668788c08fe791df73

See more details on using hashes here.

File details

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

File metadata

  • Download URL: granian-2.7.4-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.12

File hashes

Hashes for granian-2.7.4-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 07d26325cc69371ea2dc9d3a9cd0cc851c1c8e3dce40aca90e8c204547b5ba7e
MD5 fab5d0aa756dd3bfbe37bbef56ad68e0
BLAKE2b-256 5654ae2979fc45c06fbb37f595ee10eb6b138b6056202163b8e274d140d3f87b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp313-cp313-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 a29191e949a99ffae2807abb7a864f7493f7a744e4fe2ddd2b5cd8db9b71378d
MD5 9b0b7671e73b18562b0d30939c86b388
BLAKE2b-256 893cfef781ea7356b21f671615dd0d53adc00fad81031a9ea506f80d1f46a43d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp313-cp313-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 b679086082bfd7c1aa8c248ef673b715616a4ce58eec6fbeef8b83b30ac84283
MD5 03d7976e6c0f31caabb2686754cc0540
BLAKE2b-256 ceb3a1239f3bc4e9034e07cb32403e6a6d26db01bba1c244dd654f6a76bf2612

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp313-cp313-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 47b8fdbfb369d52bb3fb884514a6a3a7e4d8e81c65fd26e5232985f2b46ebe0f
MD5 5c7a4df2b9d2a1719720c8d21181393f
BLAKE2b-256 d3923878f977bda82fc3a66fc7e95a54366a7b82edd53e6c9fdb3ec053693280

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp313-cp313-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 732639e612e6b6e8d481f399f367e8c9bbb6f0e1b7b0aa74db340c574ee3dd98
MD5 8c6c502ade23db6a3afaf74d891c4fc2
BLAKE2b-256 9922402cc903e5c4e82bd363177392d4e1dcab8b27c1f7006c5316c37c597056

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 2bd56306eed06e293f4848c5ea997e1d019d1ad13b8252dde1f0bc773aca85ef
MD5 a4c3ac8e6e22ae74e9881abc2bfe50b8
BLAKE2b-256 87ac31f7155a467020e7640e91af15ca3a70b0e7da210de42e3d3344e5eba8d0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 f406648c47569e983f0c58bd0853bac30a2bcdc6227428255ee5cc65a8ee62b6
MD5 be2926666470d4f84d044eced9522be5
BLAKE2b-256 58632affbcecfe96f940744c2086ea3793935d5f6898207590a579c92fc8588f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 bb63d64c686799cea850c0c328d21adf75e323991a20be04923afc729432d2b5
MD5 81db7094756940bcf0bd945475de2125
BLAKE2b-256 ac61588f6b5397ea4f5bd9fc8de4b8cc092c555b8d95371c03d149b3bc419277

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 057a3db87e93eca1a11255dd13b45b5dd83f798a750fd87f02e14d54db5741b6
MD5 a771314763ae4d9b4c8f56f75a202ce0
BLAKE2b-256 be393088ce32d940f7982102ea3bdc230090e34ac56dc0bce04f2d03b56ea435

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp313-cp313-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 d11da4a4527ba8dc28b5533d5e3241d8d9212e593195d27c6e72c8a422010af5
MD5 9fac3fb0ee966fd8d5509be4fa23c40b
BLAKE2b-256 0a0ffa7c63afedcb214edb96703cade360d946d5f1ca59ddb0b3d8e04587fb45

See more details on using hashes here.

File details

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

File metadata

  • Download URL: granian-2.7.4-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.12

File hashes

Hashes for granian-2.7.4-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 9e0a4370773ec4a0e92a55a33fc700b60003e335480e5c7fe941f4bc3dda2e18
MD5 93fa702e0f72e9b9968fc3d68a4f5131
BLAKE2b-256 959af2fcda200f8739ddf25be72591b7a28897be0ffd952a76ec655e5f877144

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp312-cp312-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 f11336e4bcd8ef5c5143b075b5260e37e8431eb36d68564cc39416ca526c797f
MD5 5bd1aafd6fa7bcc29943a1c0a181a2d0
BLAKE2b-256 fe1216ffd64a1213858d4cf824767b398758be807dd1a6df5a303dc76994b6d6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp312-cp312-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 d34d97cfe4a7805ecb5b1b1684f3f197bb4baf019d2a9f18e34fd1d697a03a7f
MD5 3885ca0a0c40ecc2816d04c606e56f46
BLAKE2b-256 e045fc6992839d367b6ae8fa8d88b5e70ec293162c3a2e0e6b90fc426f228df2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp312-cp312-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 846c9cbfea8684ab13d21d66855ad06dc077fb95b5590e7f5040e79994d6429d
MD5 86ee975556d1e41d18f276d0b16630ba
BLAKE2b-256 4fe15746bfe202bd2f6a1506346463ce52dd015c2b5d03d07a53ecf0fddefa3f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp312-cp312-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 3d3cf4fe3cafd9b874d8b749c66c790cbf2b4225f2a7d9fb284c51b77a8e938d
MD5 1d3dc10225b954d7f3ee98024af235a4
BLAKE2b-256 c525b867f624886e11053e7a6235244de26fd864a136e65d12295e728b3e5005

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 3607b091c4ef225ee99150f3b02cb827de8d677b52fc75f0b28893244f7bab27
MD5 39cbb3016392cb5b2718ab67030c2c4a
BLAKE2b-256 1546796147587edb494a330294cb001cf68520ad8296a7da91d80ec672ac8615

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 0b778d356b61e0389c823016ad2be50a634b80d3d28a33922f7ac39553e828ad
MD5 3b4eabeee84428940b1c775999935dfd
BLAKE2b-256 d97cc770593b24a472ab5265a44546f56079757efbf89f8e8b2229a8443e453b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 74adbb6c1920dbf4271b824135639318b2a20ff5e33bc35639a8e2928a777234
MD5 2a62518d450f5e79a08f18945cbdd4cc
BLAKE2b-256 298d5c9dc91b9c9a05bf6ed0b795d30f4bb8f290d61502779a89ed2fd75f9fb6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a8111d5e74b27721e0fdda3edba7c154d44c41b469466857ca3c51b088e3846b
MD5 a5e314eccebf3dfb17dea673eccc4949
BLAKE2b-256 fcbbc53b61a7cb67d33677d96913438eca3d79de1b1b7173a361fcdf2753ade7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 2c2f40aaecf2ba3d8232e55181c8f6db7bc68d9112a419ab8d5f9e2f33f631f5
MD5 e56e6a07739d41050d49ff0b9c2bc94d
BLAKE2b-256 8dd9148024fd3a8bd974bb5c68a0cb48d15df7763fd1364bf090ccc2d423028a

See more details on using hashes here.

File details

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

File metadata

  • Download URL: granian-2.7.4-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.12

File hashes

Hashes for granian-2.7.4-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 e9cafbf391d16ea8b8a2e9f88501783fac8da75eb948620899062a17929c4a84
MD5 1678bee1814f9987afb0e08a27f1f1b0
BLAKE2b-256 04ec9022f3c2728fcd99f9374ce633e254b201f4bf76fbe60031bbc137f1cf8a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp311-cp311-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 0e60a3153456f8922ca73d3a427cc3bb594c021f70ec08ecded6581efe25f48c
MD5 a0f0046b2b20ae0376fcc60620129cb0
BLAKE2b-256 088819c01761d639b5e2c2eb2f12ff064c6765f32fa7f129c9f48162cdca0668

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp311-cp311-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 c10e056a6e76da640adb35f88d41ba40ae44065c5e04d4bc35f47c19a7f83a99
MD5 b6be0277d5f66d71c4b47a74f93b983c
BLAKE2b-256 255c9f7a836177b5e94ad15da49046254e5b837e1d2c3d03981111d4af9a9d2b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp311-cp311-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 6be8c6ebbc53efea03284aef87de9b7367df3c9433f7df3b46c1edceaaa9d840
MD5 c7e6482d809d772f00b0ae42f531c0eb
BLAKE2b-256 aeb6faed26e3abd741e1d261defc0e7e3b2ecb9a2189c557e829bb28c3281456

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp311-cp311-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 5c9c6d51a675d9b7084244e63157899dd1afe6f1a5ab014015bc86afd4871df5
MD5 6140d485d82d5a4302b4b2fd4dc68414
BLAKE2b-256 ae852feeffc37fe3c8a0f3e932393bcc99c8972984fe95907b34b380284caf1c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b0de44552990b3dacb87ea3f37ebbcce67881712c0b0db500013821b14df7e4e
MD5 10a6afe959ef9ac920213438b4b33e87
BLAKE2b-256 f196ca238b4f5d813643264abace48ca630efb1ab6d10409bd9e2c05c1d1ef12

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 0910390ea8f893cc4c3f38a28c923a321609358cf46d31aa7df5c3d3e58e8337
MD5 0a31d52043c42ca902b351ca9d42a088
BLAKE2b-256 2e1ef11c9773dbf07ed326efc26a771b39ce97f7ee25608c16d69248db2da8da

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 f9549c44b325fe51ee4fc57308761f5178add4d531f1cc333b4a1eedf4a5b7af
MD5 1f0da96e2cba35268e9bc83299616430
BLAKE2b-256 28ba3605834adaf5dc9ac3701b817bc9d42c73c89fb67815c7c87c7f64a9b6e1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f2c54f3fe69790aa4b685372bcc8f382a8e9ba570b8ea4cb476e3b240a5a5a7c
MD5 b07e19355597fb74974a98673da6a071
BLAKE2b-256 b223337ab1a0929cb0cfbdedc06879cff62d6c08cb725fa2d4e139c7e305fed3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 455c51baf51dd0c3d22004fc04f9afb0662cb84ab2b75b48e5d6bb8b3e4e3548
MD5 e581b63bf35471135e2859a59e2aa3d9
BLAKE2b-256 df00a7db7e3627992c59927f57d5447638be515e683e2c8037ab7845250270d2

See more details on using hashes here.

File details

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

File metadata

  • Download URL: granian-2.7.4-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.12

File hashes

Hashes for granian-2.7.4-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 c73c6099206288c903a305d975064fbb51f9d0c78d06c914b23dde56165105c9
MD5 04817f046a4a68c8fe8b107f28ed516f
BLAKE2b-256 19de04de408275968d4bff8e6fed9d6abf406beccac27412a08c8daaab7c9534

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp310-cp310-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 187a85fe36561c74a1db94b858175824c3154ebe6d0aa61c97124427f5c5a5fa
MD5 757072d601932c05c8df13871d18f587
BLAKE2b-256 4ce09a9d9f9d0e68277d49829d53746b2e8b3761e7b79a666fd9a4f445587321

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp310-cp310-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 acef581d94270a22763fba192fc8cef0df77dac125080ca27e6e847a5e59cd07
MD5 cb388ae4d48aebcadd0e3d5313499f4f
BLAKE2b-256 f43d5d129792626ac990d3b14d484736b8eafa202966f1a541c5b665c30fc880

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp310-cp310-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 6036316f781f7ad1412d7aa10b49c5a25e69fae3f67ed766b0923ebb43aa5118
MD5 afb326f81fd5fce279722b936d81a2c7
BLAKE2b-256 7611c10af6940d8bb73cfb4eaa6781eb3f5c7880e1b69d9d87edc63292171538

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp310-cp310-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 6b7ab6a1a0c0d77ec1dd1145b7c8f3da5251ec7926c005da22f7415bf1b217a7
MD5 a517e91d2b6a447c042b0de59b344803
BLAKE2b-256 88e3fe781d55306f1542b3db0fac13b70b39846b5e9a400fda9a3a2bf04a9af6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b7a8f411408b0b65a07460e39cb53178e30a15ff5f0c77ed6aa31e1106590ea9
MD5 4a95c40ecc452fb86bcb91559262e300
BLAKE2b-256 255d4d894789683bd074bbe0361df7e3e524a2b763e44d771e326a16d4ea014b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 c932f5c292b643019c4dd410a352789dbb8cb2cb41ec5b373779a87375de398a
MD5 087f8c0b5b553d7f1cee0f0bc242e2c2
BLAKE2b-256 c8ac176b47bb48689fe3575ccbf372d67dd52fb0390686f4d8b7174ab2538ce5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 9d068796cb7e8e0b7a4c8d51077701e37104a39cd103c655a5c232ad561fb07c
MD5 ec7d6cc337e21cf7e6fe2b405116a8c1
BLAKE2b-256 a39c1feb488abb85446ac7d12d05a93788a3a6b42810d64d5806ebc309c65fc9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 91963c4928a355d772f14075057ff721423bce70612a619edc2daf04dd258577
MD5 2abad652933a1f0a54b11a8b69c6ea25
BLAKE2b-256 91b72b0b0e2dc07cb17febbbf3b349c96f425a53d913ba76278091f821adfc22

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.4-cp310-cp310-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 1c2a13c5c119e34369f984d8414edb8ba3793d7c78c37bb795942648dda3eca1
MD5 0273f2386f66b2f13136f5fabbe48101
BLAKE2b-256 1c23ccaa1c786aa528a672d6f25ce236156aeb06a63931109aa6f2d4d3c8a350

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