cold-soccer-63228
05/18/2022, 2:37 PMpath/to/service/graphql/BUILD
files, where *.graphql
files are siblings in the directories by subclassing PutativeTargetsRequest
.
resources(
name="graphql_schema",
sources=[
"*.graphql",
],
)
I'm interested in making it so that Python sources that invoke ariadne.load_schema_by_path
have dependencies on all GraphQL resources in my codebase, e.g. the targets specified in each path/to/service/graphql/BUILD
file. (This is necessary because the ariadne.load_schema_by_path
function opens GraphQL file paths.)
I think the BUILD
file I want to generate should look something like the following:
python_sources(
dependencies=[
"path/to/service_a/graphql:graphql_schema",
"path/to/service_b/graphql:graphql_schema",
"path/to/service_c/graphql:graphql_schema",
...
]
)
I see that infer_python_dependencies_via_source is a rule that already exists in the Python backend. I was wondering if I could leverage this.
To solve my problem, would it be valid to create an additional rule, e.g. infer_python_graphql_dependencies
that awaits Get(InferredDependencies, ...)
, and then looks through the dependencies, and adds dependencies on all "path/to/service/graphql:graphql_schema"
targets whenever an ariadne
dependency is found?
So far, I have the following (not working) code that I'm trying to play with.
class InferPythonGraphQLResourceDependenciesRequest(InferDependenciesRequest):
infer_from = PythonSourceField
@rule(desc="Inferring Python GraphQL dependencies by analyzing source")
async def infer_python_graphql_dependencies(
request: InferPythonGraphQLResourceDependenciesRequest,
python_infer_subsystem: PythonInferSubsystem,
python_setup: PythonSetup,
) -> InferredDependencies:
if not python_infer_subsystem.imports and not python_infer_subsystem.assets:
return InferredDependencies([])
_wrapped_tgt = await Get(WrappedTarget, Address, request.sources_field.address)
tgt = _wrapped_tgt.target
return await Get(InferredDependencies, DependenciesRequest(tgt[Dependencies]))
def rules() -> Iterable[Rule]:
return [
infer_python_graphql_dependencies,
UnionRule(InferDependenciesRequest, InferPythonGraphQLResourceDependenciesRequest),
]
The issue with this code are errors that look like the following:
No installed rules return the type InferConftestDependencies
No installed rules return the type InferInitDependencies
No installed rules return the type InferPythonGraphQLResourceDependenciesRequest
Do I perhaps I need to re-register rules the rules()
function defined in my dependency inference declarations?bitter-ability-32190
05/18/2022, 2:59 PMDo I perhaps I need to re-register rules theMake sure yourfunction defined in my dependency inference declarations?rules()
register
has a rules()
which returns these rulesbitter-ability-32190
05/18/2022, 3:03 PMI'm interested in making it so that Python sources that invokeOnce you get the rule running, what you want should be easy. • Take thehave dependencies on all GraphQL resources in my codebaseariadne.load_schema_by_path
python_source
you're given, ask for the contents, parse it for the ast.Call
you're looking for.
• Have your Rule also take in AllAssetTargetsByPath , and filter to only those with .graphql
paths
• If the python source has the right call, return an object with the resource targets for graphQL resourcescold-soccer-63228
05/18/2022, 3:13 PMHave your Rule also take in AllAssetTargetsByPath , and filter to only those withWould this be an additional parameter in the the function signature? Or perhaps do I make my request subclass bothpaths.graphql
InferDependenciesRequest
and AllAssetTargetsRequest
? Or perhaps something else?bitter-ability-32190
05/18/2022, 3:15 PMawait Get(...)
to have the engine take your request and run the right code (or grab form the cache) the result.
In a few cases though there ARE no inputs (or more accurately the request object is just dataless).
AllAssetTargetsByPath
is one of those. In that case you can just declare it as an argument and the engine will provide itcold-soccer-63228
05/18/2022, 3:23 PMNo installed rules return the type AllAssetTargetsRequest, and it was not provided by potential callers of @rule(pants.core.target_types:326:find_all_assets(AllTargets, AllAssetTargetsRequest) -> AllAssetTargets).
If that type should be computed by a rule, ensure that that rule is installed.
If it should be provided by a caller, ensure that it is included in any relevant Query or Get.
It seems like doing the await Get(...)
worked though? But I'm not sure if my dependency inference is getting triggered. I'm using the following code the test.
async def infer_python_graphql_dependencies(request: ...) -> InferredDependencies:
all_asset_targets = await Get(AllAssetTargets, AllAssetTargetsRequest())
assets_by_path = await Get(AllAssetTargetsByPath, AllAssetTargets, all_asset_targets)
print("HUGH-TEST")
print(request.sources_field)
return InferredDependencies([])
I'm noticing that "HUGH-TEST"
never gets printed?bitter-ability-32190
05/18/2022, 3:23 PMcold-soccer-63228
05/18/2022, 3:23 PMbitter-ability-32190
05/18/2022, 3:23 PMlogging.getLogger(__name__)
)bitter-ability-32190
05/18/2022, 3:23 PM.error(...)
thats what I do 😛bitter-ability-32190
05/18/2022, 3:24 PMMake sure your argument type isCopy codeNo installed rules return the type AllAssetTargetsRequest
AllAssetTargetsByPath
. Seems like your type was the XRequest
type?cold-soccer-63228
05/18/2022, 3:40 PMMake sure your argument type isYup, this function signature triggers that above error.. Seems like your type was theAllAssetTargetsByPath
type?XRequest
async def infer_python_graphql_dependencies(
request: InferPythonGraphQLResourceDependenciesRequest, _: AllAssetTargetsByPath
) -> InferredDependencies:
...
bitter-ability-32190
05/18/2022, 3:41 PMbitter-ability-32190
05/18/2022, 3:46 PMAllAssetTargetsRequest
it might work? But I'm not sure 😅 .
Making the await Get
isn't wrong so 🤷♂️cold-soccer-63228
05/18/2022, 4:37 PMariadne
import, can I piggy-back off of the Python dependency inference script somehow?bitter-ability-32190
05/18/2022, 4:37 PMbitter-ability-32190
05/18/2022, 4:39 PMParsePythonDependenciesRequest
? Suggest using the same values as in src/python/pants/backend/python/dependency_inference/rules.py
so you get cached resultsbitter-ability-32190
05/18/2022, 4:40 PMInferPythonImportDependencies
instance to get the InferredDependencies
for your source 🙈bitter-ability-32190
05/18/2022, 4:40 PMcold-soccer-63228
05/18/2022, 4:59 PMBUILD
file, right? But it would implicitly make it so that targets depend on some other targets?bitter-ability-32190
05/18/2022, 5:00 PMbitter-ability-32190
05/18/2022, 5:00 PM./pants dependencies path/to/file.py
cold-soccer-63228
05/18/2022, 5:05 PMtarget_name
of my ariadne
address is just showing up as "requirements"
since it's a third party dependency. "requirements#ariadne"
?Address.spec
cold-soccer-63228
05/18/2022, 5:29 PM./pants dependencies ...
is showing the GraphQL resources now properly inferred, whenever we import ariadne
🙂
I know we briefly touch upon this earlier with @hundreds-father-404, but do you think it'd be worthwhile to put up a dummy merge request with the code that I wrote? This may end up being useful for other engineers that use GraphQL with the ariadne
package. It's very barebones, but it could be a starting point if we ever wanted to build a ariadne
or graphql
backendcold-soccer-63228
05/19/2022, 1:48 AMbitter-ability-32190
05/19/2022, 8:40 AMbitter-ability-32190
05/19/2022, 1:20 PMcold-soccer-63228
05/19/2022, 2:26 PMhundreds-father-404
05/19/2022, 2:49 PMcold-soccer-63228
05/19/2022, 6:22 PMariadne
directory. Please lemme know if y'all have any suggestions or anything. I'm thinking of adding tests to this repository, and then publishing this barebones plugin as a PyPI package, since the ariadne
plugin name conflicts with our ariadne
third-party package name in our production codebase 😕