Skip to main content

An embeddable, dynamically configurable HTTP library

Project description

junction-client

An embeddable, dynamically configurable HTTP library.

About

Junction is a library that allows you to dynamically configure application level HTTP routing, load balancing, and resilience by writing a few lines of configuration and dynamically pushing it to your client. Imagine having all of the features of a rich HTTP proxy that's as easy to work with as the HTTP library you're already using.

Junction can be statically configured, with plain old software, or dynamically configured with any gRPC-xDS compatible configuration server. Check out ezbake for a simple server that lets you save Junction config using the Kubernetes Gateway API

Project status

Junction is alpha software, developed in the open. We're still iterating rapidly on core code and APIs. At this stage you should expect occasional breaking changes as the library evolves. At the moment, Junction only supports talking to Kubernetes services, with support for routing to any existing DNS name coming very soon.

Features

Junction allows you to statically or dynamically configure:

  • Routing traffic to backends based on the HTTP method, path, headers, or query parameters.
  • Timeouts
  • Retries
  • Weighted traffic splitting
  • Load balancing

Junction differs from existing libraries and proxies in that we aim to do all of this in your native programming language, with low overhead and deep integration into your existing HTTP client. This approach means that Junction can provide dynamic config, but still provide first class support for things like unit testing and debugging, putting developers back in control of their applications.

Roadmap

We're starting small and focused with Junction. Our first goal is getting configuration right. Our next goal is allowing you to push configuration that you've developed and tested to a centralized config server.

Supported Languages and HTTP Libraries

Language Core Library Supported HTTP Libraries
Rust junction-core None
Python junction requests and urllib3

Using a Junction client

Junction clients are part of your application and function as a cache for dynamic configuration. All Junction clients can also be configured with static configuration that acts as a default when a server doesn't have any dynamic configuration for a route or a target. When you make an HTTP request, Junction matches it against existing configuration, decides where and how to send the request, and then hands back control to your HTTP library.

In all of our libraries, Junction clients expect to be able to talk to a dynamic configuration server. The details of how you specify which config server to talk to are specific to each language - we want it to feel natural.

If you don't already have a gRPC-compatible xDS server available, try installing ezbake in your local Kubernetes cluster.

Python

In Python, Junction is available as a standalone client and as a drop-in replacement for requests.Session or urllib3.PoolManager.

Using junction as a drop-in replacement for requests is as easy as:

import junction.requests as requests

session = requests.Session()
resp = session.get("http://my-service.prod.svc.cluster.local")

To configure your client, pass default_routes or default_backends to your Session. For example, to load-balance requests to an nginx service in the web namespace based on the x-user header, you can specify:

import junction.requests as requests

# create a new Session with a default load balancing policy for the nginx service
session = requests.Session(
    default_backends=[
        {
            "target": {"type": "service", "name": "nginx", "namespace": "web"},
            "lb": {
                "type": "RingHash",
                "hash_params": [
                    {"type": "Header", "name": "x-user"},
                ],
            },
        }
    ]
)

# make a request to the nginx service
session.get("http://nginx.web.svc.cluster.local")

Routes can be configured by default as well. To send all requests to /v2/users to a different version of your application, you could set a default configuration like:

import junction.config
import typing

import junction.requests as requests

my_service = {"type": "service", "name": "cool", "namespace": "widgets"}
my_test_service = {"type": "service", "name": "cooler", "namespace": "widgets"}

# create a new routing policy.
#
# all Junction config comes with python3 type hints, as long as you import junction.config
routes: typing.List[junction.config.Route] = [
    {
        "target": my_service,
        "rules": [
            {
                "backends": [my_test_service],
                "matches": [{"path": {"value": "/v2/users"}}],
            },
            {
                "backends": [my_service],
                "retry": retry_policy,
                "timeouts": timeouts,
            },
        ],
    },
]


# assert that requests with no path go to the cool service like normal
(_, _, matched_backend) = junction.check_route(
    routes, "GET", "http://cool.widgets.svc.cluster.local", {}
)
assert matched_backend["name"] == "cool"

# assert that requests to /v2/users go to an even cooler service
(_, _, matched_backend) = junction.check_route(
    routes, "GET", "http://cool.widgets.svc.cluster.local/v2/users", {}
)
assert matched_backend["name"] == "cooler"

# use the routes we just tested in our HTTP client
s = requests.Session(default_routes=routes)

For a more complete example configuration see the sample project. It's a runnable example containing routing tables, load balancing, retry policies, and more.

NodeJS

NodeJS support is coming soon! Please reach out to info@junctionlabs.io if you run NodeJS services and are interested in being an early access design partner.

Rust

The core of Junction is written in Rust and is available in the junction-core crate. At the moment, we don't have an integration with an HTTP library available, but you can use the core client to dynamically fetch config and resolve addresses.

See the examples directory for an example of how to use junction to resolve an address.

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

junction_python-0.1.0a1.tar.gz (151.8 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

junction_python-0.1.0a1-cp38-abi3-macosx_11_0_arm64.whl (4.3 MB view details)

Uploaded CPython 3.8+macOS 11.0+ ARM64

junction_python-0.1.0a1-cp38-abi3-macosx_10_12_x86_64.whl (4.5 MB view details)

Uploaded CPython 3.8+macOS 10.12+ x86-64

File details

Details for the file junction_python-0.1.0a1.tar.gz.

File metadata

  • Download URL: junction_python-0.1.0a1.tar.gz
  • Upload date:
  • Size: 151.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.4.28

File hashes

Hashes for junction_python-0.1.0a1.tar.gz
Algorithm Hash digest
SHA256 68ef77983047c2f595d64af713d47fe4df6ade3e82c222945a3402abe90a7121
MD5 c4e01a7cfa0834ce565f9c31232fae6e
BLAKE2b-256 8ab5aee9c64ad2083d2deff732c99ed42db923be85ac15b00fe04dd3b01119e9

See more details on using hashes here.

File details

Details for the file junction_python-0.1.0a1-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for junction_python-0.1.0a1-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e23be59d7a9887c95907a035c4698f645935804b35cb2038693c70e851d2dbd9
MD5 be226841ec8f9e611b92abeb3ab44d73
BLAKE2b-256 348fbd3327a37b0439d46ec6bb9f1c12ffb481e1418667502a36da7a2f045e02

See more details on using hashes here.

File details

Details for the file junction_python-0.1.0a1-cp38-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for junction_python-0.1.0a1-cp38-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 1dd0bc733a8c29bc73f4d8c9e9ea9be23a6380f34829df27b6b508037a9f5c09
MD5 d2adc6aa36321b97dfd8308218a3417f
BLAKE2b-256 43dec634afdd87f4b17bdf255091262ecc0f1010333265383234bc78fd86c533

See more details on using hashes here.

Provenance

The following attestation bundles were made for junction_python-0.1.0a1-cp38-abi3-macosx_10_12_x86_64.whl:

Publisher: release-python.yaml on junction-labs/junction-client

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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