Quick reference for creating Terraform data sources with pyvider. For a step-by-step tutorial, see Building Your First Data Source.
🤖 AI-Generated Content
This documentation was generated with AI assistance and is still being audited. Some, or potentially a lot, of this information may be inaccurate. Learn more.
asyncdefread(self,config:Config)->Data:result=awaitapi.query(config.id)ifnotresult:# Return empty data instead of raising errorreturnData(id=config.id,found=False,value=None,)returnData(id=result["id"],found=True,value=result["value"],)
asyncdefread(self,config:Config)->Data:# Good: Same inputs = same IDquery_id=f"{config.region}:{config.type}:{config.name}"results=awaitquery(config)returnData(id=query_id,# Deterministicresults=results,)
fromfunctoolsimportlru_cacheimporthashlibclassAPIQuery(BaseDataSource):@lru_cache(maxsize=128)asyncdef_cached_query(self,cache_key:str,endpoint:str)->dict:"""Cached API query."""asyncwithhttpx.AsyncClient()asclient:response=awaitclient.get(endpoint)returnresponse.json()asyncdefread(self,config:Config)->Data:# Generate cache key from configcache_key=hashlib.md5(f"{config.endpoint}:{config.filter}".encode()).hexdigest()result=awaitself._cached_query(cache_key,config.endpoint)returnData(id=cache_key,results=result["items"],)
# Good: Deterministicasyncdefread(self,config:Config)->Data:returnawaitapi.query(config.filter)# Same filter = same result# Bad: Non-deterministicasyncdefread(self,config:Config)->Data:returnData(id=str(uuid.uuid4()))# Different ID each time!
# Good@attrs.defineclassQueryData:id:strresults:list[str]count:intasyncdefread(self,config:Config)->QueryData:# Type safe...# Badasyncdefread(self,config:Config)->dict:# No type safetyreturn{"id":"123","results":[...]}
importpytestfrommy_provider.data_sources.api_queryimportAPIQuery,APIQueryConfig@pytest.mark.asyncioasyncdeftest_api_query():ds=APIQuery()config=APIQueryConfig(endpoint="/users",limit=5)data=awaitds.read(config)assertdata.count<=5assertlen(data.results)==data.countassertdata.id# Has stable ID@pytest.mark.asyncioasyncdeftest_api_query_error_handling():ds=APIQuery()config=APIQueryConfig(endpoint="/invalid")data=awaitds.read(config)# Should return data, not raiseassertdata.errorisnotNoneassertdata.results==[]