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

Uploaded PyPyWindows x86-64

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

Uploaded PyPymusllinux: musl 1.1+ x86-64

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

Uploaded PyPymusllinux: musl 1.1+ ARMv7l

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

Uploaded PyPymusllinux: musl 1.1+ ARM64

granian-2.7.5-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl (6.9 MB view details)

Uploaded PyPymanylinux: glibc 2.28+ ARM64

granian-2.7.5-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.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl (6.0 MB view details)

Uploaded PyPymacOS 11.0+ ARM64

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

Uploaded PyPymacOS 10.12+ x86-64

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

Uploaded CPython 3.14tWindows x86-64

granian-2.7.5-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.5-cp314-cp314t-musllinux_1_1_armv7l.whl (7.1 MB view details)

Uploaded CPython 3.14tmusllinux: musl 1.1+ ARMv7l

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

Uploaded CPython 3.14tmusllinux: musl 1.1+ ARM64

granian-2.7.5-cp314-cp314t-manylinux_2_28_aarch64.whl (6.6 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.28+ ARM64

granian-2.7.5-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.5-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.5-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.5-cp314-cp314t-macosx_11_0_arm64.whl (5.9 MB view details)

Uploaded CPython 3.14tmacOS 11.0+ ARM64

granian-2.7.5-cp314-cp314t-macosx_10_12_x86_64.whl (6.2 MB view details)

Uploaded CPython 3.14tmacOS 10.12+ x86-64

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

Uploaded CPython 3.14Windows x86-64

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

Uploaded CPython 3.14musllinux: musl 1.1+ ARMv7l

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

Uploaded CPython 3.14musllinux: musl 1.1+ ARM64

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

Uploaded CPython 3.14manylinux: glibc 2.28+ ARM64

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

Uploaded CPython 3.14manylinux: glibc 2.17+ x86-64

granian-2.7.5-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl (6.2 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ i686

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

Uploaded CPython 3.14macOS 11.0+ ARM64

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

Uploaded CPython 3.14macOS 10.12+ x86-64

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

Uploaded CPython 3.13tWindows x86-64

granian-2.7.5-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.5-cp313-cp313t-musllinux_1_1_armv7l.whl (7.1 MB view details)

Uploaded CPython 3.13tmusllinux: musl 1.1+ ARMv7l

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

Uploaded CPython 3.13tmusllinux: musl 1.1+ ARM64

granian-2.7.5-cp313-cp313t-manylinux_2_28_aarch64.whl (6.6 MB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.28+ ARM64

granian-2.7.5-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.5-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (6.9 MB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.17+ ARMv7l

granian-2.7.5-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.5-cp313-cp313t-macosx_11_0_arm64.whl (5.9 MB view details)

Uploaded CPython 3.13tmacOS 11.0+ ARM64

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

Uploaded CPython 3.13tmacOS 10.12+ x86-64

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

Uploaded CPython 3.13Windows x86-64

granian-2.7.5-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.5-cp313-cp313-musllinux_1_1_armv7l.whl (7.2 MB view details)

Uploaded CPython 3.13musllinux: musl 1.1+ ARMv7l

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

Uploaded CPython 3.13musllinux: musl 1.1+ ARM64

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

Uploaded CPython 3.13manylinux: glibc 2.28+ ARM64

granian-2.7.5-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.5-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.5-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.5-cp313-cp313-macosx_11_0_arm64.whl (6.0 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

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

Uploaded CPython 3.13macOS 10.12+ x86-64

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

Uploaded CPython 3.12Windows x86-64

granian-2.7.5-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.5-cp312-cp312-musllinux_1_1_armv7l.whl (7.2 MB view details)

Uploaded CPython 3.12musllinux: musl 1.1+ ARMv7l

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

Uploaded CPython 3.12musllinux: musl 1.1+ ARM64

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

Uploaded CPython 3.12manylinux: glibc 2.28+ ARM64

granian-2.7.5-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.5-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.5-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.5-cp312-cp312-macosx_11_0_arm64.whl (6.0 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

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

Uploaded CPython 3.12macOS 10.12+ x86-64

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

Uploaded CPython 3.11Windows x86-64

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

Uploaded CPython 3.11musllinux: musl 1.1+ ARMv7l

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

Uploaded CPython 3.11musllinux: musl 1.1+ ARM64

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

Uploaded CPython 3.11manylinux: glibc 2.28+ ARM64

granian-2.7.5-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.5-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.5-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.5-cp311-cp311-macosx_11_0_arm64.whl (6.1 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

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

Uploaded CPython 3.11macOS 10.12+ x86-64

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

Uploaded CPython 3.10Windows x86-64

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

Uploaded CPython 3.10musllinux: musl 1.1+ ARMv7l

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

Uploaded CPython 3.10musllinux: musl 1.1+ ARM64

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

Uploaded CPython 3.10manylinux: glibc 2.28+ ARM64

granian-2.7.5-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.5-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.5-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.5-cp310-cp310-macosx_11_0_arm64.whl (6.1 MB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

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

File metadata

  • Download URL: granian-2.7.5.tar.gz
  • Upload date:
  • Size: 128.3 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.5.tar.gz
Algorithm Hash digest
SHA256 06ec766c0dea9c23e286248a6c5cb9a219f362d2afe5f4c071d60f8bbe6592b3
MD5 c00813c9618c73bb85a87d4deb5facb8
BLAKE2b-256 9db385382dadbacffe3b175c9e499d247e45a8cdc40a27abbeed3f8e4897a465

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-pp311-pypy311_pp73-win_amd64.whl
Algorithm Hash digest
SHA256 842cb0d86c277916bc79967f6d92ff8b22e52460386d647ad6893d90b6d62471
MD5 e0b2697dd47c643facf0819943654b2e
BLAKE2b-256 069acb6fe8a96e47776b6b801f43054ddf1ffed9cb4d60b59fc54dc4a78824c7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 501fcdff86088cc1861991d4478babbe0cdc9933cd8c2e7253a0bb81d951c355
MD5 1d8706afa94291fd01946205708d5a60
BLAKE2b-256 22bb414b2e55a3e7cecf90a1f02c8074f2bfed3751221fa699f3ee2ce295bba5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 48c7f7b8fa9d273c6b77c20221ed8b8908180b15792c594fad33ede909f198b0
MD5 5a44bbd25988c4e84ef84c95ac992977
BLAKE2b-256 1a649156a8a7a894739445b42dc606494ab14f65d9b423d19ea0e33c2ef6e552

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 aae559e537768bc0272658404c6ccd8cfc9f0094e22e1894debf4f1986300e49
MD5 f323f88cdde13d5cbd7a5df61b394cd9
BLAKE2b-256 4af75cf21d3ca71d0da1bb10cda24c8e0ff6a80a44904dde23550671a19e14bc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 57e04bee090218182add1a2467bd6c02733ec0c33f62d0aadb1876306312c82b
MD5 c18876192062712ad5b1807cd03f2368
BLAKE2b-256 f5eda17185c1f56a1c2f9296eaa69b5b0c5cfa10b6ac97b49faabcefbc286a49

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 69e5ad5e2c6266d3d8d6e6dda5999029bc8b8b886ea1860d41b620dfcc963b48
MD5 87b37b893067cb7efb6ec276f5dedc89
BLAKE2b-256 5d6fc24c3ff1bcee0403e56b68d6917010dd72e4aca60e831101c744af678103

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 07c4bae5c81c1ad0c98c940b5c8c07976555cd9fc7b63016b05f933ed33b8dcc
MD5 d1d7865a8f3e13601a08299b9dffc680
BLAKE2b-256 43703c13cfae5623e03934cb93c1b7d217c2b27a0f395eecda806bb2985e0265

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-pp311-pypy311_pp73-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 e651e328ee0bef64acbe1a6939a27e0f9c4a473cc4bc96e814e2602164f0f0e4
MD5 ca982aeeef4fb644035e09fe2cb45d93
BLAKE2b-256 d90d79cfecfcfd57f7ec0488b05da918bfaaedb29a3b32cf194794cd8a770219

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for granian-2.7.5-cp314-cp314t-win_amd64.whl
Algorithm Hash digest
SHA256 ce2ee8565bca3bf85e8c27b27e9380c45dc84692d82f303c040cb20e0668f1ca
MD5 8d7410e61dc12bd861261eed03aec96d
BLAKE2b-256 0f6bc30b93cf3af2d7cd6e0aadd33134c75f475aa94651ec815c264c0bccdfd9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp314-cp314t-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 c8c1fb2342a8c335eb513bf3aae8c36793b73016d1e570eb0f8ccd73c51eb6f0
MD5 59102cb03e3df155f04028c5ba070143
BLAKE2b-256 a2c91ad54e31e7e63cd6d714f65fe3aa56df916d8a42cf942d66ab94fe4a69ba

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp314-cp314t-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 6d4227ad7da4f968399f45222fecf43fa5b4ca58b4d9923b44b2c072096885f6
MD5 d0eb2a226554cffb96706b197c7404c7
BLAKE2b-256 809dbcab178478f1c5029eddfda01404bfbe00395d2e35523c3d77b36426e332

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp314-cp314t-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 07bc6959f7138d07bf0148e919e612327af751df2150e0a8421fca230364ec1c
MD5 d7b2f9d1ed0a8029ec23ec24c175a16f
BLAKE2b-256 f5c12de641e36ed7f3a21a49c595bfaf39c13a11c6a91b120d1ca67b7afd13e5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp314-cp314t-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 6a9be734bea7391035f55757290b7da8b98b9a9f3389c3bdd61945be1e3f9b23
MD5 35c53b98e4a522e54253044b73814089
BLAKE2b-256 439271c4e0ff1ca794093cef2e3e9353d72ea9a9a2f01bfc83d5a92ea8c2b6f3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 cad48a638e87d67b7bd0e3cddebea34805049d9969dc1b399f3cc63cdb80e762
MD5 ac749b99b49c6d4a700c2d5c83f0c747
BLAKE2b-256 d10594bdd789dd65927fdc6887202c94b24e0ec226ffa78c2863931373fe294c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 646b62428e6d1614dc59e7bb5cfcd38603d0a5ae282586b679a572a4fc11ebac
MD5 0a9e7cc06f77eddf9f34a52659a0a607
BLAKE2b-256 77d1313d7d4a8ae3d358cbece84bba9bd613c07c9c7d0edc5402f415dd8460e2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 3139b26f48d3f8f73bbd39922fcc42b338ba4ca867b87c0242d6d85517a5b18e
MD5 7ec5e14c12299662bef2199f93a73f32
BLAKE2b-256 9635fed652ab967a0e18e3707720c145c84c1829e4d22b9b77eadbfec0b3f7af

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp314-cp314t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2137b4280f71d734a76a7f69837e32a43b039a7434ecd527ff080a3e2601e915
MD5 0a749fd663477f796713b67b6902be72
BLAKE2b-256 9feca75d6a0dfdfdc333d31185a76fa1c6453ea83212ee60eb8140a06f9e2a9b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp314-cp314t-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 225a250034f7494dadcae381eb718bec6eac0d637aac92845f9ef81cad4bddbf
MD5 c1667e7b31b7f04d505c2b018c9abb3e
BLAKE2b-256 7b51e8bf64b4d902c379b0d9dac6199abfd7866b9b3e2d17216cf864323cc9f4

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for granian-2.7.5-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 2512f50572121f433f0e14d38ecc438d07c4c1785e0d7547acf71bbf705b519d
MD5 72c92e076e842cf622026b480ea288c1
BLAKE2b-256 d25045e2a307fa82fe1ae041ee9ea1427142f99727857f64850f722f5e08c553

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp314-cp314-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 4790bba12fae741a774aa0c8376c71ffe7cff2e3a21a68ffc8f384939020b6a9
MD5 aeaee4298ea14fc2038b7f215f0a3eb5
BLAKE2b-256 8bd53700d05945e7a49a773b3df3dd597568a040763ca71637158bb6bcac6e2f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp314-cp314-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 2e997ae4438c70932072d29e4517d513bded27ec5028f252611c59b807174939
MD5 6de3472cf25a9041d78420f4149a523e
BLAKE2b-256 26da2f0f1dc7803ceb883251ba303a8669e0241eab286931d7538346c5726f02

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp314-cp314-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 07dd380c47230ed4bcc93bba8184eefc34ca02cf1d94911cf5505c15a803a1bb
MD5 ed557bcef1a3b1eb34e4fd41006de965
BLAKE2b-256 ce69409de60f3e630924164b4a7c70c096e8622e3c4e25265f4d28cde4c10d18

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp314-cp314-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 e39e8d2b67613536a958e8c0bfd158e58233d8bddde009cc85a9863bde2142f7
MD5 7efb83076cc3be735d5de54c0bdee072
BLAKE2b-256 1f2bdfa52caf495eb82f4597b403f9d3cf427dab251e0981e2dcb2c6088a1275

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 f9dcad984c1e3e56942f81ec5b98d0efb4861749a87ea45982457090682d6e6a
MD5 e56fdca9640829030e1c232820b8f28d
BLAKE2b-256 834a0f1d922be3d5c3622da20e63acf99e2381f428b8814296405d4b148daff5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 5e25116efbdebf04ba70a19c8d2dc569ea282334355350a4d9489dfb62ada5e3
MD5 fa8b6fc1616c8e737c56b9cc56959def
BLAKE2b-256 e9f54be1699e2d9307e2af45b903a1f1924b14dce229a4ac336832a85fcfe6e8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 976b4e09eeeeeb138d546384e83525e1796a94e1f369218639a5dab4cfaabcc3
MD5 d5a320f28ee860ec042c4205da95a20b
BLAKE2b-256 ff69bdf8250fc126b65c9adb193cc902fffff74e7a0731ecc0df985156382be2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7a1b468ad73e7d8a8884333967e956538aa13e8d5e890fac3cfae01c27047fb5
MD5 d170c747200bf0a88b2afcb15a7f2e0e
BLAKE2b-256 889ea91e7b186682e55d18ae1ce4dd4ed8655341f3298454be5e03bc80468e80

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp314-cp314-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 3d9643c9074dbf87a96134709e993ba424037b31184e65b1d838d2977c4b9da1
MD5 21d7d14440b47b69c1625afd09793900
BLAKE2b-256 8d84dfd5229d8d2d0b4747927f96218e6ebcda6fe5df659bc318f31977b017d6

See more details on using hashes here.

File details

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

File metadata

  • Download URL: granian-2.7.5-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.5-cp313-cp313t-win_amd64.whl
Algorithm Hash digest
SHA256 a556623974ec66121666e861b1235b2f702f2437d2827e0672f02b1cece61e7d
MD5 765fdf4ffff20909b548b20f14c2bd99
BLAKE2b-256 60b96b6fd98bce828e23df8c63142db817552991c6d345ca04521175b00cc70a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp313-cp313t-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 760f921cee53d0a74f4911d1af5bdb3f9b0563028aa6a5b5492eea28c289b6a8
MD5 5794a1a58801e6e2081f3a13f563f830
BLAKE2b-256 066dabfae8170143eb99da88b406598be9433f852669485964b60426813e566a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp313-cp313t-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 b99ef82d76bcf6c33e51b538199eeeb1e118831f46fa45955a0535fd3f7e1f09
MD5 3fe5975f797c40920c2974d69b631ada
BLAKE2b-256 6c22478abe82bcb86adb414073d0e756b72bbd91aa6259f3c71dd32b1fc19e10

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp313-cp313t-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 a1267d76f6767933fb2a2768220e2da260a098e8a5811ad31d5c90c1b93dc554
MD5 b7eebb27e03ffc65691f856d9a879541
BLAKE2b-256 fc895a91c3881b63853c7f04c19b9f194c05490905eebb17a517c5653047ec47

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp313-cp313t-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 3e4bd72e9aa9f9467a4a6c04b44aa598359971b9c75e2304e3b8c6149ba6702d
MD5 c6ec408bcdfd4625006b20b0d2ea32a9
BLAKE2b-256 047c80b3d82586a43830fc1da3b5c04ba2aa5d27ec1c07bbe96fc8010ed3a7f9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 da7772baf0f54e08cf81a18eb0363d035e2b8690c7c23151bec585cc9a1e9b7d
MD5 997b304ca28c7cd7fb2c2353da0350e8
BLAKE2b-256 5b9f5e3692ee0fe3f825dcc26d2f7e16539920b7d7be01fe5eda636e04b3b9b1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 f9a1731de49b8c315d730287c25b78c1fc38f90f2f2f44d154edfb7422b0d6cf
MD5 9dffb7ed3f05b244e1abf3c47cfa6fca
BLAKE2b-256 3a3f7b56295feb4a02121632b9dd25626b5203770932dbf0b1aa9f92152964f3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp313-cp313t-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 f64cb4df20dea367c1adae229aa3c497c6594d480691983b40857ebad1cfee85
MD5 5561afbb4dff666bb6a263c0f2f524ab
BLAKE2b-256 ff40d94255f7654e7050f80c0a9cb8a9e6dd9ee8e4d0d7361c686df829019a56

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp313-cp313t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c4ece8d02d47cb9f35d31086e9f19ed3c9f6133c61ee3ef04ef290a658482a2a
MD5 27b006100da1df6cd5b8ae1e626e28e3
BLAKE2b-256 547df6113afaa52ddb8162bde02c7a05dc27c69c0b44974e0d225ec4a9dcc0eb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp313-cp313t-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 61525e78ab081d5297bedc8e734aed077bc675566baa525b4bf24207b42c8b57
MD5 c31b732a78a6f91458e1de243514efc3
BLAKE2b-256 e9975e966a8bb1bddfd9ff6a820e44bae266cef942bf473b2be6fd6378c0509c

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for granian-2.7.5-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 2066365dd3ee466b2f4e00cc63326cc00645b81af83a1298996512a3e16a112d
MD5 fd18ad69fa7f8f332cd22a85c3d05021
BLAKE2b-256 b041ac692955541a1252d032e1755b531c0283839c4235b98624a36d381bcd01

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp313-cp313-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 e6b682ecca888e0892bb82fd214ed830a41ee3d400fef1c1bcd4949b6018994c
MD5 472050c69b39ddb7ace9c8d3d8b21284
BLAKE2b-256 61a529fdc09f58c2b8ba78f9c1edb2cc524f673aae5a30fd068b9c2446bf3f40

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp313-cp313-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 eaea1538cce2c79e0073cb40cba3a43d08d4824e828d54ba9ed4077c7163f99b
MD5 6d4fdf751d9dc4a7eb98f94980270ac4
BLAKE2b-256 242534adca974959f36196c0a700551b6206a873fcc338631b4e4687ab6f3d41

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp313-cp313-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 0645873118204ac02fdca377eb9fa7b16e7af53c9bf145711c136537d6b6c438
MD5 9b9eb2d18511a15d351b041d18710b63
BLAKE2b-256 67a986689e106641f6909992517391dea4c0b9aca967ea8d42b66479cfb45f9a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp313-cp313-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 d983e2c26df2dda9de8d6d3de657679a29f261803099fa383ad66bbc2cde2faa
MD5 f1e3eed5952f6e45f94e378253ee6161
BLAKE2b-256 cfe22810cadcec697e16d22467792fae1f1ebe19d4530eefeede6e2c2f457592

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 d43c6da412ed4538c92aabbe71be24d6051a9fe14d603079323cbedc395291ca
MD5 33f2b9ee0f1f825e53d8975eb9fee67b
BLAKE2b-256 f75b0b179a4cef14895e3a3a9682d6a98263611ae69922bfaab13e6e690b388c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 0eac951a2650a48dc4a3384bb5f5601beae0ccb0ea282e27050c85202e70faec
MD5 eec4360f3b4b48a26a28ef651393133e
BLAKE2b-256 54ffffa6b209220cb19ea28d878b8ad128b85d6993855d23180e388ba33b0366

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 4f659a4bd4b269fe9f1f58031ff10caa0048106f40791e3e30d1a7b5a5961dfe
MD5 4c8089733495f0dc2b7ce49bd9b86374
BLAKE2b-256 4ffcbf6875fb524e35752959eb6ad6b1ed4c7712b7baa865adff2ed3a323584e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 0e9f2b96b622d88b7057be06b607c97844e0362e09f0af8a68f85758bec64867
MD5 601aaf3a638ec6fb751985001669e904
BLAKE2b-256 e65b900ce216039d27aa79a14a2045baf1fb2718c5e27426f185bce2cb820b5a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp313-cp313-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 a9b78b188e61edcba62a060f6d6ce57926acdbfe7981af2cdd8eee34e4b2d18c
MD5 66afce771a16d7c0f268dbbbcac83f5e
BLAKE2b-256 3c9ffdc72f905736152a71a50d6bda801d5a7c99a9faba23be1151b7dc1e3dcc

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for granian-2.7.5-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 2b79de2fc006ef6425eb95d8d121fe322dbb2598ed0d0db0d4346ce84910240a
MD5 2f7f6bbc23c1859edf164b6b18967314
BLAKE2b-256 aead336ffdf9da3038a6efaa0fa3dcb0b9635759cdf8f89cad1895cf7994ff52

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp312-cp312-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 10083dfb27064e404be220ee3e0b3cf80b6280a0317da6bb325e1fd7c68c6760
MD5 331a81cfa1047c6e037bcbb46a1a5133
BLAKE2b-256 8ac590e8ec2b58f14d57be9ad71be5bf568dad1115363c60071e26142d39517b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp312-cp312-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 81eb0706ddcb8d7c53d6a8a8f322caa0226877a1500d1e6bed011f058b8267c1
MD5 713b730d19857daea3219381e37faf0b
BLAKE2b-256 a1090c041555e1ed5d1b41b2d99752041eebeb4e98614f0abb267d8417ec4a38

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp312-cp312-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 6448ab0af286d7d895bc5b57bd6d377eaaf848d07eb9dfe65ec331055b1bc5a5
MD5 01270ddcdca677caa1d5509e6dc4726e
BLAKE2b-256 3d3df326b004461136f77dafc42cfdcba94c8f63151a2e03606c9727eb90a591

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp312-cp312-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 bd4172335ede04cb693c2d71d3b255508c27d0be16e00fcc938846fab3475fa0
MD5 e0e544d605432c9eb7ef206a2bbbe437
BLAKE2b-256 8f3aa0026fb26632ef8fffe6dfab5d976c806722629f2170b04ad6690ab1c555

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 54ed599f5b3f1f94c0e85324b9a238dc1dacc35faf34fbfd8b38fb4f310da7b8
MD5 7303ac8227fcef6c0ee562512008c481
BLAKE2b-256 797a3d5f36ebf8b9da9366d5708d9cabb5d3b25e212ada253bb30619e0dfa691

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 3e7aa181771c737d12bc56ee83906ebbe1d6ac1a32f90f9c0dd27aadd60f00aa
MD5 0ec6a3818e40f64d267942cc7b5e2ec3
BLAKE2b-256 5504584399bd98a6fb157fe378dd54bcb0e7c1e11dade9c893ec27d4e4749875

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 2a3534d40ef71e80d781734eef8e09dace8c4c3894567a0d3c918c94912756d6
MD5 fffda9df550f835b9f468589dfcc7119
BLAKE2b-256 776a37e1ec25e5d852651c31df723a799b2341baadb460e1fea8aa8a5dd5859f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c2b691c65bec9b29f48167afc09cd588b86aa8562092445d94c95fa00bbcbceb
MD5 e03d19169b15632342a7f0c03a256c37
BLAKE2b-256 97d7de716b81c1444c44e51f44944ff276be9b8b7c7f7aff1f7f0b33408b08a4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 34cb7cf699cd0f63c56a4a28e5a08c55504d67b4298daebf984fe95a85d59c64
MD5 5f43dd9e446acfeeb6f6a7f37451268c
BLAKE2b-256 7eba9481493eb518b5f6ab71aaa600fdd03be9abfc0ff57e4b9f959cf55fd225

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for granian-2.7.5-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 92b6a66b6317f14aaf8e8c98f6681c1691db23770e80cfe68ce862440955faf4
MD5 93c20bf1436909fb514eee3f486b3ca3
BLAKE2b-256 bbf5bdb7591cf360e08a7edfdf6e0ddbf66ceb855c0fdeaeaf971577b8ebbc63

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp311-cp311-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 624c278adf4a44bfde313059dbbd99ef5031fb5408360c35d33016a680b8ad3a
MD5 b89c8e3359a20a630e25307c715294c3
BLAKE2b-256 e9b29f1135796ca0095dc3d59079525b4203283288f15c8462d47041e7542026

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp311-cp311-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 e634f9bd05cbe12a481d2d477498cf13173306fbe0651099e0b99faf9ada6599
MD5 ae7b99ce8aacb3aa7ec2d2ebfcf1028e
BLAKE2b-256 23820895b274e1caf73f0acc8e8440748a9b33faad8d311b60e3f7cf49ebf62c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp311-cp311-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 019e403a2a6f4a04e09947d8213f2f78a1f06d8e5e840054b3077a7ddbc6837f
MD5 f2d6bcff6e31e7bda22dba28124f16a5
BLAKE2b-256 99d92d117e84bd0dbf2624b6c803c0473b36bfeccd8cd8a1f8dde09785158aa8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp311-cp311-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 a99ab207030c645216f02a7789fbe598927c60118883eb41235c4599a5b0a198
MD5 5b85888c27fbbd2081d3b224263b747c
BLAKE2b-256 168be2931efbcd84b2198a656bb8d22e948a975c669e77253973d6d67d06c700

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 6b6e855a6c4195a0bc58a87a1ffdbc14b9710b30372273511a638196235bcfa6
MD5 db1bddc36de2551ab0cd26d7323c84e5
BLAKE2b-256 60f00b3be716ba780880d6ed0df266fcc5c61b5b3e1f843d6c6e3e6c90483655

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 62032eff99d9201ab95de033b8155f1ea3c3a8ada90f9312d03bb9d9bf6a3e05
MD5 f89f11212a179ab1b82429444327205d
BLAKE2b-256 3b50fce5ef6aa729d15403b396cb8de6e24c027b0ebd6793a121120ea79e0962

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 29c03b03bad095cd4efba588fba31917c4662ab5cf3b372181425071c66c7ded
MD5 6a0806f8e32e57876f5d56614e4cc316
BLAKE2b-256 1a558d962fe47593b60abece1448918b289f3ddb8ecc261dae7b8e66ccc7cbbb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d25a656405277dbd0c229c6b8d35f6dd930b30776f658856be49a6fda5b43a14
MD5 a5a2502a7e95b304a85575f66631694f
BLAKE2b-256 b6c27ab790cae66d8bb2c1f0d68a8f17236973455fd8872851499a79656bf457

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 5ffa7fa3d9d1cdd3de4214c5996edb0fa7c40abd2b7e928c89f2c7e59a7fd8b6
MD5 29898b21886c711b983de97b022af9df
BLAKE2b-256 e40fe028f81e0811e5f38dde3b8d2200b0116657ce2a1b059a9cb62a814139bc

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for granian-2.7.5-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 d5d193f591915bae14d85843c7446169b0cb7a986367a50dd99ae3babb163208
MD5 a0465f63411ab8883cbb8138b0186300
BLAKE2b-256 88a071ad1fc5e8f361f8dfc2874a51718a89c3308366c153f69a4c4f135c0842

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp310-cp310-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 6bb360e6735742533e08c678796edea226505acfc7839ad2c469e374b962991a
MD5 9c5487a1c68810249cadade9efffdd1a
BLAKE2b-256 dc3602e7a2433391b7acb0d5833969f7ef5be9d156b253bd8f1eb90f4583a1f0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp310-cp310-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 b79ae7ab181c5554a20290153bf00220421d4f146fc0531a304b072218bf8ace
MD5 4dfcc99850d62e240939bc5c42d2b32b
BLAKE2b-256 fc4017054dead4a4a87f82fc0ab39c3a5a8eb8dd28de0b3d74c97c1acfa66886

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp310-cp310-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 25451feeff3b61e7ffe5214299e6c262429efaded9c975aa498e69c35c10d80b
MD5 264709932d66c5643378bf6f79bb482e
BLAKE2b-256 792851c28d61e9283e89b10a1ff3222994be157fe1df231ab468436bdbce831a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp310-cp310-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 77ac9723f9909da6bbe94abb3bea4848ce2928c0ddedfe362ed75942a9020b3f
MD5 5a99d0ebe10220dac79c5ff01e2c9a8e
BLAKE2b-256 7ca2ad3cbf8c76b7a226eddcdb3bf138284dbc633575b003b651c4ee0df90f06

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 298d76ccd4abc9e249199cfc264a7283f931731cb51ae1db9d942e8988d43be4
MD5 0e52ce40155f643155751db7085b5d99
BLAKE2b-256 cbe2a07e7de33587d9bd7a90fffbc90e7529e676d278695002fbf4ecdecc2645

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 5db487f2a9257130b58dff08136b1b6ca48d63eff1ed0ef2ad60710fde6b1214
MD5 e4cf5603ea41d8d6f3dee6054317ec0a
BLAKE2b-256 b7360f9b82d2889cb35b7490bf2b2d9a0315a8c7d5df4b2d66c27774ef2e44fc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 ef7278ca52688d1c6a88b24f18f2085744ef2a9f17e2b4c23149fbfb47b5329e
MD5 9d7fcc7cd0c12e39e2fc98fc383cbf2c
BLAKE2b-256 7ea09347afc79f1f44d558a68598606faa39d1da8a3dca1267430050962e4049

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 30d4b2134499b79c0d9fc026568e92421ad693129dfcbc5840faaf56e6cef3da
MD5 3338c615c316e9a9e613be49cc893b09
BLAKE2b-256 8e43b80dfe37e9f835d77139c95641c0c6b83c47d5fe5bbbe70ebf2350732afa

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.5-cp310-cp310-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 67ba116e5e564a4d3f005a7bb52fea2bfacea3a6f0e3f57ebdf04866b98173a0
MD5 62623a73feacd92de18b6c793b8a30a8
BLAKE2b-256 2ea43d1212033183f61561d3c81e942b259d3c57dbed1313c56f88a0c8ecd28c

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