pypply 1.0.0
Makes it easier to use Upply API
Requires Python: >=3.9
Keywords: transport, upply, benchmark, freight, smart, supply-chain, api, python

# pypply

***pypply* makes it easier to use Upply API by providing a simple, well-structured Python interface for retrieving benchmark rates, UFI data, and geographic information. 
With quick and straightforward integration — just like the Upply API — you can get up and running in minutes.
It handles API connections, payload processing, and error management so you can focus on building your application.**

## Table of Contents

- [Features](#features)
  - [Global](#global)
  - [Products](#products)
- [Installation](#installation)
- [Authentication](#authentication)
- [Usage](#usage)
  - [Geography Feature Usage](#geography-feature-usage)
  - [Benchmark Features Usage](#benchmark-features-usage)
  - [UFI Features Usage](#ufi-features-usage)
- [License](#license)

## Features

### Global
- **Environments**: Easily switch between different API environments. Use the sandbox environment to develop and test your code without running out of credit, and switch to production when you need real Upply data.
- **Payload Processing**: Automatically merge and complete client-provided payloads with default values. This helps reduce code and ensures consistency in your API requests.
- **Validation**: Validate payload structure and input parameters using Pydantic models. This ensures that data sent to the API meets expected formats and types.
- **Error Handling**: Robust error handling with meaningful error messages and logging. This makes debugging easier and ensures that issues are reported clearly to the user.

### Products

#### Geography
- **Geocoding**: Convert a location query (such as a city, airport, or seaport) into its corresponding latitude and longitude.
- **Seamless Integration**: Integrates with benchmark payload processing so that users do not have to supply coordinates manually.

#### Benchmark
- **Benchmark Rates**: Easily retrieve lane benchmark rates for various transport modes (air, road_emea, road_na, sea_longterm) along with their associated rates.
- **Confidence Index**: Obtain a confidence index indicating the reliability of the benchmark result.
- **Emissions**: Retrieve emissions data (e.g., CO₂, SO₂, NOx, etc.) as part of the benchmark response.
- **Default Payload Support**: Use built-in default payloads so that you don't have to specify every parameter manually.
- **Geolocation Integration**: Benchmark requests can automatically fetch latitude and longitude data, eliminating the need for users to provide coordinates explicitly.

#### UFI
- **List Available UFIs**: Easily list and filter available UFIs by transport mode, market, and name.
- **Historical Data**: Retrieve historical UFI data for specified periods with flexible filtering options such as date ranges and number of months.
- **Forecast Data**: Retrieve short-term forecast rates with a configurable number of forecast weeks.
- **Full UFI Rates**: Combine historical and forecast data into a single, comprehensive view.
- **Multiple UFI Support**: Easily retrieve full data for multiple UFIs by filtering based on transport mode, market, and name.



## Installation
You can install *pypply* via pip. Make sure you have Python 3.9 or later.

```bash
pip install pypply
```

## Authentication
Authentication allows you to connect a user's Upply account to your internal app or a third party app. This process involves providing your app with a token that's generated by Upply.
If you don't already have one, please see https://developers.upply.com/docs/token-generation.

## Usage
Below are some usage examples for the main features of *pypply*. Full *pypply* documentation is available at https://developers.upply.com/docs/pypply#/ and Upply API documentation is available at https://developers.upply.com/.

### Geography Feature Usage
The geography feature enables you to retrieve latitude and longitude from location queries.

**Example**

```python
from pypply.geography import Geography

token_client = "01hp1***.69aa***"

# Create a Geography object using your development token
geography = Geography(access_token=token_client)

# Retrieve coordinates for a given query
coordinates = geography.get_lat_long(query="Paris", location_type="airport", country_code="FR")
print(f"Coordinates for Paris airport: {coordinates}")
```

### Benchmark Features Usage
The benchmark features allow you to retrieve lane benchmark rates, confidence indices, and emission data for different transport modes (air, road_emea, road_na, or sea_longterm).

**Example**

```python
from pypply.smart import Smart

token_client = "01hp1***.69aa***"

# Create a Smart object with the desired API environment
smart = Smart(access_token=token_client, env='sandbox')

# Prepare a benchmark payload
payload = {
    "pickup": {
        "latitude": 49.475,
        "longitude": 0.1333328
    },
    "delivery": {
        "latitude": 27.714281,
        "longitude": 106.917885
    },
    "shipment": {
        "container": {
            "unit": "40gp",
            "value": 1
        },
        "hazardous": False
    },
    "schedule": {"etd": "2024-10-25"},
    "pricing": {
        "thc": {
            "origin": True,
            "destination": True
        },
        "service_type": "dtd"
    }
}

# Retrieve benchmark data with optional filters (e.g., rate ranges, emission types)
benchmark_result = smart.benchmark(
    mode='sea_longterm',
    payload=payload,
    emission_types=['co2', 'so2'],
    rate_ranges=['low_high']
)

print(f"Benchmark result: {benchmark_result}")
```

### UFI Features Usage
The UFI features allow you to retrieve both historical and forecast UFI data. You can filter UFIs by transport mode, market, and name, and then request combined historical and forecast data.

**Example**

```python
from pypply.smart import Smart

token_client = "01hp1***.69aa***"

# Create a Smart object
smart = Smart(access_token=token_client, env='sandbox')

# Retrieve a list of UFIs (e.g., filtering by mode and market)
ufi_list = smart.ufi_list(mode='road_emea', market='spot', lang='en')
print(f"Available UFIs: {ufi_list}")

# Retrieve historical data for a specific UFI code
ufi_code = list(ufi_list.keys())[0]
ufi_historical = smart.ufi_historical(code=ufi_code)
print(f"UFI historical data: {ufi_historical}")

# Retrieve forecast data for the same UFI
ufi_forecast = smart.ufi_forecast(code=ufi_code, nb_weeks=4)
print(f"UFI forecast data: {ufi_forecast}")

# Retrieve combined historical and forecast data
ufi_historical_and_forecast = smart.ufi_historical_and_forecast(code=ufi_code)
print(f"UFI historical and forecast data: {ufi_historical_and_forecast}")
```

## Contributing

We welcome issues, code and docs contributions. Please keep PRs small and focused, add tests/docs, and follow our style/linting rules.  
See **[CONTRIBUTING.md](CONTRIBUTING.md)** for the full guide.

### Eligibility and API access

To contribute to code, you must be an **Upply customer** and your **company must have an API token**.  
If you don’t have a token yet, please see https://developers.upply.com/docs/token-generation.

## License
This project is licensed under the MIT License. See the LICENSE file for details.