1- # graphfaker/cli.py
21"""
32Command-line interface for GraphFaker.
43"""
4+
55from venv import logger
66import typer
77from graphfaker .core import GraphFaker
8+ from graphfaker .enums import FetcherType
89from graphfaker .fetchers .osm import OSMGraphFetcher
910from graphfaker .fetchers .flights import FlightGraphFetcher
11+ from graphfaker .utils import parse_date_range
1012
1113app = typer .Typer ()
1214
1315
14- @app .command ()
16+ @app .command (short_help = "Generate a graph using GraphFaker." )
1517def gen (
16- source : str = typer .Option ("faker" , help = "Generation source faker library) " ),
17- # for faker source
18- total_nodes : int = typer .Option (100 , help = "Total nodes for random mode" ),
19- total_edges : int = typer .Option (1000 , help = "Total edges for random mode" ),
20- # for osm source
18+ fetcher : FetcherType = typer .Option (FetcherType . FAKER , help = "Fetcher type to use. " ),
19+ # for FetcherType.FAKER source
20+ total_nodes : int = typer .Option (100 , help = "Total nodes for random mode. " ),
21+ total_edges : int = typer .Option (1000 , help = "Total edges for random mode. " ),
22+ # for FetcherType.OSM source
2123 place : str = typer .Option (
22- None , help = "OSM place name (e.g., 'Soho Square, London, UK')"
24+ None , help = "OSM place name (e.g., 'Soho Square, London, UK'). "
2325 ),
2426 address : str = typer .Option (
25- None , help = "OSM address (e.g., '1600 Amphitheatre Parkway, Mountain View, CA')"
27+ None , help = "OSM address (e.g., '1600 Amphitheatre Parkway, Mountain View, CA. ')"
2628 ),
27- bbox : str = typer .Option (None , help = "OSM bounding box as 'north,south,east,west'" ),
29+ bbox : str = typer .Option (None , help = "OSM bounding box as 'north,south,east,west. '" ),
2830 network_type : str = typer .Option (
29- "drive" , help = "OSM network type: drive | walk | bike | all"
31+ "drive" , help = "OSM network type: drive | walk | bike | all. "
3032 ),
31- simplify : str = typer .Option (True , help = "Simplify OSM graph topology" ),
32- retain_all : bool = typer .Option (False , help = "Retain all components in OSM graph" ),
33+ simplify : bool = typer .Option (True , help = "Simplify OSM graph topology. " ),
34+ retain_all : bool = typer .Option (False , help = "Retain all components in OSM graph. " ),
3335 dist : int = typer .Option (
34- 1000 , help = "Search radius (meters) when fetching around address"
36+ 1000 , help = "Search radius (meters) when fetching around address. "
3537 ),
36- # for flight source
38+ # for FetcherType.FLIGHT source
3739 country : str = typer .Option (
38- "United States" , help = "Filter airports by country for flight data"
40+ "United States" ,
41+ help = "Filter airports by country for flight data. e.g 'United States'." ,
42+ ),
43+ year : int = typer .Option (
44+ 2024 , help = "Year (YYYY) for single-month flight fetch. e.g. 2024."
45+ ),
46+ month : int = typer .Option (
47+ 1 , help = "Month (1-12) for single-month flight fetch. e.g. 1 for January."
48+ ),
49+ date_range : str = typer .Option (
50+ None ,
51+ help = "Year, Month and day range (YYYY-MM-DD,YYYY-MM-DD) for flight data. e.g. '2024-01-01,2024-01-15'." ,
3952 ),
40- year : int = typer .Option (2024 , help = "Year (YYYY) for single-month flight fetch" ),
41- month : int = typer .Option (1 , help = "Month (1-12) for single-month flight fetch" ),
42- date_range : tuple = typer .Option (None , help = "Year and Month range for flight data" ),
4353):
4454 """Generate a graph using GraphFaker."""
4555 gf = GraphFaker ()
46- if source == "faker" :
47- G = gf .generate_graph (total_nodes = total_nodes , total_edges = total_edges )
4856
49- elif source == "osm" :
57+ if fetcher == FetcherType .FAKER :
58+
59+ g = gf .generate_graph (total_nodes = total_nodes , total_edges = total_edges )
60+ print (g )
61+ return g
62+
63+ elif fetcher == FetcherType .OSM :
5064 # parse bbox string if provided
5165 bbox_tuple = None
5266 if bbox :
5367 north , south , east , west = map (float , bbox .split ("," ))
5468 bbox_tuple = (north , south , east , west )
55- G = OSMGraphFetcher .fetch_network (
69+ g = OSMGraphFetcher .fetch_network (
5670 place = place ,
5771 address = address ,
5872 bbox = bbox_tuple ,
@@ -61,28 +75,34 @@ def gen(
6175 retain_all = retain_all ,
6276 dist = dist ,
6377 )
64- elif source == "flights" :
78+ print (g )
79+ return g
80+ else :
81+ # Flight fetcher
82+ parsed_date_range = parse_date_range (date_range ) if date_range else None
83+
84+ # validate year and month
85+ if not (1 <= month <= 12 ):
86+ raise ValueError ("Month must be between 1 and 12." )
87+ if not (1900 <= year <= 2100 ):
88+ raise ValueError ("Year must be between 1900 and 2100." )
6589
6690 airlines_df = FlightGraphFetcher .fetch_airlines ()
6791
6892 airports_df = FlightGraphFetcher .fetch_airports (country = country )
6993
70- # 2) Fetch on-time performance data
7194 flights_df = FlightGraphFetcher .fetch_flights (
72- year = year , month = month , date_range = date_range
95+ year = year , month = month , date_range = parsed_date_range
7396 )
7497 logger .info (
7598 f"Fetched { len (airlines_df )} airlines, "
7699 f"{ len (airports_df )} airports, "
77100 f"{ len (flights_df )} flights."
78101 )
79102
80- # 3) Build the NetworkX graph
81- G = FlightGraphFetcher .build_graph (airlines_df , airports_df , flights_df )
82-
83- else :
84- typer .echo (f"Source '{ source } ' not supported." )
85- raise typer .Exit (code = 1 )
103+ g = FlightGraphFetcher .build_graph (airlines_df , airports_df , flights_df )
104+ print (g )
105+ return g
86106
87107
88108if __name__ == "__main__" :
0 commit comments