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.7.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.7-pp311-pypy311_pp73-win_amd64.whl (4.1 MB view details)

Uploaded PyPyWindows x86-64

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

Uploaded PyPymusllinux: musl 1.1+ x86-64

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

Uploaded PyPymusllinux: musl 1.1+ ARMv7l

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

Uploaded PyPymusllinux: musl 1.1+ ARM64

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

Uploaded PyPymanylinux: glibc 2.28+ ARM64

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

Uploaded PyPymacOS 11.0+ ARM64

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

Uploaded PyPymacOS 10.12+ x86-64

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

Uploaded CPython 3.14tWindows x86-64

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

Uploaded CPython 3.14tmusllinux: musl 1.1+ x86-64

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

Uploaded CPython 3.14tmusllinux: musl 1.1+ ARMv7l

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

Uploaded CPython 3.14tmusllinux: musl 1.1+ ARM64

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

Uploaded CPython 3.14tmanylinux: glibc 2.28+ ARM64

granian-2.7.7-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.7-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (7.2 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.17+ ARMv7l

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

Uploaded CPython 3.14tmacOS 11.0+ ARM64

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

Uploaded CPython 3.14tmacOS 10.12+ x86-64

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

Uploaded CPython 3.14Windows x86-64

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

Uploaded CPython 3.14musllinux: musl 1.1+ x86-64

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

Uploaded CPython 3.14musllinux: musl 1.1+ ARMv7l

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

Uploaded CPython 3.14musllinux: musl 1.1+ ARM64

granian-2.7.7-cp314-cp314-manylinux_2_28_aarch64.whl (7.1 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.28+ ARM64

granian-2.7.7-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.7-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.7-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (7.2 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ ARMv7l

granian-2.7.7-cp314-cp314-macosx_11_0_arm64.whl (6.2 MB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

granian-2.7.7-cp314-cp314-macosx_10_12_x86_64.whl (6.5 MB view details)

Uploaded CPython 3.14macOS 10.12+ x86-64

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

Uploaded CPython 3.13tWindows x86-64

granian-2.7.7-cp313-cp313t-musllinux_1_1_x86_64.whl (6.9 MB view details)

Uploaded CPython 3.13tmusllinux: musl 1.1+ x86-64

granian-2.7.7-cp313-cp313t-musllinux_1_1_armv7l.whl (7.4 MB view details)

Uploaded CPython 3.13tmusllinux: musl 1.1+ ARMv7l

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

Uploaded CPython 3.13tmusllinux: musl 1.1+ ARM64

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

Uploaded CPython 3.13tmanylinux: glibc 2.28+ ARM64

granian-2.7.7-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (6.7 MB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.17+ x86-64

granian-2.7.7-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.7-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.7-cp313-cp313t-macosx_11_0_arm64.whl (6.1 MB view details)

Uploaded CPython 3.13tmacOS 11.0+ ARM64

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

Uploaded CPython 3.13tmacOS 10.12+ x86-64

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

Uploaded CPython 3.13Windows x86-64

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

Uploaded CPython 3.13musllinux: musl 1.1+ x86-64

granian-2.7.7-cp313-cp313-musllinux_1_1_armv7l.whl (7.4 MB view details)

Uploaded CPython 3.13musllinux: musl 1.1+ ARMv7l

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

Uploaded CPython 3.13musllinux: musl 1.1+ ARM64

granian-2.7.7-cp313-cp313-manylinux_2_28_aarch64.whl (7.1 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ ARM64

granian-2.7.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (7.0 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

granian-2.7.7-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.7-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (7.3 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARMv7l

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

Uploaded CPython 3.13macOS 11.0+ ARM64

granian-2.7.7-cp313-cp313-macosx_10_12_x86_64.whl (6.5 MB view details)

Uploaded CPython 3.13macOS 10.12+ x86-64

granian-2.7.7-cp312-cp312-win_amd64.whl (4.1 MB view details)

Uploaded CPython 3.12Windows x86-64

granian-2.7.7-cp312-cp312-musllinux_1_1_x86_64.whl (7.1 MB view details)

Uploaded CPython 3.12musllinux: musl 1.1+ x86-64

granian-2.7.7-cp312-cp312-musllinux_1_1_armv7l.whl (7.4 MB view details)

Uploaded CPython 3.12musllinux: musl 1.1+ ARMv7l

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

Uploaded CPython 3.12musllinux: musl 1.1+ ARM64

granian-2.7.7-cp312-cp312-manylinux_2_28_aarch64.whl (7.1 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ ARM64

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

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

granian-2.7.7-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.7-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (7.3 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARMv7l

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

Uploaded CPython 3.12macOS 11.0+ ARM64

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

Uploaded CPython 3.12macOS 10.12+ x86-64

granian-2.7.7-cp311-cp311-win_amd64.whl (4.1 MB view details)

Uploaded CPython 3.11Windows x86-64

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

Uploaded CPython 3.11musllinux: musl 1.1+ x86-64

granian-2.7.7-cp311-cp311-musllinux_1_1_armv7l.whl (7.4 MB view details)

Uploaded CPython 3.11musllinux: musl 1.1+ ARMv7l

granian-2.7.7-cp311-cp311-musllinux_1_1_aarch64.whl (7.2 MB view details)

Uploaded CPython 3.11musllinux: musl 1.1+ ARM64

granian-2.7.7-cp311-cp311-manylinux_2_28_aarch64.whl (7.2 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ ARM64

granian-2.7.7-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.7-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl (6.5 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ i686

granian-2.7.7-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.7-cp311-cp311-macosx_11_0_arm64.whl (6.2 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

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

Uploaded CPython 3.11macOS 10.12+ x86-64

granian-2.7.7-cp310-cp310-win_amd64.whl (4.1 MB view details)

Uploaded CPython 3.10Windows x86-64

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

Uploaded CPython 3.10musllinux: musl 1.1+ x86-64

granian-2.7.7-cp310-cp310-musllinux_1_1_armv7l.whl (7.4 MB view details)

Uploaded CPython 3.10musllinux: musl 1.1+ ARMv7l

granian-2.7.7-cp310-cp310-musllinux_1_1_aarch64.whl (7.2 MB view details)

Uploaded CPython 3.10musllinux: musl 1.1+ ARM64

granian-2.7.7-cp310-cp310-manylinux_2_28_aarch64.whl (7.2 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ ARM64

granian-2.7.7-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.7-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl (6.5 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ i686

granian-2.7.7-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.7-cp310-cp310-macosx_11_0_arm64.whl (6.2 MB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

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

File metadata

  • Download URL: granian-2.7.7.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.7.tar.gz
Algorithm Hash digest
SHA256 2b203bc0c7de55dfd0387a52e8c11304ef1dad0e2d5e3ef3aad32c42260a041f
MD5 4fbe448928dcc3322b67cbc6deabe9f5
BLAKE2b-256 0e37b47e83868f8cda609d48da01adba8af7a86559ae0a95d460cfe2a4eef70b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-pp311-pypy311_pp73-win_amd64.whl
Algorithm Hash digest
SHA256 2d85fa4de3448baa6ce021d72f1508b2e8af0e0d58c9f9f3f9d0170f6093df93
MD5 679fc8b9092879d9e44be05c845dc399
BLAKE2b-256 c5779bd9ee707c8a0e162b1368aff834b66d7914e8b1a9b325ee59e7046864ae

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 159b513af98df597366148696e6a6646500c470899ff9d935ced9b24c9204d5d
MD5 1d5d35183989166a2302a8ea94db5dba
BLAKE2b-256 915950ecb190f848ce52aee1b1fa04a3c7d42578db73727c08149106ffbffcbb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 ed26409150824a9558e424d9f49c5d9ec17b6e1947def6a4b7e36fd726853374
MD5 33b8143c30e304769563202232e08c1d
BLAKE2b-256 5152f289572faa0c474619b36584f2133ccea5019b4ed863d9a4e1114cc5c05f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 565cee34fd42f70891b7b7275ec0caa8cbc4a73acd8653eacdda699b49184101
MD5 cecdd4c6873836df76148e8effb4aa84
BLAKE2b-256 031bd7234aed33a645ea2573faf7ffedd7087921c8a1fb13610024787d08c048

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 a1f0f2b4ab84c861e573fca2e0d5db329adae09bc0fa94221fc9e039d85d6132
MD5 e3b4273b65b7af10db2a2ebc7fd11e89
BLAKE2b-256 73877308208bcdfc7c8256a85ff851146696ebb7f334782fb46bd7ceca09a24b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 3b35ef167fadfc547e104134e4bdc910664ce70539b33b4f3b93211bf58057ae
MD5 539fb111f56897966cbf265340e1bc4f
BLAKE2b-256 3575c350ee9b95865ffa2fd9d5b82d5789c30856093e28eb802e6df2ae151831

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-pp311-pypy311_pp73-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 5800119cedab7564682f29ef301bfc3770ec270cfb8c81e64c2b76125e8c0e73
MD5 52e2c36428aecf4d277828fd99caab4b
BLAKE2b-256 9201fc4af8580154820dda9e9df072fc53861e0bdcd63deb51c640aad3798123

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-pp311-pypy311_pp73-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 527bdfd3cd19fe26933e288c739f08e5279a3ce90a5b7c9e55ae58ef35a1e093
MD5 45eb1071c757c824561cef1fa54e0f5d
BLAKE2b-256 5a7d4c2107836cab991a913bb148ec8e04b80b4dbcc826a039cc719ba0d976c9

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for granian-2.7.7-cp314-cp314t-win_amd64.whl
Algorithm Hash digest
SHA256 c1e65ba5a7cc4de58ad8186c2155da3c7eba5545e043eee3a86e164c25f156fb
MD5 83124028e94f8878b31d6044c8681904
BLAKE2b-256 af1b83a9c476251f48d9ff2586be31dfcdb81d7bd367f476a1ea79b37051cd49

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp314-cp314t-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 48b6b7fa3fda4e1b5d10e8ad1888702d9010dd7ab27820e87d0b94a479f9c313
MD5 9eaa58a6af5313542250dda4a03e2867
BLAKE2b-256 d172ea18770940c76b49d2d73e655f22a95cc704642b19142338136fe5f2464a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp314-cp314t-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 55220c4b3e4fb8853bce611998eb3c7577ac6bf291ebbe99d2102d77458a420e
MD5 690b76035b5201e0f9524e204b2e6d60
BLAKE2b-256 4cbc136823fe5592959542f46a4211d9fd761366dcbcc039e68f180862208b31

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp314-cp314t-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 c44a678dbf586b894bb4f3b4d161a6d7ad02dcfe468a3074d130fe89d536eca2
MD5 08dcd3ae00e6e514a05faee79f5816d0
BLAKE2b-256 bda8a77cb571ffd62a2e8390fbb03914b9ad8ba73f064e7b926bf336f99f7ce8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp314-cp314t-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 59b19215f155bc3d9cbfb70ad69390e5c2eaf64ddb33a748162f47477a33341d
MD5 5e75dcbd14dcfe1427e293875f3ebb30
BLAKE2b-256 e2a50836cc5b9fa934c9bc3dd144146c15651b10e7fb9839a0fd771e9676296f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b0dda03135eaa8dd0fbac83774618eae653653b313239293e840a022e0aedb4b
MD5 e934301bf359b528a0f3d64e2ccd8078
BLAKE2b-256 de3204ee0b185cec89e5ef589f3eed885249f7f798d3d0622801912c618f93fe

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 c9c5afdd0787bd845a2a22df37928dda53640529bfa6ab9c6cd3c3c1728865b7
MD5 7f24638b49b549f808325ecf56cb10fc
BLAKE2b-256 d3eeb8367758b4fd9d1042c48066e85349680f9dfc0fdffed0af31700ac407a3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 44e3b3f93cc1ec858f90fb238dbd26018573ab0ad13effbda1b199d5d1231b4c
MD5 2707762542fc688755214ef55dab0ef6
BLAKE2b-256 8f93880a60d4a5e35cbab4359466ed1ac0b5ef37bfd566470711f79b7daeefeb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp314-cp314t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 113b7713750318ba4d9fc9d8a726c4e50edc8c2aadfb7f4bbb95082282c369df
MD5 e0bc6000ee630163cb81f5f3172a05cc
BLAKE2b-256 2f73bac28dfdde786c4bf8309b891b4c63c043de2091f6cb5094917d36a51850

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp314-cp314t-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 af8746f92fdea860bd9904ea48ca1dd7d9d8c4c1c0b8c38e576d1d78fa6aa017
MD5 ab131707e31e686dcdb71821336a2759
BLAKE2b-256 9dd3a81b2578ed96fc2d1c7c10698f93b4e56aab9845fa5044f7a6115ad7e53f

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for granian-2.7.7-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 330bfe8c34daa9ef0202cc675f66992153309c8eddaa5b12decfd7e513561f73
MD5 8919192d87de3be8dd906ec658c525e1
BLAKE2b-256 c7a3b09691823430d25b3b7163105f72f19f5fd23d2b56c1edb9f2acef6970c8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp314-cp314-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 45eebc0c508ba7c0bb1bc128bf235e4d5d7bc6c6a994ebf775f4f382ea5b3208
MD5 0169e4073c62dfedb5b06e7d20fe0f4e
BLAKE2b-256 b9e80490f2b51e7673085ba78ec6e1251f8a773871b8fa1cf65deec5e3f54eb7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp314-cp314-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 17a6cbd011108a45d566d8d2d8fee402651652ba247b5dd883ecca5482d9e075
MD5 9d28d1f055d5743268aa44cef1aec1ec
BLAKE2b-256 09669f7da3d97839b506dbeeb0e5d20f536e37e8444f2d168a6b7c5fe9d59ee8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp314-cp314-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 48499b71f049114163bb10d0504b7018950cefdcfbb4dc5269b26acdf2b45a5f
MD5 435bad85189f0f47702fbe493f51c2cf
BLAKE2b-256 bd6ebd5ea12ff6f7a1939a30ce5694af41c02ad397e891cab3d524df2bc30baa

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp314-cp314-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 ecfa25ecefd94c9e0905fdebfe58b63dd6037d3c999d2ecb21b858c3510e740c
MD5 b609aacee7218c637844fc4c126e5fb1
BLAKE2b-256 7b742b0055df74eb120c0ed5e1660c49c279bede455c517bd0bf1eefc0045e0b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 259fc92f07151075d66d20e2f864b45b4c3837908fd39cef9459139ecd722652
MD5 64f3d4dbf46562ee5631fc140391fbc9
BLAKE2b-256 639170ce98db3e8f9ef6cff13868be3d919f8446cd6c05375d31418e062308a7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 de4711304a98ddc030e79fb7db712d7f9326753c9419e9e089895ab8418ba4bc
MD5 b73dccad80c2d46fac8345e0400762ee
BLAKE2b-256 0e44b7117f08ff862749efcfd13690e577232edfcfd3606e7226c79dcebd8466

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 041a457cd3238b498853085c5251e1ec0966ce1164252a410505b5d343892305
MD5 444af69a260f5a0e660637a5f64b8c77
BLAKE2b-256 98a83cc6d58c56d61ffbe7a4a257beeaebf102bea2951f7705e60d83ab9a39f3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 3bf630d3cfa51ce1c8238441d8cb15064a328dcffc372676d473c76ebf419c45
MD5 45f112c5fb0b5b93da1073337d08c0e3
BLAKE2b-256 8d66cd81af83f702fa6aabb733794d7e7f73dc57d687780e1bd466961ac4440e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp314-cp314-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 7221385245a0d48036d4693530c12435868e38197cedab1aa7c4b697ffb846cc
MD5 6d1c9d761ede0efa57e92a6a1d77e49e
BLAKE2b-256 20add23055976a72105f418497f251a9fd56a84cd98272b8a0e1113ce8167aef

See more details on using hashes here.

File details

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

File metadata

  • Download URL: granian-2.7.7-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.7-cp313-cp313t-win_amd64.whl
Algorithm Hash digest
SHA256 d82ee7710326f9bd800eecd2ce098d816fbbd61429d12253c9f2ff1739ada604
MD5 5ddaebea3d8916b7c82fe39c79adab01
BLAKE2b-256 c5c52f25ebbc0a82a9f3e1faa1998190866307f2a24b3ddc3fb7889148738469

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp313-cp313t-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 7ace32e0bafa3eb59a11128448ebbc83399defed4d5ccf9a6cb996b8916ac825
MD5 8a4f7cc9b9bb3fcb4b2d35a8524800d1
BLAKE2b-256 ee986258cc4bf5ee2d4b57f18481937eac36a98cb0fcf098c12f99235b9840b2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp313-cp313t-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 14d39fd0c189b8ed81dc7f17474f0aabb994d29ab4c8024fc212517adda4d1ea
MD5 3efbaddd440ef17977aa98334040b8bd
BLAKE2b-256 0d870a5397997c50f0bb7d9b83c47d94c676524af4dd5a371988fa9c39864029

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp313-cp313t-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 79bf3f077355cff6935c60f2bdebedfcaa368609d708413af582f9a75043be93
MD5 55da868c0b3fe3d1f73c0cc02145dbe1
BLAKE2b-256 78734aec3e0d9b3fa7ea44e51787a9c1df78d80f4b5aeaefa0629d290959abf4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp313-cp313t-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 5ef066d2d05ed7cfd3e6edb239699cff7cbce46b6379e0fafadf8c93ffa9c456
MD5 9e649fc83ccc837c266f32789008a00d
BLAKE2b-256 59396d31b9c1035f3743067ba6f4f6a084edf926e5889fc4863bcf81ec3f27c4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 00bd7763d6ff746fb932880d7a22feccb6cadcac3cb7647cf03bb2489254ee08
MD5 51a4babe0859874260dbb763cc73d545
BLAKE2b-256 7937c0cbaeee15dc4d029c295e0b4990e1d49405c54431448dcc26b6c6a27316

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 7f87201ddd949f55c6fa43f1479325ff27f3c368b7db0b0dd296f074bb08834b
MD5 4e8391f037f6b2a3e4f1c3bc24f7ec2a
BLAKE2b-256 89a4c24f4c3e1b139612e3b59520b051cb0691817cae38ee1abe0fe3cab69853

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp313-cp313t-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 5e2c801fa79d0b9a57f63682c79e5b6950d7adcddb2ac9b792191be3d14be358
MD5 5b2cb816f8f35feffbe4ae3ad8ed5b03
BLAKE2b-256 e60f6eabae02b22701800a094efe6800dfd61e52f299fa4fcee68c8836a7b18e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp313-cp313t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9f9e216cadd93d1e8472c43229a6d4ae7d4ebbc6b77b6aca60ff07c0eb772763
MD5 7237152463195509c189e0fbeba53570
BLAKE2b-256 9d6e7669c6af359507bd9ed850d7bf759e1604729e3a696973ba2591428bcb68

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp313-cp313t-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 138b9aa9329a220d14a92cdf3646083d00c515de2b37f90261f09fddc1974f7e
MD5 e930a0b77e6e7ec0dbf0d4b4b347918e
BLAKE2b-256 2db9b573b23c00c9a194b557c155151443e4dfc58be7df2a2101df80104b2e0f

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for granian-2.7.7-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 85418a0861eb5f43efb0b495c33274d851527ed0f0837d2f452d077f85afab60
MD5 b9533bbd6115e297555e326e8b2312d4
BLAKE2b-256 30d8b53f0bcdd48a042dc54dd971d5459ab7feb6d5c3d18f04c7d1d4413a12c3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp313-cp313-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 f10971988167f6cbb9355c4e7789d8ad9d244bacaccad3079315c603d05d6b12
MD5 60c2d5927d5f4458f9a4e09550314f76
BLAKE2b-256 0b4f6ef68be53d2a55549c4d1755d8d50ff13ca83d76f269e5073cf2756b1790

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp313-cp313-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 5c77d847292a508bcc2b344c80f7190dc687d788cf1ab8b5a06c9f0c4bb09855
MD5 d0789496f9f4d1cb2d0b4ffbefda91e6
BLAKE2b-256 099d0e65ac2a786c5a60bcd2631899e7ff82a2edbb61ceca7fc3fe3d8cd620fc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp313-cp313-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 55c9cd41b8a5e3296a72842cd7077bc0b7e3297d7b48cc659c8f4076b64d9c10
MD5 cb4a14a03d0ea9a92f80660abe798b43
BLAKE2b-256 c552f2e0f616d19b6b7762a0b8966fb6df037b56666f306a81ad2bee1f9a0c39

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp313-cp313-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 b258ba2f38c97ecc39f915052a970ebccd16ea04c2e6d3f2f135b8575024ac43
MD5 b2f783f8e02ddab995f5cab66cc24c48
BLAKE2b-256 e6a73b86b2205b9e7907589b58cd44465c42cbcf37efe0ee3c37da7c7676866a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 331f1b0f0fd38877c19464595629a596cb49d953dd69375014ab813f0cfb9780
MD5 3e333d645c9ea7d0f8e5b409757bc00b
BLAKE2b-256 5f149a290bf9f2032833eeec66d195220c3f5d3f77ac71f3b2d826ac63d92f64

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 3eb7b78930df0290ef04633157cf364a5ce8259d306c2755f6d4a16ec6e5c733
MD5 0271ac64d02ff8dbc680c8132654f1ae
BLAKE2b-256 137de96193fc1a56b1843182bbd1930e88da2154f64b9715f2f38dddd2316e50

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 a3af2a7b6b370d2b9d24d74597b713a99818af73bae71fcf729018309693b2e7
MD5 0468817451213dcad7fe798beaa12c29
BLAKE2b-256 241aef1ac4d12b2808361310df63e4fe51fe9c5ede507db84bbde09389b8c812

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 5ccc9c7f40b7ee81019efbb6b60ea5d8acdc0a3f8b637e0d3dcdaed508d04555
MD5 ea9ecd501dae7a93331d96f9a1f09d5e
BLAKE2b-256 0e372c31dbbd771a5a003ac7f31978048dcd9dd44f8ab2d2b65da5919483a0bd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp313-cp313-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 acce19713ef10331bb821d58233874b2bfc2ce1c324e11ea9781317375eb0eb2
MD5 822a73257a211745b1ff1fdc0ce9f0db
BLAKE2b-256 d8c3dc003ceccc6b4821e96c0a409b9413bf590cc27dd355a0ddfe4e1c7de2ff

See more details on using hashes here.

File details

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

File metadata

  • Download URL: granian-2.7.7-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 4.1 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.7-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 f6d13129ebdc60c23255702dae189f067a8927e4f4fe1c6dd5851e850271e6ff
MD5 f862eb480be8bb22320c3052d4751212
BLAKE2b-256 18c52deb03a0356be3bfa3a2e21a826b6a8a84ed79bbb4791140b3bb370430ff

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp312-cp312-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 6cca904566d12511400d90b04b8bc795687530ef8d4b684b66e6fd92c66f62e9
MD5 c5baeb2f9f0c01e9997a464548a2fbca
BLAKE2b-256 5aa60b7c9519983330956718b1c87480cb8565391d4952149cb881d1a9ec1d40

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp312-cp312-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 575fe120c98d3001517bcefc0dfe656bbbf336f25c1ba4fdafffa8ec64044dec
MD5 69541fa31afb22a48d12953c48a76dce
BLAKE2b-256 543e74d24fc3f2466005248465845818eb3b35317a4ab592c57ad6667fd1b503

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp312-cp312-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 d4c731eacbfd28683364854804e599979eb0d9db3015ff30a6048dd4a0bc7f0b
MD5 ea7371a324486dfd71fa3f744120abe9
BLAKE2b-256 3d84c281d152d1735b26381254417206bebb1d4042aa710e21db3be0f5a9045d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp312-cp312-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 c5409a68a9f7af3faf6970f5b89e02b0f283f780247f8b113a3d2404f4e55b75
MD5 fc6beed4109bb5931ea30e24854af4cc
BLAKE2b-256 7a58c316ad3061ee2f0036484a32e1f49117242a031014ac973a77365c0eae18

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 56b28b9c5583c12ff3619598288d6a85bef6bea35fe64c7ffa2cae43a2ae9536
MD5 b19504cb172d2ea282c6055f9b2e9a03
BLAKE2b-256 d36cfe6a8e171bdfc3766dbc97bd3ed07f42c5b1749ca0a09f20b9e68c69313f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 fe556dd54984f8423e183a6431556bdf44df3a12d7072137161a54eadb95114e
MD5 b820bb20e3393a4dfa544f0d9780150a
BLAKE2b-256 672deb660641857f97d693097ed0122f6c2119468a292b8f7579b1f79012bc59

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 833df52a1d30726e3ec3ee2d35693ecd5cac49b2e36d4b83516415ba8243b445
MD5 1377a57cd08283810502ff37dc6fff09
BLAKE2b-256 7b60758cf2de2c87e934a26b20f5eaf09d7d47a033845bd7d62f1ce93749b47c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 69cd22f411a6cd99c9d2d7f667be4fae74f49efac23bc544bffa9f59d3704647
MD5 69a23df82aca4cc0b7fac846cbff15b3
BLAKE2b-256 abe25f87e728614495b47a08400eef6be6a114e093a9b0bfdb56dae80f100f7f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 c9454a719d9f91e7d4afee17febda8811bc299b52c2aaf1acadaec8bedf24dbe
MD5 297f421e7190e5eba95dca49d6548325
BLAKE2b-256 b214c2791b0108662ec72b2cf65d2aa5ef133cc7d3064d640d6823e5c83e3a61

See more details on using hashes here.

File details

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

File metadata

  • Download URL: granian-2.7.7-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 4.1 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.7-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 51c3dacd98274e4ed5b9fedebabfb8e707f7d4b7a7a75e3a554e0640652ea31b
MD5 59c4370c7b8c82c77afe06b523e814bd
BLAKE2b-256 973a253634fc1ed40a4295f0cfbb1de9476bbd7135a2384db724b0a359059afa

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp311-cp311-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 db51c87d939a5440127149c8291d0bd0f9b03179af111b8436052da92d0723f7
MD5 f389d232cee4f898f8cb88c4cf2912e5
BLAKE2b-256 17a1185e92eae431caae5b4e3250e697b3ee20ef96059947b95934ca221d3c89

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp311-cp311-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 93b81e392e42d52782f7f43acc5c1dc69f44c5285a2654b89a98024099997fa6
MD5 60ecf6e544a590daa300de97b0b56211
BLAKE2b-256 21782852d3f16231bd39de1d93c703f8d99a81ae8e8b1fe890f1d740ac6038d0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp311-cp311-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 e274915850e4e8ac0431047651b0e55d2ee2806efc13df607e271f92afde1ab6
MD5 52cc2f6cee250498f714217c36ca582f
BLAKE2b-256 a53caf5ee93fc34ff06ee1e25475eaf68d8cee56450f5657ce6c3dd116ef1f02

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp311-cp311-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 e6fa7fb96c020170aade93748fe5b37d64051612d7ae7141358e1025589ab30b
MD5 6192ea9753818362ba3d0a6947122fcf
BLAKE2b-256 3c6f7d3f45152e6a435ddc11e42177318478fd999aac27d48b8d076023539855

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 22197febf1d8fa1048861bbaaf0c749a458867ca7b241be75c96a630ef393625
MD5 0070766e019c2d0e85585193dfb2fc4c
BLAKE2b-256 71a2600191ac07fb4cea901a52677182c07ae0eccbae8161587d34e9e81a1b81

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 eadf88ba1ad17d945eeba4c64ac291a1c225498819bfb7554a05d3f92d66397f
MD5 4103dbca6a777688c9f9983ec193132d
BLAKE2b-256 46b9654b62606a6c61060956d3fc88f869419449ea7484e2908883ea77c7747e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 8486235d76ba25da638528ae407f7b86dc700fc59b2ee4bdf3d77603cfafeafc
MD5 a75c3f7f6ea73ea627047849ac6194d4
BLAKE2b-256 6dfae8a7d839e344dceca6b04f4d53f25fdd11f98023e6d5c7783bad49942d77

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 8052047933e05c0e5a54fc08bf89c0599d2d0a5dd9fbe1af889bd7318d9d594e
MD5 9638c7d96472d0fb308b38cd7f0d348c
BLAKE2b-256 48e48b2e59ce2bb4bd7a507d98165b65a82f6e4cc94830490962bd06ab7d2a70

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 c5a059ce07b1f5e436d4b0c5ec5161d55e36981a90f05acb6e06c170d635e17d
MD5 9d6876a18ea97c27964fa3ae7bc579a2
BLAKE2b-256 b1e42d310ccdf09141a5ce34f2f7bef933a99c9f1645b093e5b9768fe1af97d8

See more details on using hashes here.

File details

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

File metadata

  • Download URL: granian-2.7.7-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 4.1 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.7-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 2fdf1389e302a4b880099f490c0bec8c0098690d3c10d456754fcd8762161568
MD5 82825ba1225a9db19c8b0247f68d9833
BLAKE2b-256 4aabda5371fba82db846deef852823e346b14af79a95f7d7f9fe1b6f8bec64b1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp310-cp310-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 ad85d9132e1186ca965cd8dd5277dd255a1078cc9456f002279edc579a268f13
MD5 7369cc2258653f60e42f1f37d44258af
BLAKE2b-256 14fd501f9a983dd2d0ef4cb3e3f8d93dd55789b849d4b70f72b14bb61cab8bb6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp310-cp310-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 048084071becd768b7456445bab26cbba485de07a9a4df80eaa7bdcf7e0b8193
MD5 1605ce5a49b43e3c3883c7292f26fa35
BLAKE2b-256 34eeb4e54ad06d8eb28cce52c869cdf9875fd203bbcd5084a4aa66cb6b945bad

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp310-cp310-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 dc2acd56d0ca017c67d82b758f317b3fbe5dc7518257908a86de4ffc05ac69de
MD5 b5f5675e2f660a246a71287515c324e6
BLAKE2b-256 ca40485c8682d56b7067b6cbce336c239f344c1735e8f642e449f24ee601dd2d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp310-cp310-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 0875b45286e520c56ce98c0e51d69b2f12ba228c4b2c2d4622683da94cfa15b2
MD5 81f1dfb2d3fdc90063763dcfabfb23a3
BLAKE2b-256 e64665a66ab55517ff5a346dddc456bfd1d7190ad621c311d98dd16e7b8eb3ea

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 354609ef79a7f2d12e02df69a5a93217bb231244dd6d38f455b52ab66e3cad9f
MD5 648a84533a312be6d7540439d233291b
BLAKE2b-256 a3ca15d8fbae683e12a995e30f105621e38bab1e82ddfb00876e63869a0bf5ed

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 03b0d785931f12624524312489c60531cdb75c846c7894bafb89b8d464559600
MD5 9f3a8ff274f98d46ca2661b8170c04bb
BLAKE2b-256 bfeeb35aef3f49f6839e2bc2f54d997c639dbd992197cc965d333884141052f0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 f15b928370c4ffa5164a961ad5df69d972a045bde59389e89687f5873f14f0da
MD5 64deb84845d24070ee6fe87ffb187d4c
BLAKE2b-256 162a07b15122e3d88352f62f2d7a913813437b50d1acb0ad44f400500e633aae

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a8528b44adc9e49c960a1c0ecfdfb160b56a5c8ed129f66de217df2dcf5b08a6
MD5 78d9b3a2391a3108499af46658659598
BLAKE2b-256 42a711eaa818b6ab832e01621583a7d91a9f1305d0ce28f458581a3b4a712636

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.7-cp310-cp310-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 7822ecf6602f15df10898fe9666397eac28570cb9916da2bbe1b7de401e1b3ed
MD5 f033f05396094c595c3ec755ebdd7c26
BLAKE2b-256 5b745db0210bf5386bc0714f6d1e15f0a57267aa7ea34b5b24e68c044c4944c3

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