Skip to content

Commit 5b95902

Browse files
committed
feat: setup logging
1 parent 4d05fde commit 5b95902

File tree

11 files changed

+467
-235
lines changed

11 files changed

+467
-235
lines changed

examples/demo_graphfaker.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
2-
1+
from graphfaker.logger import logger
32
import marimo
43

54
__generated_with = "0.13.1"
@@ -25,13 +24,15 @@ def _():
2524
# suppress only the single warning from unverified HTTPS
2625
import urllib3
2726
from urllib3.exceptions import InsecureRequestWarning
27+
2828
urllib3.disable_warnings(InsecureRequestWarning)
2929
return
3030

3131

3232
@app.cell
3333
def _():
3434
from graphfaker.fetchers.flights import FlightGraphFetcher
35+
3536
return (FlightGraphFetcher,)
3637

3738

@@ -51,13 +52,14 @@ def _(FlightGraphFetcher):
5152

5253
@app.cell
5354
def _(FlightGraphFetcher):
54-
flights = FlightGraphFetcher.fetch_flights(year=2024,month=1)
55+
flights = FlightGraphFetcher.fetch_flights(year=2024, month=1)
5556
return
5657

5758

5859
@app.cell
5960
def _():
6061
from graphfaker import GraphFaker
62+
6163
return (GraphFaker,)
6264

6365

@@ -82,12 +84,13 @@ def _(G_flight):
8284
@app.cell
8385
def _():
8486
import scipy
87+
8588
return
8689

8790

8891
@app.cell
8992
def _():
90-
#gf.visualize_graph(G_flight)
93+
# gf.visualize_graph(G_flight)
9194
return
9295

9396

@@ -109,9 +112,12 @@ def _(G_flight):
109112
G_small = G_flight.subgraph(sampled).copy()
110113
else:
111114
G_small = G_flight.copy()
112-
113-
print("Original:", G_flight.number_of_nodes(), "nodes,", G_flight.number_of_edges(), "edges")
114-
print("Small :", G_small.number_of_nodes(), "nodes,", G_small.number_of_edges(), "edges")
115+
logger.info(
116+
f"Original: {G_flight.number_of_nodes()} nodes, {G_flight.number_of_edges()} edges"
117+
)
118+
logger.info(
119+
f"Small : {G_small.number_of_nodes()} nodes, {G_small.number_of_edges()} edges"
120+
)
115121

116122
return (G_small,)
117123

examples/example_osm_faker_visualization.py

Lines changed: 37 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
# run_demo.py
22

33
import matplotlib
4-
matplotlib.use("TkAgg") # pick a GUI backend on desktop
4+
5+
matplotlib.use("TkAgg") # pick a GUI backend on desktop
56
from graphfaker.core import GraphFaker
67
import networkx as nx
78
from matplotlib import pyplot as plt
9+
from graphfaker.logger import logger
810

911

1012
# visualization function for faker source
@@ -18,10 +20,14 @@ def visualize_faker_graph(self, title, k=1.5, iterations=100):
1820
"Place": "lightgreen",
1921
"Organization": "orange",
2022
"Event": "pink",
21-
"Product": "yellow"
23+
"Product": "yellow",
2224
}
23-
node_colors = [color_map.get(data.get("type"), "gray") for _, data in self.G.nodes(data=True)]
24-
nx.draw_networkx_nodes(self.G, pos, node_color=node_colors, node_size=500, alpha=0.9)
25+
node_colors = [
26+
color_map.get(data.get("type"), "gray") for _, data in self.G.nodes(data=True)
27+
]
28+
nx.draw_networkx_nodes(
29+
self.G, pos, node_color=node_colors, node_size=500, alpha=0.9
30+
)
2531
nx.draw_networkx_edges(self.G, pos, alpha=0.4)
2632
labels = {node: data.get("name", node) for node, data in self.G.nodes(data=True)}
2733
nx.draw_networkx_labels(self.G, pos, labels=labels, font_size=8)
@@ -30,13 +36,15 @@ def visualize_faker_graph(self, title, k=1.5, iterations=100):
3036
plt.show()
3137

3238

33-
3439
# Visualize osm data.. since it's a multigraph
35-
def visualize_osm(self, G: nx.Graph = None,
36-
show_edge_names: bool = False,
37-
show_node_ids: bool = False,
38-
node_size: int = 20,
39-
edge_linewidth: float = 1.0):
40+
def visualize_osm(
41+
self,
42+
G: nx.Graph = None,
43+
show_edge_names: bool = False,
44+
show_node_ids: bool = False,
45+
node_size: int = 20,
46+
edge_linewidth: float = 1.0,
47+
):
4048
"""
4149
Visualize an OSM-derived graph using OSMnx plotting, with optional labels.
4250
:param G: The graph to visualize (default: last generated graph).
@@ -50,43 +58,48 @@ def visualize_osm(self, G: nx.Graph = None,
5058
try:
5159
import osmnx as ox
5260
except ImportError:
53-
raise ImportError("osmnx is required for visualize_osm. Install via `pip install osmnx`.")
61+
raise ImportError(
62+
"osmnx is required for visualize_osm. Install via `pip install osmnx`."
63+
)
5464
# Plot base OSM network
55-
fig, ax = ox.plot_graph(G, node_size=node_size, edge_linewidth=edge_linewidth,
56-
show=False, close=False)
65+
fig, ax = ox.plot_graph(
66+
G, node_size=node_size, edge_linewidth=edge_linewidth, show=False, close=False
67+
)
5768
# Prepare positions for labeling
58-
pos = {node: (data.get('x'), data.get('y')) for node, data in G.nodes(data=True)}
69+
pos = {node: (data.get("x"), data.get("y")) for node, data in G.nodes(data=True)}
5970
# Edge labels
6071
if show_edge_names:
6172
edge_labels = {}
6273
for u, v, data in G.edges(data=True):
63-
name = data.get('name')
74+
name = data.get("name")
6475
if name:
6576
# OSMnx 'name' can be list or string
6677
label = name if isinstance(name, str) else ",".join(name)
6778
edge_labels[(u, v)] = label
68-
nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels, font_size=6, ax=ax)
79+
nx.draw_networkx_edge_labels(
80+
G, pos, edge_labels=edge_labels, font_size=6, ax=ax
81+
)
6982
# Node labels
70-
if show_node_ids or any('name' in d for _, d in G.nodes(data=True)):
83+
if show_node_ids or any("name" in d for _, d in G.nodes(data=True)):
7184
labels = {}
7285
for node, data in G.nodes(data=True):
7386
if show_node_ids:
7487
labels[node] = str(node)
75-
elif 'name' in data:
76-
labels[node] = data['name']
88+
elif "name" in data:
89+
labels[node] = data["name"]
7790
nx.draw_networkx_labels(G, pos, labels=labels, font_size=6, ax=ax)
7891
ax.set_title("OSM Network Visualization")
7992
plt.show()
8093

8194

82-
8395
# Create the graph with defaults (can be overridden by user input)
8496
if __name__ == "__main__":
8597
gf = GraphFaker()
8698
G = gf.generate_graph(total_nodes=20, total_edges=60)
87-
print("-> graphfaker generation <-")
88-
print("Total nodes:", G.number_of_nodes())
89-
print("Total edges:", G.number_of_edges())
99+
logger.info("-> GraphFaker graph generation started <-")
100+
logger.info("Graph summary:")
101+
logger.info(" Total nodes: %s", G.number_of_nodes())
102+
logger.info(" Total edges: %s", G.number_of_edges())
90103
gf.visualize_faker_graph(title="Graph Faker PoC ")
91104
# sg.export_graph(filename="social_knowledge_graph.graphml")
92105

@@ -99,11 +112,6 @@ def visualize_osm(self, G: nx.Graph = None,
99112

100113
# OSM network
101114
G_osm = gf.generate_graph(
102-
source="osm",
103-
place="Chinatown, San Francisco, California",
104-
network_type="drive"
115+
source="osm", place="Chinatown, San Francisco, California", network_type="drive"
105116
)
106117
gf.visualize_faker_graph(G_osm)
107-
108-
109-

examples/experiment_wikidata.py

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import marimo
2+
from graphfaker.logger import logger
23

34
__generated_with = "0.13.1"
45
app = marimo.App()
@@ -8,12 +9,14 @@
89
def _():
910
import pandas as pd
1011
import SPARQLWrapper as sw
12+
1113
return (pd,)
1214

1315

1416
@app.cell
1517
def _():
1618
import requests
19+
1720
return (requests,)
1821

1922

@@ -36,12 +39,19 @@ def _(WIKIDATA_SPARQL_URL, requests):
3639
def run_sparql_query(query):
3740
"""Fetch data from Wikidata using SPARQL."""
3841
headers = {"Accept": "application/json"}
39-
response = requests.get(WIKIDATA_SPARQL_URL, params={"query": query, "format": "json"}, headers=headers)
42+
response = requests.get(
43+
WIKIDATA_SPARQL_URL,
44+
params={"query": query, "format": "json"},
45+
headers=headers,
46+
)
4047
if response.status_code == 200:
4148
return response.json()["results"]["bindings"]
4249
else:
43-
print("SPARQL Query Failed!", response.status_code)
50+
logger.error(
51+
"SPARQL Query Failed! Error: %s", response.status_code, exc_info=True
52+
)
4453
return []
54+
4555
return (run_sparql_query,)
4656

4757

@@ -70,12 +80,14 @@ def fetch_ceos_and_companies():
7080
G.add_edge(ceo_id, company_id, relationship="CEO_of")
7181

7282
return G
83+
7384
return (fetch_ceos_and_companies,)
7485

7586

7687
@app.cell
7788
def _():
7889
import matplotlib.pyplot as plt
90+
7991
return
8092

8193

@@ -99,7 +111,13 @@ def generate_people(num=10):
99111
G = nx.Graph()
100112
for i in range(num):
101113
pid = f"person_{i}"
102-
G.add_node(pid, type="Person", name=fake.name(), email=fake.email(), age=random.randint(18, 80))
114+
G.add_node(
115+
pid,
116+
type="Person",
117+
name=fake.name(),
118+
email=fake.email(),
119+
age=random.randint(18, 80),
120+
)
103121
return G
104122

105123
@staticmethod
@@ -115,20 +133,29 @@ def generate_organizations(num=5):
115133
G = nx.Graph()
116134
for i in range(num):
117135
oid = f"org_{i}"
118-
G.add_node(oid, type="Organization", name=fake.company(), industry=fake.job())
136+
G.add_node(
137+
oid, type="Organization", name=fake.company(), industry=fake.job()
138+
)
119139
return G
120140

121141
@staticmethod
122142
def connect_people_to_organizations(G, people_nodes, org_nodes):
123143
for p in people_nodes:
124144
org = random.choice(org_nodes)
125-
G.add_edge(p, org, relationship=random.choice(["works_at", "consults_for", "owns"]))
145+
G.add_edge(
146+
p,
147+
org,
148+
relationship=random.choice(["works_at", "consults_for", "owns"]),
149+
)
126150

127151
@staticmethod
128152
def connect_people_to_places(G, people_nodes, place_nodes):
129153
for p in people_nodes:
130154
place = random.choice(place_nodes)
131-
G.add_edge(p, place, relationship=random.choice(["lives_in", "born_in"]))
155+
G.add_edge(
156+
p, place, relationship=random.choice(["lives_in", "born_in"])
157+
)
158+
132159
return (Graphfaker,)
133160

134161

@@ -138,8 +165,12 @@ def _(Graphfaker):
138165
G_fake_places = Graphfaker.generate_places(5)
139166
G_fake_orgs = Graphfaker.generate_organizations(5)
140167

141-
Graphfaker.connect_people_to_organizations(G_people, list(G_people.nodes), list(G_fake_orgs.nodes))
142-
Graphfaker.connect_people_to_places(G_people, list(G_people.nodes), list(G_fake_places.nodes))
168+
Graphfaker.connect_people_to_organizations(
169+
G_people, list(G_people.nodes), list(G_fake_orgs.nodes)
170+
)
171+
Graphfaker.connect_people_to_places(
172+
G_people, list(G_people.nodes), list(G_fake_places.nodes)
173+
)
143174
return (G_people,)
144175

145176

@@ -157,7 +188,7 @@ def _(G_people, nx):
157188

158189
@app.cell
159190
def _(ceos_and_companies):
160-
print(ceos_and_companies.nodes(data=True))
191+
logger.info(ceos_and_companies.nodes(data=True))
161192
return
162193

163194

@@ -182,6 +213,7 @@ def fetch_places():
182213
G.add_node(city_id, type="Place", name=city_name)
183214

184215
return G
216+
185217
return
186218

187219

@@ -211,12 +243,16 @@ class WikiDataQueryResults:
211243
A class that can be used to query data from Wikidata using SPARQL and return the results as a Pandas DataFrame or a list
212244
of values for a specific key.
213245
"""
246+
214247
def __init__(self, query: str):
215248
"""
216249
Initializes the WikiDataQueryResults object with a SPARQL query string.
217250
:param query: A SPARQL query string.
218251
"""
219-
self.user_agent = "WDQS-example Python/%s.%s" % (sys.version_info[0], sys.version_info[1])
252+
self.user_agent = "WDQS-example Python/%s.%s" % (
253+
sys.version_info[0],
254+
sys.version_info[1],
255+
)
220256
self.endpoint_url = "https://query.wikidata.org/sparql"
221257
self.sparql = SPARQLWrapper(self.endpoint_url, agent=self.user_agent)
222258
self.sparql.setQuery(query)
@@ -233,7 +269,7 @@ def __transform2dicts(self, results: List[Dict]) -> List[Dict]:
233269
for result in results:
234270
new_result = {}
235271
for key in result:
236-
new_result[key] = result[key]['value']
272+
new_result[key] = result[key]["value"]
237273
new_results.append(new_result)
238274
return new_results
239275

@@ -244,7 +280,7 @@ def _load(self) -> List[Dict]:
244280
:return: A list of dictionaries, where each dictionary represents a result row and has keys corresponding to the
245281
variables in the SPARQL SELECT clause.
246282
"""
247-
results = self.sparql.queryAndConvert()['results']['bindings']
283+
results = self.sparql.queryAndConvert()["results"]["bindings"]
248284
results = self.__transform2dicts(results)
249285
return results
250286

@@ -255,6 +291,7 @@ def load_as_dataframe(self) -> pd.DataFrame:
255291
"""
256292
results = self._load()
257293
return pd.DataFrame.from_dict(results)
294+
258295
return (WikiDataQueryResults,)
259296

260297

@@ -273,7 +310,7 @@ def _(data_extracter):
273310
@app.cell
274311
def _(data_extracter):
275312
df = data_extracter.load_as_dataframe()
276-
print(df.head())
313+
logger.info(df.head())
277314
return
278315

279316

0 commit comments

Comments
 (0)