项目作者: HazardDede

项目描述 :
Resolves missing function arguments at runtime
高级语言: Python
项目地址: git://github.com/HazardDede/argresolver.git
创建时间: 2018-05-14T21:54:03Z
项目社区:https://github.com/HazardDede/argresolver

开源协议:MIT License

下载


ArgResolver v0.3.3

PyPI version
Build Status
Coverage Status
License: MIT

Resolver is a simple decorator for resolving (missing) arguments at runtime.
It performs various tasks from looking up arguments from the environment variable scope to simple service dependency injection.

1. Resolver
1.1. Environment
1.2. Map
1.3. Chain

1. Resolver

1.1. Environment

  1. # We inject arguments from the environment variables scope to a simple function
  2. # We use a `prefix` to minimize clashes with other components
  3. # username will have a correponding DB_USERNAME, same for password and database
  4. from argresolver import Environment
  5. from argresolver.utils import modified_environ # We use it to alter the environment variables
  6. @Environment()
  7. def connect(host, user, password):
  8. print("Connecting: {user}:{password}@{host}".format(**locals()))
  9. with modified_environ(PASSWORD='my_pass'):
  10. connect('localhost', 'admin')
  11. # Prints: Connecting: admin:my_pass@localhost
  1. # We inject arguments from the environment variables scope
  2. # to an instance __init__.
  3. # We use a `prefix` to minimize clashes with other components that have a username / password.
  4. # Argument username will have a correponding DB_USERNAME, same for password and database
  5. from argresolver import Environment
  6. from argresolver.utils import modified_environ # We use it to alter the environment variables
  7. class Connection:
  8. @Environment(prefix='DB')
  9. def __init__(self, username, password, database='default'):
  10. self.username = username
  11. self.password = password
  12. self.database = database
  13. def __str__(self):
  14. # Hint: In a real world example you won't put your password in here ;-)
  15. return "Connection(username='{self.username}', password='{self.password}'"\
  16. ", database='{self.database}')".format(self=self)
  17. with modified_environ(DB_USERNAME='admin', DB_PASSWORD='secret'):
  18. conn = Connection()
  19. print(str(conn)) # Connection(username='admin', password='secret', database='default')

1.2. Map

  1. # We use the Map resolver to override an argument's default value
  2. # that is better suited for our needs.
  3. from argresolver import Map
  4. # Let's assume we cannot touch this code...
  5. class Foo:
  6. def __init__(self, arg1, arg2='I_dont_like_this_default'):
  7. self.arg1 = arg1
  8. self.arg2 = arg2
  9. def __str__(self):
  10. return "Foo(arg1='{self.arg1}', arg2='{self.arg2}')".format(self=self)
  11. # But we can alter the class and wrap a resolver around the class __init__
  12. Foo.__init__ = Map(dict(arg2="better_default"), default_override=True)(Foo.__init__)
  13. foo = Foo("this is arg1")
  14. print(str(foo)) # Foo(arg1='this is arg1', arg2='better_default')

1.3. Chain

  1. # We do some automatic dependency injection with fallback
  2. from argresolver import Chain, Const, Map
  3. inject = Chain(
  4. Map(dict(service1="Service1", service2="Service2")),
  5. Const("Fallback Service")
  6. )
  7. class Orchestration:
  8. @inject
  9. def business_process1(self, service1, service2):
  10. print("Calling service:", service1)
  11. print("Calling service:", service2)
  12. @inject
  13. def business_process2(self, service1, service3):
  14. print("Calling service:", service1)
  15. print("Calling service:", service3)
  16. orchester = Orchestration()
  17. orchester.business_process1()
  18. # Prints:
  19. # Calling service: Service1
  20. # Calling service: Service2
  21. orchester.business_process2()
  22. # Prints:
  23. # Calling service: Service1
  24. # Calling service: Fallback Service