Package: safegraphQL
safegraphQLA Python library for accessingSafeGraph datathroughSafeGraph's GraphQL API.Please see theSafeGraph API documentationfor further information on GraphQL, available datasets, query types, use cases, and FAQs.Please file issues on this repository for bugs or feature requests specific to this Python client. For bugs or feature requests related to the SafeGraph API itself, please contact [...]DatasetsCore Places:Base information such as location name, category, and brand association for points of interest (POIs) where consumers spend time or business operations take place. Available for ~9.9MM POI including permanently closed POIs.Geometry: POI footprints with spatial hierarchy metadata depicting when child polygons are contained by parents or when two tenants share the same polygon. Available for ~9.2MM POI (Geometry metadata not provided for closed POIs).Patterns: Place, traffic, and demographic aggregations that answer: how often people visit, how long they stay, where they came from, where else they go, and more. Available for ~4.5MM POI in weekly and monthly versions.Historical data dating back to January 2018 is available via the API for the weekly version of Patterns only. For the monthly version of Patterns, only the most recent month is available via the API.InstallationpipinstallsafegraphQLUsageRequirementsGet an API key from theSafeGraph Shopand instantiate the client.fromsafegraphqlimportclientsgql_client=client.HTTP_Client("MY_API_KEY")Use thesgql_clientobject to make requests!OutputsBy default, query functions in safegraphQL return pandas DataFrames. See thereturn_typeparameter below for how to return a JSON response object instead.lookup()One PlacekeyQuery all Core Places columns for a single Placekey.pk='zzw-222@8fy-fjg-b8v'# Disney Worldcore=sgql_client.lookup(product='core',placekeys=pk,columns='*')coreplacekeyparent_placekeylocation_namesafegraph_brand_idsbrandstop_categorysub_categorynaics_codelatitudelongitudestreet_addresscityregionpostal_codeiso_country_codephone_numberopen_hourscategory_tagsopened_onclosed_ontracking_closed_sincegeometry_type0222-223@65y-rxx-djv224-225@65y-rxx-dgkWalmart Supercenter['SG_BRAND_04a8ca7bf49e7ecb4a32451676e929f0'][{'brand_id': 'SG_BRAND_04a8ca7bf49e7ecb4a32451676e929f0', 'brand_name': 'Walmart Supercenter Canada'}]General Merchandise Stores, including Warehouse Clubs and SupercentersAll Other General Merchandise Stores45231942.6947-73.847141 Washington Avenue ExtAlbanyNY12205US{ "Mon": [["5:00", "23:00"]], "Tue": [["5:00", "23:00"]], "Wed": [["5:00", "23:00"]], "Thu": [["5:00", "23:00"]], "Fri": [["5:00", "23:00"]], "Sat": [["5:00", "23:00"]], "Sun": [["5:00", "23:00"]] }[]2019-07-01POLYGONYou can do the same for Geometry and Monthly Patterns.geo=sgql_client.lookup(product='geometry',placekeys=pk,columns='*')patterns=sgql_client.lookup(product='monthly_patterns',placekeys=pk,columns='*')Query the most recent Weekly Patterns datawatterns=sgql_client.lookup(product='weekly_patterns',placekeys=pk,columns='*')Query an arbitrary set of columns from a dataset.# requested columns must all come from the same datasetcols=['placekey','location_name','street_address','city','region','brands','top_category','sub_category','naics_code']sgql_client.lookup(product='core',placekeys=pk,columns=cols)placekeylocation_namebrandstop_categorysub_categorynaics_codestreet_addresscityregion0222-223@65y-rxx-djvWalmart Supercenter[{'brand_id': 'SG_BRAND_04a8ca7bf49e7ecb4a32451676e929f0', 'brand_name': 'Walmart Supercenter Canada'}]General Merchandise Stores, including Warehouse Clubs and SupercentersAll Other General Merchandise Stores452319141 Washington Avenue ExtAlbanyNYMultiple PlacekeysYou can perform any of the previous queries on a set of multiple Placekeys.pks=['zzw-222@8fy-fjg-b8v',# Disney World'zzw-222@5z6-3h9-tsq'# LAX]sgql_client.lookup(product='core',placekeys=pks,columns=cols)placekeylocation_namebrandstop_categorysub_categorynaics_codestreet_addresscityregion0zzw-222@5z6-3h9-tsqLos Angeles International Airport[]Support Activities for Air TransportationOther Airport Operations4881191 World WayEl SegundoCA1zzw-222@8fy-fjg-b8vWalt Disney World Resort[]Amusement Parks and ArcadesAmusement and Theme Parks713110Walt Disney World ResortOrlandoFLreturn_typeBy default, query functions in safegraphQL return pandas DataFrames. By settingreturn_type = 'list', you can return the JSON response object instead.# core columns onlysgql_client.lookup(product='core',placekeys=pk,columns='*',return_type='list')---[{'placekey':'zzw-222@8fy-fjg-b8v','parent_placekey':None,'location_name':'Walt Disney World Resort','safegraph_brand_ids':[],'brands':[],'top_category':'Amusement Parks and Arcades','sub_category':'Amusement and Theme Parks','naics_code':713110,'latitude':28.388228,'longitude':-81.567304,'street_address':'Walt Disney World Resort','city':'Orlando','region':'FL','postal_code':'32830','iso_country_code':'US','phone_number':None,'open_hours':'{ "Mon": [["8:00", "23:00"]], "Tue": [["8:00", "23:00"]], "Wed": [["8:00", "23:00"]], "Thu": [["8:00", "23:00"]], "Fri": [["8:00", "23:00"]], "Sat": [["8:00", "23:00"]], "Sun": [["8:00", "23:00"]] }','category_tags':[],'opened_on':None,'closed_on':None,'tracking_closed_since':'2019-07-01','geometry_type':'POLYGON'}]save()Export the most recently queried result. If the previous result had been a pandas DataFrame, the saved file will be a .csv. If the result had been the JSON response object, the saved file will be a .json. The default path for the exported file will beresults.{csv/json}.# saved file will be results.csvsgql_client.lookup(product='core',placekeys=pk,columns='*')sgql_client.save()# saved file will be results.jsonsgql_client.lookup(product='core',placekeys=pk,columns='*',return_type='list')sgql_client.save()# saved file will be safegraph_data.csvsgql_client.lookup(product='core',placekeys=pk,columns='*')sgql_client.save(path='safegraph_data.csv')sg_merge()Merge safegraphQL query results withsg_merge().core=sgql_client.lookup(product='core',placekeys=pks,columns=['placekey','location_name','naics_code','top_category','sub_category'])geo=sgql_client.lookup(product='geometry',placekeys=pks,columns=['placekey','polygon_class','enclosed'])merge_set=[core,geo]merged=sgql_client.sg_merge(datasets=merge_set)placekeylocation_nametop_categorysub_categorynaics_codepolygon_classenclosed0zzw-222@5z6-3h9-tsqLos Angeles International AirportSupport Activities for Air TransportationOther Airport Operations488119OWNED_POLYGONFalse1zzw-222@8fy-fjg-b8vWalt Disney World ResortAmusement Parks and ArcadesAmusement and Theme Parks713110OWNED_POLYGONFalse!! ADD SECTION ON INNER JOIN HERE ONCE ISSUE FOR NO LONGER SHOWING NULL PATTERNS ROWS HAS BEEN RESOLVED !!sg_merge()works for JSON response objects as well.core=sgql_client.lookup(product='core',placekeys=pks,columns=['placekey','location_name','naics_code','top_category','sub_category'],return_type='list')geo=sgql_client.lookup(product='geometry',placekeys=pks,columns=['placekey','polygon_class','enclosed'],return_type='list')merge_set=[core,geo]merged=sgql_client.sg_merge(datasets=merge_set)---[{'placekey':'zzw-222@5z6-3h9-tsq','location_name':'Los Angeles International Airport','top_category':'Support Activities for Air Transportation','sub_category':'Other Airport Operations','naics_code':488119,'polygon_class':'OWNED_POLYGON','enclosed':False},{'placekey':'zzw-222@8fy-fjg-b8v','location_name':'Walt Disney World Resort','top_category':'Amusement Parks and Arcades','sub_category':'Amusement and Theme Parks','naics_code':713110,'polygon_class':'OWNED_POLYGON','enclosed':False}]Historical Weekly PatternsUselookup()to query Weekly Patterns data for a Placekey from a particular date (YYYY-MM-DDformat).date='2019-06-15'sgql_client.lookup(product='weekly_patterns',placekeys=pk,date=date,columns=['placekey','location_name','date_range_start','date_range_end','raw_visit_counts'])placekeylocation_namedate_range_startdate_range_endraw_visit_counts0zzw-222@8fy-fjg-b8vWalt Disney World Resort2019-06-10T00:00:00-04:002019-06-17T00:00:00-04:00242530Pass a list of dates to query multiple Weekly Patterns releases. Note that if two dates fall within the same release (e.g.2019-06-15and2019-06-16below), the data for the relevant week will only be returned once.# notice the dates list contains 4 elements, but only 3 rows of data are returneddates=['2019-06-15','2019-06-16','2021-05-23','2018-10-23']sgql_client.lookup(product='weekly_patterns',placekeys=pk,date=dates,columns=['placekey','location_name','date_range_start','date_range_end','raw_visit_counts'])placekeylocation_namedate_range_startdate_range_endraw_visit_counts0zzw-222@8fy-fjg-b8vWalt Disney World Resort2018-10-22T00:00:00-04:002018-10-29T00:00:00-04:001698841zzw-222@8fy-fjg-b8vWalt Disney World Resort2019-06-10T00:00:00-04:002019-06-17T00:00:00-04:002425302zzw-222@8fy-fjg-b8vWalt Disney World Resort2021-05-17T00:00:00-04:002021-05-24T00:00:00-04:00323187Pass a Python dictionary withdate_range_startanddate_range_endkey/value pairs to query a range of Weekly Patterns releases.dates={'date_range_start':'2019-04-10','date_range_end':'2019-06-05'}sgql_client.lookup(product='weekly_patterns',placekeys=pk,date=dates,columns=['placekey','location_name','date_range_start','date_range_end','raw_visit_counts'])placekeylocation_namedate_range_startdate_range_endraw_visit_counts0zzw-222@8fy-fjg-b8vWalt Disney World Resort2019-04-15T00:00:00-04:002019-04-22T00:00:00-04:002495591zzw-222@8fy-fjg-b8vWalt Disney World Resort2019-04-22T00:00:00-04:002019-04-29T00:00:00-04:002489892zzw-222@8fy-fjg-b8vWalt Disney World Resort2019-04-29T00:00:00-04:002019-05-06T00:00:00-04:002638783zzw-222@8fy-fjg-b8vWalt Disney World Resort2019-05-06T00:00:00-04:002019-05-13T00:00:00-04:002478464zzw-222@8fy-fjg-b8vWalt Disney World Resort2019-05-13T00:00:00-04:002019-05-20T00:00:00-04:002239015zzw-222@8fy-fjg-b8vWalt Disney World Resort2019-05-20T00:00:00-04:002019-05-27T00:00:00-04:002127186zzw-222@8fy-fjg-b8vWalt Disney World Resort2019-05-27T00:00:00-04:002019-06-03T00:00:00-04:002366227zzw-222@8fy-fjg-b8vWalt Disney World Resort2019-06-03T00:00:00-04:002019-06-10T00:00:00-04:00239621And combine the results with Core Places and Geometry usingsg_merge().dates={'date_range_start':'2019-04-10','date_range_end':'2019-06-05'}watterns=sgql_client.lookup(product='weekly_patterns',placekeys=pk,date=dates,columns=['placekey','location_name','date_range_start','date_range_end','raw_visit_counts'])core=sgql_client.lookup(product='core',placekeys=pk,columns=['placekey','location_name','naics_code','top_category','sub_category'])geo=sgql_client.lookup(product='geometry',placekeys=pk,columns=['placekey','polygon_class','enclosed'])merged=sgql_client.sg_merge(datasets=[core,geo,watterns])placekeylocation_nametop_categorysub_categorynaics_codepolygon_classencloseddate_range_startdate_range_endraw_visit_counts0zzw-222@8fy-fjg-b8vWalt Disney World ResortAmusement Parks and ArcadesAmusement and Theme Parks713110OWNED_POLYGONFalse2019-04-15T00:00:00-04:002019-04-22T00:00:00-04:002495591zzw-222@8fy-fjg-b8vWalt Disney World ResortAmusement Parks and ArcadesAmusement and Theme Parks713110OWNED_POLYGONFalse2019-04-22T00:00:00-04:002019-04-29T00:00:00-04:002489892zzw-222@8fy-fjg-b8vWalt Disney World ResortAmusement Parks and ArcadesAmusement and Theme Parks713110OWNED_POLYGONFalse2019-04-29T00:00:00-04:002019-05-06T00:00:00-04:002638783zzw-222@8fy-fjg-b8vWalt Disney World ResortAmusement Parks and ArcadesAmusement and Theme Parks713110OWNED_POLYGONFalse2019-05-06T00:00:00-04:002019-05-13T00:00:00-04:002478464zzw-222@8fy-fjg-b8vWalt Disney World ResortAmusement Parks and ArcadesAmusement and Theme Parks713110OWNED_POLYGONFalse2019-05-13T00:00:00-04:002019-05-20T00:00:00-04:002239015zzw-222@8fy-fjg-b8vWalt Disney World ResortAmusement Parks and ArcadesAmusement and Theme Parks713110OWNED_POLYGONFalse2019-05-20T00:00:00-04:002019-05-27T00:00:00-04:002127186zzw-222@8fy-fjg-b8vWalt Disney World ResortAmusement Parks and ArcadesAmusement and Theme Parks713110OWNED_POLYGONFalse2019-05-27T00:00:00-04:002019-06-03T00:00:00-04:002366227zzw-222@8fy-fjg-b8vWalt Disney World ResortAmusement Parks and ArcadesAmusement and Theme Parks713110OWNED_POLYGONFalse2019-06-03T00:00:00-04:002019-06-10T00:00:00-04:00239621lookup_by_name()If you don't know a location's Placekey, you can look it up by name. Note that you should use this for looking up aparticularlocation, but if you are searching formore than onerelevant location, you should use thesearch()function described below.Note:When querying by location & address, it's necessary to have at least the following combination of fields to return a result:location_name + street_address + city + region + iso_country_code
location_name + street_address + postal_code + iso_country_code
location_name + latitude + longitude + iso_country_codelocation_name="Taco Bell"street_address="710 3rd St"city="San Francisco"region="CA"iso_country_code="US"sgql_client.lookup_by_name(product='core',location_name=location_name,street_address=street_address,city=city,region=region,iso_country_code=iso_country_code,columns=['placekey','location_name','street_address','city','region','postal_code','iso_country_code','latitude','longitude'])placekeylocation_namelatitudelongitudestreet_addresscityregionpostal_codeiso_country_code0224-222@5vg-7gv-d7qTaco Bell37.7786-122.393710 3rd StSan FranciscoCA94107USSearchYou can search for SafeGraph POI by a variety of attributes, as describedhere.Search by a single criterion, such as any convenience store POI in the SafeGraph dataset (naics_code == 445120). By default,search()returns only the first 20 results.naics_code=445120search_result=sgql_client.search(product='core',columns=['placekey','location_name','street_address','city','region','iso_country_code'],naics_code=naics_code)placekeylocation_namestreet_addresscityregioniso_country_code0zzw-223@646-9rk-nqzCash & Dash 7701 Highway 701 NLorisSCUS1222-222@63r-tqr-zj97-Eleven8708 Liberia AveManassasVAUS2zzy-222@4hf-pq3-w6kLondis18 & 22 & 26 Winster Mews,GamesleyDerbyshireGB3222-223@63v-c97-hnqCircle K1608 East AveAkronOHUS4zzw-222@8dj-n5s-2hq7-Eleven13150 S US Highway 41GibsontonFLUS5224-222@66b-2d2-rhqDepanneur 7 Jours6024 Avenue De DarlingtonMontrealQCCA6222-222@5pc-4d2-8n5Kwik Trip1549 Madison AveMankatoMNUS722c-222@5z5-3r9-8jv7-Eleven5000 Wilshire BlvdLos AngelesCAUS8223-223@5z5-qcd-wc57-Eleven6401 Mission Gorge RdSan DiegoCAUS9zzw-223@5r8-2cq-nbkCasey's General Stores2604 N Range Line RdJoplinMOUS10zzw-223@8gn-kc9-5mkCircle K101 N Gilmer AveLanettALUS11zzw-222@5q9-b99-vcqCircle K7530 Village Square DrCastle PinesCOUS12zzy-225@3x7-z8z-qj9Circle K100 Twelfth Avenue South WestSlave LakeABCA13223-223@8sx-zcv-grkCircle K901 Voss AveOdemTXUS14224-222@5wb-sdq-r8vCircle K5301 W Canal DrKennewickWAUS15zzw-226@64h-vj9-mrk21st Street Deli222 W 21st St Ste JNorfolkVAUS1622k-222@627-wdk-z9fVictory Meat Center8506 Bay PkwyBrooklynNYUS17zzy-222@5pm-6rj-4n5Quick Mart129 E Hill StWaynesboroTNUS18224-222@3wz-4kr-rc57-Eleven1704 61st Street South EastCalgaryABCA19223-222@5pb-b7m-5s5Casey's General Stores907 13th St NHumboldtIAUSSearch by multiple criteria, such as Sheetz locations in Pennsylvania.brand='Sheetz'region='PA'search_result=sgql_client.search(product='core',columns=['placekey','location_name','street_address','city','region','iso_country_code'],brand=brand,region=region)search_result.head()placekeylocation_namestreet_addresscityregioniso_country_code0225-222@63p-wtm-8qfSheetz24578 Route 35 NMifflintownPAUS1224-222@63p-d8d-dgkSheetz330 Westminster DrKenmarPAUS2223-222@63s-x95-c89Sheetz420 N Baltimore AveMount Holly SpringsPAUS3223-222@63d-3y3-3wkSheetz4701 William Penn HwyMurrysvillePAUS4227-222@63p-tv5-brkSheetz8711 Woodbury PikeEast FreedomPAUSsearch()works for Geometry, Monthly Patterns, and Weekly Patterns as well.brand='Sheetz'region='PA'date='2021-07-04'search_result=sgql_client.search(product='weekly_patterns',columns=['placekey','location_name','raw_visit_counts'],date=date,brand=brand,region=region)placekeylocation_nameraw_visit_counts0225-222@63p-wtm-8qfSheetz3381224-222@63p-d8d-dgkSheetz6192223-222@63s-x95-c89Sheetz2413223-222@63d-3y3-3wkSheetz7054227-222@63p-tv5-brkSheetz564Change themax_resultsparameter to request more than the default 20 results.brand='Sheetz'region='PA'max_results=200search_result=sgql_client.search(product='core',columns=['placekey','location_name','street_address','city','region','iso_country_code'],brand=brand,region=region,max_results=max_results)placekeylocation_namestreet_addresscityregioniso_country_code0225-222@63p-wtm-8qfSheetz24578 Route 35 NMifflintownPAUS1222-222@63p-bjm-xnqSheetz270 Route 61 SSchuylkill HavenPAUS2228-222@63t-p3s-zzzSheetz107 Franklin StSlippery RockPAUS3zzw-222@63s-xr7-49zSheetz6054 Carlisle PikeMechanicsburgPAUS4zzw-222@63s-9nq-9zzSheetz3200 Cape Horn RdRed LionPAUS...195zzw-222@63n-xgm-zpvSheetz7775 N Route 220 HwyLindenPAUS196222-222@63s-xgf-cyvSheetz5201 Simpson Ferry RdMechanicsburgPAUS197222-222@63p-8qd-fcqSheetz1550 State RdDuncannonPAUS198226-222@63s-xqc-ty9Sheetz1720 Harrisburg PikeCarlislePAUS199227-222@63d-77y-dgkSheetz1297 Washington PikeBridgevillePAUSChange theafter_result_numberparameter if you want to skip the first few results. For example, maybe you already searched for the first 2 Sheetz results in PA, and you're interested in the results after that.brand='Sheetz'region='PA'max_results=200after_result_number=2search_result=sgql_client.search(product='core',columns=['placekey','location_name','street_address','city','region','iso_country_code'],brand=brand,region=region,max_results=max_results,after_result_number=after_result_number)