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

Uploaded PyPyWindows x86-64

granian-2.7.3-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl (7.1 MB view details)

Uploaded PyPymusllinux: musl 1.1+ x86-64

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

Uploaded PyPymusllinux: musl 1.1+ ARMv7l

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

Uploaded PyPymusllinux: musl 1.1+ ARM64

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

Uploaded PyPymanylinux: glibc 2.28+ ARM64

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

Uploaded PyPymacOS 11.0+ ARM64

granian-2.7.3-pp311-pypy311_pp73-macosx_10_12_x86_64.whl (6.6 MB view details)

Uploaded PyPymacOS 10.12+ x86-64

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

Uploaded CPython 3.14tWindows x86-64

granian-2.7.3-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.3-cp314-cp314t-musllinux_1_1_armv7l.whl (7.2 MB view details)

Uploaded CPython 3.14tmusllinux: musl 1.1+ ARMv7l

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

Uploaded CPython 3.14tmusllinux: musl 1.1+ ARM64

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

Uploaded CPython 3.14tmanylinux: glibc 2.28+ ARM64

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

Uploaded CPython 3.14tmanylinux: glibc 2.17+ x86-64

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

Uploaded CPython 3.14tmacOS 11.0+ ARM64

granian-2.7.3-cp314-cp314t-macosx_10_12_x86_64.whl (6.6 MB view details)

Uploaded CPython 3.14tmacOS 10.12+ x86-64

granian-2.7.3-cp314-cp314-win_amd64.whl (4.2 MB view details)

Uploaded CPython 3.14Windows x86-64

granian-2.7.3-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.3-cp314-cp314-musllinux_1_1_armv7l.whl (7.2 MB view details)

Uploaded CPython 3.14musllinux: musl 1.1+ ARMv7l

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

Uploaded CPython 3.14musllinux: musl 1.1+ ARM64

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

Uploaded CPython 3.14manylinux: glibc 2.28+ ARM64

granian-2.7.3-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.3-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.3-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (7.1 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ ARMv7l

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

Uploaded CPython 3.14macOS 11.0+ ARM64

granian-2.7.3-cp314-cp314-macosx_10_12_x86_64.whl (6.6 MB view details)

Uploaded CPython 3.14macOS 10.12+ x86-64

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

Uploaded CPython 3.13tWindows x86-64

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

Uploaded CPython 3.13tmusllinux: musl 1.1+ x86-64

granian-2.7.3-cp313-cp313t-musllinux_1_1_armv7l.whl (7.2 MB view details)

Uploaded CPython 3.13tmusllinux: musl 1.1+ ARMv7l

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

Uploaded CPython 3.13tmusllinux: musl 1.1+ ARM64

granian-2.7.3-cp313-cp313t-manylinux_2_28_aarch64.whl (6.8 MB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.28+ ARM64

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

Uploaded CPython 3.13tmanylinux: glibc 2.17+ x86-64

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

Uploaded CPython 3.13tmanylinux: glibc 2.17+ ARMv7l

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

Uploaded CPython 3.13tmanylinux: glibc 2.12+ i686

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

Uploaded CPython 3.13tmacOS 11.0+ ARM64

granian-2.7.3-cp313-cp313t-macosx_10_12_x86_64.whl (6.6 MB view details)

Uploaded CPython 3.13tmacOS 10.12+ x86-64

granian-2.7.3-cp313-cp313-win_amd64.whl (4.2 MB view details)

Uploaded CPython 3.13Windows x86-64

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

Uploaded CPython 3.13musllinux: musl 1.1+ ARMv7l

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

Uploaded CPython 3.13musllinux: musl 1.1+ ARM64

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

Uploaded CPython 3.13manylinux: glibc 2.28+ ARM64

granian-2.7.3-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.3-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl (6.4 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ i686

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

Uploaded CPython 3.13macOS 11.0+ ARM64

granian-2.7.3-cp313-cp313-macosx_10_12_x86_64.whl (6.6 MB view details)

Uploaded CPython 3.13macOS 10.12+ x86-64

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

Uploaded CPython 3.12Windows x86-64

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

Uploaded CPython 3.12musllinux: musl 1.1+ ARMv7l

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

Uploaded CPython 3.12musllinux: musl 1.1+ ARM64

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

Uploaded CPython 3.12manylinux: glibc 2.28+ ARM64

granian-2.7.3-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.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl (6.4 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ i686

granian-2.7.3-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.3-cp312-cp312-macosx_11_0_arm64.whl (6.1 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

granian-2.7.3-cp312-cp312-macosx_10_12_x86_64.whl (6.6 MB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

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

Uploaded CPython 3.11Windows x86-64

granian-2.7.3-cp311-cp311-musllinux_1_1_x86_64.whl (7.1 MB view details)

Uploaded CPython 3.11musllinux: musl 1.1+ x86-64

granian-2.7.3-cp311-cp311-musllinux_1_1_armv7l.whl (7.2 MB view details)

Uploaded CPython 3.11musllinux: musl 1.1+ ARMv7l

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

Uploaded CPython 3.11musllinux: musl 1.1+ ARM64

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

Uploaded CPython 3.11manylinux: glibc 2.28+ ARM64

granian-2.7.3-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.3-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.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (7.0 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ARMv7l

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

Uploaded CPython 3.11macOS 11.0+ ARM64

granian-2.7.3-cp311-cp311-macosx_10_12_x86_64.whl (6.6 MB view details)

Uploaded CPython 3.11macOS 10.12+ x86-64

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

Uploaded CPython 3.10Windows x86-64

granian-2.7.3-cp310-cp310-musllinux_1_1_x86_64.whl (7.1 MB view details)

Uploaded CPython 3.10musllinux: musl 1.1+ x86-64

granian-2.7.3-cp310-cp310-musllinux_1_1_armv7l.whl (7.2 MB view details)

Uploaded CPython 3.10musllinux: musl 1.1+ ARMv7l

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

Uploaded CPython 3.10musllinux: musl 1.1+ ARM64

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

Uploaded CPython 3.10manylinux: glibc 2.28+ ARM64

granian-2.7.3-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.3-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.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (7.0 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ ARMv7l

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

Uploaded CPython 3.10macOS 11.0+ ARM64

granian-2.7.3-cp310-cp310-macosx_10_12_x86_64.whl (6.6 MB view details)

Uploaded CPython 3.10macOS 10.12+ x86-64

File details

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

File metadata

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

File hashes

Hashes for granian-2.7.3.tar.gz
Algorithm Hash digest
SHA256 c57d32bd3a7d09701a6d1d1dffc116ce3ca972fb1b32c81317de9c109164464c
MD5 c75683f2b7989b722a2e7c8cd13101fd
BLAKE2b-256 88b1ce0836aca78b3267d9d3f44fb8eff22add2bd76741f0a310d5f365c9d8dc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-pp311-pypy311_pp73-win_amd64.whl
Algorithm Hash digest
SHA256 fe43bdbb15405f82ae1206a962c516790bfb870b94a164c1c5ec5a1037f2fdb9
MD5 0de190a50059d873786be2f38c154129
BLAKE2b-256 2e579166721d20af56f578a8fa72822ba32a1b047d1656ef27b79bbbda24f7e4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 d4637c3cf91c6abb6a7a1d4eb11197a23d6bb043d893f65c423c07f8b16a0413
MD5 0233b059ea16278ae9aed402e1662ce7
BLAKE2b-256 132cfa9334c1e139c6e8ce82a983f477c0ac05b0eb1fbf2eabb30aa47e37a2d2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 73de278dc711b21afa5fedacdd64911e416d0edcae00b384edac8ce0802a29f5
MD5 0380509d16c02c4b54cad709fad211c6
BLAKE2b-256 17a28622bd6a8b35192577d1030cfc5a519308c0c28cbe646a9a4fa850cdef18

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 81e399476763c3202f9025313f47bb63c046705623348076a04068be353d90d9
MD5 42b246490f08259a61ea9c991369f14b
BLAKE2b-256 90516b583588b3a404aa0b66be11e4f8cb74fce17fdab88f1cb579e1af6bf2ec

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 3866741f12fea6f62f6d1bf19826813831660954ba59c6bff394bf0d5d63191c
MD5 7c493773a1e076279c62c017fefd89c0
BLAKE2b-256 bee5457627a1f01a657461c77a1b50d0a958fde1883ce8f374ec236ab019c5bf

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 0ccbe06fd0cd6cf14b2383a52e1847863abb41c75ba4df3c19614c9fa6f6a466
MD5 68d272df87c5427de9ed4418f4b66a5f
BLAKE2b-256 68866ba941ab772e5ebe333d54fa845d8a23aa77db21c17308cb5c15329d6b38

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 fd069ef8ccacdc926c28c39a30f631145e0812b0e4ce62741fb4c5b4f2bfa2a1
MD5 cf7003733ee591cbafd67cc329f164e8
BLAKE2b-256 4a1b09d908dea3643a2e4073b9f2bd738a8d5403efb62d0cced9f9e29ae272f7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-pp311-pypy311_pp73-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 d68a61d53287b0ef58600c81ed2fd0d56c1f50e71b5709a8a1292e1321bf4583
MD5 103cfb8ac7d0ea92a94b3dc2f98758f1
BLAKE2b-256 dc081605bb0e45b909b63ad267f30a72d0b4b3b4a0cdc58ceb631b6a01a1cf99

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for granian-2.7.3-cp314-cp314t-win_amd64.whl
Algorithm Hash digest
SHA256 b7d209db3bd4b3845448538f2288006230f5e8bece1bb999f73c5f6899b66d90
MD5 4bbaa52c1a158594b6fee0e1e752545d
BLAKE2b-256 ad9dfa52f3e74b2fba31be77b197339f140444d45709a51a7d963c97187ffcfa

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp314-cp314t-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 c3b554dcfe27b2047133d61bda60d5d98255e12e2a52a11854fda4650c7ca882
MD5 9739feb37cf38d67a88d745a23f64acb
BLAKE2b-256 130316cb32a3184ffe3b94486505a06d973995afb227aa14688b82100873218c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp314-cp314t-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 02ef64622214f8c4b161ec2f136695b8fc37d92ba580141dce4f56d1a05b3595
MD5 8b159839787bf6c4346fcf7af19196f2
BLAKE2b-256 69303a6ddd23dd0aca4c6cbcec476728fff75df0a006cd72eb5b32eb4df444d4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp314-cp314t-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 62a1d670181704c39016bfa5d7e5b81e0167dba34c7b47c63ce96128adef4cee
MD5 a30f040049dab24ce5d2f24922ac6140
BLAKE2b-256 9d11d4914a10aeee8f0e32e9656872ceb4cab65a4a81f8e3053f751880c1e2f8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp314-cp314t-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 2cd750a07cd57777886fdb2f4a814bafdaf2629a4bf0b77bb0c6d827eb421533
MD5 77d531117e846575007b345a68beebcf
BLAKE2b-256 b83b44293ba95baea1753a4a60ddb54a89be047853b1409a9ce8b692a924671f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 8822c0d70c973e7085413ffaec95aeec7485aeaa45407609a38004ff3a396e96
MD5 8ca14579cbf7f5a5db8be3d62f286103
BLAKE2b-256 fbae98e640a3f2c96c31479790255a61e6e9fc6a959e72eeebc5dc590f14dd2c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 1de6bb88fc04a9832e9f05191861e885ccbdbbeea15cdef7340780b28a6dcc80
MD5 06d762ceda257ecd969cb515292d5bdf
BLAKE2b-256 f18eb751cc1cf4ef13b3e70f05e40e312bbf46cda351100b3e86dda473d7768a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 1fb923dd6778e91615e7630464b549df79800c49cc7b8f02c377d8ea105febfd
MD5 1dfc3962cc47e3b3699a85711c6ddc94
BLAKE2b-256 d76055ff3d22b7b131edfe961f3224532b015ddadb445973f597e3f15e1011c8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp314-cp314t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 1c1cc54013ea0f7f2f659cfa49566c3fa4a73517fb642a2633b68bed72377b31
MD5 fad9dc8d61068da93f163a64071521d0
BLAKE2b-256 515aeb84398bc07b01c9f6f209f28f88dca4b73ab3fff018d443d34257394779

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp314-cp314t-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 ddc335bac2d9ba04c98f90309ad1c2986d027cefd6fc8175e782a0d2d0112da9
MD5 9e5321f5c56e10d16b4f6cfcec1ba570
BLAKE2b-256 7da8ced954375d215243a040af6ac5530b08723e034215c080ba6c42bce5705f

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for granian-2.7.3-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 7c0bbb602b8d93f418d27de00d24762816cae4bc0e981ceccec653099351ac63
MD5 d52822ad3b2992c85afc3c8cdb31fc3a
BLAKE2b-256 939e01ed11211198c2c6c820bc3c2a49058a6788c36584d6e9240c086bc3aec6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp314-cp314-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 c110313bccf17331e21e60263fe0cba245302038d93365928f9f164c4e1df846
MD5 15861382dae3f2e5a0b686093de85957
BLAKE2b-256 cf21832827335ffb19c9cb59fd7f9542fe8682a4a3085d49063d51ab5c958d3a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp314-cp314-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 0ba732479015601305bb4fed3e08f98940633fa857f37ad196032ee9cb5119e1
MD5 608cb61b56c77ba247e52b7a08ee1046
BLAKE2b-256 e1008637d00b170703ef993c74aca436f0e1eb384a3eacb2a4dacce368ce6a0a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp314-cp314-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 8e9d09805a15305d3eb050ba89f610725242da91a885c7839bcdb1f6489bff8e
MD5 15c5253f75742d56acf86d1734dd2a74
BLAKE2b-256 14fae579d87a946c403cb05dc8b918e89ffce1f9d0aaab648f14e36e62e5dc9e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp314-cp314-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 0b5855dd0583bab413857e49b3997c99d3cedde9803e6636c3b5da1182d4081b
MD5 01b146677000a982d66466caf9bccd91
BLAKE2b-256 75967f22a33926d84223ee81fa26ee28cb6bbac4e95d546c2fb1b716230cbb24

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 fced47ec04ef2d9f3feb9b272fb9f54a7288092ffe3bce55aa1a8e4c0a46e1ae
MD5 a8e29045feab23391e2a2d5ffba3d37c
BLAKE2b-256 0131f7427ea8259687578a7c386658ec0b61f63ee9926c0e8d8d4bbe480784f9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 d46b7544e59280d2384c22bd9613df4465a1a12b36c1012eb9c4886ab939329b
MD5 8bb455faf279bbe039c72f972ebc0532
BLAKE2b-256 86872e6ffcb76d03d985c3503204c2ea4eeef7c0279c8b3f3d601c16274abce2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 5acfc07a4296ef6fd3f04ec365c9407a43f1fc9316075beabc1987beae23eac5
MD5 6a4459a0460c4a910dfdc8452673adc1
BLAKE2b-256 fc310261ad65c12f9a214ce19eb16c35cd1deb71be0b9e20e958671fbdc2c741

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2fd21da0675db907c7e035cf2b467a4351c2b6b347f82fedd7f128dd2d64a3a9
MD5 0d2cc8e03e5b64366f79e12cc6106343
BLAKE2b-256 874186aa37c475d0adbd147c28c4ded2feb4bd0be7aa27a8429837d5d61cddb4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp314-cp314-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 7a25a78bb490ca1204c46ff027bfe3a5a66ef68b817e68564e9b93c1615c347a
MD5 aa687aa1060ee59c37ca8bc25c9f9363
BLAKE2b-256 06eb60211ce2ecb6db3f0827bf8c3a715c90000589d4fcbbd43a122515180c62

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for granian-2.7.3-cp313-cp313t-win_amd64.whl
Algorithm Hash digest
SHA256 c9b082cf83f58cd27f4eb2f850bc14651b0d817652d2eac773376581c409fd09
MD5 26789d03d74b79dc711b8b1a6a8de68c
BLAKE2b-256 9247dcef3f79c6d8e0c59d9136cfe43a55816f88885211771a3075eebf20d363

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp313-cp313t-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 50b9e2a3914595beb93b15ca6759e7d883333b57e2f0ec603004f1a43c7d52fe
MD5 fea9f850cb1ab583bf484a410ccc16c0
BLAKE2b-256 ffef855cc9f8b47fabae393bf968ae222b76abb2b49adf978350c0996f999715

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp313-cp313t-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 5fd7ddb163bf20bdde1c864109ca0fce2cb20dadff1f70173333419934bf4cbe
MD5 f293bcc685f264e305d6e84beb1affc1
BLAKE2b-256 c0b99afe97d1db9a875015cd6a55256d75fc4234d46cd6444b8149eddd2d3f39

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp313-cp313t-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 0f58ad40bbbefe529e325aeed793d85c81cf6b0b1e5d7814857aa496817eb2f6
MD5 a478149414fe52fe6bf90b1a7e905d00
BLAKE2b-256 3fb337c44f888cbbd0020846a7438d638af50a6b4b106d551b9b95415d82a4fd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp313-cp313t-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 2c3fc51d85ec17769647808183f11b13a4801e8b3816c7954f3fcb77e8974060
MD5 c1ab3fbbc335d5a57939c9c376a0e694
BLAKE2b-256 07c23fc6a25c682e1e4b3ab1b8841b23057daa3dfe18fee7b4508957d98133fc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 d6d14ebf5b2663522624521929c4643e19f0c54c990d14ce5b7065dc26776b35
MD5 146b3037c08964574ceee2a8e581f18e
BLAKE2b-256 72014e5a3a00231e2af3f95e46ba28d3719062f8b098fcbf5662f1b9f39a0801

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 d3c2356fef1142b57a6d6807fa585e13a9e49b8bfe84d2500886f39cac00b11e
MD5 7cab38297f9235d58a6be34310df04f6
BLAKE2b-256 b28f9f319b59b093a41e6e8a67844bb8b0734ad314181d23561e27c8aa5abce8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp313-cp313t-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 598cc467ba4f9aaeb54d8d21a24b8b5d58b2560a0ba63a061bcf6bacc032afc4
MD5 981df5c5d506ad9380fe136abb6fb3cb
BLAKE2b-256 367f69fafb14fa8baa31c7b84211b39e60125bb47ac56b88469c462b0e734120

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp313-cp313t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9f23d4e922bc6a9f7468db41427bdf001f8a6f158de774dfb5914732d51255f6
MD5 c6e218157fb137008ec8fdb485da086c
BLAKE2b-256 749a99bf5a01bff73671a7154d6827cb3a4341bdf5003eddb6a69922b00a1597

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp313-cp313t-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 cf5147a7f48e53b52021d83fad0388912f5f128ec0a876db0579825f08a38f7f
MD5 a7d44f573e1b652b0f3ce77f74d911d6
BLAKE2b-256 8891e0d80c17118c7c63ec43a88a8b152a6a6692f83b28787dfad3d9982eac2f

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for granian-2.7.3-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 d115775e5c92d449a293f81d0d0db0926570a0ad6abd127f6ce1ee2b3559e7c8
MD5 3a858decc10fe2fcac1d4a6c86c3eb30
BLAKE2b-256 b3ce1f1ebffb927f222595df1219250199bde22a7fc27b1a367c08816ac7ba0b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp313-cp313-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 f605064836a9e916e94b2ec0e5a396b6a455d50d12adf046c50f6a1eee627d84
MD5 5b5efe250254fa4935c24c77a5d5b514
BLAKE2b-256 199787d6b608cd01f8aee27609f678e16d69a1791744cc63307df695d01b7db2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp313-cp313-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 1119ca1775cff17742d47c7e0ffd978ade6d5dcc7dd983db88c696376aa8d43b
MD5 f6c5b23c1e546549e00046aa975ae4c3
BLAKE2b-256 2c3a8c0dafb30d3bea01f760c6a2a4a06fc920c3b1f9db0da9a4269aee093c03

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp313-cp313-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 7eb51e0545fce99f22fd8afd4dae0e2fecbf32a22267b1cef71f230f86b666cc
MD5 e1bb13504c02a90871f281577df13dd9
BLAKE2b-256 68c79c325505e94c28c38bcff90f508a566b0c0217c9651fbc2ad9788dd424be

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp313-cp313-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 6d0df7e3a391199d030fae157a25664e1aa7efba39c42310e346353dba498117
MD5 b08c97c9e38563b0a4add8edcaaecaf5
BLAKE2b-256 d5607144d3580df3fd8001a5bfa0cece43fca418b89fbdff59e5972120243aed

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a1e7e0b6cc8ec1ad667c9197566ec11c426bf2e46c2741d49b193e2db6e9437b
MD5 a5ed1db2611c2a29f0135b7208a46db7
BLAKE2b-256 6f6b85231bfd6c6722ebbd0afba841c01b2b863c5171116f5e8ad7e0984c13f9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 177a20798d81618d2754020e0a0a6b2ef0bcd63a7f06501994e97c8cba5be1b0
MD5 743a151aedce4cab60de043bfe842b20
BLAKE2b-256 cb2039a3dbb521e05e3791f8d639ee6ed5ee9b619bea796483ed2f2d288bdad8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 436127669f836cf53d99613ee9ca386359947f3afad7a69ebf68d28d62cc187a
MD5 2aec8c90c576ec8b0bde4d526588432b
BLAKE2b-256 8d298772955d8b54df5ce9efc5b72e92d7c3afe18206a5d56967220f03976d04

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ffb51d740c52de8567969f6b339c60e817b9ed28fdff8ec09660270382f82c06
MD5 8fe924813b3b8185889f020e2c422c3b
BLAKE2b-256 a93b90cf2c64de570050db573f04e38f49662416855a3dcf9857a6d750160617

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp313-cp313-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 69366c3ea384bf86cd7f7174cc19ebac0a3ce789008f6f1793dcf111b088ab06
MD5 c77322acf39eb7578650a5d5dd76032a
BLAKE2b-256 f7dd532a4efef2efb9f10a0a37306a9681678136b4405ae6cd43650df30219fd

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for granian-2.7.3-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 9b0c8c73fceae988cec4c21fde74a0fec7fec8872d6bee2238721fd7306fe5df
MD5 a11c20d23fa36adefad90da50ce7e4d2
BLAKE2b-256 62d39c88ce18b6fd2d96160c0c2d4561247c04ad48c76798b132dc96655d43f2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp312-cp312-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 8e58e121b1e41bda208df1fb017b6f5e12c5bfdae8ad974d5705d9564886853f
MD5 38d96658b50ddbe6d29410f85689c87c
BLAKE2b-256 0a1391e76da41c239c5baff19daee8b43c24c52db29ad688736c4cc4450b3dd6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp312-cp312-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 38b6d7d49356b7f901f8e3b9f9658d364c2191db4b02c7d21ee2a5319a7affdd
MD5 fbf397ab3752c3ffe16088aa5ed9e405
BLAKE2b-256 433b14c1ce99e1a5b66791031ee8e74cd800ac477cfe717f8796dd9af1402ecf

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp312-cp312-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 1c2649af52f3f26143e2363b8209cb7c2ead6559886e157b35cd973fd7a9cd2c
MD5 095bf754aac7831af2ef0f3c67b57191
BLAKE2b-256 af1abaa09d9ad24136ed30535426f131d2a7f7d802f6086a597429fc81654265

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp312-cp312-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 f2f7752edcbea1c8ef0dcace3b71ebdbc2ae55eefb57ab3c5452e47e957b09d6
MD5 d0ea3b5146d490d3ca8afa46bf0f0a74
BLAKE2b-256 9ee2a0cb7236a3d4bf11562538e66ad78307178f84014a2c604e4f31b48b83a9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 19ed615cd42f18e845cd8c27cb63103cc9ae0a7975b821d6d4d6fa2a655e39e4
MD5 289380e017613990115926971dff3050
BLAKE2b-256 f510dadd6e574c704ed70df2bd87381a392cc0b036d98e3c96536058a8660918

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 9761cc21dc9a5a613039c9b4ac940b0c912452e31ffe78fd051411eb489a1c35
MD5 3571a584ae41ab60d067c9ee05db5d69
BLAKE2b-256 86737b854414908fc88365c2aa5743236546cd56471971595e7dbe2b57b68e06

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 364eec292c12fdaa446e7f3c3f764423bee21596ea2f60bfc852fce15924b726
MD5 e0cf483d85a1bea17b940dc39f39a8c1
BLAKE2b-256 569054e9a7816936c9613421773df28d86ca7ac368fe1beeeef31e78fd4794b2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 41f0ea1d7d629da2b3b5c085ec981a27bba5f4e62591516eef9d96707bf30198
MD5 4dea07829a67e4df982fc0ec25b6b931
BLAKE2b-256 71490cab3c84ee7c93f8057201dc484d0478aebdff5c1cfdc3f0f03bc338d760

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 31172169bd888b7f2c02b971488d5c089476f9b045bdd995fb831879df0c09f2
MD5 0d99d3085735ac28040b8ed591099eca
BLAKE2b-256 8e53c141e6f896583ad61ebbd0bb99a237d21d62687bdb69784e698b66520bc2

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for granian-2.7.3-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 75b3825c350feae4ab486591f1ad53e5f8e788c38d78615b127cfaf76f83b120
MD5 4d56eb6cb90a37de9ff94f655300e783
BLAKE2b-256 4cbd084f6a48f243fbf1de4724b0ab4f9748e8d612defff807f9c4805e84038a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp311-cp311-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 a35e97b518fc219c6a96c79e7ceafb88435d4610c50560f46076c0ad3342da81
MD5 0f5e3f71e119d04c535e2019b5d92ec2
BLAKE2b-256 5b82a0a4eee409688d204a6c8814f39a886c25aa30c797b7e05ef9efb16ade55

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp311-cp311-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 62d3e3b0c43e3acfbb38998434ba27fe1b00726fd11c9ea2c6009da09732a1c9
MD5 6d39fbc274a2b187f47e9afd908df3dc
BLAKE2b-256 b009f21d03dff90cf22a38c3bc391e4ead59a58c37a4b2c38545df126f2f3152

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp311-cp311-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 fa6d16d2a6ecc4007bebf8d2a7440b032e0f8d0ea71b127428d7071f44bd1e19
MD5 1c74fc056a2aafc96c532415d0c3bcc3
BLAKE2b-256 91156731f089098658df189e0b6e46d48ba5852ce30c47961014bebbd64a06f1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp311-cp311-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 aedc83bd73605421caaa5880056ad3161f31376ea49c136c561026a9fdbe8ac3
MD5 d6e2379182692728c0250271e725fe4e
BLAKE2b-256 b89407a5e816ad68cf6f3aa4d9101678f19ad09d68d991c7168802367d267d7d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 1cd11fba1a33b118996a5bce69fa3af42aebea287ebcd4c28721bdc6a9f90dcc
MD5 ae42ce2f23a7f120bb336b8025b31963
BLAKE2b-256 db6bfb7c2dfa3108d28ed43568635122f141869a4dfbd18e130f6f67ccc45a9f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 2f872811e563cc6611e5e30e6c95c0acbc3cd25ee9814d4d0dedf3c003d9da3b
MD5 4b039144656ecdcc696543d95a883c69
BLAKE2b-256 a7e6202aee805899483bee509437cdb3774c5bbdf54f14abb201813ddf368b93

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 5c3c2ecc3014b5708ee293d5a319d25ea5129adab86c4b1de70327cbd08ae7fd
MD5 3a777f5c3440991f58762581352420b7
BLAKE2b-256 6e22da49ec787e1ed171f2c2802bba29db113ac1ac9f7069c5de9d74d49c1764

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 765fb45f8e8e99562ac0d9abf18948a433200841c9d5871617a035c8448dbc77
MD5 0f333767d1f774ea1d20bd950d20778a
BLAKE2b-256 10d64807e645603b564ba81c42da86bd4c61de216dacb7080a638ff61ac92847

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 3927a875c013570cab9398d8983bcfee6c96795ebd225518521408ce222c68db
MD5 3083b1f883e24ff6a71f23aefe7c9709
BLAKE2b-256 1eb840b6b5ef3cf68d40ff6be35d87bda4c2fe1b89b1a9f2de32f928274ac508

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for granian-2.7.3-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 30e7115fc9de31f0652fc4d399c29d1fc199e10483a8113eec6351fb524406ad
MD5 f1895b60e6294f8ccc7607ab6344f4bd
BLAKE2b-256 21ce7cbe5500f47d9971e4a1d6adf381bde93d56c76abd5ae2d8cd405b0cb6dc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp310-cp310-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 ae6fcb7f062ad2c481e2f6236df9e44456ec4f037dd7ffe4b1ca9ad71c5ad20c
MD5 9fef1302e916161f8d45ac44c3edbdc7
BLAKE2b-256 58606a88df303b2a122401fff3a715e29e889f1751471ba434ae75238653115c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp310-cp310-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 1d5118852292c9fe0b57c90e37a86efa00a29ce24c76dd67455dd025cba8782d
MD5 a91d229f2096333101daf4eb09606754
BLAKE2b-256 65bc58cb67e45711e430a5fd264707f4c47e635a7bfdf7e34111828b3db1b0bd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp310-cp310-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 54baf31d52815640f887ef9914f2217794fbdfa93a319e735c1138c47a5479d5
MD5 bbca240c31534e06bbe3cc7572f83367
BLAKE2b-256 f8944f36d2286b6685effe9ea152b04d4e4221faa968277e56b8f4b65090b545

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp310-cp310-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 5f8c0601424103d28680aca7020aa1f661f29927ab8a3e9228eefb4d1bdf0c6b
MD5 09fc34b5d90873bd2d9f18158fa9a828
BLAKE2b-256 7feac1ebab94e08458acb488bad91ce4721e72f2334345fa9ae18eb48a605178

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 9f8ec8f75ea88e42a4dd667aa5fe3eca5493bef62837cdf2b3915783e3e05571
MD5 5cb35e9a0baa45e980c3285ed6bdb0fe
BLAKE2b-256 09ddd150afb51a86c371eeb0b27608dd4cd509fc7e1965c380af73da9a1ab95d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 b372429dbd80bfa0d9b767120d9ba4e723c9cf8d321597e357e539b16f584ab3
MD5 faddcf6c0b589008c8ca59ecf86199a4
BLAKE2b-256 e8dc692f611ece83dff029c3b8d6999fa24cabeef0865c1a08600080753261f3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 dff6df2924152e5029ebe5ad50c60cb6a9238e1c8c329745be11b721be406e05
MD5 39867bd33ee4fc9b393df6cdc9b1f450
BLAKE2b-256 53016b35fe4b004b7ded7bee8938dd438c5a21fd5ea84d61049d4682b1646111

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 109019103c4d0a3ae7fc72fed3f5b322e0d4de682f2075092d17d789ddd07f9d
MD5 6c96ea61c0617f15626d6a6af8134b2f
BLAKE2b-256 94e03121bba1abb2910afb2ba0fd99f7d017655b47885bbd8ad4634d458fe9df

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for granian-2.7.3-cp310-cp310-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 3f20cecdf2225c744dff6c497fd033974008c11d693e44f7b84865151e157f2a
MD5 4623ca7351f8c2e1df6b1402f9f287a4
BLAKE2b-256 2aae75015f27493ab19ead56b5f93f78e7a7b50db54f1ac250a61bb61762a09b

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