Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use injector to initialize storage adaptor type #916

Merged
merged 2 commits into from
Jul 17, 2024

Conversation

corps
Copy link
Contributor

@corps corps commented Jul 16, 2024

  1. Extract the AppConfig object that can parse os.environ on app bootup, consolidating our various environment variable usages.
  2. get_storage_adaptor_class is a now a module.provider that receives the AppConfig object via injected and selects its implementation based on that.
  3. Tests simplify a bit as a result of this.

I will be making more refactorings that integrate AppConfig in other places to simplify our configuration and bootup sequence.

@corps corps requested a review from a team July 16, 2024 23:44
@@ -159,7 +160,13 @@ def get_namespace(
return CodebaseNamespace.from_db(db_namespace)

@classmethod
def load_workspace(cls, namespace_id: int, skip_copy: bool = False):
@inject
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because we use injected we have to decorate the method with @inject OR @module.provider.

The difference is wether this method is a singleton that takes no required arguments, or a helper method that takes required arguments. Because this method is not a singleton, that is, it takes in arguments and runs differently based on the inputs, it uses inject.


def __init__(self, repo_id: int, namespace_slug: str):
@inject
def __init__(self, repo_id: int, namespace_slug: str, app_config: AppConfig = injected):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Creating a StorageAdaptor now "gets" the AppConfig for free here.

storage_type = os.getenv("CODEBASE_STORAGE_TYPE", "filesystem")

autofix_logger.debug(f"Using storage type: {storage_type}")
@module.provider
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a module.provider because it is instantiated just once and then provided to other things as injected.

If the return value of a provider is going to be injected elsewhere, it is a @module.provider.

ParsePath = Annotated[str, BeforeValidator(as_absolute_path)]


class AppConfig(BaseModel):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Helpful class that parses and types all of our os.environ inputs in one clean place. We can use pydantic features, including validators and post init, to catch configuration issues easily.

In the future, I intend to use this to check if your current .env file needs further values, making development more straight forward and automated.

@@ -76,11 +77,23 @@ def from_annotation(cls, source: Any) -> "FactoryAnnotation":
not inner.is_collection
), f"Cannot get_factory {source}: collections must be of concrete types, not other lists"
return dataclasses.replace(inner, is_collection=True)
elif annotation.origin is type:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is support for factories that themselves return type[X].



class TestStorageAdapter(unittest.TestCase):
def test_fs_workspace_clear(self):
os.environ["CODEBASE_STORAGE_TYPE"] = "filesystem"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't need to this kind of manipulation, see above how we set an override for stub_module that will be used by default in tests.



@stub_module.provider
def provide_test_defaults() -> AppConfig:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can create defaults for tests here, so that each test doesn't have to know how to create useful fake defaults.

@corps corps merged commit cc9ad01 into main Jul 17, 2024
10 checks passed
@corps corps deleted the zc/use-app-configuration-object branch July 17, 2024 15:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants