diff --git a/.gitignore b/.gitignore index b55dbcf0e38887f7d1621023301e0ec0e91fc116..22992efc664d9e6281434e7c3ef85fb5c79eef2e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *~ *__pycache__* +.vscode diff --git a/mc_openapi/assets/__init__.py b/mc_openapi/assets/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/mc_openapi/assets/doml.ecore b/mc_openapi/assets/doml.ecore new file mode 100644 index 0000000000000000000000000000000000000000..e8cc0d6e555f08f8fcf9b10522f40ffaecbcca7d --- /dev/null +++ b/mc_openapi/assets/doml.ecore @@ -0,0 +1,349 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="doml" nsURI="http://www.piacere-project.eu/doml" nsPrefix="doml"> + <eAnnotations source="emf.gen"> + <details key="basePackage" value="eu.piacere.doml"/> + <details key="fileExtensions" value="domlx"/> + <details key="complianceLevel" value="JDK80"/> + </eAnnotations> + <eSubpackages name="commons" nsURI="http://www.piacere-project.eu/doml/commons" + nsPrefix="commons"> + <eClassifiers xsi:type="ecore:EClass" name="DOMLModel" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="application" eType="#//application/ApplicationLayer" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="infrastructure" eType="#//infrastructure/InfrastructureLayer" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="concretizations" upperBound="-1" + eType="#//concrete/ConcreteInfrastructure" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="optimization" eType="#//optimization/OptimizationLayer" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="configurations" upperBound="-1" + eType="#//commons/Configuration" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="activeConfiguration" + eType="#//commons/Configuration"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="activeInfrastructure" + eType="#//concrete/ConcreteInfrastructure"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="functionalRequirements" + upperBound="-1" eType="#//commons/Requirement" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="key" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="type" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="reference" eType="#//commons/DOMLElement"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtensionElement" abstract="true"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="metaclassName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DOMLElement" abstract="true"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="annotations" upperBound="-1" + eType="#//commons/Property" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="contributesTo" upperBound="-1" + eType="#//commons/Requirement" eOpposite="#//commons/Requirement/predicatesOn"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Configuration" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="deployments" upperBound="-1" + eType="#//commons/Deployment" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Deployment"> + <eStructuralFeatures xsi:type="ecore:EReference" name="component" lowerBound="1" + eType="#//application/ApplicationComponent"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="node" lowerBound="1" + eType="#//infrastructure/InfrastructureElement"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Requirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="identifier" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="predicatesOn" upperBound="-1" + eType="#//commons/DOMLElement" eOpposite="#//commons/DOMLElement/contributesTo"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="RangedRequirement" eSuperTypes="#//commons/Requirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="EnumeratedRequirement" eSuperTypes="#//commons/Requirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="values" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentRequirement" abstract="true" + eSuperTypes="#//commons/Requirement"/> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentToNodeTypeRequirement" eSuperTypes="#//commons/DeploymentRequirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="validTypes" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentToNodeWithPropertyRequirement" + eSuperTypes="#//commons/DeploymentRequirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="values" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentToSpecificNodeRequirement" + eSuperTypes="#//commons/DeploymentRequirement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="validElements" upperBound="-1" + eType="#//infrastructure/InfrastructureElement"/> + </eClassifiers> + </eSubpackages> + <eSubpackages name="application" nsURI="http://www.piacere-project.eu/doml/application" + nsPrefix="app"> + <eClassifiers xsi:type="ecore:EClass" name="ApplicationLayer" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="components" upperBound="-1" + eType="#//application/ApplicationComponent" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ApplicationComponent" abstract="true" + eSuperTypes="#//commons/DOMLElement"/> + <eClassifiers xsi:type="ecore:EClass" name="SoftwareComponent" eSuperTypes="#//application/ApplicationComponent"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="isPersistent" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject" + defaultValueLiteral="false"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="licenseCost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="configFile" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="exposedInterfaces" upperBound="-1" + eType="#//application/SoftwareInterface" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="consumedInterfaces" upperBound="-1" + eType="#//application/SoftwareInterface"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DBMS" eSuperTypes="#//application/SoftwareComponent"/> + <eClassifiers xsi:type="ecore:EClass" name="SaaS" eSuperTypes="#//application/ApplicationComponent"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="licenseCost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="exposedInterfaces" upperBound="-1" + eType="#//application/SoftwareInterface" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SaaSDBMS" eSuperTypes="#//application/SaaS"/> + <eClassifiers xsi:type="ecore:EClass" name="SoftwareInterface" eSuperTypes="#//application/ApplicationComponent"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="endPoint" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtApplicationComponent" eSuperTypes="#//application/ApplicationComponent #//commons/ExtensionElement"/> + </eSubpackages> + <eSubpackages name="infrastructure" nsURI="http://www.piacere-project.eu/doml/infrastructure" + nsPrefix="infra"> + <eClassifiers xsi:type="ecore:EClass" name="InfrastructureLayer" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1" + eType="#//infrastructure/ComputingNode" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1" + eType="#//infrastructure/VPC" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="secGroups" upperBound="-1" + eType="#//infrastructure/SecurityGroup" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="generators" upperBound="-1" + eType="#//infrastructure/ComputingNodeGenerator" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1" + eType="#//infrastructure/Storage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="faas" upperBound="-1" + eType="#//infrastructure/FunctionAsAService" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" upperBound="-1" + eType="#//infrastructure/Credentials" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ComputingGroup" abstract="true" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="groupedNodes" upperBound="-1" + eType="#//infrastructure/ComputingNode" eOpposite="#//infrastructure/ComputingNode/group"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="AutoScalingGroup" eSuperTypes="#//infrastructure/ComputingNode"> + <eStructuralFeatures xsi:type="ecore:EReference" name="machineDefinition" lowerBound="1" + eType="#//infrastructure/VirtualMachine" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject" + defaultValueLiteral="1"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject" + defaultValueLiteral="1"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="deploymentNetwork" eType="#//infrastructure/Network"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="securityGroup" eType="#//infrastructure/SecurityGroup" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="loadBalancer" eType="#//infrastructure/LoadBalancerKind" + defaultValueLiteral="DEFAULT"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="LoadBalancerKind"> + <eLiterals name="DEFAULT"/> + <eLiterals name="INTERNAL" value="1"/> + <eLiterals name="EXTERNAL" value="2"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Rule" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/RuleKind"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="fromPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="toPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="addressRanges" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="RuleKind"> + <eLiterals name="EGRESS"/> + <eLiterals name="INGRESS" value="1"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SecurityGroup" eSuperTypes="#//infrastructure/ComputingGroup"> + <eStructuralFeatures xsi:type="ecore:EReference" name="rules" upperBound="-1" + eType="#//infrastructure/Rule" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/associated"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="AvailabilityGroup" eSuperTypes="#//infrastructure/ComputingGroup"/> + <eClassifiers xsi:type="ecore:EClass" name="InfrastructureElement" abstract="true" + eSuperTypes="#//commons/DOMLElement"/> + <eClassifiers xsi:type="ecore:EClass" name="ComputingNode" abstract="true" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="architecture" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="os" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="memory" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="storage" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cpu" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="location" eType="#//infrastructure/Location" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" eType="#//infrastructure/Credentials"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="group" eType="#//infrastructure/ComputingGroup" + eOpposite="#//infrastructure/ComputingGroup/groupedNodes"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ComputingNodeGenerator" abstract="true" + eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="uri" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/GeneratorKind"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="GeneratorKind"> + <eLiterals name="SCRIPT"/> + <eLiterals name="IMAGE" value="1"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="VMImage" eSuperTypes="#//infrastructure/ComputingNodeGenerator"> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedVMs" upperBound="-1" + eType="#//infrastructure/VirtualMachine" eOpposite="#//infrastructure/VirtualMachine/generatedFrom"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ContainerImage" eSuperTypes="#//infrastructure/ComputingNodeGenerator"> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedContainers" + upperBound="-1" eType="#//infrastructure/Container" eOpposite="#//infrastructure/Container/generatedFrom"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="PhysicalComputingNode" eSuperTypes="#//infrastructure/ComputingNode"/> + <eClassifiers xsi:type="ecore:EClass" name="VirtualMachine" eSuperTypes="#//infrastructure/ComputingNode"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="sizeDescription" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/VMImage" + eOpposite="#//infrastructure/VMImage/generatedVMs"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Location" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="region" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="zone" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Container" eSuperTypes="#//infrastructure/ComputingNode"> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/ContainerImage" + eOpposite="#//infrastructure/ContainerImage/generatedContainers"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="host" eType="#//infrastructure/ComputingNode"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Network" abstract="true" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="addressRange" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="connectedIfaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/belongsTo"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="igws" upperBound="-1" + eType="#//infrastructure/InternetGateway" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="VPC" eSuperTypes="#//infrastructure/Network"> + <eStructuralFeatures xsi:type="ecore:EReference" name="subnets" upperBound="-1" + eType="#//infrastructure/Subnet" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Subnet" eSuperTypes="#//infrastructure/Network"> + <eStructuralFeatures xsi:type="ecore:EReference" name="connectedTo" upperBound="-1" + eType="#//infrastructure/Subnet"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="NetworkInterface" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="speed" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="endPoint" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="belongsTo" eType="#//infrastructure/Network" + eOpposite="#//infrastructure/Network/connectedIfaces"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="associated" eType="#//infrastructure/SecurityGroup" + eOpposite="#//infrastructure/SecurityGroup/ifaces"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="InternetGateway" eSuperTypes="#//infrastructure/NetworkInterface"/> + <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="storage" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="FunctionAsAService" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Credentials" abstract="true" eSuperTypes="#//commons/DOMLElement"/> + <eClassifiers xsi:type="ecore:EClass" name="KeyPair" eSuperTypes="#//infrastructure/Credentials"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="algorithm" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="bits" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="UserPass" eSuperTypes="#//infrastructure/Credentials"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="username" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="password" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtInfrastructureElement" eSuperTypes="#//infrastructure/InfrastructureElement #//commons/ExtensionElement"/> + </eSubpackages> + <eSubpackages name="concrete" nsURI="http://www.piacere-project.eu/doml/concrete" + nsPrefix="concrete"> + <eClassifiers xsi:type="ecore:EClass" name="ConcreteInfrastructure" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="providers" upperBound="-1" + eType="#//concrete/RuntimeProvider" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="RuntimeProvider" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="vms" upperBound="-1" + eType="#//concrete/VirtualMachine" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="vmImages" upperBound="-1" + eType="#//concrete/VMImage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerImages" upperBound="-1" + eType="#//concrete/ContainerImage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1" + eType="#//concrete/Network" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1" + eType="#//concrete/Storage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="faas" upperBound="-1" + eType="#//concrete/FunctionAsAService" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="group" upperBound="-1" + eType="#//concrete/ComputingGroup" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ConcreteElement" abstract="true" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="configurationScript" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="VirtualMachine" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/VirtualMachine"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="VMImage" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/VMImage"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ContainerImage" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/ContainerImage"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Network" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/Network"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/Storage"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="FunctionAsAService" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/FunctionAsAService"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ComputingGroup" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/ComputingGroup"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtConcreteElement" eSuperTypes="#//concrete/ConcreteElement #//commons/ExtensionElement"/> + </eSubpackages> + <eSubpackages name="optimization" nsURI="http://www.piacere-project.eu/doml/optimization" + nsPrefix="optimization"> + <eClassifiers xsi:type="ecore:EClass" name="OptimizationLayer" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="startingHint" eType="#//commons/Configuration"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="solutions" upperBound="-1" + eType="#//optimization/OptimizationSolution" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="objectives" upperBound="-1" + eType="#//optimization/OptimizationObjective" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="nonfunctionalRequirements" + upperBound="-1" eType="#//commons/Requirement" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="OptimizationSolution" eSuperTypes="#//commons/Configuration"/> + <eClassifiers xsi:type="ecore:EClass" name="OptimizationObjective" abstract="true" + eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" + defaultValueLiteral="Max"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="CountObjective" eSuperTypes="#//optimization/OptimizationObjective"/> + <eClassifiers xsi:type="ecore:EClass" name="MeasurableObjective" eSuperTypes="#//optimization/OptimizationObjective"/> + <eClassifiers xsi:type="ecore:EClass" name="ExtOptimizationObjective" eSuperTypes="#//optimization/OptimizationObjective #//commons/ExtensionElement"/> + </eSubpackages> +</ecore:EPackage> diff --git a/mc_openapi/assets/doml_meta.yaml b/mc_openapi/assets/doml_meta.yaml new file mode 100644 index 0000000000000000000000000000000000000000..111096e50e9741d8e37f292a4edfa17069b8b9b9 --- /dev/null +++ b/mc_openapi/assets/doml_meta.yaml @@ -0,0 +1,334 @@ +commons: + DOMLElement: + attributes: + name: + type: String + multiplicity: "1" + description: + type: String + multiplicity: "0..1" + Configuration: + superclass: commons_DOMLElement + associations: + deployments: + class: commons_Deployment + multiplicity: "0..*" + Deployment: + associations: + source: + class: application_ApplicationComponent + multiplicity: "1" + target: + class: infrastructure_InfrastructureElement + multiplicity: "1" + +application: + ApplicationLayer: + superclass: commons_DOMLElement + associations: + components: + class: application_ApplicationComponent + multiplicity: "0..*" + ApplicationComponent: + superclass: commons_DOMLElement + SoftwareComponent: + superclass: application_ApplicationComponent + attributes: + isPersistent: + type: Boolean + multiplicity: "1" + default: false + associations: + exposedInterfaces: + class: application_SoftwareInterface + mutiplicity: "0..*" + consumedInterfaces: + class: application_SoftwareInterface + mutiplicity: "0..*" + SaaS: + superclass: application_ApplicationComponent + associations: + exposedInterfaces: + class: application_SoftwareInterface + mutiplicity: "0..*" + SoftwareInterface: + superclass: application_ApplicationComponent + attributes: + endPoint: + type: String + multiplicity: "1" + DBMS: + superclass: application_SoftwarePackage + SaaSDBMS: + superclass: application_SaaS + +infrastructure: + InfrastructureLayer: + superclass: commons_DOMLElement + associations: + nodes: + class: infrastructure_ComputingNode + multiplicity: "0..*" + generators: + class: infrastructure_ComputingNodeGenerator + multiplicity: "0..*" + asGroups: + class: infrastructure_AutoScalingGroup + multiplicity: "0..*" + networks: + class: infrastructure_Network + multiplicity: "0..*" + firewalls: + class: infrastructure_Firewall + multiplicity: "0..*" + storages: + class: infrastructure_Storage + multiplicity: "0..*" + faas: + class: infrastructure_FunctionAsAService + multiplicity: "0..*" + InfrastructureElement: + superclass: commons_DOMLElement + ComputingNode: + superclass: infrastructure_InfrastructureElement + attributes: + architecture: + type: String + multiplicity: "0..1" + os: + type: String + multiplicity: "0..1" + memory: + type: String + multiplicity: "0..1" + storage: + type: String + multiplicity: "0..1" + cpu: + type: String + multiplicity: "0..1" + cost: + type: Integer # in cents + multiplicity: "0..1" + associations: + group: + class: infrastructure_AutoScalingGroup + multiplicity: "0..1" + ifaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + location: + class: infrastructure_Location + multiplicity: "0..1" + PhysicalComputingNode: + superclass: infrastructure_ComputingNode + VirtualMachine: + superclass: infrastructure_ComputingNode + attributes: + sizeDescription: + type: String + multiplicity: "0..1" + associations: + generatedFrom: + class: infrastructure_VMImage + multiplicity: "0..1" + location: + class: infrastructure_Location + multiplicity: "0..1" + Location: + superclass: commons_DOMLElement + attributes: + region: + type: String + multiplicity: "1" + zone: + type: String + multiplicity: "0..1" + Container: + superclass: infrastructure_ComputingNode + associations: + generatedFrom: + class: infrastructure_ContainerImage + multiplicity: "0..1" + host: + class: infrastructure_ComputingNode + multiplicity: "1" + ComputingNodeGenerator: + superclass: commons_DOMLElement + attributes: + uri: + type: String + multiplicity: "0..1" + kind: + type: GeneratorKind # enum { SCRIPT, IMAGE } + VMImage: + superclass: infrastructure_ComputingNodeGenerator + associations: + generatedVMs: + class: infrastructure_VirtualMachine + multiplicity: "0..*" + inverse_of: infrastructure_VirtualMachine::generatedFrom + ContainerImage: + superclass: infrastructure_ComputingNodeGenerator + associations: + generatedContainers: + class: infrastructure_Container + multiplicity: "0..*" + inverse_of: infrastructure_Container::generatedFrom + AutoScalingGroup: + superclass: commons_DOMLElement + associations: + # runtimeProvider + groupedNodes: + class: infrastructure_ComputingNode + multiplicity: "0..*" + inverse_of: infrastructure_ComputingNode::group + SecurityGroup: + superclass: commons_DOMLElement + associations: + # runtimeProvider + groupedNodes: + class: infrastructure_ComputingNode + multiplicity: "0..*" + inverse_of: infrastructure_ComputingNode::group + Storage: + superclass: infrastructure_InfrastructureElement + attributes: + storage: + type: Integer # in MBs + multiplicity: "0..1" + cost: + type: Integer # in cents + multiplicity: "0..1" + associations: + ifaces: + class: infrastructure_NetworkInterface + multiplicity: "0..1" + FunctionAsAService: + superclass: infrastructure_InfrastructureElement + attributes: + cost: + type: Integer # in cents + multiplicity: "0..1" + associations: + ifaces: + class: infrastructure_NetworkInterface + multiplicity: "0..1" + Network: + superclass: commons_DOMLElement + attributes: + protocol: + type: String + multiplicity: "0..1" + address_lb: + type: Integer + multiplicity: "0..1" + address_ub: + type: Integer + multiplicity: "0..1" + associations: + connectedIfaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + inverse_of: infrastructure_NetworkInterface::belongsTo + subnets: + class: infrastructure_Subnet + multiplicity: "0..*" + Subnet: + superclass: infrastructure_Network + NetworkInterface: + superclass: infrastructure_InfrastructureElement + attributes: + endPoint: + type: Integer + multiplicity: "0..1" + speed: + type: String + multiplicity: "0..1" + associations: + belongsTo: + class: infrastructure_Network + multiplicity: "1" + Firewall: + superclass: infrastructure_DOMLElement + associations: + ifaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + +concrete: + ConcreteInfrastructure: + superclass: commons_DOMLElement + associations: + providers: + class: concrete_RuntimeProvider + multiplicity: "0..*" + nodes: + class: concrete_VirtualMachine + multiplicity: "0..*" + asGroups: + class: concrete_AutoScalingGroup + multiplicity: "0..*" + networks: + class: concrete_Network + multiplicity: "0..*" + storages: + class: concrete_Storage + multiplicity: "0..*" + faas: + class: concrete_FunctionAsAService + multiplicity: "0..*" + ConcreteElement: + superclass: commons_DOMLElement + attributes: + configurationScript: + type: String + multiplicity: "0..1" + RuntimeProvider: + superclass: commons_DOMLElement + associations: + supportedGroups: + class: concrete_AutoScalingGroup + multiplicity: "0..*" + vms: + class: concrete_VirtualMachine + multiplicity: "0..*" + networks: + class: concrete_Network + multiplicity: "0..*" + storages: + class: concrete_Storage + multiplicity: "0..*" + faas: + class: concrete_FunctionAsAService + multiplicity: "0..*" + VirtualMachine: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_VirtualMachine + multiplicity: "1" + Network: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_Network + multiplicity: "1" + Storage: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_Storage + multiplicity: "1" + FunctionAsAService: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_FunctionAsAService + multiplicity: "1" + AutoScalingGroup: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_AutoScalingGroup + multiplicity: "1" \ No newline at end of file diff --git a/mc_openapi/string_uri.py b/mc_openapi/bytes_uri.py similarity index 61% rename from mc_openapi/string_uri.py rename to mc_openapi/bytes_uri.py index c8d0e92742f90213ab32f6e3bd1d4bce9c54c08b..b6b3cbb2e97c4499aa544b00777f127455b536f4 100644 --- a/mc_openapi/string_uri.py +++ b/mc_openapi/bytes_uri.py @@ -1,11 +1,11 @@ from pyecore.resources import URI from io import BytesIO -class StringURI(URI): - def __init__(self, uri, text=None): - super(StringURI, self).__init__(uri) - if text is not None: - self.__stream = BytesIO(text) +class BytesURI(URI): + def __init__(self, uri, bytes=None): + super(BytesURI, self).__init__(uri) + if bytes is not None: + self.__stream = BytesIO(bytes) def getvalue(self): return self.__stream.getvalue() diff --git a/mc_openapi/doml_mc/__init__.py b/mc_openapi/doml_mc/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..49ecc4d3eea9c907a11df234f7725ee65dad74f2 --- /dev/null +++ b/mc_openapi/doml_mc/__init__.py @@ -0,0 +1,4 @@ +from .mc import SMTEncoding, ModelChecker # noqa: F401 + +# Load metamodel +ModelChecker.init_metamodel() diff --git a/mc_openapi/doml_mc/_utils.py b/mc_openapi/doml_mc/_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..458c453bc55b6d4975d1cb4c61bd836f206177f6 --- /dev/null +++ b/mc_openapi/doml_mc/_utils.py @@ -0,0 +1,10 @@ +from typing import TypeVar +from collections.abc import Iterable + + +_K = TypeVar("_K") +_V = TypeVar("_V") + + +def merge_dicts(it: Iterable[dict[_K, _V]]) -> dict[_K, _V]: + return dict(kv for d in it for kv in d.items()) diff --git a/mc_openapi/doml_mc/example.ipynb b/mc_openapi/doml_mc/example.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..b025bd121a6a206fd63a84bcc9db382a0ff2d524 --- /dev/null +++ b/mc_openapi/doml_mc/example.ipynb @@ -0,0 +1,706 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from mc_openapi.doml_mc.intermediate_model.metamodel import parse_metamodel, parse_inverse_associations\n", + "import yaml\n", + "with open(\"../assets/doml_meta.yaml\") as mmf:\n", + " mmdoc = yaml.load(mmf, yaml.Loader)\n", + "mm = parse_metamodel(mmdoc)\n", + "inv_assoc = parse_inverse_associations(mmdoc)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import prettyprinter as pp\n", + "from prettyprinter.prettyprinter import IMPLICIT_MODULES\n", + "pp.install_extras(include=['dataclasses'])" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "mc_openapi.doml_mc.intermediate_model.metamodel.DOMLClass(\n", + " name='application_SoftwareComponent',\n", + " superclass='application_ApplicationComponent',\n", + " attributes={\n", + " 'isPersistent': mc_openapi.doml_mc.intermediate_model.metamodel.DOMLAttribute(\n", + " name='isPersistent',\n", + " type='Boolean',\n", + " multiplicity=('1', '1'),\n", + " default=False\n", + " )\n", + " },\n", + " associations={\n", + " 'exposedInterfaces': mc_openapi.doml_mc.intermediate_model.metamodel.DOMLAssociation(\n", + " name='exposedInterfaces',\n", + " class_='application_SoftwareInterface',\n", + " multiplicity=('0', '*')\n", + " ),\n", + " 'consumedInterfaces': mc_openapi.doml_mc.intermediate_model.metamodel.DOMLAssociation(\n", + " name='consumedInterfaces',\n", + " class_='application_SoftwareInterface',\n", + " multiplicity=('0', '*')\n", + " )\n", + " }\n", + ")\n" + ] + } + ], + "source": [ + "IMPLICIT_MODULES.add('doml_mc.intermediate_model.metamodel')\n", + "pp.pprint(mm[\"application_SoftwareComponent\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Load the DOML document here:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "from mc_openapi.doml_mc.xmi_parser.doml_model import parse_doml_model\n", + "# doml_document_path = \"../../tests/doml/nginx-openstack_v2.domlx\"\n", + "doml_document_path = \"../../tests/doml/nginx-openstack_v2_wrong.domlx\"\n", + "with open(doml_document_path, \"rb\") as xmif:\n", + " doc = xmif.read()\n", + "\n", + "doml_model = parse_doml_model(doc, mm)\n", + "print(doml_model)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "from mc_openapi.doml_mc.intermediate_model.doml_model2im import doml_model_to_im\n", + "from mc_openapi.doml_mc.intermediate_model.doml_element import reciprocate_inverse_associations\n", + "im = doml_model_to_im(doml_model, mm)\n", + "reciprocate_inverse_associations(im, inv_assoc)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\n", + " 'nginx': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", + " name='nginx',\n", + " class_='application_SoftwareComponent',\n", + " attributes={'commons_DOMLElement::name': 'nginx'},\n", + " associations={\n", + " 'application_SoftwarePackage::consumedInterfaces': set(),\n", + " 'application_SoftwarePackage::exposedInterfaces': set()\n", + " }\n", + " ),\n", + " 'vm1': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", + " name='vm1',\n", + " class_='infrastructure_VirtualMachine',\n", + " attributes={'commons_DOMLElement::name': 'vm1'},\n", + " associations={'infrastructure_ComputingNode::ifaces': set()}\n", + " ),\n", + " 'net1': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", + " name='net1',\n", + " class_='infrastructure_Network',\n", + " attributes={\n", + " 'commons_DOMLElement::name': 'net1',\n", + " 'infrastructure_Network::address_lb': 268435456,\n", + " 'infrastructure_Network::address_ub': 268435711\n", + " },\n", + " associations={}\n", + " ),\n", + " 'sg': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", + " name='sg',\n", + " class_='infrastructure_SecurityGroup',\n", + " attributes={'commons_DOMLElement::name': 'sg'},\n", + " associations={}\n", + " ),\n", + " 'con_infra': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", + " name='con_infra',\n", + " class_='concrete_ConcreteInfrastructure',\n", + " attributes={'commons_DOMLElement::name': 'con_infra'},\n", + " associations={\n", + " 'concrete_ConcreteInfrastructure::providers': {'openstack'},\n", + " 'concrete_ConcreteInfrastructure::nodes': {'concrete_vm'},\n", + " 'concrete_ConcreteInfrastructure::asGroups': set(),\n", + " 'concrete_ConcreteInfrastructure::networks': {'concrete_net'},\n", + " 'concrete_ConcreteInfrastructure::storages': set()\n", + " }\n", + " ),\n", + " 'concrete_vm': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", + " name='concrete_vm',\n", + " class_='concrete_VirtualMachine',\n", + " attributes={'commons_DOMLElement::name': 'concrete_vm'},\n", + " associations={'concrete_VirtualMachine::maps': {'vm1'}}\n", + " ),\n", + " 'openstack': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", + " name='openstack',\n", + " class_='concrete_RuntimeProvider',\n", + " attributes={'commons_DOMLElement::name': 'openstack'},\n", + " associations={\n", + " 'concrete_RuntimeProvider::supportedGroups': set(),\n", + " 'concrete_RuntimeProvider::vms': {'concrete_vm'},\n", + " 'concrete_RuntimeProvider::networks': {'concrete_net'},\n", + " 'concrete_RuntimeProvider::storages': set()\n", + " }\n", + " ),\n", + " 'concrete_net': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", + " name='concrete_net',\n", + " class_='concrete_Network',\n", + " attributes={'commons_DOMLElement::name': 'concrete_net'},\n", + " associations={'concrete_Network::maps': {'net1'}}\n", + " )\n", + "}\n" + ] + } + ], + "source": [ + "IMPLICIT_MODULES.add('doml_mc.intermediate_model.doml_element')\n", + "pp.pprint(im)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "unbound_elems_n = 1\n", + "unbound_elems = [f\"unbound{i}\" for i in range(unbound_elems_n)]" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "from z3 import Solver\n", + "\n", + "from mc_openapi.doml_mc.z3.metamodel_encoding import (\n", + " def_association_rel_and_assert_constraints,\n", + " def_attribute_rel_and_assert_constraints,\n", + " mk_association_sort_dict,\n", + " mk_attribute_sort_dict,\n", + " mk_class_sort_dict\n", + ")\n", + "from mc_openapi.doml_mc.z3.im_encoding import (\n", + " assert_im_associations_q,\n", + " assert_im_attributes,\n", + " def_elem_class_f_and_assert_classes,\n", + " mk_elem_sort_dict,\n", + " mk_stringsym_sort_dict\n", + ")\n", + "from mc_openapi.doml_mc.z3.utils import mk_adata_sort\n", + "\n", + "solver = Solver()\n", + "\n", + "class_sort, class_ = mk_class_sort_dict(mm)\n", + "assoc_sort, assoc = mk_association_sort_dict(mm)\n", + "attr_sort, attr = mk_attribute_sort_dict(mm)\n", + "elem_sort, elem = mk_elem_sort_dict(im, unbound_elems)\n", + "ss_sort, ss = mk_stringsym_sort_dict(im, mm)\n", + "AData = mk_adata_sort(ss_sort)\n", + "elem_class_f = def_elem_class_f_and_assert_classes(\n", + " im,\n", + " solver,\n", + " elem_sort,\n", + " elem,\n", + " class_sort,\n", + " class_\n", + ")\n", + "attr_rel = def_attribute_rel_and_assert_constraints(\n", + " mm,\n", + " solver,\n", + " attr_sort,\n", + " attr,\n", + " class_,\n", + " elem_class_f,\n", + " elem_sort,\n", + " AData,\n", + " ss\n", + ")\n", + "assert_im_attributes(\n", + " attr_rel,\n", + " solver,\n", + " im,\n", + " mm,\n", + " elem,\n", + " attr_sort,\n", + " attr,\n", + " AData,\n", + " ss\n", + ")\n", + "assoc_rel = def_association_rel_and_assert_constraints(\n", + " mm,\n", + " solver,\n", + " assoc_sort,\n", + " assoc,\n", + " class_,\n", + " elem_class_f,\n", + " elem_sort,\n", + " inv_assoc\n", + ")\n", + "assert_im_associations_q(\n", + " assoc_rel,\n", + " solver,\n", + " {k: v for k, v in im.items() if k not in unbound_elems},\n", + " elem,\n", + " assoc_sort,\n", + " assoc,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "# solver.push()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Metamodel statistics" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Number of classes: 36\n", + "Number of tuples in the subclass relation: 91\n", + "Number of attributes: 24\n", + "Number of attribute assertions: 72\n", + "Number of associations: 47\n", + "Number of associations assertions: 146\n" + ] + } + ], + "source": [ + "from mc_openapi.doml_mc.intermediate_model.metamodel import get_subclasses_dict\n", + "\n", + "print(\"Number of classes:\", len(mm))\n", + "print(\n", + " \"Number of tuples in the subclass relation:\",\n", + " sum(len(s) for s in get_subclasses_dict(mm).values())\n", + ")\n", + "n_attrs = sum(len(c.attributes) for c in mm.values())\n", + "print(\"Number of attributes:\", n_attrs)\n", + "print(\"Number of attribute assertions:\", 3 * n_attrs)\n", + "n_assocs = sum(len(c.associations) for c in mm.values())\n", + "print(\"Number of associations:\", n_assocs)\n", + "print(\"Number of associations assertions:\", 3 * n_assocs + len(inv_assoc))\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### DOML model statistics" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Number of elements: 8\n", + "Number of attributes (IM): 10\n", + "Number of associations (IM): 7\n", + "Number of string symbols: 10\n", + "Number of IM attribute assertions: 8\n", + "Number of IM association assertions: 64\n" + ] + } + ], + "source": [ + "n_elems = len(im)\n", + "print(\"Number of elements:\", n_elems)\n", + "n_attrs_im = sum(len(e.attributes) for e in im.values())\n", + "print(\"Number of attributes (IM):\", n_attrs_im)\n", + "n_assocs_im = sum(len(a) for e in im.values() for a in e.associations.values())\n", + "print(\"Number of associations (IM):\", n_assocs_im)\n", + "print(\"Number of string symbols:\", len(ss))\n", + "print(\"Number of IM attribute assertions:\", n_elems)\n", + "print(\"Number of IM association assertions:\", n_elems ** 2)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<b>sat</b>" + ], + "text/plain": [ + "sat" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "solver.check()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(:added-eqs 4046\n", + " :arith-make-feasible 5\n", + " :arith-max-columns 6\n", + " :binary-propagations 208\n", + " :conflicts 26\n", + " :datatype-accessor-ax 246\n", + " :datatype-constructor-ax 1534\n", + " :datatype-splits 249\n", + " :decisions 7349\n", + " :del-clause 14\n", + " :final-checks 8\n", + " :max-generation 4\n", + " :max-memory 22.49\n", + " :memory 22.49\n", + " :mk-bool-var 1342\n", + " :mk-clause 473\n", + " :num-allocs 2766758\n", + " :num-checks 1\n", + " :propagations 1442\n", + " :quant-instantiations 339\n", + " :restarts 3\n", + " :rlimit-count 958188\n", + " :time 0.16)" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "solver.statistics()" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "from z3 import Consts, ForAll, Exists, Implies, And, Or" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "# All VMs have a network interface.\n", + "vm, iface = Consts(\n", + " \"vm iface\", elem_sort\n", + ")\n", + "vmIfaceAssertion = ForAll(\n", + " [vm],\n", + " Implies(\n", + " elem_class_f(vm) == class_[\"infrastructure_VirtualMachine\"],\n", + " Exists(\n", + " [iface],\n", + " And(\n", + " assoc_rel(vm, assoc[\"infrastructure_ComputingNode::ifaces\"], iface)\n", + " )\n", + " )\n", + " )\n", + ")\n", + "solver.assert_and_track(vmIfaceAssertion, \"vm_iface\")" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<b>sat</b>" + ], + "text/plain": [ + "sat" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "solver.check()" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "23.16" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "solver.statistics().memory" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[attribute_st_types infrastructure_VirtualMachine::sizeDescription = True,\n", + " attribute_mult_ub infrastructure_Network::address_ub = True,\n", + " attribute_values vm1 = True,\n", + " association_st_classes concrete_ConcreteInfrastructure::storages = True,\n", + " association_st_classes concrete_VirtualMachine::maps = True,\n", + " attribute_mult_ub infrastructure_Storage::cost = True,\n", + " attribute_st_types commons_DOMLElement::name = True,\n", + " attribute_st_types infrastructure_Network::address_lb = True,\n", + " association_mult_ub concrete_FunctionAsAService::maps = True,\n", + " associations con_infra con_infra = True,\n", + " association_inverse infrastructure_Container::generatedFrom infrastructure_ContainerImage::generatedContainers = True,\n", + " associations concrete_vm sg = True,\n", + " association_mult_ub infrastructure_Container::generatedFrom = True,\n", + " association_st_classes infrastructure_FunctionAsAService::ifaces = True,\n", + " association_mult_ub infrastructure_VirtualMachine::location = True,\n", + " association_st_classes concrete_Storage::maps = True,\n", + " elem_class vm1 infrastructure_VirtualMachine = True,\n", + " attribute_values concrete_vm = True,\n", + " elem_class nginx application_SoftwareComponent = True,\n", + " attribute_values nginx = True,\n", + " association_st_classes infrastructure_Storage::ifaces = True,\n", + " associations nginx nginx = True,\n", + " attribute_st_types infrastructure_Storage::storage = True,\n", + " associations nginx openstack = True,\n", + " association_st_classes concrete_RuntimeProvider::vms = True,\n", + " attribute_st_types infrastructure_Network::protocol = True,\n", + " associations concrete_net openstack = True,\n", + " associations sg nginx = True,\n", + " attribute_mult_ub infrastructure_ComputingNodeGenerator::uri = True,\n", + " association_mult_ub commons_Deployment::source = True,\n", + " attribute_st_types infrastructure_ComputingNode::os = True,\n", + " attribute_values sg = True,\n", + " associations net1 vm1 = True,\n", + " elem_class concrete_vm concrete_VirtualMachine = True,\n", + " attribute_mult_ub application_SoftwareComponent::isPersistent = True,\n", + " attribute_values concrete_net = True,\n", + " association_st_classes infrastructure_ContainerImage::generatedContainers = True,\n", + " association_mult_lb infrastructure_NetworkInterface::belongsTo = True,\n", + " association_mult_lb concrete_VirtualMachine::maps = True,\n", + " association_st_classes concrete_ConcreteInfrastructure::nodes = True,\n", + " association_mult_ub concrete_VirtualMachine::maps = True,\n", + " association_st_classes commons_Deployment::target = True,\n", + " association_st_classes concrete_ConcreteInfrastructure::faas = True,\n", + " associations net1 con_infra = True,\n", + " attribute_st_types concrete_ConcreteElement::configurationScript = True,\n", + " association_mult_ub infrastructure_VirtualMachine::generatedFrom = True,\n", + " associations nginx net1 = True,\n", + " attribute_st_types infrastructure_Network::address_ub = True,\n", + " attribute_values openstack = True,\n", + " attribute_st_types infrastructure_ComputingNode::cost = True,\n", + " association_mult_ub infrastructure_NetworkInterface::belongsTo = True,\n", + " associations nginx vm1 = True,\n", + " associations con_infra concrete_vm = True,\n", + " association_mult_ub infrastructure_ComputingNode::location = True,\n", + " association_mult_lb concrete_AutoScalingGroup::maps = True,\n", + " attribute_values net1 = True,\n", + " association_mult_ub infrastructure_Storage::ifaces = True,\n", + " attribute_mult_ub infrastructure_Location::zone = True,\n", + " associations vm1 openstack = True,\n", + " association_mult_ub infrastructure_ComputingNode::group = True,\n", + " associations sg concrete_net = True,\n", + " association_st_classes infrastructure_VirtualMachine::generatedFrom = True,\n", + " association_st_classes concrete_FunctionAsAService::maps = True,\n", + " associations concrete_vm net1 = True,\n", + " associations net1 openstack = True,\n", + " associations concrete_vm concrete_vm = True,\n", + " association_st_classes concrete_ConcreteInfrastructure::networks = True,\n", + " associations openstack vm1 = True,\n", + " associations con_infra concrete_net = True,\n", + " association_inverse infrastructure_ComputingNode::group infrastructure_AutoScalingGroup::groupedNodes = True,\n", + " association_mult_ub commons_Deployment::target = True,\n", + " associations con_infra vm1 = True,\n", + " attribute_mult_lb commons_DOMLElement::name = True,\n", + " associations vm1 nginx = True,\n", + " association_mult_ub infrastructure_FunctionAsAService::ifaces = True,\n", + " association_st_classes infrastructure_SecurityGroup::groupedNodes = True,\n", + " attribute_mult_ub infrastructure_Network::address_lb = True,\n", + " association_st_classes infrastructure_ComputingNode::location = True,\n", + " association_st_classes infrastructure_VirtualMachine::location = True,\n", + " attribute_mult_lb application_SoftwareInterface::endPoint = True,\n", + " association_st_classes concrete_RuntimeProvider::networks = True,\n", + " vm_iface = True,\n", + " associations net1 nginx = True,\n", + " attribute_mult_ub infrastructure_Location::region = True,\n", + " associations con_infra nginx = True,\n", + " association_mult_ub concrete_Storage::maps = True,\n", + " association_st_classes commons_Deployment::source = True,\n", + " associations con_infra net1 = True,\n", + " attribute_mult_ub commons_DOMLElement::description = True,\n", + " association_st_classes application_SoftwareComponent::exposedInterfaces = True,\n", + " association_inverse infrastructure_ComputingNode::group infrastructure_SecurityGroup::groupedNodes = True,\n", + " association_mult_lb commons_Deployment::target = True,\n", + " associations nginx concrete_net = True,\n", + " elem_class con_infra concrete_ConcreteInfrastructure = True,\n", + " association_mult_lb infrastructure_Container::host = True,\n", + " association_st_classes concrete_AutoScalingGroup::maps = True,\n", + " attribute_values con_infra = True,\n", + " associations sg openstack = True,\n", + " associations sg sg = True,\n", + " association_st_classes concrete_ConcreteInfrastructure::providers = True,\n", + " attribute_mult_ub infrastructure_ComputingNode::memory = True,\n", + " attribute_mult_ub infrastructure_Network::protocol = True,\n", + " elem_class concrete_net concrete_Network = True,\n", + " attribute_st_types infrastructure_ComputingNode::cpu = True,\n", + " association_mult_ub infrastructure_Container::host = True,\n", + " associations openstack openstack = True,\n", + " association_st_classes infrastructure_InfrastructureLayer::generators = True,\n", + " attribute_mult_lb infrastructure_Location::region = True,\n", + " attribute_mult_ub infrastructure_ComputingNode::cost = True,\n", + " attribute_st_types application_SoftwareComponent::isPersistent = True,\n", + " association_st_classes infrastructure_Network::subnets = True,\n", + " association_st_classes infrastructure_InfrastructureLayer::nodes = True,\n", + " association_st_classes infrastructure_VMImage::generatedVMs = True,\n", + " associations net1 sg = True,\n", + " associations nginx con_infra = True,\n", + " associations concrete_net nginx = True,\n", + " elem_class sg infrastructure_SecurityGroup = True,\n", + " associations con_infra sg = True,\n", + " association_st_classes concrete_RuntimeProvider::faas = True,\n", + " associations openstack nginx = True,\n", + " associations concrete_net con_infra = True,\n", + " associations nginx concrete_vm = True,\n", + " associations sg net1 = True,\n", + " association_mult_lb commons_Deployment::source = True,\n", + " associations net1 concrete_vm = True,\n", + " association_st_classes infrastructure_Firewall::ifaces = True,\n", + " associations con_infra openstack = True,\n", + " attribute_st_types infrastructure_Location::region = True,\n", + " associations vm1 concrete_net = True,\n", + " ...]\n" + ] + } + ], + "source": [ + "m = solver.model()\n", + "print(m)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "vm1 infrastructure_ComputingNode::ifaces unbound0\n", + "net1 infrastructure_Network::connectedIfaces unbound0\n", + "unbound0 infrastructure_NetworkInterface::belongsTo net1\n" + ] + } + ], + "source": [ + "from itertools import product\n", + "for (e1n, e1), a, (e2n, e2) in product(elem.items(), assoc.values(), elem.items()):\n", + " if (e1n in unbound_elems or e2n in unbound_elems) and m.eval(assoc_rel(e1, a, e2)):\n", + " print(e1, a, e2)" + ] + } + ], + "metadata": { + "interpreter": { + "hash": "a6678cf6b5907da3ee1c64f7f36cf1b3f0e5fe51f4038e28403f1c01345fc5bd" + }, + "kernelspec": { + "display_name": "Python 3.9.9 64-bit", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.12" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/mc_openapi/doml_mc/intermediate_model/__init__.py b/mc_openapi/doml_mc/intermediate_model/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/mc_openapi/doml_mc/intermediate_model/application2im.py b/mc_openapi/doml_mc/intermediate_model/application2im.py new file mode 100644 index 0000000000000000000000000000000000000000..eee31cc0c23924fe45cf95699d7c62948258e39d --- /dev/null +++ b/mc_openapi/doml_mc/intermediate_model/application2im.py @@ -0,0 +1,45 @@ +from ..model.application import Application, ApplicationComponent +from .._utils import merge_dicts + +from .types import IntermediateModel +from .doml_element import DOMLElement + + +def application_to_im(app: Application) -> IntermediateModel: + def app_comp_to_im( + app_comp: ApplicationComponent, + ) -> IntermediateModel: + comp_elem = DOMLElement( + name=app_comp.name, + class_=app_comp.typeId, + attributes={"commons_DOMLElement::name": app_comp.name}, + associations={ + "application_SoftwarePackage::consumedInterfaces": { + f"{cn}_{ifacen}" + for cn, ifacens in app_comp.consumedInterfaces.items() + for ifacen in ifacens + }, + "application_SoftwarePackage::exposedInterfaces": { + f"{app_comp.name}_{ifacen}" + for ifacen in app_comp.exposedInterfaces + }, + }, + ) + + iface_elems = { + elem_n: DOMLElement( + name=elem_n, + class_="application_SoftwareInterface", + attributes={ + "commons_DOMLElement::name": elem_n, + "application_SoftwareInterface::endPoint": iface.endPoint, + }, + associations={}, + ) + for ifacen, iface in app_comp.exposedInterfaces.items() + for elem_n in [f"{app_comp.name}_{ifacen}"] + } + + return {app_comp.name: comp_elem} | iface_elems + + return merge_dicts(app_comp_to_im(comp) for comp in app.children.values()) diff --git a/mc_openapi/doml_mc/intermediate_model/concrete2im.py b/mc_openapi/doml_mc/intermediate_model/concrete2im.py new file mode 100644 index 0000000000000000000000000000000000000000..04e7ffd2157c4d77ddee6ba498e8666ed340e68c --- /dev/null +++ b/mc_openapi/doml_mc/intermediate_model/concrete2im.py @@ -0,0 +1,111 @@ +from .._utils import merge_dicts +from ..model.concretization import ( + Concretization, + Group, + Network, + Provider, + Storage, + VirtualMachine, +) + +from .doml_element import DOMLElement +from .types import IntermediateModel + + +def concretization_to_im(conc: Concretization) -> IntermediateModel: + def group_to_im(g: Group) -> IntermediateModel: + return { + g.name: DOMLElement( + name=g.name, + class_="concrete_AutoScalingGroup", + attributes={"commons_DOMLElement::name": g.name}, + associations={"concrete_AutoScalingGroup::maps": {g.maps}}, + ) + } + + def vm_to_im(vm: VirtualMachine) -> IntermediateModel: + return { + vm.name: DOMLElement( + name=vm.name, + class_="concrete_VirtualMachine", + attributes={"commons_DOMLElement::name": vm.name}, + associations={"concrete_VirtualMachine::maps": {vm.maps}}, + ) + } + + def storage_to_im(s: Storage) -> IntermediateModel: + return { + s.name: DOMLElement( + name=s.name, + class_="concrete_Storage", + attributes={"commons_DOMLElement::name": s.name}, + associations={"concrete_Storage::maps": {s.maps}}, + ) + } + + def network_to_im(n: Network) -> IntermediateModel: + return { + n.name: DOMLElement( + name=n.name, + class_="concrete_Network", + attributes={"commons_DOMLElement::name": n.name}, + associations={"concrete_Network::maps": {n.maps}}, + ) + } + + def provider_to_im(p: Provider) -> IntermediateModel: + return { + p.name: DOMLElement( + name=p.name, + class_="concrete_RuntimeProvider", + attributes={"commons_DOMLElement::name": p.name}, + associations={ + "concrete_RuntimeProvider::supportedGroups": set( + p.supportedGroups + ), + "concrete_RuntimeProvider::vms": set(p.providedVMs), + "concrete_RuntimeProvider::networks": set( + p.providedNetworks + ), + "concrete_RuntimeProvider::storages": set(p.storages), + }, + ) + } + + im_groups = merge_dicts(group_to_im(g) for g in conc.groups.values()) + im_vms = merge_dicts(vm_to_im(vm) for vm in conc.vms.values()) + im_providers = merge_dicts( + provider_to_im(p) for p in conc.providers.values() + ) + im_storages = merge_dicts(storage_to_im(s) for s in conc.storages.values()) + im_networks = merge_dicts(network_to_im(n) for n in conc.networks.values()) + + return ( + { + conc.name: DOMLElement( + name=conc.name, + class_="concrete_ConcreteInfrastructure", + attributes={"commons_DOMLElement::name": conc.name}, + associations={ + "concrete_ConcreteInfrastructure::providers": set( + im_providers + ), + "concrete_ConcreteInfrastructure::nodes": set(im_vms), + "concrete_ConcreteInfrastructure::asGroups": set( + im_groups + ), + "concrete_ConcreteInfrastructure::networks": set( + im_networks + ), + "concrete_ConcreteInfrastructure::storages": set( + im_storages + ), + }, + ) + } + | im_groups + | im_vms + | im_providers + | im_storages + | im_networks + ) diff --git a/mc_openapi/doml_mc/intermediate_model/doml_element.py b/mc_openapi/doml_mc/intermediate_model/doml_element.py new file mode 100644 index 0000000000000000000000000000000000000000..1f532b9fa1dae54fc7ab06d9a5d8d4eb8b150adb --- /dev/null +++ b/mc_openapi/doml_mc/intermediate_model/doml_element.py @@ -0,0 +1,69 @@ +from typing import Union +from dataclasses import dataclass + +from .metamodel import ( + AssociationNotFound, + AttributeNotFound, + MetaModel, + get_mangled_attribute_name, + get_mangled_association_name, +) + +Attributes = dict[str, Union[str, int, bool]] +Associations = dict[str, set[str]] + + +@dataclass +class DOMLElement: + name: str + class_: str + # the keys of the `attributes`/`associations` dicts are + # attribute/association names mangled with the type that declares them, + # e.g., `"application_SoftwarePackage::isPersistent"`. + attributes: Attributes + associations: Associations + + +IntermediateModel = dict[str, "DOMLElement"] + + +def parse_attrs_and_assocs_from_doc( + doc: dict, + cname: str, + mm: MetaModel, +) -> tuple[Attributes, Associations]: + attrs = {} + assocs = {} + for k, v in doc.items(): + try: + man = get_mangled_attribute_name(mm, cname, k) + attrs[man] = v + except AttributeNotFound: + try: + man = get_mangled_association_name(mm, cname, k) + # Only single target associations are found + # with this function. Change otherwise. + assocs[man] = {v} + except AssociationNotFound: + pass + return attrs, assocs + + +def reciprocate_inverse_associations( + im: IntermediateModel, + invs: list[tuple[str, str]], +) -> None: + """ + ### Effects + This procedure is effectful on `im`. + """ + # A dict for inverse lookup where inverse relationships are mapped both + # ways. + inv_dict = dict(invs) | {an2: an1 for an1, an2 in invs} + for ename, elem in im.items(): + for aname, atgts in elem.associations.items(): + if aname in inv_dict: + for atgt in atgts: + im[atgt].associations[inv_dict[aname]] = im[ + atgt + ].associations.get(inv_dict[aname], set()) | {ename} diff --git a/mc_openapi/doml_mc/intermediate_model/doml_model2im.py b/mc_openapi/doml_mc/intermediate_model/doml_model2im.py new file mode 100644 index 0000000000000000000000000000000000000000..1014dc3bd20568265b2cdaa0408f58122b4159e1 --- /dev/null +++ b/mc_openapi/doml_mc/intermediate_model/doml_model2im.py @@ -0,0 +1,18 @@ +from .._utils import merge_dicts +from ..model.doml_model import DOMLModel + +from .types import IntermediateModel, MetaModel +from .application2im import application_to_im +from .infrastructure2im import infrastructure_to_im +from .concrete2im import concretization_to_im + + +def doml_model_to_im(model: DOMLModel, mm: MetaModel) -> IntermediateModel: + return ( + application_to_im(model.application) + | infrastructure_to_im(model.infrastructure, mm) + | merge_dicts( + concretization_to_im(conc) + for conc in model.concretizations.values() + ) + ) diff --git a/mc_openapi/doml_mc/intermediate_model/infrastructure2im.py b/mc_openapi/doml_mc/intermediate_model/infrastructure2im.py new file mode 100644 index 0000000000000000000000000000000000000000..5e826734697520ad538e61a1d92f2b42069c8158 --- /dev/null +++ b/mc_openapi/doml_mc/intermediate_model/infrastructure2im.py @@ -0,0 +1,92 @@ +from ipaddress import ip_address, ip_network + +from ..model.infrastructure import ( + Infrastructure, + InfrastructureNode, + Network, + Group, +) +from .._utils import merge_dicts + +from .types import IntermediateModel, MetaModel +from .doml_element import DOMLElement +from .metamodel import get_subclasses_dict + + +def infrastructure_to_im( + infra: Infrastructure, mm: MetaModel +) -> IntermediateModel: + subclasses_dict = get_subclasses_dict(mm) + + def infra_node_to_im( + infra_node: InfrastructureNode, + ) -> IntermediateModel: + nifacereln = ( + "infrastructure_Storage::ifaces" + if infra_node.typeId in subclasses_dict["infrastructure_Storage"] + else "infrastructure_FunctionAsAService::ifaces" + if infra_node.typeId + in subclasses_dict["infrastructure_FunctionAsAService"] + else "infrastructure_ComputingNode::ifaces" + ) + node_elem = DOMLElement( + name=infra_node.name, + class_=infra_node.typeId, + attributes=infra_node.attributes + | {"commons_DOMLElement::name": infra_node.name}, + associations=infra_node.associations + | {nifacereln: set(infra_node.network_interfaces.keys())}, + ) + niface_elems = { + nifacen: DOMLElement( + name=nifacen, + class_="infrastructure_NetworkInterface", + attributes={ + "commons_DOMLElement::name": nifacen, + "infrastructure_NetworkInterface::endPoint": int( + ip_address(niface.endPoint) + ), + }, + associations={ + "infrastructure_NetworkInterface::belongsTo": { + niface.belongsTo + } + }, + ) + for nifacen, niface in infra_node.network_interfaces.items() + } + return {node_elem.name: node_elem} | niface_elems + + def network_to_im(net: Network) -> IntermediateModel: + return { + net.name: DOMLElement( + name=net.name, + class_="infrastructure_Network", + attributes={ + "commons_DOMLElement::name": net.name, + "infrastructure_Network::address_lb": int( + ip_network(net.addressRange)[0] + ), + "infrastructure_Network::address_ub": int( + ip_network(net.addressRange)[-1] + ), + }, + associations={}, + ) + } + + def group_to_im(group: Group) -> IntermediateModel: + return { + group.name: DOMLElement( + name=group.name, + class_=group.typeId, + attributes={"commons_DOMLElement::name": group.name}, + associations={}, + ) + } + + return ( + merge_dicts(infra_node_to_im(inode) for inode in infra.nodes.values()) + | merge_dicts(network_to_im(net) for net in infra.networks.values()) + | merge_dicts(group_to_im(group) for group in infra.groups.values()) + ) diff --git a/mc_openapi/doml_mc/intermediate_model/metamodel.py b/mc_openapi/doml_mc/intermediate_model/metamodel.py new file mode 100644 index 0000000000000000000000000000000000000000..cfb25248ee183f1e86c401dd11532658f6ed18a9 --- /dev/null +++ b/mc_openapi/doml_mc/intermediate_model/metamodel.py @@ -0,0 +1,229 @@ +from dataclasses import dataclass +from typing import cast, Literal, Optional, Union + +import networkx as nx + +from .._utils import merge_dicts + +Multiplicity = tuple[Literal["0", "1"], Literal["1", "*"]] + + +class AttributeNotFound(Exception): + pass + + +class AssociationNotFound(Exception): + pass + + +@dataclass +class DOMLClass: + name: str + superclass: Optional[str] + attributes: dict[str, "DOMLAttribute"] + associations: dict[str, "DOMLAssociation"] + + +@dataclass +class DOMLAttribute: + name: str + type: Literal["Boolean", "Integer", "String", "GeneratorKind"] + multiplicity: Multiplicity + default: Optional[Union[str, int, bool]] + + +@dataclass +class DOMLAssociation: + name: str + class_: str + multiplicity: Multiplicity + + +MetaModel = dict[str, DOMLClass] + + +def parse_metamodel(mmdoc: dict) -> MetaModel: + def parse_class(cname: str, cdoc: dict) -> DOMLClass: + def parse_mult( + mults: Literal["0..1", "0..*", "1", "1..*"] + ) -> Multiplicity: + if mults == "0..1": + return ("0", "1") + elif mults == "1": + return ("1", "1") + elif mults == "1..*": + return ("1", "*") + else: + return ("0", "*") + + def parse_attribute(aname: str, adoc: dict) -> DOMLAttribute: + # sourcery skip: merge-comparisons + type_: str = adoc["type"] + assert ( + type_ == "Boolean" + or type_ == "Integer" + or type_ == "String" + or type_ == "GeneratorKind" + ) + mults: str = adoc.get("multiplicity", "0..*") + assert ( + mults == "0..1" + or mults == "0..*" + or mults == "1" + or mults == "1..*" + ) + return DOMLAttribute( + name=aname, + type=type_, + multiplicity=parse_mult(mults), + default=adoc.get("default"), + ) + + def parse_association(aname: str, adoc: dict) -> DOMLAssociation: + # sourcery skip: merge-comparisons + mults: str = adoc.get("multiplicity", "0..*") + assert ( + mults == "0..1" + or mults == "0..*" + or mults == "1" + or mults == "1..*" + ) + return DOMLAssociation( + name=aname, + class_=adoc["class"], + multiplicity=parse_mult(mults), + ) + + return DOMLClass( + name=cname, + superclass=cdoc.get("superclass"), + attributes={ + aname: parse_attribute(aname, adoc) + for aname, adoc in cdoc.get("attributes", {}).items() + }, + associations={ + aname: parse_association(aname, adoc) + for aname, adoc in cdoc.get("associations", {}).items() + }, + ) + + assert set(mmdoc.keys()) <= { + "commons", + "application", + "infrastructure", + "concrete", + } + + return merge_dicts( + { + prefixed_name: parse_class(prefixed_name, cdoc) + for cname, cdoc in csdoc.items() + for prefixed_name in [f"{prefix}_{cname}"] + } + for prefix, csdoc in mmdoc.items() + ) + + +def parse_inverse_associations(doc: dict) -> list[tuple[str, str]]: + return [ + (inv_of, f"{layer}_{cname}::{aname}") + for layer, ldoc in doc.items() + for cname, cdoc in ldoc.items() + for aname, adoc in cdoc.get("associations", {}).items() + for inv_of in [adoc.get("inverse_of")] + if inv_of is not None + ] + + +def _find_association_class( + mm: MetaModel, + cname: str, + aname: str, +) -> DOMLClass: + c = mm[cname] + if aname in c.associations: + return c + elif c.superclass is None: + raise AssociationNotFound( + f"Association {aname} not found in subclasses of {cname}." + ) + else: + return _find_association_class(mm, c.superclass, aname) + + +def get_mangled_association_name( + mm: MetaModel, + cname: str, + aname: str, +) -> str: + return f"{_find_association_class(mm, cname, aname).name}::{aname}" + + +def get_mangled_attribute_defaults( + mm: MetaModel, + cname: str, +) -> dict[str, Union[str, int, bool]]: + c = mm[cname] + defaults = { + f"{cname}::{aname}": a.default + for aname, a in c.attributes.items() + if a.default is not None + } + if c.superclass is None: + return defaults + else: + return get_mangled_attribute_defaults(mm, c.superclass) | defaults + + +def _find_attribute_class( + mm: MetaModel, + cname: str, + aname: str, +) -> DOMLClass: + c = mm[cname] + if aname in c.attributes: + return c + elif c.superclass is None: + raise AttributeNotFound( + f"Attribute {aname} not found in subclasses of {cname}." + ) + else: + return _find_attribute_class(mm, c.superclass, aname) + + +def get_mangled_attribute_name( + mm: MetaModel, + cname: str, + aname: str, +) -> str: + return f"{_find_attribute_class(mm, cname, aname).name}::{aname}" + + +def get_subclasses_dict(mm: MetaModel) -> dict[str, set[str]]: + inherits_dg = nx.DiGraph( + [ + (c.name, c.superclass) + for c in mm.values() + if c.superclass is not None + ] + ) + inherits_dg.add_nodes_from(mm) + inherits_dg_trans = cast( + nx.DiGraph, nx.transitive_closure(inherits_dg, reflexive=True) + ) + return {cname: set(inherits_dg_trans.predecessors(cname)) for cname in mm} + + +def get_superclasses_dict(mm: MetaModel) -> dict[str, set[str]]: + inherits_dg = nx.DiGraph( + [ + (c.name, c.superclass) + for c in mm.values() + if c.superclass is not None + ] + ) + inherits_dg.add_nodes_from(mm) + inherits_dg_trans = cast( + nx.DiGraph, nx.transitive_closure(inherits_dg, reflexive=True) + ) + return {cname: set(inherits_dg_trans.successors(cname)) for cname in mm} diff --git a/mc_openapi/doml_mc/intermediate_model/types.py b/mc_openapi/doml_mc/intermediate_model/types.py new file mode 100644 index 0000000000000000000000000000000000000000..6ca340b68f2d29708d852e599cc6a0eb09abd2bc --- /dev/null +++ b/mc_openapi/doml_mc/intermediate_model/types.py @@ -0,0 +1,2 @@ +from .metamodel import MetaModel # noqa: F401 +from .doml_element import IntermediateModel # noqa: F401 diff --git a/mc_openapi/doml_mc/mc.py b/mc_openapi/doml_mc/mc.py new file mode 100644 index 0000000000000000000000000000000000000000..7b7180351ae432150797f952c7d3411ade0d60b4 --- /dev/null +++ b/mc_openapi/doml_mc/mc.py @@ -0,0 +1,172 @@ +import importlib.resources as ilres + +import yaml +from dataclasses import dataclass + +from z3 import ( + CheckSatResult, Consts, ExprRef, FuncDeclRef, Solver, SortRef, + ForAll, Exists, Implies, And +) + +from .. import assets +from .intermediate_model.doml_element import reciprocate_inverse_associations +from .intermediate_model.doml_model2im import doml_model_to_im +from .intermediate_model.metamodel import ( + parse_inverse_associations, + parse_metamodel +) +from .xmi_parser.doml_model import parse_doml_model +from .z3encoding.im_encoding import ( + assert_im_associations_q, assert_im_attributes, + def_elem_class_f_and_assert_classes, + mk_elem_sort_dict, mk_stringsym_sort_dict +) +from .z3encoding.metamodel_encoding import ( + def_association_rel_and_assert_constraints, + def_attribute_rel_and_assert_constraints, + mk_association_sort_dict, + mk_attribute_sort_dict, mk_class_sort_dict +) +from .z3encoding.types import Refs +from .z3encoding.utils import mk_adata_sort + + +@dataclass +class SMTEncoding: + classes: Refs + associations: Refs + attributes: Refs + elements: Refs + str_symbols: Refs + element_class_fun: FuncDeclRef + attribute_rel: FuncDeclRef + association_rel: FuncDeclRef + + +@dataclass +class SMTSorts: + class_sort: SortRef + association_sort: SortRef + attribute_sort: SortRef + element_sort: SortRef + str_symbols_sort: SortRef + + +class ModelChecker: + metamodel = None + inv_assoc = None + + @staticmethod + def init_metamodel(): + mmdoc = yaml.load(ilres.read_text(assets, "doml_meta.yaml"), yaml.Loader) + ModelChecker.metamodel = parse_metamodel(mmdoc) + ModelChecker.inv_assoc = parse_inverse_associations(mmdoc) + + def __init__(self, xmi_model: bytes): + def instantiate_solver(): + unbound_elems = [] # TODO: add this later + self.solver = Solver() + + class_sort, class_ = mk_class_sort_dict(ModelChecker.metamodel) + assoc_sort, assoc = mk_association_sort_dict(ModelChecker.metamodel) + attr_sort, attr = mk_attribute_sort_dict(ModelChecker.metamodel) + elem_sort, elem = mk_elem_sort_dict(self.intermediate_model, unbound_elems) + ss_sort, ss = mk_stringsym_sort_dict(self.intermediate_model, ModelChecker.metamodel) + AData = mk_adata_sort(ss_sort) + elem_class_f = def_elem_class_f_and_assert_classes( + self.intermediate_model, + self.solver, + elem_sort, + elem, + class_sort, + class_ + ) + attr_rel = def_attribute_rel_and_assert_constraints( + ModelChecker.metamodel, + self.solver, + attr_sort, + attr, + class_, + elem_class_f, + elem_sort, + AData, + ss + ) + assert_im_attributes( + attr_rel, + self.solver, + self.intermediate_model, + ModelChecker.metamodel, + elem, + attr_sort, + attr, + AData, + ss + ) + assoc_rel = def_association_rel_and_assert_constraints( + ModelChecker.metamodel, + self.solver, + assoc_sort, + assoc, + class_, + elem_class_f, + elem_sort, + ModelChecker.inv_assoc + ) + assert_im_associations_q( + assoc_rel, + self.solver, + {k: v for k, v in self.intermediate_model.items() if k not in unbound_elems}, + elem, + assoc_sort, + assoc, + ) + self.smt_encoding = SMTEncoding( + class_, + assoc, + attr, + elem, + ss, + elem_class_f, + attr_rel, + assoc_rel + ) + self.smt_sorts = SMTSorts( + class_sort, + assoc_sort, + attr_sort, + elem_sort, + ss_sort + ) + + assert ModelChecker.metamodel and ModelChecker.inv_assoc + doml_model = parse_doml_model(xmi_model, ModelChecker.metamodel) + self.intermediate_model = doml_model_to_im(doml_model, ModelChecker.metamodel) + reciprocate_inverse_associations(self.intermediate_model, ModelChecker.inv_assoc) + instantiate_solver() + + def get_consts(self, consts: list[str]) -> list[ExprRef]: + return Consts(" ".join(consts), self.smt_sorts.element_sort) + + def check(self) -> CheckSatResult: + return self.solver.check() + + def add_requirement(self, assertion: ExprRef, description: str): + self.solver.assert_and_track(assertion, description) + + def add_common_requirements(self): + vm, iface = self.get_consts(["vm", "iface"]) + smtenc = self.smt_encoding + vmIfaceAssertion = ForAll( + [vm], + Implies( + smtenc.element_class_fun(vm) == smtenc.classes["infrastructure_VirtualMachine"], + Exists( + [iface], + And( + smtenc.association_rel(vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], iface) + ) + ) + ) + ) + self.add_requirement(vmIfaceAssertion, "vm_iface") diff --git a/mc_openapi/doml_mc/model/__init__.py b/mc_openapi/doml_mc/model/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/mc_openapi/doml_mc/model/application.py b/mc_openapi/doml_mc/model/application.py new file mode 100644 index 0000000000000000000000000000000000000000..162cff5e67ae1b7f31f6cf7896f02608169b8665 --- /dev/null +++ b/mc_openapi/doml_mc/model/application.py @@ -0,0 +1,63 @@ +from dataclasses import dataclass + + +@dataclass +class Application: + name: str + children: dict[str, "ApplicationComponent"] + + +@dataclass +class ApplicationComponent: + typeId: str + name: str + consumedInterfaces: dict[str, list[str]] + exposedInterfaces: dict[str, "ApplicationInterface"] + + +@dataclass +class ApplicationInterface: + name: str + componentName: str + typeId: str + endPoint: str + + +def parse_application(doc: dict) -> Application: + def parse_application_component(doc: dict) -> ApplicationComponent: + def remove_prefix(s: str, prefix: str) -> str: + return s[len(prefix) :] if s.startswith(prefix) else s + + def parse_application_interface( + doc: dict, componentName: str + ) -> ApplicationInterface: + return ApplicationInterface( + name=doc["name"], + componentName=componentName, + typeId=doc["typeId"], + endPoint=doc["endPoint"], + ) + + return ApplicationComponent( + name=doc["name"], + typeId=doc["typeId"], + consumedInterfaces={ + remove_prefix(k, "consumedInterfaces->"): d + for k, d in doc.items() + if k.startswith("consumedInterfaces->") + }, + exposedInterfaces={ + intdoc["name"]: parse_application_interface( + intdoc, doc["name"] + ) + for intdoc in doc.get("exposedInterfaces", []) + }, + ) + + return Application( + name=doc["name"], + children={ + compdoc["name"]: parse_application_component(compdoc) + for compdoc in doc["children"] + }, + ) diff --git a/mc_openapi/doml_mc/model/concretization.py b/mc_openapi/doml_mc/model/concretization.py new file mode 100644 index 0000000000000000000000000000000000000000..2769d8b663806267989841d7df50358823d4828e --- /dev/null +++ b/mc_openapi/doml_mc/model/concretization.py @@ -0,0 +1,102 @@ +from dataclasses import dataclass + + +@dataclass +class Concretization: + name: str + groups: dict[str, "Group"] + vms: dict[str, "VirtualMachine"] + providers: dict[str, "Provider"] + storages: dict[str, "Storage"] + networks: dict[str, "Network"] + + +@dataclass +class Group: + name: str + maps: str + + +@dataclass +class VirtualMachine: + name: str + maps: str + + +@dataclass +class Provider: + name: str + supportedGroups: list[str] + providedVMs: list[str] + storages: list[str] + providedNetworks: list[str] + description: str + + +@dataclass +class Storage: + name: str + maps: str + + +@dataclass +class Network: + name: str + maps: str + + +def parse_concretization(doc: dict) -> Concretization: + def parse_group(doc: dict) -> Group: + return Group( + name=doc["name"], + maps=doc["maps"], + ) + + def parse_virtual_machine(doc: dict) -> VirtualMachine: + return VirtualMachine( + name=doc["name"], + maps=doc["maps"], + ) + + def parse_provider(doc: dict) -> Provider: + return Provider( + name=doc["name"], + supportedGroups=doc.get("supportedGroups", []), + providedVMs=doc["providedVMs"], + storages=doc.get("storages", []), + providedNetworks=doc["providedNetworks"], + description=doc.get("description", ""), + ) + + def parse_storage(doc: dict) -> Storage: + return Storage( + name=doc["name"], + maps=doc["maps"], + ) + + def parse_network(doc: dict) -> Network: + return Network( + name=doc["name"], + maps=doc["maps"], + ) + + return Concretization( + name=doc["name"], + groups={ + gdoc["name"]: parse_group(gdoc) for gdoc in doc.get("asGroups", []) + }, + vms={ + vmdooc["name"]: parse_virtual_machine(vmdooc) + for vmdooc in doc["vms"] + }, + providers={ + pdoc["name"]: parse_provider(pdoc) for pdoc in doc["providers"] + }, + storages={ + sdoc["name"]: parse_storage(sdoc) + for sdoc in doc.get("storages", []) + }, + networks={ + ndoc["name"]: parse_network(ndoc) for ndoc in doc["networks"] + }, + ) diff --git a/mc_openapi/doml_mc/model/doml_model.py b/mc_openapi/doml_mc/model/doml_model.py new file mode 100644 index 0000000000000000000000000000000000000000..4088d4e734938cbf8f5ccfe3d4856499c703b71d --- /dev/null +++ b/mc_openapi/doml_mc/model/doml_model.py @@ -0,0 +1,39 @@ +from dataclasses import dataclass +from typing import Optional + +from ..intermediate_model.metamodel import MetaModel + +from .application import Application, parse_application +from .infrastructure import Infrastructure, parse_infrastructure +from .optimization import Optimization, parse_optimization +from .concretization import Concretization, parse_concretization + + +@dataclass +class DOMLModel: + name: str + modelname: str + id: str + version: str + application: Application + infrastructure: Infrastructure + optimization: Optional[Optimization] + concretizations: dict[str, Concretization] + + +def parse_doml_model(doc: dict, mm: MetaModel) -> DOMLModel: + return DOMLModel( + name=doc["name"], + modelname=doc["modelname"], + id=doc["id"], + version=doc["version"], + application=parse_application(doc["application"]), + infrastructure=parse_infrastructure(doc["infrastructure"], mm), + optimization=parse_optimization(doc["optimization"]) + if "optimization" in doc + else None, + concretizations={ + concdoc["name"]: parse_concretization(concdoc) + for concdoc in doc["concretizations"] + }, + ) diff --git a/mc_openapi/doml_mc/model/infrastructure.py b/mc_openapi/doml_mc/model/infrastructure.py new file mode 100644 index 0000000000000000000000000000000000000000..829345a42784b567889b530800602cd45a67ebee --- /dev/null +++ b/mc_openapi/doml_mc/model/infrastructure.py @@ -0,0 +1,96 @@ +from dataclasses import dataclass +from typing import Union + +from mc_openapi.doml_mc.intermediate_model.doml_element import ( + parse_attrs_and_assocs_from_doc, +) + +from ..intermediate_model.metamodel import MetaModel + +Attributes = dict[str, Union[str, int, bool]] +Associations = dict[str, set[str]] + + +@dataclass +class Infrastructure: + nodes: dict[str, "InfrastructureNode"] + networks: dict[str, "Network"] + groups: dict[str, "Group"] + + +@dataclass +class InfrastructureNode: + name: str + typeId: str + network_interfaces: dict[str, "NetworkInterface"] + attributes: Attributes + associations: Associations + + +@dataclass +class Network: + name: str + protocol: str + addressRange: str + + +@dataclass +class NetworkInterface: + name: str + belongsTo: str + endPoint: str + + +@dataclass +class Group: + name: str + typeId: str + + +def parse_infrastructure(doc: dict, mm: MetaModel) -> Infrastructure: + def parse_infrastructure_node(doc: dict) -> InfrastructureNode: + def parse_network_interface(doc: dict) -> NetworkInterface: + return NetworkInterface( + name=doc["name"], + belongsTo=doc["belongsTo"], + endPoint=doc["endPoint"], + ) + + typeId = doc["typeId"] + attrs, assocs = parse_attrs_and_assocs_from_doc(doc, typeId, mm) + return InfrastructureNode( + name=doc["name"], + typeId=typeId, + network_interfaces={ + niface_doc["name"]: parse_network_interface(niface_doc) + for niface_doc in doc.get("interfaces", []) + }, + attributes=attrs, + associations=assocs, + ) + + def parse_network(doc: dict) -> Network: + return Network( + name=doc["name"], + protocol=doc["protocol"], + addressRange=doc["addressRange"], + ) + + def parse_group(doc: dict) -> Group: + return Group( + name=doc["name"], + typeId=doc["typeId"], + ) + + return Infrastructure( + nodes={ + ndoc["name"]: parse_infrastructure_node(ndoc) + for ndoc in doc["nodes"] + }, + networks={ + ndoc["name"]: parse_network(ndoc) for ndoc in doc["networks"] + }, + groups={ + gdoc["name"]: parse_group(gdoc) for gdoc in doc.get("groups", []) + }, + ) diff --git a/mc_openapi/doml_mc/model/optimization.py b/mc_openapi/doml_mc/model/optimization.py new file mode 100644 index 0000000000000000000000000000000000000000..5d104d535e2a9d90a1263ed21690cbff9d525ed5 --- /dev/null +++ b/mc_openapi/doml_mc/model/optimization.py @@ -0,0 +1,12 @@ +from dataclasses import dataclass + + +@dataclass +class Optimization: + typeId: str + + +def parse_optimization(doc: dict) -> Optimization: + return Optimization( + typeId=doc["typeId"], + ) diff --git a/mc_openapi/doml_mc/test.ipynb b/mc_openapi/doml_mc/test.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..fde0a33ebb02c98f28959ae07c9bf6c99de7abba --- /dev/null +++ b/mc_openapi/doml_mc/test.ipynb @@ -0,0 +1,52 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import mc\n", + "\n", + "doml_document_path = \"../../tests/doml/nginx-openstack_v2.domlx\"\n", + "# doml_document_path = \"../../tests/doml/nginx-openstack_v2_wrong.domlx\"\n", + "with open(doml_document_path, \"rb\") as xmif:\n", + " doc = xmif.read()\n", + "\n", + "dmc = mc.ModelChecker(doc)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "vm, iface = dmc.get_consts([\"vm\", \"iface\"])\n", + "smtenc = dmc.smt_encoding\n", + "vmIfaceAssertion = ForAll(\n", + " [vm],\n", + " Implies(\n", + " smt_enc.element_class_fun(vm) == smt_enc.classes[\"infrastructure_VirtualMachine\"],\n", + " Exists(\n", + " [iface],\n", + " And(\n", + " smt_enc.association_rel(vm, smt_enc.associations[\"infrastructure_ComputingNode::ifaces\"], iface)\n", + " )\n", + " )\n", + " )\n", + ")\n", + "dmc.add_requirement(vmIfaceAssertion, \"vm_iface\")\n", + "dmc.check()" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/mc_openapi/doml_mc/xmi_parser/__init__.py b/mc_openapi/doml_mc/xmi_parser/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..381f99a5015e215f99c790d736aaf19381518b65 --- /dev/null +++ b/mc_openapi/doml_mc/xmi_parser/__init__.py @@ -0,0 +1,3 @@ +from .doml_model import parse_doml_model, init_doml_rset # noqa: F401 + +init_doml_rset() diff --git a/mc_openapi/doml_mc/xmi_parser/application.py b/mc_openapi/doml_mc/xmi_parser/application.py new file mode 100644 index 0000000000000000000000000000000000000000..d945af6d063b33760b52c2a8717fe4baa9feb2bf --- /dev/null +++ b/mc_openapi/doml_mc/xmi_parser/application.py @@ -0,0 +1,63 @@ +from dataclasses import dataclass +from pyecore.ecore import EObject + +from ..model.application import Application, ApplicationComponent, ApplicationInterface + + +# @dataclass +# class Property: +# key: str +# value: str +# typeId: str +# +# def parse_property(doc: ecore.Property) -> Property: +# return Property( +# key=doc.key, +# value=doc.value, +# typeId=doc.type +# ) + +def parse_application(doc: EObject) -> Application: + # TODO: consider full ApplicationComponent class hierarchy + def parse_application_interface(doc: EObject, componentName: str) -> ApplicationInterface: + return ApplicationInterface( + name=doc.endPoint, + componentName=componentName, + typeId="application_" + doc.eClass.name, + endPoint=doc.endPoint, + ) + def parse_application_component(doc: EObject, interfaces: dict) -> ApplicationComponent: + consumed = {} + for cif in doc.consumedInterfaces: + cifProvider = interfaces[cif.endPoint].componentName + if cifProvider in consumed: + consumed[cifProvider].append(cif.endPoint) + else: + consumed[cifProvider] = [cif.endPoint] + + return ApplicationComponent( + name=doc.name, + typeId="application_" + doc.eClass.name, + consumedInterfaces=consumed, + exposedInterfaces={ + intdoc.endpoint: parse_application_interface( + intdoc, doc.name + ) + for intdoc in doc.exposedInterfaces + }, + ) + + # Parse all interfaces first + interfaces = { + iface.name: parse_application_interface(iface) + for comp in doc.components + for iface in comp.exposedInterfaces + } + + return Application( + name=doc.name, + children={ + compdoc.name: parse_application_component(compdoc, interfaces) + for compdoc in doc.components + }, + ) diff --git a/mc_openapi/doml_mc/xmi_parser/concretization.py b/mc_openapi/doml_mc/xmi_parser/concretization.py new file mode 100644 index 0000000000000000000000000000000000000000..2c0919fed823a016806a499fc5c4a2371f60a7f1 --- /dev/null +++ b/mc_openapi/doml_mc/xmi_parser/concretization.py @@ -0,0 +1,62 @@ +from pyecore.ecore import EObject + +from ..model.concretization import Concretization, Group, VirtualMachine, Provider, Storage, Network + + +def parse_concretization(doc: dict) -> Concretization: + def parse_provider(doc: EObject) -> (Provider, list[VirtualMachine], list[Group], list[Storage], list[Network]): + def parse_group(doc: EObject) -> Group: + return Group( + name=doc.name, + maps=doc.maps.name, + ) + + def parse_virtual_machine(doc: EObject) -> VirtualMachine: + return VirtualMachine( + name=doc.name, + maps=doc.maps.name, + ) + + def parse_storage(doc: EObject) -> Storage: + return Storage( + name=doc.name, + maps=doc.maps, + ) + + def parse_network(doc: EObject) -> Network: + return Network( + name=doc.name, + maps=doc.maps.name, + ) + + groups = list(map(parse_group, doc.group)) + vms = list(map(parse_virtual_machine, doc.vms)) + storages = list(map(parse_storage, doc.storages)) + networks = list(map(parse_network, doc.networks)) + provider = Provider( + name=doc.name, + supportedGroups=[g.name for g in groups], + providedVMs=[vm.name for vm in vms], + storages=[st.name for st in storages], + providedNetworks=[net.name for net in networks], + description=doc.description, + ) + return (provider, vms, groups, storages, networks) + + groups, vms, providers, storages, networks = ({}, {}, {}, {}, {}) + for provdoc in doc.providers: + prov, pvms, pgroups, pstorages, pnets = parse_provider(provdoc) + providers[prov.name] = prov + vms |= {vm.name: vm for vm in pvms} + groups |= {gr.name: gr for gr in pgroups} + storages |= {st.name: st for st in pstorages} + networks |= {net.name: net for net in pnets} + + return Concretization( + name=doc.name, + groups=groups, + vms=vms, + providers=providers, + storages=storages, + networks=networks, + ) diff --git a/mc_openapi/doml_mc/xmi_parser/doml_model.py b/mc_openapi/doml_mc/xmi_parser/doml_model.py new file mode 100644 index 0000000000000000000000000000000000000000..e7fe649041f06a12479722ab742373a79fe4ac45 --- /dev/null +++ b/mc_openapi/doml_mc/xmi_parser/doml_model.py @@ -0,0 +1,66 @@ +import copy +import importlib.resources as ilres + +from mc_openapi import assets +from mc_openapi.bytes_uri import BytesURI +from pyecore.ecore import EObject +from pyecore.resources import ResourceSet + +from ..intermediate_model.metamodel import MetaModel +from ..model.doml_model import DOMLModel +from .application import parse_application +from .concretization import parse_concretization +from .infrastructure import parse_infrastructure +from .optimization import parse_optimization + +doml_rset = None +def init_doml_rset(): + global doml_rset + rset = ResourceSet() + resource = rset.get_resource(BytesURI( + "doml", bytes=ilres.read_binary(assets, "doml.ecore") + )) + doml_metamodel = resource.contents[0] + + rset.metamodel_registry[doml_metamodel.nsURI] = doml_metamodel + for subp in doml_metamodel.eSubpackages: + rset.metamodel_registry[subp.nsURI] = subp + + doml_rset = rset + + +def get_rset(): + assert doml_rset is not None + return copy.copy(doml_rset) + + +def parse_xmi_model(raw_model: bytes) -> EObject: + try: + rset = get_rset() + doml_uri = BytesURI("user_doml", bytes=raw_model) + resource = rset.create_resource(doml_uri) + resource.load() + return resource.contents[0] + + except Exception: + # TODO: do something meaningful + raise + + +def parse_doml_model(raw_model: bytes, mm: MetaModel) -> DOMLModel: + model = parse_xmi_model(raw_model) + + return DOMLModel( + name=model.name, + modelname=model.name, + id=model.name, + version="", + application=parse_application(model.application), + infrastructure=parse_infrastructure(model.infrastructure, mm), + optimization=parse_optimization(model.optimization) + if model.optimization is not None else None, + concretizations={ + concdoc.name: parse_concretization(concdoc) + for concdoc in model.concretizations + }, + ) diff --git a/mc_openapi/doml_mc/xmi_parser/infrastructure.py b/mc_openapi/doml_mc/xmi_parser/infrastructure.py new file mode 100644 index 0000000000000000000000000000000000000000..c4428f3ab09a43cca0bb37b8ef1e083a35465e1b --- /dev/null +++ b/mc_openapi/doml_mc/xmi_parser/infrastructure.py @@ -0,0 +1,59 @@ +from pyecore.ecore import EObject + +from mc_openapi.doml_mc.intermediate_model.doml_element import parse_attrs_and_assocs_from_doc + +from ..intermediate_model.metamodel import MetaModel +from ..model.infrastructure import Infrastructure, InfrastructureNode, Network, NetworkInterface, Group + + +def parse_infrastructure(doc: EObject, mm: MetaModel) -> Infrastructure: + def parse_infrastructure_node(doc: EObject) -> InfrastructureNode: + def parse_network_interface(doc: EObject) -> NetworkInterface: + return NetworkInterface( + name=doc.name, + belongsTo=doc.belongsTo.name, + endPoint=doc.endPoint, + ) + + if doc.eClass.name == "AutoScalingGroup": + doc = doc.machineDefinition + + typeId = "infrastructure_" + doc.eClass.name + annotations_dict = {a.key: a.value for a in doc.annotations} + attrs, assocs = parse_attrs_and_assocs_from_doc(annotations_dict, typeId, mm) + return InfrastructureNode( + name=doc.name, + typeId=typeId, + network_interfaces={ + niface_doc.name: parse_network_interface(niface_doc) + for niface_doc in doc.ifaces + }, + attributes=attrs, + associations=assocs, + ) + + def parse_network(doc: EObject) -> Network: + return Network( + name=doc.name, + protocol=doc.protocol, + addressRange=doc.addressRange, + ) + + def parse_group(doc: EObject) -> Group: + return Group( + name=doc.name, + typeId="infrastructure_" + doc.eClass.name, + ) + + return Infrastructure( + nodes={ + inode.name: inode + for inode in map(parse_infrastructure_node, doc.nodes) + }, + networks={ + ndoc.name: parse_network(ndoc) for ndoc in doc.networks + }, + groups={ + gdoc.name: parse_group(gdoc) for gdoc in doc.secGroups + }, + ) diff --git a/mc_openapi/doml_mc/xmi_parser/optimization.py b/mc_openapi/doml_mc/xmi_parser/optimization.py new file mode 100644 index 0000000000000000000000000000000000000000..4b4e4ea0f2e956e22b162911d1bde4b3a0752e65 --- /dev/null +++ b/mc_openapi/doml_mc/xmi_parser/optimization.py @@ -0,0 +1,9 @@ +from dataclasses import dataclass +from pyecore.ecore import EObject + +from ..model.optimization import Optimization + +def parse_optimization(doc: EObject) -> Optimization: + return Optimization( + typeId="optimization_" + doc.eClass.name, + ) diff --git a/mc_openapi/doml_mc/z3encoding/__init__.py b/mc_openapi/doml_mc/z3encoding/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/mc_openapi/doml_mc/z3encoding/im_encoding.py b/mc_openapi/doml_mc/z3encoding/im_encoding.py new file mode 100644 index 0000000000000000000000000000000000000000..084f1f4e56619da9a1449f24c08b21f4728106d9 --- /dev/null +++ b/mc_openapi/doml_mc/z3encoding/im_encoding.py @@ -0,0 +1,181 @@ +from typing import Union +from itertools import product + +from z3 import ( + And, + Const, + DatatypeRef, + DatatypeSortRef, + ForAll, + FuncDeclRef, + Function, + Or, + Solver, +) + +from ..intermediate_model.types import IntermediateModel, MetaModel +from ..intermediate_model.metamodel import get_mangled_attribute_defaults + +from .types import Refs, SortAndRefs +from .utils import ( + assert_relation_tuples, + Iff, + mk_enum_sort_dict, + mk_stringsym_sort_from_strings, +) + + +def mk_elem_sort_dict( + im: IntermediateModel, additional_elems: list[str] = [] +) -> SortAndRefs: + return mk_enum_sort_dict("Element", list(im) + additional_elems) + + +def def_elem_class_f_and_assert_classes( + im: IntermediateModel, + solver: Solver, + elem_sort: DatatypeSortRef, + elem: Refs, + class_sort: DatatypeSortRef, + class_: Refs, +) -> FuncDeclRef: + """ + ### Effects + This procedure is effectful on `solver`. + """ + elem_class_f = Function("elem_class", elem_sort, class_sort) + for ename, e in im.items(): + solver.assert_and_track( + elem_class_f(elem[ename]) == class_[e.class_], + f"elem_class {ename} {e.class_}", + ) + return elem_class_f + + +def assert_im_attributes( + attr_rel: FuncDeclRef, + solver: Solver, + im: IntermediateModel, + mm: MetaModel, + elem: Refs, + attr_sort: DatatypeSortRef, + attr: Refs, + AData: DatatypeSortRef, + ss: Refs, +) -> None: + """ + ### Effects + This procedure is effectful on `solver`. + """ + + def encode_adata(v: Union[str, int, bool]) -> DatatypeRef: + if type(v) is str: + return AData.ss(ss[v]) # type: ignore + elif type(v) is int: + return AData.int(v) # type: ignore + else: # type(v) is bool + return AData.bool(v) # type: ignore + + a = Const("a", attr_sort) + d = Const("d", AData) + for esn, im_es in im.items(): + mangled_attrs = ( + get_mangled_attribute_defaults(mm, im_es.class_) | im_es.attributes + ) + assn = ForAll( + [a, d], + Iff( + attr_rel(elem[esn], a, d), + Or( + *( + And( + a == attr[amn], + d == encode_adata(avalue), + ) + for amn, avalue in mangled_attrs.items() + ) + ), + ), + ) + solver.assert_and_track(assn, f"attribute_values {esn}") + + +def assert_im_associations( + assoc_rel: FuncDeclRef, + solver: Solver, + im: IntermediateModel, + mm: MetaModel, + elem: Refs, + assoc: Refs, +) -> None: + """ + ### Effects + This procedure is effectful on `solver`. + """ + elem_names = set(im.keys()) + assoc_mangled_names = { + f"{cname}::{aname}" + for cname, c in mm.items() + for aname in c.associations + } + rel_tpls = [ + [esn, amn, etn] + for esn, amn, etn in product( + elem_names, assoc_mangled_names, elem_names + ) + if etn in im[esn].associations.get(amn, set()) + ] + assert_relation_tuples(assoc_rel, solver, rel_tpls, elem, assoc, elem) + + +def assert_im_associations_q( + assoc_rel: FuncDeclRef, + solver: Solver, + im: IntermediateModel, + elem: Refs, + assoc_sort: DatatypeSortRef, + assoc: Refs, +) -> None: + """ + ### Effects + This procedure is effectful on `solver`. + """ + + a = Const("a", assoc_sort) + for (esn, im_es), etn in product(im.items(), im): + assn = ForAll( + [a], + Iff( + assoc_rel(elem[esn], a, elem[etn]), + Or( + *( + a == assoc[amn] + for amn, etns in im_es.associations.items() + if etn in etns + ) + ), + ), + ) + solver.assert_and_track(assn, f"associations {esn} {etn}") + + +def mk_stringsym_sort_dict( + im: IntermediateModel, + mm: MetaModel, +) -> SortAndRefs: + strings = ( + { + v + for e in im.values() + for v in e.attributes.values() + if type(v) is str + } + | { + a.default + for c in mm.values() + for a in c.attributes.values() + if type(a.default) is str + } + | {"SCRIPT", "IMAGE"} # GeneratorKind values + ) + return mk_stringsym_sort_from_strings(list(strings)) diff --git a/mc_openapi/doml_mc/z3encoding/metamodel_encoding.py b/mc_openapi/doml_mc/z3encoding/metamodel_encoding.py new file mode 100644 index 0000000000000000000000000000000000000000..5cbd6fbd58b3ab33f3bca1271c0cf0b57d8a9dc7 --- /dev/null +++ b/mc_openapi/doml_mc/z3encoding/metamodel_encoding.py @@ -0,0 +1,240 @@ +from z3 import ( + And, + BoolSort, + Const, + Consts, + DatatypeSortRef, + Exists, + ForAll, + FuncDeclRef, + Function, + Implies, + Or, + Solver, +) +from ..intermediate_model.types import MetaModel +from ..intermediate_model.metamodel import get_subclasses_dict + +from .types import Refs, SortAndRefs +from .utils import Iff, mk_enum_sort_dict + + +def mk_class_sort_dict( + mm: MetaModel, +) -> SortAndRefs: + return mk_enum_sort_dict("Class", list(mm)) + + +def mk_attribute_sort_dict( + mm: MetaModel, +) -> SortAndRefs: + atts = [ + f"{cname}::{aname}" + for cname, c in mm.items() + for aname in c.attributes + ] + return mk_enum_sort_dict("Attribute", atts) + + +def mk_association_sort_dict( + mm: MetaModel, +) -> SortAndRefs: + assocs = [ + f"{cname}::{aname}" + for cname, c in mm.items() + for aname in c.associations + ] + return mk_enum_sort_dict("Association", assocs) + + +def def_attribute_rel_and_assert_constraints( + mm: MetaModel, + solver: Solver, + attr_sort: DatatypeSortRef, + attr: Refs, + class_: Refs, + elem_class_f: FuncDeclRef, + elem_sort: DatatypeSortRef, + AData: DatatypeSortRef, + ss: Refs, +) -> FuncDeclRef: + """ + ### Effects + This procedure is effectful on `solver`. + """ + attr_rel = Function("attribute", elem_sort, attr_sort, AData, BoolSort()) + subclasses_dict = get_subclasses_dict(mm) + es = Const("es", elem_sort) + ad, ad_ = Consts("ad ad_", AData) + # A type validity constraint is added for every attribute: + for cname, c in mm.items(): + src_subclass_cond = Or( # Source subclass condition + *( + elem_class_f(es) == class_[scname] + for scname in subclasses_dict[cname] + ) + ) + for mm_attr in c.attributes.values(): + # For all source elements and attribute data, their classes must be + # a subtype of the source class, and the data must be of the data + # type of the attribute. + if mm_attr.type == "Boolean": + tgt_type_cond = AData.is_bool(ad) # type: ignore + elif mm_attr.type == "Integer": + tgt_type_cond = AData.is_int(ad) # type: ignore + elif mm_attr.type == "String": + tgt_type_cond = AData.is_ss(ad) # type: ignore + else: # mm_attr.type == "GeneratorKind" + tgt_type_cond = Or( + ad == AData.ss(ss["IMAGE"]), # type: ignore + ad == AData.ss(ss["SCRIPT"]), # type: ignore + ) + assn = ForAll( + [es, ad], + Implies( + attr_rel(es, attr[f"{cname}::{mm_attr.name}"], ad), + And( + src_subclass_cond, + tgt_type_cond, + ), + ), + ) + solver.assert_and_track( + assn, f"attribute_st_types {cname}::{mm_attr.name}" + ) + + # Multiplicity constraints + lb, ub = mm_attr.multiplicity + if lb == "1": + mult_lb_assn = ForAll( + [es], + Implies( + src_subclass_cond, + Exists( + [ad], + attr_rel(es, attr[f"{cname}::{mm_attr.name}"], ad), + ), + ), + ) + solver.assert_and_track( + mult_lb_assn, + f"attribute_mult_lb {cname}::{mm_attr.name}", + ) + if ub == "1": + mult_ub_assn = ForAll( + [es, ad, ad_], + Implies( + And( + attr_rel(es, attr[f"{cname}::{mm_attr.name}"], ad), + attr_rel( + es, attr[f"{cname}::{mm_attr.name}"], ad_ + ), + ), + ad == ad_, + ), + ) + solver.assert_and_track( + mult_ub_assn, + f"attribute_mult_ub {cname}::{mm_attr.name}", + ) + return attr_rel + + +def def_association_rel_and_assert_constraints( + mm: MetaModel, + solver: Solver, + assoc_sort: DatatypeSortRef, + assoc: Refs, + class_: Refs, + elem_class_f: FuncDeclRef, + elem_sort: DatatypeSortRef, + inv_assoc: list[tuple[str, str]], +) -> FuncDeclRef: + """ + ### Effects + This procedure is effectful on `solver`. + """ + assoc_rel = Function( + "association", elem_sort, assoc_sort, elem_sort, BoolSort() + ) + subclasses_dict = get_subclasses_dict(mm) + es, et, et_ = Consts("es et et_", elem_sort) + # A type validity constraint is added for every association: + for cname, c in mm.items(): + src_subclass_cond = Or( # Source subclass condition + *( + elem_class_f(es) == class_[scname] + for scname in subclasses_dict[cname] + ) + ) + for mm_assoc in c.associations.values(): + # For all source and target elements that are associated, their + # classes must be a subtype of the source and target classes resp. + # of the association. + class_assn = ForAll( + [es, et], + Implies( + assoc_rel(es, assoc[f"{cname}::{mm_assoc.name}"], et), + And( + src_subclass_cond, + Or( # Target subclass condition + *( + elem_class_f(et) == class_[scname] + for scname in subclasses_dict[mm_assoc.class_] + ) + ), + ), + ), + ) + solver.assert_and_track( + class_assn, f"association_st_classes {cname}::{mm_assoc.name}" + ) + + # Multiplicity constraints + lb, ub = mm_assoc.multiplicity + if lb == "1": + mult_lb_assn = ForAll( + [es], + Implies( + src_subclass_cond, + Exists( + [et], + assoc_rel( + es, assoc[f"{cname}::{mm_assoc.name}"], et + ), + ), + ), + ) + solver.assert_and_track( + mult_lb_assn, + f"association_mult_lb {cname}::{mm_assoc.name}", + ) + if ub == "1": + mult_ub_assn = ForAll( + [es, et, et_], + Implies( + And( + assoc_rel( + es, assoc[f"{cname}::{mm_assoc.name}"], et + ), + assoc_rel( + es, assoc[f"{cname}::{mm_assoc.name}"], et_ + ), + ), + et == et_, + ), + ) + solver.assert_and_track( + mult_ub_assn, + f"association_mult_ub {cname}::{mm_assoc.name}", + ) + + # Inverse association assertions + for an1, an2 in inv_assoc: + inv_assn = ForAll( + [es, et], + Iff(assoc_rel(es, assoc[an1], et), assoc_rel(et, assoc[an2], es)), + ) + solver.assert_and_track(inv_assn, f"association_inverse {an1} {an2}") + + return assoc_rel diff --git a/mc_openapi/doml_mc/z3encoding/types.py b/mc_openapi/doml_mc/z3encoding/types.py new file mode 100644 index 0000000000000000000000000000000000000000..9107a492bc789d6bd9f96c3f95d9add502d22fc1 --- /dev/null +++ b/mc_openapi/doml_mc/z3encoding/types.py @@ -0,0 +1,4 @@ +from z3 import DatatypeRef, DatatypeSortRef + +Refs = dict[str, DatatypeRef] +SortAndRefs = tuple[DatatypeSortRef, Refs] diff --git a/mc_openapi/doml_mc/z3encoding/utils.py b/mc_openapi/doml_mc/z3encoding/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..5e2f0b6d5e53d1940e54d19e208226d909b80db2 --- /dev/null +++ b/mc_openapi/doml_mc/z3encoding/utils.py @@ -0,0 +1,147 @@ +from typing import cast +from collections.abc import Sequence +from itertools import product + +from z3 import ( + BoolSort, + BoolVal, + Datatype, + DatatypeSortRef, + ExprRef, + EnumSort, + FuncDeclRef, + IntSort, + Solver, +) + +from .types import Refs, SortAndRefs + + +def mk_enum_sort_dict(name: str, values: list[str]) -> SortAndRefs: + """Makes a Z3 sort and a dict indexing sort values by their name""" + + sort, dtrefs = EnumSort(name, values) + return sort, dict(zip(values, dtrefs)) + + +def assert_relation_tuples( + rel: FuncDeclRef, + solver: Solver, + rel_tpls: list[list[str]], + *sig_dicts: Refs, +) -> None: + """ + ### Parameters + - `rel` is a Z3 function with return type Bool representing a relation; + - `solver` is the Z3 solver on which to assert; + - `rel_tpls` is a list of lists of names of symbols which are related in + `rel`; + - `sig_dicts` are the domains of `rel`. + + ### Effects + This procedure is effectful on `solver`. + """ + + # Length of tuples must me homogeneous and equal to the number of given + # domains. + if lengths := [len(tpl) for tpl in rel_tpls]: + assert min(lengths) == max(lengths) + assert lengths[0] == len(sig_dicts) + + sym_tpls = [ + cast( + list[ExprRef], + [dom[sym_name] for sym_name, dom in zip(doms_tpl, sig_dicts)], + ) + + [BoolVal(doms_tpl in rel_tpls)] + for doms_tpl in map(list, product(*sig_dicts)) + ] + + assert_function_tuples_raw(rel, solver, sym_tpls) + + +def assert_function_tuples( + f: FuncDeclRef, + solver: Solver, + f_tpls: list[list[str]], + *sig_dicts: Refs, +) -> None: + """ + ### Parameters + - `f` is a Z3 function; + - `solver` is the Z3 solver on which to assert; + - `f_tpls` is a list of tuples of Z3 symbols. The first elements in each + tuple are the inputs of `f`, and the last element is its output; + - `sig_dicts` are the domains of `f`, the last one being its codomain. + + ### Effects + This procedure is effectful on `solver`. + """ + + # Length of tuples must me homogeneous and equal to the number of given + # domains. + if lengths := [len(tpl) for tpl in f_tpls]: + assert min(lengths) == max(lengths) + assert lengths[0] == len(sig_dicts) + + sym_tpls = [ + [dom[sym_name] for sym_name, dom in zip(f_tpl, sig_dicts)] + for f_tpl in f_tpls + ] + + assert_function_tuples_raw(f, solver, sym_tpls) + + +def assert_function_tuples_raw( + f: FuncDeclRef, + solver: Solver, + f_tpls: Sequence[Sequence[ExprRef]], +) -> None: + """ + ### Parameters + - `f` is a Z3 function; + - `solver` is the Z3 solver on which to assert; + - `f_tpls` is a list of tuples of Z3 references or otherwise accepted + values. The first elements in each tuple are the inputs of `f`, and the + last element is its output; + + ### Effects + This procedure is effectful on `solver`. + """ + # Length of tuples must me homogeneous. + if lengths := [len(tpl) for tpl in f_tpls]: + assert min(lengths) == max(lengths) + + for *xs, y in f_tpls: + solver.assert_and_track( + f(*xs) == y, + f"{f.name()} " + " ".join(str(x) for x in xs) + f" {y}", + ) + + +def mk_stringsym_sort_from_strings( + strings: list[str], +) -> SortAndRefs: + def symbolize(s: str) -> str: + return "".join([c.lower() if c.isalnum() else "_" for c in s[:16]]) + + ss_list = [f"ss_{i}_{symbolize(s)}" for i, s in enumerate(strings)] + stringsym_sort, ss_refs_dict = mk_enum_sort_dict("StringSym", ss_list) + stringsym_sort_dict = { + s: ss_refs_dict[ss] for s, ss in zip(strings, ss_list) + } + return stringsym_sort, stringsym_sort_dict + + +def mk_adata_sort( + ss_sort: DatatypeSortRef, +) -> DatatypeSortRef: + AData = Datatype("AttributeData") + AData.declare("int", ("get_int", IntSort())) + AData.declare("bool", ("get_bool", BoolSort())) + AData.declare("ss", ("get_ss", ss_sort)) + return AData.create() + + +def Iff(a, b): + return a == b diff --git a/mc_openapi/handlers.py b/mc_openapi/handlers.py index 9e467c82b8cab77a43979138b43a7680cdfac8b1..641cc4165ea42da97cc75200d9e5084a9f1f5a9d 100644 --- a/mc_openapi/handlers.py +++ b/mc_openapi/handlers.py @@ -1,44 +1,30 @@ import datetime -import copy -from pyecore.resources import ResourceSet, URI -from mc_openapi.string_uri import StringURI +from z3 import sat, unsat +from .doml_mc import ModelChecker -def get_rset(): - if get_rset.doml_rset is None: - rset = ResourceSet() - resource = rset.get_resource(URI("mc_openapi/doml/doml.ecore")) - doml_metamodel = resource.contents[0] - - rset.metamodel_registry[doml_metamodel.nsURI] = doml_metamodel - for subp in doml_metamodel.eSubpackages: - rset.metamodel_registry[subp.nsURI] = subp - - get_rset.doml_rset = rset - - assert get_rset.doml_rset is not None - return copy.copy(get_rset.doml_rset) -get_rset.doml_rset = None def make_error(user_msg, debug_msg=None): - result = { "message": user_msg, "timestamp": datetime.datetime.now() } + result = {"message": user_msg, "timestamp": datetime.datetime.now()} if debug_msg is not None: result["debug_message"] = debug_msg return result + def post(body, requirement=None): doml_xmi = body try: - rset = get_rset() - doml_uri = StringURI("user_doml", text=doml_xmi) - resource = rset.create_resource(doml_uri) - resource.load() - doml = resource.contents[0] - - if doml.infrastructure.nodes[0].machineDefinition.ifaces[0].belongsTo is None: - return { "result": "unsat", - "description": "Virtual machine is not linked to any network." } - - return { "result": "sat" } + dmc = ModelChecker(doml_xmi) + dmc.add_common_requirements() + + result = dmc.check() + + if result == sat: + return {"result": "sat"} + elif result == unsat: + return {"result": "unsat", + "description": "Virtual machine is not linked to any network."} + else: + return {"result": "dontknow"} except Exception as e: return make_error("Supplied with malformed DOML XMI model.", debug_msg=str(e)), 400 diff --git a/poetry.lock b/poetry.lock index c532720446b09c97e8966afbd396d8fb825a4056..30b284ea5e3b654c519c2b67cf7dda4a73001734 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,3 +1,25 @@ +[[package]] +name = "appnope" +version = "0.1.3" +description = "Disable App Nap on macOS >= 10.9" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "asttokens" +version = "2.0.5" +description = "Annotate AST trees with source code positions" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +six = "*" + +[package.extras] +test = ["astroid", "pytest"] + [[package]] name = "atomicwrites" version = "1.4.0" @@ -8,17 +30,25 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "attrs" -version = "21.2.0" +version = "21.4.0" description = "Classes Without Boilerplate" category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit"] +dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins"] +tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] +tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"] + +[[package]] +name = "backcall" +version = "0.2.0" +description = "Specifications for callback functions passed in to an API" +category = "dev" +optional = false +python-versions = "*" [[package]] name = "certifi" @@ -28,9 +58,20 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "cffi" +version = "1.15.0" +description = "Foreign Function Interface for Python calling C code." +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +pycparser = "*" + [[package]] name = "charset-normalizer" -version = "2.0.9" +version = "2.0.12" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." category = "main" optional = false @@ -41,11 +82,14 @@ unicode_backport = ["unicodedata2"] [[package]] name = "click" -version = "7.1.2" +version = "8.1.2" description = "Composable command line interface toolkit" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.7" + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} [[package]] name = "clickclick" @@ -63,13 +107,24 @@ PyYAML = ">=3.11" name = "colorama" version = "0.4.4" description = "Cross-platform colored terminal text." -category = "dev" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +[[package]] +name = "colorful" +version = "0.5.4" +description = "Terminal string styling done right, in Python." +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + [[package]] name = "connexion" -version = "2.12.0" +version = "2.13.0" description = "Connexion - API first applications with OpenAPI/Swagger and Flask" category = "main" optional = false @@ -81,7 +136,8 @@ flask = ">=1.0.4,<3" inflection = ">=0.3.1,<0.6" itsdangerous = ">=0.24" jsonschema = ">=2.5.1,<5" -PyYAML = ">=5.1,<6" +packaging = ">=20" +PyYAML = ">=5.1,<7" requests = ">=2.9.1,<3" swagger-ui-bundle = {version = ">=0.0.2,<0.1", optional = true, markers = "extra == \"swagger-ui\""} werkzeug = ">=1.0,<3" @@ -93,23 +149,55 @@ flask = ["flask (>=1.0.4,<3)", "itsdangerous (>=0.24)"] swagger-ui = ["swagger-ui-bundle (>=0.0.2,<0.1)"] tests = ["decorator (>=5,<6)", "pytest (>=6,<7)", "pytest-cov (>=2,<3)", "testfixtures (>=6,<7)", "flask (>=1.0.4,<3)", "itsdangerous (>=0.24)", "swagger-ui-bundle (>=0.0.2,<0.1)", "aiohttp (>=2.3.10,<4)", "aiohttp-jinja2 (>=0.14.0,<2)", "MarkupSafe (>=0.23)", "pytest-aiohttp", "aiohttp-remotes"] +[[package]] +name = "debugpy" +version = "1.6.0" +description = "An implementation of the Debug Adapter Protocol for Python" +category = "dev" +optional = false +python-versions = ">=3.7" + +[[package]] +name = "decorator" +version = "5.1.1" +description = "Decorators for Humans" +category = "dev" +optional = false +python-versions = ">=3.5" + +[[package]] +name = "entrypoints" +version = "0.4" +description = "Discover and load entry points from installed packages." +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "executing" +version = "0.8.3" +description = "Get the currently executing AST node of a frame, and other information" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "flask" -version = "1.1.4" +version = "2.1.1" description = "A simple framework for building complex web applications." category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.7" [package.dependencies] -click = ">=5.1,<8.0" -itsdangerous = ">=0.24,<2.0" -Jinja2 = ">=2.10.1,<3.0" -Werkzeug = ">=0.15,<2.0" +click = ">=8.0" +importlib-metadata = {version = ">=3.6.0", markers = "python_version < \"3.10\""} +itsdangerous = ">=2.0" +Jinja2 = ">=3.0" +Werkzeug = ">=2.0" [package.extras] -dev = ["pytest", "coverage", "tox", "sphinx", "pallets-sphinx-themes", "sphinxcontrib-log-cabinet", "sphinx-issues"] -docs = ["sphinx", "pallets-sphinx-themes", "sphinxcontrib-log-cabinet", "sphinx-issues"] +async = ["asgiref (>=3.2)"] dotenv = ["python-dotenv"] [[package]] @@ -131,6 +219,22 @@ category = "main" optional = false python-versions = ">=3.5" +[[package]] +name = "importlib-metadata" +version = "4.11.3" +description = "Read metadata from Python packages" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +zipp = ">=0.5" + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)"] +perf = ["ipython"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "importlib-resources (>=1.3)"] + [[package]] name = "inflection" version = "0.5.1" @@ -139,44 +243,149 @@ category = "main" optional = false python-versions = ">=3.5" +[[package]] +name = "ipykernel" +version = "6.13.0" +description = "IPython Kernel for Jupyter" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +appnope = {version = "*", markers = "platform_system == \"Darwin\""} +debugpy = ">=1.0" +ipython = ">=7.23.1" +jupyter-client = ">=6.1.12" +matplotlib-inline = ">=0.1" +nest-asyncio = "*" +packaging = "*" +psutil = "*" +tornado = ">=6.1" +traitlets = ">=5.1.0" + +[package.extras] +test = ["pytest (>=6.0)", "pytest-cov", "flaky", "ipyparallel", "pre-commit", "pytest-timeout"] + +[[package]] +name = "ipython" +version = "8.2.0" +description = "IPython: Productive Interactive Computing" +category = "dev" +optional = false +python-versions = ">=3.8" + +[package.dependencies] +appnope = {version = "*", markers = "sys_platform == \"darwin\""} +backcall = "*" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +decorator = "*" +jedi = ">=0.16" +matplotlib-inline = "*" +pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} +pickleshare = "*" +prompt-toolkit = ">=2.0.0,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.1.0" +pygments = ">=2.4.0" +stack-data = "*" +traitlets = ">=5" + +[package.extras] +all = ["black", "Sphinx (>=1.3)", "ipykernel", "nbconvert", "nbformat", "ipywidgets", "notebook", "ipyparallel", "qtconsole", "pytest (<7.1)", "pytest-asyncio", "testpath", "curio", "matplotlib (!=3.2.0)", "numpy (>=1.19)", "pandas", "trio"] +black = ["black"] +doc = ["Sphinx (>=1.3)"] +kernel = ["ipykernel"] +nbconvert = ["nbconvert"] +nbformat = ["nbformat"] +notebook = ["ipywidgets", "notebook"] +parallel = ["ipyparallel"] +qtconsole = ["qtconsole"] +test = ["pytest (<7.1)", "pytest-asyncio", "testpath"] +test_extra = ["pytest (<7.1)", "pytest-asyncio", "testpath", "curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.19)", "pandas", "trio"] + [[package]] name = "itsdangerous" -version = "1.1.0" -description = "Various helpers to pass data to untrusted environments and back." +version = "2.1.2" +description = "Safely pass data to untrusted environments and back." category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.7" + +[[package]] +name = "jedi" +version = "0.18.1" +description = "An autocompletion tool for Python that can be used for text editors." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +parso = ">=0.8.0,<0.9.0" + +[package.extras] +qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] +testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<7.0.0)"] [[package]] name = "jinja2" -version = "2.11.3" +version = "3.1.1" description = "A very fast and expressive template engine." category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.7" [package.dependencies] -MarkupSafe = ">=0.23" +MarkupSafe = ">=2.0" [package.extras] -i18n = ["Babel (>=0.8)"] +i18n = ["Babel (>=2.7)"] [[package]] name = "jsonschema" -version = "3.2.0" +version = "4.4.0" description = "An implementation of JSON Schema validation for Python" category = "main" optional = false -python-versions = "*" +python-versions = ">=3.7" [package.dependencies] attrs = ">=17.4.0" -pyrsistent = ">=0.14.0" -six = ">=1.11.0" +pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" [package.extras] -format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] -format_nongpl = ["idna", "jsonpointer (>1.13)", "webcolors", "rfc3986-validator (>0.1.0)", "rfc3339-validator"] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format_nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] + +[[package]] +name = "jupyter-client" +version = "7.2.2" +description = "Jupyter protocol implementation and client libraries" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +entrypoints = "*" +jupyter-core = ">=4.9.2" +nest-asyncio = ">=1.5.4" +python-dateutil = ">=2.8.2" +pyzmq = ">=22.3" +tornado = ">=6.0" +traitlets = "*" + +[package.extras] +doc = ["ipykernel", "myst-parser", "sphinx (>=1.3.6)", "sphinx-rtd-theme", "sphinxcontrib-github-alt"] +test = ["codecov", "coverage", "ipykernel (>=6.5)", "ipython", "mypy", "pre-commit", "pytest", "pytest-asyncio (>=0.18)", "pytest-cov", "pytest-timeout"] + +[[package]] +name = "jupyter-core" +version = "4.9.2" +description = "Jupyter core package. A base package on which Jupyter projects rely." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +pywin32 = {version = ">=1.0", markers = "sys_platform == \"win32\" and platform_python_implementation != \"PyPy\""} +traitlets = "*" [[package]] name = "lxml" @@ -194,11 +403,22 @@ source = ["Cython (>=0.29.7)"] [[package]] name = "markupsafe" -version = "2.0.1" +version = "2.1.1" description = "Safely add untrusted strings to HTML/XML markup." category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" + +[[package]] +name = "matplotlib-inline" +version = "0.1.3" +description = "Inline Matplotlib backend for Jupyter" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +traitlets = "*" [[package]] name = "more-itertools" @@ -208,6 +428,29 @@ category = "dev" optional = false python-versions = ">=3.5" +[[package]] +name = "nest-asyncio" +version = "1.5.5" +description = "Patch asyncio to allow nested event loops" +category = "dev" +optional = false +python-versions = ">=3.5" + +[[package]] +name = "networkx" +version = "2.8" +description = "Python package for creating and manipulating graphs and networks" +category = "main" +optional = false +python-versions = ">=3.8" + +[package.extras] +default = ["numpy (>=1.19)", "scipy (>=1.8)", "matplotlib (>=3.4)", "pandas (>=1.3)"] +developer = ["pre-commit (>=2.18)", "mypy (>=0.942)"] +doc = ["sphinx (>=4.5)", "pydata-sphinx-theme (>=0.8.1)", "sphinx-gallery (>=0.10)", "numpydoc (>=1.2)", "pillow (>=9.1)", "nb2plots (>=0.6)", "texext (>=0.6.6)"] +extra = ["lxml (>=4.6)", "pygraphviz (>=1.9)", "pydot (>=1.4.2)", "sympy (>=1.10)"] +test = ["pytest (>=7.1)", "pytest-cov (>=3.0)", "codecov (>=2.1)"] + [[package]] name = "ordered-set" version = "4.1.0" @@ -223,13 +466,44 @@ dev = ["pytest", "black", "mypy"] name = "packaging" version = "21.3" description = "Core utilities for Python packages" -category = "dev" +category = "main" optional = false python-versions = ">=3.6" [package.dependencies] pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" +[[package]] +name = "parso" +version = "0.8.3" +description = "A Python Parser" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] +testing = ["docopt", "pytest (<6.0.0)"] + +[[package]] +name = "pexpect" +version = "4.8.0" +description = "Pexpect allows easy control of interactive console applications." +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +ptyprocess = ">=0.5" + +[[package]] +name = "pickleshare" +version = "0.7.5" +description = "Tiny 'shelve'-like database with concurrency support" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "pluggy" version = "0.13.1" @@ -241,6 +515,59 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.extras] dev = ["pre-commit", "tox"] +[[package]] +name = "prettyprinter" +version = "0.18.0" +description = "Syntax-highlighting, declarative and composable pretty printer for Python 3.5+" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +colorful = ">=0.4.0" +Pygments = ">=2.2.0" + +[[package]] +name = "prompt-toolkit" +version = "3.0.29" +description = "Library for building powerful interactive command lines in Python" +category = "dev" +optional = false +python-versions = ">=3.6.2" + +[package.dependencies] +wcwidth = "*" + +[[package]] +name = "psutil" +version = "5.9.0" +description = "Cross-platform lib for process and system monitoring in Python." +category = "dev" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.extras] +test = ["ipaddress", "mock", "unittest2", "enum34", "pywin32", "wmi"] + +[[package]] +name = "ptyprocess" +version = "0.7.0" +description = "Run a subprocess in a pseudo terminal" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "pure-eval" +version = "0.2.2" +description = "Safely evaluate AST nodes without side effects" +category = "dev" +optional = false +python-versions = "*" + +[package.extras] +tests = ["pytest"] + [[package]] name = "py" version = "1.11.0" @@ -249,6 +576,14 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +[[package]] +name = "pycparser" +version = "2.21" +description = "C parser in Python" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + [[package]] name = "pyecore" version = "0.12.2" @@ -264,23 +599,31 @@ ordered-set = ">=4.0.1" restrictedpython = ">=4.0b6" [[package]] -name = "pyparsing" -version = "3.0.6" -description = "Python parsing module" +name = "pygments" +version = "2.11.2" +description = "Pygments is a syntax highlighting package written in Python." category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.5" + +[[package]] +name = "pyparsing" +version = "3.0.8" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" +category = "main" +optional = false +python-versions = ">=3.6.8" [package.extras] -diagrams = ["jinja2", "railroad-diagrams"] +diagrams = ["railroad-diagrams", "jinja2"] [[package]] name = "pyrsistent" -version = "0.18.0" +version = "0.18.1" description = "Persistent/Functional/Immutable data structures" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [[package]] name = "pytest" @@ -304,17 +647,48 @@ wcwidth = "*" checkqa-mypy = ["mypy (==v0.761)"] testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] +[[package]] +name = "python-dateutil" +version = "2.8.2" +description = "Extensions to the standard Python datetime module" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "pywin32" +version = "303" +description = "Python for Window Extensions" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "pyyaml" -version = "5.4.1" +version = "6.0" description = "YAML parser and emitter for Python" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +python-versions = ">=3.6" + +[[package]] +name = "pyzmq" +version = "22.3.0" +description = "Python bindings for 0MQ" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +cffi = {version = "*", markers = "implementation_name == \"pypy\""} +py = {version = "*", markers = "implementation_name == \"pypy\""} [[package]] name = "requests" -version = "2.26.0" +version = "2.27.1" description = "Python HTTP for Humans." category = "main" optional = false @@ -345,10 +719,26 @@ test = ["pytest", "pytest-mock"] name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "main" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +[[package]] +name = "stack-data" +version = "0.2.0" +description = "Extract data from python stack frames and tracebacks for informative displays" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +asttokens = "*" +executing = "*" +pure-eval = "*" + +[package.extras] +tests = ["pytest", "typeguard", "pygments", "littleutils", "cython"] + [[package]] name = "swagger-ui-bundle" version = "0.0.9" @@ -360,16 +750,35 @@ python-versions = "*" [package.dependencies] Jinja2 = ">=2.0" +[[package]] +name = "tornado" +version = "6.1" +description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." +category = "dev" +optional = false +python-versions = ">= 3.5" + +[[package]] +name = "traitlets" +version = "5.1.1" +description = "Traitlets Python configuration system" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +test = ["pytest"] + [[package]] name = "urllib3" -version = "1.26.7" +version = "1.26.9" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" [package.extras] -brotli = ["brotlipy (>=0.6.0)"] +brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"] secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] @@ -391,41 +800,124 @@ python-versions = "*" [[package]] name = "werkzeug" -version = "1.0.1" +version = "2.1.1" description = "The comprehensive WSGI web application library." category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.7" [package.extras] -dev = ["pytest", "pytest-timeout", "coverage", "tox", "sphinx", "pallets-sphinx-themes", "sphinx-issues"] watchdog = ["watchdog"] +[[package]] +name = "z3-solver" +version = "4.8.15.0" +description = "an efficient SMT solver library" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "zipp" +version = "3.8.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"] + [metadata] lock-version = "1.1" -python-versions = "^3.8" -content-hash = "230a5aa6082d4f5282cacd6b28dc9e65a0564056fc42ad904ede0d3956d7fdb8" +python-versions = "^3.9" +content-hash = "72a3672221767f9290b32103d450d8eef559efdbdad5c2775ba3e13f40d4b0ba" [metadata.files] +appnope = [ + {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"}, + {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"}, +] +asttokens = [ + {file = "asttokens-2.0.5-py2.py3-none-any.whl", hash = "sha256:0844691e88552595a6f4a4281a9f7f79b8dd45ca4ccea82e5e05b4bbdb76705c"}, + {file = "asttokens-2.0.5.tar.gz", hash = "sha256:9a54c114f02c7a9480d56550932546a3f1fe71d8a02f1bc7ccd0ee3ee35cf4d5"}, +] atomicwrites = [ {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, ] attrs = [ - {file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"}, - {file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"}, + {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, + {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, +] +backcall = [ + {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, + {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, ] certifi = [ {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"}, {file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"}, ] +cffi = [ + {file = "cffi-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962"}, + {file = "cffi-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0"}, + {file = "cffi-1.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14"}, + {file = "cffi-1.15.0-cp27-cp27m-win32.whl", hash = "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474"}, + {file = "cffi-1.15.0-cp27-cp27m-win_amd64.whl", hash = "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6"}, + {file = "cffi-1.15.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27"}, + {file = "cffi-1.15.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023"}, + {file = "cffi-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2"}, + {file = "cffi-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e"}, + {file = "cffi-1.15.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7"}, + {file = "cffi-1.15.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3"}, + {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c"}, + {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962"}, + {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382"}, + {file = "cffi-1.15.0-cp310-cp310-win32.whl", hash = "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55"}, + {file = "cffi-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0"}, + {file = "cffi-1.15.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e"}, + {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39"}, + {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc"}, + {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032"}, + {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8"}, + {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605"}, + {file = "cffi-1.15.0-cp36-cp36m-win32.whl", hash = "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e"}, + {file = "cffi-1.15.0-cp36-cp36m-win_amd64.whl", hash = "sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc"}, + {file = "cffi-1.15.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636"}, + {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4"}, + {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997"}, + {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b"}, + {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2"}, + {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7"}, + {file = "cffi-1.15.0-cp37-cp37m-win32.whl", hash = "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66"}, + {file = "cffi-1.15.0-cp37-cp37m-win_amd64.whl", hash = "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029"}, + {file = "cffi-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880"}, + {file = "cffi-1.15.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20"}, + {file = "cffi-1.15.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024"}, + {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e"}, + {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728"}, + {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6"}, + {file = "cffi-1.15.0-cp38-cp38-win32.whl", hash = "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c"}, + {file = "cffi-1.15.0-cp38-cp38-win_amd64.whl", hash = "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443"}, + {file = "cffi-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a"}, + {file = "cffi-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37"}, + {file = "cffi-1.15.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a"}, + {file = "cffi-1.15.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e"}, + {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796"}, + {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df"}, + {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8"}, + {file = "cffi-1.15.0-cp39-cp39-win32.whl", hash = "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a"}, + {file = "cffi-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139"}, + {file = "cffi-1.15.0.tar.gz", hash = "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954"}, +] charset-normalizer = [ - {file = "charset-normalizer-2.0.9.tar.gz", hash = "sha256:b0b883e8e874edfdece9c28f314e3dd5badf067342e42fb162203335ae61aa2c"}, - {file = "charset_normalizer-2.0.9-py3-none-any.whl", hash = "sha256:1eecaa09422db5be9e29d7fc65664e6c33bd06f9ced7838578ba40d58bdf3721"}, + {file = "charset-normalizer-2.0.12.tar.gz", hash = "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597"}, + {file = "charset_normalizer-2.0.12-py3-none-any.whl", hash = "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"}, ] click = [ - {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, - {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, + {file = "click-8.1.2-py3-none-any.whl", hash = "sha256:24e1a4a9ec5bf6299411369b208c1df2188d9eb8d916302fe6bf03faed227f1e"}, + {file = "click-8.1.2.tar.gz", hash = "sha256:479707fe14d9ec9a0757618b7a100a0ae4c4e236fac5b7f80ca68028141a1a72"}, ] clickclick = [ {file = "clickclick-20.10.2-py2.py3-none-any.whl", hash = "sha256:c8f33e6d9ec83f68416dd2136a7950125bd256ec39ccc9a85c6e280a16be2bb5"}, @@ -435,13 +927,49 @@ colorama = [ {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, ] +colorful = [ + {file = "colorful-0.5.4-py2.py3-none-any.whl", hash = "sha256:8d264b52a39aae4c0ba3e2a46afbaec81b0559a99be0d2cfe2aba4cf94531348"}, + {file = "colorful-0.5.4.tar.gz", hash = "sha256:86848ad4e2eda60cd2519d8698945d22f6f6551e23e95f3f14dfbb60997807ea"}, +] connexion = [ - {file = "connexion-2.12.0-py2.py3-none-any.whl", hash = "sha256:2d163976fbc8766038d71f4232ace07826be7dd0a8fe7a539ce5fc8a80f1ab35"}, - {file = "connexion-2.12.0.tar.gz", hash = "sha256:c08b530418a1c448d34cd142713ddd1b245e7694f45cd80533fe8538b64aa7eb"}, + {file = "connexion-2.13.0-py2.py3-none-any.whl", hash = "sha256:26a570a0283bbe4cdaf5d90dfb3441aaf8e18cb9de10f3f96bbc128a8a3d8b47"}, + {file = "connexion-2.13.0.tar.gz", hash = "sha256:0ba5c163d34cb3cb3bf597d5b95fc14bad5d3596bf10ec86e32cdb63f68d0c8a"}, +] +debugpy = [ + {file = "debugpy-1.6.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:eb1946efac0c0c3d411cea0b5ac772fbde744109fd9520fb0c5a51979faf05ad"}, + {file = "debugpy-1.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e3513399177dd37af4c1332df52da5da1d0c387e5927dc4c0709e26ee7302e8f"}, + {file = "debugpy-1.6.0-cp310-cp310-win32.whl", hash = "sha256:5c492235d6b68f879df3bdbdb01f25c15be15682665517c2c7d0420e5658d71f"}, + {file = "debugpy-1.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:40de9ba137d355538432209d05e0f5fe5d0498dce761c39119ad4b950b51db31"}, + {file = "debugpy-1.6.0-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:0d383b91efee57dbb923ba20801130cf60450a0eda60bce25bccd937de8e323a"}, + {file = "debugpy-1.6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1ff853e60e77e1c16f85a31adb8360bb2d98ca588d7ed645b7f0985b240bdb5e"}, + {file = "debugpy-1.6.0-cp37-cp37m-win32.whl", hash = "sha256:8e972c717d95f56b6a3a7a29a5ede1ee8f2c3802f6f0e678203b0778eb322bf1"}, + {file = "debugpy-1.6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:a8aaeb53e87225141fda7b9081bd87155c1debc13e2f5a532d341112d1983b65"}, + {file = "debugpy-1.6.0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:132defb585b518955358321d0f42f6aa815aa15b432be27db654807707c70b2f"}, + {file = "debugpy-1.6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8ee75844242b4537beb5899f3e60a578454d1f136b99e8d57ac424573797b94a"}, + {file = "debugpy-1.6.0-cp38-cp38-win32.whl", hash = "sha256:a65a2499761d47df3e9ea9567109be6e73d412e00ac3ffcf74839f3ddfcdf028"}, + {file = "debugpy-1.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:bd980d533d0ddfc451e03a3bb32acb2900049fec39afc3425b944ebf0889be62"}, + {file = "debugpy-1.6.0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:245c7789a012f86210847ec7ee9f38c30a30d4c2223c3e111829a76c9006a5d0"}, + {file = "debugpy-1.6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0e3aa2368883e83e7b689ddff3cafb595f7b711f6a065886b46a96a7fef874e7"}, + {file = "debugpy-1.6.0-cp39-cp39-win32.whl", hash = "sha256:72bcfa97f3afa0064afc77ab811f48ad4a06ac330f290b675082c24437730366"}, + {file = "debugpy-1.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:30abefefd2ff5a5481162d613cb70e60e2fa80a5eb4c994717c0f008ed25d2e1"}, + {file = "debugpy-1.6.0-py2.py3-none-any.whl", hash = "sha256:4de7777842da7e08652f2776c552070bbdd758557fdec73a15d7be0e4aab95ce"}, + {file = "debugpy-1.6.0.zip", hash = "sha256:7b79c40852991f7b6c3ea65845ed0f5f6b731c37f4f9ad9c61e2ab4bd48a9275"}, +] +decorator = [ + {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, + {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, +] +entrypoints = [ + {file = "entrypoints-0.4-py3-none-any.whl", hash = "sha256:f174b5ff827504fd3cd97cc3f8649f3693f51538c7e4bdf3ef002c8429d42f9f"}, + {file = "entrypoints-0.4.tar.gz", hash = "sha256:b706eddaa9218a19ebcd67b56818f05bb27589b1ca9e8d797b74affad4ccacd4"}, +] +executing = [ + {file = "executing-0.8.3-py2.py3-none-any.whl", hash = "sha256:d1eef132db1b83649a3905ca6dd8897f71ac6f8cac79a7e58a1a09cf137546c9"}, + {file = "executing-0.8.3.tar.gz", hash = "sha256:c6554e21c6b060590a6d3be4b82fb78f8f0194d809de5ea7df1c093763311501"}, ] flask = [ - {file = "Flask-1.1.4-py2.py3-none-any.whl", hash = "sha256:c34f04500f2cbbea882b1acb02002ad6fe6b7ffa64a6164577995657f50aed22"}, - {file = "Flask-1.1.4.tar.gz", hash = "sha256:0fbeb6180d383a9186d0d6ed954e0042ad9f18e0e8de088b2b419d526927d196"}, + {file = "Flask-2.1.1-py3-none-any.whl", hash = "sha256:8a4cf32d904cf5621db9f0c9fbcd7efabf3003f22a04e4d0ce790c7137ec5264"}, + {file = "Flask-2.1.1.tar.gz", hash = "sha256:a8c9bd3e558ec99646d177a9739c41df1ded0629480b4c8d2975412f3c9519c8"}, ] future-fstrings = [ {file = "future_fstrings-1.2.0-py2.py3-none-any.whl", hash = "sha256:90e49598b553d8746c4dc7d9442e0359d038c3039d802c91c0a55505da318c63"}, @@ -451,21 +979,45 @@ idna = [ {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, ] +importlib-metadata = [ + {file = "importlib_metadata-4.11.3-py3-none-any.whl", hash = "sha256:1208431ca90a8cca1a6b8af391bb53c1a2db74e5d1cef6ddced95d4b2062edc6"}, + {file = "importlib_metadata-4.11.3.tar.gz", hash = "sha256:ea4c597ebf37142f827b8f39299579e31685c31d3a438b59f469406afd0f2539"}, +] inflection = [ {file = "inflection-0.5.1-py2.py3-none-any.whl", hash = "sha256:f38b2b640938a4f35ade69ac3d053042959b62a0f1076a5bbaa1b9526605a8a2"}, {file = "inflection-0.5.1.tar.gz", hash = "sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417"}, ] +ipykernel = [ + {file = "ipykernel-6.13.0-py3-none-any.whl", hash = "sha256:2b0987af43c0d4b62cecb13c592755f599f96f29aafe36c01731aaa96df30d39"}, + {file = "ipykernel-6.13.0.tar.gz", hash = "sha256:0e28273e290858393e86e152b104e5506a79c13d25b951ac6eca220051b4be60"}, +] +ipython = [ + {file = "ipython-8.2.0-py3-none-any.whl", hash = "sha256:1b672bfd7a48d87ab203d9af8727a3b0174a4566b4091e9447c22fb63ea32857"}, + {file = "ipython-8.2.0.tar.gz", hash = "sha256:70e5eb132cac594a34b5f799bd252589009905f05104728aea6a403ec2519dc1"}, +] itsdangerous = [ - {file = "itsdangerous-1.1.0-py2.py3-none-any.whl", hash = "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"}, - {file = "itsdangerous-1.1.0.tar.gz", hash = "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19"}, + {file = "itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44"}, + {file = "itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"}, +] +jedi = [ + {file = "jedi-0.18.1-py2.py3-none-any.whl", hash = "sha256:637c9635fcf47945ceb91cd7f320234a7be540ded6f3e99a50cb6febdfd1ba8d"}, + {file = "jedi-0.18.1.tar.gz", hash = "sha256:74137626a64a99c8eb6ae5832d99b3bdd7d29a3850fe2aa80a4126b2a7d949ab"}, ] jinja2 = [ - {file = "Jinja2-2.11.3-py2.py3-none-any.whl", hash = "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419"}, - {file = "Jinja2-2.11.3.tar.gz", hash = "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6"}, + {file = "Jinja2-3.1.1-py3-none-any.whl", hash = "sha256:539835f51a74a69f41b848a9645dbdc35b4f20a3b601e2d9a7e22947b15ff119"}, + {file = "Jinja2-3.1.1.tar.gz", hash = "sha256:640bed4bb501cbd17194b3cace1dc2126f5b619cf068a726b98192a0fde74ae9"}, ] jsonschema = [ - {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, - {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, + {file = "jsonschema-4.4.0-py3-none-any.whl", hash = "sha256:77281a1f71684953ee8b3d488371b162419767973789272434bbc3f29d9c8823"}, + {file = "jsonschema-4.4.0.tar.gz", hash = "sha256:636694eb41b3535ed608fe04129f26542b59ed99808b4f688aa32dcf55317a83"}, +] +jupyter-client = [ + {file = "jupyter_client-7.2.2-py3-none-any.whl", hash = "sha256:44045448eadc12493d819d965eb1dc9d10d1927698adbb9b14eb9a3a4a45ba53"}, + {file = "jupyter_client-7.2.2.tar.gz", hash = "sha256:8fdbad344a8baa6a413d86d25bbf87ce21cb2b4aa5a8e0413863b9754eb8eb8a"}, +] +jupyter-core = [ + {file = "jupyter_core-4.9.2-py3-none-any.whl", hash = "sha256:f875e4d27e202590311d468fa55f90c575f201490bd0c18acabe4e318db4a46d"}, + {file = "jupyter_core-4.9.2.tar.gz", hash = "sha256:d69baeb9ffb128b8cd2657fcf2703f89c769d1673c851812119e3a2a0e93ad9a"}, ] lxml = [ {file = "lxml-4.8.0-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:e1ab2fac607842ac36864e358c42feb0960ae62c34aa4caaf12ada0a1fb5d99b"}, @@ -531,80 +1083,63 @@ lxml = [ {file = "lxml-4.8.0.tar.gz", hash = "sha256:f63f62fc60e6228a4ca9abae28228f35e1bd3ce675013d1dfb828688d50c6e23"}, ] markupsafe = [ - {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-win32.whl", hash = "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"}, - {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-win32.whl", hash = "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-win32.whl", hash = "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-win32.whl", hash = "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-win32.whl", hash = "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"}, + {file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"}, +] +matplotlib-inline = [ + {file = "matplotlib-inline-0.1.3.tar.gz", hash = "sha256:a04bfba22e0d1395479f866853ec1ee28eea1485c1d69a6faf00dc3e24ff34ee"}, + {file = "matplotlib_inline-0.1.3-py3-none-any.whl", hash = "sha256:aed605ba3b72462d64d475a21a9296f400a19c4f74a31b59103d2a99ffd5aa5c"}, ] more-itertools = [ {file = "more-itertools-8.12.0.tar.gz", hash = "sha256:7dc6ad46f05f545f900dd59e8dfb4e84a4827b97b3cfecb175ea0c7d247f6064"}, {file = "more_itertools-8.12.0-py3-none-any.whl", hash = "sha256:43e6dd9942dffd72661a2c4ef383ad7da1e6a3e968a927ad7a6083ab410a688b"}, ] +nest-asyncio = [ + {file = "nest_asyncio-1.5.5-py3-none-any.whl", hash = "sha256:b98e3ec1b246135e4642eceffa5a6c23a3ab12c82ff816a92c612d68205813b2"}, + {file = "nest_asyncio-1.5.5.tar.gz", hash = "sha256:e442291cd942698be619823a17a86a5759eabe1f8613084790de189fe9e16d65"}, +] +networkx = [ + {file = "networkx-2.8-py3-none-any.whl", hash = "sha256:1a1e8fe052cc1b4e0339b998f6795099562a264a13a5af7a32cad45ab9d4e126"}, + {file = "networkx-2.8.tar.gz", hash = "sha256:4a52cf66aed221955420e11b3e2e05ca44196b4829aab9576d4d439212b0a14f"}, +] ordered-set = [ {file = "ordered-set-4.1.0.tar.gz", hash = "sha256:694a8e44c87657c59292ede72891eb91d34131f6531463aab3009191c77364a8"}, {file = "ordered_set-4.1.0-py3-none-any.whl", hash = "sha256:046e1132c71fcf3330438a539928932caf51ddbc582496833e23de611de14562"}, @@ -613,83 +1148,224 @@ packaging = [ {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, ] +parso = [ + {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"}, + {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, +] +pexpect = [ + {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, + {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"}, +] +pickleshare = [ + {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, + {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, +] pluggy = [ {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, ] +prettyprinter = [ + {file = "prettyprinter-0.18.0-py2.py3-none-any.whl", hash = "sha256:358a58f276cb312e3ca29d7a7f244c91e4e0bda7848249d30e4f36d2eb58b67c"}, + {file = "prettyprinter-0.18.0.tar.gz", hash = "sha256:9fe5da7ec53510881dd35d7a5c677ba45f34cfe6a8e78d1abd20652cf82139a8"}, +] +prompt-toolkit = [ + {file = "prompt_toolkit-3.0.29-py3-none-any.whl", hash = "sha256:62291dad495e665fca0bda814e342c69952086afb0f4094d0893d357e5c78752"}, + {file = "prompt_toolkit-3.0.29.tar.gz", hash = "sha256:bd640f60e8cecd74f0dc249713d433ace2ddc62b65ee07f96d358e0b152b6ea7"}, +] +psutil = [ + {file = "psutil-5.9.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:55ce319452e3d139e25d6c3f85a1acf12d1607ddedea5e35fb47a552c051161b"}, + {file = "psutil-5.9.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:7336292a13a80eb93c21f36bde4328aa748a04b68c13d01dfddd67fc13fd0618"}, + {file = "psutil-5.9.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:cb8d10461c1ceee0c25a64f2dd54872b70b89c26419e147a05a10b753ad36ec2"}, + {file = "psutil-5.9.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:7641300de73e4909e5d148e90cc3142fb890079e1525a840cf0dfd39195239fd"}, + {file = "psutil-5.9.0-cp27-none-win32.whl", hash = "sha256:ea42d747c5f71b5ccaa6897b216a7dadb9f52c72a0fe2b872ef7d3e1eacf3ba3"}, + {file = "psutil-5.9.0-cp27-none-win_amd64.whl", hash = "sha256:ef216cc9feb60634bda2f341a9559ac594e2eeaadd0ba187a4c2eb5b5d40b91c"}, + {file = "psutil-5.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90a58b9fcae2dbfe4ba852b57bd4a1dded6b990a33d6428c7614b7d48eccb492"}, + {file = "psutil-5.9.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff0d41f8b3e9ebb6b6110057e40019a432e96aae2008951121ba4e56040b84f3"}, + {file = "psutil-5.9.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:742c34fff804f34f62659279ed5c5b723bb0195e9d7bd9907591de9f8f6558e2"}, + {file = "psutil-5.9.0-cp310-cp310-win32.whl", hash = "sha256:8293942e4ce0c5689821f65ce6522ce4786d02af57f13c0195b40e1edb1db61d"}, + {file = "psutil-5.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:9b51917c1af3fa35a3f2dabd7ba96a2a4f19df3dec911da73875e1edaf22a40b"}, + {file = "psutil-5.9.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e9805fed4f2a81de98ae5fe38b75a74c6e6ad2df8a5c479594c7629a1fe35f56"}, + {file = "psutil-5.9.0-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c51f1af02334e4b516ec221ee26b8fdf105032418ca5a5ab9737e8c87dafe203"}, + {file = "psutil-5.9.0-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32acf55cb9a8cbfb29167cd005951df81b567099295291bcfd1027365b36591d"}, + {file = "psutil-5.9.0-cp36-cp36m-win32.whl", hash = "sha256:e5c783d0b1ad6ca8a5d3e7b680468c9c926b804be83a3a8e95141b05c39c9f64"}, + {file = "psutil-5.9.0-cp36-cp36m-win_amd64.whl", hash = "sha256:d62a2796e08dd024b8179bd441cb714e0f81226c352c802fca0fd3f89eeacd94"}, + {file = "psutil-5.9.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d00a664e31921009a84367266b35ba0aac04a2a6cad09c550a89041034d19a0"}, + {file = "psutil-5.9.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7779be4025c540d1d65a2de3f30caeacc49ae7a2152108adeaf42c7534a115ce"}, + {file = "psutil-5.9.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:072664401ae6e7c1bfb878c65d7282d4b4391f1bc9a56d5e03b5a490403271b5"}, + {file = "psutil-5.9.0-cp37-cp37m-win32.whl", hash = "sha256:df2c8bd48fb83a8408c8390b143c6a6fa10cb1a674ca664954de193fdcab36a9"}, + {file = "psutil-5.9.0-cp37-cp37m-win_amd64.whl", hash = "sha256:1d7b433519b9a38192dfda962dd8f44446668c009833e1429a52424624f408b4"}, + {file = "psutil-5.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c3400cae15bdb449d518545cbd5b649117de54e3596ded84aacabfbb3297ead2"}, + {file = "psutil-5.9.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2237f35c4bbae932ee98902a08050a27821f8f6dfa880a47195e5993af4702d"}, + {file = "psutil-5.9.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1070a9b287846a21a5d572d6dddd369517510b68710fca56b0e9e02fd24bed9a"}, + {file = "psutil-5.9.0-cp38-cp38-win32.whl", hash = "sha256:76cebf84aac1d6da5b63df11fe0d377b46b7b500d892284068bacccf12f20666"}, + {file = "psutil-5.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:3151a58f0fbd8942ba94f7c31c7e6b310d2989f4da74fcbf28b934374e9bf841"}, + {file = "psutil-5.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:539e429da49c5d27d5a58e3563886057f8fc3868a5547b4f1876d9c0f007bccf"}, + {file = "psutil-5.9.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58c7d923dc209225600aec73aa2c4ae8ea33b1ab31bc11ef8a5933b027476f07"}, + {file = "psutil-5.9.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3611e87eea393f779a35b192b46a164b1d01167c9d323dda9b1e527ea69d697d"}, + {file = "psutil-5.9.0-cp39-cp39-win32.whl", hash = "sha256:4e2fb92e3aeae3ec3b7b66c528981fd327fb93fd906a77215200404444ec1845"}, + {file = "psutil-5.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:7d190ee2eaef7831163f254dc58f6d2e2a22e27382b936aab51c835fc080c3d3"}, + {file = "psutil-5.9.0.tar.gz", hash = "sha256:869842dbd66bb80c3217158e629d6fceaecc3a3166d3d1faee515b05dd26ca25"}, +] +ptyprocess = [ + {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, + {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, +] +pure-eval = [ + {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"}, + {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"}, +] py = [ {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, ] +pycparser = [ + {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, + {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, +] pyecore = [ {file = "pyecore-0.12.2-py3-none-any.whl", hash = "sha256:8ebbefea2fcb97602ddb9eb859ae15d7c0900231128da92e10b7f9a9e1a29b76"}, {file = "pyecore-0.12.2.tar.gz", hash = "sha256:4fb417df37fc5433da37f3d42724f7c4cc36cbbe63988f3e43ad7653e0808387"}, ] +pygments = [ + {file = "Pygments-2.11.2-py3-none-any.whl", hash = "sha256:44238f1b60a76d78fc8ca0528ee429702aae011c265fe6a8dd8b63049ae41c65"}, + {file = "Pygments-2.11.2.tar.gz", hash = "sha256:4e426f72023d88d03b2fa258de560726ce890ff3b630f88c21cbb8b2503b8c6a"}, +] pyparsing = [ - {file = "pyparsing-3.0.6-py3-none-any.whl", hash = "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4"}, - {file = "pyparsing-3.0.6.tar.gz", hash = "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81"}, + {file = "pyparsing-3.0.8-py3-none-any.whl", hash = "sha256:ef7b523f6356f763771559412c0d7134753f037822dad1b16945b7b846f7ad06"}, + {file = "pyparsing-3.0.8.tar.gz", hash = "sha256:7bf433498c016c4314268d95df76c81b842a4cb2b276fa3312cfb1e1d85f6954"}, ] pyrsistent = [ - {file = "pyrsistent-0.18.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f4c8cabb46ff8e5d61f56a037974228e978f26bfefce4f61a4b1ac0ba7a2ab72"}, - {file = "pyrsistent-0.18.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:da6e5e818d18459fa46fac0a4a4e543507fe1110e808101277c5a2b5bab0cd2d"}, - {file = "pyrsistent-0.18.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:5e4395bbf841693eaebaa5bb5c8f5cdbb1d139e07c975c682ec4e4f8126e03d2"}, - {file = "pyrsistent-0.18.0-cp36-cp36m-win32.whl", hash = "sha256:527be2bfa8dc80f6f8ddd65242ba476a6c4fb4e3aedbf281dfbac1b1ed4165b1"}, - {file = "pyrsistent-0.18.0-cp36-cp36m-win_amd64.whl", hash = "sha256:2aaf19dc8ce517a8653746d98e962ef480ff34b6bc563fc067be6401ffb457c7"}, - {file = "pyrsistent-0.18.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58a70d93fb79dc585b21f9d72487b929a6fe58da0754fa4cb9f279bb92369396"}, - {file = "pyrsistent-0.18.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4916c10896721e472ee12c95cdc2891ce5890898d2f9907b1b4ae0f53588b710"}, - {file = "pyrsistent-0.18.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:73ff61b1411e3fb0ba144b8f08d6749749775fe89688093e1efef9839d2dcc35"}, - {file = "pyrsistent-0.18.0-cp37-cp37m-win32.whl", hash = "sha256:b29b869cf58412ca5738d23691e96d8aff535e17390128a1a52717c9a109da4f"}, - {file = "pyrsistent-0.18.0-cp37-cp37m-win_amd64.whl", hash = "sha256:097b96f129dd36a8c9e33594e7ebb151b1515eb52cceb08474c10a5479e799f2"}, - {file = "pyrsistent-0.18.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:772e94c2c6864f2cd2ffbe58bb3bdefbe2a32afa0acb1a77e472aac831f83427"}, - {file = "pyrsistent-0.18.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:c1a9ff320fa699337e05edcaae79ef8c2880b52720bc031b219e5b5008ebbdef"}, - {file = "pyrsistent-0.18.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:cd3caef37a415fd0dae6148a1b6957a8c5f275a62cca02e18474608cb263640c"}, - {file = "pyrsistent-0.18.0-cp38-cp38-win32.whl", hash = "sha256:e79d94ca58fcafef6395f6352383fa1a76922268fa02caa2272fff501c2fdc78"}, - {file = "pyrsistent-0.18.0-cp38-cp38-win_amd64.whl", hash = "sha256:a0c772d791c38bbc77be659af29bb14c38ced151433592e326361610250c605b"}, - {file = "pyrsistent-0.18.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d5ec194c9c573aafaceebf05fc400656722793dac57f254cd4741f3c27ae57b4"}, - {file = "pyrsistent-0.18.0-cp39-cp39-manylinux1_i686.whl", hash = "sha256:6b5eed00e597b5b5773b4ca30bd48a5774ef1e96f2a45d105db5b4ebb4bca680"}, - {file = "pyrsistent-0.18.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:48578680353f41dca1ca3dc48629fb77dfc745128b56fc01096b2530c13fd426"}, - {file = "pyrsistent-0.18.0-cp39-cp39-win32.whl", hash = "sha256:f3ef98d7b76da5eb19c37fda834d50262ff9167c65658d1d8f974d2e4d90676b"}, - {file = "pyrsistent-0.18.0-cp39-cp39-win_amd64.whl", hash = "sha256:404e1f1d254d314d55adb8d87f4f465c8693d6f902f67eb6ef5b4526dc58e6ea"}, - {file = "pyrsistent-0.18.0.tar.gz", hash = "sha256:773c781216f8c2900b42a7b638d5b517bb134ae1acbebe4d1e8f1f41ea60eb4b"}, + {file = "pyrsistent-0.18.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:df46c854f490f81210870e509818b729db4488e1f30f2a1ce1698b2295a878d1"}, + {file = "pyrsistent-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d45866ececf4a5fff8742c25722da6d4c9e180daa7b405dc0a2a2790d668c26"}, + {file = "pyrsistent-0.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4ed6784ceac462a7d6fcb7e9b663e93b9a6fb373b7f43594f9ff68875788e01e"}, + {file = "pyrsistent-0.18.1-cp310-cp310-win32.whl", hash = "sha256:e4f3149fd5eb9b285d6bfb54d2e5173f6a116fe19172686797c056672689daf6"}, + {file = "pyrsistent-0.18.1-cp310-cp310-win_amd64.whl", hash = "sha256:636ce2dc235046ccd3d8c56a7ad54e99d5c1cd0ef07d9ae847306c91d11b5fec"}, + {file = "pyrsistent-0.18.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e92a52c166426efbe0d1ec1332ee9119b6d32fc1f0bbfd55d5c1088070e7fc1b"}, + {file = "pyrsistent-0.18.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7a096646eab884bf8bed965bad63ea327e0d0c38989fc83c5ea7b8a87037bfc"}, + {file = "pyrsistent-0.18.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cdfd2c361b8a8e5d9499b9082b501c452ade8bbf42aef97ea04854f4a3f43b22"}, + {file = "pyrsistent-0.18.1-cp37-cp37m-win32.whl", hash = "sha256:7ec335fc998faa4febe75cc5268a9eac0478b3f681602c1f27befaf2a1abe1d8"}, + {file = "pyrsistent-0.18.1-cp37-cp37m-win_amd64.whl", hash = "sha256:6455fc599df93d1f60e1c5c4fe471499f08d190d57eca040c0ea182301321286"}, + {file = "pyrsistent-0.18.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fd8da6d0124efa2f67d86fa70c851022f87c98e205f0594e1fae044e7119a5a6"}, + {file = "pyrsistent-0.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bfe2388663fd18bd8ce7db2c91c7400bf3e1a9e8bd7d63bf7e77d39051b85ec"}, + {file = "pyrsistent-0.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e3e1fcc45199df76053026a51cc59ab2ea3fc7c094c6627e93b7b44cdae2c8c"}, + {file = "pyrsistent-0.18.1-cp38-cp38-win32.whl", hash = "sha256:b568f35ad53a7b07ed9b1b2bae09eb15cdd671a5ba5d2c66caee40dbf91c68ca"}, + {file = "pyrsistent-0.18.1-cp38-cp38-win_amd64.whl", hash = "sha256:d1b96547410f76078eaf66d282ddca2e4baae8964364abb4f4dcdde855cd123a"}, + {file = "pyrsistent-0.18.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f87cc2863ef33c709e237d4b5f4502a62a00fab450c9e020892e8e2ede5847f5"}, + {file = "pyrsistent-0.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bc66318fb7ee012071b2792024564973ecc80e9522842eb4e17743604b5e045"}, + {file = "pyrsistent-0.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:914474c9f1d93080338ace89cb2acee74f4f666fb0424896fcfb8d86058bf17c"}, + {file = "pyrsistent-0.18.1-cp39-cp39-win32.whl", hash = "sha256:1b34eedd6812bf4d33814fca1b66005805d3640ce53140ab8bbb1e2651b0d9bc"}, + {file = "pyrsistent-0.18.1-cp39-cp39-win_amd64.whl", hash = "sha256:e24a828f57e0c337c8d8bb9f6b12f09dfdf0273da25fda9e314f0b684b415a07"}, + {file = "pyrsistent-0.18.1.tar.gz", hash = "sha256:d4d61f8b993a7255ba714df3aca52700f8125289f84f704cf80916517c46eb96"}, ] pytest = [ {file = "pytest-5.4.3-py3-none-any.whl", hash = "sha256:5c0db86b698e8f170ba4582a492248919255fcd4c79b1ee64ace34301fb589a1"}, {file = "pytest-5.4.3.tar.gz", hash = "sha256:7979331bfcba207414f5e1263b5a0f8f521d0f457318836a7355531ed1a4c7d8"}, ] +python-dateutil = [ + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, +] +pywin32 = [ + {file = "pywin32-303-cp310-cp310-win32.whl", hash = "sha256:6fed4af057039f309263fd3285d7b8042d41507343cd5fa781d98fcc5b90e8bb"}, + {file = "pywin32-303-cp310-cp310-win_amd64.whl", hash = "sha256:51cb52c5ec6709f96c3f26e7795b0bf169ee0d8395b2c1d7eb2c029a5008ed51"}, + {file = "pywin32-303-cp311-cp311-win32.whl", hash = "sha256:d9b5d87ca944eb3aa4cd45516203ead4b37ab06b8b777c54aedc35975dec0dee"}, + {file = "pywin32-303-cp311-cp311-win_amd64.whl", hash = "sha256:fcf44032f5b14fcda86028cdf49b6ebdaea091230eb0a757282aa656e4732439"}, + {file = "pywin32-303-cp36-cp36m-win32.whl", hash = "sha256:aad484d52ec58008ca36bd4ad14a71d7dd0a99db1a4ca71072213f63bf49c7d9"}, + {file = "pywin32-303-cp36-cp36m-win_amd64.whl", hash = "sha256:2a09632916b6bb231ba49983fe989f2f625cea237219530e81a69239cd0c4559"}, + {file = "pywin32-303-cp37-cp37m-win32.whl", hash = "sha256:b1675d82bcf6dbc96363fca747bac8bff6f6e4a447a4287ac652aa4b9adc796e"}, + {file = "pywin32-303-cp37-cp37m-win_amd64.whl", hash = "sha256:c268040769b48a13367221fced6d4232ed52f044ffafeda247bd9d2c6bdc29ca"}, + {file = "pywin32-303-cp38-cp38-win32.whl", hash = "sha256:5f9ec054f5a46a0f4dfd72af2ce1372f3d5a6e4052af20b858aa7df2df7d355b"}, + {file = "pywin32-303-cp38-cp38-win_amd64.whl", hash = "sha256:793bf74fce164bcffd9d57bb13c2c15d56e43c9542a7b9687b4fccf8f8a41aba"}, + {file = "pywin32-303-cp39-cp39-win32.whl", hash = "sha256:7d3271c98434617a11921c5ccf74615794d97b079e22ed7773790822735cc352"}, + {file = "pywin32-303-cp39-cp39-win_amd64.whl", hash = "sha256:79cbb862c11b9af19bcb682891c1b91942ec2ff7de8151e2aea2e175899cda34"}, +] pyyaml = [ - {file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"}, - {file = "PyYAML-5.4.1-cp27-cp27m-win32.whl", hash = "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393"}, - {file = "PyYAML-5.4.1-cp27-cp27m-win_amd64.whl", hash = "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8"}, - {file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"}, - {file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"}, - {file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"}, - {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347"}, - {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541"}, - {file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"}, - {file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"}, - {file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"}, - {file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"}, - {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa"}, - {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0"}, - {file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"}, - {file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"}, - {file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"}, - {file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"}, - {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247"}, - {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc"}, - {file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"}, - {file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"}, - {file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"}, - {file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"}, - {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122"}, - {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6"}, - {file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"}, - {file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"}, - {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"}, + {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, + {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, + {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, + {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, + {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, + {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, + {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, + {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, + {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, + {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, + {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, + {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, + {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, + {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, + {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, + {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, + {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, + {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, +] +pyzmq = [ + {file = "pyzmq-22.3.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:6b217b8f9dfb6628f74b94bdaf9f7408708cb02167d644edca33f38746ca12dd"}, + {file = "pyzmq-22.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2841997a0d85b998cbafecb4183caf51fd19c4357075dfd33eb7efea57e4c149"}, + {file = "pyzmq-22.3.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f89468059ebc519a7acde1ee50b779019535db8dcf9b8c162ef669257fef7a93"}, + {file = "pyzmq-22.3.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea12133df25e3a6918718fbb9a510c6ee5d3fdd5a346320421aac3882f4feeea"}, + {file = "pyzmq-22.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76c532fd68b93998aab92356be280deec5de8f8fe59cd28763d2cc8a58747b7f"}, + {file = "pyzmq-22.3.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:f907c7359ce8bf7f7e63c82f75ad0223384105f5126f313400b7e8004d9b33c3"}, + {file = "pyzmq-22.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:902319cfe23366595d3fa769b5b751e6ee6750a0a64c5d9f757d624b2ac3519e"}, + {file = "pyzmq-22.3.0-cp310-cp310-win32.whl", hash = "sha256:67db33bea0a29d03e6eeec55a8190e033318cee3cbc732ba8fd939617cbf762d"}, + {file = "pyzmq-22.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:7661fc1d5cb73481cf710a1418a4e1e301ed7d5d924f91c67ba84b2a1b89defd"}, + {file = "pyzmq-22.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:79244b9e97948eaf38695f4b8e6fc63b14b78cc37f403c6642ba555517ac1268"}, + {file = "pyzmq-22.3.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab888624ed68930442a3f3b0b921ad7439c51ba122dbc8c386e6487a658e4a4e"}, + {file = "pyzmq-22.3.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:18cd854b423fce44951c3a4d3e686bac8f1243d954f579e120a1714096637cc0"}, + {file = "pyzmq-22.3.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:de8df0684398bd74ad160afdc2a118ca28384ac6f5e234eb0508858d8d2d9364"}, + {file = "pyzmq-22.3.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:62bcade20813796c426409a3e7423862d50ff0639f5a2a95be4b85b09a618666"}, + {file = "pyzmq-22.3.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:ea5a79e808baef98c48c884effce05c31a0698c1057de8fc1c688891043c1ce1"}, + {file = "pyzmq-22.3.0-cp36-cp36m-win32.whl", hash = "sha256:3c1895c95be92600233e476fe283f042e71cf8f0b938aabf21b7aafa62a8dac9"}, + {file = "pyzmq-22.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:851977788b9caa8ed011f5f643d3ee8653af02c5fc723fa350db5125abf2be7b"}, + {file = "pyzmq-22.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b4ebed0977f92320f6686c96e9e8dd29eed199eb8d066936bac991afc37cbb70"}, + {file = "pyzmq-22.3.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42abddebe2c6a35180ca549fadc7228d23c1e1f76167c5ebc8a936b5804ea2df"}, + {file = "pyzmq-22.3.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c1e41b32d6f7f9c26bc731a8b529ff592f31fc8b6ef2be9fa74abd05c8a342d7"}, + {file = "pyzmq-22.3.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:be4e0f229cf3a71f9ecd633566bd6f80d9fa6afaaff5489492be63fe459ef98c"}, + {file = "pyzmq-22.3.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:08c4e315a76ef26eb833511ebf3fa87d182152adf43dedee8d79f998a2162a0b"}, + {file = "pyzmq-22.3.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:badb868fff14cfd0e200eaa845887b1011146a7d26d579aaa7f966c203736b92"}, + {file = "pyzmq-22.3.0-cp37-cp37m-win32.whl", hash = "sha256:7c58f598d9fcc52772b89a92d72bf8829c12d09746a6d2c724c5b30076c1f11d"}, + {file = "pyzmq-22.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:2b97502c16a5ec611cd52410bdfaab264997c627a46b0f98d3f666227fd1ea2d"}, + {file = "pyzmq-22.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d728b08448e5ac3e4d886b165385a262883c34b84a7fe1166277fe675e1c197a"}, + {file = "pyzmq-22.3.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:480b9931bfb08bf8b094edd4836271d4d6b44150da051547d8c7113bf947a8b0"}, + {file = "pyzmq-22.3.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7dc09198e4073e6015d9a8ea093fc348d4e59de49382476940c3dd9ae156fba8"}, + {file = "pyzmq-22.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ca6cd58f62a2751728016d40082008d3b3412a7f28ddfb4a2f0d3c130f69e74"}, + {file = "pyzmq-22.3.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:468bd59a588e276961a918a3060948ae68f6ff5a7fa10bb2f9160c18fe341067"}, + {file = "pyzmq-22.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c88fa7410e9fc471e0858638f403739ee869924dd8e4ae26748496466e27ac59"}, + {file = "pyzmq-22.3.0-cp38-cp38-win32.whl", hash = "sha256:c0f84360dcca3481e8674393bdf931f9f10470988f87311b19d23cda869bb6b7"}, + {file = "pyzmq-22.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:f762442bab706fd874064ca218b33a1d8e40d4938e96c24dafd9b12e28017f45"}, + {file = "pyzmq-22.3.0-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:954e73c9cd4d6ae319f1c936ad159072b6d356a92dcbbabfd6e6204b9a79d356"}, + {file = "pyzmq-22.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f43b4a2e6218371dd4f41e547bd919ceeb6ebf4abf31a7a0669cd11cd91ea973"}, + {file = "pyzmq-22.3.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:acebba1a23fb9d72b42471c3771b6f2f18dcd46df77482612054bd45c07dfa36"}, + {file = "pyzmq-22.3.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cf98fd7a6c8aaa08dbc699ffae33fd71175696d78028281bc7b832b26f00ca57"}, + {file = "pyzmq-22.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d072f7dfbdb184f0786d63bda26e8a0882041b1e393fbe98940395f7fab4c5e2"}, + {file = "pyzmq-22.3.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:53f4fd13976789ffafedd4d46f954c7bb01146121812b72b4ddca286034df966"}, + {file = "pyzmq-22.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d1b5d457acbadcf8b27561deeaa386b0217f47626b29672fa7bd31deb6e91e1b"}, + {file = "pyzmq-22.3.0-cp39-cp39-win32.whl", hash = "sha256:e6a02cf7271ee94674a44f4e62aa061d2d049001c844657740e156596298b70b"}, + {file = "pyzmq-22.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:d3dcb5548ead4f1123851a5ced467791f6986d68c656bc63bfff1bf9e36671e2"}, + {file = "pyzmq-22.3.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3a4c9886d61d386b2b493377d980f502186cd71d501fffdba52bd2a0880cef4f"}, + {file = "pyzmq-22.3.0-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:80e043a89c6cadefd3a0712f8a1322038e819ebe9dbac7eca3bce1721bcb63bf"}, + {file = "pyzmq-22.3.0-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1621e7a2af72cced1f6ec8ca8ca91d0f76ac236ab2e8828ac8fe909512d566cb"}, + {file = "pyzmq-22.3.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:d6157793719de168b199194f6b6173f0ccd3bf3499e6870fac17086072e39115"}, + {file = "pyzmq-22.3.0.tar.gz", hash = "sha256:8eddc033e716f8c91c6a2112f0a8ebc5e00532b4a6ae1eb0ccc48e027f9c671c"}, ] requests = [ - {file = "requests-2.26.0-py2.py3-none-any.whl", hash = "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24"}, - {file = "requests-2.26.0.tar.gz", hash = "sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7"}, + {file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"}, + {file = "requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"}, ] restrictedpython = [ {file = "RestrictedPython-5.0-py2.py3-none-any.whl", hash = "sha256:9bd69505147b0ff8c68f4ff5a275975a3ab66fc43cbf3b61a195650ed767cd4e"}, @@ -699,13 +1375,64 @@ six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] +stack-data = [ + {file = "stack_data-0.2.0-py3-none-any.whl", hash = "sha256:999762f9c3132308789affa03e9271bbbe947bf78311851f4d485d8402ed858e"}, + {file = "stack_data-0.2.0.tar.gz", hash = "sha256:45692d41bd633a9503a5195552df22b583caf16f0b27c4e58c98d88c8b648e12"}, +] swagger-ui-bundle = [ {file = "swagger_ui_bundle-0.0.9-py3-none-any.whl", hash = "sha256:cea116ed81147c345001027325c1ddc9ca78c1ee7319935c3c75d3669279d575"}, {file = "swagger_ui_bundle-0.0.9.tar.gz", hash = "sha256:b462aa1460261796ab78fd4663961a7f6f347ce01760f1303bbbdf630f11f516"}, ] +tornado = [ + {file = "tornado-6.1-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:d371e811d6b156d82aa5f9a4e08b58debf97c302a35714f6f45e35139c332e32"}, + {file = "tornado-6.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:0d321a39c36e5f2c4ff12b4ed58d41390460f798422c4504e09eb5678e09998c"}, + {file = "tornado-6.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9de9e5188a782be6b1ce866e8a51bc76a0fbaa0e16613823fc38e4fc2556ad05"}, + {file = "tornado-6.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:61b32d06ae8a036a6607805e6720ef00a3c98207038444ba7fd3d169cd998910"}, + {file = "tornado-6.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:3e63498f680547ed24d2c71e6497f24bca791aca2fe116dbc2bd0ac7f191691b"}, + {file = "tornado-6.1-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:6c77c9937962577a6a76917845d06af6ab9197702a42e1346d8ae2e76b5e3675"}, + {file = "tornado-6.1-cp35-cp35m-win32.whl", hash = "sha256:6286efab1ed6e74b7028327365cf7346b1d777d63ab30e21a0f4d5b275fc17d5"}, + {file = "tornado-6.1-cp35-cp35m-win_amd64.whl", hash = "sha256:fa2ba70284fa42c2a5ecb35e322e68823288a4251f9ba9cc77be04ae15eada68"}, + {file = "tornado-6.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:0a00ff4561e2929a2c37ce706cb8233b7907e0cdc22eab98888aca5dd3775feb"}, + {file = "tornado-6.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:748290bf9112b581c525e6e6d3820621ff020ed95af6f17fedef416b27ed564c"}, + {file = "tornado-6.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:e385b637ac3acaae8022e7e47dfa7b83d3620e432e3ecb9a3f7f58f150e50921"}, + {file = "tornado-6.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:25ad220258349a12ae87ede08a7b04aca51237721f63b1808d39bdb4b2164558"}, + {file = "tornado-6.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:65d98939f1a2e74b58839f8c4dab3b6b3c1ce84972ae712be02845e65391ac7c"}, + {file = "tornado-6.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:e519d64089b0876c7b467274468709dadf11e41d65f63bba207e04217f47c085"}, + {file = "tornado-6.1-cp36-cp36m-win32.whl", hash = "sha256:b87936fd2c317b6ee08a5741ea06b9d11a6074ef4cc42e031bc6403f82a32575"}, + {file = "tornado-6.1-cp36-cp36m-win_amd64.whl", hash = "sha256:cc0ee35043162abbf717b7df924597ade8e5395e7b66d18270116f8745ceb795"}, + {file = "tornado-6.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7250a3fa399f08ec9cb3f7b1b987955d17e044f1ade821b32e5f435130250d7f"}, + {file = "tornado-6.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:ed3ad863b1b40cd1d4bd21e7498329ccaece75db5a5bf58cd3c9f130843e7102"}, + {file = "tornado-6.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:dcef026f608f678c118779cd6591c8af6e9b4155c44e0d1bc0c87c036fb8c8c4"}, + {file = "tornado-6.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:70dec29e8ac485dbf57481baee40781c63e381bebea080991893cd297742b8fd"}, + {file = "tornado-6.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:d3f7594930c423fd9f5d1a76bee85a2c36fd8b4b16921cae7e965f22575e9c01"}, + {file = "tornado-6.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:3447475585bae2e77ecb832fc0300c3695516a47d46cefa0528181a34c5b9d3d"}, + {file = "tornado-6.1-cp37-cp37m-win32.whl", hash = "sha256:e7229e60ac41a1202444497ddde70a48d33909e484f96eb0da9baf8dc68541df"}, + {file = "tornado-6.1-cp37-cp37m-win_amd64.whl", hash = "sha256:cb5ec8eead331e3bb4ce8066cf06d2dfef1bfb1b2a73082dfe8a161301b76e37"}, + {file = "tornado-6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:20241b3cb4f425e971cb0a8e4ffc9b0a861530ae3c52f2b0434e6c1b57e9fd95"}, + {file = "tornado-6.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:c77da1263aa361938476f04c4b6c8916001b90b2c2fdd92d8d535e1af48fba5a"}, + {file = "tornado-6.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:fba85b6cd9c39be262fcd23865652920832b61583de2a2ca907dbd8e8a8c81e5"}, + {file = "tornado-6.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:1e8225a1070cd8eec59a996c43229fe8f95689cb16e552d130b9793cb570a288"}, + {file = "tornado-6.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:d14d30e7f46a0476efb0deb5b61343b1526f73ebb5ed84f23dc794bdb88f9d9f"}, + {file = "tornado-6.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:8f959b26f2634a091bb42241c3ed8d3cedb506e7c27b8dd5c7b9f745318ddbb6"}, + {file = "tornado-6.1-cp38-cp38-win32.whl", hash = "sha256:34ca2dac9e4d7afb0bed4677512e36a52f09caa6fded70b4e3e1c89dbd92c326"}, + {file = "tornado-6.1-cp38-cp38-win_amd64.whl", hash = "sha256:6196a5c39286cc37c024cd78834fb9345e464525d8991c21e908cc046d1cc02c"}, + {file = "tornado-6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0ba29bafd8e7e22920567ce0d232c26d4d47c8b5cf4ed7b562b5db39fa199c5"}, + {file = "tornado-6.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:33892118b165401f291070100d6d09359ca74addda679b60390b09f8ef325ffe"}, + {file = "tornado-6.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7da13da6f985aab7f6f28debab00c67ff9cbacd588e8477034c0652ac141feea"}, + {file = "tornado-6.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:e0791ac58d91ac58f694d8d2957884df8e4e2f6687cdf367ef7eb7497f79eaa2"}, + {file = "tornado-6.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:66324e4e1beede9ac79e60f88de548da58b1f8ab4b2f1354d8375774f997e6c0"}, + {file = "tornado-6.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:a48900ecea1cbb71b8c71c620dee15b62f85f7c14189bdeee54966fbd9a0c5bd"}, + {file = "tornado-6.1-cp39-cp39-win32.whl", hash = "sha256:d3d20ea5782ba63ed13bc2b8c291a053c8d807a8fa927d941bd718468f7b950c"}, + {file = "tornado-6.1-cp39-cp39-win_amd64.whl", hash = "sha256:548430be2740e327b3fe0201abe471f314741efcb0067ec4f2d7dcfb4825f3e4"}, + {file = "tornado-6.1.tar.gz", hash = "sha256:33c6e81d7bd55b468d2e793517c909b139960b6c790a60b7991b9b6b76fb9791"}, +] +traitlets = [ + {file = "traitlets-5.1.1-py3-none-any.whl", hash = "sha256:2d313cc50a42cd6c277e7d7dc8d4d7fedd06a2c215f78766ae7b1a66277e0033"}, + {file = "traitlets-5.1.1.tar.gz", hash = "sha256:059f456c5a7c1c82b98c2e8c799f39c9b8128f6d0d46941ee118daace9eb70c7"}, +] urllib3 = [ - {file = "urllib3-1.26.7-py2.py3-none-any.whl", hash = "sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844"}, - {file = "urllib3-1.26.7.tar.gz", hash = "sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece"}, + {file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"}, + {file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"}, ] uwsgi = [ {file = "uwsgi-2.0.20.tar.gz", hash = "sha256:88ab9867d8973d8ae84719cf233b7dafc54326fcaec89683c3f9f77c002cdff9"}, @@ -715,6 +1442,17 @@ wcwidth = [ {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, ] werkzeug = [ - {file = "Werkzeug-1.0.1-py2.py3-none-any.whl", hash = "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43"}, - {file = "Werkzeug-1.0.1.tar.gz", hash = "sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c"}, + {file = "Werkzeug-2.1.1-py3-none-any.whl", hash = "sha256:3c5493ece8268fecdcdc9c0b112211acd006354723b280d643ec732b6d4063d6"}, + {file = "Werkzeug-2.1.1.tar.gz", hash = "sha256:f8e89a20aeabbe8a893c24a461d3ee5dad2123b05cc6abd73ceed01d39c3ae74"}, +] +z3-solver = [ + {file = "z3-solver-4.8.15.0.tar.gz", hash = "sha256:4f1612fcca67eba92bb1752182e6e659d0607ae5d88d8db99a07451ed7f8ff49"}, + {file = "z3_solver-4.8.15.0-py2.py3-none-macosx_10_16_x86_64.whl", hash = "sha256:f260b46db33a11d09d2a4bc720f418ca8059b9b59a392cc9e0d985e3dd4dc821"}, + {file = "z3_solver-4.8.15.0-py2.py3-none-manylinux1_x86_64.whl", hash = "sha256:e743cf7e4f553a56fb26851555d1a5f1cbbadffcce2fa812f7cc997814cbdfc0"}, + {file = "z3_solver-4.8.15.0-py2.py3-none-win32.whl", hash = "sha256:9916cc09dbae7e3d69b1fe2ce193a3e8ac17172795b56a11456c9452239792c6"}, + {file = "z3_solver-4.8.15.0-py2.py3-none-win_amd64.whl", hash = "sha256:3a7918ff81d3af833cfda07925e6b14b9c851e2794cf69fc7353baaf5ae3e031"}, +] +zipp = [ + {file = "zipp-3.8.0-py3-none-any.whl", hash = "sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099"}, + {file = "zipp-3.8.0.tar.gz", hash = "sha256:56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad"}, ] diff --git a/pyproject.toml b/pyproject.toml index 992fc4b79fa3b9eaa4606cc14a01bc1ee2cfb8f7..415df653a8ff9993988f14b5327045e333947883 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,18 +2,23 @@ name = "mc_openapi" version = "0.1.0" description = "OpenAPI interface for the PIACERE DOML model checker." -authors = ["Michele Chiari <michele.chiari@polimi.it>"] +authors = ["Michele Chiari <michele.chiari@polimi.it>", "Michele De Pascalis <michele.de.pascalis.1024@gmail.com>"] license = "Apache-2.0" [tool.poetry.dependencies] -python = "^3.8" +python = "^3.9" connexion = {extras = ["swagger-ui"], version = "^2.9.0"} uWSGI = "^2.0.20" pyecore = "^0.12.2" +z3-solver = "^4.8.15" +PyYAML = "^6.0" +networkx = "^2.7.1" [tool.poetry.dev-dependencies] pytest = "^5.2" requests = "^2.26.0" +ipykernel = "^6.12.1" +prettyprinter = "^0.18.0" [build-system] requires = ["poetry-core>=1.0.0"] diff --git a/tests/doml/nginx-openstack_v2_wrong.domlx b/tests/doml/nginx-openstack_v2_wrong.domlx index 70276c9fa13a283a9ab06fd88adc2a5849d49bf3..8aaa96b565829b42c1cbdd53fc6ea514f9a1ce25 100644 --- a/tests/doml/nginx-openstack_v2_wrong.domlx +++ b/tests/doml/nginx-openstack_v2_wrong.domlx @@ -7,12 +7,10 @@ </application> <infrastructure name="infra"> <nodes xsi:type="infra:AutoScalingGroup" name="ag" deploymentNetwork="//@infrastructure/@networks.0"> - <machineDefinition name="vm1" credentials="//@infrastructure/@credentials.0" group="//@infrastructure/@secGroups.0" generatedFrom="//@infrastructure/@generators.0"> - <ifaces name="i1" endPoint="16.0.0.1" /> - </machineDefinition> + <machineDefinition name="vm1" credentials="//@infrastructure/@credentials.0" group="//@infrastructure/@secGroups.0" generatedFrom="//@infrastructure/@generators.0" /> </nodes> <networks name="net1" protocol="tcp/ip" addressRange="16.0.0.0/24" /> - <secGroups name="sg" groupedNodes="//@infrastructure/@nodes.0/@machineDefinition" ifaces="//@infrastructure/@nodes.0/@machineDefinition/@ifaces.0"> + <secGroups name="sg" groupedNodes="//@infrastructure/@nodes.0/@machineDefinition"> <rules name="out_all" protocol="-1" fromPort="0" toPort="0"> <addressRanges>0.0.0.0/0</addressRanges> <addressRanges>::/0</addressRanges> diff --git a/tests/test_mc_openapi.py b/tests/test_mc_openapi.py index ce51dce8c9a1dd953cba51414e8a5e2ba3129736..7536bfacb730732aa3203f3675a8b1a78e7a4552 100644 --- a/tests/test_mc_openapi.py +++ b/tests/test_mc_openapi.py @@ -1,10 +1,11 @@ from mc_openapi import __version__ import requests -import json + def test_version(): assert __version__ == '0.1.0' + def test_post_sat(): with open("tests/doml/nginx-openstack_v2.domlx", "r") as f: doml = f.read() @@ -15,6 +16,7 @@ def test_post_sat(): assert payload["result"] is not None assert payload["result"] == "sat" + def test_post_unsat(): with open("tests/doml/nginx-openstack_v2_wrong.domlx", "r") as f: doml = f.read()