Skip to content

Commit

Permalink
Feat: London Transport Integration (#226)
Browse files Browse the repository at this point in the history
Co-authored-by: Joshua Croft <[email protected]>
  • Loading branch information
dpdrabla and devjsc authored Feb 16, 2024
1 parent bd08cd8 commit 13a4b83
Show file tree
Hide file tree
Showing 8 changed files with 203 additions and 0 deletions.
Binary file added integrations/.DS_Store
Binary file not shown.
8 changes: 8 additions & 0 deletions integrations/london-transport-integration/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.idea/
*.py[cgo]
__pycache__
*.json
!project.json
dist/
*.sqlite3
.DS_Store
38 changes: 38 additions & 0 deletions integrations/london-transport-integration/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# uAgent London Transport Examples

This repository contains examples of london transport journey planner integrations using three agents: `tfl_agent` and `user_agent`.

1. `user_agent` : This agent takes from and to location request as details from user, and responds with all possible routes with detailed plan.

2. `tfl_agent`: This agent takes from and to location from user, fetches the post code using [UK PostCode API](https://rapidapi.com/search/uk%2Bpostcodes) and sends request to tfl request link with journey endpoint. https://api.tfl.gov.uk/Journey/JourneyResults/from_loc/to/to_loc. This sends all possible routes to the user agent.

## Getting Started 🚀

To use these agents, follow the steps below:

### Step 1: Obtain API Keys 🔑

Before running the agents, you need to obtain the required API keys:

#### UK_POSTCODE_API

1. Visit the RapidAPI website: https://rapidapi.com/search/uk%2Bpostcodes
2. If you don't have an account, create one by signing up.
3. Once you are logged in, click on test endpoint and register for API on free-tier.
4. Once done you will see X-RapidAPI-Key in header parameter.

### Step 2: Set API Keys and address in agent scripts

1. Fill in the API Keys in the `tfl_agent` scripts.
2. Replace the london_transport agent address in user agent's script.

### Step 3: Run Project

To run the project and its agents:

```bash
cd src
python main.py
```

Now you have the agents up and running to perform london transport journey planner integrations using the provided APIs. Happy integrating! 🎉
5 changes: 5 additions & 0 deletions integrations/london-transport-integration/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"title": "London Transport Journey Planner",
"description": "This integration helps user to plan Journey using london transport",
"categories": ["London Transport", "Transport"]
}
93 changes: 93 additions & 0 deletions integrations/london-transport-integration/src/agents/tfl_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# importing required libraries
import requests
from uagents import Agent, Model, Context, Protocol
from uagents.setup import fund_agent_if_low
from message.model import Response, Location
import os


# defining london transport angent
london_transport = Agent(
name = 'london_transport_agent',
port = 1123,
seed = 'London Transport agent secret seed phrase',
endpoint = 'http://localhost:1123/submit'
)

# funding london transport agent
fund_agent_if_low(london_transport.wallet.address())

# define function to get postcode from area name
async def get_area_pincode(area_name: str):
api_key = 'YOUR_RAPID_API_KEY' # Replace with your actual RapidAPI key
base_url = "https://uk-postcode.p.rapidapi.com/search"
headers = {
"X-RapidAPI-Host": "uk-postcode.p.rapidapi.com",
"X-RapidAPI-Key": api_key,
}
querystring = {"q": area_name}
try:
response = requests.get(base_url, headers=headers, params=querystring)
response.raise_for_status() # Raises an HTTPError if the response was an error
data = response.json()
pinCode = data['results'][0]['postCode']
return pinCode
except (requests.RequestException, IndexError) as e:
print(f"Error fetching pin code for {area_name}: {e}")
return None

# define function to get possible routes from location1 to location2
async def get_journey_data(loc1_pin, loc2_pin):
try:
tfl_url = f"https://api.tfl.gov.uk/Journey/JourneyResults/{loc1_pin}/to/{loc2_pin}"
reply = requests.get(tfl_url)
reply.raise_for_status() # Check for HTTP errors
data = reply.json()
return data
except requests.RequestException as e:
print(f"Error fetching journey data: {e}")
return None

# checking user agent's address
@london_transport.on_event('startup')
async def agent_address(ctx: Context):
ctx.logger.info(london_transport.address)

# Define Message handler to handle user request
@london_transport.on_message(model = Location, replies = Response)
async def handle_request(ctx: Context, sender: str, msg: Location):
# Get pin codes for the locations
loc1_pin = await get_area_pincode(msg.from_loc)
loc2_pin = await get_area_pincode(msg.to_loc)

response = "" # Initialize an empty string to hold the response

if loc1_pin and loc2_pin:
# Make the initial TfL API request
journey_data = await get_journey_data(loc1_pin, loc2_pin)
for journey in journey_data['journeys']:
response += f"Start Time: {journey['startDateTime']}\n"
response += f"Duration: {journey['duration']} minutes\n"
response += f"Arrival Time: {journey['arrivalDateTime']}\n"

# Loop through each leg of the journey
for leg in journey['legs']:
mode = leg['mode']['name']
departure_time = leg['departureTime']
arrival_time = leg['arrivalTime']
distance = leg.get('distance', 'N/A') # Some legs might not have distance information

# Append leg details to the response string
response += f"\nLeg Mode: {mode}\n"
response += f"Departure Time: {departure_time}\n"
response += f"Arrival Time: {arrival_time}\n"
response += f"Distance: {distance} meters\n"

# Instruction details if available
if 'instruction' in leg:
instruction_summary = leg['instruction']['summary']
response += f"Instructions: {instruction_summary}\n"

response += "\n--------------------------------\n"
# Sending back response to user agent
await ctx.send(sender, Response(response = response))
38 changes: 38 additions & 0 deletions integrations/london-transport-integration/src/agents/user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# import required libraries
from uagents import Agent, Context
from uagents.setup import fund_agent_if_low
from message.model import Response, Location
import os

# restuarant agent's address
londonTransportAgent = "YOUR_TRANSPORT_AGENT_ADDRESS" # replace with your london transport agent

# defining user agent
user = Agent(
name="user",
port=8000,
seed="user secret phrase",
endpoint=["http://localhost:8000/submit"],
)

#funding user agent
fund_agent_if_low(user.wallet.address())

#checking user agent's address
@user.on_event('startup')
async def agent_address(ctx: Context):
ctx.logger.info(user.address)

# This on_interval agent function performs a request on a defined period of 100 seconds
@user.on_interval(period=100.0, messages=Location)
async def interval(ctx: Context):
#taking input for city and category from user
from_loc = str(input('From where you want to travel using london transport?'))
to_loc = str(input('To where you want to travel using london transport?'))
await ctx.send(londonTransportAgent, Location(from_loc = from_loc, to_loc = to_loc))

#Logging response from Business finder agent
@user.on_message(Response)
async def handle_query_response(ctx: Context, sender: str, msg: Response):
ctx.logger.info(msg.response)

10 changes: 10 additions & 0 deletions integrations/london-transport-integration/src/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from agents.tfl_agent import london_transport
from agents.user import user
from uagents import Bureau

#adding all users to bureau and running it
if __name__ == "__main__":
bureau = Bureau(endpoint="http://127.0.0.1:8000/submit", port=8000)
bureau.add(london_transport)
bureau.add(user)
bureau.run()
11 changes: 11 additions & 0 deletions integrations/london-transport-integration/src/message/model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Importing model from uagents libraru
from uagents import Model

# defining model to take input form user
class Location(Model):
from_loc : str
to_loc : str

# defining model to give response to user.
class Response(Model):
response : str

0 comments on commit 13a4b83

Please sign in to comment.