Migration Guide: From run_socialmapper to Modern API¶
This guide helps you migrate from the deprecated run_socialmapper
function to the modern SocialMapper API.
Why Migrate?¶
The new API provides: - Better error handling with Result types instead of exceptions - Type safety with full type hints - Resource management with context managers - Cleaner configuration with the builder pattern - Progress tracking and async support - Improved testability with dependency injection
Quick Migration Examples¶
Basic POI Analysis¶
Old way:
from socialmapper import run_socialmapper
results = run_socialmapper(
geocode_area="San Francisco",
state="CA",
poi_type="amenity",
poi_name="library",
travel_time=15,
census_variables=["total_population", "median_income"]
)
New way:
from socialmapper import SocialMapperClient
with SocialMapperClient() as client:
result = client.analyze(
location="San Francisco, CA",
poi_type="amenity",
poi_name="library",
travel_time=15,
census_variables=["total_population", "median_income"]
)
if result.is_ok():
analysis = result.unwrap()
# Use analysis.poi_count, analysis.files_generated, etc.
Custom Coordinates¶
Old way:
results = run_socialmapper(
custom_coords_path="my_locations.csv",
travel_time=20,
census_variables=["total_population"],
export_csv=True,
export_isochrones=True
)
New way:
from socialmapper import SocialMapperClient, SocialMapperBuilder
with SocialMapperClient() as client:
config = (SocialMapperBuilder()
.with_custom_pois("my_locations.csv")
.with_travel_time(20)
.with_census_variables("total_population")
.with_exports(csv=True, isochrones=True)
.build()
)
result = client.run_analysis(config)
With API Key and Custom Output¶
Old way:
results = run_socialmapper(
geocode_area="Chicago",
state="IL",
poi_type="leisure",
poi_name="park",
travel_time=30,
geographic_level="zcta",
census_variables=["total_population", "median_age"],
api_key="your-api-key",
output_dir="parks_analysis"
)
New way:
from socialmapper import SocialMapperClient, SocialMapperBuilder
with SocialMapperClient() as client:
config = (SocialMapperBuilder()
.with_location("Chicago", "IL")
.with_osm_pois("leisure", "park")
.with_travel_time(30)
.with_geographic_level("zcta")
.with_census_variables("total_population", "median_age")
.with_census_api_key("your-api-key")
.with_output_directory("parks_analysis")
.build()
)
result = client.run_analysis(config)
Key Differences¶
1. Error Handling¶
Old way: Exceptions are raised
New way: Result types with explicit error handling
result = client.analyze(...)
if result.is_err():
error = result.unwrap_err()
print(f"Error type: {error.type.name}")
print(f"Message: {error.message}")
2. Configuration¶
Old way: Many function parameters
run_socialmapper(
geocode_area="...",
state="...",
poi_type="...",
poi_name="...",
travel_time=15,
# ... many more parameters
)
New way: Fluent builder pattern
config = (SocialMapperBuilder()
.with_location("City", "State")
.with_osm_pois("type", "name")
.with_travel_time(15)
# ... chain as needed
.build()
)
3. Return Values¶
Old way: Dictionary with various keys
results = run_socialmapper(...)
pois = results.get("poi_data", {}).get("pois", [])
census = results.get("census_data", [])
New way: Structured result object
if result.is_ok():
analysis = result.unwrap()
print(f"POIs found: {analysis.poi_count}")
print(f"Census units: {analysis.census_units_analyzed}")
for file_type, path in analysis.files_generated.items():
print(f"{file_type}: {path}")
4. Client Configuration¶
New way only: Configure client behavior
from socialmapper import SocialMapperClient, ClientConfig
config = ClientConfig(
api_key="your-census-api-key",
rate_limit=5, # requests per second
timeout=600, # seconds
retry_attempts=3
)
with SocialMapperClient(config) as client:
# Use client with custom configuration
Advanced Features¶
Progress Tracking¶
def on_progress(percent: float):
print(f"Progress: {percent:.1f}%")
result = client.run_analysis(config, on_progress=on_progress)
Batch Processing¶
configs = [config1, config2, config3]
with client.batch_analyses(configs) as batch:
results = batch.run_all()
for i, result in enumerate(results):
if result.is_ok():
print(f"Analysis {i+1} completed")
Custom Cache Strategy¶
class MyCache:
def get(self, key: str):
# Your cache implementation
pass
def set(self, key: str, value: Any, ttl: Optional[int] = None):
# Your cache implementation
pass
config = ClientConfig(cache_strategy=MyCache())
Common Patterns¶
1. Simple Analysis¶
# Most common use case
with SocialMapperClient() as client:
result = client.analyze(
location="Portland, OR",
poi_type="amenity",
poi_name="library"
)
2. Full Configuration¶
# When you need full control
with SocialMapperClient() as client:
config = (SocialMapperBuilder()
.with_location("Austin", "TX")
.with_osm_pois("amenity", "school", {"operator": "Austin ISD"})
.with_travel_time(20)
.with_census_variables(
"total_population",
"median_household_income",
"percent_poverty",
"percent_without_vehicle"
)
.with_geographic_level("block-group")
.with_exports(csv=True, isochrones=True)
.with_output_directory("school_analysis")
.build()
)
result = client.run_analysis(config)
3. Error Recovery¶
with SocialMapperClient() as client:
locations = ["San Francisco, CA", "Invalid City, XX", "Seattle, WA"]
for location in locations:
result = client.analyze(location, "amenity", "hospital")
match result:
case Ok(analysis):
print(f"{location}: {analysis.poi_count} hospitals")
case Err(error) if error.type == ErrorType.GEOCODING:
print(f"{location}: Could not geocode location")
case Err(error):
print(f"{location}: {error.message}")
Need Help?¶
- Check the API Reference for detailed documentation
- See examples for working code samples
- Report issues at https://github.com/anthropics/socialmapper/issues