diff --git a/cmd/npm/npm.go b/cmd/npm/npm.go
index e89dc36..5e8f86f 100644
--- a/cmd/npm/npm.go
+++ b/cmd/npm/npm.go
@@ -4,6 +4,7 @@ import (
 	"context"
 
 	"github.com/safedep/dry/log"
+	"github.com/safedep/pmg/config"
 	"github.com/safedep/pmg/internal/flows"
 	"github.com/safedep/pmg/internal/ui"
 	"github.com/safedep/pmg/packagemanager"
@@ -31,6 +32,20 @@ func executeNpmFlow(ctx context.Context, args []string) error {
 	if err != nil {
 		ui.Fatalf("Failed to create npm package manager proxy: %s", err)
 	}
+	config, err := config.FromContext(ctx)
+	if err != nil {
+		ui.Fatalf("Failed to get config: %s", err)
+	}
+
+	packageResolverConfig := packagemanager.NewDefaultNpmDependencyResolverConfig()
+	packageResolverConfig.IncludeTransitiveDependencies = config.Transitive
+	packageResolverConfig.TransitiveDepth = config.TransitiveDepth
+	packageResolverConfig.IncludeDevDependencies = config.IncludeDevDependencies
+
+	packageResolver, err := packagemanager.NewNpmDependencyResolver(packageResolverConfig)
+	if err != nil {
+		ui.Fatalf("Failed to create dependency resolver: %s", err)
+	}
 
-	return flows.Common(packageManager).Run(ctx, args)
+	return flows.Common(packageManager, packageResolver, config).Run(ctx, args)
 }
diff --git a/cmd/npm/pnpm.go b/cmd/npm/pnpm.go
index c161c0d..a010244 100644
--- a/cmd/npm/pnpm.go
+++ b/cmd/npm/pnpm.go
@@ -5,6 +5,7 @@ import (
 	_ "embed"
 
 	"github.com/safedep/dry/log"
+	"github.com/safedep/pmg/config"
 	"github.com/safedep/pmg/internal/flows"
 	"github.com/safedep/pmg/internal/ui"
 	"github.com/safedep/pmg/packagemanager"
@@ -32,6 +33,17 @@ func executePnpmFlow(ctx context.Context, args []string) error {
 	if err != nil {
 		ui.Fatalf("Failed to create pnpm package manager proxy: %s", err)
 	}
+	config, err := config.FromContext(ctx)
+	if err != nil {
+		ui.Fatalf("Failed to get config: %s", err)
+	}
+
+	packageResolverConfig := packagemanager.NewDefaultNpmDependencyResolverConfig()
+	packageResolverConfig.IncludeTransitiveDependencies = config.Transitive
+	packageResolverConfig.TransitiveDepth = config.TransitiveDepth
+	packageResolverConfig.IncludeDevDependencies = config.IncludeDevDependencies
+
+	packageResolver, err := packagemanager.NewNpmDependencyResolver(packageResolverConfig)
 
-	return flows.Common(packageManager).Run(ctx, args)
+	return flows.Common(packageManager, packageResolver, config).Run(ctx, args)
 }
diff --git a/cmd/pypi/pip.go b/cmd/pypi/pip.go
index 56d03f7..4cc9a65 100644
--- a/cmd/pypi/pip.go
+++ b/cmd/pypi/pip.go
@@ -6,6 +6,7 @@ import (
 
 	"github.com/safedep/dry/log"
 	"github.com/safedep/pmg/config"
+	"github.com/safedep/pmg/internal/flows"
 	"github.com/safedep/pmg/internal/ui"
 	"github.com/safedep/pmg/packagemanager"
 	"github.com/spf13/cobra"
@@ -17,12 +18,7 @@ func NewPipCommand() *cobra.Command {
 		Short:              "Guard pip package manager",
 		DisableFlagParsing: true,
 		RunE: func(cmd *cobra.Command, args []string) error {
-			config, err := config.FromContext(cmd.Context())
-			if err != nil {
-				ui.Fatalf("Failed to get config: %s", err)
-			}
-
-			err = executePipFlow(cmd.Context(), config, args)
+			err := executePipFlow(cmd.Context(), args)
 			if err != nil {
 				log.Errorf("Failed to execute pip flow: %s", err)
 			}
@@ -32,12 +28,24 @@ func NewPipCommand() *cobra.Command {
 	}
 }
 
-func executePipFlow(context context.Context, config config.Config, args []string) error {
+func executePipFlow(ctx context.Context, args []string) error {
 	packageManager, err := packagemanager.NewPipPackageManager(packagemanager.DefaultPipPackageManagerConfig())
 	if err != nil {
 		return fmt.Errorf("failed to create pip package manager: %w", err)
 	}
-	cmd, _ := packageManager.ParseCommand(args)
-	fmt.Println("Cmd: ", cmd.InstallTargets[0])
-	return nil
+	config, err := config.FromContext(ctx)
+	if err != nil {
+		ui.Fatalf("Failed to get config: %s", err)
+	}
+	packageResolverConfig := packagemanager.NewDefaultPypiDependencyResolverConfig()
+	packageResolverConfig.IncludeTransitiveDependencies = config.Transitive
+	packageResolverConfig.TransitiveDepth = config.TransitiveDepth
+	packageResolverConfig.IncludeDevDependencies = config.IncludeDevDependencies
+
+	packageResolver, err := packagemanager.NewPypiDependencyResolver(packageResolverConfig)
+	if err != nil {
+		ui.Fatalf("Failed to create dependency resolver: %s", err)
+	}
+
+	return flows.Common(packageManager, packageResolver, config).Run(ctx, args)
 }
diff --git a/internal/flows/common.go b/internal/flows/common.go
index a8cbaae..dbc82ca 100644
--- a/internal/flows/common.go
+++ b/internal/flows/common.go
@@ -11,37 +11,26 @@ import (
 )
 
 type commonFlow struct {
-	pm packagemanager.PackageManager
+	pm              packagemanager.PackageManager
+	packageResolver packagemanager.PackageResolver
+	config          config.Config
 }
 
 // Creates a common flow of execution for all package managers. This should work for most
 // of the cases unless a package manager has its own unique requirements. Configuration
 // should be passed through the context (Global Config)
-func Common(pm packagemanager.PackageManager) *commonFlow {
+func Common(pm packagemanager.PackageManager, pkgResolver packagemanager.PackageResolver, config config.Config) *commonFlow {
 	return &commonFlow{
-		pm: pm,
+		pm:              pm,
+		packageResolver: pkgResolver,
+		config:          config,
 	}
 }
 
 func (f *commonFlow) Run(ctx context.Context, args []string) error {
-	config, err := config.FromContext(ctx)
-	if err != nil {
-		ui.Fatalf("Failed to get config: %s", err)
-	}
-
-	packageResolverConfig := packagemanager.NewDefaultNpmDependencyResolverConfig()
-	packageResolverConfig.IncludeTransitiveDependencies = config.Transitive
-	packageResolverConfig.TransitiveDepth = config.TransitiveDepth
-	packageResolverConfig.IncludeDevDependencies = config.IncludeDevDependencies
-
-	packageResolver, err := packagemanager.NewNpmDependencyResolver(packageResolverConfig)
-	if err != nil {
-		ui.Fatalf("Failed to create dependency resolver: %s", err)
-	}
-
 	var analyzers []analyzer.PackageVersionAnalyzer
 
-	if config.Paranoid {
+	if f.config.Paranoid {
 		malysisActiveScanAnalyzer, err := analyzer.NewMalysisActiveScanAnalyzer(analyzer.DefaultMalysisActiveScanAnalyzerConfig())
 		if err != nil {
 			ui.Fatalf("Failed to create malware analyzer: %s", err)
@@ -65,9 +54,9 @@ func (f *commonFlow) Run(ctx context.Context, args []string) error {
 	}
 
 	guardConfig := guard.DefaultPackageManagerGuardConfig()
-	guardConfig.DryRun = config.DryRun
+	guardConfig.DryRun = f.config.DryRun
 
-	proxy, err := guard.NewPackageManagerGuard(guardConfig, f.pm, packageResolver, analyzers, interaction)
+	proxy, err := guard.NewPackageManagerGuard(guardConfig, f.pm, f.packageResolver, analyzers, interaction)
 	if err != nil {
 		ui.Fatalf("Failed to create package manager guard: %s", err)
 	}
diff --git a/packagemanager/dependency_resolver.go b/packagemanager/dependency_resolver.go
index 1f3c7a1..2d48a8f 100644
--- a/packagemanager/dependency_resolver.go
+++ b/packagemanager/dependency_resolver.go
@@ -13,7 +13,7 @@ import (
 
 // Contract for a function that implements ecosystem specific version
 // resolver from a version range specification.
-type versionSpecResolver func(version string) string
+type versionSpecResolver func(packageName, version string) string
 
 type dependencyResolverConfig struct {
 	IncludeDevDependencies        bool
@@ -38,7 +38,7 @@ func newDependencyResolver(client packageregistry.Client, config dependencyResol
 
 	if versionSpecResolver == nil {
 		// Default version spec resolver
-		versionSpecResolver = func(version string) string {
+		versionSpecResolver = func(packageName, version string) string {
 			return version
 		}
 	}
@@ -141,7 +141,7 @@ func (r *dependencyResolver) resolvePackageDependenciesConcurrent(
 				Ecosystem: packageVersion.GetPackage().GetEcosystem(),
 				Name:      dependency.Name,
 			},
-			Version: r.versionSpecResolver(dependency.VersionSpec),
+			Version: r.versionSpecResolver(dependency.Name, dependency.VersionSpec),
 		})
 	}
 
diff --git a/packagemanager/npm_resolver.go b/packagemanager/npm_resolver.go
index 68293a4..dd46c2c 100644
--- a/packagemanager/npm_resolver.go
+++ b/packagemanager/npm_resolver.go
@@ -78,7 +78,9 @@ func (r *npmDependencyResolver) ResolveDependencies(ctx context.Context,
 		TransitiveDepth:               r.config.TransitiveDepth,
 		FailFast:                      r.config.FailFast,
 		MaxConcurrency:                r.config.MaxConcurrency,
-	}, npmCleanVersion)
+	}, func(packageName, version string) string {
+		return npmCleanVersion(version)
+	})
 
 	return resolver.resolveDependencies(ctx, packageVersion)
 }
diff --git a/packagemanager/pypi.go b/packagemanager/pypi.go
index 615a664..08a79cf 100644
--- a/packagemanager/pypi.go
+++ b/packagemanager/pypi.go
@@ -83,8 +83,6 @@ func (pip *pipPackageManager) ParseCommand(args []string) (*ParsedCommand, error
 			}
 		}
 
-		fmt.Printf("Package Name: %s Version: %s\n", packageName, version)
-
 		installTargets = append(installTargets, &PackageInstallTarget{
 			PackageVersion: &packagev1.PackageVersion{
 				Package: &packagev1.Package{
diff --git a/packagemanager/pypi_resolver.go b/packagemanager/pypi_resolver.go
index dd6d22a..5e952bb 100644
--- a/packagemanager/pypi_resolver.go
+++ b/packagemanager/pypi_resolver.go
@@ -2,11 +2,8 @@ package packagemanager
 
 import (
 	"context"
-	"encoding/json"
 	"fmt"
-	"net/http"
 	"strings"
-	"time"
 
 	packagev1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/messages/package/v1"
 	"github.com/Masterminds/semver"
@@ -62,6 +59,13 @@ func (p *pypiDependencyResolver) ResolveDependencies(ctx context.Context, pkg *p
 		TransitiveDepth:               p.config.TransitiveDepth,
 		FailFast:                      p.config.FailFast,
 		MaxConcurrency:                p.config.MaxConcurrency,
+	}, func(packageName, version string) string {
+		ver, err := pipGetMatchingVersion(packageName, version)
+		if err != nil {
+			log.Debugf("error getting matching version for %s@%s", packageName, version)
+			return ""
+		}
+		return ver
 	})
 
 	return resolver.resolveDependencies(ctx, pkg)
@@ -74,6 +78,7 @@ func (p *pypiDependencyResolver) ResolveLatestVersion(ctx context.Context, pkg *
 	}
 
 	pkgInfo, err := pd.GetPackage(pkg.Name)
+	fmt.Println("Package Info version: ", pkgInfo.LatestVersion, " Error: ", err)
 	if err != nil {
 		return nil, fmt.Errorf("failed to get package: %w", err)
 	}
@@ -85,13 +90,6 @@ func (p *pypiDependencyResolver) ResolveLatestVersion(ctx context.Context, pkg *
 	}, nil
 }
 
-// PyPIPackage represents the package information from PyPI
-type PyPIPackage struct {
-	Releases map[string]any `json:"releases"`
-}
-
-var httpClient = &http.Client{Timeout: 10 * time.Second}
-
 func pipGetMatchingVersion(packageName, versionConstraint string) (string, error) {
 	// Already a exact version
 	if strings.HasPrefix(versionConstraint, "==") {
@@ -103,8 +101,18 @@ func pipGetMatchingVersion(packageName, versionConstraint string) (string, error
 		versionConstraint = pipConvertCompatibleRelease(versionConstraint)
 	}
 
+	registry, err := packageregistry.NewPypiAdapter()
+	if err != nil {
+		return "", fmt.Errorf("failed to create pypi adapter: %w", err)
+	}
+
+	pd, err := registry.PackageDiscovery()
+	if err != nil {
+		return "", fmt.Errorf("failed to get package discovery: %w", err)
+	}
+
 	// Get package info from PyPI
-	pkg, err := pipFetchPackageVersionsInfo(packageName)
+	pkg, err := pd.GetPackage(packageName)
 	if err != nil {
 		return "", err
 	}
@@ -116,7 +124,7 @@ func pipGetMatchingVersion(packageName, versionConstraint string) (string, error
 	}
 
 	// Get valid versions and find best match
-	bestMatch, err := findBestMatchingVersion(pkg.Releases, constraint)
+	bestMatch, err := findBestMatchingVersion(pkg.Versions, constraint)
 	if err != nil {
 		return "", fmt.Errorf("no version matches constraint %q: %w", versionConstraint, err)
 	}
@@ -124,36 +132,15 @@ func pipGetMatchingVersion(packageName, versionConstraint string) (string, error
 	return bestMatch.Original(), nil
 }
 
-// pipFetchPackageVersionsInfo retrieves package information from PyPI
-func pipFetchPackageVersionsInfo(packageName string) (*PyPIPackage, error) {
-	url := fmt.Sprintf("https://pypi.org/pypi/%s/json", packageName)
-	resp, err := httpClient.Get(url)
-	if err != nil {
-		return nil, fmt.Errorf("failed to fetch package info: %w", err)
-	}
-	defer resp.Body.Close()
-
-	if resp.StatusCode != 200 {
-		return nil, fmt.Errorf("package not found or HTTP error: %d", resp.StatusCode)
-	}
-
-	var pypiPkg PyPIPackage
-	if err := json.NewDecoder(resp.Body).Decode(&pypiPkg); err != nil {
-		return nil, fmt.Errorf("failed to parse JSON: %w", err)
-	}
-
-	return &pypiPkg, nil
-}
-
-func findBestMatchingVersion(releases map[string]any, constraint *semver.Constraints) (*semver.Version, error) {
+func findBestMatchingVersion(releases []packageregistry.PackageVersionInfo, constraint *semver.Constraints) (*semver.Version, error) {
 	if len(releases) == 0 {
 		return nil, fmt.Errorf("no versions available")
 	}
 
 	var bestMatch *semver.Version
 	// We'll iterate once through all versions
-	for v := range releases {
-		ver, err := semver.NewVersion(v)
+	for _, v := range releases {
+		ver, err := semver.NewVersion(v.Version)
 		if err != nil {
 			continue // Skip invalid versions
 		}
