Skip to main content

Spring-Ready Python

Make your Python FastAPI app work seamlessly with Spring Boot ecosystem: Eureka, Config Server, Spring Boot Admin, and Prometheus.

Why This Exists

You have a Spring Boot microservices architecture with Eureka, Config Server, Spring Boot Admin, and Prometheus monitoring. You want to add a Python service but keep everything working together. This library makes that dead simple.

Features

Eureka Service Registration - Automatic registration with heartbeat
Config Server Integration - Load config from Spring Cloud Config with Eureka discovery
Actuator Endpoints - /actuator/health, /actuator/info, /actuator/prometheus
FastAPI Integration - Drop-in support for FastAPI apps
Fail-Fast Behavior - Matches Spring Boot's startup failure handling
Exponential Backoff Retry - Retry logic for Eureka and Config Server
Zero Magic - Own implementation, no hidden dependencies

Installation

pip install spring-ready-python

Optional dependencies:

# For Config Server support
pip install spring-config-client-python

# For Prometheus metrics
pip install prometheus-client

Quick Start

from spring_ready import SpringReadyApp
from fastapi import FastAPI

# Create FastAPI app
app = FastAPI()

# Add Spring integration
spring_app = SpringReadyApp(app)
spring_app.start()

# Your routes
@app.get("/")
def read_root():
    return {"message": "Hello from Spring-Ready Python!"}

# Run with uvicorn
if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8080)

That's it. Your app now:

  • Registers with Eureka
  • Loads config from Config Server (discovered via Eureka)
  • Exposes /actuator/health, /actuator/info, /actuator/prometheus
  • Shows up in Spring Boot Admin

Configuration

Set via environment variables (matching Spring Boot conventions):

# Application
SPRING_APPLICATION_NAME=my-python-service
APP_PORT=8080
SPRING_PROFILES_ACTIVE=production

# Eureka
EUREKA_SERVER_URL=http://eureka:8761/eureka/
EUREKA_INSTANCE_IP=192.168.1.100  # Optional: custom IP for registration
EUREKA_INSTANCE_HOSTNAME=my-service.example.com  # Optional: custom hostname

# Config Server (optional - will be discovered from Eureka)
CONFIG_SERVER_URI=http://config-server:8888
CONFIG_SERVER_USERNAME=admin
CONFIG_SERVER_PASSWORD=secret

Environment Variables Reference

Variable Description Default Example
SPRING_APPLICATION_NAME Application name python-service my-python-service
APP_PORT Application port 8080 8080
SPRING_PROFILES_ACTIVE Active profile default production
EUREKA_SERVER_URL Eureka server URL(s) http://localhost:8761/eureka/ http://eureka:8761/eureka/
EUREKA_INSTANCE_IP Custom IP for registration Auto-detected 192.168.1.100
EUREKA_INSTANCE_HOSTNAME Custom hostname Auto-detected my-service.local
EUREKA_INSTANCE_SECURE Register with HTTPS URLs false true
CONFIG_SERVER_URI Config Server URL Discovered from Eureka http://config:8888
CONFIG_SERVER_SERVICE_ID Config Server service ID CONFIG-SERVER CONFIG-SERVER
CONFIG_SERVER_USERNAME Config Server username None admin
CONFIG_SERVER_PASSWORD Config Server password None secret

Docker Example

FROM python:3.11-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . .

ENV SPRING_APPLICATION_NAME=my-service
ENV EUREKA_SERVER_URL=http://eureka:8761/eureka/
ENV SPRING_PROFILES_ACTIVE=production

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"]
# docker-compose.yml
services:
  my-service:
    build: .
    environment:
      - EUREKA_SERVER_URL=http://eureka:8761/eureka/
      - SPRING_PROFILES_ACTIVE=production
    ports:
      - "8080:8080"

Advanced Usage

Custom Health Checks

from spring_ready import SpringReadyApp

spring_app = SpringReadyApp(app)
spring_app.start()

# Add custom health check
def check_database():
    # Your database check logic
    return database.is_connected()

spring_app.health_endpoint.add_check("database", check_database)

Service Discovery

# Find another service registered in Eureka
config_server_url = spring_app.service_discovery.get_service_url("CONFIG-SERVER")

# Get all instances of a service
instances = spring_app.service_discovery.get_instances("my-other-service")

for instance in instances:
    print(f"Instance: {instance.base_url}")

Manual Configuration

from spring_ready import SpringReadyApp

spring_app = SpringReadyApp(
    app=app,
    app_name="my-service",
    app_port=8080,
    eureka_servers=["http://eureka1:8761/eureka/", "http://eureka2:8761/eureka/"],
    profile="production",
    fail_fast=True,
    prefer_ip_address=True
)
spring_app.start()

Custom IP Address Registration

from spring_ready import SpringReadyApp

# Specify a custom IP address for Eureka registration
# Useful in Docker/Kubernetes when you need to advertise a specific IP
spring_app = SpringReadyApp(
    app=app,
    app_name="my-service",
    instance_ip="192.168.1.100",  # Custom IP address
    instance_hostname="my-service.example.com"  # Optional: custom hostname
)
spring_app.start()

Or via environment variables:

export EUREKA_INSTANCE_IP=192.168.1.100
export EUREKA_INSTANCE_HOSTNAME=my-service.example.com

HTTPS Registration (Secure Mode)

When your application uses HTTPS, you need to register with HTTPS URLs in Eureka so that Spring Boot Admin and other services can connect to it correctly.

from spring_ready import SpringReadyApp

# Register with HTTPS URLs in Eureka
spring_app = SpringReadyApp(
    app=app,
    app_name="my-service",
    app_port=8443,
    secure=True  # Register with https:// URLs
)
spring_app.start()

Or via environment variable:

export EUREKA_INSTANCE_SECURE=true

When secure=True:

  • The homePageUrl, statusPageUrl, and healthCheckUrl will use https://
  • The securePort will be enabled and set to your app_port
  • The regular port will be disabled

This is equivalent to Spring Boot's:

eureka:
  instance:
    secure-port-enabled: true
    non-secure-port-enabled: false

How It Works

Startup Sequence

  1. Eureka Registration: Registers with Eureka (with retry/backoff)
  2. Config Discovery: Discovers Config Server from Eureka
  3. Config Loading: Loads configuration into os.environ
  4. Actuator Setup: Exposes health, info, and metrics endpoints
  5. Heartbeat: Starts background thread for Eureka heartbeats (every 30s)

Shutdown Sequence

  1. Stops heartbeat thread
  2. Deregisters from Eureka
  3. Clean exit

Behavior Matching Spring Boot

Feature Spring Boot spring-ready-python
Fail-fast on startup
Exponential backoff retry
Eureka heartbeat (30s)
Config Server discovery
Actuator endpoints
Graceful shutdown

Actuator Endpoints

GET /actuator/health

Returns application health status:

{
  "status": "UP",
  "components": {
    "diskSpace": {"status": "UP"},
    "eureka": {"status": "UP"},
    "ping": {"status": "UP"}
  }
}

GET /actuator/info

Returns application metadata:

{
  "app": {
    "name": "my-python-service",
    "version": "1.0.0"
  },
  "python": {
    "version": "3.11.5",
    "runtime": {
      "name": "CPython",
      "version": "3.11.5"
    }
  }
}

GET /actuator/prometheus

Returns Prometheus metrics in exposition format:

# HELP python_info Python platform information
# TYPE python_info gauge
python_info{implementation="CPython",version="3.11.5"} 1.0
...

Troubleshooting

No Registration Attempts to Eureka Server

Symptom: You don't see any connection attempts to your Eureka server in logs or network monitoring.

Cause: The application is likely using the default Eureka URL (http://localhost:8761/eureka/) instead of your server.

Solution:

  1. Set the environment variable (Recommended):

    export EUREKA_SERVER_URL=http://10.10.0.1:8761/eureka/
    python your_app.py
    
  2. Or pass it explicitly in code:

    spring_app = SpringReadyApp(
        app,
        eureka_servers=["http://10.10.0.1:8761/eureka/"]
    )
    
  3. Verify your configuration:

    import os
    print(f"EUREKA_SERVER_URL: {os.getenv('EUREKA_SERVER_URL')}")
    
  4. Check the startup logs: Look for this message:

    INFO:spring_ready.core:Configured Eureka server(s): http://10.10.0.1:8761/eureka/
    

    If you see:

    WARNING:spring_ready.core:Using default Eureka server URL (http://localhost:8761/eureka/)
    

    Then you need to set EUREKA_SERVER_URL.

  5. Enable debug logging to see detailed registration attempts:

    import logging
    logging.basicConfig(level=logging.DEBUG)
    
  6. Verify network connectivity:

    curl http://10.10.0.1:8761/eureka/apps
    

    Should return XML/JSON with registered applications.

Common mistakes:

  • Forgetting to set EUREKA_SERVER_URL in Docker/Kubernetes deployments
  • Setting the variable in your IDE but not in the runtime environment
  • Using localhost when running in containers (use service names or IPs instead)

Eureka Registration Fails

Check Eureka server is reachable:

curl http://eureka:8761/eureka/apps

Set fail_fast=False to start anyway:

spring_app = SpringReadyApp(app, fail_fast=False)

Config Server Not Found

Ensure Config Server is registered in Eureka:

curl http://eureka:8761/eureka/apps/CONFIG-SERVER

Or provide direct URL:

export CONFIG_SERVER_URI=http://config-server:8888

Port Already in Use

Change the port:

spring_app = SpringReadyApp(app, app_port=8081)

Or via environment:

export APP_PORT=8081

Differences from Spring Boot

Aspect Spring Boot Python
Metrics names jvm.memory.used process_virtual_memory_bytes
Runtime info Java/JVM Python/CPython
Config refresh /actuator/refresh Not supported (restart required)
Auto-configuration Annotations Explicit initialization

Requirements

  • Python 3.9+
  • FastAPI
  • requests

Optional:

  • spring-config-client-python for Config Server support
  • prometheus-client for metrics

License

MIT

Contributing

Contributions welcome! This library is intentionally simple and focused. See CONTRIBUTING.md.

Comparison with Spring Boot

// Spring Boot (Kotlin)
@SpringBootApplication
@EnableDiscoveryClient
class MyApplication

// Configuration in application.yml
# Python equivalent
from spring_ready import SpringReadyApp
from fastapi import FastAPI

app = FastAPI()
spring_app = SpringReadyApp(app)
spring_app.start()

# Configuration from environment variables

Note: This library focuses on making Python apps work with existing Spring Boot infrastructure. It's not a replacement for Spring Boot itself.

Release files for spring-ready-python 1.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for spring-ready-python 1.1.2
File Size Uploaded
spring_ready_python-1.1.2.tar.gz 53.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for spring-ready-python 1.1.2
File Interpreter ABI Platform
spring_ready_python-1.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 109.3 kB

Release files / spring_ready_python-1.1.2.tar.gz

Download URL spring_ready_python-1.1.2.tar.gz
Size 53.4 kB
Tags Source
SHA-256 checksum
How to use checksums
8c1ab4ec19979313c0137a617136acb2d0bba38277b2788ac190475f0cf3c60c
BLAKE2b-256 checksum
How to use checksums
2adcf270f0705c386b92a243f7b530e03ea16fc0e362a2a3d166dd22b2f16e18
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Feb 11, 2026.

Transparency log

Release files / spring_ready_python-1.1.2-py3-none-any.whl

Download URL spring_ready_python-1.1.2-py3-none-any.whl
Size 56.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
76385ea764924dec2d5ef3d089aad3811884c68d3e5eb95e42a42640d9513a1b
BLAKE2b-256 checksum
How to use checksums
667f25f183e5176acca68ded9bf389dec99bea1f95037dd34016a1153578d414
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Feb 11, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.1.2 This release

2 release files

1.1.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page