0

I am trying to validate the dictionary parameter.

import logging
import os
# decorator
def file_validator(f):
    def wrapped(*args):
        """
        Once there is passed values,
        file_path = os.path.join(path_info, file_info)
        if os.path.exists(file_path):
            logging.info('{} exists'.format(file_info))
        else:
            logging.info('{} does not exist'.format(file_info))
        """

# original function
@file_validator
def original_function(file_dict):
    # pass only specific element to file_validator decorator for checking
    # for example only "pathA": "/files", "fileA": "bar.csv"

sample_dict = {"pathA": "/files", "fileA": "bar.csv", "fileB": "hello.txt"}
original_function(sample_dict)

Is there a way to check this way using decorator?
EDIT This could be equivalent to what I want to do.

def file_validator(filepath, filename):
    file_path = os.path.join(filepath + filename)
    if os.path.exists(file_path):
        logging.info('{} exists'.format(filename))
    else:
        logging.info('{} does not exist'.format(filename))

def original_function(file_dict):
    file_validator(file_dict['pathA'], file_dict['fileA'])
    file_validator(file_dict['pathA'], file_dict['fileB'])

sample_dict = {"pathA": "/files", "fileA": "bar.csv", "fileB": "hello.txt"}
original_function(sample_dict)
jayko03
  • 2,329
  • 7
  • 28
  • 51
  • Please take a look at https://stackoverflow.com/questions/5929107/decorators-with-parameters . Let us know still if help needed – HArdRe537 Jun 17 '20 at 04:12
  • @HArdRese7 I edited since I think my question was not clear. I also checked that link, but I don't feel it is much related?? – jayko03 Jun 17 '20 at 04:43
  • You can pass your dict as input to the decorator function and achieve what you want . Decorators are useful in modifying the function behaviour but not the arguments that are passed to the function. You can use the classes and achieve the same funcitionality (Take a look at Django's class level decorator implementation if you are interested) – HArdRe537 Jun 17 '20 at 05:03

2 Answers2

0

Seems like something like this should do the trick:

import os
import logging

def file_validator(func):
    def wrapper(file_dict:dict):
        
        # Turn file_dict to two lists:
        #   paths = ["/files"]
        #   files = ["bar.csv", "hello.txt"]
        paths = [
            path 
            for name, path in file_dict.items() 
            if name.startswith("path")
        ]
        files = [
            file 
            for name, file in file_dict.items() 
            if name.startswith("file")
        ]

        # Loop through all the path & file combinations and check if they exist
        for path in paths:
            for file in files:
               
                full_path = os.path.join(path, file)
                if os.path.exists(full_path):
                    logging.info('{} exists'.format(file))
                else:
                    logging.info('{} does not exist'.format(file))

        # Run the actual function
        return func(file_dict)
    return wrapper

@file_validator
def original_function(file_dict):
    ...

files = {"pathA": "/files", "fileA": "bar.csv", "fileB": "hello.txt"}
original_function(files) 
# Note that fileB is not checked as it's missing "pathB" 
# but from the question it is unclear how this should be handled 

But there is some code smell. If possible, I would advise not to store your paths and files in that way as that's not easy to manipulate and prone to bugs. Much better would be to store them as a list of full paths by creating all the combinations using itertools.combinations, or then just having two lists: paths and files.

miksus
  • 2,426
  • 1
  • 18
  • 34
-1

logging.info replaced by print here for verification.

import logging
import os

def file_validator(f):
    def wrapper(args):
        for path, file in args.items():
            file_path = os.path.join(path, file)
            if os.path.exists(file_path):
                print('{} exists'.format(file_path))
            else:
                print('{} does not exist'.format(file_path))
        f(args)
    return wrapper


@file_validator
def original_function(file_dict):
    print(file_dict)

sample_dict = {"pathA": "\\files", "fileA": "bar.csv", "fileB": "hello.txt"}
original_function(sample_dict)
Jason Yang
  • 11,284
  • 2
  • 9
  • 23